From 31cb769c317e0623cbe2a3e8da437b6cd7ddef9b Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Thu, 6 Oct 2022 13:19:48 +0300 Subject: [PATCH 001/705] hw/char/pl011: fix baud rate calculation The PL011 TRM says that "UARTIBRD = 0 is invalid and UARTFBRD is ignored when this is the case". But the code looks at FBRD for the invalid case. Fix this. Signed-off-by: Baruch Siach Message-id: 1408f62a2e45665816527d4845ffde650957d5ab.1665051588.git.baruchs-c@neureality.ai Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/char/pl011.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/char/pl011.c b/hw/char/pl011.c index 6e2d7f7509..c076813423 100644 --- a/hw/char/pl011.c +++ b/hw/char/pl011.c @@ -176,7 +176,7 @@ static unsigned int pl011_get_baudrate(const PL011State *s) { uint64_t clk; - if (s->fbrd == 0) { + if (s->ibrd == 0) { return 0; } From 947692e708bc61ca724429b5198f0b0f5f68102d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Mon, 10 Oct 2022 16:32:25 +0100 Subject: [PATCH 002/705] target/arm: update the cortex-a15 MIDR to latest rev MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QEMU doesn't model micro-architectural details which includes most chip errata. The ARM_ERRATA_798181 work around in the Linux kernel (see erratum_a15_798181_init) currently detects QEMU's cortex-a15 as broken and triggers additional expensive TLB flushes as a result. Change the MIDR to report what the latest silicon would (r4p0). We explicitly set the IMPDEF revidr bits to 0 because we don't need to set anything other than the silicon revision to indicate these flushes are not needed. This cuts about 5s from my Debian kernel boot with the latest 6.0rc1 kernel (29s->24s). Signed-off-by: Alex Bennée Reviewed-by: Philippe Mathieu-Daudé Tested-by: Anders Roxell Message-id: 20221010153225.506394-1-alex.bennee@linaro.org Cc: Arnd Bergmann Cc: Anders Roxell Reviewed-by: Philippe Mathieu-Daudé Tested-by: Anders Roxell Message-Id: <20220906172257.2776521-1-alex.bennee@linaro.org> Signed-off-by: Peter Maydell --- target/arm/cpu_tcg.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c index 98b5ba2160..60ff539fa1 100644 --- a/target/arm/cpu_tcg.c +++ b/target/arm/cpu_tcg.c @@ -592,7 +592,9 @@ static void cortex_a15_initfn(Object *obj) set_feature(&cpu->env, ARM_FEATURE_EL3); set_feature(&cpu->env, ARM_FEATURE_PMU); cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A15; - cpu->midr = 0x412fc0f1; + /* r4p0 cpu, not requiring expensive tlb flush errata */ + cpu->midr = 0x414fc0f0; + cpu->revidr = 0x0; cpu->reset_fpsid = 0x410430f0; cpu->isar.mvfr0 = 0x10110222; cpu->isar.mvfr1 = 0x11111111; From 24d18d5d7e31462b7bd5bb2c6ee19856699e34ed Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 10 Oct 2022 20:18:48 -0700 Subject: [PATCH 003/705] target/arm: Enable TARGET_PAGE_ENTRY_EXTRA Copy attrs and shareability, into the TLB. This will eventually be used by S1_ptw_translate to report stage1 translation failures, and by do_ats_write to fill in PAR_EL1. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20221011031911.2408754-2-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/cpu-param.h | 12 ++++++++++++ target/arm/tlb_helper.c | 3 +++ 2 files changed, 15 insertions(+) diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h index 08681828ac..38347b0d20 100644 --- a/target/arm/cpu-param.h +++ b/target/arm/cpu-param.h @@ -30,6 +30,18 @@ */ # define TARGET_PAGE_BITS_VARY # define TARGET_PAGE_BITS_MIN 10 + +/* + * Cache the attrs and shareability fields from the page table entry. + * + * For ARMMMUIdx_Stage2*, pte_attrs is the S2 descriptor bits [5:2]. + * Otherwise, pte_attrs is the same as the MAIR_EL1 8-bit format. + * For shareability, as in the SH field of the VMSAv8-64 PTEs. + */ +# define TARGET_PAGE_ENTRY_EXTRA \ + uint8_t pte_attrs; \ + uint8_t shareability; + #endif #define NB_MMU_MODES 8 diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c index 49601394ec..353edbeb1d 100644 --- a/target/arm/tlb_helper.c +++ b/target/arm/tlb_helper.c @@ -236,6 +236,9 @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size, arm_tlb_mte_tagged(&res.f.attrs) = true; } + res.f.pte_attrs = res.cacheattrs.attrs; + res.f.shareability = res.cacheattrs.shareability; + tlb_set_page_full(cs, mmu_idx, address, &res.f); return true; } else if (probe) { From b8967ddf393aaf35fdbc07b4cb538a40f8b6fe37 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 10 Oct 2022 20:18:49 -0700 Subject: [PATCH 004/705] target/arm: Use probe_access_full for MTE The CPUTLBEntryFull structure now stores the original pte attributes, as well as the physical address. Therefore, we no longer need a separate bit in MemTxAttrs, nor do we need to walk the tree of memory regions. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20221011031911.2408754-3-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/cpu.h | 1 - target/arm/mte_helper.c | 62 ++++++++++------------------------ target/arm/sve_helper.c | 54 ++++++++++------------------- target/arm/sve_ldst_internal.h | 1 + target/arm/tlb_helper.c | 4 --- 5 files changed, 36 insertions(+), 86 deletions(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index e3dbef5be8..9a358c410b 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -3400,7 +3400,6 @@ static inline MemTxAttrs *typecheck_memtxattrs(MemTxAttrs *x) * generic target bits directly. */ #define arm_tlb_bti_gp(x) (typecheck_memtxattrs(x)->target_tlb_bit0) -#define arm_tlb_mte_tagged(x) (typecheck_memtxattrs(x)->target_tlb_bit1) /* * AArch64 usage of the PAGE_TARGET_* bits for linux-user. diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c index fdd23ab3f8..e85208339e 100644 --- a/target/arm/mte_helper.c +++ b/target/arm/mte_helper.c @@ -105,10 +105,9 @@ static uint8_t *allocation_tag_mem(CPUARMState *env, int ptr_mmu_idx, TARGET_PAGE_BITS - LOG2_TAG_GRANULE - 1); return tags + index; #else - uintptr_t index; CPUTLBEntryFull *full; + MemTxAttrs attrs; int in_page, flags; - ram_addr_t ptr_ra; hwaddr ptr_paddr, tag_paddr, xlat; MemoryRegion *mr; ARMASIdx tag_asi; @@ -124,30 +123,12 @@ static uint8_t *allocation_tag_mem(CPUARMState *env, int ptr_mmu_idx, * valid. Indicate to probe_access_flags no-fault, then assert that * we received a valid page. */ - flags = probe_access_flags(env, ptr, ptr_access, ptr_mmu_idx, - ra == 0, &host, ra); + flags = probe_access_full(env, ptr, ptr_access, ptr_mmu_idx, + ra == 0, &host, &full, ra); assert(!(flags & TLB_INVALID_MASK)); - /* - * Find the CPUTLBEntryFull for ptr. This *must* be present in the TLB - * because we just found the mapping. - * TODO: Perhaps there should be a cputlb helper that returns a - * matching tlb entry + iotlb entry. - */ - index = tlb_index(env, ptr_mmu_idx, ptr); -# ifdef CONFIG_DEBUG_TCG - { - CPUTLBEntry *entry = tlb_entry(env, ptr_mmu_idx, ptr); - target_ulong comparator = (ptr_access == MMU_DATA_LOAD - ? entry->addr_read - : tlb_addr_write(entry)); - g_assert(tlb_hit(comparator, ptr)); - } -# endif - full = &env_tlb(env)->d[ptr_mmu_idx].fulltlb[index]; - /* If the virtual page MemAttr != Tagged, access unchecked. */ - if (!arm_tlb_mte_tagged(&full->attrs)) { + if (full->pte_attrs != 0xf0) { return NULL; } @@ -162,6 +143,14 @@ static uint8_t *allocation_tag_mem(CPUARMState *env, int ptr_mmu_idx, return NULL; } + /* + * Remember these values across the second lookup below, + * which may invalidate this pointer via tlb resize. + */ + ptr_paddr = full->phys_addr; + attrs = full->attrs; + full = NULL; + /* * The Normal memory access can extend to the next page. E.g. a single * 8-byte access to the last byte of a page will check only the last @@ -170,9 +159,8 @@ static uint8_t *allocation_tag_mem(CPUARMState *env, int ptr_mmu_idx, */ in_page = -(ptr | TARGET_PAGE_MASK); if (unlikely(ptr_size > in_page)) { - void *ignore; - flags |= probe_access_flags(env, ptr + in_page, ptr_access, - ptr_mmu_idx, ra == 0, &ignore, ra); + flags |= probe_access_full(env, ptr + in_page, ptr_access, + ptr_mmu_idx, ra == 0, &host, &full, ra); assert(!(flags & TLB_INVALID_MASK)); } @@ -180,33 +168,17 @@ static uint8_t *allocation_tag_mem(CPUARMState *env, int ptr_mmu_idx, if (unlikely(flags & TLB_WATCHPOINT)) { int wp = ptr_access == MMU_DATA_LOAD ? BP_MEM_READ : BP_MEM_WRITE; assert(ra != 0); - cpu_check_watchpoint(env_cpu(env), ptr, ptr_size, - full->attrs, wp, ra); + cpu_check_watchpoint(env_cpu(env), ptr, ptr_size, attrs, wp, ra); } - /* - * Find the physical address within the normal mem space. - * The memory region lookup must succeed because TLB_MMIO was - * not set in the cputlb lookup above. - */ - mr = memory_region_from_host(host, &ptr_ra); - tcg_debug_assert(mr != NULL); - tcg_debug_assert(memory_region_is_ram(mr)); - ptr_paddr = ptr_ra; - do { - ptr_paddr += mr->addr; - mr = mr->container; - } while (mr); - /* Convert to the physical address in tag space. */ tag_paddr = ptr_paddr >> (LOG2_TAG_GRANULE + 1); /* Look up the address in tag space. */ - tag_asi = full->attrs.secure ? ARMASIdx_TagS : ARMASIdx_TagNS; + tag_asi = attrs.secure ? ARMASIdx_TagS : ARMASIdx_TagNS; tag_as = cpu_get_address_space(env_cpu(env), tag_asi); mr = address_space_translate(tag_as, tag_paddr, &xlat, NULL, - tag_access == MMU_DATA_STORE, - full->attrs); + tag_access == MMU_DATA_STORE, attrs); /* * Note that @mr will never be NULL. If there is nothing in the address diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c index 9cae8fd352..3d0d2987cd 100644 --- a/target/arm/sve_helper.c +++ b/target/arm/sve_helper.c @@ -5351,8 +5351,19 @@ bool sve_probe_page(SVEHostPage *info, bool nofault, CPUARMState *env, */ addr = useronly_clean_ptr(addr); +#ifdef CONFIG_USER_ONLY flags = probe_access_flags(env, addr, access_type, mmu_idx, nofault, &info->host, retaddr); + memset(&info->attrs, 0, sizeof(info->attrs)); + /* Require both ANON and MTE; see allocation_tag_mem(). */ + info->tagged = (flags & PAGE_ANON) && (flags & PAGE_MTE); +#else + CPUTLBEntryFull *full; + flags = probe_access_full(env, addr, access_type, mmu_idx, nofault, + &info->host, &full, retaddr); + info->attrs = full->attrs; + info->tagged = full->pte_attrs == 0xf0; +#endif info->flags = flags; if (flags & TLB_INVALID_MASK) { @@ -5362,33 +5373,6 @@ bool sve_probe_page(SVEHostPage *info, bool nofault, CPUARMState *env, /* Ensure that info->host[] is relative to addr, not addr + mem_off. */ info->host -= mem_off; - -#ifdef CONFIG_USER_ONLY - memset(&info->attrs, 0, sizeof(info->attrs)); - /* Require both MAP_ANON and PROT_MTE -- see allocation_tag_mem. */ - arm_tlb_mte_tagged(&info->attrs) = - (flags & PAGE_ANON) && (flags & PAGE_MTE); -#else - /* - * Find the iotlbentry for addr and return the transaction attributes. - * This *must* be present in the TLB because we just found the mapping. - */ - { - uintptr_t index = tlb_index(env, mmu_idx, addr); - -# ifdef CONFIG_DEBUG_TCG - CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr); - target_ulong comparator = (access_type == MMU_DATA_LOAD - ? entry->addr_read - : tlb_addr_write(entry)); - g_assert(tlb_hit(comparator, addr)); -# endif - - CPUTLBEntryFull *full = &env_tlb(env)->d[mmu_idx].fulltlb[index]; - info->attrs = full->attrs; - } -#endif - return true; } @@ -5617,7 +5601,7 @@ void sve_cont_ldst_mte_check(SVEContLdSt *info, CPUARMState *env, intptr_t mem_off, reg_off, reg_last; /* Process the page only if MemAttr == Tagged. */ - if (arm_tlb_mte_tagged(&info->page[0].attrs)) { + if (info->page[0].tagged) { mem_off = info->mem_off_first[0]; reg_off = info->reg_off_first[0]; reg_last = info->reg_off_split; @@ -5638,7 +5622,7 @@ void sve_cont_ldst_mte_check(SVEContLdSt *info, CPUARMState *env, } mem_off = info->mem_off_first[1]; - if (mem_off >= 0 && arm_tlb_mte_tagged(&info->page[1].attrs)) { + if (mem_off >= 0 && info->page[1].tagged) { reg_off = info->reg_off_first[1]; reg_last = info->reg_off_last[1]; @@ -6017,7 +6001,7 @@ void sve_ldnfff1_r(CPUARMState *env, void *vg, const target_ulong addr, * Disable MTE checking if the Tagged bit is not set. Since TBI must * be set within MTEDESC for MTE, !mtedesc => !mte_active. */ - if (!arm_tlb_mte_tagged(&info.page[0].attrs)) { + if (!info.page[0].tagged) { mtedesc = 0; } @@ -6568,7 +6552,7 @@ void sve_ld1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm, cpu_check_watchpoint(env_cpu(env), addr, msize, info.attrs, BP_MEM_READ, retaddr); } - if (mtedesc && arm_tlb_mte_tagged(&info.attrs)) { + if (mtedesc && info.tagged) { mte_check(env, mtedesc, addr, retaddr); } if (unlikely(info.flags & TLB_MMIO)) { @@ -6585,7 +6569,7 @@ void sve_ld1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm, msize, info.attrs, BP_MEM_READ, retaddr); } - if (mtedesc && arm_tlb_mte_tagged(&info.attrs)) { + if (mtedesc && info.tagged) { mte_check(env, mtedesc, addr, retaddr); } tlb_fn(env, &scratch, reg_off, addr, retaddr); @@ -6786,9 +6770,7 @@ void sve_ldff1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm, (env_cpu(env), addr, msize) & BP_MEM_READ)) { goto fault; } - if (mtedesc && - arm_tlb_mte_tagged(&info.attrs) && - !mte_probe(env, mtedesc, addr)) { + if (mtedesc && info.tagged && !mte_probe(env, mtedesc, addr)) { goto fault; } @@ -6974,7 +6956,7 @@ void sve_st1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm, info.attrs, BP_MEM_WRITE, retaddr); } - if (mtedesc && arm_tlb_mte_tagged(&info.attrs)) { + if (mtedesc && info.tagged) { mte_check(env, mtedesc, addr, retaddr); } } diff --git a/target/arm/sve_ldst_internal.h b/target/arm/sve_ldst_internal.h index b5c473fc48..4f159ec4ad 100644 --- a/target/arm/sve_ldst_internal.h +++ b/target/arm/sve_ldst_internal.h @@ -134,6 +134,7 @@ typedef struct { void *host; int flags; MemTxAttrs attrs; + bool tagged; } SVEHostPage; bool sve_probe_page(SVEHostPage *info, bool nofault, CPUARMState *env, diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c index 353edbeb1d..3462a6ea14 100644 --- a/target/arm/tlb_helper.c +++ b/target/arm/tlb_helper.c @@ -231,10 +231,6 @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size, res.f.phys_addr &= TARGET_PAGE_MASK; address &= TARGET_PAGE_MASK; } - /* Notice and record tagged memory. */ - if (cpu_isar_feature(aa64_mte, cpu) && res.cacheattrs.attrs == 0xf0) { - arm_tlb_mte_tagged(&res.f.attrs) = true; - } res.f.pte_attrs = res.cacheattrs.attrs; res.f.shareability = res.cacheattrs.shareability; From 937f2245596de9026ca8ae017ef47889523c4326 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 10 Oct 2022 20:18:50 -0700 Subject: [PATCH 005/705] target/arm: Use probe_access_full for BTI Add a field to TARGET_PAGE_ENTRY_EXTRA to hold the guarded bit. In is_guarded_page, use probe_access_full instead of just guessing that the tlb entry is still present. Also handles the FIXME about executing from device memory. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20221011031911.2408754-4-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/cpu-param.h | 9 +++++---- target/arm/cpu.h | 13 ------------- target/arm/internals.h | 1 + target/arm/ptw.c | 7 ++++--- target/arm/translate-a64.c | 21 ++++++++++----------- 5 files changed, 20 insertions(+), 31 deletions(-) diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h index 38347b0d20..f4338fd10e 100644 --- a/target/arm/cpu-param.h +++ b/target/arm/cpu-param.h @@ -36,12 +36,13 @@ * * For ARMMMUIdx_Stage2*, pte_attrs is the S2 descriptor bits [5:2]. * Otherwise, pte_attrs is the same as the MAIR_EL1 8-bit format. - * For shareability, as in the SH field of the VMSAv8-64 PTEs. + * For shareability and guarded, as in the SH and GP fields respectively + * of the VMSAv8-64 PTEs. */ # define TARGET_PAGE_ENTRY_EXTRA \ - uint8_t pte_attrs; \ - uint8_t shareability; - + uint8_t pte_attrs; \ + uint8_t shareability; \ + bool guarded; #endif #define NB_MMU_MODES 8 diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 9a358c410b..9df7adbe81 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -3388,19 +3388,6 @@ static inline uint64_t *aa64_vfp_qreg(CPUARMState *env, unsigned regno) /* Shared between translate-sve.c and sve_helper.c. */ extern const uint64_t pred_esz_masks[5]; -/* Helper for the macros below, validating the argument type. */ -static inline MemTxAttrs *typecheck_memtxattrs(MemTxAttrs *x) -{ - return x; -} - -/* - * Lvalue macros for ARM TLB bits that we must cache in the TCG TLB. - * Using these should be a bit more self-documenting than using the - * generic target bits directly. - */ -#define arm_tlb_bti_gp(x) (typecheck_memtxattrs(x)->target_tlb_bit0) - /* * AArch64 usage of the PAGE_TARGET_* bits for linux-user. * Note that with the Linux kernel, PROT_MTE may not be cleared by mprotect diff --git a/target/arm/internals.h b/target/arm/internals.h index 9566364dca..c3c3920ded 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -1095,6 +1095,7 @@ typedef struct ARMCacheAttrs { unsigned int attrs:8; unsigned int shareability:2; /* as in the SH field of the VMSAv8-64 PTEs */ bool is_s2_format:1; + bool guarded:1; /* guarded bit of the v8-64 PTE */ } ARMCacheAttrs; /* Fields that are valid upon success. */ diff --git a/target/arm/ptw.c b/target/arm/ptw.c index 23f16f4ff7..2d182d62e5 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -1313,9 +1313,10 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address, */ result->f.attrs.secure = false; } - /* When in aarch64 mode, and BTI is enabled, remember GP in the IOTLB. */ - if (aarch64 && guarded && cpu_isar_feature(aa64_bti, cpu)) { - arm_tlb_bti_gp(&result->f.attrs) = true; + + /* When in aarch64 mode, and BTI is enabled, remember GP in the TLB. */ + if (aarch64 && cpu_isar_feature(aa64_bti, cpu)) { + result->f.guarded = guarded; } if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) { diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index 5b67375f4e..60ff753d81 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -14601,22 +14601,21 @@ static bool is_guarded_page(CPUARMState *env, DisasContext *s) #ifdef CONFIG_USER_ONLY return page_get_flags(addr) & PAGE_BTI; #else + CPUTLBEntryFull *full; + void *host; int mmu_idx = arm_to_core_mmu_idx(s->mmu_idx); - unsigned int index = tlb_index(env, mmu_idx, addr); - CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr); + int flags; /* * We test this immediately after reading an insn, which means - * that any normal page must be in the TLB. The only exception - * would be for executing from flash or device memory, which - * does not retain the TLB entry. - * - * FIXME: Assume false for those, for now. We could use - * arm_cpu_get_phys_page_attrs_debug to re-read the page - * table entry even for that case. + * that the TLB entry must be present and valid, and thus this + * access will never raise an exception. */ - return (tlb_hit(entry->addr_code, addr) && - arm_tlb_bti_gp(&env_tlb(env)->d[mmu_idx].fulltlb[index].attrs)); + flags = probe_access_full(env, addr, MMU_INST_FETCH, mmu_idx, + false, &host, &full, 0); + assert(!(flags & TLB_INVALID_MASK)); + + return full->guarded; #endif } From a1ce3084c572e39d588a7978002d83fee01edd60 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 10 Oct 2022 20:18:51 -0700 Subject: [PATCH 006/705] target/arm: Add ARMMMUIdx_Phys_{S,NS} Not yet used, but add mmu indexes for 1-1 mapping to physical addresses. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20221011031911.2408754-5-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/cpu-param.h | 2 +- target/arm/cpu.h | 7 ++++++- target/arm/ptw.c | 19 +++++++++++++++++-- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h index f4338fd10e..a5b27db275 100644 --- a/target/arm/cpu-param.h +++ b/target/arm/cpu-param.h @@ -45,6 +45,6 @@ bool guarded; #endif -#define NB_MMU_MODES 8 +#define NB_MMU_MODES 10 #endif diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 9df7adbe81..b185f39bf5 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -2905,8 +2905,9 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync); * EL2 EL2&0 +PAN * EL2 (aka NS PL2) * EL3 (aka S PL1) + * Physical (NS & S) * - * for a total of 8 different mmu_idx. + * for a total of 10 different mmu_idx. * * R profile CPUs have an MPU, but can use the same set of MMU indexes * as A profile. They only need to distinguish EL0 and EL1 (and @@ -2971,6 +2972,10 @@ typedef enum ARMMMUIdx { ARMMMUIdx_E2 = 6 | ARM_MMU_IDX_A, ARMMMUIdx_E3 = 7 | ARM_MMU_IDX_A, + /* TLBs with 1-1 mapping to the physical address spaces. */ + ARMMMUIdx_Phys_NS = 8 | ARM_MMU_IDX_A, + ARMMMUIdx_Phys_S = 9 | ARM_MMU_IDX_A, + /* * These are not allocated TLBs and are used only for AT system * instructions or for the first stage of an S12 page table walk. diff --git a/target/arm/ptw.c b/target/arm/ptw.c index 2d182d62e5..a977d09c6d 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -179,6 +179,11 @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx, case ARMMMUIdx_E3: break; + case ARMMMUIdx_Phys_NS: + case ARMMMUIdx_Phys_S: + /* No translation for physical address spaces. */ + return true; + default: g_assert_not_reached(); } @@ -2280,10 +2285,17 @@ static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address, { uint8_t memattr = 0x00; /* Device nGnRnE */ uint8_t shareability = 0; /* non-sharable */ + int r_el; - if (mmu_idx != ARMMMUIdx_Stage2 && mmu_idx != ARMMMUIdx_Stage2_S) { - int r_el = regime_el(env, mmu_idx); + switch (mmu_idx) { + case ARMMMUIdx_Stage2: + case ARMMMUIdx_Stage2_S: + case ARMMMUIdx_Phys_NS: + case ARMMMUIdx_Phys_S: + break; + default: + r_el = regime_el(env, mmu_idx); if (arm_el_is_aa64(env, r_el)) { int pamax = arm_pamax(env_archcpu(env)); uint64_t tcr = env->cp15.tcr_el[r_el]; @@ -2332,6 +2344,7 @@ static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address, shareability = 2; /* outer sharable */ } result->cacheattrs.is_s2_format = false; + break; } result->f.phys_addr = address; @@ -2536,6 +2549,7 @@ bool get_phys_addr(CPUARMState *env, target_ulong address, is_secure = arm_is_secure_below_el3(env); break; case ARMMMUIdx_Stage2: + case ARMMMUIdx_Phys_NS: case ARMMMUIdx_MPrivNegPri: case ARMMMUIdx_MUserNegPri: case ARMMMUIdx_MPriv: @@ -2544,6 +2558,7 @@ bool get_phys_addr(CPUARMState *env, target_ulong address, break; case ARMMMUIdx_E3: case ARMMMUIdx_Stage2_S: + case ARMMMUIdx_Phys_S: case ARMMMUIdx_MSPrivNegPri: case ARMMMUIdx_MSUserNegPri: case ARMMMUIdx_MSPriv: From 575a94af3c113157cf749364a921336ddd346e9a Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 10 Oct 2022 20:18:52 -0700 Subject: [PATCH 007/705] target/arm: Move ARMMMUIdx_Stage2 to a real tlb mmu_idx We had been marking this ARM_MMU_IDX_NOTLB, move it to a real tlb. Flush the tlb when invalidating stage 1+2 translations. Re-use alle1_tlbmask() for other instances of EL1&0 + Stage2. Signed-off-by: Richard Henderson Reviewed-by: Peter Maydell Message-id: 20221011031911.2408754-6-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/cpu-param.h | 2 +- target/arm/cpu.h | 23 ++++--- target/arm/helper.c | 151 ++++++++++++++++++++++++++++++----------- 3 files changed, 127 insertions(+), 49 deletions(-) diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h index a5b27db275..b7bde18986 100644 --- a/target/arm/cpu-param.h +++ b/target/arm/cpu-param.h @@ -45,6 +45,6 @@ bool guarded; #endif -#define NB_MMU_MODES 10 +#define NB_MMU_MODES 12 #endif diff --git a/target/arm/cpu.h b/target/arm/cpu.h index b185f39bf5..315c1c2820 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -2906,8 +2906,9 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync); * EL2 (aka NS PL2) * EL3 (aka S PL1) * Physical (NS & S) + * Stage2 (NS & S) * - * for a total of 10 different mmu_idx. + * for a total of 12 different mmu_idx. * * R profile CPUs have an MPU, but can use the same set of MMU indexes * as A profile. They only need to distinguish EL0 and EL1 (and @@ -2976,6 +2977,15 @@ typedef enum ARMMMUIdx { ARMMMUIdx_Phys_NS = 8 | ARM_MMU_IDX_A, ARMMMUIdx_Phys_S = 9 | ARM_MMU_IDX_A, + /* + * Used for second stage of an S12 page table walk, or for descriptor + * loads during first stage of an S1 page table walk. Note that both + * are in use simultaneously for SecureEL2: the security state for + * the S2 ptw is selected by the NS bit from the S1 ptw. + */ + ARMMMUIdx_Stage2 = 10 | ARM_MMU_IDX_A, + ARMMMUIdx_Stage2_S = 11 | ARM_MMU_IDX_A, + /* * These are not allocated TLBs and are used only for AT system * instructions or for the first stage of an S12 page table walk. @@ -2983,15 +2993,6 @@ typedef enum ARMMMUIdx { ARMMMUIdx_Stage1_E0 = 0 | ARM_MMU_IDX_NOTLB, ARMMMUIdx_Stage1_E1 = 1 | ARM_MMU_IDX_NOTLB, ARMMMUIdx_Stage1_E1_PAN = 2 | ARM_MMU_IDX_NOTLB, - /* - * Not allocated a TLB: used only for second stage of an S12 page - * table walk, or for descriptor loads during first stage of an S1 - * page table walk. Note that if we ever want to have a TLB for this - * then various TLB flush insns which currently are no-ops or flush - * only stage 1 MMU indexes will need to change to flush stage 2. - */ - ARMMMUIdx_Stage2 = 3 | ARM_MMU_IDX_NOTLB, - ARMMMUIdx_Stage2_S = 4 | ARM_MMU_IDX_NOTLB, /* * M-profile. @@ -3022,6 +3023,8 @@ typedef enum ARMMMUIdxBit { TO_CORE_BIT(E20_2), TO_CORE_BIT(E20_2_PAN), TO_CORE_BIT(E3), + TO_CORE_BIT(Stage2), + TO_CORE_BIT(Stage2_S), TO_CORE_BIT(MUser), TO_CORE_BIT(MPriv), diff --git a/target/arm/helper.c b/target/arm/helper.c index dde64a487a..18c51bb777 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -399,6 +399,21 @@ static void contextidr_write(CPUARMState *env, const ARMCPRegInfo *ri, raw_write(env, ri, value); } +static int alle1_tlbmask(CPUARMState *env) +{ + /* + * Note that the 'ALL' scope must invalidate both stage 1 and + * stage 2 translations, whereas most other scopes only invalidate + * stage 1 translations. + */ + return (ARMMMUIdxBit_E10_1 | + ARMMMUIdxBit_E10_1_PAN | + ARMMMUIdxBit_E10_0 | + ARMMMUIdxBit_Stage2 | + ARMMMUIdxBit_Stage2_S); +} + + /* IS variants of TLB operations must affect all cores */ static void tlbiall_is_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) @@ -501,10 +516,7 @@ static void tlbiall_nsnh_write(CPUARMState *env, const ARMCPRegInfo *ri, { CPUState *cs = env_cpu(env); - tlb_flush_by_mmuidx(cs, - ARMMMUIdxBit_E10_1 | - ARMMMUIdxBit_E10_1_PAN | - ARMMMUIdxBit_E10_0); + tlb_flush_by_mmuidx(cs, alle1_tlbmask(env)); } static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri, @@ -512,10 +524,7 @@ static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri, { CPUState *cs = env_cpu(env); - tlb_flush_by_mmuidx_all_cpus_synced(cs, - ARMMMUIdxBit_E10_1 | - ARMMMUIdxBit_E10_1_PAN | - ARMMMUIdxBit_E10_0); + tlb_flush_by_mmuidx_all_cpus_synced(cs, alle1_tlbmask(env)); } @@ -554,6 +563,24 @@ static void tlbimva_hyp_is_write(CPUARMState *env, const ARMCPRegInfo *ri, ARMMMUIdxBit_E2); } +static void tlbiipas2_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + CPUState *cs = env_cpu(env); + uint64_t pageaddr = (value & MAKE_64BIT_MASK(0, 28)) << 12; + + tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_Stage2); +} + +static void tlbiipas2is_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + CPUState *cs = env_cpu(env); + uint64_t pageaddr = (value & MAKE_64BIT_MASK(0, 28)) << 12; + + tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr, ARMMMUIdxBit_Stage2); +} + static const ARMCPRegInfo cp_reginfo[] = { /* Define the secure and non-secure FCSE identifier CP registers * separately because there is no secure bank in V8 (no _EL3). This allows @@ -3786,13 +3813,10 @@ static void vttbr_write(CPUARMState *env, const ARMCPRegInfo *ri, /* * A change in VMID to the stage2 page table (Stage2) invalidates - * the combined stage 1&2 tlbs (EL10_1 and EL10_0). + * the stage2 and combined stage 1&2 tlbs (EL10_1 and EL10_0). */ if (raw_read(env, ri) != value) { - uint16_t mask = ARMMMUIdxBit_E10_1 | - ARMMMUIdxBit_E10_1_PAN | - ARMMMUIdxBit_E10_0; - tlb_flush_by_mmuidx(cs, mask); + tlb_flush_by_mmuidx(cs, alle1_tlbmask(env)); raw_write(env, ri, value); } } @@ -4313,18 +4337,6 @@ static void tlbi_aa64_vmalle1_write(CPUARMState *env, const ARMCPRegInfo *ri, } } -static int alle1_tlbmask(CPUARMState *env) -{ - /* - * Note that the 'ALL' scope must invalidate both stage 1 and - * stage 2 translations, whereas most other scopes only invalidate - * stage 1 translations. - */ - return (ARMMMUIdxBit_E10_1 | - ARMMMUIdxBit_E10_1_PAN | - ARMMMUIdxBit_E10_0); -} - static int e2_tlbmask(CPUARMState *env) { return (ARMMMUIdxBit_E20_0 | @@ -4467,6 +4479,43 @@ static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri, ARMMMUIdxBit_E3, bits); } +static int ipas2e1_tlbmask(CPUARMState *env, int64_t value) +{ + /* + * The MSB of value is the NS field, which only applies if SEL2 + * is implemented and SCR_EL3.NS is not set (i.e. in secure mode). + */ + return (value >= 0 + && cpu_isar_feature(aa64_sel2, env_archcpu(env)) + && arm_is_secure_below_el3(env) + ? ARMMMUIdxBit_Stage2_S + : ARMMMUIdxBit_Stage2); +} + +static void tlbi_aa64_ipas2e1_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + CPUState *cs = env_cpu(env); + int mask = ipas2e1_tlbmask(env, value); + uint64_t pageaddr = sextract64(value << 12, 0, 56); + + if (tlb_force_broadcast(env)) { + tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr, mask); + } else { + tlb_flush_page_by_mmuidx(cs, pageaddr, mask); + } +} + +static void tlbi_aa64_ipas2e1is_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + CPUState *cs = env_cpu(env); + int mask = ipas2e1_tlbmask(env, value); + uint64_t pageaddr = sextract64(value << 12, 0, 56); + + tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr, mask); +} + #ifdef TARGET_AARCH64 typedef struct { uint64_t base; @@ -4652,6 +4701,20 @@ static void tlbi_aa64_rvae3is_write(CPUARMState *env, do_rvae_write(env, value, ARMMMUIdxBit_E3, true); } + +static void tlbi_aa64_ripas2e1_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + do_rvae_write(env, value, ipas2e1_tlbmask(env, value), + tlb_force_broadcast(env)); +} + +static void tlbi_aa64_ripas2e1is_write(CPUARMState *env, + const ARMCPRegInfo *ri, + uint64_t value) +{ + do_rvae_write(env, value, ipas2e1_tlbmask(env, value), true); +} #endif static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri, @@ -4930,10 +4993,12 @@ static const ARMCPRegInfo v8_cp_reginfo[] = { .writefn = tlbi_aa64_vae1_write }, { .name = "TLBI_IPAS2E1IS", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1, - .access = PL2_W, .type = ARM_CP_NOP }, + .access = PL2_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_ipas2e1is_write }, { .name = "TLBI_IPAS2LE1IS", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5, - .access = PL2_W, .type = ARM_CP_NOP }, + .access = PL2_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_ipas2e1is_write }, { .name = "TLBI_ALLE1IS", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4, .access = PL2_W, .type = ARM_CP_NO_RAW, @@ -4944,10 +5009,12 @@ static const ARMCPRegInfo v8_cp_reginfo[] = { .writefn = tlbi_aa64_alle1is_write }, { .name = "TLBI_IPAS2E1", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1, - .access = PL2_W, .type = ARM_CP_NOP }, + .access = PL2_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_ipas2e1_write }, { .name = "TLBI_IPAS2LE1", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5, - .access = PL2_W, .type = ARM_CP_NOP }, + .access = PL2_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_ipas2e1_write }, { .name = "TLBI_ALLE1", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4, .access = PL2_W, .type = ARM_CP_NO_RAW, @@ -5028,16 +5095,20 @@ static const ARMCPRegInfo v8_cp_reginfo[] = { .writefn = tlbimva_hyp_is_write }, { .name = "TLBIIPAS2", .cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1, - .type = ARM_CP_NOP, .access = PL2_W }, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbiipas2_hyp_write }, { .name = "TLBIIPAS2IS", .cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1, - .type = ARM_CP_NOP, .access = PL2_W }, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbiipas2is_hyp_write }, { .name = "TLBIIPAS2L", .cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5, - .type = ARM_CP_NOP, .access = PL2_W }, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbiipas2_hyp_write }, { .name = "TLBIIPAS2LIS", .cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5, - .type = ARM_CP_NOP, .access = PL2_W }, + .type = ARM_CP_NO_RAW, .access = PL2_W, + .writefn = tlbiipas2is_hyp_write }, /* 32 bit cache operations */ { .name = "ICIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0, .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_pou_access }, @@ -6694,10 +6765,12 @@ static const ARMCPRegInfo tlbirange_reginfo[] = { .writefn = tlbi_aa64_rvae1_write }, { .name = "TLBI_RIPAS2E1IS", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 2, - .access = PL2_W, .type = ARM_CP_NOP }, + .access = PL2_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_ripas2e1is_write }, { .name = "TLBI_RIPAS2LE1IS", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 6, - .access = PL2_W, .type = ARM_CP_NOP }, + .access = PL2_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_ripas2e1is_write }, { .name = "TLBI_RVAE2IS", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 2, .opc2 = 1, .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF, @@ -6708,10 +6781,12 @@ static const ARMCPRegInfo tlbirange_reginfo[] = { .writefn = tlbi_aa64_rvae2is_write }, { .name = "TLBI_RIPAS2E1", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 2, - .access = PL2_W, .type = ARM_CP_NOP }, - { .name = "TLBI_RIPAS2LE1", .state = ARM_CP_STATE_AA64, + .access = PL2_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_ripas2e1_write }, + { .name = "TLBI_RIPAS2LE1", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 6, - .access = PL2_W, .type = ARM_CP_NOP }, + .access = PL2_W, .type = ARM_CP_NO_RAW, + .writefn = tlbi_aa64_ripas2e1_write }, { .name = "TLBI_RVAE2OS", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 5, .opc2 = 1, .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF, From 00b20ee42ea97f2329779851a7f8a290712109ee Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 10 Oct 2022 20:18:53 -0700 Subject: [PATCH 008/705] target/arm: Restrict tlb flush from vttbr_write to vmid change Compare only the VMID field when considering whether we need to flush. Signed-off-by: Richard Henderson Reviewed-by: Peter Maydell Message-id: 20221011031911.2408754-7-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/helper.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index 18c51bb777..c672903f43 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -3815,10 +3815,10 @@ static void vttbr_write(CPUARMState *env, const ARMCPRegInfo *ri, * A change in VMID to the stage2 page table (Stage2) invalidates * the stage2 and combined stage 1&2 tlbs (EL10_1 and EL10_0). */ - if (raw_read(env, ri) != value) { + if (extract64(raw_read(env, ri) ^ value, 48, 16) != 0) { tlb_flush_by_mmuidx(cs, alle1_tlbmask(env)); - raw_write(env, ri, value); } + raw_write(env, ri, value); } static const ARMCPRegInfo vmsa_pmsa_cp_reginfo[] = { From 6d2654ffacea813916176c5df27958098b20af6a Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 10 Oct 2022 20:18:54 -0700 Subject: [PATCH 009/705] target/arm: Split out S1Translate type Consolidate most of the inputs and outputs of S1_ptw_translate into a single structure. Plumb this through arm_ld*_ptw from the controlling get_phys_addr_* routine. Signed-off-by: Richard Henderson Reviewed-by: Peter Maydell Message-id: 20221011031911.2408754-8-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/ptw.c | 140 ++++++++++++++++++++++++++--------------------- 1 file changed, 79 insertions(+), 61 deletions(-) diff --git a/target/arm/ptw.c b/target/arm/ptw.c index a977d09c6d..dee69ee743 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -14,9 +14,16 @@ #include "idau.h" -static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address, - MMUAccessType access_type, ARMMMUIdx mmu_idx, - bool is_secure, bool s1_is_el0, +typedef struct S1Translate { + ARMMMUIdx in_mmu_idx; + bool in_secure; + bool out_secure; + hwaddr out_phys; +} S1Translate; + +static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, + uint64_t address, + MMUAccessType access_type, bool s1_is_el0, GetPhysAddrResult *result, ARMMMUFaultInfo *fi) __attribute__((nonnull)); @@ -211,28 +218,31 @@ static bool ptw_attrs_are_device(uint64_t hcr, ARMCacheAttrs cacheattrs) } /* Translate a S1 pagetable walk through S2 if needed. */ -static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx, - hwaddr addr, bool *is_secure_ptr, - ARMMMUFaultInfo *fi) +static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw, + hwaddr addr, ARMMMUFaultInfo *fi) { - bool is_secure = *is_secure_ptr; + bool is_secure = ptw->in_secure; ARMMMUIdx s2_mmu_idx = is_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2; - if (arm_mmu_idx_is_stage1_of_2(mmu_idx) && + if (arm_mmu_idx_is_stage1_of_2(ptw->in_mmu_idx) && !regime_translation_disabled(env, s2_mmu_idx, is_secure)) { GetPhysAddrResult s2 = {}; + S1Translate s2ptw = { + .in_mmu_idx = s2_mmu_idx, + .in_secure = is_secure, + }; uint64_t hcr; int ret; - ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, s2_mmu_idx, - is_secure, false, &s2, fi); + ret = get_phys_addr_lpae(env, &s2ptw, addr, MMU_DATA_LOAD, + false, &s2, fi); if (ret) { assert(fi->type != ARMFault_None); fi->s2addr = addr; fi->stage2 = true; fi->s1ptw = true; fi->s1ns = !is_secure; - return ~0; + return false; } hcr = arm_hcr_el2_eff_secstate(env, is_secure); @@ -246,7 +256,7 @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx, fi->stage2 = true; fi->s1ptw = true; fi->s1ns = !is_secure; - return ~0; + return false; } if (arm_is_secure_below_el3(env)) { @@ -256,19 +266,21 @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx, } else { is_secure = !(env->cp15.vtcr_el2 & VTCR_NSW); } - *is_secure_ptr = is_secure; } else { assert(!is_secure); } addr = s2.f.phys_addr; } - return addr; + + ptw->out_secure = is_secure; + ptw->out_phys = addr; + return true; } /* All loads done in the course of a page table walk go through here. */ -static uint32_t arm_ldl_ptw(CPUARMState *env, hwaddr addr, bool is_secure, - ARMMMUIdx mmu_idx, ARMMMUFaultInfo *fi) +static uint32_t arm_ldl_ptw(CPUARMState *env, S1Translate *ptw, hwaddr addr, + ARMMMUFaultInfo *fi) { CPUState *cs = env_cpu(env); MemTxAttrs attrs = {}; @@ -276,13 +288,13 @@ static uint32_t arm_ldl_ptw(CPUARMState *env, hwaddr addr, bool is_secure, AddressSpace *as; uint32_t data; - addr = S1_ptw_translate(env, mmu_idx, addr, &is_secure, fi); - attrs.secure = is_secure; - as = arm_addressspace(cs, attrs); - if (fi->s1ptw) { + if (!S1_ptw_translate(env, ptw, addr, fi)) { return 0; } - if (regime_translation_big_endian(env, mmu_idx)) { + addr = ptw->out_phys; + attrs.secure = ptw->out_secure; + as = arm_addressspace(cs, attrs); + if (regime_translation_big_endian(env, ptw->in_mmu_idx)) { data = address_space_ldl_be(as, addr, attrs, &result); } else { data = address_space_ldl_le(as, addr, attrs, &result); @@ -295,8 +307,8 @@ static uint32_t arm_ldl_ptw(CPUARMState *env, hwaddr addr, bool is_secure, return 0; } -static uint64_t arm_ldq_ptw(CPUARMState *env, hwaddr addr, bool is_secure, - ARMMMUIdx mmu_idx, ARMMMUFaultInfo *fi) +static uint64_t arm_ldq_ptw(CPUARMState *env, S1Translate *ptw, hwaddr addr, + ARMMMUFaultInfo *fi) { CPUState *cs = env_cpu(env); MemTxAttrs attrs = {}; @@ -304,13 +316,13 @@ static uint64_t arm_ldq_ptw(CPUARMState *env, hwaddr addr, bool is_secure, AddressSpace *as; uint64_t data; - addr = S1_ptw_translate(env, mmu_idx, addr, &is_secure, fi); - attrs.secure = is_secure; - as = arm_addressspace(cs, attrs); - if (fi->s1ptw) { + if (!S1_ptw_translate(env, ptw, addr, fi)) { return 0; } - if (regime_translation_big_endian(env, mmu_idx)) { + addr = ptw->out_phys; + attrs.secure = ptw->out_secure; + as = arm_addressspace(cs, attrs); + if (regime_translation_big_endian(env, ptw->in_mmu_idx)) { data = address_space_ldq_be(as, addr, attrs, &result); } else { data = address_space_ldq_le(as, addr, attrs, &result); @@ -431,10 +443,9 @@ static int simple_ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx, int ap) return simple_ap_to_rw_prot_is_user(ap, regime_is_user(env, mmu_idx)); } -static bool get_phys_addr_v5(CPUARMState *env, uint32_t address, - MMUAccessType access_type, ARMMMUIdx mmu_idx, - bool is_secure, GetPhysAddrResult *result, - ARMMMUFaultInfo *fi) +static bool get_phys_addr_v5(CPUARMState *env, S1Translate *ptw, + uint32_t address, MMUAccessType access_type, + GetPhysAddrResult *result, ARMMMUFaultInfo *fi) { int level = 1; uint32_t table; @@ -448,18 +459,18 @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address, /* Pagetable walk. */ /* Lookup l1 descriptor. */ - if (!get_level1_table_address(env, mmu_idx, &table, address)) { + if (!get_level1_table_address(env, ptw->in_mmu_idx, &table, address)) { /* Section translation fault if page walk is disabled by PD0 or PD1 */ fi->type = ARMFault_Translation; goto do_fault; } - desc = arm_ldl_ptw(env, table, is_secure, mmu_idx, fi); + desc = arm_ldl_ptw(env, ptw, table, fi); if (fi->type != ARMFault_None) { goto do_fault; } type = (desc & 3); domain = (desc >> 5) & 0x0f; - if (regime_el(env, mmu_idx) == 1) { + if (regime_el(env, ptw->in_mmu_idx) == 1) { dacr = env->cp15.dacr_ns; } else { dacr = env->cp15.dacr_s; @@ -491,7 +502,7 @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address, /* Fine pagetable. */ table = (desc & 0xfffff000) | ((address >> 8) & 0xffc); } - desc = arm_ldl_ptw(env, table, is_secure, mmu_idx, fi); + desc = arm_ldl_ptw(env, ptw, table, fi); if (fi->type != ARMFault_None) { goto do_fault; } @@ -535,7 +546,7 @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address, g_assert_not_reached(); } } - result->f.prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot); + result->f.prot = ap_to_rw_prot(env, ptw->in_mmu_idx, ap, domain_prot); result->f.prot |= result->f.prot ? PAGE_EXEC : 0; if (!(result->f.prot & (1 << access_type))) { /* Access permission fault. */ @@ -550,12 +561,12 @@ do_fault: return true; } -static bool get_phys_addr_v6(CPUARMState *env, uint32_t address, - MMUAccessType access_type, ARMMMUIdx mmu_idx, - bool is_secure, GetPhysAddrResult *result, - ARMMMUFaultInfo *fi) +static bool get_phys_addr_v6(CPUARMState *env, S1Translate *ptw, + uint32_t address, MMUAccessType access_type, + GetPhysAddrResult *result, ARMMMUFaultInfo *fi) { ARMCPU *cpu = env_archcpu(env); + ARMMMUIdx mmu_idx = ptw->in_mmu_idx; int level = 1; uint32_t table; uint32_t desc; @@ -576,7 +587,7 @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address, fi->type = ARMFault_Translation; goto do_fault; } - desc = arm_ldl_ptw(env, table, is_secure, mmu_idx, fi); + desc = arm_ldl_ptw(env, ptw, table, fi); if (fi->type != ARMFault_None) { goto do_fault; } @@ -629,7 +640,7 @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address, ns = extract32(desc, 3, 1); /* Lookup l2 entry. */ table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc); - desc = arm_ldl_ptw(env, table, is_secure, mmu_idx, fi); + desc = arm_ldl_ptw(env, ptw, table, fi); if (fi->type != ARMFault_None) { goto do_fault; } @@ -972,22 +983,25 @@ static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level, * the WnR bit is never set (the caller must do this). * * @env: CPUARMState + * @ptw: Current and next stage parameters for the walk. * @address: virtual address to get physical address for * @access_type: MMU_DATA_LOAD, MMU_DATA_STORE or MMU_INST_FETCH - * @mmu_idx: MMU index indicating required translation regime - * @s1_is_el0: if @mmu_idx is ARMMMUIdx_Stage2 (so this is a stage 2 page - * table walk), must be true if this is stage 2 of a stage 1+2 + * @s1_is_el0: if @ptw->in_mmu_idx is ARMMMUIdx_Stage2 + * (so this is a stage 2 page table walk), + * must be true if this is stage 2 of a stage 1+2 * walk for an EL0 access. If @mmu_idx is anything else, * @s1_is_el0 is ignored. * @result: set on translation success, * @fi: set to fault info if the translation fails */ -static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address, - MMUAccessType access_type, ARMMMUIdx mmu_idx, - bool is_secure, bool s1_is_el0, +static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, + uint64_t address, + MMUAccessType access_type, bool s1_is_el0, GetPhysAddrResult *result, ARMMMUFaultInfo *fi) { ARMCPU *cpu = env_archcpu(env); + ARMMMUIdx mmu_idx = ptw->in_mmu_idx; + bool is_secure = ptw->in_secure; /* Read an LPAE long-descriptor translation table. */ ARMFaultType fault_type = ARMFault_Translation; uint32_t level; @@ -1204,7 +1218,8 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address, descaddr |= (address >> (stride * (4 - level))) & indexmask; descaddr &= ~7ULL; nstable = extract32(tableattrs, 4, 1); - descriptor = arm_ldq_ptw(env, descaddr, !nstable, mmu_idx, fi); + ptw->in_secure = !nstable; + descriptor = arm_ldq_ptw(env, ptw, descaddr, fi); if (fi->type != ARMFault_None) { goto do_fault; } @@ -2361,6 +2376,7 @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address, ARMMMUFaultInfo *fi) { ARMMMUIdx s1_mmu_idx = stage_1_mmu_idx(mmu_idx); + S1Translate ptw; if (mmu_idx != s1_mmu_idx) { /* @@ -2373,7 +2389,6 @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address, int ret; bool ipa_secure, s2walk_secure; ARMCacheAttrs cacheattrs1; - ARMMMUIdx s2_mmu_idx; bool is_el0; uint64_t hcr; @@ -2398,8 +2413,9 @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address, s2walk_secure = false; } - s2_mmu_idx = (s2walk_secure - ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2); + ptw.in_mmu_idx = + s2walk_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2; + ptw.in_secure = s2walk_secure; is_el0 = mmu_idx == ARMMMUIdx_E10_0; /* @@ -2411,8 +2427,8 @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address, cacheattrs1 = result->cacheattrs; memset(result, 0, sizeof(*result)); - ret = get_phys_addr_lpae(env, ipa, access_type, s2_mmu_idx, - s2walk_secure, is_el0, result, fi); + ret = get_phys_addr_lpae(env, &ptw, ipa, access_type, + is_el0, result, fi); fi->s2addr = ipa; /* Combine the S1 and S2 perms. */ @@ -2517,15 +2533,17 @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address, return get_phys_addr_disabled(env, address, access_type, mmu_idx, is_secure, result, fi); } + + ptw.in_mmu_idx = mmu_idx; + ptw.in_secure = is_secure; + if (regime_using_lpae_format(env, mmu_idx)) { - return get_phys_addr_lpae(env, address, access_type, mmu_idx, - is_secure, false, result, fi); + return get_phys_addr_lpae(env, &ptw, address, access_type, false, + result, fi); } else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) { - return get_phys_addr_v6(env, address, access_type, mmu_idx, - is_secure, result, fi); + return get_phys_addr_v6(env, &ptw, address, access_type, result, fi); } else { - return get_phys_addr_v5(env, address, access_type, mmu_idx, - is_secure, result, fi); + return get_phys_addr_v5(env, &ptw, address, access_type, result, fi); } } From 4a35855682cebb89f9630b07aa9fd37c4e8c733b Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 10 Oct 2022 20:18:55 -0700 Subject: [PATCH 010/705] target/arm: Plumb debug into S1Translate Before using softmmu page tables for the ptw, plumb down a debug parameter so that we can query page table entries from gdbstub without modifying cpu state. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20221011031911.2408754-9-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/ptw.c | 55 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/target/arm/ptw.c b/target/arm/ptw.c index dee69ee743..8fa0088d98 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -17,6 +17,7 @@ typedef struct S1Translate { ARMMMUIdx in_mmu_idx; bool in_secure; + bool in_debug; bool out_secure; hwaddr out_phys; } S1Translate; @@ -230,6 +231,7 @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw, S1Translate s2ptw = { .in_mmu_idx = s2_mmu_idx, .in_secure = is_secure, + .in_debug = ptw->in_debug, }; uint64_t hcr; int ret; @@ -2370,13 +2372,15 @@ static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address, return 0; } -bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address, - MMUAccessType access_type, ARMMMUIdx mmu_idx, - bool is_secure, GetPhysAddrResult *result, - ARMMMUFaultInfo *fi) +static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw, + target_ulong address, + MMUAccessType access_type, + GetPhysAddrResult *result, + ARMMMUFaultInfo *fi) { + ARMMMUIdx mmu_idx = ptw->in_mmu_idx; ARMMMUIdx s1_mmu_idx = stage_1_mmu_idx(mmu_idx); - S1Translate ptw; + bool is_secure = ptw->in_secure; if (mmu_idx != s1_mmu_idx) { /* @@ -2392,8 +2396,9 @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address, bool is_el0; uint64_t hcr; - ret = get_phys_addr_with_secure(env, address, access_type, - s1_mmu_idx, is_secure, result, fi); + ptw->in_mmu_idx = s1_mmu_idx; + ret = get_phys_addr_with_struct(env, ptw, address, access_type, + result, fi); /* If S1 fails or S2 is disabled, return early. */ if (ret || regime_translation_disabled(env, ARMMMUIdx_Stage2, @@ -2413,9 +2418,9 @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address, s2walk_secure = false; } - ptw.in_mmu_idx = + ptw->in_mmu_idx = s2walk_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2; - ptw.in_secure = s2walk_secure; + ptw->in_secure = s2walk_secure; is_el0 = mmu_idx == ARMMMUIdx_E10_0; /* @@ -2427,7 +2432,7 @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address, cacheattrs1 = result->cacheattrs; memset(result, 0, sizeof(*result)); - ret = get_phys_addr_lpae(env, &ptw, ipa, access_type, + ret = get_phys_addr_lpae(env, ptw, ipa, access_type, is_el0, result, fi); fi->s2addr = ipa; @@ -2534,19 +2539,29 @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address, is_secure, result, fi); } - ptw.in_mmu_idx = mmu_idx; - ptw.in_secure = is_secure; - if (regime_using_lpae_format(env, mmu_idx)) { - return get_phys_addr_lpae(env, &ptw, address, access_type, false, + return get_phys_addr_lpae(env, ptw, address, access_type, false, result, fi); } else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) { - return get_phys_addr_v6(env, &ptw, address, access_type, result, fi); + return get_phys_addr_v6(env, ptw, address, access_type, result, fi); } else { - return get_phys_addr_v5(env, &ptw, address, access_type, result, fi); + return get_phys_addr_v5(env, ptw, address, access_type, result, fi); } } +bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address, + MMUAccessType access_type, ARMMMUIdx mmu_idx, + bool is_secure, GetPhysAddrResult *result, + ARMMMUFaultInfo *fi) +{ + S1Translate ptw = { + .in_mmu_idx = mmu_idx, + .in_secure = is_secure, + }; + return get_phys_addr_with_struct(env, &ptw, address, access_type, + result, fi); +} + bool get_phys_addr(CPUARMState *env, target_ulong address, MMUAccessType access_type, ARMMMUIdx mmu_idx, GetPhysAddrResult *result, ARMMMUFaultInfo *fi) @@ -2595,12 +2610,16 @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr, { ARMCPU *cpu = ARM_CPU(cs); CPUARMState *env = &cpu->env; + S1Translate ptw = { + .in_mmu_idx = arm_mmu_idx(env), + .in_secure = arm_is_secure(env), + .in_debug = true, + }; GetPhysAddrResult res = {}; ARMMMUFaultInfo fi = {}; - ARMMMUIdx mmu_idx = arm_mmu_idx(env); bool ret; - ret = get_phys_addr(env, addr, MMU_DATA_LOAD, mmu_idx, &res, &fi); + ret = get_phys_addr_with_struct(env, &ptw, addr, MMU_DATA_LOAD, &res, &fi); *attrs = res.f.attrs; if (ret) { From 4e7a2c9860eabd21376da522ef11e6b39fe36f85 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 10 Oct 2022 20:18:56 -0700 Subject: [PATCH 011/705] target/arm: Move be test for regime into S1TranslateResult Hoist this test out of arm_ld[lq]_ptw into S1_ptw_translate. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20221011031911.2408754-10-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/ptw.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/target/arm/ptw.c b/target/arm/ptw.c index 8fa0088d98..c58788ac69 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -19,6 +19,7 @@ typedef struct S1Translate { bool in_secure; bool in_debug; bool out_secure; + bool out_be; hwaddr out_phys; } S1Translate; @@ -277,6 +278,7 @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw, ptw->out_secure = is_secure; ptw->out_phys = addr; + ptw->out_be = regime_translation_big_endian(env, ptw->in_mmu_idx); return true; } @@ -296,7 +298,7 @@ static uint32_t arm_ldl_ptw(CPUARMState *env, S1Translate *ptw, hwaddr addr, addr = ptw->out_phys; attrs.secure = ptw->out_secure; as = arm_addressspace(cs, attrs); - if (regime_translation_big_endian(env, ptw->in_mmu_idx)) { + if (ptw->out_be) { data = address_space_ldl_be(as, addr, attrs, &result); } else { data = address_space_ldl_le(as, addr, attrs, &result); @@ -324,7 +326,7 @@ static uint64_t arm_ldq_ptw(CPUARMState *env, S1Translate *ptw, hwaddr addr, addr = ptw->out_phys; attrs.secure = ptw->out_secure; as = arm_addressspace(cs, attrs); - if (regime_translation_big_endian(env, ptw->in_mmu_idx)) { + if (ptw->out_be) { data = address_space_ldq_be(as, addr, attrs, &result); } else { data = address_space_ldq_le(as, addr, attrs, &result); From f3639a64f602ea5c1436eb9c9b89f42028e3a4a8 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 10 Oct 2022 20:18:57 -0700 Subject: [PATCH 012/705] target/arm: Use softmmu tlbs for page table walking So far, limit the change to S1_ptw_translate, arm_ldl_ptw, and arm_ldq_ptw. Use probe_access_full to find the host address, and if so use a host load. If the probe fails, we've got our fault info already. On the off chance that page tables are not in RAM, continue to use the address_space_ld* functions. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20221011031911.2408754-11-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/cpu.h | 5 + target/arm/ptw.c | 196 +++++++++++++++++++++++++--------------- target/arm/tlb_helper.c | 17 +++- 3 files changed, 144 insertions(+), 74 deletions(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 315c1c2820..64fc03214c 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -225,6 +225,8 @@ typedef struct CPUARMTBFlags { target_ulong flags2; } CPUARMTBFlags; +typedef struct ARMMMUFaultInfo ARMMMUFaultInfo; + typedef struct CPUArchState { /* Regs for current mode. */ uint32_t regs[16]; @@ -715,6 +717,9 @@ typedef struct CPUArchState { struct CPUBreakpoint *cpu_breakpoint[16]; struct CPUWatchpoint *cpu_watchpoint[16]; + /* Optional fault info across tlb lookup. */ + ARMMMUFaultInfo *tlb_fi; + /* Fields up to this point are cleared by a CPU reset */ struct {} end_reset_fields; diff --git a/target/arm/ptw.c b/target/arm/ptw.c index c58788ac69..8f41d285b7 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -9,6 +9,7 @@ #include "qemu/osdep.h" #include "qemu/log.h" #include "qemu/range.h" +#include "exec/exec-all.h" #include "cpu.h" #include "internals.h" #include "idau.h" @@ -21,6 +22,7 @@ typedef struct S1Translate { bool out_secure; bool out_be; hwaddr out_phys; + void *out_host; } S1Translate; static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, @@ -200,7 +202,7 @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx, return (regime_sctlr(env, mmu_idx) & SCTLR_M) == 0; } -static bool ptw_attrs_are_device(uint64_t hcr, ARMCacheAttrs cacheattrs) +static bool S2_attrs_are_device(uint64_t hcr, uint8_t attrs) { /* * For an S1 page table walk, the stage 1 attributes are always @@ -211,11 +213,10 @@ static bool ptw_attrs_are_device(uint64_t hcr, ARMCacheAttrs cacheattrs) * With HCR_EL2.FWB == 1 this is when descriptor bit [4] is 0, ie * when cacheattrs.attrs bit [2] is 0. */ - assert(cacheattrs.is_s2_format); if (hcr & HCR_FWB) { - return (cacheattrs.attrs & 0x4) == 0; + return (attrs & 0x4) == 0; } else { - return (cacheattrs.attrs & 0xc) == 0; + return (attrs & 0xc) == 0; } } @@ -224,32 +225,65 @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw, hwaddr addr, ARMMMUFaultInfo *fi) { bool is_secure = ptw->in_secure; + ARMMMUIdx mmu_idx = ptw->in_mmu_idx; ARMMMUIdx s2_mmu_idx = is_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2; + bool s2_phys = false; + uint8_t pte_attrs; + bool pte_secure; - if (arm_mmu_idx_is_stage1_of_2(ptw->in_mmu_idx) && - !regime_translation_disabled(env, s2_mmu_idx, is_secure)) { - GetPhysAddrResult s2 = {}; - S1Translate s2ptw = { - .in_mmu_idx = s2_mmu_idx, - .in_secure = is_secure, - .in_debug = ptw->in_debug, - }; - uint64_t hcr; - int ret; + if (!arm_mmu_idx_is_stage1_of_2(mmu_idx) + || regime_translation_disabled(env, s2_mmu_idx, is_secure)) { + s2_mmu_idx = is_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS; + s2_phys = true; + } - ret = get_phys_addr_lpae(env, &s2ptw, addr, MMU_DATA_LOAD, - false, &s2, fi); - if (ret) { - assert(fi->type != ARMFault_None); - fi->s2addr = addr; - fi->stage2 = true; - fi->s1ptw = true; - fi->s1ns = !is_secure; - return false; + if (unlikely(ptw->in_debug)) { + /* + * From gdbstub, do not use softmmu so that we don't modify the + * state of the cpu at all, including softmmu tlb contents. + */ + if (s2_phys) { + ptw->out_phys = addr; + pte_attrs = 0; + pte_secure = is_secure; + } else { + S1Translate s2ptw = { + .in_mmu_idx = s2_mmu_idx, + .in_secure = is_secure, + .in_debug = true, + }; + GetPhysAddrResult s2 = { }; + if (!get_phys_addr_lpae(env, &s2ptw, addr, MMU_DATA_LOAD, + false, &s2, fi)) { + goto fail; + } + ptw->out_phys = s2.f.phys_addr; + pte_attrs = s2.cacheattrs.attrs; + pte_secure = s2.f.attrs.secure; } + ptw->out_host = NULL; + } else { + CPUTLBEntryFull *full; + int flags; - hcr = arm_hcr_el2_eff_secstate(env, is_secure); - if ((hcr & HCR_PTW) && ptw_attrs_are_device(hcr, s2.cacheattrs)) { + env->tlb_fi = fi; + flags = probe_access_full(env, addr, MMU_DATA_LOAD, + arm_to_core_mmu_idx(s2_mmu_idx), + true, &ptw->out_host, &full, 0); + env->tlb_fi = NULL; + + if (unlikely(flags & TLB_INVALID_MASK)) { + goto fail; + } + ptw->out_phys = full->phys_addr; + pte_attrs = full->pte_attrs; + pte_secure = full->attrs.secure; + } + + if (!s2_phys) { + uint64_t hcr = arm_hcr_el2_eff_secstate(env, is_secure); + + if ((hcr & HCR_PTW) && S2_attrs_are_device(hcr, pte_attrs)) { /* * PTW set and S1 walk touched S2 Device memory: * generate Permission fault. @@ -261,25 +295,23 @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw, fi->s1ns = !is_secure; return false; } - - if (arm_is_secure_below_el3(env)) { - /* Check if page table walk is to secure or non-secure PA space. */ - if (is_secure) { - is_secure = !(env->cp15.vstcr_el2 & VSTCR_SW); - } else { - is_secure = !(env->cp15.vtcr_el2 & VTCR_NSW); - } - } else { - assert(!is_secure); - } - - addr = s2.f.phys_addr; } - ptw->out_secure = is_secure; - ptw->out_phys = addr; - ptw->out_be = regime_translation_big_endian(env, ptw->in_mmu_idx); + /* Check if page table walk is to secure or non-secure PA space. */ + ptw->out_secure = (is_secure + && !(pte_secure + ? env->cp15.vstcr_el2 & VSTCR_SW + : env->cp15.vtcr_el2 & VTCR_NSW)); + ptw->out_be = regime_translation_big_endian(env, mmu_idx); return true; + + fail: + assert(fi->type != ARMFault_None); + fi->s2addr = addr; + fi->stage2 = true; + fi->s1ptw = true; + fi->s1ns = !is_secure; + return false; } /* All loads done in the course of a page table walk go through here. */ @@ -287,56 +319,78 @@ static uint32_t arm_ldl_ptw(CPUARMState *env, S1Translate *ptw, hwaddr addr, ARMMMUFaultInfo *fi) { CPUState *cs = env_cpu(env); - MemTxAttrs attrs = {}; - MemTxResult result = MEMTX_OK; - AddressSpace *as; uint32_t data; if (!S1_ptw_translate(env, ptw, addr, fi)) { + /* Failure. */ + assert(fi->s1ptw); return 0; } - addr = ptw->out_phys; - attrs.secure = ptw->out_secure; - as = arm_addressspace(cs, attrs); - if (ptw->out_be) { - data = address_space_ldl_be(as, addr, attrs, &result); + + if (likely(ptw->out_host)) { + /* Page tables are in RAM, and we have the host address. */ + if (ptw->out_be) { + data = ldl_be_p(ptw->out_host); + } else { + data = ldl_le_p(ptw->out_host); + } } else { - data = address_space_ldl_le(as, addr, attrs, &result); + /* Page tables are in MMIO. */ + MemTxAttrs attrs = { .secure = ptw->out_secure }; + AddressSpace *as = arm_addressspace(cs, attrs); + MemTxResult result = MEMTX_OK; + + if (ptw->out_be) { + data = address_space_ldl_be(as, ptw->out_phys, attrs, &result); + } else { + data = address_space_ldl_le(as, ptw->out_phys, attrs, &result); + } + if (unlikely(result != MEMTX_OK)) { + fi->type = ARMFault_SyncExternalOnWalk; + fi->ea = arm_extabort_type(result); + return 0; + } } - if (result == MEMTX_OK) { - return data; - } - fi->type = ARMFault_SyncExternalOnWalk; - fi->ea = arm_extabort_type(result); - return 0; + return data; } static uint64_t arm_ldq_ptw(CPUARMState *env, S1Translate *ptw, hwaddr addr, ARMMMUFaultInfo *fi) { CPUState *cs = env_cpu(env); - MemTxAttrs attrs = {}; - MemTxResult result = MEMTX_OK; - AddressSpace *as; uint64_t data; if (!S1_ptw_translate(env, ptw, addr, fi)) { + /* Failure. */ + assert(fi->s1ptw); return 0; } - addr = ptw->out_phys; - attrs.secure = ptw->out_secure; - as = arm_addressspace(cs, attrs); - if (ptw->out_be) { - data = address_space_ldq_be(as, addr, attrs, &result); + + if (likely(ptw->out_host)) { + /* Page tables are in RAM, and we have the host address. */ + if (ptw->out_be) { + data = ldq_be_p(ptw->out_host); + } else { + data = ldq_le_p(ptw->out_host); + } } else { - data = address_space_ldq_le(as, addr, attrs, &result); + /* Page tables are in MMIO. */ + MemTxAttrs attrs = { .secure = ptw->out_secure }; + AddressSpace *as = arm_addressspace(cs, attrs); + MemTxResult result = MEMTX_OK; + + if (ptw->out_be) { + data = address_space_ldq_be(as, ptw->out_phys, attrs, &result); + } else { + data = address_space_ldq_le(as, ptw->out_phys, attrs, &result); + } + if (unlikely(result != MEMTX_OK)) { + fi->type = ARMFault_SyncExternalOnWalk; + fi->ea = arm_extabort_type(result); + return 0; + } } - if (result == MEMTX_OK) { - return data; - } - fi->type = ARMFault_SyncExternalOnWalk; - fi->ea = arm_extabort_type(result); - return 0; + return data; } static bool get_level1_table_address(CPUARMState *env, ARMMMUIdx mmu_idx, diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c index 3462a6ea14..69b0dc69df 100644 --- a/target/arm/tlb_helper.c +++ b/target/arm/tlb_helper.c @@ -208,10 +208,21 @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size, bool probe, uintptr_t retaddr) { ARMCPU *cpu = ARM_CPU(cs); - ARMMMUFaultInfo fi = {}; GetPhysAddrResult res = {}; + ARMMMUFaultInfo local_fi, *fi; int ret; + /* + * Allow S1_ptw_translate to see any fault generated here. + * Since this may recurse, read and clear. + */ + fi = cpu->env.tlb_fi; + if (fi) { + cpu->env.tlb_fi = NULL; + } else { + fi = memset(&local_fi, 0, sizeof(local_fi)); + } + /* * Walk the page table and (if the mapping exists) add the page * to the TLB. On success, return true. Otherwise, if probing, @@ -220,7 +231,7 @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size, */ ret = get_phys_addr(&cpu->env, address, access_type, core_to_arm_mmu_idx(&cpu->env, mmu_idx), - &res, &fi); + &res, fi); if (likely(!ret)) { /* * Map a single [sub]page. Regions smaller than our declared @@ -242,7 +253,7 @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size, } else { /* now we have a real cpu fault */ cpu_restore_state(cs, retaddr, true); - arm_deliver_fault(cpu, address, access_type, mmu_idx, &fi); + arm_deliver_fault(cpu, address, access_type, mmu_idx, fi); } } #else From 3f5a74c543b491556b4a0020b1683b16659b178f Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 10 Oct 2022 20:18:58 -0700 Subject: [PATCH 013/705] target/arm: Split out get_phys_addr_twostage Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20221011031911.2408754-12-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/ptw.c | 191 +++++++++++++++++++++++++---------------------- 1 file changed, 100 insertions(+), 91 deletions(-) diff --git a/target/arm/ptw.c b/target/arm/ptw.c index 8f41d285b7..dd6556560a 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -31,6 +31,13 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, GetPhysAddrResult *result, ARMMMUFaultInfo *fi) __attribute__((nonnull)); +static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw, + target_ulong address, + MMUAccessType access_type, + GetPhysAddrResult *result, + ARMMMUFaultInfo *fi) + __attribute__((nonnull)); + /* This mapping is common between ID_AA64MMFR0.PARANGE and TCR_ELx.{I}PS. */ static const uint8_t pamax_map[] = { [0] = 32, @@ -2428,6 +2435,94 @@ static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address, return 0; } +static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw, + target_ulong address, + MMUAccessType access_type, + GetPhysAddrResult *result, + ARMMMUFaultInfo *fi) +{ + hwaddr ipa; + int s1_prot; + int ret; + bool is_secure = ptw->in_secure; + bool ipa_secure, s2walk_secure; + ARMCacheAttrs cacheattrs1; + bool is_el0; + uint64_t hcr; + + ret = get_phys_addr_with_struct(env, ptw, address, access_type, result, fi); + + /* If S1 fails or S2 is disabled, return early. */ + if (ret || regime_translation_disabled(env, ARMMMUIdx_Stage2, is_secure)) { + return ret; + } + + ipa = result->f.phys_addr; + ipa_secure = result->f.attrs.secure; + if (is_secure) { + /* Select TCR based on the NS bit from the S1 walk. */ + s2walk_secure = !(ipa_secure + ? env->cp15.vstcr_el2 & VSTCR_SW + : env->cp15.vtcr_el2 & VTCR_NSW); + } else { + assert(!ipa_secure); + s2walk_secure = false; + } + + is_el0 = ptw->in_mmu_idx == ARMMMUIdx_Stage1_E0; + ptw->in_mmu_idx = s2walk_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2; + ptw->in_secure = s2walk_secure; + + /* + * S1 is done, now do S2 translation. + * Save the stage1 results so that we may merge prot and cacheattrs later. + */ + s1_prot = result->f.prot; + cacheattrs1 = result->cacheattrs; + memset(result, 0, sizeof(*result)); + + ret = get_phys_addr_lpae(env, ptw, ipa, access_type, is_el0, result, fi); + fi->s2addr = ipa; + + /* Combine the S1 and S2 perms. */ + result->f.prot &= s1_prot; + + /* If S2 fails, return early. */ + if (ret) { + return ret; + } + + /* Combine the S1 and S2 cache attributes. */ + hcr = arm_hcr_el2_eff_secstate(env, is_secure); + if (hcr & HCR_DC) { + /* + * HCR.DC forces the first stage attributes to + * Normal Non-Shareable, + * Inner Write-Back Read-Allocate Write-Allocate, + * Outer Write-Back Read-Allocate Write-Allocate. + * Do not overwrite Tagged within attrs. + */ + if (cacheattrs1.attrs != 0xf0) { + cacheattrs1.attrs = 0xff; + } + cacheattrs1.shareability = 0; + } + result->cacheattrs = combine_cacheattrs(hcr, cacheattrs1, + result->cacheattrs); + + /* + * Check if IPA translates to secure or non-secure PA space. + * Note that VSTCR overrides VTCR and {N}SW overrides {N}SA. + */ + result->f.attrs.secure = + (is_secure + && !(env->cp15.vstcr_el2 & (VSTCR_SA | VSTCR_SW)) + && (ipa_secure + || !(env->cp15.vtcr_el2 & (VTCR_NSA | VTCR_NSW)))); + + return 0; +} + static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw, target_ulong address, MMUAccessType access_type, @@ -2441,99 +2536,13 @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw, if (mmu_idx != s1_mmu_idx) { /* * Call ourselves recursively to do the stage 1 and then stage 2 - * translations if mmu_idx is a two-stage regime. + * translations if mmu_idx is a two-stage regime, and EL2 present. + * Otherwise, a stage1+stage2 translation is just stage 1. */ + ptw->in_mmu_idx = mmu_idx = s1_mmu_idx; if (arm_feature(env, ARM_FEATURE_EL2)) { - hwaddr ipa; - int s1_prot; - int ret; - bool ipa_secure, s2walk_secure; - ARMCacheAttrs cacheattrs1; - bool is_el0; - uint64_t hcr; - - ptw->in_mmu_idx = s1_mmu_idx; - ret = get_phys_addr_with_struct(env, ptw, address, access_type, - result, fi); - - /* If S1 fails or S2 is disabled, return early. */ - if (ret || regime_translation_disabled(env, ARMMMUIdx_Stage2, - is_secure)) { - return ret; - } - - ipa = result->f.phys_addr; - ipa_secure = result->f.attrs.secure; - if (is_secure) { - /* Select TCR based on the NS bit from the S1 walk. */ - s2walk_secure = !(ipa_secure - ? env->cp15.vstcr_el2 & VSTCR_SW - : env->cp15.vtcr_el2 & VTCR_NSW); - } else { - assert(!ipa_secure); - s2walk_secure = false; - } - - ptw->in_mmu_idx = - s2walk_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2; - ptw->in_secure = s2walk_secure; - is_el0 = mmu_idx == ARMMMUIdx_E10_0; - - /* - * S1 is done, now do S2 translation. - * Save the stage1 results so that we may merge - * prot and cacheattrs later. - */ - s1_prot = result->f.prot; - cacheattrs1 = result->cacheattrs; - memset(result, 0, sizeof(*result)); - - ret = get_phys_addr_lpae(env, ptw, ipa, access_type, - is_el0, result, fi); - fi->s2addr = ipa; - - /* Combine the S1 and S2 perms. */ - result->f.prot &= s1_prot; - - /* If S2 fails, return early. */ - if (ret) { - return ret; - } - - /* Combine the S1 and S2 cache attributes. */ - hcr = arm_hcr_el2_eff_secstate(env, is_secure); - if (hcr & HCR_DC) { - /* - * HCR.DC forces the first stage attributes to - * Normal Non-Shareable, - * Inner Write-Back Read-Allocate Write-Allocate, - * Outer Write-Back Read-Allocate Write-Allocate. - * Do not overwrite Tagged within attrs. - */ - if (cacheattrs1.attrs != 0xf0) { - cacheattrs1.attrs = 0xff; - } - cacheattrs1.shareability = 0; - } - result->cacheattrs = combine_cacheattrs(hcr, cacheattrs1, - result->cacheattrs); - - /* - * Check if IPA translates to secure or non-secure PA space. - * Note that VSTCR overrides VTCR and {N}SW overrides {N}SA. - */ - result->f.attrs.secure = - (is_secure - && !(env->cp15.vstcr_el2 & (VSTCR_SA | VSTCR_SW)) - && (ipa_secure - || !(env->cp15.vtcr_el2 & (VTCR_NSA | VTCR_NSW)))); - - return 0; - } else { - /* - * For non-EL2 CPUs a stage1+stage2 translation is just stage 1. - */ - mmu_idx = stage_1_mmu_idx(mmu_idx); + return get_phys_addr_twostage(env, ptw, address, access_type, + result, fi); } } From 6b72c5424a4a725bc0bacd09bd83f7e8be649345 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 10 Oct 2022 20:18:59 -0700 Subject: [PATCH 014/705] target/arm: Use bool consistently for get_phys_addr subroutines The return type of the functions is already bool, but in a few instances we used an integer type with the return statement. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20221011031911.2408754-13-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/ptw.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/target/arm/ptw.c b/target/arm/ptw.c index dd6556560a..6c5ed56a10 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -2432,7 +2432,7 @@ static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address, result->f.lg_page_size = TARGET_PAGE_BITS; result->cacheattrs.shareability = shareability; result->cacheattrs.attrs = memattr; - return 0; + return false; } static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw, @@ -2443,9 +2443,8 @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw, { hwaddr ipa; int s1_prot; - int ret; bool is_secure = ptw->in_secure; - bool ipa_secure, s2walk_secure; + bool ret, ipa_secure, s2walk_secure; ARMCacheAttrs cacheattrs1; bool is_el0; uint64_t hcr; @@ -2520,7 +2519,7 @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw, && (ipa_secure || !(env->cp15.vtcr_el2 & (VTCR_NSA | VTCR_NSW)))); - return 0; + return false; } static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw, From 8df87279739a30c2f70832f880fd03cb65950775 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 20 Oct 2022 13:06:33 +1000 Subject: [PATCH 015/705] target/arm: Introduce curr_insn_len MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A simple helper to retrieve the length of the current insn. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson Message-id: 20221020030641.2066807-2-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/translate-vfp.c | 2 +- target/arm/translate.c | 5 ++--- target/arm/translate.h | 5 +++++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c index bd5ae27d09..94cc1e4b77 100644 --- a/target/arm/translate-vfp.c +++ b/target/arm/translate-vfp.c @@ -242,7 +242,7 @@ static bool vfp_access_check_a(DisasContext *s, bool ignore_vfp_enabled) if (s->sme_trap_nonstreaming) { gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_smetrap(SME_ET_Streaming, - s->base.pc_next - s->pc_curr == 2)); + curr_insn_len(s) == 2)); return false; } diff --git a/target/arm/translate.c b/target/arm/translate.c index 2f72afe019..5752b7af5c 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -6650,7 +6650,7 @@ static ISSInfo make_issinfo(DisasContext *s, int rd, bool p, bool w) /* ISS not valid if writeback */ if (p && !w) { ret = rd; - if (s->base.pc_next - s->pc_curr == 2) { + if (curr_insn_len(s) == 2) { ret |= ISSIs16Bit; } } else { @@ -9812,8 +9812,7 @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) /* nothing more to generate */ break; case DISAS_WFI: - gen_helper_wfi(cpu_env, - tcg_constant_i32(dc->base.pc_next - dc->pc_curr)); + gen_helper_wfi(cpu_env, tcg_constant_i32(curr_insn_len(dc))); /* * The helper doesn't necessarily throw an exception, but we * must go back to the main loop to check for interrupts anyway. diff --git a/target/arm/translate.h b/target/arm/translate.h index af5d4a7086..90bf7c57fc 100644 --- a/target/arm/translate.h +++ b/target/arm/translate.h @@ -226,6 +226,11 @@ static inline void disas_set_insn_syndrome(DisasContext *s, uint32_t syn) s->insn_start = NULL; } +static inline int curr_insn_len(DisasContext *s) +{ + return s->base.pc_next - s->pc_curr; +} + /* is_jmp field values */ #define DISAS_JUMP DISAS_TARGET_0 /* only pc was modified dynamically */ /* CPU state was modified dynamically; exit to main loop for interrupts. */ From 168122419ed1c4087748e21131a523c6d9b632e1 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 20 Oct 2022 13:06:34 +1000 Subject: [PATCH 016/705] target/arm: Change gen_goto_tb to work on displacements In preparation for TARGET_TB_PCREL, reduce reliance on absolute values. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20221020030641.2066807-3-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/translate-a64.c | 40 ++++++++++++++++++++------------------ target/arm/translate.c | 10 ++++++---- 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index 60ff753d81..928445a7cb 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -370,8 +370,10 @@ static inline bool use_goto_tb(DisasContext *s, uint64_t dest) return translator_use_goto_tb(&s->base, dest); } -static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest) +static void gen_goto_tb(DisasContext *s, int n, int64_t diff) { + uint64_t dest = s->pc_curr + diff; + if (use_goto_tb(s, dest)) { tcg_gen_goto_tb(n); gen_a64_set_pc_im(dest); @@ -1354,7 +1356,7 @@ static inline AArch64DecodeFn *lookup_disas_fn(const AArch64DecodeTable *table, */ static void disas_uncond_b_imm(DisasContext *s, uint32_t insn) { - uint64_t addr = s->pc_curr + sextract32(insn, 0, 26) * 4; + int64_t diff = sextract32(insn, 0, 26) * 4; if (insn & (1U << 31)) { /* BL Branch with link */ @@ -1363,7 +1365,7 @@ static void disas_uncond_b_imm(DisasContext *s, uint32_t insn) /* B Branch / BL Branch with link */ reset_btype(s); - gen_goto_tb(s, 0, addr); + gen_goto_tb(s, 0, diff); } /* Compare and branch (immediate) @@ -1375,14 +1377,14 @@ static void disas_uncond_b_imm(DisasContext *s, uint32_t insn) static void disas_comp_b_imm(DisasContext *s, uint32_t insn) { unsigned int sf, op, rt; - uint64_t addr; + int64_t diff; TCGLabel *label_match; TCGv_i64 tcg_cmp; sf = extract32(insn, 31, 1); op = extract32(insn, 24, 1); /* 0: CBZ; 1: CBNZ */ rt = extract32(insn, 0, 5); - addr = s->pc_curr + sextract32(insn, 5, 19) * 4; + diff = sextract32(insn, 5, 19) * 4; tcg_cmp = read_cpu_reg(s, rt, sf); label_match = gen_new_label(); @@ -1391,9 +1393,9 @@ static void disas_comp_b_imm(DisasContext *s, uint32_t insn) tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ, tcg_cmp, 0, label_match); - gen_goto_tb(s, 0, s->base.pc_next); + gen_goto_tb(s, 0, 4); gen_set_label(label_match); - gen_goto_tb(s, 1, addr); + gen_goto_tb(s, 1, diff); } /* Test and branch (immediate) @@ -1405,13 +1407,13 @@ static void disas_comp_b_imm(DisasContext *s, uint32_t insn) static void disas_test_b_imm(DisasContext *s, uint32_t insn) { unsigned int bit_pos, op, rt; - uint64_t addr; + int64_t diff; TCGLabel *label_match; TCGv_i64 tcg_cmp; bit_pos = (extract32(insn, 31, 1) << 5) | extract32(insn, 19, 5); op = extract32(insn, 24, 1); /* 0: TBZ; 1: TBNZ */ - addr = s->pc_curr + sextract32(insn, 5, 14) * 4; + diff = sextract32(insn, 5, 14) * 4; rt = extract32(insn, 0, 5); tcg_cmp = tcg_temp_new_i64(); @@ -1422,9 +1424,9 @@ static void disas_test_b_imm(DisasContext *s, uint32_t insn) tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ, tcg_cmp, 0, label_match); tcg_temp_free_i64(tcg_cmp); - gen_goto_tb(s, 0, s->base.pc_next); + gen_goto_tb(s, 0, 4); gen_set_label(label_match); - gen_goto_tb(s, 1, addr); + gen_goto_tb(s, 1, diff); } /* Conditional branch (immediate) @@ -1436,13 +1438,13 @@ static void disas_test_b_imm(DisasContext *s, uint32_t insn) static void disas_cond_b_imm(DisasContext *s, uint32_t insn) { unsigned int cond; - uint64_t addr; + int64_t diff; if ((insn & (1 << 4)) || (insn & (1 << 24))) { unallocated_encoding(s); return; } - addr = s->pc_curr + sextract32(insn, 5, 19) * 4; + diff = sextract32(insn, 5, 19) * 4; cond = extract32(insn, 0, 4); reset_btype(s); @@ -1450,12 +1452,12 @@ static void disas_cond_b_imm(DisasContext *s, uint32_t insn) /* genuinely conditional branches */ TCGLabel *label_match = gen_new_label(); arm_gen_test_cc(cond, label_match); - gen_goto_tb(s, 0, s->base.pc_next); + gen_goto_tb(s, 0, 4); gen_set_label(label_match); - gen_goto_tb(s, 1, addr); + gen_goto_tb(s, 1, diff); } else { /* 0xe and 0xf are both "always" conditions */ - gen_goto_tb(s, 0, addr); + gen_goto_tb(s, 0, diff); } } @@ -1629,7 +1631,7 @@ static void handle_sync(DisasContext *s, uint32_t insn, * any pending interrupts immediately. */ reset_btype(s); - gen_goto_tb(s, 0, s->base.pc_next); + gen_goto_tb(s, 0, 4); return; case 7: /* SB */ @@ -1641,7 +1643,7 @@ static void handle_sync(DisasContext *s, uint32_t insn, * MB and end the TB instead. */ tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC); - gen_goto_tb(s, 0, s->base.pc_next); + gen_goto_tb(s, 0, 4); return; default: @@ -14946,7 +14948,7 @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) switch (dc->base.is_jmp) { case DISAS_NEXT: case DISAS_TOO_MANY: - gen_goto_tb(dc, 1, dc->base.pc_next); + gen_goto_tb(dc, 1, 4); break; default: case DISAS_UPDATE_EXIT: diff --git a/target/arm/translate.c b/target/arm/translate.c index 5752b7af5c..ae30c26ca4 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -2590,8 +2590,10 @@ static void gen_goto_ptr(void) * cpu_loop_exec. Any live exit_requests will be processed as we * enter the next TB. */ -static void gen_goto_tb(DisasContext *s, int n, target_ulong dest) +static void gen_goto_tb(DisasContext *s, int n, int diff) { + target_ulong dest = s->pc_curr + diff; + if (translator_use_goto_tb(&s->base, dest)) { tcg_gen_goto_tb(n); gen_set_pc_im(s, dest); @@ -2625,7 +2627,7 @@ static inline void gen_jmp_tb(DisasContext *s, uint32_t dest, int tbno) * gen_jmp(); * on the second call to gen_jmp(). */ - gen_goto_tb(s, tbno, dest); + gen_goto_tb(s, tbno, dest - s->pc_curr); break; case DISAS_UPDATE_NOCHAIN: case DISAS_UPDATE_EXIT: @@ -9793,7 +9795,7 @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) switch (dc->base.is_jmp) { case DISAS_NEXT: case DISAS_TOO_MANY: - gen_goto_tb(dc, 1, dc->base.pc_next); + gen_goto_tb(dc, 1, curr_insn_len(dc)); break; case DISAS_UPDATE_NOCHAIN: gen_set_pc_im(dc, dc->base.pc_next); @@ -9845,7 +9847,7 @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) gen_set_pc_im(dc, dc->base.pc_next); gen_singlestep_exception(dc); } else { - gen_goto_tb(dc, 1, dc->base.pc_next); + gen_goto_tb(dc, 1, curr_insn_len(dc)); } } } From c44c8b8b99959068801726be97b6a444ee2989bc Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 20 Oct 2022 13:06:35 +1000 Subject: [PATCH 017/705] target/arm: Change gen_*set_pc_im to gen_*update_pc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In preparation for TARGET_TB_PCREL, reduce reliance on absolute values by passing in pc difference. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson Message-id: 20221020030641.2066807-4-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/translate-a32.h | 2 +- target/arm/translate-a64.c | 32 +++++++++--------- target/arm/translate-vfp.c | 2 +- target/arm/translate.c | 68 ++++++++++++++++++++------------------ target/arm/translate.h | 6 ++-- 5 files changed, 56 insertions(+), 54 deletions(-) diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h index 78a84c1414..5339c22f1e 100644 --- a/target/arm/translate-a32.h +++ b/target/arm/translate-a32.h @@ -40,7 +40,7 @@ void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop); TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs); void gen_set_cpsr(TCGv_i32 var, uint32_t mask); void gen_set_condexec(DisasContext *s); -void gen_set_pc_im(DisasContext *s, target_ulong val); +void gen_update_pc(DisasContext *s, target_long diff); void gen_lookup_tb(DisasContext *s); long vfp_reg_offset(bool dp, unsigned reg); long neon_full_reg_offset(unsigned reg); diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index 928445a7cb..b638d14f2d 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -140,9 +140,9 @@ static void reset_btype(DisasContext *s) } } -void gen_a64_set_pc_im(uint64_t val) +void gen_a64_update_pc(DisasContext *s, target_long diff) { - tcg_gen_movi_i64(cpu_pc, val); + tcg_gen_movi_i64(cpu_pc, s->pc_curr + diff); } /* @@ -334,14 +334,14 @@ static void gen_exception_internal(int excp) static void gen_exception_internal_insn(DisasContext *s, uint64_t pc, int excp) { - gen_a64_set_pc_im(pc); + gen_a64_update_pc(s, pc - s->pc_curr); gen_exception_internal(excp); s->base.is_jmp = DISAS_NORETURN; } static void gen_exception_bkpt_insn(DisasContext *s, uint32_t syndrome) { - gen_a64_set_pc_im(s->pc_curr); + gen_a64_update_pc(s, 0); gen_helper_exception_bkpt_insn(cpu_env, tcg_constant_i32(syndrome)); s->base.is_jmp = DISAS_NORETURN; } @@ -376,11 +376,11 @@ static void gen_goto_tb(DisasContext *s, int n, int64_t diff) if (use_goto_tb(s, dest)) { tcg_gen_goto_tb(n); - gen_a64_set_pc_im(dest); + gen_a64_update_pc(s, diff); tcg_gen_exit_tb(s->base.tb, n); s->base.is_jmp = DISAS_NORETURN; } else { - gen_a64_set_pc_im(dest); + gen_a64_update_pc(s, diff); if (s->ss_active) { gen_step_complete_exception(s); } else { @@ -1952,7 +1952,7 @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread, uint32_t syndrome; syndrome = syn_aa64_sysregtrap(op0, op1, op2, crn, crm, rt, isread); - gen_a64_set_pc_im(s->pc_curr); + gen_a64_update_pc(s, 0); gen_helper_access_check_cp_reg(cpu_env, tcg_constant_ptr(ri), tcg_constant_i32(syndrome), @@ -1962,7 +1962,7 @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread, * The readfn or writefn might raise an exception; * synchronize the CPU state in case it does. */ - gen_a64_set_pc_im(s->pc_curr); + gen_a64_update_pc(s, 0); } /* Handle special cases first */ @@ -2172,7 +2172,7 @@ static void disas_exc(DisasContext *s, uint32_t insn) /* The pre HVC helper handles cases when HVC gets trapped * as an undefined insn by runtime configuration. */ - gen_a64_set_pc_im(s->pc_curr); + gen_a64_update_pc(s, 0); gen_helper_pre_hvc(cpu_env); gen_ss_advance(s); gen_exception_insn_el(s, s->base.pc_next, EXCP_HVC, @@ -2183,7 +2183,7 @@ static void disas_exc(DisasContext *s, uint32_t insn) unallocated_encoding(s); break; } - gen_a64_set_pc_im(s->pc_curr); + gen_a64_update_pc(s, 0); gen_helper_pre_smc(cpu_env, tcg_constant_i32(syn_aa64_smc(imm16))); gen_ss_advance(s); gen_exception_insn_el(s, s->base.pc_next, EXCP_SMC, @@ -14935,7 +14935,7 @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) */ switch (dc->base.is_jmp) { default: - gen_a64_set_pc_im(dc->base.pc_next); + gen_a64_update_pc(dc, 4); /* fall through */ case DISAS_EXIT: case DISAS_JUMP: @@ -14952,13 +14952,13 @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) break; default: case DISAS_UPDATE_EXIT: - gen_a64_set_pc_im(dc->base.pc_next); + gen_a64_update_pc(dc, 4); /* fall through */ case DISAS_EXIT: tcg_gen_exit_tb(NULL, 0); break; case DISAS_UPDATE_NOCHAIN: - gen_a64_set_pc_im(dc->base.pc_next); + gen_a64_update_pc(dc, 4); /* fall through */ case DISAS_JUMP: tcg_gen_lookup_and_goto_ptr(); @@ -14967,11 +14967,11 @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) case DISAS_SWI: break; case DISAS_WFE: - gen_a64_set_pc_im(dc->base.pc_next); + gen_a64_update_pc(dc, 4); gen_helper_wfe(cpu_env); break; case DISAS_YIELD: - gen_a64_set_pc_im(dc->base.pc_next); + gen_a64_update_pc(dc, 4); gen_helper_yield(cpu_env); break; case DISAS_WFI: @@ -14979,7 +14979,7 @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) * This is a special case because we don't want to just halt * the CPU if trying to debug across a WFI. */ - gen_a64_set_pc_im(dc->base.pc_next); + gen_a64_update_pc(dc, 4); gen_helper_wfi(cpu_env, tcg_constant_i32(4)); /* * The helper doesn't necessarily throw an exception, but we diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c index 94cc1e4b77..070f465b17 100644 --- a/target/arm/translate-vfp.c +++ b/target/arm/translate-vfp.c @@ -856,7 +856,7 @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a) case ARM_VFP_FPSID: if (s->current_el == 1) { gen_set_condexec(s); - gen_set_pc_im(s, s->pc_curr); + gen_update_pc(s, 0); gen_helper_check_hcr_el2_trap(cpu_env, tcg_constant_i32(a->rt), tcg_constant_i32(a->reg)); diff --git a/target/arm/translate.c b/target/arm/translate.c index ae30c26ca4..9863a08f49 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -768,9 +768,9 @@ void gen_set_condexec(DisasContext *s) } } -void gen_set_pc_im(DisasContext *s, target_ulong val) +void gen_update_pc(DisasContext *s, target_long diff) { - tcg_gen_movi_i32(cpu_R[15], val); + tcg_gen_movi_i32(cpu_R[15], s->pc_curr + diff); } /* Set PC and Thumb state from var. var is marked as dead. */ @@ -862,7 +862,7 @@ static inline void gen_bxns(DisasContext *s, int rm) /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory * we need to sync state before calling it, but: - * - we don't need to do gen_set_pc_im() because the bxns helper will + * - we don't need to do gen_update_pc() because the bxns helper will * always set the PC itself * - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE * unless it's outside an IT block or the last insn in an IT block, @@ -883,7 +883,7 @@ static inline void gen_blxns(DisasContext *s, int rm) * We do however need to set the PC, because the blxns helper reads it. * The blxns helper may throw an exception. */ - gen_set_pc_im(s, s->base.pc_next); + gen_update_pc(s, curr_insn_len(s)); gen_helper_v7m_blxns(cpu_env, var); tcg_temp_free_i32(var); s->base.is_jmp = DISAS_EXIT; @@ -1051,7 +1051,7 @@ static inline void gen_hvc(DisasContext *s, int imm16) * as an undefined insn by runtime configuration (ie before * the insn really executes). */ - gen_set_pc_im(s, s->pc_curr); + gen_update_pc(s, 0); gen_helper_pre_hvc(cpu_env); /* Otherwise we will treat this as a real exception which * happens after execution of the insn. (The distinction matters @@ -1059,7 +1059,7 @@ static inline void gen_hvc(DisasContext *s, int imm16) * for single stepping.) */ s->svc_imm = imm16; - gen_set_pc_im(s, s->base.pc_next); + gen_update_pc(s, curr_insn_len(s)); s->base.is_jmp = DISAS_HVC; } @@ -1068,16 +1068,16 @@ static inline void gen_smc(DisasContext *s) /* As with HVC, we may take an exception either before or after * the insn executes. */ - gen_set_pc_im(s, s->pc_curr); + gen_update_pc(s, 0); gen_helper_pre_smc(cpu_env, tcg_constant_i32(syn_aa32_smc())); - gen_set_pc_im(s, s->base.pc_next); + gen_update_pc(s, curr_insn_len(s)); s->base.is_jmp = DISAS_SMC; } static void gen_exception_internal_insn(DisasContext *s, uint32_t pc, int excp) { gen_set_condexec(s); - gen_set_pc_im(s, pc); + gen_update_pc(s, pc - s->pc_curr); gen_exception_internal(excp); s->base.is_jmp = DISAS_NORETURN; } @@ -1103,10 +1103,10 @@ static void gen_exception_insn_el_v(DisasContext *s, uint64_t pc, int excp, uint32_t syn, TCGv_i32 tcg_el) { if (s->aarch64) { - gen_a64_set_pc_im(pc); + gen_a64_update_pc(s, pc - s->pc_curr); } else { gen_set_condexec(s); - gen_set_pc_im(s, pc); + gen_update_pc(s, pc - s->pc_curr); } gen_exception_el_v(excp, syn, tcg_el); s->base.is_jmp = DISAS_NORETURN; @@ -1121,10 +1121,10 @@ void gen_exception_insn_el(DisasContext *s, uint64_t pc, int excp, void gen_exception_insn(DisasContext *s, uint64_t pc, int excp, uint32_t syn) { if (s->aarch64) { - gen_a64_set_pc_im(pc); + gen_a64_update_pc(s, pc - s->pc_curr); } else { gen_set_condexec(s); - gen_set_pc_im(s, pc); + gen_update_pc(s, pc - s->pc_curr); } gen_exception(excp, syn); s->base.is_jmp = DISAS_NORETURN; @@ -1133,7 +1133,7 @@ void gen_exception_insn(DisasContext *s, uint64_t pc, int excp, uint32_t syn) static void gen_exception_bkpt_insn(DisasContext *s, uint32_t syn) { gen_set_condexec(s); - gen_set_pc_im(s, s->pc_curr); + gen_update_pc(s, 0); gen_helper_exception_bkpt_insn(cpu_env, tcg_constant_i32(syn)); s->base.is_jmp = DISAS_NORETURN; } @@ -2596,10 +2596,10 @@ static void gen_goto_tb(DisasContext *s, int n, int diff) if (translator_use_goto_tb(&s->base, dest)) { tcg_gen_goto_tb(n); - gen_set_pc_im(s, dest); + gen_update_pc(s, diff); tcg_gen_exit_tb(s->base.tb, n); } else { - gen_set_pc_im(s, dest); + gen_update_pc(s, diff); gen_goto_ptr(); } s->base.is_jmp = DISAS_NORETURN; @@ -2608,9 +2608,11 @@ static void gen_goto_tb(DisasContext *s, int n, int diff) /* Jump, specifying which TB number to use if we gen_goto_tb() */ static inline void gen_jmp_tb(DisasContext *s, uint32_t dest, int tbno) { + int diff = dest - s->pc_curr; + if (unlikely(s->ss_active)) { /* An indirect jump so that we still trigger the debug exception. */ - gen_set_pc_im(s, dest); + gen_update_pc(s, diff); s->base.is_jmp = DISAS_JUMP; return; } @@ -2627,7 +2629,7 @@ static inline void gen_jmp_tb(DisasContext *s, uint32_t dest, int tbno) * gen_jmp(); * on the second call to gen_jmp(). */ - gen_goto_tb(s, tbno, dest - s->pc_curr); + gen_goto_tb(s, tbno, diff); break; case DISAS_UPDATE_NOCHAIN: case DISAS_UPDATE_EXIT: @@ -2636,7 +2638,7 @@ static inline void gen_jmp_tb(DisasContext *s, uint32_t dest, int tbno) * Avoid using goto_tb so we really do exit back to the main loop * and don't chain to another TB. */ - gen_set_pc_im(s, dest); + gen_update_pc(s, diff); gen_goto_ptr(); s->base.is_jmp = DISAS_NORETURN; break; @@ -2904,7 +2906,7 @@ static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn) /* Sync state because msr_banked() can raise exceptions */ gen_set_condexec(s); - gen_set_pc_im(s, s->pc_curr); + gen_update_pc(s, 0); tcg_reg = load_reg(s, rn); gen_helper_msr_banked(cpu_env, tcg_reg, tcg_constant_i32(tgtmode), @@ -2924,7 +2926,7 @@ static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn) /* Sync state because mrs_banked() can raise exceptions */ gen_set_condexec(s); - gen_set_pc_im(s, s->pc_curr); + gen_update_pc(s, 0); tcg_reg = tcg_temp_new_i32(); gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_constant_i32(tgtmode), @@ -4745,7 +4747,7 @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64, } gen_set_condexec(s); - gen_set_pc_im(s, s->pc_curr); + gen_update_pc(s, 0); gen_helper_access_check_cp_reg(cpu_env, tcg_constant_ptr(ri), tcg_constant_i32(syndrome), @@ -4756,7 +4758,7 @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64, * synchronize the CPU state in case it does. */ gen_set_condexec(s); - gen_set_pc_im(s, s->pc_curr); + gen_update_pc(s, 0); } /* Handle special cases first */ @@ -4770,7 +4772,7 @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64, unallocated_encoding(s); return; } - gen_set_pc_im(s, s->base.pc_next); + gen_update_pc(s, curr_insn_len(s)); s->base.is_jmp = DISAS_WFI; return; default: @@ -5157,7 +5159,7 @@ static void gen_srs(DisasContext *s, addr = tcg_temp_new_i32(); /* get_r13_banked() will raise an exception if called from System mode */ gen_set_condexec(s); - gen_set_pc_im(s, s->pc_curr); + gen_update_pc(s, 0); gen_helper_get_r13_banked(addr, cpu_env, tcg_constant_i32(mode)); switch (amode) { case 0: /* DA */ @@ -6226,7 +6228,7 @@ static bool trans_YIELD(DisasContext *s, arg_YIELD *a) * scheduling of other vCPUs. */ if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) { - gen_set_pc_im(s, s->base.pc_next); + gen_update_pc(s, curr_insn_len(s)); s->base.is_jmp = DISAS_YIELD; } return true; @@ -6242,7 +6244,7 @@ static bool trans_WFE(DisasContext *s, arg_WFE *a) * implemented so we can't sleep like WFI does. */ if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) { - gen_set_pc_im(s, s->base.pc_next); + gen_update_pc(s, curr_insn_len(s)); s->base.is_jmp = DISAS_WFE; } return true; @@ -6251,7 +6253,7 @@ static bool trans_WFE(DisasContext *s, arg_WFE *a) static bool trans_WFI(DisasContext *s, arg_WFI *a) { /* For WFI, halt the vCPU until an IRQ. */ - gen_set_pc_im(s, s->base.pc_next); + gen_update_pc(s, curr_insn_len(s)); s->base.is_jmp = DISAS_WFI; return true; } @@ -8761,7 +8763,7 @@ static bool trans_SVC(DisasContext *s, arg_SVC *a) (a->imm == semihost_imm)) { gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST); } else { - gen_set_pc_im(s, s->base.pc_next); + gen_update_pc(s, curr_insn_len(s)); s->svc_imm = a->imm; s->base.is_jmp = DISAS_SWI; } @@ -9774,7 +9776,7 @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) case DISAS_TOO_MANY: case DISAS_UPDATE_EXIT: case DISAS_UPDATE_NOCHAIN: - gen_set_pc_im(dc, dc->base.pc_next); + gen_update_pc(dc, curr_insn_len(dc)); /* fall through */ default: /* FIXME: Single stepping a WFI insn will not halt the CPU. */ @@ -9798,13 +9800,13 @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) gen_goto_tb(dc, 1, curr_insn_len(dc)); break; case DISAS_UPDATE_NOCHAIN: - gen_set_pc_im(dc, dc->base.pc_next); + gen_update_pc(dc, curr_insn_len(dc)); /* fall through */ case DISAS_JUMP: gen_goto_ptr(); break; case DISAS_UPDATE_EXIT: - gen_set_pc_im(dc, dc->base.pc_next); + gen_update_pc(dc, curr_insn_len(dc)); /* fall through */ default: /* indicate that the hash table must be used to find the next TB */ @@ -9844,7 +9846,7 @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) gen_set_label(dc->condlabel); gen_set_condexec(dc); if (unlikely(dc->ss_active)) { - gen_set_pc_im(dc, dc->base.pc_next); + gen_update_pc(dc, curr_insn_len(dc)); gen_singlestep_exception(dc); } else { gen_goto_tb(dc, 1, curr_insn_len(dc)); diff --git a/target/arm/translate.h b/target/arm/translate.h index 90bf7c57fc..d651044855 100644 --- a/target/arm/translate.h +++ b/target/arm/translate.h @@ -254,7 +254,7 @@ static inline int curr_insn_len(DisasContext *s) * For instructions which want an immediate exit to the main loop, as opposed * to attempting to use lookup_and_goto_ptr. Unlike DISAS_UPDATE_EXIT, this * doesn't write the PC on exiting the translation loop so you need to ensure - * something (gen_a64_set_pc_im or runtime helper) has done so before we reach + * something (gen_a64_update_pc or runtime helper) has done so before we reach * return from cpu_tb_exec. */ #define DISAS_EXIT DISAS_TARGET_9 @@ -263,14 +263,14 @@ static inline int curr_insn_len(DisasContext *s) #ifdef TARGET_AARCH64 void a64_translate_init(void); -void gen_a64_set_pc_im(uint64_t val); +void gen_a64_update_pc(DisasContext *s, target_long diff); extern const TranslatorOps aarch64_translator_ops; #else static inline void a64_translate_init(void) { } -static inline void gen_a64_set_pc_im(uint64_t val) +static inline void gen_a64_update_pc(DisasContext *s, target_long diff) { } #endif From 55086e628ffcb35c71317b310d9caf6f718ae870 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 20 Oct 2022 13:06:36 +1000 Subject: [PATCH 018/705] target/arm: Change gen_exception_insn* to work on displacements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In preparation for TARGET_TB_PCREL, reduce reliance on absolute values. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson Message-id: 20221020030641.2066807-5-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/translate-a64.c | 28 ++++++++++------------- target/arm/translate-m-nocp.c | 6 ++--- target/arm/translate-mve.c | 2 +- target/arm/translate-vfp.c | 6 ++--- target/arm/translate.c | 42 +++++++++++++++++------------------ target/arm/translate.h | 5 +++-- 6 files changed, 43 insertions(+), 46 deletions(-) diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index b638d14f2d..8ed192198f 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -1155,7 +1155,7 @@ static bool fp_access_check_only(DisasContext *s) assert(!s->fp_access_checked); s->fp_access_checked = true; - gen_exception_insn_el(s, s->pc_curr, EXCP_UDEF, + gen_exception_insn_el(s, 0, EXCP_UDEF, syn_fp_access_trap(1, 0xe, false, 0), s->fp_excp_el); return false; @@ -1170,7 +1170,7 @@ static bool fp_access_check(DisasContext *s) return false; } if (s->sme_trap_nonstreaming && s->is_nonstreaming) { - gen_exception_insn(s, s->pc_curr, EXCP_UDEF, + gen_exception_insn(s, 0, EXCP_UDEF, syn_smetrap(SME_ET_Streaming, false)); return false; } @@ -1190,7 +1190,7 @@ bool sve_access_check(DisasContext *s) goto fail_exit; } } else if (s->sve_excp_el) { - gen_exception_insn_el(s, s->pc_curr, EXCP_UDEF, + gen_exception_insn_el(s, 0, EXCP_UDEF, syn_sve_access_trap(), s->sve_excp_el); goto fail_exit; } @@ -1212,7 +1212,7 @@ bool sve_access_check(DisasContext *s) static bool sme_access_check(DisasContext *s) { if (s->sme_excp_el) { - gen_exception_insn_el(s, s->pc_curr, EXCP_UDEF, + gen_exception_insn_el(s, 0, EXCP_UDEF, syn_smetrap(SME_ET_AccessTrap, false), s->sme_excp_el); return false; @@ -1242,12 +1242,12 @@ bool sme_enabled_check_with_svcr(DisasContext *s, unsigned req) return false; } if (FIELD_EX64(req, SVCR, SM) && !s->pstate_sm) { - gen_exception_insn(s, s->pc_curr, EXCP_UDEF, + gen_exception_insn(s, 0, EXCP_UDEF, syn_smetrap(SME_ET_NotStreaming, false)); return false; } if (FIELD_EX64(req, SVCR, ZA) && !s->pstate_za) { - gen_exception_insn(s, s->pc_curr, EXCP_UDEF, + gen_exception_insn(s, 0, EXCP_UDEF, syn_smetrap(SME_ET_InactiveZA, false)); return false; } @@ -1907,7 +1907,7 @@ static void gen_sysreg_undef(DisasContext *s, bool isread, } else { syndrome = syn_uncategorized(); } - gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syndrome); + gen_exception_insn(s, 0, EXCP_UDEF, syndrome); } /* MRS - move from system register @@ -2161,8 +2161,7 @@ static void disas_exc(DisasContext *s, uint32_t insn) switch (op2_ll) { case 1: /* SVC */ gen_ss_advance(s); - gen_exception_insn(s, s->base.pc_next, EXCP_SWI, - syn_aa64_svc(imm16)); + gen_exception_insn(s, 4, EXCP_SWI, syn_aa64_svc(imm16)); break; case 2: /* HVC */ if (s->current_el == 0) { @@ -2175,8 +2174,7 @@ static void disas_exc(DisasContext *s, uint32_t insn) gen_a64_update_pc(s, 0); gen_helper_pre_hvc(cpu_env); gen_ss_advance(s); - gen_exception_insn_el(s, s->base.pc_next, EXCP_HVC, - syn_aa64_hvc(imm16), 2); + gen_exception_insn_el(s, 4, EXCP_HVC, syn_aa64_hvc(imm16), 2); break; case 3: /* SMC */ if (s->current_el == 0) { @@ -2186,8 +2184,7 @@ static void disas_exc(DisasContext *s, uint32_t insn) gen_a64_update_pc(s, 0); gen_helper_pre_smc(cpu_env, tcg_constant_i32(syn_aa64_smc(imm16))); gen_ss_advance(s); - gen_exception_insn_el(s, s->base.pc_next, EXCP_SMC, - syn_aa64_smc(imm16), 3); + gen_exception_insn_el(s, 4, EXCP_SMC, syn_aa64_smc(imm16), 3); break; default: unallocated_encoding(s); @@ -14824,7 +14821,7 @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) * Illegal execution state. This has priority over BTI * exceptions, but comes after instruction abort exceptions. */ - gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_illegalstate()); + gen_exception_insn(s, 0, EXCP_UDEF, syn_illegalstate()); return; } @@ -14855,8 +14852,7 @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) if (s->btype != 0 && s->guarded_page && !btype_destination_ok(insn, s->bt, s->btype)) { - gen_exception_insn(s, s->pc_curr, EXCP_UDEF, - syn_btitrap(s->btype)); + gen_exception_insn(s, 0, EXCP_UDEF, syn_btitrap(s->btype)); return; } } else { diff --git a/target/arm/translate-m-nocp.c b/target/arm/translate-m-nocp.c index 4029d7fdd4..694fae7e2e 100644 --- a/target/arm/translate-m-nocp.c +++ b/target/arm/translate-m-nocp.c @@ -143,7 +143,7 @@ static bool trans_VSCCLRM(DisasContext *s, arg_VSCCLRM *a) tcg_gen_brcondi_i32(TCG_COND_EQ, sfpa, 0, s->condlabel); if (s->fp_excp_el != 0) { - gen_exception_insn_el(s, s->pc_curr, EXCP_NOCP, + gen_exception_insn_el(s, 0, EXCP_NOCP, syn_uncategorized(), s->fp_excp_el); return true; } @@ -765,12 +765,12 @@ static bool trans_NOCP(DisasContext *s, arg_nocp *a) } if (a->cp != 10) { - gen_exception_insn(s, s->pc_curr, EXCP_NOCP, syn_uncategorized()); + gen_exception_insn(s, 0, EXCP_NOCP, syn_uncategorized()); return true; } if (s->fp_excp_el != 0) { - gen_exception_insn_el(s, s->pc_curr, EXCP_NOCP, + gen_exception_insn_el(s, 0, EXCP_NOCP, syn_uncategorized(), s->fp_excp_el); return true; } diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c index 0cf1b5ea4f..db7ea3f603 100644 --- a/target/arm/translate-mve.c +++ b/target/arm/translate-mve.c @@ -100,7 +100,7 @@ bool mve_eci_check(DisasContext *s) return true; default: /* Reserved value: INVSTATE UsageFault */ - gen_exception_insn(s, s->pc_curr, EXCP_INVSTATE, syn_uncategorized()); + gen_exception_insn(s, 0, EXCP_INVSTATE, syn_uncategorized()); return false; } } diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c index 070f465b17..5c5d58d2c6 100644 --- a/target/arm/translate-vfp.c +++ b/target/arm/translate-vfp.c @@ -230,7 +230,7 @@ static bool vfp_access_check_a(DisasContext *s, bool ignore_vfp_enabled) int coproc = arm_dc_feature(s, ARM_FEATURE_V8) ? 0 : 0xa; uint32_t syn = syn_fp_access_trap(1, 0xe, false, coproc); - gen_exception_insn_el(s, s->pc_curr, EXCP_UDEF, syn, s->fp_excp_el); + gen_exception_insn_el(s, 0, EXCP_UDEF, syn, s->fp_excp_el); return false; } @@ -240,7 +240,7 @@ static bool vfp_access_check_a(DisasContext *s, bool ignore_vfp_enabled) * appear to be any insns which touch VFP which are allowed. */ if (s->sme_trap_nonstreaming) { - gen_exception_insn(s, s->pc_curr, EXCP_UDEF, + gen_exception_insn(s, 0, EXCP_UDEF, syn_smetrap(SME_ET_Streaming, curr_insn_len(s) == 2)); return false; @@ -272,7 +272,7 @@ bool vfp_access_check_m(DisasContext *s, bool skip_context_update) * the encoding space handled by the patterns in m-nocp.decode, * and for them we may need to raise NOCP here. */ - gen_exception_insn_el(s, s->pc_curr, EXCP_NOCP, + gen_exception_insn_el(s, 0, EXCP_NOCP, syn_uncategorized(), s->fp_excp_el); return false; } diff --git a/target/arm/translate.c b/target/arm/translate.c index 9863a08f49..350f991649 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -1099,32 +1099,34 @@ static void gen_exception(int excp, uint32_t syndrome) tcg_constant_i32(syndrome)); } -static void gen_exception_insn_el_v(DisasContext *s, uint64_t pc, int excp, - uint32_t syn, TCGv_i32 tcg_el) +static void gen_exception_insn_el_v(DisasContext *s, target_long pc_diff, + int excp, uint32_t syn, TCGv_i32 tcg_el) { if (s->aarch64) { - gen_a64_update_pc(s, pc - s->pc_curr); + gen_a64_update_pc(s, pc_diff); } else { gen_set_condexec(s); - gen_update_pc(s, pc - s->pc_curr); + gen_update_pc(s, pc_diff); } gen_exception_el_v(excp, syn, tcg_el); s->base.is_jmp = DISAS_NORETURN; } -void gen_exception_insn_el(DisasContext *s, uint64_t pc, int excp, +void gen_exception_insn_el(DisasContext *s, target_long pc_diff, int excp, uint32_t syn, uint32_t target_el) { - gen_exception_insn_el_v(s, pc, excp, syn, tcg_constant_i32(target_el)); + gen_exception_insn_el_v(s, pc_diff, excp, syn, + tcg_constant_i32(target_el)); } -void gen_exception_insn(DisasContext *s, uint64_t pc, int excp, uint32_t syn) +void gen_exception_insn(DisasContext *s, target_long pc_diff, + int excp, uint32_t syn) { if (s->aarch64) { - gen_a64_update_pc(s, pc - s->pc_curr); + gen_a64_update_pc(s, pc_diff); } else { gen_set_condexec(s); - gen_update_pc(s, pc - s->pc_curr); + gen_update_pc(s, pc_diff); } gen_exception(excp, syn); s->base.is_jmp = DISAS_NORETURN; @@ -1141,7 +1143,7 @@ static void gen_exception_bkpt_insn(DisasContext *s, uint32_t syn) void unallocated_encoding(DisasContext *s) { /* Unallocated and reserved encodings are uncategorized */ - gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized()); + gen_exception_insn(s, 0, EXCP_UDEF, syn_uncategorized()); } /* Force a TB lookup after an instruction that changes the CPU state. */ @@ -2865,7 +2867,7 @@ static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn, tcg_el = tcg_constant_i32(3); } - gen_exception_insn_el_v(s, s->pc_curr, EXCP_UDEF, + gen_exception_insn_el_v(s, 0, EXCP_UDEF, syn_uncategorized(), tcg_el); tcg_temp_free_i32(tcg_el); return false; @@ -2891,7 +2893,7 @@ static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn, undef: /* If we get here then some access check did not pass */ - gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized()); + gen_exception_insn(s, 0, EXCP_UDEF, syn_uncategorized()); return false; } @@ -5115,8 +5117,7 @@ static void gen_srs(DisasContext *s, * For the UNPREDICTABLE cases we choose to UNDEF. */ if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) { - gen_exception_insn_el(s, s->pc_curr, EXCP_UDEF, - syn_uncategorized(), 3); + gen_exception_insn_el(s, 0, EXCP_UDEF, syn_uncategorized(), 3); return; } @@ -8498,7 +8499,7 @@ static bool trans_WLS(DisasContext *s, arg_WLS *a) * Do the check-and-raise-exception by hand. */ if (s->fp_excp_el) { - gen_exception_insn_el(s, s->pc_curr, EXCP_NOCP, + gen_exception_insn_el(s, 0, EXCP_NOCP, syn_uncategorized(), s->fp_excp_el); return true; } @@ -8601,7 +8602,7 @@ static bool trans_LE(DisasContext *s, arg_LE *a) tmp = load_cpu_field(v7m.ltpsize); tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 4, skipexc); tcg_temp_free_i32(tmp); - gen_exception_insn(s, s->pc_curr, EXCP_INVSTATE, syn_uncategorized()); + gen_exception_insn(s, 0, EXCP_INVSTATE, syn_uncategorized()); gen_set_label(skipexc); } @@ -9069,7 +9070,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) * UsageFault exception. */ if (arm_dc_feature(s, ARM_FEATURE_M)) { - gen_exception_insn(s, s->pc_curr, EXCP_INVSTATE, syn_uncategorized()); + gen_exception_insn(s, 0, EXCP_INVSTATE, syn_uncategorized()); return; } @@ -9078,7 +9079,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) * Illegal execution state. This has priority over BTI * exceptions, but comes after instruction abort exceptions. */ - gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_illegalstate()); + gen_exception_insn(s, 0, EXCP_UDEF, syn_illegalstate()); return; } @@ -9642,7 +9643,7 @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) * Illegal execution state. This has priority over BTI * exceptions, but comes after instruction abort exceptions. */ - gen_exception_insn(dc, dc->pc_curr, EXCP_UDEF, syn_illegalstate()); + gen_exception_insn(dc, 0, EXCP_UDEF, syn_illegalstate()); return; } @@ -9715,8 +9716,7 @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) */ tcg_remove_ops_after(dc->insn_eci_rewind); dc->condjmp = 0; - gen_exception_insn(dc, dc->pc_curr, EXCP_INVSTATE, - syn_uncategorized()); + gen_exception_insn(dc, 0, EXCP_INVSTATE, syn_uncategorized()); } arm_post_translate_insn(dc); diff --git a/target/arm/translate.h b/target/arm/translate.h index d651044855..4aa239e23c 100644 --- a/target/arm/translate.h +++ b/target/arm/translate.h @@ -281,9 +281,10 @@ void arm_jump_cc(DisasCompare *cmp, TCGLabel *label); void arm_gen_test_cc(int cc, TCGLabel *label); MemOp pow2_align(unsigned i); void unallocated_encoding(DisasContext *s); -void gen_exception_insn_el(DisasContext *s, uint64_t pc, int excp, +void gen_exception_insn_el(DisasContext *s, target_long pc_diff, int excp, uint32_t syn, uint32_t target_el); -void gen_exception_insn(DisasContext *s, uint64_t pc, int excp, uint32_t syn); +void gen_exception_insn(DisasContext *s, target_long pc_diff, + int excp, uint32_t syn); /* Return state of Alternate Half-precision flag, caller frees result */ static inline TCGv_i32 get_ahp_flag(void) From b4f8d987f6a9ff2733bcd6e5fa78f6582dc84771 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 20 Oct 2022 13:06:37 +1000 Subject: [PATCH 019/705] target/arm: Remove gen_exception_internal_insn pc argument MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In preparation for TARGET_TB_PCREL, reduce reliance on absolute values. Since we always pass dc->pc_curr, fold the arithmetic to zero displacement. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson Message-id: 20221020030641.2066807-6-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/translate-a64.c | 6 +++--- target/arm/translate.c | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index 8ed192198f..713f1a89a4 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -332,9 +332,9 @@ static void gen_exception_internal(int excp) gen_helper_exception_internal(cpu_env, tcg_constant_i32(excp)); } -static void gen_exception_internal_insn(DisasContext *s, uint64_t pc, int excp) +static void gen_exception_internal_insn(DisasContext *s, int excp) { - gen_a64_update_pc(s, pc - s->pc_curr); + gen_a64_update_pc(s, 0); gen_exception_internal(excp); s->base.is_jmp = DISAS_NORETURN; } @@ -2211,7 +2211,7 @@ static void disas_exc(DisasContext *s, uint32_t insn) * Secondly, "HLT 0xf000" is the A64 semihosting syscall instruction. */ if (semihosting_enabled(s->current_el == 0) && imm16 == 0xf000) { - gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST); + gen_exception_internal_insn(s, EXCP_SEMIHOST); } else { unallocated_encoding(s); } diff --git a/target/arm/translate.c b/target/arm/translate.c index 350f991649..9104ab8232 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -1074,10 +1074,10 @@ static inline void gen_smc(DisasContext *s) s->base.is_jmp = DISAS_SMC; } -static void gen_exception_internal_insn(DisasContext *s, uint32_t pc, int excp) +static void gen_exception_internal_insn(DisasContext *s, int excp) { gen_set_condexec(s); - gen_update_pc(s, pc - s->pc_curr); + gen_update_pc(s, 0); gen_exception_internal(excp); s->base.is_jmp = DISAS_NORETURN; } @@ -1169,7 +1169,7 @@ static inline void gen_hlt(DisasContext *s, int imm) */ if (semihosting_enabled(s->current_el != 0) && (imm == (s->thumb ? 0x3c : 0xf000))) { - gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST); + gen_exception_internal_insn(s, EXCP_SEMIHOST); return; } @@ -6556,7 +6556,7 @@ static bool trans_BKPT(DisasContext *s, arg_BKPT *a) if (arm_dc_feature(s, ARM_FEATURE_M) && semihosting_enabled(s->current_el == 0) && (a->imm == 0xab)) { - gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST); + gen_exception_internal_insn(s, EXCP_SEMIHOST); } else { gen_exception_bkpt_insn(s, syn_aa32_bkpt(a->imm, false)); } @@ -8762,7 +8762,7 @@ static bool trans_SVC(DisasContext *s, arg_SVC *a) if (!arm_dc_feature(s, ARM_FEATURE_M) && semihosting_enabled(s->current_el == 0) && (a->imm == semihost_imm)) { - gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST); + gen_exception_internal_insn(s, EXCP_SEMIHOST); } else { gen_update_pc(s, curr_insn_len(s)); s->svc_imm = a->imm; From bb0356170a60ce31d992ad273bdede2075724a29 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 20 Oct 2022 13:06:38 +1000 Subject: [PATCH 020/705] target/arm: Change gen_jmp* to work on displacements In preparation for TARGET_TB_PCREL, reduce reliance on absolute values. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20221020030641.2066807-7-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/translate.c | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/target/arm/translate.c b/target/arm/translate.c index 9104ab8232..ca128edab7 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -266,6 +266,12 @@ static uint32_t read_pc(DisasContext *s) return s->pc_curr + (s->thumb ? 4 : 8); } +/* The pc_curr difference for an architectural jump. */ +static target_long jmp_diff(DisasContext *s, target_long diff) +{ + return diff + (s->thumb ? 4 : 8); +} + /* Set a variable to the value of a CPU register. */ void load_reg_var(DisasContext *s, TCGv_i32 var, int reg) { @@ -2592,7 +2598,7 @@ static void gen_goto_ptr(void) * cpu_loop_exec. Any live exit_requests will be processed as we * enter the next TB. */ -static void gen_goto_tb(DisasContext *s, int n, int diff) +static void gen_goto_tb(DisasContext *s, int n, target_long diff) { target_ulong dest = s->pc_curr + diff; @@ -2608,10 +2614,8 @@ static void gen_goto_tb(DisasContext *s, int n, int diff) } /* Jump, specifying which TB number to use if we gen_goto_tb() */ -static inline void gen_jmp_tb(DisasContext *s, uint32_t dest, int tbno) +static void gen_jmp_tb(DisasContext *s, target_long diff, int tbno) { - int diff = dest - s->pc_curr; - if (unlikely(s->ss_active)) { /* An indirect jump so that we still trigger the debug exception. */ gen_update_pc(s, diff); @@ -2653,9 +2657,9 @@ static inline void gen_jmp_tb(DisasContext *s, uint32_t dest, int tbno) } } -static inline void gen_jmp(DisasContext *s, uint32_t dest) +static inline void gen_jmp(DisasContext *s, target_long diff) { - gen_jmp_tb(s, dest, 0); + gen_jmp_tb(s, diff, 0); } static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y) @@ -8322,7 +8326,7 @@ static bool trans_CLRM(DisasContext *s, arg_CLRM *a) static bool trans_B(DisasContext *s, arg_i *a) { - gen_jmp(s, read_pc(s) + a->imm); + gen_jmp(s, jmp_diff(s, a->imm)); return true; } @@ -8337,14 +8341,14 @@ static bool trans_B_cond_thumb(DisasContext *s, arg_ci *a) return true; } arm_skip_unless(s, a->cond); - gen_jmp(s, read_pc(s) + a->imm); + gen_jmp(s, jmp_diff(s, a->imm)); return true; } static bool trans_BL(DisasContext *s, arg_i *a) { tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb); - gen_jmp(s, read_pc(s) + a->imm); + gen_jmp(s, jmp_diff(s, a->imm)); return true; } @@ -8364,7 +8368,8 @@ static bool trans_BLX_i(DisasContext *s, arg_BLX_i *a) } tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb); store_cpu_field_constant(!s->thumb, thumb); - gen_jmp(s, (read_pc(s) & ~3) + a->imm); + /* This jump is computed from an aligned PC: subtract off the low bits. */ + gen_jmp(s, jmp_diff(s, a->imm - (s->pc_curr & 3))); return true; } @@ -8525,10 +8530,10 @@ static bool trans_WLS(DisasContext *s, arg_WLS *a) * when we take this upcoming exit from this TB, so gen_jmp_tb() is OK. */ } - gen_jmp_tb(s, s->base.pc_next, 1); + gen_jmp_tb(s, curr_insn_len(s), 1); gen_set_label(nextlabel); - gen_jmp(s, read_pc(s) + a->imm); + gen_jmp(s, jmp_diff(s, a->imm)); return true; } @@ -8608,7 +8613,7 @@ static bool trans_LE(DisasContext *s, arg_LE *a) if (a->f) { /* Loop-forever: just jump back to the loop start */ - gen_jmp(s, read_pc(s) - a->imm); + gen_jmp(s, jmp_diff(s, -a->imm)); return true; } @@ -8639,7 +8644,7 @@ static bool trans_LE(DisasContext *s, arg_LE *a) tcg_temp_free_i32(decr); } /* Jump back to the loop start */ - gen_jmp(s, read_pc(s) - a->imm); + gen_jmp(s, jmp_diff(s, -a->imm)); gen_set_label(loopend); if (a->tp) { @@ -8647,7 +8652,7 @@ static bool trans_LE(DisasContext *s, arg_LE *a) store_cpu_field(tcg_constant_i32(4), v7m.ltpsize); } /* End TB, continuing to following insn */ - gen_jmp_tb(s, s->base.pc_next, 1); + gen_jmp_tb(s, curr_insn_len(s), 1); return true; } @@ -8746,7 +8751,7 @@ static bool trans_CBZ(DisasContext *s, arg_CBZ *a) tcg_gen_brcondi_i32(a->nz ? TCG_COND_EQ : TCG_COND_NE, tmp, 0, s->condlabel); tcg_temp_free_i32(tmp); - gen_jmp(s, read_pc(s) + a->imm); + gen_jmp(s, jmp_diff(s, a->imm)); return true; } From 19f6b76baa10b96d37d545897c94f8738393481e Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 20 Oct 2022 13:06:39 +1000 Subject: [PATCH 021/705] target/arm: Introduce gen_pc_plus_diff for aarch64 In preparation for TARGET_TB_PCREL, reduce reliance on absolute values. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20221020030641.2066807-8-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/translate-a64.c | 41 +++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index 713f1a89a4..c231635295 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -140,9 +140,14 @@ static void reset_btype(DisasContext *s) } } +static void gen_pc_plus_diff(DisasContext *s, TCGv_i64 dest, target_long diff) +{ + tcg_gen_movi_i64(dest, s->pc_curr + diff); +} + void gen_a64_update_pc(DisasContext *s, target_long diff) { - tcg_gen_movi_i64(cpu_pc, s->pc_curr + diff); + gen_pc_plus_diff(s, cpu_pc, diff); } /* @@ -1360,7 +1365,7 @@ static void disas_uncond_b_imm(DisasContext *s, uint32_t insn) if (insn & (1U << 31)) { /* BL Branch with link */ - tcg_gen_movi_i64(cpu_reg(s, 30), s->base.pc_next); + gen_pc_plus_diff(s, cpu_reg(s, 30), curr_insn_len(s)); } /* B Branch / BL Branch with link */ @@ -2301,11 +2306,17 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn) default: goto do_unallocated; } - gen_a64_set_pc(s, dst); /* BLR also needs to load return address */ if (opc == 1) { - tcg_gen_movi_i64(cpu_reg(s, 30), s->base.pc_next); + TCGv_i64 lr = cpu_reg(s, 30); + if (dst == lr) { + TCGv_i64 tmp = new_tmp_a64(s); + tcg_gen_mov_i64(tmp, dst); + dst = tmp; + } + gen_pc_plus_diff(s, lr, curr_insn_len(s)); } + gen_a64_set_pc(s, dst); break; case 8: /* BRAA */ @@ -2328,11 +2339,17 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn) } else { dst = cpu_reg(s, rn); } - gen_a64_set_pc(s, dst); /* BLRAA also needs to load return address */ if (opc == 9) { - tcg_gen_movi_i64(cpu_reg(s, 30), s->base.pc_next); + TCGv_i64 lr = cpu_reg(s, 30); + if (dst == lr) { + TCGv_i64 tmp = new_tmp_a64(s); + tcg_gen_mov_i64(tmp, dst); + dst = tmp; + } + gen_pc_plus_diff(s, lr, curr_insn_len(s)); } + gen_a64_set_pc(s, dst); break; case 4: /* ERET */ @@ -2900,7 +2917,8 @@ static void disas_ld_lit(DisasContext *s, uint32_t insn) tcg_rt = cpu_reg(s, rt); - clean_addr = tcg_constant_i64(s->pc_curr + imm); + clean_addr = new_tmp_a64(s); + gen_pc_plus_diff(s, clean_addr, imm); if (is_vector) { do_fp_ld(s, rt, clean_addr, size); } else { @@ -4244,23 +4262,22 @@ static void disas_ldst(DisasContext *s, uint32_t insn) static void disas_pc_rel_adr(DisasContext *s, uint32_t insn) { unsigned int page, rd; - uint64_t base; - uint64_t offset; + int64_t offset; page = extract32(insn, 31, 1); /* SignExtend(immhi:immlo) -> offset */ offset = sextract64(insn, 5, 19); offset = offset << 2 | extract32(insn, 29, 2); rd = extract32(insn, 0, 5); - base = s->pc_curr; if (page) { /* ADRP (page based) */ - base &= ~0xfff; offset <<= 12; + /* The page offset is ok for TARGET_TB_PCREL. */ + offset -= s->pc_curr & 0xfff; } - tcg_gen_movi_i64(cpu_reg(s, rd), base + offset); + gen_pc_plus_diff(s, cpu_reg(s, rd), offset); } /* From 35dbeb81778d5c772e7ce42ea06429c419e707f1 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 20 Oct 2022 13:06:40 +1000 Subject: [PATCH 022/705] target/arm: Introduce gen_pc_plus_diff for aarch32 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In preparation for TARGET_TB_PCREL, reduce reliance on absolute values. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson Message-id: 20221020030641.2066807-9-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/translate.c | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/target/arm/translate.c b/target/arm/translate.c index ca128edab7..5f6bd9b5b7 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -260,23 +260,22 @@ static inline int get_a32_user_mem_index(DisasContext *s) } } -/* The architectural value of PC. */ -static uint32_t read_pc(DisasContext *s) -{ - return s->pc_curr + (s->thumb ? 4 : 8); -} - /* The pc_curr difference for an architectural jump. */ static target_long jmp_diff(DisasContext *s, target_long diff) { return diff + (s->thumb ? 4 : 8); } +static void gen_pc_plus_diff(DisasContext *s, TCGv_i32 var, target_long diff) +{ + tcg_gen_movi_i32(var, s->pc_curr + diff); +} + /* Set a variable to the value of a CPU register. */ void load_reg_var(DisasContext *s, TCGv_i32 var, int reg) { if (reg == 15) { - tcg_gen_movi_i32(var, read_pc(s)); + gen_pc_plus_diff(s, var, jmp_diff(s, 0)); } else { tcg_gen_mov_i32(var, cpu_R[reg]); } @@ -292,7 +291,11 @@ TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs) TCGv_i32 tmp = tcg_temp_new_i32(); if (reg == 15) { - tcg_gen_movi_i32(tmp, (read_pc(s) & ~3) + ofs); + /* + * This address is computed from an aligned PC: + * subtract off the low bits. + */ + gen_pc_plus_diff(s, tmp, jmp_diff(s, ofs - (s->pc_curr & 3))); } else { tcg_gen_addi_i32(tmp, cpu_R[reg], ofs); } @@ -1155,7 +1158,7 @@ void unallocated_encoding(DisasContext *s) /* Force a TB lookup after an instruction that changes the CPU state. */ void gen_lookup_tb(DisasContext *s) { - tcg_gen_movi_i32(cpu_R[15], s->base.pc_next); + gen_pc_plus_diff(s, cpu_R[15], curr_insn_len(s)); s->base.is_jmp = DISAS_EXIT; } @@ -6479,7 +6482,7 @@ static bool trans_BLX_r(DisasContext *s, arg_BLX_r *a) return false; } tmp = load_reg(s, a->rm); - tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb); + gen_pc_plus_diff(s, cpu_R[14], curr_insn_len(s) | s->thumb); gen_bx(s, tmp); return true; } @@ -8347,7 +8350,7 @@ static bool trans_B_cond_thumb(DisasContext *s, arg_ci *a) static bool trans_BL(DisasContext *s, arg_i *a) { - tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb); + gen_pc_plus_diff(s, cpu_R[14], curr_insn_len(s) | s->thumb); gen_jmp(s, jmp_diff(s, a->imm)); return true; } @@ -8366,7 +8369,7 @@ static bool trans_BLX_i(DisasContext *s, arg_BLX_i *a) if (s->thumb && (a->imm & 2)) { return false; } - tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb); + gen_pc_plus_diff(s, cpu_R[14], curr_insn_len(s) | s->thumb); store_cpu_field_constant(!s->thumb, thumb); /* This jump is computed from an aligned PC: subtract off the low bits. */ gen_jmp(s, jmp_diff(s, a->imm - (s->pc_curr & 3))); @@ -8376,7 +8379,7 @@ static bool trans_BLX_i(DisasContext *s, arg_BLX_i *a) static bool trans_BL_BLX_prefix(DisasContext *s, arg_BL_BLX_prefix *a) { assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2)); - tcg_gen_movi_i32(cpu_R[14], read_pc(s) + (a->imm << 12)); + gen_pc_plus_diff(s, cpu_R[14], jmp_diff(s, a->imm << 12)); return true; } @@ -8386,7 +8389,7 @@ static bool trans_BL_suffix(DisasContext *s, arg_BL_suffix *a) assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2)); tcg_gen_addi_i32(tmp, cpu_R[14], (a->imm << 1) | 1); - tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1); + gen_pc_plus_diff(s, cpu_R[14], curr_insn_len(s) | 1); gen_bx(s, tmp); return true; } @@ -8402,7 +8405,7 @@ static bool trans_BLX_suffix(DisasContext *s, arg_BLX_suffix *a) tmp = tcg_temp_new_i32(); tcg_gen_addi_i32(tmp, cpu_R[14], a->imm << 1); tcg_gen_andi_i32(tmp, tmp, 0xfffffffc); - tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1); + gen_pc_plus_diff(s, cpu_R[14], curr_insn_len(s) | 1); gen_bx(s, tmp); return true; } @@ -8725,10 +8728,11 @@ static bool op_tbranch(DisasContext *s, arg_tbranch *a, bool half) tcg_gen_add_i32(addr, addr, tmp); gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), half ? MO_UW : MO_UB); - tcg_temp_free_i32(addr); tcg_gen_add_i32(tmp, tmp, tmp); - tcg_gen_addi_i32(tmp, tmp, read_pc(s)); + gen_pc_plus_diff(s, addr, jmp_diff(s, 0)); + tcg_gen_add_i32(tmp, tmp, addr); + tcg_temp_free_i32(addr); store_reg(s, 15, tmp); return true; } From abb80995d722814c2e3f314629ef4c5700424ae7 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 20 Oct 2022 13:06:41 +1000 Subject: [PATCH 023/705] target/arm: Enable TARGET_TB_PCREL Signed-off-by: Richard Henderson Message-id: 20221020030641.2066807-10-richard.henderson@linaro.org Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- target/arm/cpu-param.h | 2 + target/arm/cpu.c | 23 ++++---- target/arm/translate-a64.c | 64 +++++++++++++------- target/arm/translate-m-nocp.c | 2 +- target/arm/translate.c | 108 +++++++++++++++++++++++----------- target/arm/translate.h | 50 +++++++++++++++- 6 files changed, 178 insertions(+), 71 deletions(-) diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h index b7bde18986..53cac9c89b 100644 --- a/target/arm/cpu-param.h +++ b/target/arm/cpu-param.h @@ -31,6 +31,8 @@ # define TARGET_PAGE_BITS_VARY # define TARGET_PAGE_BITS_MIN 10 +# define TARGET_TB_PCREL 1 + /* * Cache the attrs and shareability fields from the page table entry. * diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 94ca6f163f..0bc5e9b125 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -76,17 +76,18 @@ static vaddr arm_cpu_get_pc(CPUState *cs) void arm_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb) { - ARMCPU *cpu = ARM_CPU(cs); - CPUARMState *env = &cpu->env; - - /* - * It's OK to look at env for the current mode here, because it's - * never possible for an AArch64 TB to chain to an AArch32 TB. - */ - if (is_a64(env)) { - env->pc = tb_pc(tb); - } else { - env->regs[15] = tb_pc(tb); + /* The program counter is always up to date with TARGET_TB_PCREL. */ + if (!TARGET_TB_PCREL) { + CPUARMState *env = cs->env_ptr; + /* + * It's OK to look at env for the current mode here, because it's + * never possible for an AArch64 TB to chain to an AArch32 TB. + */ + if (is_a64(env)) { + env->pc = tb_pc(tb); + } else { + env->regs[15] = tb_pc(tb); + } } } #endif /* CONFIG_TCG */ diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index c231635295..2ee171f249 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -142,12 +142,18 @@ static void reset_btype(DisasContext *s) static void gen_pc_plus_diff(DisasContext *s, TCGv_i64 dest, target_long diff) { - tcg_gen_movi_i64(dest, s->pc_curr + diff); + assert(s->pc_save != -1); + if (TARGET_TB_PCREL) { + tcg_gen_addi_i64(dest, cpu_pc, (s->pc_curr - s->pc_save) + diff); + } else { + tcg_gen_movi_i64(dest, s->pc_curr + diff); + } } void gen_a64_update_pc(DisasContext *s, target_long diff) { gen_pc_plus_diff(s, cpu_pc, diff); + s->pc_save = s->pc_curr + diff; } /* @@ -201,6 +207,7 @@ static void gen_a64_set_pc(DisasContext *s, TCGv_i64 src) * then loading an address into the PC will clear out any tag. */ gen_top_byte_ignore(s, cpu_pc, src, s->tbii); + s->pc_save = -1; } /* @@ -377,11 +384,22 @@ static inline bool use_goto_tb(DisasContext *s, uint64_t dest) static void gen_goto_tb(DisasContext *s, int n, int64_t diff) { - uint64_t dest = s->pc_curr + diff; - - if (use_goto_tb(s, dest)) { - tcg_gen_goto_tb(n); - gen_a64_update_pc(s, diff); + if (use_goto_tb(s, s->pc_curr + diff)) { + /* + * For pcrel, the pc must always be up-to-date on entry to + * the linked TB, so that it can use simple additions for all + * further adjustments. For !pcrel, the linked TB is compiled + * to know its full virtual address, so we can delay the + * update to pc to the unlinked path. A long chain of links + * can thus avoid many updates to the PC. + */ + if (TARGET_TB_PCREL) { + gen_a64_update_pc(s, diff); + tcg_gen_goto_tb(n); + } else { + tcg_gen_goto_tb(n); + gen_a64_update_pc(s, diff); + } tcg_gen_exit_tb(s->base.tb, n); s->base.is_jmp = DISAS_NORETURN; } else { @@ -1383,7 +1401,7 @@ static void disas_comp_b_imm(DisasContext *s, uint32_t insn) { unsigned int sf, op, rt; int64_t diff; - TCGLabel *label_match; + DisasLabel match; TCGv_i64 tcg_cmp; sf = extract32(insn, 31, 1); @@ -1392,14 +1410,13 @@ static void disas_comp_b_imm(DisasContext *s, uint32_t insn) diff = sextract32(insn, 5, 19) * 4; tcg_cmp = read_cpu_reg(s, rt, sf); - label_match = gen_new_label(); - reset_btype(s); - tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ, - tcg_cmp, 0, label_match); + match = gen_disas_label(s); + tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ, + tcg_cmp, 0, match.label); gen_goto_tb(s, 0, 4); - gen_set_label(label_match); + set_disas_label(s, match); gen_goto_tb(s, 1, diff); } @@ -1413,7 +1430,7 @@ static void disas_test_b_imm(DisasContext *s, uint32_t insn) { unsigned int bit_pos, op, rt; int64_t diff; - TCGLabel *label_match; + DisasLabel match; TCGv_i64 tcg_cmp; bit_pos = (extract32(insn, 31, 1) << 5) | extract32(insn, 19, 5); @@ -1423,14 +1440,15 @@ static void disas_test_b_imm(DisasContext *s, uint32_t insn) tcg_cmp = tcg_temp_new_i64(); tcg_gen_andi_i64(tcg_cmp, cpu_reg(s, rt), (1ULL << bit_pos)); - label_match = gen_new_label(); reset_btype(s); + + match = gen_disas_label(s); tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ, - tcg_cmp, 0, label_match); + tcg_cmp, 0, match.label); tcg_temp_free_i64(tcg_cmp); gen_goto_tb(s, 0, 4); - gen_set_label(label_match); + set_disas_label(s, match); gen_goto_tb(s, 1, diff); } @@ -1455,10 +1473,10 @@ static void disas_cond_b_imm(DisasContext *s, uint32_t insn) reset_btype(s); if (cond < 0x0e) { /* genuinely conditional branches */ - TCGLabel *label_match = gen_new_label(); - arm_gen_test_cc(cond, label_match); + DisasLabel match = gen_disas_label(s); + arm_gen_test_cc(cond, match.label); gen_goto_tb(s, 0, 4); - gen_set_label(label_match); + set_disas_label(s, match); gen_goto_tb(s, 1, diff); } else { /* 0xe and 0xf are both "always" conditions */ @@ -14698,7 +14716,7 @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase, dc->isar = &arm_cpu->isar; dc->condjmp = 0; - + dc->pc_save = dc->base.pc_first; dc->aarch64 = true; dc->thumb = false; dc->sctlr_b = 0; @@ -14780,8 +14798,12 @@ static void aarch64_tr_tb_start(DisasContextBase *db, CPUState *cpu) static void aarch64_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu) { DisasContext *dc = container_of(dcbase, DisasContext, base); + target_ulong pc_arg = dc->base.pc_next; - tcg_gen_insn_start(dc->base.pc_next, 0, 0); + if (TARGET_TB_PCREL) { + pc_arg &= ~TARGET_PAGE_MASK; + } + tcg_gen_insn_start(pc_arg, 0, 0); dc->insn_start = tcg_last_op(); } diff --git a/target/arm/translate-m-nocp.c b/target/arm/translate-m-nocp.c index 694fae7e2e..5df7d46120 100644 --- a/target/arm/translate-m-nocp.c +++ b/target/arm/translate-m-nocp.c @@ -140,7 +140,7 @@ static bool trans_VSCCLRM(DisasContext *s, arg_VSCCLRM *a) tcg_gen_andi_i32(sfpa, sfpa, R_V7M_CONTROL_SFPA_MASK); tcg_gen_or_i32(sfpa, sfpa, aspen); arm_gen_condlabel(s); - tcg_gen_brcondi_i32(TCG_COND_EQ, sfpa, 0, s->condlabel); + tcg_gen_brcondi_i32(TCG_COND_EQ, sfpa, 0, s->condlabel.label); if (s->fp_excp_el != 0) { gen_exception_insn_el(s, 0, EXCP_NOCP, diff --git a/target/arm/translate.c b/target/arm/translate.c index 5f6bd9b5b7..d1b868430e 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -162,7 +162,7 @@ uint64_t asimd_imm_const(uint32_t imm, int cmode, int op) void arm_gen_condlabel(DisasContext *s) { if (!s->condjmp) { - s->condlabel = gen_new_label(); + s->condlabel = gen_disas_label(s); s->condjmp = 1; } } @@ -268,7 +268,12 @@ static target_long jmp_diff(DisasContext *s, target_long diff) static void gen_pc_plus_diff(DisasContext *s, TCGv_i32 var, target_long diff) { - tcg_gen_movi_i32(var, s->pc_curr + diff); + assert(s->pc_save != -1); + if (TARGET_TB_PCREL) { + tcg_gen_addi_i32(var, cpu_R[15], (s->pc_curr - s->pc_save) + diff); + } else { + tcg_gen_movi_i32(var, s->pc_curr + diff); + } } /* Set a variable to the value of a CPU register. */ @@ -314,6 +319,7 @@ void store_reg(DisasContext *s, int reg, TCGv_i32 var) */ tcg_gen_andi_i32(var, var, s->thumb ? ~1 : ~3); s->base.is_jmp = DISAS_JUMP; + s->pc_save = -1; } else if (reg == 13 && arm_dc_feature(s, ARM_FEATURE_M)) { /* For M-profile SP bits [1:0] are always zero */ tcg_gen_andi_i32(var, var, ~3); @@ -779,7 +785,8 @@ void gen_set_condexec(DisasContext *s) void gen_update_pc(DisasContext *s, target_long diff) { - tcg_gen_movi_i32(cpu_R[15], s->pc_curr + diff); + gen_pc_plus_diff(s, cpu_R[15], diff); + s->pc_save = s->pc_curr + diff; } /* Set PC and Thumb state from var. var is marked as dead. */ @@ -789,6 +796,7 @@ static inline void gen_bx(DisasContext *s, TCGv_i32 var) tcg_gen_andi_i32(cpu_R[15], var, ~1); tcg_gen_andi_i32(var, var, 1); store_cpu_field(var, thumb); + s->pc_save = -1; } /* @@ -830,7 +838,7 @@ static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var) static inline void gen_bx_excret_final_code(DisasContext *s) { /* Generate the code to finish possible exception return and end the TB */ - TCGLabel *excret_label = gen_new_label(); + DisasLabel excret_label = gen_disas_label(s); uint32_t min_magic; if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY)) { @@ -842,14 +850,14 @@ static inline void gen_bx_excret_final_code(DisasContext *s) } /* Is the new PC value in the magic range indicating exception return? */ - tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], min_magic, excret_label); + tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], min_magic, excret_label.label); /* No: end the TB as we would for a DISAS_JMP */ if (s->ss_active) { gen_singlestep_exception(s); } else { tcg_gen_exit_tb(NULL, 0); } - gen_set_label(excret_label); + set_disas_label(s, excret_label); /* Yes: this is an exception return. * At this point in runtime env->regs[15] and env->thumb will hold * the exception-return magic number, which do_v7m_exception_exit() @@ -2603,11 +2611,22 @@ static void gen_goto_ptr(void) */ static void gen_goto_tb(DisasContext *s, int n, target_long diff) { - target_ulong dest = s->pc_curr + diff; - - if (translator_use_goto_tb(&s->base, dest)) { - tcg_gen_goto_tb(n); - gen_update_pc(s, diff); + if (translator_use_goto_tb(&s->base, s->pc_curr + diff)) { + /* + * For pcrel, the pc must always be up-to-date on entry to + * the linked TB, so that it can use simple additions for all + * further adjustments. For !pcrel, the linked TB is compiled + * to know its full virtual address, so we can delay the + * update to pc to the unlinked path. A long chain of links + * can thus avoid many updates to the PC. + */ + if (TARGET_TB_PCREL) { + gen_update_pc(s, diff); + tcg_gen_goto_tb(n); + } else { + tcg_gen_goto_tb(n); + gen_update_pc(s, diff); + } tcg_gen_exit_tb(s->base.tb, n); } else { gen_update_pc(s, diff); @@ -5221,7 +5240,7 @@ static void gen_srs(DisasContext *s, static void arm_skip_unless(DisasContext *s, uint32_t cond) { arm_gen_condlabel(s); - arm_gen_test_cc(cond ^ 1, s->condlabel); + arm_gen_test_cc(cond ^ 1, s->condlabel.label); } @@ -8472,7 +8491,7 @@ static bool trans_WLS(DisasContext *s, arg_WLS *a) { /* M-profile low-overhead while-loop start */ TCGv_i32 tmp; - TCGLabel *nextlabel; + DisasLabel nextlabel; if (!dc_isar_feature(aa32_lob, s)) { return false; @@ -8513,8 +8532,8 @@ static bool trans_WLS(DisasContext *s, arg_WLS *a) } } - nextlabel = gen_new_label(); - tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_R[a->rn], 0, nextlabel); + nextlabel = gen_disas_label(s); + tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_R[a->rn], 0, nextlabel.label); tmp = load_reg(s, a->rn); store_reg(s, 14, tmp); if (a->size != 4) { @@ -8535,7 +8554,7 @@ static bool trans_WLS(DisasContext *s, arg_WLS *a) } gen_jmp_tb(s, curr_insn_len(s), 1); - gen_set_label(nextlabel); + set_disas_label(s, nextlabel); gen_jmp(s, jmp_diff(s, a->imm)); return true; } @@ -8551,7 +8570,7 @@ static bool trans_LE(DisasContext *s, arg_LE *a) * any faster. */ TCGv_i32 tmp; - TCGLabel *loopend; + DisasLabel loopend; bool fpu_active; if (!dc_isar_feature(aa32_lob, s)) { @@ -8606,12 +8625,12 @@ static bool trans_LE(DisasContext *s, arg_LE *a) if (!a->tp && dc_isar_feature(aa32_mve, s) && fpu_active) { /* Need to do a runtime check for LTPSIZE != 4 */ - TCGLabel *skipexc = gen_new_label(); + DisasLabel skipexc = gen_disas_label(s); tmp = load_cpu_field(v7m.ltpsize); - tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 4, skipexc); + tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 4, skipexc.label); tcg_temp_free_i32(tmp); gen_exception_insn(s, 0, EXCP_INVSTATE, syn_uncategorized()); - gen_set_label(skipexc); + set_disas_label(s, skipexc); } if (a->f) { @@ -8626,9 +8645,9 @@ static bool trans_LE(DisasContext *s, arg_LE *a) * loop decrement value is 1. For LETP we need to calculate the decrement * value from LTPSIZE. */ - loopend = gen_new_label(); + loopend = gen_disas_label(s); if (!a->tp) { - tcg_gen_brcondi_i32(TCG_COND_LEU, cpu_R[14], 1, loopend); + tcg_gen_brcondi_i32(TCG_COND_LEU, cpu_R[14], 1, loopend.label); tcg_gen_addi_i32(cpu_R[14], cpu_R[14], -1); } else { /* @@ -8641,7 +8660,7 @@ static bool trans_LE(DisasContext *s, arg_LE *a) tcg_gen_shl_i32(decr, tcg_constant_i32(1), decr); tcg_temp_free_i32(ltpsize); - tcg_gen_brcond_i32(TCG_COND_LEU, cpu_R[14], decr, loopend); + tcg_gen_brcond_i32(TCG_COND_LEU, cpu_R[14], decr, loopend.label); tcg_gen_sub_i32(cpu_R[14], cpu_R[14], decr); tcg_temp_free_i32(decr); @@ -8649,7 +8668,7 @@ static bool trans_LE(DisasContext *s, arg_LE *a) /* Jump back to the loop start */ gen_jmp(s, jmp_diff(s, -a->imm)); - gen_set_label(loopend); + set_disas_label(s, loopend); if (a->tp) { /* Exits from tail-pred loops must reset LTPSIZE to 4 */ store_cpu_field(tcg_constant_i32(4), v7m.ltpsize); @@ -8753,7 +8772,7 @@ static bool trans_CBZ(DisasContext *s, arg_CBZ *a) arm_gen_condlabel(s); tcg_gen_brcondi_i32(a->nz ? TCG_COND_EQ : TCG_COND_NE, - tmp, 0, s->condlabel); + tmp, 0, s->condlabel.label); tcg_temp_free_i32(tmp); gen_jmp(s, jmp_diff(s, a->imm)); return true; @@ -9319,7 +9338,7 @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) dc->isar = &cpu->isar; dc->condjmp = 0; - + dc->pc_save = dc->base.pc_first; dc->aarch64 = false; dc->thumb = EX_TBFLAG_AM32(tb_flags, THUMB); dc->be_data = EX_TBFLAG_ANY(tb_flags, BE_DATA) ? MO_BE : MO_LE; @@ -9337,7 +9356,6 @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) */ dc->eci = dc->condexec_mask = dc->condexec_cond = 0; dc->eci_handled = false; - dc->insn_eci_rewind = NULL; if (condexec & 0xf) { dc->condexec_mask = (condexec & 0xf) << 1; dc->condexec_cond = condexec >> 4; @@ -9473,13 +9491,17 @@ static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu) * fields here. */ uint32_t condexec_bits; + target_ulong pc_arg = dc->base.pc_next; + if (TARGET_TB_PCREL) { + pc_arg &= ~TARGET_PAGE_MASK; + } if (dc->eci) { condexec_bits = dc->eci << 4; } else { condexec_bits = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1); } - tcg_gen_insn_start(dc->base.pc_next, condexec_bits, 0); + tcg_gen_insn_start(pc_arg, condexec_bits, 0); dc->insn_start = tcg_last_op(); } @@ -9522,8 +9544,11 @@ static bool arm_check_ss_active(DisasContext *dc) static void arm_post_translate_insn(DisasContext *dc) { - if (dc->condjmp && !dc->base.is_jmp) { - gen_set_label(dc->condlabel); + if (dc->condjmp && dc->base.is_jmp == DISAS_NEXT) { + if (dc->pc_save != dc->condlabel.pc_save) { + gen_update_pc(dc, dc->condlabel.pc_save - dc->pc_save); + } + gen_set_label(dc->condlabel.label); dc->condjmp = 0; } translator_loop_temp_check(&dc->base); @@ -9626,6 +9651,9 @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) uint32_t pc = dc->base.pc_next; uint32_t insn; bool is_16bit; + /* TCG op to rewind to if this turns out to be an invalid ECI state */ + TCGOp *insn_eci_rewind = NULL; + target_ulong insn_eci_pc_save = -1; /* Misaligned thumb PC is architecturally impossible. */ assert((dc->base.pc_next & 1) == 0); @@ -9687,7 +9715,8 @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) * insn" case. We will rewind to the marker (ie throwing away * all the generated code) and instead emit "take exception". */ - dc->insn_eci_rewind = tcg_last_op(); + insn_eci_rewind = tcg_last_op(); + insn_eci_pc_save = dc->pc_save; } if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) { @@ -9723,7 +9752,8 @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) * Insn wasn't valid for ECI/ICI at all: undo what we * just generated and instead emit an exception */ - tcg_remove_ops_after(dc->insn_eci_rewind); + tcg_remove_ops_after(insn_eci_rewind); + dc->pc_save = insn_eci_pc_save; dc->condjmp = 0; gen_exception_insn(dc, 0, EXCP_INVSTATE, syn_uncategorized()); } @@ -9852,7 +9882,7 @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) if (dc->condjmp) { /* "Condition failed" instruction codepath for the branch/trap insn */ - gen_set_label(dc->condlabel); + set_disas_label(dc, dc->condlabel); gen_set_condexec(dc); if (unlikely(dc->ss_active)) { gen_update_pc(dc, curr_insn_len(dc)); @@ -9914,11 +9944,19 @@ void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, target_ulong *data) { if (is_a64(env)) { - env->pc = data[0]; + if (TARGET_TB_PCREL) { + env->pc = (env->pc & TARGET_PAGE_MASK) | data[0]; + } else { + env->pc = data[0]; + } env->condexec_bits = 0; env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT; } else { - env->regs[15] = data[0]; + if (TARGET_TB_PCREL) { + env->regs[15] = (env->regs[15] & TARGET_PAGE_MASK) | data[0]; + } else { + env->regs[15] = data[0]; + } env->condexec_bits = data[1]; env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT; } diff --git a/target/arm/translate.h b/target/arm/translate.h index 4aa239e23c..3cdc7dbc2f 100644 --- a/target/arm/translate.h +++ b/target/arm/translate.h @@ -6,18 +6,42 @@ /* internal defines */ + +/* + * Save pc_save across a branch, so that we may restore the value from + * before the branch at the point the label is emitted. + */ +typedef struct DisasLabel { + TCGLabel *label; + target_ulong pc_save; +} DisasLabel; + typedef struct DisasContext { DisasContextBase base; const ARMISARegisters *isar; /* The address of the current instruction being translated. */ target_ulong pc_curr; + /* + * For TARGET_TB_PCREL, the full value of cpu_pc is not known + * (although the page offset is known). For convenience, the + * translation loop uses the full virtual address that triggered + * the translation, from base.pc_start through pc_curr. + * For efficiency, we do not update cpu_pc for every instruction. + * Instead, pc_save has the value of pc_curr at the time of the + * last update to cpu_pc, which allows us to compute the addend + * needed to bring cpu_pc current: pc_curr - pc_save. + * If cpu_pc now contains the destination of an indirect branch, + * pc_save contains -1 to indicate that relative updates are no + * longer possible. + */ + target_ulong pc_save; target_ulong page_start; uint32_t insn; /* Nonzero if this instruction has been conditionally skipped. */ int condjmp; /* The label that will be jumped to when the instruction is skipped. */ - TCGLabel *condlabel; + DisasLabel condlabel; /* Thumb-2 conditional execution bits. */ int condexec_mask; int condexec_cond; @@ -28,8 +52,6 @@ typedef struct DisasContext { * after decode (ie after any UNDEF checks) */ bool eci_handled; - /* TCG op to rewind to if this turns out to be an invalid ECI state */ - TCGOp *insn_eci_rewind; int sctlr_b; MemOp be_data; #if !defined(CONFIG_USER_ONLY) @@ -566,6 +588,28 @@ static inline MemOp finalize_memop(DisasContext *s, MemOp opc) */ uint64_t asimd_imm_const(uint32_t imm, int cmode, int op); +/* + * gen_disas_label: + * Create a label and cache a copy of pc_save. + */ +static inline DisasLabel gen_disas_label(DisasContext *s) +{ + return (DisasLabel){ + .label = gen_new_label(), + .pc_save = s->pc_save, + }; +} + +/* + * set_disas_label: + * Emit a label and restore the cached copy of pc_save. + */ +static inline void set_disas_label(DisasContext *s, DisasLabel l) +{ + gen_set_label(l.label); + s->pc_save = l.pc_save; +} + /* * Helpers for implementing sets of trans_* functions. * Defer the implementation of NAME to FUNC, with optional extra arguments. From 5db899303799e49209016a93289b8694afa1449e Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 13 Oct 2022 18:40:42 +0100 Subject: [PATCH 024/705] hw/ide/microdrive: Use device_cold_reset() for self-resets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently the microdrive code uses device_legacy_reset() to reset itself, and has its reset method call reset on the IDE bus as the last thing it does. Switch to using device_cold_reset(). The only concrete microdrive device is the TYPE_DSCM1XXXX; it is not command-line pluggable, so it is used only by the old pxa2xx Arm boards 'akita', 'borzoi', 'spitz', 'terrier' and 'tosa'. You might think that this would result in the IDE bus being reset automatically, but it does not, because the IDEBus type does not set the BusClass::reset method. Instead the controller must explicitly call ide_bus_reset(). We therefore leave that call in md_reset(). Note also that because the PCMCIA card device is a direct subclass of TYPE_DEVICE and we don't model the PCMCIA controller-to-card interface as a qbus, PCMCIA cards are not on any qbus and so they don't get reset when the system is reset. The reset only happens via the dscm1xxxx_attach() and dscm1xxxx_detach() functions during machine creation. Because our aim here is merely to try to get rid of calls to the device_legacy_reset() function, we leave these other dubious reset-related issues alone. (They all stem from this code being absolutely ancient.) Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Message-id: 20221013174042.1602926-1-peter.maydell@linaro.org --- hw/ide/microdrive.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/ide/microdrive.c b/hw/ide/microdrive.c index 6df9b4cbbe..56c5be3655 100644 --- a/hw/ide/microdrive.c +++ b/hw/ide/microdrive.c @@ -175,7 +175,7 @@ static void md_attr_write(PCMCIACardState *card, uint32_t at, uint8_t value) case 0x00: /* Configuration Option Register */ s->opt = value & 0xcf; if (value & OPT_SRESET) { - device_legacy_reset(DEVICE(s)); + device_cold_reset(DEVICE(s)); } md_interrupt_update(s); break; @@ -318,7 +318,7 @@ static void md_common_write(PCMCIACardState *card, uint32_t at, uint16_t value) case 0xe: /* Device Control */ s->ctrl = value; if (value & CTRL_SRST) { - device_legacy_reset(DEVICE(s)); + device_cold_reset(DEVICE(s)); } md_interrupt_update(s); break; @@ -543,7 +543,7 @@ static int dscm1xxxx_attach(PCMCIACardState *card) md->attr_base = pcc->cis[0x74] | (pcc->cis[0x76] << 8); md->io_base = 0x0; - device_legacy_reset(DEVICE(md)); + device_cold_reset(DEVICE(md)); md_interrupt_update(md); return 0; @@ -553,7 +553,7 @@ static int dscm1xxxx_detach(PCMCIACardState *card) { MicroDriveState *md = MICRODRIVE(card); - device_legacy_reset(DEVICE(md)); + device_cold_reset(DEVICE(md)); return 0; } From 0d4bcac3cac461798d810e6df54768d9613ea794 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 19 Oct 2022 14:32:04 +0200 Subject: [PATCH 025/705] target/i386: decode-new: avoid out-of-bounds access to xmm_regs[-1] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the destination is a memory register, op->n is -1. Going through tcg_gen_gvec_dup_imm path is both useless (the value has been stored by the gen_* function already) and wrong because of the out-of-bounds access. Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Signed-off-by: Paolo Bonzini --- target/i386/tcg/emit.c.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc index 27eca591a9..ebf299451d 100644 --- a/target/i386/tcg/emit.c.inc +++ b/target/i386/tcg/emit.c.inc @@ -296,7 +296,7 @@ static void gen_writeback(DisasContext *s, X86DecodedInsn *decode, int opn, TCGv case X86_OP_MMX: break; case X86_OP_SSE: - if ((s->prefix & PREFIX_VEX) && op->ot == MO_128) { + if (!op->has_ea && (s->prefix & PREFIX_VEX) && op->ot == MO_128) { tcg_gen_gvec_dup_imm(MO_64, offsetof(CPUX86State, xmm_regs[op->n].ZMM_X(1)), 16, 16, 0); From 314d3eff66f41f39191aaca2e5f6e3dc81480c1b Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 19 Oct 2022 14:01:36 +0200 Subject: [PATCH 026/705] target/i386: introduce function to set rounding mode from FPCW or MXCSR bits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit VROUND, FSTCW and STMXCSR all have to perform the same conversion from x86 rounding modes to softfloat constants. Since the ISA is consistent on the meaning of the two-bit rounding modes, extract the common code into a wrapper for set_float_rounding_mode. Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Signed-off-by: Paolo Bonzini --- target/i386/ops_sse.h | 60 +++--------------------------------- target/i386/tcg/fpu_helper.c | 60 +++++++++++++----------------------- 2 files changed, 25 insertions(+), 95 deletions(-) diff --git a/target/i386/ops_sse.h b/target/i386/ops_sse.h index d35fc15c65..0799712f6e 100644 --- a/target/i386/ops_sse.h +++ b/target/i386/ops_sse.h @@ -1684,20 +1684,7 @@ void glue(helper_roundps, SUFFIX)(CPUX86State *env, Reg *d, Reg *s, prev_rounding_mode = env->sse_status.float_rounding_mode; if (!(mode & (1 << 2))) { - switch (mode & 3) { - case 0: - set_float_rounding_mode(float_round_nearest_even, &env->sse_status); - break; - case 1: - set_float_rounding_mode(float_round_down, &env->sse_status); - break; - case 2: - set_float_rounding_mode(float_round_up, &env->sse_status); - break; - case 3: - set_float_rounding_mode(float_round_to_zero, &env->sse_status); - break; - } + set_x86_rounding_mode(mode & 3, &env->sse_status); } for (i = 0; i < 2 << SHIFT; i++) { @@ -1721,20 +1708,7 @@ void glue(helper_roundpd, SUFFIX)(CPUX86State *env, Reg *d, Reg *s, prev_rounding_mode = env->sse_status.float_rounding_mode; if (!(mode & (1 << 2))) { - switch (mode & 3) { - case 0: - set_float_rounding_mode(float_round_nearest_even, &env->sse_status); - break; - case 1: - set_float_rounding_mode(float_round_down, &env->sse_status); - break; - case 2: - set_float_rounding_mode(float_round_up, &env->sse_status); - break; - case 3: - set_float_rounding_mode(float_round_to_zero, &env->sse_status); - break; - } + set_x86_rounding_mode(mode & 3, &env->sse_status); } for (i = 0; i < 1 << SHIFT; i++) { @@ -1759,20 +1733,7 @@ void glue(helper_roundss, SUFFIX)(CPUX86State *env, Reg *d, Reg *v, Reg *s, prev_rounding_mode = env->sse_status.float_rounding_mode; if (!(mode & (1 << 2))) { - switch (mode & 3) { - case 0: - set_float_rounding_mode(float_round_nearest_even, &env->sse_status); - break; - case 1: - set_float_rounding_mode(float_round_down, &env->sse_status); - break; - case 2: - set_float_rounding_mode(float_round_up, &env->sse_status); - break; - case 3: - set_float_rounding_mode(float_round_to_zero, &env->sse_status); - break; - } + set_x86_rounding_mode(mode & 3, &env->sse_status); } d->ZMM_S(0) = float32_round_to_int(s->ZMM_S(0), &env->sse_status); @@ -1797,20 +1758,7 @@ void glue(helper_roundsd, SUFFIX)(CPUX86State *env, Reg *d, Reg *v, Reg *s, prev_rounding_mode = env->sse_status.float_rounding_mode; if (!(mode & (1 << 2))) { - switch (mode & 3) { - case 0: - set_float_rounding_mode(float_round_nearest_even, &env->sse_status); - break; - case 1: - set_float_rounding_mode(float_round_down, &env->sse_status); - break; - case 2: - set_float_rounding_mode(float_round_up, &env->sse_status); - break; - case 3: - set_float_rounding_mode(float_round_to_zero, &env->sse_status); - break; - } + set_x86_rounding_mode(mode & 3, &env->sse_status); } d->ZMM_D(0) = float64_round_to_int(s->ZMM_D(0), &env->sse_status); diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c index a6a90a1817..6f3741b635 100644 --- a/target/i386/tcg/fpu_helper.c +++ b/target/i386/tcg/fpu_helper.c @@ -32,7 +32,8 @@ #define ST(n) (env->fpregs[(env->fpstt + (n)) & 7].d) #define ST1 ST(1) -#define FPU_RC_MASK 0xc00 +#define FPU_RC_SHIFT 10 +#define FPU_RC_MASK (3 << FPU_RC_SHIFT) #define FPU_RC_NEAR 0x000 #define FPU_RC_DOWN 0x400 #define FPU_RC_UP 0x800 @@ -685,28 +686,26 @@ uint32_t helper_fnstcw(CPUX86State *env) return env->fpuc; } +static void set_x86_rounding_mode(unsigned mode, float_status *status) +{ + static FloatRoundMode x86_round_mode[4] = { + float_round_nearest_even, + float_round_down, + float_round_up, + float_round_to_zero + }; + assert(mode < ARRAY_SIZE(x86_round_mode)); + set_float_rounding_mode(x86_round_mode[mode], status); +} + void update_fp_status(CPUX86State *env) { - FloatRoundMode rnd_mode; + int rnd_mode; FloatX80RoundPrec rnd_prec; /* set rounding mode */ - switch (env->fpuc & FPU_RC_MASK) { - default: - case FPU_RC_NEAR: - rnd_mode = float_round_nearest_even; - break; - case FPU_RC_DOWN: - rnd_mode = float_round_down; - break; - case FPU_RC_UP: - rnd_mode = float_round_up; - break; - case FPU_RC_CHOP: - rnd_mode = float_round_to_zero; - break; - } - set_float_rounding_mode(rnd_mode, &env->fp_status); + rnd_mode = (env->fpuc & FPU_RC_MASK) >> FPU_RC_SHIFT; + set_x86_rounding_mode(rnd_mode, &env->fp_status); switch ((env->fpuc >> 8) & 3) { case 0: @@ -3038,11 +3037,8 @@ void helper_xsetbv(CPUX86State *env, uint32_t ecx, uint64_t mask) /* XXX: optimize by storing fptt and fptags in the static cpu state */ #define SSE_DAZ 0x0040 -#define SSE_RC_MASK 0x6000 -#define SSE_RC_NEAR 0x0000 -#define SSE_RC_DOWN 0x2000 -#define SSE_RC_UP 0x4000 -#define SSE_RC_CHOP 0x6000 +#define SSE_RC_SHIFT 13 +#define SSE_RC_MASK (3 << SSE_RC_SHIFT) #define SSE_FZ 0x8000 void update_mxcsr_status(CPUX86State *env) @@ -3051,22 +3047,8 @@ void update_mxcsr_status(CPUX86State *env) int rnd_type; /* set rounding mode */ - switch (mxcsr & SSE_RC_MASK) { - default: - case SSE_RC_NEAR: - rnd_type = float_round_nearest_even; - break; - case SSE_RC_DOWN: - rnd_type = float_round_down; - break; - case SSE_RC_UP: - rnd_type = float_round_up; - break; - case SSE_RC_CHOP: - rnd_type = float_round_to_zero; - break; - } - set_float_rounding_mode(rnd_type, &env->sse_status); + rnd_type = (mxcsr & SSE_RC_MASK) >> SSE_RC_SHIFT; + set_x86_rounding_mode(rnd_type, &env->sse_status); /* Set exception flags. */ set_float_exception_flags((mxcsr & FPUS_IE ? float_flag_invalid : 0) | From cf5ec6641ed456e2748b211b7bbf5103bfc93098 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 19 Oct 2022 13:22:06 +0200 Subject: [PATCH 027/705] target/i386: implement F16C instructions F16C only consists of two instructions, which are a bit peculiar nevertheless. First, they access only the low half of an YMM or XMM register for the packed-half operand; the exact size still depends on the VEX.L flag. This is similar to the existing avx_movx flag, but not exactly because avx_movx is hardcoded to affect operand 2. To this end I added a "ph" format name; it's possible to reuse this approach for the VPMOVSX and VPMOVZX instructions, though that would also require adding two more formats for the low-quarter and low-eighth of an operand. Second, VCVTPS2PH is somewhat weird because it *stores* the result of the instruction into memory rather than loading it. Reviewed-by: Richard Henderson Signed-off-by: Paolo Bonzini --- target/i386/cpu.c | 5 ++--- target/i386/cpu.h | 3 +++ target/i386/ops_sse.h | 29 +++++++++++++++++++++++++++++ target/i386/ops_sse_header.h | 6 ++++++ target/i386/tcg/decode-new.c.inc | 8 ++++++++ target/i386/tcg/decode-new.h | 2 ++ target/i386/tcg/emit.c.inc | 17 ++++++++++++++++- tests/tcg/i386/test-avx.c | 17 +++++++++++++++++ tests/tcg/i386/test-avx.py | 8 ++++++-- 9 files changed, 89 insertions(+), 6 deletions(-) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 0ebd610faa..6292b7e12f 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -625,13 +625,12 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1, CPUID_EXT_SSE41 | CPUID_EXT_SSE42 | CPUID_EXT_POPCNT | \ CPUID_EXT_XSAVE | /* CPUID_EXT_OSXSAVE is dynamic */ \ CPUID_EXT_MOVBE | CPUID_EXT_AES | CPUID_EXT_HYPERVISOR | \ - CPUID_EXT_RDRAND | CPUID_EXT_AVX) + CPUID_EXT_RDRAND | CPUID_EXT_AVX | CPUID_EXT_F16C) /* missing: CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_SMX, CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_CID, CPUID_EXT_FMA, CPUID_EXT_XTPR, CPUID_EXT_PDCM, CPUID_EXT_PCID, CPUID_EXT_DCA, - CPUID_EXT_X2APIC, CPUID_EXT_TSC_DEADLINE_TIMER, - CPUID_EXT_F16C */ + CPUID_EXT_X2APIC, CPUID_EXT_TSC_DEADLINE_TIMER */ #ifdef TARGET_X86_64 #define TCG_EXT2_X86_64_FEATURES (CPUID_EXT2_SYSCALL | CPUID_EXT2_LM) diff --git a/target/i386/cpu.h b/target/i386/cpu.h index dad2b2db8d..d4bc19577a 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -1258,6 +1258,7 @@ typedef union ZMMReg { uint16_t _w_ZMMReg[512 / 16]; uint32_t _l_ZMMReg[512 / 32]; uint64_t _q_ZMMReg[512 / 64]; + float16 _h_ZMMReg[512 / 16]; float32 _s_ZMMReg[512 / 32]; float64 _d_ZMMReg[512 / 64]; XMMReg _x_ZMMReg[512 / 128]; @@ -1282,6 +1283,7 @@ typedef struct BNDCSReg { #define ZMM_B(n) _b_ZMMReg[63 - (n)] #define ZMM_W(n) _w_ZMMReg[31 - (n)] #define ZMM_L(n) _l_ZMMReg[15 - (n)] +#define ZMM_H(n) _h_ZMMReg[31 - (n)] #define ZMM_S(n) _s_ZMMReg[15 - (n)] #define ZMM_Q(n) _q_ZMMReg[7 - (n)] #define ZMM_D(n) _d_ZMMReg[7 - (n)] @@ -1301,6 +1303,7 @@ typedef struct BNDCSReg { #define ZMM_B(n) _b_ZMMReg[n] #define ZMM_W(n) _w_ZMMReg[n] #define ZMM_L(n) _l_ZMMReg[n] +#define ZMM_H(n) _h_ZMMReg[n] #define ZMM_S(n) _s_ZMMReg[n] #define ZMM_Q(n) _q_ZMMReg[n] #define ZMM_D(n) _d_ZMMReg[n] diff --git a/target/i386/ops_sse.h b/target/i386/ops_sse.h index 0799712f6e..33c61896ee 100644 --- a/target/i386/ops_sse.h +++ b/target/i386/ops_sse.h @@ -586,6 +586,35 @@ void glue(helper_cvtpd2ps, SUFFIX)(CPUX86State *env, Reg *d, Reg *s) } } +#if SHIFT >= 1 +void glue(helper_cvtph2ps, SUFFIX)(CPUX86State *env, Reg *d, Reg *s) +{ + int i; + + for (i = 2 << SHIFT; --i >= 0; ) { + d->ZMM_S(i) = float16_to_float32(s->ZMM_H(i), true, &env->sse_status); + } +} + +void glue(helper_cvtps2ph, SUFFIX)(CPUX86State *env, Reg *d, Reg *s, int mode) +{ + int i; + FloatRoundMode prev_rounding_mode = env->sse_status.float_rounding_mode; + if (!(mode & (1 << 2))) { + set_x86_rounding_mode(mode & 3, &env->sse_status); + } + + for (i = 0; i < 2 << SHIFT; i++) { + d->ZMM_H(i) = float32_to_float16(s->ZMM_S(i), true, &env->sse_status); + } + for (i >>= 2; i < 1 << SHIFT; i++) { + d->Q(i) = 0; + } + + env->sse_status.float_rounding_mode = prev_rounding_mode; +} +#endif + #if SHIFT == 1 void helper_cvtss2sd(CPUX86State *env, Reg *d, Reg *v, Reg *s) { diff --git a/target/i386/ops_sse_header.h b/target/i386/ops_sse_header.h index 2f1f811f9f..c4c41976c0 100644 --- a/target/i386/ops_sse_header.h +++ b/target/i386/ops_sse_header.h @@ -353,6 +353,12 @@ DEF_HELPER_4(glue(aeskeygenassist, SUFFIX), void, env, Reg, Reg, i32) DEF_HELPER_5(glue(pclmulqdq, SUFFIX), void, env, Reg, Reg, Reg, i32) #endif +/* F16C helpers */ +#if SHIFT >= 1 +DEF_HELPER_3(glue(cvtph2ps, SUFFIX), void, env, Reg, Reg) +DEF_HELPER_4(glue(cvtps2ph, SUFFIX), void, env, Reg, Reg, int) +#endif + /* AVX helpers */ #if SHIFT >= 1 DEF_HELPER_4(glue(vpermilpd, SUFFIX), void, env, Reg, Reg, Reg) diff --git a/target/i386/tcg/decode-new.c.inc b/target/i386/tcg/decode-new.c.inc index 8e1eb9db42..8baee9018a 100644 --- a/target/i386/tcg/decode-new.c.inc +++ b/target/i386/tcg/decode-new.c.inc @@ -336,6 +336,7 @@ static const X86OpEntry opcodes_0F38_00toEF[240] = { [0x07] = X86_OP_ENTRY3(PHSUBSW, V,x, H,x, W,x, vex4 cpuid(SSSE3) mmx avx2_256 p_00_66), [0x10] = X86_OP_ENTRY2(PBLENDVB, V,x, W,x, vex4 cpuid(SSE41) avx2_256 p_66), + [0x13] = X86_OP_ENTRY2(VCVTPH2PS, V,x, W,ph, vex11 cpuid(F16C) p_66), [0x14] = X86_OP_ENTRY2(BLENDVPS, V,x, W,x, vex4 cpuid(SSE41) p_66), [0x15] = X86_OP_ENTRY2(BLENDVPD, V,x, W,x, vex4 cpuid(SSE41) p_66), /* Listed incorrectly as type 4 */ @@ -525,6 +526,7 @@ static const X86OpEntry opcodes_0F3A[256] = { [0x15] = X86_OP_ENTRY3(PEXTRW, E,w, V,dq, I,b, vex5 cpuid(SSE41) zext0 p_66), [0x16] = X86_OP_ENTRY3(PEXTR, E,y, V,dq, I,b, vex5 cpuid(SSE41) p_66), [0x17] = X86_OP_ENTRY3(VEXTRACTPS, E,d, V,dq, I,b, vex5 cpuid(SSE41) p_66), + [0x1d] = X86_OP_ENTRY3(VCVTPS2PH, W,ph, V,x, I,b, vex11 cpuid(F16C) p_66), [0x20] = X86_OP_ENTRY4(PINSRB, V,dq, H,dq, E,b, vex5 cpuid(SSE41) zext2 p_66), [0x21] = X86_OP_GROUP0(VINSERTPS), @@ -1051,6 +1053,10 @@ static bool decode_op_size(DisasContext *s, X86OpEntry *e, X86OpSize size, MemOp *ot = s->vex_l ? MO_256 : MO_128; return true; + case X86_SIZE_ph: /* SSE/AVX packed half precision */ + *ot = s->vex_l ? MO_128 : MO_64; + return true; + case X86_SIZE_d64: /* Default to 64-bit in 64-bit mode */ *ot = CODE64(s) && s->dflag == MO_32 ? MO_64 : s->dflag; return true; @@ -1342,6 +1348,8 @@ static bool has_cpuid_feature(DisasContext *s, X86CPUIDFeature cpuid) switch (cpuid) { case X86_FEAT_None: return true; + case X86_FEAT_F16C: + return (s->cpuid_ext_features & CPUID_EXT_F16C); case X86_FEAT_MOVBE: return (s->cpuid_ext_features & CPUID_EXT_MOVBE); case X86_FEAT_PCLMULQDQ: diff --git a/target/i386/tcg/decode-new.h b/target/i386/tcg/decode-new.h index f159c26850..0ef54628ee 100644 --- a/target/i386/tcg/decode-new.h +++ b/target/i386/tcg/decode-new.h @@ -92,6 +92,7 @@ typedef enum X86OpSize { /* Custom */ X86_SIZE_d64, X86_SIZE_f64, + X86_SIZE_ph, /* SSE/AVX packed half precision */ } X86OpSize; typedef enum X86CPUIDFeature { @@ -103,6 +104,7 @@ typedef enum X86CPUIDFeature { X86_FEAT_AVX2, X86_FEAT_BMI1, X86_FEAT_BMI2, + X86_FEAT_F16C, X86_FEAT_MOVBE, X86_FEAT_PCLMULQDQ, X86_FEAT_SSE, diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc index ebf299451d..9334f0939d 100644 --- a/target/i386/tcg/emit.c.inc +++ b/target/i386/tcg/emit.c.inc @@ -296,7 +296,7 @@ static void gen_writeback(DisasContext *s, X86DecodedInsn *decode, int opn, TCGv case X86_OP_MMX: break; case X86_OP_SSE: - if (!op->has_ea && (s->prefix & PREFIX_VEX) && op->ot == MO_128) { + if (!op->has_ea && (s->prefix & PREFIX_VEX) && op->ot <= MO_128) { tcg_gen_gvec_dup_imm(MO_64, offsetof(CPUX86State, xmm_regs[op->n].ZMM_X(1)), 16, 16, 0); @@ -852,6 +852,7 @@ UNARY_INT_SSE(VCVTTPD2DQ, cvttpd2dq) UNARY_INT_SSE(VCVTDQ2PS, cvtdq2ps) UNARY_INT_SSE(VCVTPS2DQ, cvtps2dq) UNARY_INT_SSE(VCVTTPS2DQ, cvttps2dq) +UNARY_INT_SSE(VCVTPH2PS, cvtph2ps) static inline void gen_unary_imm_sse(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode, @@ -1868,6 +1869,20 @@ static void gen_VCVTfp2fp(DisasContext *s, CPUX86State *env, X86DecodedInsn *dec gen_helper_cvtsd2ss, gen_helper_cvtss2sd); } +static void gen_VCVTPS2PH(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode) +{ + gen_unary_imm_fp_sse(s, env, decode, + gen_helper_cvtps2ph_xmm, + gen_helper_cvtps2ph_ymm); + /* + * VCVTPS2PH is the only instruction that performs an operation on a + * register source and then *stores* into memory. + */ + if (decode->op[0].has_ea) { + gen_store_sse(s, decode, decode->op[0].offset); + } +} + static void gen_VCVTSI2Sx(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode) { int vec_len = vector_len(s, decode); diff --git a/tests/tcg/i386/test-avx.c b/tests/tcg/i386/test-avx.c index 953e2906fe..c39c0e5bce 100644 --- a/tests/tcg/i386/test-avx.c +++ b/tests/tcg/i386/test-avx.c @@ -28,6 +28,7 @@ typedef struct { } TestDef; reg_state initI; +reg_state initF16; reg_state initF32; reg_state initF64; @@ -221,6 +222,7 @@ static void run_all(void) #define ARRAY_LEN(x) (sizeof(x) / sizeof(x[0])) +uint16_t val_f16[] = { 0x4000, 0xbc00, 0x44cd, 0x3a66, 0x4200, 0x7a1a, 0x4780, 0x4826 }; float val_f32[] = {2.0, -1.0, 4.8, 0.8, 3, -42.0, 5e6, 7.5, 8.3}; double val_f64[] = {2.0, -1.0, 4.8, 0.8, 3, -42.0, 5e6, 7.5}; v4di val_i64[] = { @@ -241,6 +243,12 @@ v4di indexd = {0x00000002000000efull, 0xfffffff500000010ull, v4di gather_mem[0x20]; +void init_f16reg(v4di *r) +{ + memset(r, 0, sizeof(*r)); + memcpy(r, val_f16, sizeof(val_f16)); +} + void init_f32reg(v4di *r) { static int n; @@ -315,6 +323,15 @@ int main(int argc, char *argv[]) printf("Int:\n"); dump_regs(&initI); + init_all(&initF16); + init_f16reg(&initF16.ymm[10]); + init_f16reg(&initF16.ymm[11]); + init_f16reg(&initF16.ymm[12]); + init_f16reg(&initF16.mem0[1]); + initF16.ff = 16; + printf("F16:\n"); + dump_regs(&initF16); + init_all(&initF32); init_f32reg(&initF32.ymm[10]); init_f32reg(&initF32.ymm[11]); diff --git a/tests/tcg/i386/test-avx.py b/tests/tcg/i386/test-avx.py index 02982329f1..ebb1d99c5e 100755 --- a/tests/tcg/i386/test-avx.py +++ b/tests/tcg/i386/test-avx.py @@ -9,6 +9,7 @@ from fnmatch import fnmatch archs = [ "SSE", "SSE2", "SSE3", "SSSE3", "SSE4_1", "SSE4_2", "AES", "AVX", "AVX2", "AES+AVX", "VAES+AVX", + "F16C", ] ignore = set(["FISTTP", @@ -19,6 +20,7 @@ imask = { 'vBLENDPS': 0x0f, 'CMP[PS][SD]': 0x07, 'VCMP[PS][SD]': 0x1f, + 'vCVTPS2PH': 0x7, 'vDPPD': 0x33, 'vDPPS': 0xff, 'vEXTRACTPS': 0x03, @@ -221,8 +223,10 @@ def ArgGenerator(arg, op): class InsnGenerator: def __init__(self, op, args): self.op = op - if op[-2:] in ["PS", "PD", "SS", "SD"]: - if op[-1] == 'S': + if op[-2:] in ["PH", "PS", "PD", "SS", "SD"]: + if op[-1] == 'H': + self.optype = 'F16' + elif op[-1] == 'S': self.optype = 'F32' else: self.optype = 'F64' From eeed22916b8292b12d21e46ba9d3a383d669d9ff Mon Sep 17 00:00:00 2001 From: WANG Xuerui Date: Thu, 6 Oct 2022 16:55:00 +0800 Subject: [PATCH 028/705] linux-user: Fix more MIPS n32 syscall ABI issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In commit 80f0fe3a85 ("linux-user: Fix syscall parameter handling for MIPS n32") the ABI problem regarding offset64 on MIPS n32 was fixed, but still some cases remain where the n32 is incorrectly treated as any other 32-bit ABI that passes 64-bit arguments in pairs of GPRs. Fix by excluding TARGET_ABI_MIPSN32 from various TARGET_ABI_BITS == 32 checks. Closes: https://gitlab.com/qemu-project/qemu/-/issues/1238 Signed-off-by: WANG Xuerui Cc: Philippe Mathieu-Daudé Cc: Jiaxun Yang Cc: Andreas K. Hüttel Cc: Joshua Kinard Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Jiaxun Yang Tested-by: Jiaxun Yang Tested-by: Andreas K. Huettel Message-Id: <20221006085500.290341-1-xen0n@gentoo.org> Signed-off-by: Laurent Vivier --- linux-user/syscall.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 2e954d8dbd..8b2d39fe73 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -11793,7 +11793,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1, return -host_to_target_errno(ret); #endif -#if TARGET_ABI_BITS == 32 +#if TARGET_ABI_BITS == 32 && !defined(TARGET_ABI_MIPSN32) #ifdef TARGET_NR_fadvise64_64 case TARGET_NR_fadvise64_64: @@ -11920,7 +11920,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1, return get_errno(sys_gettid()); #ifdef TARGET_NR_readahead case TARGET_NR_readahead: -#if TARGET_ABI_BITS == 32 +#if TARGET_ABI_BITS == 32 && !defined(TARGET_ABI_MIPSN32) if (regpairs_aligned(cpu_env, num)) { arg2 = arg3; arg3 = arg4; @@ -12612,7 +12612,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1, #endif /* CONFIG_EVENTFD */ #if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate) case TARGET_NR_fallocate: -#if TARGET_ABI_BITS == 32 +#if TARGET_ABI_BITS == 32 && !defined(TARGET_ABI_MIPSN32) ret = get_errno(fallocate(arg1, arg2, target_offset64(arg3, arg4), target_offset64(arg5, arg6))); #else @@ -12623,7 +12623,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1, #if defined(CONFIG_SYNC_FILE_RANGE) #if defined(TARGET_NR_sync_file_range) case TARGET_NR_sync_file_range: -#if TARGET_ABI_BITS == 32 +#if TARGET_ABI_BITS == 32 && !defined(TARGET_ABI_MIPSN32) #if defined(TARGET_MIPS) ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4), target_offset64(arg5, arg6), arg7)); @@ -12645,7 +12645,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1, case TARGET_NR_arm_sync_file_range: #endif /* This is like sync_file_range but the arguments are reordered */ -#if TARGET_ABI_BITS == 32 +#if TARGET_ABI_BITS == 32 && !defined(TARGET_ABI_MIPSN32) ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4), target_offset64(arg5, arg6), arg2)); #else From 46187d707e7639b743a3b9f72da03ad4b9abc255 Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Wed, 5 Oct 2022 18:38:26 +0200 Subject: [PATCH 029/705] linux-user: fix pidfd_send_signal() According to pidfd_send_signal(2), info argument can be a NULL pointer. Fix strace to correctly manage ending comma in parameters. Fixes: cc054c6f13 ("linux-user: Add pidfd_open(), pidfd_send_signal() and pidfd_getfd() syscalls") cc: Helge Deller Signed-off-by: Laurent Vivier Reviewed-by: Helge Deller Message-Id: <20221005163826.1455313-1-laurent@vivier.eu> Signed-off-by: Laurent Vivier --- linux-user/strace.c | 4 ++-- linux-user/syscall.c | 19 ++++++++++++------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/linux-user/strace.c b/linux-user/strace.c index 37bc96df9b..86c081c83f 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -3383,10 +3383,10 @@ print_pidfd_send_signal(CPUArchState *cpu_env, const struct syscallname *name, unlock_user(p, arg2, 0); } else { - print_pointer(arg2, 1); + print_pointer(arg2, 0); } - print_raw_param("%u", arg3, 0); + print_raw_param("%u", arg3, 1); print_syscall_epilogue(name); } #endif diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 8b2d39fe73..ad06ec7bd5 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -8679,16 +8679,21 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1, #if defined(__NR_pidfd_send_signal) && defined(TARGET_NR_pidfd_send_signal) case TARGET_NR_pidfd_send_signal: { - siginfo_t uinfo; + siginfo_t uinfo, *puinfo; - p = lock_user(VERIFY_READ, arg3, sizeof(target_siginfo_t), 1); - if (!p) { - return -TARGET_EFAULT; + if (arg3) { + p = lock_user(VERIFY_READ, arg3, sizeof(target_siginfo_t), 1); + if (!p) { + return -TARGET_EFAULT; + } + target_to_host_siginfo(&uinfo, p); + unlock_user(p, arg3, 0); + puinfo = &uinfo; + } else { + puinfo = NULL; } - target_to_host_siginfo(&uinfo, p); - unlock_user(p, arg3, 0); ret = get_errno(pidfd_send_signal(arg1, target_to_host_signal(arg2), - &uinfo, arg4)); + puinfo, arg4)); } return ret; #endif From f07eb1c4f805c0dcc14dd69fee49b601ce0b2d2c Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Tue, 27 Sep 2022 14:43:56 +0200 Subject: [PATCH 030/705] linux-user: handle /proc/self/exe with execve() syscall If path is /proc/self/exe, use the executable path provided by exec_path. Don't use execfd as it is closed by loader_exec() and otherwise will survive to the exec() syscall and be usable child process. Signed-off-by: Laurent Vivier Message-Id: <20220927124357.688536-2-laurent@vivier.eu> Signed-off-by: Laurent Vivier --- linux-user/syscall.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index ad06ec7bd5..a7a29091c9 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -8860,7 +8860,11 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1, * before the execve completes and makes it the other * program's problem. */ - ret = get_errno(safe_execve(p, argp, envp)); + if (is_proc_myself(p, "exe")) { + ret = get_errno(safe_execve(exec_path, argp, envp)); + } else { + ret = get_errno(safe_execve(p, argp, envp)); + } unlock_user(p, arg1, 0); goto execve_end; From 00ed8a3459869f46dbb4e18d4dcc81882dfe8776 Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Tue, 27 Sep 2022 14:43:57 +0200 Subject: [PATCH 031/705] linux-user: don't use AT_EXECFD in do_openat() AT_EXECFD gives access to the binary file even if it is not readable (only executable). Moreover it can be opened with flags and mode that are not the ones provided by do_openat() caller. And it is not available because loader_exec() has closed it. To avoid that, use only safe_openat() with the exec_path. Signed-off-by: Laurent Vivier Message-Id: <20220927124357.688536-3-laurent@vivier.eu> Signed-off-by: Laurent Vivier --- linux-user/syscall.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index a7a29091c9..665db67c05 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -8251,8 +8251,7 @@ static int do_openat(CPUArchState *cpu_env, int dirfd, const char *pathname, int }; if (is_proc_myself(pathname, "exe")) { - int execfd = qemu_getauxval(AT_EXECFD); - return execfd ? execfd : safe_openat(dirfd, exec_path, flags, mode); + return safe_openat(dirfd, exec_path, flags, mode); } for (fake_open = fakes; fake_open->filename; fake_open++) { From c5495f4ecb0cdaaf2e9dddeb48f1689cdb520ca0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Tue, 4 Oct 2022 10:32:03 +0100 Subject: [PATCH 032/705] linux-user: add more compat ioctl definitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GLibc changes prevent us from including linux/fs.h anymore, and we previously adjusted to this in commit 3cd3df2a9584e6f753bb62a0028bd67124ab5532 Author: Daniel P. Berrangé Date: Tue Aug 2 12:41:34 2022 -0400 linux-user: fix compat with glibc >= 2.36 sys/mount.h That change required adding compat ioctl definitions on the QEMU side for any ioctls that we would otherwise obtain from linux/fs.h. This commit adds more that were initially missed, due to their usage being conditionalized in QEMU. Signed-off-by: Daniel P. Berrangé Reviewed-by: Laurent Vivier Message-Id: <20221004093206.652431-2-berrange@redhat.com> Signed-off-by: Laurent Vivier --- linux-user/syscall.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 665db67c05..d499cac1d5 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -111,6 +111,31 @@ #define FS_IOC32_SETFLAGS _IOW('f', 2, int) #define FS_IOC32_GETVERSION _IOR('v', 1, int) #define FS_IOC32_SETVERSION _IOW('v', 2, int) + +#define BLKGETSIZE64 _IOR(0x12,114,size_t) +#define BLKDISCARD _IO(0x12,119) +#define BLKIOMIN _IO(0x12,120) +#define BLKIOOPT _IO(0x12,121) +#define BLKALIGNOFF _IO(0x12,122) +#define BLKPBSZGET _IO(0x12,123) +#define BLKDISCARDZEROES _IO(0x12,124) +#define BLKSECDISCARD _IO(0x12,125) +#define BLKROTATIONAL _IO(0x12,126) +#define BLKZEROOUT _IO(0x12,127) + +#define FIBMAP _IO(0x00,1) +#define FIGETBSZ _IO(0x00,2) + +struct file_clone_range { + __s64 src_fd; + __u64 src_offset; + __u64 src_length; + __u64 dest_offset; +}; + +#define FICLONE _IOW(0x94, 9, int) +#define FICLONERANGE _IOW(0x94, 13, struct file_clone_range) + #else #include #endif From ed98cdecf8dabce137f693641777503112d884b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Tue, 4 Oct 2022 10:32:04 +0100 Subject: [PATCH 033/705] linux-user: remove conditionals for many fs.h ioctls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These ioctls have been defined in linux/fs.h for a long time * BLKGETSIZE64 - <2.6.12 (linux.git epoch) * BLKDISCARD - 2.6.28 (d30a2605be9d5132d95944916e8f578fcfe4f976) * BLKIOMIN - 2.6.32 (ac481c20ef8f6c6f2be75d581863f40c43874ef7) * BLKIOOPT - 2.6.32 (ac481c20ef8f6c6f2be75d581863f40c43874ef7) * BLKALIGNOFF - 2.6.32 (ac481c20ef8f6c6f2be75d581863f40c43874ef7) * BLKPBSZGET - 2.6.32 (ac481c20ef8f6c6f2be75d581863f40c43874ef7) * BLKDISCARDZEROES - 2.6.32 (98262f2762f0067375f83824d81ea929e37e6bfe) * BLKSECDISCARD - 2.6.36 (8d57a98ccd0b4489003473979da8f5a1363ba7a3) * BLKROTATIONAL - 3.2 (ef00f59c95fe6e002e7c6e3663cdea65e253f4cc) * BLKZEROOUT - 3.6 (66ba32dc167202c3cf8c86806581a9393ec7f488) * FIBMAP - <2.6.12 (linux.git epoch) * FIGETBSZ - <2.6.12 (linux.git epoch) and when building with latest glibc, we'll see compat definitions in syscall.c anyway thanks to the previous patch. Thus we can assume they always exist and remove the conditional checks. Signed-off-by: Daniel P. Berrangé Reviewed-by: Laurent Vivier Message-Id: <20221004093206.652431-3-berrange@redhat.com> Signed-off-by: Laurent Vivier --- linux-user/ioctls.h | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h index f182d40190..071f7ca253 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h @@ -96,9 +96,7 @@ IOCTL(BLKROGET, IOC_R, MK_PTR(TYPE_INT)) IOCTL(BLKRRPART, 0, TYPE_NULL) IOCTL(BLKGETSIZE, IOC_R, MK_PTR(TYPE_ULONG)) -#ifdef BLKGETSIZE64 IOCTL(BLKGETSIZE64, IOC_R, MK_PTR(TYPE_ULONGLONG)) -#endif IOCTL(BLKFLSBUF, 0, TYPE_NULL) IOCTL(BLKRASET, 0, TYPE_INT) IOCTL(BLKRAGET, IOC_R, MK_PTR(TYPE_LONG)) @@ -107,33 +105,15 @@ IOCTL_SPECIAL(BLKPG, IOC_W, do_ioctl_blkpg, MK_PTR(MK_STRUCT(STRUCT_blkpg_ioctl_arg))) -#ifdef BLKDISCARD IOCTL(BLKDISCARD, IOC_W, MK_PTR(MK_ARRAY(TYPE_ULONGLONG, 2))) -#endif -#ifdef BLKIOMIN IOCTL(BLKIOMIN, IOC_R, MK_PTR(TYPE_INT)) -#endif -#ifdef BLKIOOPT IOCTL(BLKIOOPT, IOC_R, MK_PTR(TYPE_INT)) -#endif -#ifdef BLKALIGNOFF IOCTL(BLKALIGNOFF, IOC_R, MK_PTR(TYPE_INT)) -#endif -#ifdef BLKPBSZGET IOCTL(BLKPBSZGET, IOC_R, MK_PTR(TYPE_INT)) -#endif -#ifdef BLKDISCARDZEROES IOCTL(BLKDISCARDZEROES, IOC_R, MK_PTR(TYPE_INT)) -#endif -#ifdef BLKSECDISCARD IOCTL(BLKSECDISCARD, IOC_W, MK_PTR(MK_ARRAY(TYPE_ULONGLONG, 2))) -#endif -#ifdef BLKROTATIONAL IOCTL(BLKROTATIONAL, IOC_R, MK_PTR(TYPE_SHORT)) -#endif -#ifdef BLKZEROOUT IOCTL(BLKZEROOUT, IOC_W, MK_PTR(MK_ARRAY(TYPE_ULONGLONG, 2))) -#endif IOCTL(FDMSGON, 0, TYPE_NULL) IOCTL(FDMSGOFF, 0, TYPE_NULL) @@ -149,17 +129,13 @@ IOCTL(FDTWADDLE, 0, TYPE_NULL) IOCTL(FDEJECT, 0, TYPE_NULL) -#ifdef FIBMAP IOCTL(FIBMAP, IOC_W | IOC_R, MK_PTR(TYPE_LONG)) -#endif #ifdef FICLONE IOCTL(FICLONE, IOC_W, TYPE_INT) IOCTL(FICLONERANGE, IOC_W, MK_PTR(MK_STRUCT(STRUCT_file_clone_range))) #endif -#ifdef FIGETBSZ IOCTL(FIGETBSZ, IOC_R, MK_PTR(TYPE_LONG)) -#endif #ifdef CONFIG_FIEMAP IOCTL_SPECIAL(FS_IOC_FIEMAP, IOC_W | IOC_R, do_ioctl_fs_ioc_fiemap, MK_PTR(MK_STRUCT(STRUCT_fiemap))) From 35a2c85f7d691db7aa2c47181902ac87478eef7a Mon Sep 17 00:00:00 2001 From: WANG Xuerui Date: Sun, 9 Oct 2022 14:08:13 +0800 Subject: [PATCH 034/705] linux-user: Implement faccessat2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User space has been preferring this syscall for a while, due to its closer match with C semantics, and newer platforms such as LoongArch apparently have libc implementations that don't fallback to faccessat so normal access checks are failing without the emulation in place. Tested by successfully emerging several packages within a Gentoo loong stage3 chroot, emulated on amd64 with help of static qemu-loongarch64. Reported-by: Andreas K. Hüttel Signed-off-by: WANG Xuerui Message-Id: <20221009060813.2289077-1-xen0n@gentoo.org> [lv: removing defined(__NR_faccessat2) in syscall.c, adding defined(TARGET_NR_faccessat2) on print_faccessat()] Signed-off-by: Laurent Vivier --- linux-user/strace.c | 2 +- linux-user/strace.list | 3 +++ linux-user/syscall.c | 9 +++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/linux-user/strace.c b/linux-user/strace.c index 86c081c83f..9ae5a812cd 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -1969,7 +1969,7 @@ print_execv(CPUArchState *cpu_env, const struct syscallname *name, } #endif -#ifdef TARGET_NR_faccessat +#if defined(TARGET_NR_faccessat) || defined(TARGET_NR_faccessat2) static void print_faccessat(CPUArchState *cpu_env, const struct syscallname *name, abi_long arg0, abi_long arg1, abi_long arg2, diff --git a/linux-user/strace.list b/linux-user/strace.list index a87415bf3d..3df2184580 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -178,6 +178,9 @@ #ifdef TARGET_NR_faccessat { TARGET_NR_faccessat, "faccessat" , NULL, print_faccessat, NULL }, #endif +#ifdef TARGET_NR_faccessat2 +{ TARGET_NR_faccessat2, "faccessat2" , NULL, print_faccessat, NULL }, +#endif #ifdef TARGET_NR_fadvise64 { TARGET_NR_fadvise64, "fadvise64" , NULL, NULL, NULL }, #endif diff --git a/linux-user/syscall.c b/linux-user/syscall.c index d499cac1d5..e985ad167f 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -9143,6 +9143,15 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1, unlock_user(p, arg2, 0); return ret; #endif +#if defined(TARGET_NR_faccessat2) + case TARGET_NR_faccessat2: + if (!(p = lock_user_string(arg2))) { + return -TARGET_EFAULT; + } + ret = get_errno(faccessat(arg1, p, arg3, arg4)); + unlock_user(p, arg2, 0); + return ret; +#endif #ifdef TARGET_NR_nice /* not on alpha */ case TARGET_NR_nice: return get_errno(nice(arg1)); From 693869a66ed7b49f2c790d88a25fc3d0ec791e0c Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Mon, 26 Sep 2022 13:38:59 +0200 Subject: [PATCH 035/705] m68k: rework BI_VIRT_RNG_SEED as BI_RNG_SEED Following a change on the kernel side (see link), pass BI_RNG_SEED instead of BI_VIRT_RNG_SEED. This should have no impact on compatibility, as there will simply be no effect if it's an old kernel, which is how things have always been. We then use this as an opportunity to add this to q800, since now we can, which is a nice improvement. Cc: Geert Uytterhoeven Cc: Laurent Vivier Link: https://lore.kernel.org/lkml/20220923170340.4099226-3-Jason@zx2c4.com/ Signed-off-by: Jason A. Donenfeld Message-Id: <20220926113900.1256630-1-Jason@zx2c4.com> [lv: s/^I/ /g] Signed-off-by: Laurent Vivier --- hw/m68k/q800.c | 7 +++++++ hw/m68k/virt.c | 8 ++++---- include/standard-headers/asm-m68k/bootinfo-virt.h | 4 +++- include/standard-headers/asm-m68k/bootinfo.h | 8 +++++++- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c index 101ab0f803..a4590c2cb0 100644 --- a/hw/m68k/q800.c +++ b/hw/m68k/q800.c @@ -23,6 +23,7 @@ #include "qemu/osdep.h" #include "qemu/units.h" #include "qemu/datadir.h" +#include "qemu/guest-random.h" #include "sysemu/sysemu.h" #include "cpu.h" #include "hw/boards.h" @@ -385,6 +386,7 @@ static void q800_init(MachineState *machine) NubusBus *nubus; DeviceState *glue; DriveInfo *dinfo; + uint8_t rng_seed[32]; linux_boot = (kernel_filename != NULL); @@ -634,6 +636,11 @@ static void q800_init(MachineState *machine) kernel_cmdline); } + /* Pass seed to RNG. */ + qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed)); + BOOTINFODATA(cs->as, parameters_base, BI_RNG_SEED, + rng_seed, sizeof(rng_seed)); + /* load initrd */ if (initrd_filename) { initrd_size = get_image_size(initrd_filename); diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c index 2f3ffc0de6..f7b903ea1b 100644 --- a/hw/m68k/virt.c +++ b/hw/m68k/virt.c @@ -248,10 +248,10 @@ static void virt_init(MachineState *machine) kernel_cmdline); } - /* Pass seed to RNG. */ - qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed)); - BOOTINFODATA(cs->as, parameters_base, BI_VIRT_RNG_SEED, - rng_seed, sizeof(rng_seed)); + /* Pass seed to RNG. */ + qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed)); + BOOTINFODATA(cs->as, parameters_base, BI_RNG_SEED, + rng_seed, sizeof(rng_seed)); /* load initrd */ if (initrd_filename) { diff --git a/include/standard-headers/asm-m68k/bootinfo-virt.h b/include/standard-headers/asm-m68k/bootinfo-virt.h index 1b1ffd4705..75ac6bbd7d 100644 --- a/include/standard-headers/asm-m68k/bootinfo-virt.h +++ b/include/standard-headers/asm-m68k/bootinfo-virt.h @@ -12,7 +12,9 @@ #define BI_VIRT_GF_TTY_BASE 0x8003 #define BI_VIRT_VIRTIO_BASE 0x8004 #define BI_VIRT_CTRL_BASE 0x8005 -#define BI_VIRT_RNG_SEED 0x8006 + +/* No longer used -- replaced with BI_RNG_SEED -- but don't reuse this index: + * #define BI_VIRT_RNG_SEED 0x8006 */ #define VIRT_BOOTI_VERSION MK_BI_VERSION(2, 0) diff --git a/include/standard-headers/asm-m68k/bootinfo.h b/include/standard-headers/asm-m68k/bootinfo.h index 7b790e8ec8..b7a8dd2514 100644 --- a/include/standard-headers/asm-m68k/bootinfo.h +++ b/include/standard-headers/asm-m68k/bootinfo.h @@ -57,7 +57,13 @@ struct mem_info { /* (struct mem_info) */ #define BI_COMMAND_LINE 0x0007 /* kernel command line parameters */ /* (string) */ - +/* + * A random seed used to initialize the RNG. Record format: + * + * - length [ 2 bytes, 16-bit big endian ] + * - seed data [ `length` bytes, padded to preserve 4-byte struct alignment ] + */ +#define BI_RNG_SEED 0x0008 /* * Linux/m68k Architectures (BI_MACHTYPE) From 2872b0f390c3fbd8f19f6b82da3dca15fa820118 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 19 Oct 2022 13:22:06 +0200 Subject: [PATCH 036/705] target/i386: implement FMA instructions The only issue with FMA instructions is that there are _a lot_ of them (30 opcodes, each of which comes in up to 4 versions depending on VEX.W and VEX.L; a total of 96 possibilities). However, they can be implement with only 6 helpers, two for scalar operations and four for packed operations. (Scalar versions do not do any merging; they only affect the bottom 32 or 64 bits of the output operand. Therefore, there is no separate XMM and YMM of the scalar helpers). First, we can reduce the number of helpers to one third by passing four operands (one output and three inputs); the reordering of which operands go to the multiply and which go to the add is done in emit.c. Second, the different instructions also dispatch to the same softfloat function, so the flags for float32_muladd and float64_muladd are passed in the helper as int arguments, with a little extra complication to handle FMADDSUB and FMSUBADD. Reviewed-by: Richard Henderson Signed-off-by: Paolo Bonzini --- target/i386/cpu.c | 5 ++-- target/i386/ops_sse.h | 27 +++++++++++++++++ target/i386/ops_sse_header.h | 11 +++++++ target/i386/tcg/decode-new.c.inc | 40 +++++++++++++++++++++++++ target/i386/tcg/decode-new.h | 1 + target/i386/tcg/emit.c.inc | 51 ++++++++++++++++++++++++++++++++ target/i386/tcg/translate.c | 1 + tests/tcg/i386/test-avx.py | 2 +- 8 files changed, 135 insertions(+), 3 deletions(-) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 6292b7e12f..22b681ca37 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -625,10 +625,11 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1, CPUID_EXT_SSE41 | CPUID_EXT_SSE42 | CPUID_EXT_POPCNT | \ CPUID_EXT_XSAVE | /* CPUID_EXT_OSXSAVE is dynamic */ \ CPUID_EXT_MOVBE | CPUID_EXT_AES | CPUID_EXT_HYPERVISOR | \ - CPUID_EXT_RDRAND | CPUID_EXT_AVX | CPUID_EXT_F16C) + CPUID_EXT_RDRAND | CPUID_EXT_AVX | CPUID_EXT_F16C | \ + CPUID_EXT_FMA) /* missing: CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_SMX, - CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_CID, CPUID_EXT_FMA, + CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_CID, CPUID_EXT_XTPR, CPUID_EXT_PDCM, CPUID_EXT_PCID, CPUID_EXT_DCA, CPUID_EXT_X2APIC, CPUID_EXT_TSC_DEADLINE_TIMER */ diff --git a/target/i386/ops_sse.h b/target/i386/ops_sse.h index 33c61896ee..3cbc36a59d 100644 --- a/target/i386/ops_sse.h +++ b/target/i386/ops_sse.h @@ -2522,6 +2522,33 @@ void helper_vpermd_ymm(Reg *d, Reg *v, Reg *s) } #endif +/* FMA3 op helpers */ +#if SHIFT == 1 +#define SSE_HELPER_FMAS(name, elem, F) \ + void name(CPUX86State *env, Reg *d, Reg *a, Reg *b, Reg *c, int flags) \ + { \ + d->elem(0) = F(a->elem(0), b->elem(0), c->elem(0), flags, &env->sse_status); \ + } +#define SSE_HELPER_FMAP(name, elem, num, F) \ + void glue(name, SUFFIX)(CPUX86State *env, Reg *d, Reg *a, Reg *b, Reg *c, \ + int flags, int flip) \ + { \ + int i; \ + for (i = 0; i < num; i++) { \ + d->elem(i) = F(a->elem(i), b->elem(i), c->elem(i), flags, &env->sse_status); \ + flags ^= flip; \ + } \ + } + +SSE_HELPER_FMAS(helper_fma4ss, ZMM_S, float32_muladd) +SSE_HELPER_FMAS(helper_fma4sd, ZMM_D, float64_muladd) +#endif + +#if SHIFT >= 1 +SSE_HELPER_FMAP(helper_fma4ps, ZMM_S, 2 << SHIFT, float32_muladd) +SSE_HELPER_FMAP(helper_fma4pd, ZMM_D, 1 << SHIFT, float64_muladd) +#endif + #undef SSE_HELPER_S #undef LANE_WIDTH diff --git a/target/i386/ops_sse_header.h b/target/i386/ops_sse_header.h index c4c41976c0..8a7b2f4e2f 100644 --- a/target/i386/ops_sse_header.h +++ b/target/i386/ops_sse_header.h @@ -359,6 +359,17 @@ DEF_HELPER_3(glue(cvtph2ps, SUFFIX), void, env, Reg, Reg) DEF_HELPER_4(glue(cvtps2ph, SUFFIX), void, env, Reg, Reg, int) #endif +/* FMA3 helpers */ +#if SHIFT == 1 +DEF_HELPER_6(fma4ss, void, env, Reg, Reg, Reg, Reg, int) +DEF_HELPER_6(fma4sd, void, env, Reg, Reg, Reg, Reg, int) +#endif + +#if SHIFT >= 1 +DEF_HELPER_7(glue(fma4ps, SUFFIX), void, env, Reg, Reg, Reg, Reg, int, int) +DEF_HELPER_7(glue(fma4pd, SUFFIX), void, env, Reg, Reg, Reg, Reg, int, int) +#endif + /* AVX helpers */ #if SHIFT >= 1 DEF_HELPER_4(glue(vpermilpd, SUFFIX), void, env, Reg, Reg, Reg) diff --git a/target/i386/tcg/decode-new.c.inc b/target/i386/tcg/decode-new.c.inc index 8baee9018a..e4878b967f 100644 --- a/target/i386/tcg/decode-new.c.inc +++ b/target/i386/tcg/decode-new.c.inc @@ -376,6 +376,16 @@ static const X86OpEntry opcodes_0F38_00toEF[240] = { [0x92] = X86_OP_ENTRY3(VPGATHERD, V,x, H,x, M,d, vex12 cpuid(AVX2) p_66), /* vgatherdps/d */ [0x93] = X86_OP_ENTRY3(VPGATHERQ, V,x, H,x, M,q, vex12 cpuid(AVX2) p_66), /* vgatherqps/d */ + /* Should be exception type 2 but they do not have legacy SSE equivalents? */ + [0x96] = X86_OP_ENTRY3(VFMADDSUB132Px, V,x, H,x, W,x, vex6 cpuid(FMA) p_66), + [0x97] = X86_OP_ENTRY3(VFMSUBADD132Px, V,x, H,x, W,x, vex6 cpuid(FMA) p_66), + + [0xa6] = X86_OP_ENTRY3(VFMADDSUB213Px, V,x, H,x, W,x, vex6 cpuid(FMA) p_66), + [0xa7] = X86_OP_ENTRY3(VFMSUBADD213Px, V,x, H,x, W,x, vex6 cpuid(FMA) p_66), + + [0xb6] = X86_OP_ENTRY3(VFMADDSUB231Px, V,x, H,x, W,x, vex6 cpuid(FMA) p_66), + [0xb7] = X86_OP_ENTRY3(VFMSUBADD231Px, V,x, H,x, W,x, vex6 cpuid(FMA) p_66), + [0x08] = X86_OP_ENTRY3(PSIGNB, V,x, H,x, W,x, vex4 cpuid(SSSE3) mmx avx2_256 p_00_66), [0x09] = X86_OP_ENTRY3(PSIGNW, V,x, H,x, W,x, vex4 cpuid(SSSE3) mmx avx2_256 p_00_66), [0x0a] = X86_OP_ENTRY3(PSIGND, V,x, H,x, W,x, vex4 cpuid(SSSE3) mmx avx2_256 p_00_66), @@ -421,6 +431,34 @@ static const X86OpEntry opcodes_0F38_00toEF[240] = { [0x8c] = X86_OP_ENTRY3(VPMASKMOV, V,x, H,x, WM,x, vex6 cpuid(AVX2) p_66), [0x8e] = X86_OP_ENTRY3(VPMASKMOV_st, M,x, V,x, H,x, vex6 cpuid(AVX2) p_66), + /* Should be exception type 2 or 3 but they do not have legacy SSE equivalents? */ + [0x98] = X86_OP_ENTRY3(VFMADD132Px, V,x, H,x, W,x, vex6 cpuid(FMA) p_66), + [0x99] = X86_OP_ENTRY3(VFMADD132Sx, V,x, H,x, W,x, vex6 cpuid(FMA) p_66), + [0x9a] = X86_OP_ENTRY3(VFMSUB132Px, V,x, H,x, W,x, vex6 cpuid(FMA) p_66), + [0x9b] = X86_OP_ENTRY3(VFMSUB132Sx, V,x, H,x, W,x, vex6 cpuid(FMA) p_66), + [0x9c] = X86_OP_ENTRY3(VFNMADD132Px, V,x, H,x, W,x, vex6 cpuid(FMA) p_66), + [0x9d] = X86_OP_ENTRY3(VFNMADD132Sx, V,x, H,x, W,x, vex6 cpuid(FMA) p_66), + [0x9e] = X86_OP_ENTRY3(VFNMSUB132Px, V,x, H,x, W,x, vex6 cpuid(FMA) p_66), + [0x9f] = X86_OP_ENTRY3(VFNMSUB132Sx, V,x, H,x, W,x, vex6 cpuid(FMA) p_66), + + [0xa8] = X86_OP_ENTRY3(VFMADD213Px, V,x, H,x, W,x, vex6 cpuid(FMA) p_66), + [0xa9] = X86_OP_ENTRY3(VFMADD213Sx, V,x, H,x, W,x, vex6 cpuid(FMA) p_66), + [0xaa] = X86_OP_ENTRY3(VFMSUB213Px, V,x, H,x, W,x, vex6 cpuid(FMA) p_66), + [0xab] = X86_OP_ENTRY3(VFMSUB213Sx, V,x, H,x, W,x, vex6 cpuid(FMA) p_66), + [0xac] = X86_OP_ENTRY3(VFNMADD213Px, V,x, H,x, W,x, vex6 cpuid(FMA) p_66), + [0xad] = X86_OP_ENTRY3(VFNMADD213Sx, V,x, H,x, W,x, vex6 cpuid(FMA) p_66), + [0xae] = X86_OP_ENTRY3(VFNMSUB213Px, V,x, H,x, W,x, vex6 cpuid(FMA) p_66), + [0xaf] = X86_OP_ENTRY3(VFNMSUB213Sx, V,x, H,x, W,x, vex6 cpuid(FMA) p_66), + + [0xb8] = X86_OP_ENTRY3(VFMADD231Px, V,x, H,x, W,x, vex6 cpuid(FMA) p_66), + [0xb9] = X86_OP_ENTRY3(VFMADD231Sx, V,x, H,x, W,x, vex6 cpuid(FMA) p_66), + [0xba] = X86_OP_ENTRY3(VFMSUB231Px, V,x, H,x, W,x, vex6 cpuid(FMA) p_66), + [0xbb] = X86_OP_ENTRY3(VFMSUB231Sx, V,x, H,x, W,x, vex6 cpuid(FMA) p_66), + [0xbc] = X86_OP_ENTRY3(VFNMADD231Px, V,x, H,x, W,x, vex6 cpuid(FMA) p_66), + [0xbd] = X86_OP_ENTRY3(VFNMADD231Sx, V,x, H,x, W,x, vex6 cpuid(FMA) p_66), + [0xbe] = X86_OP_ENTRY3(VFNMSUB231Px, V,x, H,x, W,x, vex6 cpuid(FMA) p_66), + [0xbf] = X86_OP_ENTRY3(VFNMSUB231Sx, V,x, H,x, W,x, vex6 cpuid(FMA) p_66), + [0xdb] = X86_OP_ENTRY3(VAESIMC, V,dq, None,None, W,dq, vex4 cpuid(AES) p_66), [0xdc] = X86_OP_ENTRY3(VAESENC, V,x, H,x, W,x, vex4 cpuid(AES) p_66), [0xdd] = X86_OP_ENTRY3(VAESENCLAST, V,x, H,x, W,x, vex4 cpuid(AES) p_66), @@ -1350,6 +1388,8 @@ static bool has_cpuid_feature(DisasContext *s, X86CPUIDFeature cpuid) return true; case X86_FEAT_F16C: return (s->cpuid_ext_features & CPUID_EXT_F16C); + case X86_FEAT_FMA: + return (s->cpuid_ext_features & CPUID_EXT_FMA); case X86_FEAT_MOVBE: return (s->cpuid_ext_features & CPUID_EXT_MOVBE); case X86_FEAT_PCLMULQDQ: diff --git a/target/i386/tcg/decode-new.h b/target/i386/tcg/decode-new.h index 0ef54628ee..cb6b8bcf67 100644 --- a/target/i386/tcg/decode-new.h +++ b/target/i386/tcg/decode-new.h @@ -105,6 +105,7 @@ typedef enum X86CPUIDFeature { X86_FEAT_BMI1, X86_FEAT_BMI2, X86_FEAT_F16C, + X86_FEAT_FMA, X86_FEAT_MOVBE, X86_FEAT_PCLMULQDQ, X86_FEAT_SSE, diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc index 9334f0939d..7037ff91c6 100644 --- a/target/i386/tcg/emit.c.inc +++ b/target/i386/tcg/emit.c.inc @@ -39,6 +39,11 @@ typedef void (*SSEFunc_0_eppt)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b, TCGv val); typedef void (*SSEFunc_0_epppti)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b, TCGv_ptr reg_c, TCGv a0, TCGv_i32 scale); +typedef void (*SSEFunc_0_eppppi)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b, + TCGv_ptr reg_c, TCGv_ptr reg_d, TCGv_i32 flags); +typedef void (*SSEFunc_0_eppppii)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b, + TCGv_ptr reg_c, TCGv_ptr reg_d, TCGv_i32 even, + TCGv_i32 odd); static inline TCGv_i32 tcg_constant8u_i32(uint8_t val) { @@ -491,6 +496,52 @@ FP_SSE(VMIN, min) FP_SSE(VDIV, div) FP_SSE(VMAX, max) +#define FMA_SSE_PACKED(uname, ptr0, ptr1, ptr2, even, odd) \ +static void gen_##uname##Px(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode) \ +{ \ + SSEFunc_0_eppppii xmm = s->vex_w ? gen_helper_fma4pd_xmm : gen_helper_fma4ps_xmm; \ + SSEFunc_0_eppppii ymm = s->vex_w ? gen_helper_fma4pd_ymm : gen_helper_fma4ps_ymm; \ + SSEFunc_0_eppppii fn = s->vex_l ? ymm : xmm; \ + \ + fn(cpu_env, OP_PTR0, ptr0, ptr1, ptr2, \ + tcg_constant_i32(even), \ + tcg_constant_i32((even) ^ (odd))); \ +} + +#define FMA_SSE(uname, ptr0, ptr1, ptr2, flags) \ +FMA_SSE_PACKED(uname, ptr0, ptr1, ptr2, flags, flags) \ +static void gen_##uname##Sx(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode) \ +{ \ + SSEFunc_0_eppppi fn = s->vex_w ? gen_helper_fma4sd : gen_helper_fma4ss; \ + \ + fn(cpu_env, OP_PTR0, ptr0, ptr1, ptr2, \ + tcg_constant_i32(flags)); \ +} \ + +FMA_SSE(VFMADD231, OP_PTR1, OP_PTR2, OP_PTR0, 0) +FMA_SSE(VFMADD213, OP_PTR1, OP_PTR0, OP_PTR2, 0) +FMA_SSE(VFMADD132, OP_PTR0, OP_PTR2, OP_PTR1, 0) + +FMA_SSE(VFNMADD231, OP_PTR1, OP_PTR2, OP_PTR0, float_muladd_negate_product) +FMA_SSE(VFNMADD213, OP_PTR1, OP_PTR0, OP_PTR2, float_muladd_negate_product) +FMA_SSE(VFNMADD132, OP_PTR0, OP_PTR2, OP_PTR1, float_muladd_negate_product) + +FMA_SSE(VFMSUB231, OP_PTR1, OP_PTR2, OP_PTR0, float_muladd_negate_c) +FMA_SSE(VFMSUB213, OP_PTR1, OP_PTR0, OP_PTR2, float_muladd_negate_c) +FMA_SSE(VFMSUB132, OP_PTR0, OP_PTR2, OP_PTR1, float_muladd_negate_c) + +FMA_SSE(VFNMSUB231, OP_PTR1, OP_PTR2, OP_PTR0, float_muladd_negate_c|float_muladd_negate_product) +FMA_SSE(VFNMSUB213, OP_PTR1, OP_PTR0, OP_PTR2, float_muladd_negate_c|float_muladd_negate_product) +FMA_SSE(VFNMSUB132, OP_PTR0, OP_PTR2, OP_PTR1, float_muladd_negate_c|float_muladd_negate_product) + +FMA_SSE_PACKED(VFMADDSUB231, OP_PTR1, OP_PTR2, OP_PTR0, float_muladd_negate_c, 0) +FMA_SSE_PACKED(VFMADDSUB213, OP_PTR1, OP_PTR0, OP_PTR2, float_muladd_negate_c, 0) +FMA_SSE_PACKED(VFMADDSUB132, OP_PTR0, OP_PTR2, OP_PTR1, float_muladd_negate_c, 0) + +FMA_SSE_PACKED(VFMSUBADD231, OP_PTR1, OP_PTR2, OP_PTR0, 0, float_muladd_negate_c) +FMA_SSE_PACKED(VFMSUBADD213, OP_PTR1, OP_PTR0, OP_PTR2, 0, float_muladd_negate_c) +FMA_SSE_PACKED(VFMSUBADD132, OP_PTR0, OP_PTR2, OP_PTR1, 0, float_muladd_negate_c) + #define FP_UNPACK_SSE(uname, lname) \ static void gen_##uname(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode) \ { \ diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c index e19d5c1c64..85be2e58c2 100644 --- a/target/i386/tcg/translate.c +++ b/target/i386/tcg/translate.c @@ -26,6 +26,7 @@ #include "tcg/tcg-op-gvec.h" #include "exec/cpu_ldst.h" #include "exec/translator.h" +#include "fpu/softfloat.h" #include "exec/helper-proto.h" #include "exec/helper-gen.h" diff --git a/tests/tcg/i386/test-avx.py b/tests/tcg/i386/test-avx.py index ebb1d99c5e..d9ca00a49e 100755 --- a/tests/tcg/i386/test-avx.py +++ b/tests/tcg/i386/test-avx.py @@ -9,7 +9,7 @@ from fnmatch import fnmatch archs = [ "SSE", "SSE2", "SSE3", "SSSE3", "SSE4_1", "SSE4_2", "AES", "AVX", "AVX2", "AES+AVX", "VAES+AVX", - "F16C", + "F16C", "FMA", ] ignore = set(["FISTTP", From 8ad708a9d8f7e40a1fc33c69d1590f10e3da50b0 Mon Sep 17 00:00:00 2001 From: "Wang, Lei" Date: Thu, 20 Oct 2022 17:19:21 +0000 Subject: [PATCH 037/705] .gitignore: add multiple items to .gitignore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add /.vscode/, .clang-format and .gdb_history to .gitignore because: - For VSCode, workspace settings as well as debugging and task configurations are stored at the root in a .vscode folder; - For ClangFormat, the .clang-format file is searched relative to the current working directory when reading stdin; - For GDB, GDB command history file defaults to the value of the environment variable GDBHISTFILE, or to ./.gdb_history if this variable is not set. Signed-off-by: Wang, Lei Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20221020171921.1078533-1-lei4.wang@intel.com> Signed-off-by: Laurent Vivier --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 8aab671265..61fa39967b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,13 @@ /GNUmakefile /build/ /.cache/ +/.vscode/ *.pyc .sdk .stgit-* .git-submodule-status +.clang-format +.gdb_history cscope.* tags TAGS From 2d7279984fdf735fb80f32e5a09f777e4188c57e Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Fri, 23 Sep 2022 14:00:23 +0200 Subject: [PATCH 038/705] hw/core: Tidy up unnecessary casting away of const Signed-off-by: Markus Armbruster Message-Id: <20220923120025.448759-2-armbru@redhat.com> Signed-off-by: Laurent Vivier --- hw/core/sysbus-fdt.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hw/core/sysbus-fdt.c b/hw/core/sysbus-fdt.c index edb0c49b19..eebcd28f9a 100644 --- a/hw/core/sysbus-fdt.c +++ b/hw/core/sysbus-fdt.c @@ -299,7 +299,8 @@ static int add_amd_xgbe_fdt_node(SysBusDevice *sbdev, void *opaque) void *guest_fdt = data->fdt, *host_fdt; const void *r; int i, prop_len; - uint32_t *irq_attr, *reg_attr, *host_clock_phandles; + uint32_t *irq_attr, *reg_attr; + const uint32_t *host_clock_phandles; uint64_t mmio_base, irq_number; uint32_t guest_clock_phandles[2]; @@ -339,7 +340,7 @@ static int add_amd_xgbe_fdt_node(SysBusDevice *sbdev, void *opaque) error_report("%s clocks property should contain 2 handles", __func__); exit(1); } - host_clock_phandles = (uint32_t *)r; + host_clock_phandles = r; guest_clock_phandles[0] = qemu_fdt_alloc_phandle(guest_fdt); guest_clock_phandles[1] = qemu_fdt_alloc_phandle(guest_fdt); From 4bb5923605b2b8994f933df23aa948efe7ba545c Mon Sep 17 00:00:00 2001 From: lu zhipeng Date: Fri, 7 Oct 2022 10:01:28 +0800 Subject: [PATCH 039/705] elf2dmp: free memory in failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 'kdgb' is allocating memory in get_kdbg(), but it is not freed in error path. So fix that. Signed-off-by: lu zhipeng Reviewed-by: Viktor Prutyanov Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20221007020128.760-1-luzhipeng@cestc.cn> Signed-off-by: Laurent Vivier --- contrib/elf2dmp/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/elf2dmp/main.c b/contrib/elf2dmp/main.c index b9fc6d230c..d77b8f98f7 100644 --- a/contrib/elf2dmp/main.c +++ b/contrib/elf2dmp/main.c @@ -125,6 +125,7 @@ static KDDEBUGGER_DATA64 *get_kdbg(uint64_t KernBase, struct pdb_reader *pdb, if (va_space_rw(vs, KdDebuggerDataBlock, kdbg, kdbg_hdr.Size, 0)) { eprintf("Failed to extract entire KDBG\n"); + free(kdbg); return NULL; } From 0a553c12c71d5627abf223a926ab9688a5573f54 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Fri, 23 Sep 2022 14:00:24 +0200 Subject: [PATCH 040/705] Drop useless casts from g_malloc() & friends to pointer These memory allocation functions return void *, and casting to another pointer type is useless clutter. Drop these casts. If you really want another pointer type, consider g_new(). Signed-off-by: Markus Armbruster Reviewed-by: Laurent Vivier Message-Id: <20220923120025.448759-3-armbru@redhat.com> Signed-off-by: Laurent Vivier --- hw/arm/nseries.c | 4 ++-- hw/char/exynos4210_uart.c | 2 +- hw/display/blizzard.c | 2 +- hw/misc/cbus.c | 6 +++--- hw/nvram/eeprom93xx.c | 2 +- hw/usb/ccid-card-emulated.c | 2 +- target/i386/kvm/kvm.c | 3 +-- target/i386/whpx/whpx-all.c | 5 ++--- target/s390x/kvm/kvm.c | 2 +- ui/vnc-enc-hextile.c | 4 ++-- 10 files changed, 15 insertions(+), 17 deletions(-) diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c index 692c94ceb4..b151113c27 100644 --- a/hw/arm/nseries.c +++ b/hw/arm/nseries.c @@ -702,7 +702,7 @@ static uint32_t mipid_txrx(void *opaque, uint32_t cmd, int len) static void *mipid_init(void) { - struct mipid_s *s = (struct mipid_s *) g_malloc0(sizeof(*s)); + struct mipid_s *s = g_malloc0(sizeof(*s)); s->id = 0x838f03; mipid_reset(s); @@ -1300,7 +1300,7 @@ static int n810_atag_setup(const struct arm_boot_info *info, void *p) static void n8x0_init(MachineState *machine, struct arm_boot_info *binfo, int model) { - struct n800_s *s = (struct n800_s *) g_malloc0(sizeof(*s)); + struct n800_s *s = g_malloc0(sizeof(*s)); MachineClass *mc = MACHINE_GET_CLASS(machine); if (machine->ram_size != mc->default_ram_size) { diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c index addcd59b02..7b7c56b6ef 100644 --- a/hw/char/exynos4210_uart.c +++ b/hw/char/exynos4210_uart.c @@ -211,7 +211,7 @@ static void fifo_reset(Exynos4210UartFIFO *q) g_free(q->data); q->data = NULL; - q->data = (uint8_t *)g_malloc0(q->size); + q->data = g_malloc0(q->size); q->sp = 0; q->rp = 0; diff --git a/hw/display/blizzard.c b/hw/display/blizzard.c index 105241577d..ebe230dd0a 100644 --- a/hw/display/blizzard.c +++ b/hw/display/blizzard.c @@ -1007,7 +1007,7 @@ static const GraphicHwOps blizzard_ops = { void *s1d13745_init(qemu_irq gpio_int) { - BlizzardState *s = (BlizzardState *) g_malloc0(sizeof(*s)); + BlizzardState *s = g_malloc0(sizeof(*s)); DisplaySurface *surface; s->fb = g_malloc(0x180000); diff --git a/hw/misc/cbus.c b/hw/misc/cbus.c index 3c3721ad2d..653e8ddcd5 100644 --- a/hw/misc/cbus.c +++ b/hw/misc/cbus.c @@ -133,7 +133,7 @@ static void cbus_sel(void *opaque, int line, int level) CBus *cbus_init(qemu_irq dat) { - CBusPriv *s = (CBusPriv *) g_malloc0(sizeof(*s)); + CBusPriv *s = g_malloc0(sizeof(*s)); s->dat_out = dat; s->cbus.clk = qemu_allocate_irq(cbus_clk, s, 0); @@ -388,7 +388,7 @@ static void retu_io(void *opaque, int rw, int reg, uint16_t *val) void *retu_init(qemu_irq irq, int vilma) { - CBusRetu *s = (CBusRetu *) g_malloc0(sizeof(*s)); + CBusRetu *s = g_malloc0(sizeof(*s)); s->irq = irq; s->irqen = 0xffff; @@ -604,7 +604,7 @@ static void tahvo_io(void *opaque, int rw, int reg, uint16_t *val) void *tahvo_init(qemu_irq irq, int betty) { - CBusTahvo *s = (CBusTahvo *) g_malloc0(sizeof(*s)); + CBusTahvo *s = g_malloc0(sizeof(*s)); s->irq = irq; s->irqen = 0xffff; diff --git a/hw/nvram/eeprom93xx.c b/hw/nvram/eeprom93xx.c index a1b9c78844..1081e2cc0d 100644 --- a/hw/nvram/eeprom93xx.c +++ b/hw/nvram/eeprom93xx.c @@ -315,7 +315,7 @@ eeprom_t *eeprom93xx_new(DeviceState *dev, uint16_t nwords) addrbits = 6; } - eeprom = (eeprom_t *)g_malloc0(sizeof(*eeprom) + nwords * 2); + eeprom = g_malloc0(sizeof(*eeprom) + nwords * 2); eeprom->size = nwords; eeprom->addrbits = addrbits; /* Output DO is tristate, read results in 1. */ diff --git a/hw/usb/ccid-card-emulated.c b/hw/usb/ccid-card-emulated.c index 1ddf7297f6..ee41a81801 100644 --- a/hw/usb/ccid-card-emulated.c +++ b/hw/usb/ccid-card-emulated.c @@ -140,7 +140,7 @@ static void emulated_apdu_from_guest(CCIDCardState *base, const uint8_t *apdu, uint32_t len) { EmulatedState *card = EMULATED_CCID_CARD(base); - EmulEvent *event = (EmulEvent *)g_malloc(sizeof(EmulEvent) + len); + EmulEvent *event = g_malloc(sizeof(EmulEvent) + len); assert(event); event->p.data.type = EMUL_GUEST_APDU; diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index dac100c67c..4df0428089 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -2262,8 +2262,7 @@ static int kvm_get_supported_feature_msrs(KVMState *s) } assert(msr_list.nmsrs > 0); - kvm_feature_msrs = (struct kvm_msr_list *) \ - g_malloc0(sizeof(msr_list) + + kvm_feature_msrs = g_malloc0(sizeof(msr_list) + msr_list.nmsrs * sizeof(msr_list.indices[0])); kvm_feature_msrs->nmsrs = msr_list.nmsrs; diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c index 8e4969edeb..e738d83e81 100644 --- a/target/i386/whpx/whpx-all.c +++ b/target/i386/whpx/whpx-all.c @@ -1164,9 +1164,8 @@ static void whpx_translate_cpu_breakpoints( (breakpoints->breakpoints ? breakpoints->breakpoints->used : 0); struct whpx_breakpoint_collection *new_breakpoints = - (struct whpx_breakpoint_collection *)g_malloc0( - sizeof(struct whpx_breakpoint_collection) + - max_breakpoints * sizeof(struct whpx_breakpoint)); + g_malloc0(sizeof(struct whpx_breakpoint_collection) + + max_breakpoints * sizeof(struct whpx_breakpoint)); new_breakpoints->allocated = max_breakpoints; new_breakpoints->used = 0; diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c index 508c24cfec..da8c47f57b 100644 --- a/target/s390x/kvm/kvm.c +++ b/target/s390x/kvm/kvm.c @@ -1033,7 +1033,7 @@ int kvm_arch_remove_hw_breakpoint(target_ulong addr, } size = nb_hw_breakpoints * sizeof(struct kvm_hw_breakpoint); hw_breakpoints = - (struct kvm_hw_breakpoint *)g_realloc(hw_breakpoints, size); + g_realloc(hw_breakpoints, size); } else { g_free(hw_breakpoints); hw_breakpoints = NULL; diff --git a/ui/vnc-enc-hextile.c b/ui/vnc-enc-hextile.c index 4215bd7daf..c763256f29 100644 --- a/ui/vnc-enc-hextile.c +++ b/ui/vnc-enc-hextile.c @@ -50,8 +50,8 @@ int vnc_hextile_send_framebuffer_update(VncState *vs, int x, int has_fg, has_bg; uint8_t *last_fg, *last_bg; - last_fg = (uint8_t *) g_malloc(VNC_SERVER_FB_BYTES); - last_bg = (uint8_t *) g_malloc(VNC_SERVER_FB_BYTES); + last_fg = g_malloc(VNC_SERVER_FB_BYTES); + last_bg = g_malloc(VNC_SERVER_FB_BYTES); has_fg = has_bg = 0; for (j = y; j < (y + h); j += 16) { for (i = x; i < (x + w); i += 16) { From b1f6208cf986a60e1c9f8b960db5a00851f48f98 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Mon, 17 Oct 2022 21:20:22 +0800 Subject: [PATCH 041/705] tests/qtest: migration-test: Fix [-Werror=format-overflow=] build warning When tmpfs is NULL, a build warning is seen with GCC 9.3.0. It's strange that GCC 11.2.0 on Ubuntu 22.04 does not catch this, neither did the QEMU CI. While we are here, improve the error message as well. Reported-by: Shengjiang Wu Fixes: e5553c1b8d28 ("tests/qtest: migration-test: Avoid using hardcoded /tmp") Signed-off-by: Bin Meng Reviewed-by: Markus Armbruster Message-Id: <20221017132023.2228641-1-bmeng.cn@gmail.com> Signed-off-by: Laurent Vivier --- tests/qtest/migration-test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c index ef4427ff4d..aa1ba179fa 100644 --- a/tests/qtest/migration-test.c +++ b/tests/qtest/migration-test.c @@ -2481,8 +2481,8 @@ int main(int argc, char **argv) tmpfs = g_dir_make_tmp("migration-test-XXXXXX", &err); if (!tmpfs) { - g_test_message("g_dir_make_tmp on path (%s): %s", tmpfs, - err->message); + g_test_message("Can't create temporary directory in %s: %s", + g_get_tmp_dir(), err->message); } g_assert(tmpfs); From 1c324bf908e3de1cf352e36484c73dc07767d938 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Mon, 17 Oct 2022 21:20:23 +0800 Subject: [PATCH 042/705] tests/qtest: vhost-user-test: Fix [-Werror=format-overflow=] build warning When tmpfs is NULL, a build warning is seen with GCC 9.3.0. It's strange that GCC 11.2.0 on Ubuntu 22.04 does not catch this, neither did the QEMU CI. While we are here, improve the error message as well. Reported-by: Shengjiang Wu Fixes: e6efe236c1d1 ("tests/qtest: vhost-user-test: Avoid using hardcoded /tmp") Signed-off-by: Bin Meng Reviewed-by: Markus Armbruster Message-Id: <20221017132023.2228641-2-bmeng.cn@gmail.com> Signed-off-by: Laurent Vivier --- tests/qtest/vhost-user-test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/qtest/vhost-user-test.c b/tests/qtest/vhost-user-test.c index e8d2da7228..bf9f7c4248 100644 --- a/tests/qtest/vhost-user-test.c +++ b/tests/qtest/vhost-user-test.c @@ -571,8 +571,8 @@ static TestServer *test_server_new(const gchar *name, tmpfs = g_dir_make_tmp("vhost-test-XXXXXX", &err); if (!tmpfs) { - g_test_message("g_dir_make_tmp on path (%s): %s", tmpfs, - err->message); + g_test_message("Can't create temporary directory in %s: %s", + g_get_tmp_dir(), err->message); g_error_free(err); } g_assert(tmpfs); From 6191347991225a291ce38f5faf4d6e8181b5561f Mon Sep 17 00:00:00 2001 From: dinglimin Date: Wed, 28 Sep 2022 17:03:12 +0800 Subject: [PATCH 043/705] vmstate-static-checker:remove this redundant return Jump statements, such as return and continue let you change the default flow of program execution, but jump statements that direct the control flow to the original direction are just a waste of keystrokes. Signed-off-by: dinglimin Reviewed-by: John Snow Message-Id: <20220928090312.2537-1-dinglimin@cmss.chinamobile.com> Signed-off-by: Laurent Vivier --- scripts/vmstate-static-checker.py | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/vmstate-static-checker.py b/scripts/vmstate-static-checker.py index b369388360..dfeee8231a 100755 --- a/scripts/vmstate-static-checker.py +++ b/scripts/vmstate-static-checker.py @@ -367,7 +367,6 @@ def check_machine_type(s, d): if s["Name"] != d["Name"]: print("Warning: checking incompatible machine types:", end=' ') print("\"" + s["Name"] + "\", \"" + d["Name"] + "\"") - return def main(): From fe8a7390c10c78b806211d7e36727c461d39a17f Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 13 Oct 2022 14:05:00 +0100 Subject: [PATCH 044/705] include/hw/scsi/scsi.h: Remove unused scsi_legacy_handle_cmdline() prototype MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In commit 1454509726719e0933c80 we removed the function scsi_legacy_handle_cmdline() and all of its callers, but forgot to delete the prototype from the header function. Delete the prototype too. Signed-off-by: Peter Maydell Reviewed-by: Thomas Huth Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20221013130500.967432-1-peter.maydell@linaro.org> Signed-off-by: Laurent Vivier --- include/hw/scsi/scsi.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h index 3b1b3d278e..6ea4b64fe7 100644 --- a/include/hw/scsi/scsi.h +++ b/include/hw/scsi/scsi.h @@ -188,7 +188,6 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk, const char *serial, Error **errp); void scsi_bus_set_ua(SCSIBus *bus, SCSISense sense); void scsi_bus_legacy_handle_cmdline(SCSIBus *bus); -void scsi_legacy_handle_cmdline(void); SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, SCSIDevice *d, uint32_t tag, uint32_t lun, void *hba_private); From 281ac13ecedf8bfe1b83e566f39cb5683e553cb6 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Sun, 23 Oct 2022 21:13:41 +0200 Subject: [PATCH 045/705] m68k: write bootinfo as rom section and re-randomize on reboot Rather than poking directly into RAM, add the bootinfo block as a proper ROM, so that it's restored when rebooting the system. This way, if the guest corrupts any of the bootinfo items, but then tries to reboot, it'll still be restored back to normal as expected. Then, since the RNG seed needs to be fresh on each boot, regenerate the RNG seed in the ROM when reseting the CPU. Cc: Geert Uytterhoeven Cc: Laurent Vivier Signed-off-by: Jason A. Donenfeld Message-Id: <20221023191340.36238-1-Jason@zx2c4.com> Signed-off-by: Laurent Vivier --- hw/m68k/bootinfo.h | 48 ++++++++++++++++---------------- hw/m68k/q800.c | 69 +++++++++++++++++++++++++++++++++------------- hw/m68k/virt.c | 51 ++++++++++++++++++++++++---------- 3 files changed, 110 insertions(+), 58 deletions(-) diff --git a/hw/m68k/bootinfo.h b/hw/m68k/bootinfo.h index 897162b818..a3d37e3c80 100644 --- a/hw/m68k/bootinfo.h +++ b/hw/m68k/bootinfo.h @@ -12,66 +12,66 @@ #ifndef HW_M68K_BOOTINFO_H #define HW_M68K_BOOTINFO_H -#define BOOTINFO0(as, base, id) \ +#define BOOTINFO0(base, id) \ do { \ - stw_phys(as, base, id); \ + stw_p(base, id); \ base += 2; \ - stw_phys(as, base, sizeof(struct bi_record)); \ + stw_p(base, sizeof(struct bi_record)); \ base += 2; \ } while (0) -#define BOOTINFO1(as, base, id, value) \ +#define BOOTINFO1(base, id, value) \ do { \ - stw_phys(as, base, id); \ + stw_p(base, id); \ base += 2; \ - stw_phys(as, base, sizeof(struct bi_record) + 4); \ + stw_p(base, sizeof(struct bi_record) + 4); \ base += 2; \ - stl_phys(as, base, value); \ + stl_p(base, value); \ base += 4; \ } while (0) -#define BOOTINFO2(as, base, id, value1, value2) \ +#define BOOTINFO2(base, id, value1, value2) \ do { \ - stw_phys(as, base, id); \ + stw_p(base, id); \ base += 2; \ - stw_phys(as, base, sizeof(struct bi_record) + 8); \ + stw_p(base, sizeof(struct bi_record) + 8); \ base += 2; \ - stl_phys(as, base, value1); \ + stl_p(base, value1); \ base += 4; \ - stl_phys(as, base, value2); \ + stl_p(base, value2); \ base += 4; \ } while (0) -#define BOOTINFOSTR(as, base, id, string) \ +#define BOOTINFOSTR(base, id, string) \ do { \ int i; \ - stw_phys(as, base, id); \ + stw_p(base, id); \ base += 2; \ - stw_phys(as, base, \ + stw_p(base, \ (sizeof(struct bi_record) + strlen(string) + \ 1 /* null termination */ + 3 /* padding */) & ~3); \ base += 2; \ for (i = 0; string[i]; i++) { \ - stb_phys(as, base++, string[i]); \ + stb_p(base++, string[i]); \ } \ - stb_phys(as, base++, 0); \ - base = (base + 3) & ~3; \ + stb_p(base++, 0); \ + base = QEMU_ALIGN_PTR_UP(base, 4); \ } while (0) -#define BOOTINFODATA(as, base, id, data, len) \ +#define BOOTINFODATA(base, id, data, len) \ do { \ int i; \ - stw_phys(as, base, id); \ + stw_p(base, id); \ base += 2; \ - stw_phys(as, base, \ + stw_p(base, \ (sizeof(struct bi_record) + len + \ 2 /* length field */ + 3 /* padding */) & ~3); \ base += 2; \ - stw_phys(as, base, len); \ + stw_p(base, len); \ base += 2; \ for (i = 0; i < len; ++i) { \ - stb_phys(as, base++, data[i]); \ + stb_p(base++, data[i]); \ } \ - base = (base + 3) & ~3; \ + base = QEMU_ALIGN_PTR_UP(base, 4); \ } while (0) #endif diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c index a4590c2cb0..e09e244ddc 100644 --- a/hw/m68k/q800.c +++ b/hw/m68k/q800.c @@ -321,11 +321,22 @@ static const TypeInfo glue_info = { }, }; +typedef struct { + M68kCPU *cpu; + struct bi_record *rng_seed; +} ResetInfo; + static void main_cpu_reset(void *opaque) { - M68kCPU *cpu = opaque; + ResetInfo *reset_info = opaque; + M68kCPU *cpu = reset_info->cpu; CPUState *cs = CPU(cpu); + if (reset_info->rng_seed) { + qemu_guest_getrandom_nofail((void *)reset_info->rng_seed->data + 2, + be16_to_cpu(*(uint16_t *)reset_info->rng_seed->data)); + } + cpu_reset(cs); cpu->env.aregs[7] = ldl_phys(cs->as, 0); cpu->env.pc = ldl_phys(cs->as, 4); @@ -386,6 +397,7 @@ static void q800_init(MachineState *machine) NubusBus *nubus; DeviceState *glue; DriveInfo *dinfo; + ResetInfo *reset_info; uint8_t rng_seed[32]; linux_boot = (kernel_filename != NULL); @@ -396,9 +408,12 @@ static void q800_init(MachineState *machine) exit(1); } + reset_info = g_new0(ResetInfo, 1); + /* init CPUs */ cpu = M68K_CPU(cpu_create(machine->cpu_type)); - qemu_register_reset(main_cpu_reset, cpu); + reset_info->cpu = cpu; + qemu_register_reset(main_cpu_reset, reset_info); /* RAM */ memory_region_add_subregion(get_system_memory(), 0, machine->ram); @@ -598,6 +613,14 @@ static void q800_init(MachineState *machine) cs = CPU(cpu); if (linux_boot) { uint64_t high; + void *param_blob, *param_ptr, *param_rng_seed; + + if (kernel_cmdline) { + param_blob = g_malloc(strlen(kernel_cmdline) + 1024); + } else { + param_blob = g_malloc(1024); + } + kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, &elf_entry, NULL, &high, NULL, 1, EM_68K, 0, 0); @@ -607,23 +630,24 @@ static void q800_init(MachineState *machine) } stl_phys(cs->as, 4, elf_entry); /* reset initial PC */ parameters_base = (high + 1) & ~1; + param_ptr = param_blob; - BOOTINFO1(cs->as, parameters_base, BI_MACHTYPE, MACH_MAC); - BOOTINFO1(cs->as, parameters_base, BI_FPUTYPE, FPU_68040); - BOOTINFO1(cs->as, parameters_base, BI_MMUTYPE, MMU_68040); - BOOTINFO1(cs->as, parameters_base, BI_CPUTYPE, CPU_68040); - BOOTINFO1(cs->as, parameters_base, BI_MAC_CPUID, CPUB_68040); - BOOTINFO1(cs->as, parameters_base, BI_MAC_MODEL, MAC_MODEL_Q800); - BOOTINFO1(cs->as, parameters_base, + BOOTINFO1(param_ptr, BI_MACHTYPE, MACH_MAC); + BOOTINFO1(param_ptr, BI_FPUTYPE, FPU_68040); + BOOTINFO1(param_ptr, BI_MMUTYPE, MMU_68040); + BOOTINFO1(param_ptr, BI_CPUTYPE, CPU_68040); + BOOTINFO1(param_ptr, BI_MAC_CPUID, CPUB_68040); + BOOTINFO1(param_ptr, BI_MAC_MODEL, MAC_MODEL_Q800); + BOOTINFO1(param_ptr, BI_MAC_MEMSIZE, ram_size >> 20); /* in MB */ - BOOTINFO2(cs->as, parameters_base, BI_MEMCHUNK, 0, ram_size); - BOOTINFO1(cs->as, parameters_base, BI_MAC_VADDR, + BOOTINFO2(param_ptr, BI_MEMCHUNK, 0, ram_size); + BOOTINFO1(param_ptr, BI_MAC_VADDR, VIDEO_BASE + macfb_mode->offset); - BOOTINFO1(cs->as, parameters_base, BI_MAC_VDEPTH, graphic_depth); - BOOTINFO1(cs->as, parameters_base, BI_MAC_VDIM, + BOOTINFO1(param_ptr, BI_MAC_VDEPTH, graphic_depth); + BOOTINFO1(param_ptr, BI_MAC_VDIM, (graphic_height << 16) | graphic_width); - BOOTINFO1(cs->as, parameters_base, BI_MAC_VROW, macfb_mode->stride); - BOOTINFO1(cs->as, parameters_base, BI_MAC_SCCBASE, SCC_BASE); + BOOTINFO1(param_ptr, BI_MAC_VROW, macfb_mode->stride); + BOOTINFO1(param_ptr, BI_MAC_SCCBASE, SCC_BASE); rom = g_malloc(sizeof(*rom)); memory_region_init_ram_ptr(rom, NULL, "m68k_fake_mac.rom", @@ -632,13 +656,14 @@ static void q800_init(MachineState *machine) memory_region_add_subregion(get_system_memory(), MACROM_ADDR, rom); if (kernel_cmdline) { - BOOTINFOSTR(cs->as, parameters_base, BI_COMMAND_LINE, + BOOTINFOSTR(param_ptr, BI_COMMAND_LINE, kernel_cmdline); } /* Pass seed to RNG. */ + param_rng_seed = param_ptr; qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed)); - BOOTINFODATA(cs->as, parameters_base, BI_RNG_SEED, + BOOTINFODATA(param_ptr, BI_RNG_SEED, rng_seed, sizeof(rng_seed)); /* load initrd */ @@ -653,13 +678,19 @@ static void q800_init(MachineState *machine) initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK; load_image_targphys(initrd_filename, initrd_base, ram_size - initrd_base); - BOOTINFO2(cs->as, parameters_base, BI_RAMDISK, initrd_base, + BOOTINFO2(param_ptr, BI_RAMDISK, initrd_base, initrd_size); } else { initrd_base = 0; initrd_size = 0; } - BOOTINFO0(cs->as, parameters_base, BI_LAST); + BOOTINFO0(param_ptr, BI_LAST); + rom_add_blob_fixed_as("bootinfo", param_blob, param_ptr - param_blob, + parameters_base, cs->as); + reset_info->rng_seed = rom_ptr_for_as(cs->as, parameters_base, + param_ptr - param_blob) + + (param_rng_seed - param_blob); + g_free(param_blob); } else { uint8_t *ptr; /* allocate and load BIOS */ diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c index f7b903ea1b..89c4108eb5 100644 --- a/hw/m68k/virt.c +++ b/hw/m68k/virt.c @@ -89,6 +89,7 @@ typedef struct { M68kCPU *cpu; hwaddr initial_pc; hwaddr initial_stack; + struct bi_record *rng_seed; } ResetInfo; static void main_cpu_reset(void *opaque) @@ -97,6 +98,11 @@ static void main_cpu_reset(void *opaque) M68kCPU *cpu = reset_info->cpu; CPUState *cs = CPU(cpu); + if (reset_info->rng_seed) { + qemu_guest_getrandom_nofail((void *)reset_info->rng_seed->data + 2, + be16_to_cpu(*(uint16_t *)reset_info->rng_seed->data)); + } + cpu_reset(cs); cpu->env.aregs[7] = reset_info->initial_stack; cpu->env.pc = reset_info->initial_pc; @@ -212,6 +218,13 @@ static void virt_init(MachineState *machine) if (kernel_filename) { CPUState *cs = CPU(cpu); uint64_t high; + void *param_blob, *param_ptr, *param_rng_seed; + + if (kernel_cmdline) { + param_blob = g_malloc(strlen(kernel_cmdline) + 1024); + } else { + param_blob = g_malloc(1024); + } kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, &elf_entry, NULL, &high, NULL, 1, @@ -222,35 +235,37 @@ static void virt_init(MachineState *machine) } reset_info->initial_pc = elf_entry; parameters_base = (high + 1) & ~1; + param_ptr = param_blob; - BOOTINFO1(cs->as, parameters_base, BI_MACHTYPE, MACH_VIRT); - BOOTINFO1(cs->as, parameters_base, BI_FPUTYPE, FPU_68040); - BOOTINFO1(cs->as, parameters_base, BI_MMUTYPE, MMU_68040); - BOOTINFO1(cs->as, parameters_base, BI_CPUTYPE, CPU_68040); - BOOTINFO2(cs->as, parameters_base, BI_MEMCHUNK, 0, ram_size); + BOOTINFO1(param_ptr, BI_MACHTYPE, MACH_VIRT); + BOOTINFO1(param_ptr, BI_FPUTYPE, FPU_68040); + BOOTINFO1(param_ptr, BI_MMUTYPE, MMU_68040); + BOOTINFO1(param_ptr, BI_CPUTYPE, CPU_68040); + BOOTINFO2(param_ptr, BI_MEMCHUNK, 0, ram_size); - BOOTINFO1(cs->as, parameters_base, BI_VIRT_QEMU_VERSION, + BOOTINFO1(param_ptr, BI_VIRT_QEMU_VERSION, ((QEMU_VERSION_MAJOR << 24) | (QEMU_VERSION_MINOR << 16) | (QEMU_VERSION_MICRO << 8))); - BOOTINFO2(cs->as, parameters_base, BI_VIRT_GF_PIC_BASE, + BOOTINFO2(param_ptr, BI_VIRT_GF_PIC_BASE, VIRT_GF_PIC_MMIO_BASE, VIRT_GF_PIC_IRQ_BASE); - BOOTINFO2(cs->as, parameters_base, BI_VIRT_GF_RTC_BASE, + BOOTINFO2(param_ptr, BI_VIRT_GF_RTC_BASE, VIRT_GF_RTC_MMIO_BASE, VIRT_GF_RTC_IRQ_BASE); - BOOTINFO2(cs->as, parameters_base, BI_VIRT_GF_TTY_BASE, + BOOTINFO2(param_ptr, BI_VIRT_GF_TTY_BASE, VIRT_GF_TTY_MMIO_BASE, VIRT_GF_TTY_IRQ_BASE); - BOOTINFO2(cs->as, parameters_base, BI_VIRT_CTRL_BASE, + BOOTINFO2(param_ptr, BI_VIRT_CTRL_BASE, VIRT_CTRL_MMIO_BASE, VIRT_CTRL_IRQ_BASE); - BOOTINFO2(cs->as, parameters_base, BI_VIRT_VIRTIO_BASE, + BOOTINFO2(param_ptr, BI_VIRT_VIRTIO_BASE, VIRT_VIRTIO_MMIO_BASE, VIRT_VIRTIO_IRQ_BASE); if (kernel_cmdline) { - BOOTINFOSTR(cs->as, parameters_base, BI_COMMAND_LINE, + BOOTINFOSTR(param_ptr, BI_COMMAND_LINE, kernel_cmdline); } /* Pass seed to RNG. */ + param_rng_seed = param_ptr; qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed)); - BOOTINFODATA(cs->as, parameters_base, BI_RNG_SEED, + BOOTINFODATA(param_ptr, BI_RNG_SEED, rng_seed, sizeof(rng_seed)); /* load initrd */ @@ -265,13 +280,19 @@ static void virt_init(MachineState *machine) initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK; load_image_targphys(initrd_filename, initrd_base, ram_size - initrd_base); - BOOTINFO2(cs->as, parameters_base, BI_RAMDISK, initrd_base, + BOOTINFO2(param_ptr, BI_RAMDISK, initrd_base, initrd_size); } else { initrd_base = 0; initrd_size = 0; } - BOOTINFO0(cs->as, parameters_base, BI_LAST); + BOOTINFO0(param_ptr, BI_LAST); + rom_add_blob_fixed_as("bootinfo", param_blob, param_ptr - param_blob, + parameters_base, cs->as); + reset_info->rng_seed = rom_ptr_for_as(cs->as, parameters_base, + param_ptr - param_blob) + + (param_rng_seed - param_blob); + g_free(param_blob); } } From 3648d31fa81c4a391b8cd74e9fcd410a74f72383 Mon Sep 17 00:00:00 2001 From: Peter Delevoryas Date: Mon, 24 Oct 2022 11:20:15 +0200 Subject: [PATCH 046/705] hw/i2c/aspeed: Fix old reg slave receive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I think when Klaus ported his slave mode changes from the original patch series to the rewritten I2C module, he changed the behavior of the first byte that is received by the slave device. What's supposed to happen is that the AspeedI2CBus's slave device's i2c_event callback should run, and if the event is "send_async", then it should populate the byte buffer with the 8-bit I2C address that is being sent to. Since we only support "send_async", the lowest bit should always be 0 (indicating that the master is requesting to send data). This is the code Klaus had previously, for reference. [1] switch (event) { case I2C_START_SEND: bus->buf = bus->dev_addr << 1; bus->buf &= I2CD_BYTE_BUF_RX_MASK; bus->buf <<= I2CD_BYTE_BUF_RX_SHIFT; bus->intr_status |= (I2CD_INTR_SLAVE_ADDR_RX_MATCH | I2CD_INTR_RX_DONE); aspeed_i2c_set_state(bus, I2CD_STXD); break; [1]: https://lore.kernel.org/qemu-devel/20220331165737.1073520-4-its@irrelevant.dk/ Fixes: a8d48f59cd021b25 ("hw/i2c/aspeed: add slave device in old register mode") Signed-off-by: Peter Delevoryas Reviewed-by: Klaus Jensen Message-Id: <20220820225712.713209-2-peter@pjd.dev> Signed-off-by: Cédric Le Goater --- hw/i2c/aspeed_i2c.c | 8 +++++--- include/hw/i2c/aspeed_i2c.h | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c index 42c6d69b82..c166fd20fa 100644 --- a/hw/i2c/aspeed_i2c.c +++ b/hw/i2c/aspeed_i2c.c @@ -1131,7 +1131,9 @@ static int aspeed_i2c_bus_slave_event(I2CSlave *slave, enum i2c_event event) AspeedI2CBus *bus = ASPEED_I2C_BUS(qbus->parent); uint32_t reg_intr_sts = aspeed_i2c_bus_intr_sts_offset(bus); uint32_t reg_byte_buf = aspeed_i2c_bus_byte_buf_offset(bus); - uint32_t value; + uint32_t reg_dev_addr = aspeed_i2c_bus_dev_addr_offset(bus); + uint32_t dev_addr = SHARED_ARRAY_FIELD_EX32(bus->regs, reg_dev_addr, + SLAVE_DEV_ADDR1); if (aspeed_i2c_is_new_mode(bus->controller)) { return aspeed_i2c_bus_new_slave_event(bus, event); @@ -1139,8 +1141,8 @@ static int aspeed_i2c_bus_slave_event(I2CSlave *slave, enum i2c_event event) switch (event) { case I2C_START_SEND_ASYNC: - value = SHARED_ARRAY_FIELD_EX32(bus->regs, reg_byte_buf, TX_BUF); - SHARED_ARRAY_FIELD_DP32(bus->regs, reg_byte_buf, RX_BUF, value << 1); + /* Bit[0] == 0 indicates "send". */ + SHARED_ARRAY_FIELD_DP32(bus->regs, reg_byte_buf, RX_BUF, dev_addr << 1); ARRAY_FIELD_DP32(bus->regs, I2CD_INTR_STS, SLAVE_ADDR_RX_MATCH, 1); SHARED_ARRAY_FIELD_DP32(bus->regs, reg_intr_sts, RX_DONE, 1); diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h index 300a89b343..adc904d6c1 100644 --- a/include/hw/i2c/aspeed_i2c.h +++ b/include/hw/i2c/aspeed_i2c.h @@ -130,6 +130,7 @@ REG32(I2CD_CMD, 0x14) /* I2CD Command/Status */ SHARED_FIELD(M_TX_CMD, 1, 1) SHARED_FIELD(M_START_CMD, 0, 1) REG32(I2CD_DEV_ADDR, 0x18) /* Slave Device Address */ + SHARED_FIELD(SLAVE_DEV_ADDR1, 0, 7) REG32(I2CD_POOL_CTRL, 0x1C) /* Pool Buffer Control */ SHARED_FIELD(RX_COUNT, 24, 5) SHARED_FIELD(RX_SIZE, 16, 5) From 7b5093b85b74158efda30798ffff6da973a353c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Mon, 24 Oct 2022 11:20:15 +0200 Subject: [PATCH 047/705] tests/avocado/machine_aspeed.py: Fix typos on buildroot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace 'buidroot' and 'builroot' by 'buildroot'. Fixes: f7bc7da0724f ("test/avocado/machine_aspeed.py: Add tests using buildroot images") Reviewed-by: Thomas Huth Reviewed-by: Richard Henderson Reviewed-by: Joel Stanley Message-Id: <20220923084803.498337-2-clg@kaod.org> Signed-off-by: Cédric Le Goater --- tests/avocado/machine_aspeed.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/avocado/machine_aspeed.py b/tests/avocado/machine_aspeed.py index 124649a24b..fba6527026 100644 --- a/tests/avocado/machine_aspeed.py +++ b/tests/avocado/machine_aspeed.py @@ -92,7 +92,7 @@ class AST2x00Machine(QemuSystemTest): self.do_test_arm_aspeed(image_path) - def do_test_arm_aspeed_buidroot_start(self, image, cpu_id): + def do_test_arm_aspeed_buildroot_start(self, image, cpu_id): self.require_netdev('user') self.vm.set_console() @@ -111,11 +111,11 @@ class AST2x00Machine(QemuSystemTest): exec_command(self, 'root') time.sleep(0.1) - def do_test_arm_aspeed_buidroot_poweroff(self): + def do_test_arm_aspeed_buildroot_poweroff(self): exec_command_and_wait_for_pattern(self, 'poweroff', 'reboot: System halted'); - def test_arm_ast2500_evb_builroot(self): + def test_arm_ast2500_evb_buildroot(self): """ :avocado: tags=arch:arm :avocado: tags=machine:ast2500-evb @@ -129,7 +129,7 @@ class AST2x00Machine(QemuSystemTest): self.vm.add_args('-device', 'tmp105,bus=aspeed.i2c.bus.3,address=0x4d,id=tmp-test'); - self.do_test_arm_aspeed_buidroot_start(image_path, '0x0') + self.do_test_arm_aspeed_buildroot_start(image_path, '0x0') exec_command_and_wait_for_pattern(self, 'echo lm75 0x4d > /sys/class/i2c-dev/i2c-3/device/new_device', @@ -141,9 +141,9 @@ class AST2x00Machine(QemuSystemTest): exec_command_and_wait_for_pattern(self, 'cat /sys/class/hwmon/hwmon1/temp1_input', '18000') - self.do_test_arm_aspeed_buidroot_poweroff() + self.do_test_arm_aspeed_buildroot_poweroff() - def test_arm_ast2600_evb_builroot(self): + def test_arm_ast2600_evb_buildroot(self): """ :avocado: tags=arch:arm :avocado: tags=machine:ast2600-evb @@ -159,7 +159,7 @@ class AST2x00Machine(QemuSystemTest): 'tmp105,bus=aspeed.i2c.bus.3,address=0x4d,id=tmp-test'); self.vm.add_args('-device', 'ds1338,bus=aspeed.i2c.bus.3,address=0x32'); - self.do_test_arm_aspeed_buidroot_start(image_path, '0xf00') + self.do_test_arm_aspeed_buildroot_start(image_path, '0xf00') exec_command_and_wait_for_pattern(self, 'echo lm75 0x4d > /sys/class/i2c-dev/i2c-3/device/new_device', @@ -177,7 +177,7 @@ class AST2x00Machine(QemuSystemTest): year = time.strftime("%Y") exec_command_and_wait_for_pattern(self, 'hwclock -f /dev/rtc1', year); - self.do_test_arm_aspeed_buidroot_poweroff() + self.do_test_arm_aspeed_buildroot_poweroff() class AST2x00MachineSDK(QemuSystemTest): From db96605a49b334eeb2a5d1cc12981778f7d792aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Mon, 24 Oct 2022 11:20:15 +0200 Subject: [PATCH 048/705] ssi: cache SSIPeripheralClass to avoid GET_CLASS() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Investigating why some BMC models are so slow compared to a plain ARM virt machines I did some profiling of: ./qemu-system-arm -M romulus-bmc -nic user \ -drive file=obmc-phosphor-image-romulus.static.mtd,format=raw,if=mtd \ -nographic -serial mon:stdio And saw that object_class_dynamic_cast_assert was dominating the profile times. We have a number of cases in this model of the SSI bus. As the class is static once the object is created we just cache it and use it instead of the dynamic case macros. Profiling against: ./tests/venv/bin/avocado run \ tests/avocado/machine_aspeed.py:test_arm_ast2500_romulus_openbmc_v2_9_0 Before: 35.565 s ± 0.087 s After: 15.713 s ± 0.287 s Signed-off-by: Alex Bennée Cc: Cédric Le Goater Tested-by: Cédric Le Goater Reviewed-by: Cédric Le Goater Message-Id: <20220811151413.3350684-6-alex.bennee@linaro.org> Message-Id: <20220923084803.498337-6-clg@kaod.org> Signed-off-by: Cédric Le Goater --- hw/ssi/ssi.c | 18 ++++++++---------- include/hw/ssi/ssi.h | 3 +++ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/hw/ssi/ssi.c b/hw/ssi/ssi.c index 003931fb50..d54a109bee 100644 --- a/hw/ssi/ssi.c +++ b/hw/ssi/ssi.c @@ -38,9 +38,8 @@ static void ssi_cs_default(void *opaque, int n, int level) bool cs = !!level; assert(n == 0); if (s->cs != cs) { - SSIPeripheralClass *ssc = SSI_PERIPHERAL_GET_CLASS(s); - if (ssc->set_cs) { - ssc->set_cs(s, cs); + if (s->spc->set_cs) { + s->spc->set_cs(s, cs); } } s->cs = cs; @@ -48,11 +47,11 @@ static void ssi_cs_default(void *opaque, int n, int level) static uint32_t ssi_transfer_raw_default(SSIPeripheral *dev, uint32_t val) { - SSIPeripheralClass *ssc = SSI_PERIPHERAL_GET_CLASS(dev); + SSIPeripheralClass *ssc = dev->spc; if ((dev->cs && ssc->cs_polarity == SSI_CS_HIGH) || - (!dev->cs && ssc->cs_polarity == SSI_CS_LOW) || - ssc->cs_polarity == SSI_CS_NONE) { + (!dev->cs && ssc->cs_polarity == SSI_CS_LOW) || + ssc->cs_polarity == SSI_CS_NONE) { return ssc->transfer(dev, val); } return 0; @@ -67,6 +66,7 @@ static void ssi_peripheral_realize(DeviceState *dev, Error **errp) ssc->cs_polarity != SSI_CS_NONE) { qdev_init_gpio_in_named(dev, ssi_cs_default, SSI_GPIO_CS, 1); } + s->spc = ssc; ssc->realize(s, errp); } @@ -115,13 +115,11 @@ uint32_t ssi_transfer(SSIBus *bus, uint32_t val) { BusState *b = BUS(bus); BusChild *kid; - SSIPeripheralClass *ssc; uint32_t r = 0; QTAILQ_FOREACH(kid, &b->children, sibling) { - SSIPeripheral *peripheral = SSI_PERIPHERAL(kid->child); - ssc = SSI_PERIPHERAL_GET_CLASS(peripheral); - r |= ssc->transfer_raw(peripheral, val); + SSIPeripheral *p = SSI_PERIPHERAL(kid->child); + r |= p->spc->transfer_raw(p, val); } return r; diff --git a/include/hw/ssi/ssi.h b/include/hw/ssi/ssi.h index f411858ab0..6950f86810 100644 --- a/include/hw/ssi/ssi.h +++ b/include/hw/ssi/ssi.h @@ -59,6 +59,9 @@ struct SSIPeripheralClass { struct SSIPeripheral { DeviceState parent_obj; + /* cache the class */ + SSIPeripheralClass *spc; + /* Chip select state */ bool cs; }; From b84a9482a3c9e3b6fbdf1fd4b0477e4a7a51683e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Mon, 24 Oct 2022 11:20:15 +0200 Subject: [PATCH 049/705] aspeed/smc: Cache AspeedSMCClass MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Store a reference on the AspeedSMC class under the flash object and use it when accessing the flash contents. Avoiding the class cast checkers in these hot paths improves performance by 10% when running the aspeed avocado tests. Message-Id: <20220923084803.498337-7-clg@kaod.org> Signed-off-by: Cédric Le Goater --- hw/ssi/aspeed_smc.c | 9 ++++----- include/hw/ssi/aspeed_smc.h | 2 ++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c index faed7e0cbe..22df4be528 100644 --- a/hw/ssi/aspeed_smc.c +++ b/hw/ssi/aspeed_smc.c @@ -388,7 +388,7 @@ static inline int aspeed_smc_flash_cmd(const AspeedSMCFlash *fl) static inline int aspeed_smc_flash_addr_width(const AspeedSMCFlash *fl) { const AspeedSMCState *s = fl->controller; - AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s); + AspeedSMCClass *asc = fl->asc; if (asc->addr_width) { return asc->addr_width(s); @@ -420,7 +420,7 @@ static uint32_t aspeed_smc_check_segment_addr(const AspeedSMCFlash *fl, uint32_t addr) { const AspeedSMCState *s = fl->controller; - AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s); + AspeedSMCClass *asc = fl->asc; AspeedSegments seg; asc->reg_to_segment(s, s->regs[R_SEG_ADDR0 + fl->cs], &seg); @@ -1234,7 +1234,6 @@ static const TypeInfo aspeed_smc_info = { static void aspeed_smc_flash_realize(DeviceState *dev, Error **errp) { AspeedSMCFlash *s = ASPEED_SMC_FLASH(dev); - AspeedSMCClass *asc; g_autofree char *name = g_strdup_printf(TYPE_ASPEED_SMC_FLASH ".%d", s->cs); if (!s->controller) { @@ -1242,14 +1241,14 @@ static void aspeed_smc_flash_realize(DeviceState *dev, Error **errp) return; } - asc = ASPEED_SMC_GET_CLASS(s->controller); + s->asc = ASPEED_SMC_GET_CLASS(s->controller); /* * Use the default segment value to size the memory region. This * can be changed by FW at runtime. */ memory_region_init_io(&s->mmio, OBJECT(s), &aspeed_smc_flash_ops, - s, name, asc->segments[s->cs].size); + s, name, s->asc->segments[s->cs].size); sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio); } diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h index 2d5f8f3d8f..8e1dda556b 100644 --- a/include/hw/ssi/aspeed_smc.h +++ b/include/hw/ssi/aspeed_smc.h @@ -30,6 +30,7 @@ #include "qom/object.h" struct AspeedSMCState; +struct AspeedSMCClass; #define TYPE_ASPEED_SMC_FLASH "aspeed.smc.flash" OBJECT_DECLARE_SIMPLE_TYPE(AspeedSMCFlash, ASPEED_SMC_FLASH) @@ -37,6 +38,7 @@ struct AspeedSMCFlash { SysBusDevice parent_obj; struct AspeedSMCState *controller; + struct AspeedSMCClass *asc; uint8_t cs; MemoryRegion mmio; From e5c1b489acac6e2d264c67d5c0665ef940f85e86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Mon, 24 Oct 2022 11:20:15 +0200 Subject: [PATCH 050/705] ast2600: Drop NEON from the CPU features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, the CPU features exposed to the AST2600 QEMU machines are : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm But, the features of the Cortex A7 CPU on the Aspeed AST2600 A3 SoC are : half thumb fastmult vfp edsp vfpv3 vfpv3d16 tls vfpv4 idiva idivt lpae evtstrm Drop NEON support in the Aspeed AST2600 SoC. Reviewed-by: Joel Stanley Message-Id: <20220928164719.655586-3-clg@kaod.org> Signed-off-by: Cédric Le Goater --- hw/arm/aspeed_ast2600.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c index aa2cd90bec..cd75465c2b 100644 --- a/hw/arm/aspeed_ast2600.c +++ b/hw/arm/aspeed_ast2600.c @@ -307,6 +307,8 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp) object_property_set_int(OBJECT(&s->cpu[i]), "cntfrq", 1125000000, &error_abort); + object_property_set_bool(OBJECT(&s->cpu[i]), "neon", false, + &error_abort); object_property_set_link(OBJECT(&s->cpu[i]), "memory", OBJECT(s->memory), &error_abort); From 104bdaffd753042c652a3731753fc3b391e32d87 Mon Sep 17 00:00:00 2001 From: Patrick Williams Date: Mon, 24 Oct 2022 11:20:15 +0200 Subject: [PATCH 051/705] hw/arm/aspeed: increase Bletchley memory size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For the PVT-class hardware we have increased the memory size of this device to 2 GiB. Adjust the device model accordingly. Signed-off-by: Patrick Williams Reviewed-by: Cédric Le Goater Message-Id: <20221007110529.3657749-1-patrick@stwcx.xyz> Signed-off-by: Cédric Le Goater --- hw/arm/aspeed.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c index bc3ecdb619..bc5c1e1677 100644 --- a/hw/arm/aspeed.c +++ b/hw/arm/aspeed.c @@ -1330,6 +1330,13 @@ static void aspeed_machine_fuji_class_init(ObjectClass *oc, void *data) aspeed_soc_num_cpus(amc->soc_name); }; +/* On 32-bit hosts, lower RAM to 1G because of the 2047 MB limit */ +#if HOST_LONG_BITS == 32 +#define BLETCHLEY_BMC_RAM_SIZE (1 * GiB) +#else +#define BLETCHLEY_BMC_RAM_SIZE (2 * GiB) +#endif + static void aspeed_machine_bletchley_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -1344,7 +1351,7 @@ static void aspeed_machine_bletchley_class_init(ObjectClass *oc, void *data) amc->num_cs = 2; amc->macs_mask = ASPEED_MAC2_ON; amc->i2c_init = bletchley_bmc_i2c_init; - mc->default_ram_size = 512 * MiB; + mc->default_ram_size = BLETCHLEY_BMC_RAM_SIZE; mc->default_cpus = mc->min_cpus = mc->max_cpus = aspeed_soc_num_cpus(amc->soc_name); } From 2389bcc259df915d1b244b270e9c3d3d7e097a88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Mon, 24 Oct 2022 11:20:15 +0200 Subject: [PATCH 052/705] m25p80: Add basic support for the SFDP command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit JEDEC STANDARD JESD216 for Serial Flash Discovery Parameters (SFDP) provides a mean to describe the features of a serial flash device using a set of internal parameter tables. This is the initial framework for the RDSFDP command giving access to a private SFDP area under the flash. This area now needs to be populated with the flash device characteristics, using a new 'sfdp_read' handler under FlashPartInfo. Reviewed-by: Francisco Iglesias Message-Id: <20220722063602.128144-2-clg@kaod.org> Message-Id: <20221013161241.2805140-2-clg@kaod.org> Signed-off-by: Cédric Le Goater --- MAINTAINERS | 2 +- hw/block/m25p80.c | 27 +++++++++++++++++++++++++++ hw/block/m25p80_sfdp.h | 18 ++++++++++++++++++ hw/block/trace-events | 1 + 4 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 hw/block/m25p80_sfdp.h diff --git a/MAINTAINERS b/MAINTAINERS index e3d5b7e09c..32e495e165 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1915,7 +1915,7 @@ SSI M: Alistair Francis S: Maintained F: hw/ssi/* -F: hw/block/m25p80.c +F: hw/block/m25p80* F: include/hw/ssi/ssi.h X: hw/ssi/xilinx_* F: tests/qtest/m25p80-test.c diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c index a8d2519141..abdc4c0b0d 100644 --- a/hw/block/m25p80.c +++ b/hw/block/m25p80.c @@ -35,6 +35,7 @@ #include "qapi/error.h" #include "trace.h" #include "qom/object.h" +#include "m25p80_sfdp.h" /* 16 MiB max in 3 byte address mode */ #define MAX_3BYTES_SIZE 0x1000000 @@ -72,6 +73,7 @@ typedef struct FlashPartInfo { * This field inform how many die is in the chip. */ uint8_t die_cnt; + uint8_t (*sfdp_read)(uint32_t sfdp_addr); } FlashPartInfo; /* adapted from linux */ @@ -355,6 +357,7 @@ typedef enum { BULK_ERASE = 0xc7, READ_FSR = 0x70, RDCR = 0x15, + RDSFDP = 0x5a, READ = 0x03, READ4 = 0x13, @@ -421,6 +424,7 @@ typedef enum { STATE_COLLECTING_DATA, STATE_COLLECTING_VAR_LEN_DATA, STATE_READING_DATA, + STATE_READING_SFDP, } CMDState; typedef enum { @@ -679,6 +683,8 @@ static inline int get_addr_length(Flash *s) } switch (s->cmd_in_progress) { + case RDSFDP: + return 3; case PP4: case PP4_4: case QPP_4: @@ -823,6 +829,11 @@ static void complete_collecting_data(Flash *s) " by device\n"); } break; + + case RDSFDP: + s->state = STATE_READING_SFDP; + break; + default: break; } @@ -1431,6 +1442,16 @@ static void decode_new_cmd(Flash *s, uint32_t value) qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Unknown cmd %x\n", value); } break; + case RDSFDP: + if (s->pi->sfdp_read) { + s->needed_bytes = get_addr_length(s) + 1; /* SFDP addr + dummy */ + s->pos = 0; + s->len = 0; + s->state = STATE_COLLECTING_DATA; + break; + } + /* Fallthrough */ + default: s->pos = 0; s->len = 1; @@ -1538,6 +1559,12 @@ static uint32_t m25p80_transfer8(SSIPeripheral *ss, uint32_t tx) } } break; + case STATE_READING_SFDP: + assert(s->pi->sfdp_read); + r = s->pi->sfdp_read(s->cur_addr); + trace_m25p80_read_sfdp(s, s->cur_addr, (uint8_t)r); + s->cur_addr = (s->cur_addr + 1) & (M25P80_SFDP_MAX_SIZE - 1); + break; default: case STATE_IDLE: diff --git a/hw/block/m25p80_sfdp.h b/hw/block/m25p80_sfdp.h new file mode 100644 index 0000000000..230b07ef33 --- /dev/null +++ b/hw/block/m25p80_sfdp.h @@ -0,0 +1,18 @@ +/* + * M25P80 SFDP + * + * Copyright (c) 2020, IBM Corporation. + * + * This code is licensed under the GPL version 2 or later. See the + * COPYING file in the top-level directory. + */ + +#ifndef HW_M25P80_SFDP_H +#define HW_M25P80_SFDP_H + +/* + * SFDP area has a 3 bytes address space. + */ +#define M25P80_SFDP_MAX_SIZE (1 << 24) + +#endif diff --git a/hw/block/trace-events b/hw/block/trace-events index d86b53520c..2c45a62bd5 100644 --- a/hw/block/trace-events +++ b/hw/block/trace-events @@ -80,5 +80,6 @@ m25p80_page_program(void *s, uint32_t addr, uint8_t tx) "[%p] page program cur_a m25p80_transfer(void *s, uint8_t state, uint32_t len, uint8_t needed, uint32_t pos, uint32_t cur_addr, uint8_t t) "[%p] Transfer state 0x%"PRIx8" len 0x%"PRIx32" needed 0x%"PRIx8" pos 0x%"PRIx32" addr 0x%"PRIx32" tx 0x%"PRIx8 m25p80_read_byte(void *s, uint32_t addr, uint8_t v) "[%p] Read byte 0x%"PRIx32"=0x%"PRIx8 m25p80_read_data(void *s, uint32_t pos, uint8_t v) "[%p] Read data 0x%"PRIx32"=0x%"PRIx8 +m25p80_read_sfdp(void *s, uint32_t addr, uint8_t v) "[%p] Read SFDP 0x%"PRIx32"=0x%"PRIx8 m25p80_binding(void *s) "[%p] Binding to IF_MTD drive" m25p80_binding_no_bdrv(void *s) "[%p] No BDRV - binding to RAM" From 5eb24fbd8c82fc71282fa6db5184a40e560ed25c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Mon, 24 Oct 2022 11:20:15 +0200 Subject: [PATCH 053/705] m25p80: Add the n25q256a SFDP table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The same values were collected on 4 differents OpenPower systems, palmettos, romulus and tacoma. The SFDP table size is defined as being 0x100 bytes but it could be bigger. Only the mandatory table for basic features is available at byte 0x30. Reviewed-by: Francisco Iglesias Message-Id: <20220722063602.128144-3-clg@kaod.org> Message-Id: <20221013161241.2805140-3-clg@kaod.org> Signed-off-by: Cédric Le Goater --- hw/block/m25p80.c | 8 +++--- hw/block/m25p80_sfdp.c | 58 ++++++++++++++++++++++++++++++++++++++++++ hw/block/m25p80_sfdp.h | 2 ++ hw/block/meson.build | 1 + 4 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 hw/block/m25p80_sfdp.c diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c index abdc4c0b0d..13e7b28fd2 100644 --- a/hw/block/m25p80.c +++ b/hw/block/m25p80.c @@ -247,13 +247,15 @@ static const FlashPartInfo known_devices[] = { { INFO("n25q128a11", 0x20bb18, 0, 64 << 10, 256, ER_4K) }, { INFO("n25q128a13", 0x20ba18, 0, 64 << 10, 256, ER_4K) }, { INFO("n25q256a11", 0x20bb19, 0, 64 << 10, 512, ER_4K) }, - { INFO("n25q256a13", 0x20ba19, 0, 64 << 10, 512, ER_4K) }, + { INFO("n25q256a13", 0x20ba19, 0, 64 << 10, 512, ER_4K), + .sfdp_read = m25p80_sfdp_n25q256a }, { INFO("n25q512a11", 0x20bb20, 0, 64 << 10, 1024, ER_4K) }, { INFO("n25q512a13", 0x20ba20, 0, 64 << 10, 1024, ER_4K) }, { INFO("n25q128", 0x20ba18, 0, 64 << 10, 256, 0) }, { INFO("n25q256a", 0x20ba19, 0, 64 << 10, 512, - ER_4K | HAS_SR_BP3_BIT6 | HAS_SR_TB) }, - { INFO("n25q512a", 0x20ba20, 0, 64 << 10, 1024, ER_4K) }, + ER_4K | HAS_SR_BP3_BIT6 | HAS_SR_TB), + .sfdp_read = m25p80_sfdp_n25q256a }, + { INFO("n25q512a", 0x20ba20, 0, 64 << 10, 1024, ER_4K) }, { INFO("n25q512ax3", 0x20ba20, 0x1000, 64 << 10, 1024, ER_4K) }, { INFO("mt25ql512ab", 0x20ba20, 0x1044, 64 << 10, 1024, ER_4K | ER_32K) }, { INFO_STACKED("mt35xu01g", 0x2c5b1b, 0x104100, 128 << 10, 1024, diff --git a/hw/block/m25p80_sfdp.c b/hw/block/m25p80_sfdp.c new file mode 100644 index 0000000000..24ec05de79 --- /dev/null +++ b/hw/block/m25p80_sfdp.c @@ -0,0 +1,58 @@ +/* + * M25P80 Serial Flash Discoverable Parameter (SFDP) + * + * Copyright (c) 2020, IBM Corporation. + * + * This code is licensed under the GPL version 2 or later. See the + * COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qemu/host-utils.h" +#include "m25p80_sfdp.h" + +#define define_sfdp_read(model) \ + uint8_t m25p80_sfdp_##model(uint32_t addr) \ + { \ + assert(is_power_of_2(sizeof(sfdp_##model))); \ + return sfdp_##model[addr & (sizeof(sfdp_##model) - 1)]; \ + } + +/* + * Micron + */ +static const uint8_t sfdp_n25q256a[] = { + 0x53, 0x46, 0x44, 0x50, 0x00, 0x01, 0x00, 0xff, + 0x00, 0x00, 0x01, 0x09, 0x30, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xe5, 0x20, 0xfb, 0xff, 0xff, 0xff, 0xff, 0x0f, + 0x29, 0xeb, 0x27, 0x6b, 0x08, 0x3b, 0x27, 0xbb, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x27, 0xbb, + 0xff, 0xff, 0x29, 0xeb, 0x0c, 0x20, 0x10, 0xd8, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +}; +define_sfdp_read(n25q256a); diff --git a/hw/block/m25p80_sfdp.h b/hw/block/m25p80_sfdp.h index 230b07ef33..7245412cc1 100644 --- a/hw/block/m25p80_sfdp.h +++ b/hw/block/m25p80_sfdp.h @@ -15,4 +15,6 @@ */ #define M25P80_SFDP_MAX_SIZE (1 << 24) +uint8_t m25p80_sfdp_n25q256a(uint32_t addr); + #endif diff --git a/hw/block/meson.build b/hw/block/meson.build index 1908abd45c..b434d5654c 100644 --- a/hw/block/meson.build +++ b/hw/block/meson.build @@ -12,6 +12,7 @@ softmmu_ss.add(when: 'CONFIG_ONENAND', if_true: files('onenand.c')) softmmu_ss.add(when: 'CONFIG_PFLASH_CFI01', if_true: files('pflash_cfi01.c')) softmmu_ss.add(when: 'CONFIG_PFLASH_CFI02', if_true: files('pflash_cfi02.c')) softmmu_ss.add(when: 'CONFIG_SSI_M25P80', if_true: files('m25p80.c')) +softmmu_ss.add(when: 'CONFIG_SSI_M25P80', if_true: files('m25p80_sfdp.c')) softmmu_ss.add(when: 'CONFIG_SWIM', if_true: files('swim.c')) softmmu_ss.add(when: 'CONFIG_XEN', if_true: files('xen-block.c')) softmmu_ss.add(when: 'CONFIG_TC58128', if_true: files('tc58128.c')) From 0c14a3c7da01d7a7343824ed08c664e98b9c4057 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Mon, 24 Oct 2022 11:20:15 +0200 Subject: [PATCH 054/705] m25p80: Add erase size for mx25l25635e MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Francisco Iglesias Message-Id: <20221013161241.2805140-4-clg@kaod.org> Signed-off-by: Cédric Le Goater --- hw/block/m25p80.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c index 13e7b28fd2..637c25d76e 100644 --- a/hw/block/m25p80.c +++ b/hw/block/m25p80.c @@ -232,7 +232,8 @@ static const FlashPartInfo known_devices[] = { { INFO("mx25l6405d", 0xc22017, 0, 64 << 10, 128, 0) }, { INFO("mx25l12805d", 0xc22018, 0, 64 << 10, 256, 0) }, { INFO("mx25l12855e", 0xc22618, 0, 64 << 10, 256, 0) }, - { INFO6("mx25l25635e", 0xc22019, 0xc22019, 64 << 10, 512, 0) }, + { INFO6("mx25l25635e", 0xc22019, 0xc22019, 64 << 10, 512, + ER_4K | ER_32K) }, { INFO("mx25l25655e", 0xc22619, 0, 64 << 10, 512, 0) }, { INFO("mx66l51235f", 0xc2201a, 0, 64 << 10, 1024, ER_4K | ER_32K) }, { INFO("mx66u51235f", 0xc2253a, 0, 64 << 10, 1024, ER_4K | ER_32K) }, From dc907a667cbd2689a3618608c0c079fb03926ec3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Mon, 24 Oct 2022 11:20:15 +0200 Subject: [PATCH 055/705] m25p80: Add the mx25l25635e SFPD table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SFDP table is 0x80 bytes long. The mandatory table for basic features is available at byte 0x30 and an extra Macronix specific table is available at 0x60. 4B opcodes are not supported. Reviewed-by: Francisco Iglesias Message-Id: <20220722063602.128144-4-clg@kaod.org> Message-Id: <20221013161241.2805140-5-clg@kaod.org> Signed-off-by: Cédric Le Goater --- hw/block/m25p80.c | 2 +- hw/block/m25p80_sfdp.c | 26 ++++++++++++++++++++++++++ hw/block/m25p80_sfdp.h | 3 +++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c index 637c25d76e..5ddc544e1b 100644 --- a/hw/block/m25p80.c +++ b/hw/block/m25p80.c @@ -233,7 +233,7 @@ static const FlashPartInfo known_devices[] = { { INFO("mx25l12805d", 0xc22018, 0, 64 << 10, 256, 0) }, { INFO("mx25l12855e", 0xc22618, 0, 64 << 10, 256, 0) }, { INFO6("mx25l25635e", 0xc22019, 0xc22019, 64 << 10, 512, - ER_4K | ER_32K) }, + ER_4K | ER_32K), .sfdp_read = m25p80_sfdp_mx25l25635e }, { INFO("mx25l25655e", 0xc22619, 0, 64 << 10, 512, 0) }, { INFO("mx66l51235f", 0xc2201a, 0, 64 << 10, 1024, ER_4K | ER_32K) }, { INFO("mx66u51235f", 0xc2253a, 0, 64 << 10, 1024, ER_4K | ER_32K) }, diff --git a/hw/block/m25p80_sfdp.c b/hw/block/m25p80_sfdp.c index 24ec05de79..6499c4c399 100644 --- a/hw/block/m25p80_sfdp.c +++ b/hw/block/m25p80_sfdp.c @@ -56,3 +56,29 @@ static const uint8_t sfdp_n25q256a[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }; define_sfdp_read(n25q256a); + + +/* + * Matronix + */ + +/* mx25l25635e. No 4B opcodes */ +static const uint8_t sfdp_mx25l25635e[] = { + 0x53, 0x46, 0x44, 0x50, 0x00, 0x01, 0x01, 0xff, + 0x00, 0x00, 0x01, 0x09, 0x30, 0x00, 0x00, 0xff, + 0xc2, 0x00, 0x01, 0x04, 0x60, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xe5, 0x20, 0xf3, 0xff, 0xff, 0xff, 0xff, 0x0f, + 0x44, 0xeb, 0x08, 0x6b, 0x08, 0x3b, 0x04, 0xbb, + 0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, + 0xff, 0xff, 0x00, 0xff, 0x0c, 0x20, 0x0f, 0x52, + 0x10, 0xd8, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x36, 0x00, 0x27, 0xf7, 0x4f, 0xff, 0xff, + 0xd9, 0xc8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +}; +define_sfdp_read(mx25l25635e) diff --git a/hw/block/m25p80_sfdp.h b/hw/block/m25p80_sfdp.h index 7245412cc1..ecdb9c7f69 100644 --- a/hw/block/m25p80_sfdp.h +++ b/hw/block/m25p80_sfdp.h @@ -17,4 +17,7 @@ uint8_t m25p80_sfdp_n25q256a(uint32_t addr); +uint8_t m25p80_sfdp_mx25l25635e(uint32_t addr); + + #endif From 51f4613d6514b4cfb132997b81d6d70be86fef8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Mon, 24 Oct 2022 11:20:15 +0200 Subject: [PATCH 056/705] m25p80: Add the mx25l25635f SFPD table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The mx25l25635e and mx25l25635f chips have the same JEDEC id but the mx25l25635f has more capabilities reported in the SFDP table. Support for 4B opcodes is of interest because it is exploited by the Linux kernel. The SFDP table size is 0x200 bytes long. The mandatory table for basic features is available at byte 0x30 and an extra Macronix specific table is available at 0x60. Reviewed-by: Francisco Iglesias Message-Id: <20220722063602.128144-5-clg@kaod.org> Message-Id: <20221013161241.2805140-6-clg@kaod.org> Signed-off-by: Cédric Le Goater --- hw/block/m25p80.c | 2 ++ hw/block/m25p80_sfdp.c | 68 ++++++++++++++++++++++++++++++++++++++++++ hw/block/m25p80_sfdp.h | 1 + 3 files changed, 71 insertions(+) diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c index 5ddc544e1b..ffed1d69d5 100644 --- a/hw/block/m25p80.c +++ b/hw/block/m25p80.c @@ -234,6 +234,8 @@ static const FlashPartInfo known_devices[] = { { INFO("mx25l12855e", 0xc22618, 0, 64 << 10, 256, 0) }, { INFO6("mx25l25635e", 0xc22019, 0xc22019, 64 << 10, 512, ER_4K | ER_32K), .sfdp_read = m25p80_sfdp_mx25l25635e }, + { INFO6("mx25l25635f", 0xc22019, 0xc22019, 64 << 10, 512, + ER_4K | ER_32K), .sfdp_read = m25p80_sfdp_mx25l25635f }, { INFO("mx25l25655e", 0xc22619, 0, 64 << 10, 512, 0) }, { INFO("mx66l51235f", 0xc2201a, 0, 64 << 10, 1024, ER_4K | ER_32K) }, { INFO("mx66u51235f", 0xc2253a, 0, 64 << 10, 1024, ER_4K | ER_32K) }, diff --git a/hw/block/m25p80_sfdp.c b/hw/block/m25p80_sfdp.c index 6499c4c399..70c13aea7c 100644 --- a/hw/block/m25p80_sfdp.c +++ b/hw/block/m25p80_sfdp.c @@ -82,3 +82,71 @@ static const uint8_t sfdp_mx25l25635e[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }; define_sfdp_read(mx25l25635e) + +static const uint8_t sfdp_mx25l25635f[] = { + 0x53, 0x46, 0x44, 0x50, 0x00, 0x01, 0x01, 0xff, + 0x00, 0x00, 0x01, 0x09, 0x30, 0x00, 0x00, 0xff, + 0xc2, 0x00, 0x01, 0x04, 0x60, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xe5, 0x20, 0xf3, 0xff, 0xff, 0xff, 0xff, 0x0f, + 0x44, 0xeb, 0x08, 0x6b, 0x08, 0x3b, 0x04, 0xbb, + 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, + 0xff, 0xff, 0x44, 0xeb, 0x0c, 0x20, 0x0f, 0x52, + 0x10, 0xd8, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x36, 0x00, 0x27, 0x9d, 0xf9, 0xc0, 0x64, + 0x85, 0xcb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xc2, 0xf5, 0x08, 0x0a, + 0x08, 0x04, 0x03, 0x06, 0x00, 0x00, 0x07, 0x29, + 0x17, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +}; +define_sfdp_read(mx25l25635f); diff --git a/hw/block/m25p80_sfdp.h b/hw/block/m25p80_sfdp.h index ecdb9c7f69..506817bdc9 100644 --- a/hw/block/m25p80_sfdp.h +++ b/hw/block/m25p80_sfdp.h @@ -18,6 +18,7 @@ uint8_t m25p80_sfdp_n25q256a(uint32_t addr); uint8_t m25p80_sfdp_mx25l25635e(uint32_t addr); +uint8_t m25p80_sfdp_mx25l25635f(uint32_t addr); #endif From 52514908ffb35bcd2f443fe5fe7c3b8f8d83ae33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Mon, 24 Oct 2022 11:20:15 +0200 Subject: [PATCH 057/705] m25p80: Add the mx66l1g45g SFDP table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SFDP table size is 0x200 bytes long. The mandatory table for basic features is available at byte 0x30 plus some more Macronix specific tables. Reviewed-by: Francisco Iglesias Message-Id: <20220722063602.128144-6-clg@kaod.org> Message-Id: <20221013161241.2805140-7-clg@kaod.org> Signed-off-by: Cédric Le Goater --- hw/block/m25p80.c | 3 +- hw/block/m25p80_sfdp.c | 68 ++++++++++++++++++++++++++++++++++++++++++ hw/block/m25p80_sfdp.h | 2 +- 3 files changed, 71 insertions(+), 2 deletions(-) diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c index ffed1d69d5..376be327e5 100644 --- a/hw/block/m25p80.c +++ b/hw/block/m25p80.c @@ -240,7 +240,8 @@ static const FlashPartInfo known_devices[] = { { INFO("mx66l51235f", 0xc2201a, 0, 64 << 10, 1024, ER_4K | ER_32K) }, { INFO("mx66u51235f", 0xc2253a, 0, 64 << 10, 1024, ER_4K | ER_32K) }, { INFO("mx66u1g45g", 0xc2253b, 0, 64 << 10, 2048, ER_4K | ER_32K) }, - { INFO("mx66l1g45g", 0xc2201b, 0, 64 << 10, 2048, ER_4K | ER_32K) }, + { INFO("mx66l1g45g", 0xc2201b, 0, 64 << 10, 2048, ER_4K | ER_32K), + .sfdp_read = m25p80_sfdp_mx66l1g45g }, /* Micron */ { INFO("n25q032a11", 0x20bb16, 0, 64 << 10, 64, ER_4K) }, diff --git a/hw/block/m25p80_sfdp.c b/hw/block/m25p80_sfdp.c index 70c13aea7c..38c3ced34d 100644 --- a/hw/block/m25p80_sfdp.c +++ b/hw/block/m25p80_sfdp.c @@ -150,3 +150,71 @@ static const uint8_t sfdp_mx25l25635f[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }; define_sfdp_read(mx25l25635f); + +static const uint8_t sfdp_mx66l1g45g[] = { + 0x53, 0x46, 0x44, 0x50, 0x06, 0x01, 0x02, 0xff, + 0x00, 0x06, 0x01, 0x10, 0x30, 0x00, 0x00, 0xff, + 0xc2, 0x00, 0x01, 0x04, 0x10, 0x01, 0x00, 0xff, + 0x84, 0x00, 0x01, 0x02, 0xc0, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xe5, 0x20, 0xfb, 0xff, 0xff, 0xff, 0xff, 0x3f, + 0x44, 0xeb, 0x08, 0x6b, 0x08, 0x3b, 0x04, 0xbb, + 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, + 0xff, 0xff, 0x44, 0xeb, 0x0c, 0x20, 0x0f, 0x52, + 0x10, 0xd8, 0x00, 0xff, 0xd6, 0x49, 0xc5, 0x00, + 0x85, 0xdf, 0x04, 0xe3, 0x44, 0x03, 0x67, 0x38, + 0x30, 0xb0, 0x30, 0xb0, 0xf7, 0xbd, 0xd5, 0x5c, + 0x4a, 0x9e, 0x29, 0xff, 0xf0, 0x50, 0xf9, 0x85, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x7f, 0xef, 0xff, 0xff, 0x21, 0x5c, 0xdc, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x36, 0x00, 0x27, 0x9d, 0xf9, 0xc0, 0x64, + 0x85, 0xcb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xc2, 0xf5, 0x08, 0x00, 0x0c, 0x04, 0x08, 0x08, + 0x01, 0x00, 0x19, 0x0f, 0x01, 0x01, 0x06, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +}; +define_sfdp_read(mx66l1g45g); diff --git a/hw/block/m25p80_sfdp.h b/hw/block/m25p80_sfdp.h index 506817bdc9..ec829644b0 100644 --- a/hw/block/m25p80_sfdp.h +++ b/hw/block/m25p80_sfdp.h @@ -19,6 +19,6 @@ uint8_t m25p80_sfdp_n25q256a(uint32_t addr); uint8_t m25p80_sfdp_mx25l25635e(uint32_t addr); uint8_t m25p80_sfdp_mx25l25635f(uint32_t addr); - +uint8_t m25p80_sfdp_mx66l1g45g(uint32_t addr); #endif From e9041884d273928286733a3e966cd89d7cc2d1c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Mon, 24 Oct 2022 11:20:15 +0200 Subject: [PATCH 058/705] m25p80: Add the w25q256 SFPD table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SFDP table size is 0x100 bytes long. Only the mandatory table for basic features is available at byte 0x80. Reviewed-by: Francisco Iglesias Message-Id: <20220722063602.128144-7-clg@kaod.org> Message-Id: <20221013161241.2805140-8-clg@kaod.org> Signed-off-by: Cédric Le Goater --- hw/block/m25p80.c | 3 ++- hw/block/m25p80_sfdp.c | 40 ++++++++++++++++++++++++++++++++++++++++ hw/block/m25p80_sfdp.h | 2 ++ 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c index 376be327e5..6119c57c89 100644 --- a/hw/block/m25p80.c +++ b/hw/block/m25p80.c @@ -345,7 +345,8 @@ static const FlashPartInfo known_devices[] = { { INFO("w25q64", 0xef4017, 0, 64 << 10, 128, ER_4K) }, { INFO("w25q80", 0xef5014, 0, 64 << 10, 16, ER_4K) }, { INFO("w25q80bl", 0xef4014, 0, 64 << 10, 16, ER_4K) }, - { INFO("w25q256", 0xef4019, 0, 64 << 10, 512, ER_4K) }, + { INFO("w25q256", 0xef4019, 0, 64 << 10, 512, ER_4K), + .sfdp_read = m25p80_sfdp_w25q256 }, { INFO("w25q512jv", 0xef4020, 0, 64 << 10, 1024, ER_4K) }, { INFO("w25q01jvq", 0xef4021, 0, 64 << 10, 2048, ER_4K) }, }; diff --git a/hw/block/m25p80_sfdp.c b/hw/block/m25p80_sfdp.c index 38c3ced34d..5b011559d4 100644 --- a/hw/block/m25p80_sfdp.c +++ b/hw/block/m25p80_sfdp.c @@ -218,3 +218,43 @@ static const uint8_t sfdp_mx66l1g45g[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }; define_sfdp_read(mx66l1g45g); + +/* + * Windbond + */ + +static const uint8_t sfdp_w25q256[] = { + 0x53, 0x46, 0x44, 0x50, 0x00, 0x01, 0x00, 0xff, + 0x00, 0x00, 0x01, 0x09, 0x80, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xe5, 0x20, 0xf3, 0xff, 0xff, 0xff, 0xff, 0x0f, + 0x44, 0xeb, 0x08, 0x6b, 0x08, 0x3b, 0x42, 0xbb, + 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, + 0xff, 0xff, 0x21, 0xeb, 0x0c, 0x20, 0x0f, 0x52, + 0x10, 0xd8, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +}; +define_sfdp_read(w25q256); diff --git a/hw/block/m25p80_sfdp.h b/hw/block/m25p80_sfdp.h index ec829644b0..595be9000d 100644 --- a/hw/block/m25p80_sfdp.h +++ b/hw/block/m25p80_sfdp.h @@ -21,4 +21,6 @@ uint8_t m25p80_sfdp_mx25l25635e(uint32_t addr); uint8_t m25p80_sfdp_mx25l25635f(uint32_t addr); uint8_t m25p80_sfdp_mx66l1g45g(uint32_t addr); +uint8_t m25p80_sfdp_w25q256(uint32_t addr); + #endif From 8e57da5856e47904029d982240ed25c3cdef5e80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Mon, 24 Oct 2022 11:20:16 +0200 Subject: [PATCH 059/705] m25p80: Add the w25q512jv SFPD table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SFDP table size is 0x100 bytes long. The mandatory table for basic features is available at byte 0x80 and two extra Winbond specifics table are available at 0xC0 and 0xF0. Reviewed-by: Francisco Iglesias Message-Id: <20220722063602.128144-8-clg@kaod.org> Message-Id: <20221013161241.2805140-9-clg@kaod.org> Signed-off-by: Cédric Le Goater --- hw/block/m25p80.c | 3 ++- hw/block/m25p80_sfdp.c | 36 ++++++++++++++++++++++++++++++++++++ hw/block/m25p80_sfdp.h | 1 + 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c index 6119c57c89..8353a00a05 100644 --- a/hw/block/m25p80.c +++ b/hw/block/m25p80.c @@ -347,7 +347,8 @@ static const FlashPartInfo known_devices[] = { { INFO("w25q80bl", 0xef4014, 0, 64 << 10, 16, ER_4K) }, { INFO("w25q256", 0xef4019, 0, 64 << 10, 512, ER_4K), .sfdp_read = m25p80_sfdp_w25q256 }, - { INFO("w25q512jv", 0xef4020, 0, 64 << 10, 1024, ER_4K) }, + { INFO("w25q512jv", 0xef4020, 0, 64 << 10, 1024, ER_4K), + .sfdp_read = m25p80_sfdp_w25q512jv }, { INFO("w25q01jvq", 0xef4021, 0, 64 << 10, 2048, ER_4K) }, }; diff --git a/hw/block/m25p80_sfdp.c b/hw/block/m25p80_sfdp.c index 5b011559d4..dad3d7e64f 100644 --- a/hw/block/m25p80_sfdp.c +++ b/hw/block/m25p80_sfdp.c @@ -258,3 +258,39 @@ static const uint8_t sfdp_w25q256[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }; define_sfdp_read(w25q256); + +static const uint8_t sfdp_w25q512jv[] = { + 0x53, 0x46, 0x44, 0x50, 0x06, 0x01, 0x01, 0xff, + 0x00, 0x06, 0x01, 0x10, 0x80, 0x00, 0x00, 0xff, + 0x84, 0x00, 0x01, 0x02, 0xd0, 0x00, 0x00, 0xff, + 0x03, 0x00, 0x01, 0x02, 0xf0, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xe5, 0x20, 0xfb, 0xff, 0xff, 0xff, 0xff, 0x1f, + 0x44, 0xeb, 0x08, 0x6b, 0x08, 0x3b, 0x42, 0xbb, + 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, + 0xff, 0xff, 0x40, 0xeb, 0x0c, 0x20, 0x0f, 0x52, + 0x10, 0xd8, 0x00, 0x00, 0x36, 0x02, 0xa6, 0x00, + 0x82, 0xea, 0x14, 0xe2, 0xe9, 0x63, 0x76, 0x33, + 0x7a, 0x75, 0x7a, 0x75, 0xf7, 0xa2, 0xd5, 0x5c, + 0x19, 0xf7, 0x4d, 0xff, 0xe9, 0x70, 0xf9, 0xa5, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x0a, 0xf0, 0xff, 0x21, 0xff, 0xdc, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +}; +define_sfdp_read(w25q512jv); diff --git a/hw/block/m25p80_sfdp.h b/hw/block/m25p80_sfdp.h index 595be9000d..e50f57e48e 100644 --- a/hw/block/m25p80_sfdp.h +++ b/hw/block/m25p80_sfdp.h @@ -22,5 +22,6 @@ uint8_t m25p80_sfdp_mx25l25635f(uint32_t addr); uint8_t m25p80_sfdp_mx66l1g45g(uint32_t addr); uint8_t m25p80_sfdp_w25q256(uint32_t addr); +uint8_t m25p80_sfdp_w25q512jv(uint32_t addr); #endif From a34b0d5315522159ba723feecf507a4d07e043f3 Mon Sep 17 00:00:00 2001 From: Patrick Williams Date: Mon, 24 Oct 2022 11:20:16 +0200 Subject: [PATCH 060/705] m25p80: Add the w25q01jvq SFPD table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Generated from hardware using the following command and then padding with 0xff to fill out a power-of-2: hexdump -v -e '8/1 "0x%02x, " "\n"' sfdp` Signed-off-by: Patrick Williams Reviewed-by: Francisco Iglesias [ clg: removed extern ] Message-Id: <20221006224424.3556372-1-patrick@stwcx.xyz> Message-Id: <20221013161241.2805140-10-clg@kaod.org> Signed-off-by: Cédric Le Goater --- hw/block/m25p80.c | 3 ++- hw/block/m25p80_sfdp.c | 36 ++++++++++++++++++++++++++++++++++++ hw/block/m25p80_sfdp.h | 2 ++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c index 8353a00a05..02adc87527 100644 --- a/hw/block/m25p80.c +++ b/hw/block/m25p80.c @@ -349,7 +349,8 @@ static const FlashPartInfo known_devices[] = { .sfdp_read = m25p80_sfdp_w25q256 }, { INFO("w25q512jv", 0xef4020, 0, 64 << 10, 1024, ER_4K), .sfdp_read = m25p80_sfdp_w25q512jv }, - { INFO("w25q01jvq", 0xef4021, 0, 64 << 10, 2048, ER_4K) }, + { INFO("w25q01jvq", 0xef4021, 0, 64 << 10, 2048, ER_4K), + .sfdp_read = m25p80_sfdp_w25q01jvq }, }; typedef enum { diff --git a/hw/block/m25p80_sfdp.c b/hw/block/m25p80_sfdp.c index dad3d7e64f..77615fa29e 100644 --- a/hw/block/m25p80_sfdp.c +++ b/hw/block/m25p80_sfdp.c @@ -294,3 +294,39 @@ static const uint8_t sfdp_w25q512jv[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }; define_sfdp_read(w25q512jv); + +static const uint8_t sfdp_w25q01jvq[] = { + 0x53, 0x46, 0x44, 0x50, 0x06, 0x01, 0x01, 0xff, + 0x00, 0x06, 0x01, 0x10, 0x80, 0x00, 0x00, 0xff, + 0x84, 0x00, 0x01, 0x02, 0xd0, 0x00, 0x00, 0xff, + 0x03, 0x00, 0x01, 0x02, 0xf0, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xe5, 0x20, 0xfb, 0xff, 0xff, 0xff, 0xff, 0x3f, + 0x44, 0xeb, 0x08, 0x6b, 0x08, 0x3b, 0x42, 0xbb, + 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, + 0xff, 0xff, 0x40, 0xeb, 0x0c, 0x20, 0x0f, 0x52, + 0x10, 0xd8, 0x00, 0x00, 0x36, 0x02, 0xa6, 0x00, + 0x82, 0xea, 0x14, 0xe2, 0xe9, 0x63, 0x76, 0x33, + 0x7a, 0x75, 0x7a, 0x75, 0xf7, 0xa2, 0xd5, 0x5c, + 0x19, 0xf7, 0x4d, 0xff, 0xe9, 0x70, 0xf9, 0xa5, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x0a, 0xf0, 0xff, 0x21, 0xff, 0xdc, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +}; +define_sfdp_read(w25q01jvq); diff --git a/hw/block/m25p80_sfdp.h b/hw/block/m25p80_sfdp.h index e50f57e48e..df7adfb5ce 100644 --- a/hw/block/m25p80_sfdp.h +++ b/hw/block/m25p80_sfdp.h @@ -24,4 +24,6 @@ uint8_t m25p80_sfdp_mx66l1g45g(uint32_t addr); uint8_t m25p80_sfdp_w25q256(uint32_t addr); uint8_t m25p80_sfdp_w25q512jv(uint32_t addr); +uint8_t m25p80_sfdp_w25q01jvq(uint32_t addr); + #endif From 703229132bb05327044368fc6d19f6acf7dde848 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Mon, 24 Oct 2022 11:20:16 +0200 Subject: [PATCH 061/705] arm/aspeed: Replace mx25l25635e chip model MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A mx25l25635f chip model is generally found on these machines. It's newer and uses 4B opcodes which is better to exercise the support in the Linux kernel. Reviewed-by: Francisco Iglesias Message-Id: <20220722063602.128144-9-clg@kaod.org> Message-Id: <20221013161241.2805140-11-clg@kaod.org> Signed-off-by: Cédric Le Goater --- hw/arm/aspeed.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c index bc5c1e1677..f8bc6d4a14 100644 --- a/hw/arm/aspeed.c +++ b/hw/arm/aspeed.c @@ -1099,7 +1099,7 @@ static void aspeed_machine_palmetto_class_init(ObjectClass *oc, void *data) amc->soc_name = "ast2400-a1"; amc->hw_strap1 = PALMETTO_BMC_HW_STRAP1; amc->fmc_model = "n25q256a"; - amc->spi_model = "mx25l25635e"; + amc->spi_model = "mx25l25635f"; amc->num_cs = 1; amc->i2c_init = palmetto_bmc_i2c_init; mc->default_ram_size = 256 * MiB; @@ -1150,7 +1150,7 @@ static void aspeed_machine_ast2500_evb_class_init(ObjectClass *oc, void *data) amc->soc_name = "ast2500-a1"; amc->hw_strap1 = AST2500_EVB_HW_STRAP1; amc->fmc_model = "mx25l25635e"; - amc->spi_model = "mx25l25635e"; + amc->spi_model = "mx25l25635f"; amc->num_cs = 1; amc->i2c_init = ast2500_evb_i2c_init; mc->default_ram_size = 512 * MiB; @@ -1200,7 +1200,7 @@ static void aspeed_machine_witherspoon_class_init(ObjectClass *oc, void *data) mc->desc = "OpenPOWER Witherspoon BMC (ARM1176)"; amc->soc_name = "ast2500-a1"; amc->hw_strap1 = WITHERSPOON_BMC_HW_STRAP1; - amc->fmc_model = "mx25l25635e"; + amc->fmc_model = "mx25l25635f"; amc->spi_model = "mx66l1g45g"; amc->num_cs = 2; amc->i2c_init = witherspoon_bmc_i2c_init; From f723f626627fda681327075105701695d7c630e5 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Tue, 27 Sep 2022 19:06:04 +0800 Subject: [PATCH 062/705] fsdev/virtfs-proxy-helper: Use g_mkdir() Use g_mkdir() to create a directory on all platforms. Signed-off-by: Bin Meng Reviewed-by: Christian Schoenebeck Message-Id: <20220927110632.1973965-27-bmeng.cn@gmail.com> Signed-off-by: Christian Schoenebeck --- fsdev/virtfs-proxy-helper.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fsdev/virtfs-proxy-helper.c b/fsdev/virtfs-proxy-helper.c index 2dde27922f..5cafcd7703 100644 --- a/fsdev/virtfs-proxy-helper.c +++ b/fsdev/virtfs-proxy-helper.c @@ -10,6 +10,7 @@ */ #include "qemu/osdep.h" +#include #include #include #include @@ -639,7 +640,7 @@ static int do_create_others(int type, struct iovec *iovec) if (retval < 0) { goto err_out; } - retval = mkdir(path.data, mode); + retval = g_mkdir(path.data, mode); break; case T_SYMLINK: retval = proxy_unmarshal(iovec, offset, "ss", &oldpath, &path); From 684f912034395a4958600a3ccca972db5d31be94 Mon Sep 17 00:00:00 2001 From: Christian Schoenebeck Date: Thu, 29 Sep 2022 13:41:06 +0200 Subject: [PATCH 063/705] tests/9p: split virtio-9p-test.c into tests and 9p client part This patch is pure refactoring, it does not change behaviour. virtio-9p-test.c grew to 1657 lines. Let's split this file up between actual 9p test cases vs. 9p test client, to make it easier to concentrate on the actual 9p tests. Move the 9p test client code to a new unit virtio-9p-client.c, which are basically all functions and types prefixed with v9fs_* already. Note that some client wrapper functions (do_*) are preserved in virtio-9p-test.c, simply because these wrapper functions are going to be wiped with subsequent patches anyway. As the global QGuestAllocator variable is moved to virtio-9p-client.c, add a new function v9fs_set_allocator() to be used by virtio-9p-test.c instead of fiddling with a global variable across units and libraries. Signed-off-by: Christian Schoenebeck Reviewed-by: Greg Kurz Message-Id: --- tests/qtest/libqos/meson.build | 1 + tests/qtest/libqos/virtio-9p-client.c | 684 +++++++++++++++++++++++ tests/qtest/libqos/virtio-9p-client.h | 138 +++++ tests/qtest/virtio-9p-test.c | 770 +------------------------- 4 files changed, 849 insertions(+), 744 deletions(-) create mode 100644 tests/qtest/libqos/virtio-9p-client.c create mode 100644 tests/qtest/libqos/virtio-9p-client.h diff --git a/tests/qtest/libqos/meson.build b/tests/qtest/libqos/meson.build index a5b6d5197a..113c80b4e4 100644 --- a/tests/qtest/libqos/meson.build +++ b/tests/qtest/libqos/meson.build @@ -34,6 +34,7 @@ libqos_srcs = files( 'tpci200.c', 'virtio.c', 'virtio-9p.c', + 'virtio-9p-client.c', 'virtio-balloon.c', 'virtio-blk.c', 'vhost-user-blk.c', diff --git a/tests/qtest/libqos/virtio-9p-client.c b/tests/qtest/libqos/virtio-9p-client.c new file mode 100644 index 0000000000..f5c35fd722 --- /dev/null +++ b/tests/qtest/libqos/virtio-9p-client.c @@ -0,0 +1,684 @@ +/* + * 9P network client for VirtIO 9P test cases (based on QTest) + * + * Copyright (c) 2014 SUSE LINUX Products GmbH + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +/* + * Not so fast! You might want to read the 9p developer docs first: + * https://wiki.qemu.org/Documentation/9p + */ + +#include "qemu/osdep.h" +#include "virtio-9p-client.h" + +#define QVIRTIO_9P_TIMEOUT_US (10 * 1000 * 1000) +static QGuestAllocator *alloc; + +void v9fs_set_allocator(QGuestAllocator *t_alloc) +{ + alloc = t_alloc; +} + +void v9fs_memwrite(P9Req *req, const void *addr, size_t len) +{ + qtest_memwrite(req->qts, req->t_msg + req->t_off, addr, len); + req->t_off += len; +} + +void v9fs_memskip(P9Req *req, size_t len) +{ + req->r_off += len; +} + +void v9fs_memread(P9Req *req, void *addr, size_t len) +{ + qtest_memread(req->qts, req->r_msg + req->r_off, addr, len); + req->r_off += len; +} + +void v9fs_uint8_read(P9Req *req, uint8_t *val) +{ + v9fs_memread(req, val, 1); +} + +void v9fs_uint16_write(P9Req *req, uint16_t val) +{ + uint16_t le_val = cpu_to_le16(val); + + v9fs_memwrite(req, &le_val, 2); +} + +void v9fs_uint16_read(P9Req *req, uint16_t *val) +{ + v9fs_memread(req, val, 2); + le16_to_cpus(val); +} + +void v9fs_uint32_write(P9Req *req, uint32_t val) +{ + uint32_t le_val = cpu_to_le32(val); + + v9fs_memwrite(req, &le_val, 4); +} + +void v9fs_uint64_write(P9Req *req, uint64_t val) +{ + uint64_t le_val = cpu_to_le64(val); + + v9fs_memwrite(req, &le_val, 8); +} + +void v9fs_uint32_read(P9Req *req, uint32_t *val) +{ + v9fs_memread(req, val, 4); + le32_to_cpus(val); +} + +void v9fs_uint64_read(P9Req *req, uint64_t *val) +{ + v9fs_memread(req, val, 8); + le64_to_cpus(val); +} + +/* len[2] string[len] */ +uint16_t v9fs_string_size(const char *string) +{ + size_t len = strlen(string); + + g_assert_cmpint(len, <=, UINT16_MAX - 2); + + return 2 + len; +} + +void v9fs_string_write(P9Req *req, const char *string) +{ + int len = strlen(string); + + g_assert_cmpint(len, <=, UINT16_MAX); + + v9fs_uint16_write(req, (uint16_t) len); + v9fs_memwrite(req, string, len); +} + +void v9fs_string_read(P9Req *req, uint16_t *len, char **string) +{ + uint16_t local_len; + + v9fs_uint16_read(req, &local_len); + if (len) { + *len = local_len; + } + if (string) { + *string = g_malloc(local_len + 1); + v9fs_memread(req, *string, local_len); + (*string)[local_len] = 0; + } else { + v9fs_memskip(req, local_len); + } +} + +typedef struct { + uint32_t size; + uint8_t id; + uint16_t tag; +} QEMU_PACKED P9Hdr; + +P9Req *v9fs_req_init(QVirtio9P *v9p, uint32_t size, uint8_t id, + uint16_t tag) +{ + P9Req *req = g_new0(P9Req, 1); + uint32_t total_size = 7; /* 9P header has well-known size of 7 bytes */ + P9Hdr hdr = { + .id = id, + .tag = cpu_to_le16(tag) + }; + + g_assert_cmpint(total_size, <=, UINT32_MAX - size); + total_size += size; + hdr.size = cpu_to_le32(total_size); + + g_assert_cmpint(total_size, <=, P9_MAX_SIZE); + + req->qts = global_qtest; + req->v9p = v9p; + req->t_size = total_size; + req->t_msg = guest_alloc(alloc, req->t_size); + v9fs_memwrite(req, &hdr, 7); + req->tag = tag; + return req; +} + +void v9fs_req_send(P9Req *req) +{ + QVirtio9P *v9p = req->v9p; + + req->r_msg = guest_alloc(alloc, P9_MAX_SIZE); + req->free_head = qvirtqueue_add(req->qts, v9p->vq, req->t_msg, req->t_size, + false, true); + qvirtqueue_add(req->qts, v9p->vq, req->r_msg, P9_MAX_SIZE, true, false); + qvirtqueue_kick(req->qts, v9p->vdev, v9p->vq, req->free_head); + req->t_off = 0; +} + +static const char *rmessage_name(uint8_t id) +{ + return + id == P9_RLERROR ? "RLERROR" : + id == P9_RVERSION ? "RVERSION" : + id == P9_RATTACH ? "RATTACH" : + id == P9_RWALK ? "RWALK" : + id == P9_RLOPEN ? "RLOPEN" : + id == P9_RWRITE ? "RWRITE" : + id == P9_RMKDIR ? "RMKDIR" : + id == P9_RLCREATE ? "RLCREATE" : + id == P9_RSYMLINK ? "RSYMLINK" : + id == P9_RLINK ? "RLINK" : + id == P9_RUNLINKAT ? "RUNLINKAT" : + id == P9_RFLUSH ? "RFLUSH" : + id == P9_RREADDIR ? "READDIR" : + ""; +} + +void v9fs_req_wait_for_reply(P9Req *req, uint32_t *len) +{ + QVirtio9P *v9p = req->v9p; + + qvirtio_wait_used_elem(req->qts, v9p->vdev, v9p->vq, req->free_head, len, + QVIRTIO_9P_TIMEOUT_US); +} + +void v9fs_req_recv(P9Req *req, uint8_t id) +{ + P9Hdr hdr; + + v9fs_memread(req, &hdr, 7); + hdr.size = ldl_le_p(&hdr.size); + hdr.tag = lduw_le_p(&hdr.tag); + + g_assert_cmpint(hdr.size, >=, 7); + g_assert_cmpint(hdr.size, <=, P9_MAX_SIZE); + g_assert_cmpint(hdr.tag, ==, req->tag); + + if (hdr.id != id) { + g_printerr("Received response %d (%s) instead of %d (%s)\n", + hdr.id, rmessage_name(hdr.id), id, rmessage_name(id)); + + if (hdr.id == P9_RLERROR) { + uint32_t err; + v9fs_uint32_read(req, &err); + g_printerr("Rlerror has errno %d (%s)\n", err, strerror(err)); + } + } + g_assert_cmpint(hdr.id, ==, id); +} + +void v9fs_req_free(P9Req *req) +{ + guest_free(alloc, req->t_msg); + guest_free(alloc, req->r_msg); + g_free(req); +} + +/* size[4] Rlerror tag[2] ecode[4] */ +void v9fs_rlerror(P9Req *req, uint32_t *err) +{ + v9fs_req_recv(req, P9_RLERROR); + v9fs_uint32_read(req, err); + v9fs_req_free(req); +} + +/* size[4] Tversion tag[2] msize[4] version[s] */ +P9Req *v9fs_tversion(QVirtio9P *v9p, uint32_t msize, const char *version, + uint16_t tag) +{ + P9Req *req; + uint32_t body_size = 4; + uint16_t string_size = v9fs_string_size(version); + + g_assert_cmpint(body_size, <=, UINT32_MAX - string_size); + body_size += string_size; + req = v9fs_req_init(v9p, body_size, P9_TVERSION, tag); + + v9fs_uint32_write(req, msize); + v9fs_string_write(req, version); + v9fs_req_send(req); + return req; +} + +/* size[4] Rversion tag[2] msize[4] version[s] */ +void v9fs_rversion(P9Req *req, uint16_t *len, char **version) +{ + uint32_t msize; + + v9fs_req_recv(req, P9_RVERSION); + v9fs_uint32_read(req, &msize); + + g_assert_cmpint(msize, ==, P9_MAX_SIZE); + + if (len || version) { + v9fs_string_read(req, len, version); + } + + v9fs_req_free(req); +} + +/* size[4] Tattach tag[2] fid[4] afid[4] uname[s] aname[s] n_uname[4] */ +P9Req *v9fs_tattach(QVirtio9P *v9p, uint32_t fid, uint32_t n_uname, + uint16_t tag) +{ + const char *uname = ""; /* ignored by QEMU */ + const char *aname = ""; /* ignored by QEMU */ + P9Req *req = v9fs_req_init(v9p, 4 + 4 + 2 + 2 + 4, P9_TATTACH, tag); + + v9fs_uint32_write(req, fid); + v9fs_uint32_write(req, P9_NOFID); + v9fs_string_write(req, uname); + v9fs_string_write(req, aname); + v9fs_uint32_write(req, n_uname); + v9fs_req_send(req); + return req; +} + +/* size[4] Rattach tag[2] qid[13] */ +void v9fs_rattach(P9Req *req, v9fs_qid *qid) +{ + v9fs_req_recv(req, P9_RATTACH); + if (qid) { + v9fs_memread(req, qid, 13); + } + v9fs_req_free(req); +} + +/* size[4] Twalk tag[2] fid[4] newfid[4] nwname[2] nwname*(wname[s]) */ +P9Req *v9fs_twalk(QVirtio9P *v9p, uint32_t fid, uint32_t newfid, + uint16_t nwname, char *const wnames[], uint16_t tag) +{ + P9Req *req; + int i; + uint32_t body_size = 4 + 4 + 2; + + for (i = 0; i < nwname; i++) { + uint16_t wname_size = v9fs_string_size(wnames[i]); + + g_assert_cmpint(body_size, <=, UINT32_MAX - wname_size); + body_size += wname_size; + } + req = v9fs_req_init(v9p, body_size, P9_TWALK, tag); + v9fs_uint32_write(req, fid); + v9fs_uint32_write(req, newfid); + v9fs_uint16_write(req, nwname); + for (i = 0; i < nwname; i++) { + v9fs_string_write(req, wnames[i]); + } + v9fs_req_send(req); + return req; +} + +/* size[4] Rwalk tag[2] nwqid[2] nwqid*(wqid[13]) */ +void v9fs_rwalk(P9Req *req, uint16_t *nwqid, v9fs_qid **wqid) +{ + uint16_t local_nwqid; + + v9fs_req_recv(req, P9_RWALK); + v9fs_uint16_read(req, &local_nwqid); + if (nwqid) { + *nwqid = local_nwqid; + } + if (wqid) { + *wqid = g_malloc(local_nwqid * 13); + v9fs_memread(req, *wqid, local_nwqid * 13); + } + v9fs_req_free(req); +} + +/* size[4] Tgetattr tag[2] fid[4] request_mask[8] */ +P9Req *v9fs_tgetattr(QVirtio9P *v9p, uint32_t fid, uint64_t request_mask, + uint16_t tag) +{ + P9Req *req; + + req = v9fs_req_init(v9p, 4 + 8, P9_TGETATTR, tag); + v9fs_uint32_write(req, fid); + v9fs_uint64_write(req, request_mask); + v9fs_req_send(req); + return req; +} + +/* + * size[4] Rgetattr tag[2] valid[8] qid[13] mode[4] uid[4] gid[4] nlink[8] + * rdev[8] size[8] blksize[8] blocks[8] + * atime_sec[8] atime_nsec[8] mtime_sec[8] mtime_nsec[8] + * ctime_sec[8] ctime_nsec[8] btime_sec[8] btime_nsec[8] + * gen[8] data_version[8] + */ +void v9fs_rgetattr(P9Req *req, v9fs_attr *attr) +{ + v9fs_req_recv(req, P9_RGETATTR); + + v9fs_uint64_read(req, &attr->valid); + v9fs_memread(req, &attr->qid, 13); + v9fs_uint32_read(req, &attr->mode); + v9fs_uint32_read(req, &attr->uid); + v9fs_uint32_read(req, &attr->gid); + v9fs_uint64_read(req, &attr->nlink); + v9fs_uint64_read(req, &attr->rdev); + v9fs_uint64_read(req, &attr->size); + v9fs_uint64_read(req, &attr->blksize); + v9fs_uint64_read(req, &attr->blocks); + v9fs_uint64_read(req, &attr->atime_sec); + v9fs_uint64_read(req, &attr->atime_nsec); + v9fs_uint64_read(req, &attr->mtime_sec); + v9fs_uint64_read(req, &attr->mtime_nsec); + v9fs_uint64_read(req, &attr->ctime_sec); + v9fs_uint64_read(req, &attr->ctime_nsec); + v9fs_uint64_read(req, &attr->btime_sec); + v9fs_uint64_read(req, &attr->btime_nsec); + v9fs_uint64_read(req, &attr->gen); + v9fs_uint64_read(req, &attr->data_version); + + v9fs_req_free(req); +} + +/* size[4] Treaddir tag[2] fid[4] offset[8] count[4] */ +P9Req *v9fs_treaddir(QVirtio9P *v9p, uint32_t fid, uint64_t offset, + uint32_t count, uint16_t tag) +{ + P9Req *req; + + req = v9fs_req_init(v9p, 4 + 8 + 4, P9_TREADDIR, tag); + v9fs_uint32_write(req, fid); + v9fs_uint64_write(req, offset); + v9fs_uint32_write(req, count); + v9fs_req_send(req); + return req; +} + +/* size[4] Rreaddir tag[2] count[4] data[count] */ +void v9fs_rreaddir(P9Req *req, uint32_t *count, uint32_t *nentries, + struct V9fsDirent **entries) +{ + uint32_t local_count; + struct V9fsDirent *e = NULL; + uint16_t slen; + uint32_t n = 0; + + v9fs_req_recv(req, P9_RREADDIR); + v9fs_uint32_read(req, &local_count); + + if (count) { + *count = local_count; + } + + for (int32_t togo = (int32_t)local_count; + togo >= 13 + 8 + 1 + 2; + togo -= 13 + 8 + 1 + 2 + slen, ++n) + { + if (!e) { + e = g_new(struct V9fsDirent, 1); + if (entries) { + *entries = e; + } + } else { + e = e->next = g_new(struct V9fsDirent, 1); + } + e->next = NULL; + /* qid[13] offset[8] type[1] name[s] */ + v9fs_memread(req, &e->qid, 13); + v9fs_uint64_read(req, &e->offset); + v9fs_uint8_read(req, &e->type); + v9fs_string_read(req, &slen, &e->name); + } + + if (nentries) { + *nentries = n; + } + + v9fs_req_free(req); +} + +void v9fs_free_dirents(struct V9fsDirent *e) +{ + struct V9fsDirent *next = NULL; + + for (; e; e = next) { + next = e->next; + g_free(e->name); + g_free(e); + } +} + +/* size[4] Tlopen tag[2] fid[4] flags[4] */ +P9Req *v9fs_tlopen(QVirtio9P *v9p, uint32_t fid, uint32_t flags, + uint16_t tag) +{ + P9Req *req; + + req = v9fs_req_init(v9p, 4 + 4, P9_TLOPEN, tag); + v9fs_uint32_write(req, fid); + v9fs_uint32_write(req, flags); + v9fs_req_send(req); + return req; +} + +/* size[4] Rlopen tag[2] qid[13] iounit[4] */ +void v9fs_rlopen(P9Req *req, v9fs_qid *qid, uint32_t *iounit) +{ + v9fs_req_recv(req, P9_RLOPEN); + if (qid) { + v9fs_memread(req, qid, 13); + } else { + v9fs_memskip(req, 13); + } + if (iounit) { + v9fs_uint32_read(req, iounit); + } + v9fs_req_free(req); +} + +/* size[4] Twrite tag[2] fid[4] offset[8] count[4] data[count] */ +P9Req *v9fs_twrite(QVirtio9P *v9p, uint32_t fid, uint64_t offset, + uint32_t count, const void *data, uint16_t tag) +{ + P9Req *req; + uint32_t body_size = 4 + 8 + 4; + + g_assert_cmpint(body_size, <=, UINT32_MAX - count); + body_size += count; + req = v9fs_req_init(v9p, body_size, P9_TWRITE, tag); + v9fs_uint32_write(req, fid); + v9fs_uint64_write(req, offset); + v9fs_uint32_write(req, count); + v9fs_memwrite(req, data, count); + v9fs_req_send(req); + return req; +} + +/* size[4] Rwrite tag[2] count[4] */ +void v9fs_rwrite(P9Req *req, uint32_t *count) +{ + v9fs_req_recv(req, P9_RWRITE); + if (count) { + v9fs_uint32_read(req, count); + } + v9fs_req_free(req); +} + +/* size[4] Tflush tag[2] oldtag[2] */ +P9Req *v9fs_tflush(QVirtio9P *v9p, uint16_t oldtag, uint16_t tag) +{ + P9Req *req; + + req = v9fs_req_init(v9p, 2, P9_TFLUSH, tag); + v9fs_uint32_write(req, oldtag); + v9fs_req_send(req); + return req; +} + +/* size[4] Rflush tag[2] */ +void v9fs_rflush(P9Req *req) +{ + v9fs_req_recv(req, P9_RFLUSH); + v9fs_req_free(req); +} + +/* size[4] Tmkdir tag[2] dfid[4] name[s] mode[4] gid[4] */ +P9Req *v9fs_tmkdir(QVirtio9P *v9p, uint32_t dfid, const char *name, + uint32_t mode, uint32_t gid, uint16_t tag) +{ + P9Req *req; + + uint32_t body_size = 4 + 4 + 4; + uint16_t string_size = v9fs_string_size(name); + + g_assert_cmpint(body_size, <=, UINT32_MAX - string_size); + body_size += string_size; + + req = v9fs_req_init(v9p, body_size, P9_TMKDIR, tag); + v9fs_uint32_write(req, dfid); + v9fs_string_write(req, name); + v9fs_uint32_write(req, mode); + v9fs_uint32_write(req, gid); + v9fs_req_send(req); + return req; +} + +/* size[4] Rmkdir tag[2] qid[13] */ +void v9fs_rmkdir(P9Req *req, v9fs_qid *qid) +{ + v9fs_req_recv(req, P9_RMKDIR); + if (qid) { + v9fs_memread(req, qid, 13); + } else { + v9fs_memskip(req, 13); + } + v9fs_req_free(req); +} + +/* size[4] Tlcreate tag[2] fid[4] name[s] flags[4] mode[4] gid[4] */ +P9Req *v9fs_tlcreate(QVirtio9P *v9p, uint32_t fid, const char *name, + uint32_t flags, uint32_t mode, uint32_t gid, + uint16_t tag) +{ + P9Req *req; + + uint32_t body_size = 4 + 4 + 4 + 4; + uint16_t string_size = v9fs_string_size(name); + + g_assert_cmpint(body_size, <=, UINT32_MAX - string_size); + body_size += string_size; + + req = v9fs_req_init(v9p, body_size, P9_TLCREATE, tag); + v9fs_uint32_write(req, fid); + v9fs_string_write(req, name); + v9fs_uint32_write(req, flags); + v9fs_uint32_write(req, mode); + v9fs_uint32_write(req, gid); + v9fs_req_send(req); + return req; +} + +/* size[4] Rlcreate tag[2] qid[13] iounit[4] */ +void v9fs_rlcreate(P9Req *req, v9fs_qid *qid, uint32_t *iounit) +{ + v9fs_req_recv(req, P9_RLCREATE); + if (qid) { + v9fs_memread(req, qid, 13); + } else { + v9fs_memskip(req, 13); + } + if (iounit) { + v9fs_uint32_read(req, iounit); + } + v9fs_req_free(req); +} + +/* size[4] Tsymlink tag[2] fid[4] name[s] symtgt[s] gid[4] */ +P9Req *v9fs_tsymlink(QVirtio9P *v9p, uint32_t fid, const char *name, + const char *symtgt, uint32_t gid, uint16_t tag) +{ + P9Req *req; + + uint32_t body_size = 4 + 4; + uint16_t string_size = v9fs_string_size(name) + v9fs_string_size(symtgt); + + g_assert_cmpint(body_size, <=, UINT32_MAX - string_size); + body_size += string_size; + + req = v9fs_req_init(v9p, body_size, P9_TSYMLINK, tag); + v9fs_uint32_write(req, fid); + v9fs_string_write(req, name); + v9fs_string_write(req, symtgt); + v9fs_uint32_write(req, gid); + v9fs_req_send(req); + return req; +} + +/* size[4] Rsymlink tag[2] qid[13] */ +void v9fs_rsymlink(P9Req *req, v9fs_qid *qid) +{ + v9fs_req_recv(req, P9_RSYMLINK); + if (qid) { + v9fs_memread(req, qid, 13); + } else { + v9fs_memskip(req, 13); + } + v9fs_req_free(req); +} + +/* size[4] Tlink tag[2] dfid[4] fid[4] name[s] */ +P9Req *v9fs_tlink(QVirtio9P *v9p, uint32_t dfid, uint32_t fid, + const char *name, uint16_t tag) +{ + P9Req *req; + + uint32_t body_size = 4 + 4; + uint16_t string_size = v9fs_string_size(name); + + g_assert_cmpint(body_size, <=, UINT32_MAX - string_size); + body_size += string_size; + + req = v9fs_req_init(v9p, body_size, P9_TLINK, tag); + v9fs_uint32_write(req, dfid); + v9fs_uint32_write(req, fid); + v9fs_string_write(req, name); + v9fs_req_send(req); + return req; +} + +/* size[4] Rlink tag[2] */ +void v9fs_rlink(P9Req *req) +{ + v9fs_req_recv(req, P9_RLINK); + v9fs_req_free(req); +} + +/* size[4] Tunlinkat tag[2] dirfd[4] name[s] flags[4] */ +P9Req *v9fs_tunlinkat(QVirtio9P *v9p, uint32_t dirfd, const char *name, + uint32_t flags, uint16_t tag) +{ + P9Req *req; + + uint32_t body_size = 4 + 4; + uint16_t string_size = v9fs_string_size(name); + + g_assert_cmpint(body_size, <=, UINT32_MAX - string_size); + body_size += string_size; + + req = v9fs_req_init(v9p, body_size, P9_TUNLINKAT, tag); + v9fs_uint32_write(req, dirfd); + v9fs_string_write(req, name); + v9fs_uint32_write(req, flags); + v9fs_req_send(req); + return req; +} + +/* size[4] Runlinkat tag[2] */ +void v9fs_runlinkat(P9Req *req) +{ + v9fs_req_recv(req, P9_RUNLINKAT); + v9fs_req_free(req); +} diff --git a/tests/qtest/libqos/virtio-9p-client.h b/tests/qtest/libqos/virtio-9p-client.h new file mode 100644 index 0000000000..c502d12a66 --- /dev/null +++ b/tests/qtest/libqos/virtio-9p-client.h @@ -0,0 +1,138 @@ +/* + * 9P network client for VirtIO 9P test cases (based on QTest) + * + * Copyright (c) 2014 SUSE LINUX Products GmbH + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +/* + * Not so fast! You might want to read the 9p developer docs first: + * https://wiki.qemu.org/Documentation/9p + */ + +#ifndef TESTS_LIBQOS_VIRTIO_9P_CLIENT_H +#define TESTS_LIBQOS_VIRTIO_9P_CLIENT_H + +#include "hw/9pfs/9p.h" +#include "hw/9pfs/9p-synth.h" +#include "virtio-9p.h" +#include "qgraph.h" +#include "tests/qtest/libqtest-single.h" + +#define P9_MAX_SIZE 4096 /* Max size of a T-message or R-message */ + +typedef struct { + QTestState *qts; + QVirtio9P *v9p; + uint16_t tag; + uint64_t t_msg; + uint32_t t_size; + uint64_t r_msg; + /* No r_size, it is hardcoded to P9_MAX_SIZE */ + size_t t_off; + size_t r_off; + uint32_t free_head; +} P9Req; + +/* type[1] version[4] path[8] */ +typedef char v9fs_qid[13]; + +typedef struct v9fs_attr { + uint64_t valid; + v9fs_qid qid; + uint32_t mode; + uint32_t uid; + uint32_t gid; + uint64_t nlink; + uint64_t rdev; + uint64_t size; + uint64_t blksize; + uint64_t blocks; + uint64_t atime_sec; + uint64_t atime_nsec; + uint64_t mtime_sec; + uint64_t mtime_nsec; + uint64_t ctime_sec; + uint64_t ctime_nsec; + uint64_t btime_sec; + uint64_t btime_nsec; + uint64_t gen; + uint64_t data_version; +} v9fs_attr; + +#define P9_GETATTR_BASIC 0x000007ffULL /* Mask for fields up to BLOCKS */ + +struct V9fsDirent { + v9fs_qid qid; + uint64_t offset; + uint8_t type; + char *name; + struct V9fsDirent *next; +}; + +void v9fs_set_allocator(QGuestAllocator *t_alloc); +void v9fs_memwrite(P9Req *req, const void *addr, size_t len); +void v9fs_memskip(P9Req *req, size_t len); +void v9fs_memread(P9Req *req, void *addr, size_t len); +void v9fs_uint8_read(P9Req *req, uint8_t *val); +void v9fs_uint16_write(P9Req *req, uint16_t val); +void v9fs_uint16_read(P9Req *req, uint16_t *val); +void v9fs_uint32_write(P9Req *req, uint32_t val); +void v9fs_uint64_write(P9Req *req, uint64_t val); +void v9fs_uint32_read(P9Req *req, uint32_t *val); +void v9fs_uint64_read(P9Req *req, uint64_t *val); +uint16_t v9fs_string_size(const char *string); +void v9fs_string_write(P9Req *req, const char *string); +void v9fs_string_read(P9Req *req, uint16_t *len, char **string); +P9Req *v9fs_req_init(QVirtio9P *v9p, uint32_t size, uint8_t id, + uint16_t tag); +void v9fs_req_send(P9Req *req); +void v9fs_req_wait_for_reply(P9Req *req, uint32_t *len); +void v9fs_req_recv(P9Req *req, uint8_t id); +void v9fs_req_free(P9Req *req); +void v9fs_rlerror(P9Req *req, uint32_t *err); +P9Req *v9fs_tversion(QVirtio9P *v9p, uint32_t msize, const char *version, + uint16_t tag); +void v9fs_rversion(P9Req *req, uint16_t *len, char **version); +P9Req *v9fs_tattach(QVirtio9P *v9p, uint32_t fid, uint32_t n_uname, + uint16_t tag); +void v9fs_rattach(P9Req *req, v9fs_qid *qid); +P9Req *v9fs_twalk(QVirtio9P *v9p, uint32_t fid, uint32_t newfid, + uint16_t nwname, char *const wnames[], uint16_t tag); +void v9fs_rwalk(P9Req *req, uint16_t *nwqid, v9fs_qid **wqid); +P9Req *v9fs_tgetattr(QVirtio9P *v9p, uint32_t fid, uint64_t request_mask, + uint16_t tag); +void v9fs_rgetattr(P9Req *req, v9fs_attr *attr); +P9Req *v9fs_treaddir(QVirtio9P *v9p, uint32_t fid, uint64_t offset, + uint32_t count, uint16_t tag); +void v9fs_rreaddir(P9Req *req, uint32_t *count, uint32_t *nentries, + struct V9fsDirent **entries); +void v9fs_free_dirents(struct V9fsDirent *e); +P9Req *v9fs_tlopen(QVirtio9P *v9p, uint32_t fid, uint32_t flags, + uint16_t tag); +void v9fs_rlopen(P9Req *req, v9fs_qid *qid, uint32_t *iounit); +P9Req *v9fs_twrite(QVirtio9P *v9p, uint32_t fid, uint64_t offset, + uint32_t count, const void *data, uint16_t tag); +void v9fs_rwrite(P9Req *req, uint32_t *count); +P9Req *v9fs_tflush(QVirtio9P *v9p, uint16_t oldtag, uint16_t tag); +void v9fs_rflush(P9Req *req); +P9Req *v9fs_tmkdir(QVirtio9P *v9p, uint32_t dfid, const char *name, + uint32_t mode, uint32_t gid, uint16_t tag); +void v9fs_rmkdir(P9Req *req, v9fs_qid *qid); +P9Req *v9fs_tlcreate(QVirtio9P *v9p, uint32_t fid, const char *name, + uint32_t flags, uint32_t mode, uint32_t gid, + uint16_t tag); +void v9fs_rlcreate(P9Req *req, v9fs_qid *qid, uint32_t *iounit); +P9Req *v9fs_tsymlink(QVirtio9P *v9p, uint32_t fid, const char *name, + const char *symtgt, uint32_t gid, uint16_t tag); +void v9fs_rsymlink(P9Req *req, v9fs_qid *qid); +P9Req *v9fs_tlink(QVirtio9P *v9p, uint32_t dfid, uint32_t fid, + const char *name, uint16_t tag); +void v9fs_rlink(P9Req *req); +P9Req *v9fs_tunlinkat(QVirtio9P *v9p, uint32_t dirfd, const char *name, + uint32_t flags, uint16_t tag); +void v9fs_runlinkat(P9Req *req); + +#endif diff --git a/tests/qtest/virtio-9p-test.c b/tests/qtest/virtio-9p-test.c index 25305a4cf7..498c32e21b 100644 --- a/tests/qtest/virtio-9p-test.c +++ b/tests/qtest/virtio-9p-test.c @@ -13,15 +13,8 @@ */ #include "qemu/osdep.h" -#include "libqtest-single.h" #include "qemu/module.h" -#include "hw/9pfs/9p.h" -#include "hw/9pfs/9p-synth.h" -#include "libqos/virtio-9p.h" -#include "libqos/qgraph.h" - -#define QVIRTIO_9P_TIMEOUT_US (10 * 1000 * 1000) -static QGuestAllocator *alloc; +#include "libqos/virtio-9p-client.h" /* * Used to auto generate new fids. Start with arbitrary high value to avoid @@ -82,7 +75,7 @@ static void split_free(char ***out) static void pci_config(void *obj, void *data, QGuestAllocator *t_alloc) { QVirtio9P *v9p = obj; - alloc = t_alloc; + v9fs_set_allocator(t_alloc); size_t tag_len = qvirtio_config_readw(v9p->vdev, 0); g_autofree char *tag = NULL; int i; @@ -96,565 +89,12 @@ static void pci_config(void *obj, void *data, QGuestAllocator *t_alloc) g_assert_cmpmem(tag, tag_len, MOUNT_TAG, tag_len); } -#define P9_MAX_SIZE 4096 /* Max size of a T-message or R-message */ - -typedef struct { - QTestState *qts; - QVirtio9P *v9p; - uint16_t tag; - uint64_t t_msg; - uint32_t t_size; - uint64_t r_msg; - /* No r_size, it is hardcoded to P9_MAX_SIZE */ - size_t t_off; - size_t r_off; - uint32_t free_head; -} P9Req; - -static void v9fs_memwrite(P9Req *req, const void *addr, size_t len) -{ - qtest_memwrite(req->qts, req->t_msg + req->t_off, addr, len); - req->t_off += len; -} - -static void v9fs_memskip(P9Req *req, size_t len) -{ - req->r_off += len; -} - -static void v9fs_memread(P9Req *req, void *addr, size_t len) -{ - qtest_memread(req->qts, req->r_msg + req->r_off, addr, len); - req->r_off += len; -} - -static void v9fs_uint8_read(P9Req *req, uint8_t *val) -{ - v9fs_memread(req, val, 1); -} - -static void v9fs_uint16_write(P9Req *req, uint16_t val) -{ - uint16_t le_val = cpu_to_le16(val); - - v9fs_memwrite(req, &le_val, 2); -} - -static void v9fs_uint16_read(P9Req *req, uint16_t *val) -{ - v9fs_memread(req, val, 2); - le16_to_cpus(val); -} - -static void v9fs_uint32_write(P9Req *req, uint32_t val) -{ - uint32_t le_val = cpu_to_le32(val); - - v9fs_memwrite(req, &le_val, 4); -} - -static void v9fs_uint64_write(P9Req *req, uint64_t val) -{ - uint64_t le_val = cpu_to_le64(val); - - v9fs_memwrite(req, &le_val, 8); -} - -static void v9fs_uint32_read(P9Req *req, uint32_t *val) -{ - v9fs_memread(req, val, 4); - le32_to_cpus(val); -} - -static void v9fs_uint64_read(P9Req *req, uint64_t *val) -{ - v9fs_memread(req, val, 8); - le64_to_cpus(val); -} - -/* len[2] string[len] */ -static uint16_t v9fs_string_size(const char *string) -{ - size_t len = strlen(string); - - g_assert_cmpint(len, <=, UINT16_MAX - 2); - - return 2 + len; -} - -static void v9fs_string_write(P9Req *req, const char *string) -{ - int len = strlen(string); - - g_assert_cmpint(len, <=, UINT16_MAX); - - v9fs_uint16_write(req, (uint16_t) len); - v9fs_memwrite(req, string, len); -} - -static void v9fs_string_read(P9Req *req, uint16_t *len, char **string) -{ - uint16_t local_len; - - v9fs_uint16_read(req, &local_len); - if (len) { - *len = local_len; - } - if (string) { - *string = g_malloc(local_len + 1); - v9fs_memread(req, *string, local_len); - (*string)[local_len] = 0; - } else { - v9fs_memskip(req, local_len); - } -} - - typedef struct { - uint32_t size; - uint8_t id; - uint16_t tag; -} QEMU_PACKED P9Hdr; - -static P9Req *v9fs_req_init(QVirtio9P *v9p, uint32_t size, uint8_t id, - uint16_t tag) -{ - P9Req *req = g_new0(P9Req, 1); - uint32_t total_size = 7; /* 9P header has well-known size of 7 bytes */ - P9Hdr hdr = { - .id = id, - .tag = cpu_to_le16(tag) - }; - - g_assert_cmpint(total_size, <=, UINT32_MAX - size); - total_size += size; - hdr.size = cpu_to_le32(total_size); - - g_assert_cmpint(total_size, <=, P9_MAX_SIZE); - - req->qts = global_qtest; - req->v9p = v9p; - req->t_size = total_size; - req->t_msg = guest_alloc(alloc, req->t_size); - v9fs_memwrite(req, &hdr, 7); - req->tag = tag; - return req; -} - -static void v9fs_req_send(P9Req *req) -{ - QVirtio9P *v9p = req->v9p; - - req->r_msg = guest_alloc(alloc, P9_MAX_SIZE); - req->free_head = qvirtqueue_add(req->qts, v9p->vq, req->t_msg, req->t_size, - false, true); - qvirtqueue_add(req->qts, v9p->vq, req->r_msg, P9_MAX_SIZE, true, false); - qvirtqueue_kick(req->qts, v9p->vdev, v9p->vq, req->free_head); - req->t_off = 0; -} - -static const char *rmessage_name(uint8_t id) -{ - return - id == P9_RLERROR ? "RLERROR" : - id == P9_RVERSION ? "RVERSION" : - id == P9_RATTACH ? "RATTACH" : - id == P9_RWALK ? "RWALK" : - id == P9_RLOPEN ? "RLOPEN" : - id == P9_RWRITE ? "RWRITE" : - id == P9_RMKDIR ? "RMKDIR" : - id == P9_RLCREATE ? "RLCREATE" : - id == P9_RSYMLINK ? "RSYMLINK" : - id == P9_RLINK ? "RLINK" : - id == P9_RUNLINKAT ? "RUNLINKAT" : - id == P9_RFLUSH ? "RFLUSH" : - id == P9_RREADDIR ? "READDIR" : - ""; -} - -static void v9fs_req_wait_for_reply(P9Req *req, uint32_t *len) -{ - QVirtio9P *v9p = req->v9p; - - qvirtio_wait_used_elem(req->qts, v9p->vdev, v9p->vq, req->free_head, len, - QVIRTIO_9P_TIMEOUT_US); -} - -static void v9fs_req_recv(P9Req *req, uint8_t id) -{ - P9Hdr hdr; - - v9fs_memread(req, &hdr, 7); - hdr.size = ldl_le_p(&hdr.size); - hdr.tag = lduw_le_p(&hdr.tag); - - g_assert_cmpint(hdr.size, >=, 7); - g_assert_cmpint(hdr.size, <=, P9_MAX_SIZE); - g_assert_cmpint(hdr.tag, ==, req->tag); - - if (hdr.id != id) { - g_printerr("Received response %d (%s) instead of %d (%s)\n", - hdr.id, rmessage_name(hdr.id), id, rmessage_name(id)); - - if (hdr.id == P9_RLERROR) { - uint32_t err; - v9fs_uint32_read(req, &err); - g_printerr("Rlerror has errno %d (%s)\n", err, strerror(err)); - } - } - g_assert_cmpint(hdr.id, ==, id); -} - -static void v9fs_req_free(P9Req *req) -{ - guest_free(alloc, req->t_msg); - guest_free(alloc, req->r_msg); - g_free(req); -} - -/* size[4] Rlerror tag[2] ecode[4] */ -static void v9fs_rlerror(P9Req *req, uint32_t *err) -{ - v9fs_req_recv(req, P9_RLERROR); - v9fs_uint32_read(req, err); - v9fs_req_free(req); -} - -/* size[4] Tversion tag[2] msize[4] version[s] */ -static P9Req *v9fs_tversion(QVirtio9P *v9p, uint32_t msize, const char *version, - uint16_t tag) -{ - P9Req *req; - uint32_t body_size = 4; - uint16_t string_size = v9fs_string_size(version); - - g_assert_cmpint(body_size, <=, UINT32_MAX - string_size); - body_size += string_size; - req = v9fs_req_init(v9p, body_size, P9_TVERSION, tag); - - v9fs_uint32_write(req, msize); - v9fs_string_write(req, version); - v9fs_req_send(req); - return req; -} - -/* size[4] Rversion tag[2] msize[4] version[s] */ -static void v9fs_rversion(P9Req *req, uint16_t *len, char **version) -{ - uint32_t msize; - - v9fs_req_recv(req, P9_RVERSION); - v9fs_uint32_read(req, &msize); - - g_assert_cmpint(msize, ==, P9_MAX_SIZE); - - if (len || version) { - v9fs_string_read(req, len, version); - } - - v9fs_req_free(req); -} - -/* size[4] Tattach tag[2] fid[4] afid[4] uname[s] aname[s] n_uname[4] */ -static P9Req *v9fs_tattach(QVirtio9P *v9p, uint32_t fid, uint32_t n_uname, - uint16_t tag) -{ - const char *uname = ""; /* ignored by QEMU */ - const char *aname = ""; /* ignored by QEMU */ - P9Req *req = v9fs_req_init(v9p, 4 + 4 + 2 + 2 + 4, P9_TATTACH, tag); - - v9fs_uint32_write(req, fid); - v9fs_uint32_write(req, P9_NOFID); - v9fs_string_write(req, uname); - v9fs_string_write(req, aname); - v9fs_uint32_write(req, n_uname); - v9fs_req_send(req); - return req; -} - -/* type[1] version[4] path[8] */ -typedef char v9fs_qid[13]; - static inline bool is_same_qid(v9fs_qid a, v9fs_qid b) { /* don't compare QID version for checking for file ID equalness */ return a[0] == b[0] && memcmp(&a[5], &b[5], 8) == 0; } -/* size[4] Rattach tag[2] qid[13] */ -static void v9fs_rattach(P9Req *req, v9fs_qid *qid) -{ - v9fs_req_recv(req, P9_RATTACH); - if (qid) { - v9fs_memread(req, qid, 13); - } - v9fs_req_free(req); -} - -/* size[4] Twalk tag[2] fid[4] newfid[4] nwname[2] nwname*(wname[s]) */ -static P9Req *v9fs_twalk(QVirtio9P *v9p, uint32_t fid, uint32_t newfid, - uint16_t nwname, char *const wnames[], uint16_t tag) -{ - P9Req *req; - int i; - uint32_t body_size = 4 + 4 + 2; - - for (i = 0; i < nwname; i++) { - uint16_t wname_size = v9fs_string_size(wnames[i]); - - g_assert_cmpint(body_size, <=, UINT32_MAX - wname_size); - body_size += wname_size; - } - req = v9fs_req_init(v9p, body_size, P9_TWALK, tag); - v9fs_uint32_write(req, fid); - v9fs_uint32_write(req, newfid); - v9fs_uint16_write(req, nwname); - for (i = 0; i < nwname; i++) { - v9fs_string_write(req, wnames[i]); - } - v9fs_req_send(req); - return req; -} - -/* size[4] Rwalk tag[2] nwqid[2] nwqid*(wqid[13]) */ -static void v9fs_rwalk(P9Req *req, uint16_t *nwqid, v9fs_qid **wqid) -{ - uint16_t local_nwqid; - - v9fs_req_recv(req, P9_RWALK); - v9fs_uint16_read(req, &local_nwqid); - if (nwqid) { - *nwqid = local_nwqid; - } - if (wqid) { - *wqid = g_malloc(local_nwqid * 13); - v9fs_memread(req, *wqid, local_nwqid * 13); - } - v9fs_req_free(req); -} - -/* size[4] Tgetattr tag[2] fid[4] request_mask[8] */ -static P9Req *v9fs_tgetattr(QVirtio9P *v9p, uint32_t fid, uint64_t request_mask, - uint16_t tag) -{ - P9Req *req; - - req = v9fs_req_init(v9p, 4 + 8, P9_TGETATTR, tag); - v9fs_uint32_write(req, fid); - v9fs_uint64_write(req, request_mask); - v9fs_req_send(req); - return req; -} - -typedef struct v9fs_attr { - uint64_t valid; - v9fs_qid qid; - uint32_t mode; - uint32_t uid; - uint32_t gid; - uint64_t nlink; - uint64_t rdev; - uint64_t size; - uint64_t blksize; - uint64_t blocks; - uint64_t atime_sec; - uint64_t atime_nsec; - uint64_t mtime_sec; - uint64_t mtime_nsec; - uint64_t ctime_sec; - uint64_t ctime_nsec; - uint64_t btime_sec; - uint64_t btime_nsec; - uint64_t gen; - uint64_t data_version; -} v9fs_attr; - -#define P9_GETATTR_BASIC 0x000007ffULL /* Mask for fields up to BLOCKS */ - -/* - * size[4] Rgetattr tag[2] valid[8] qid[13] mode[4] uid[4] gid[4] nlink[8] - * rdev[8] size[8] blksize[8] blocks[8] - * atime_sec[8] atime_nsec[8] mtime_sec[8] mtime_nsec[8] - * ctime_sec[8] ctime_nsec[8] btime_sec[8] btime_nsec[8] - * gen[8] data_version[8] - */ -static void v9fs_rgetattr(P9Req *req, v9fs_attr *attr) -{ - v9fs_req_recv(req, P9_RGETATTR); - - v9fs_uint64_read(req, &attr->valid); - v9fs_memread(req, &attr->qid, 13); - v9fs_uint32_read(req, &attr->mode); - v9fs_uint32_read(req, &attr->uid); - v9fs_uint32_read(req, &attr->gid); - v9fs_uint64_read(req, &attr->nlink); - v9fs_uint64_read(req, &attr->rdev); - v9fs_uint64_read(req, &attr->size); - v9fs_uint64_read(req, &attr->blksize); - v9fs_uint64_read(req, &attr->blocks); - v9fs_uint64_read(req, &attr->atime_sec); - v9fs_uint64_read(req, &attr->atime_nsec); - v9fs_uint64_read(req, &attr->mtime_sec); - v9fs_uint64_read(req, &attr->mtime_nsec); - v9fs_uint64_read(req, &attr->ctime_sec); - v9fs_uint64_read(req, &attr->ctime_nsec); - v9fs_uint64_read(req, &attr->btime_sec); - v9fs_uint64_read(req, &attr->btime_nsec); - v9fs_uint64_read(req, &attr->gen); - v9fs_uint64_read(req, &attr->data_version); - - v9fs_req_free(req); -} - -/* size[4] Treaddir tag[2] fid[4] offset[8] count[4] */ -static P9Req *v9fs_treaddir(QVirtio9P *v9p, uint32_t fid, uint64_t offset, - uint32_t count, uint16_t tag) -{ - P9Req *req; - - req = v9fs_req_init(v9p, 4 + 8 + 4, P9_TREADDIR, tag); - v9fs_uint32_write(req, fid); - v9fs_uint64_write(req, offset); - v9fs_uint32_write(req, count); - v9fs_req_send(req); - return req; -} - -struct V9fsDirent { - v9fs_qid qid; - uint64_t offset; - uint8_t type; - char *name; - struct V9fsDirent *next; -}; - -/* size[4] Rreaddir tag[2] count[4] data[count] */ -static void v9fs_rreaddir(P9Req *req, uint32_t *count, uint32_t *nentries, - struct V9fsDirent **entries) -{ - uint32_t local_count; - struct V9fsDirent *e = NULL; - uint16_t slen; - uint32_t n = 0; - - v9fs_req_recv(req, P9_RREADDIR); - v9fs_uint32_read(req, &local_count); - - if (count) { - *count = local_count; - } - - for (int32_t togo = (int32_t)local_count; - togo >= 13 + 8 + 1 + 2; - togo -= 13 + 8 + 1 + 2 + slen, ++n) - { - if (!e) { - e = g_new(struct V9fsDirent, 1); - if (entries) { - *entries = e; - } - } else { - e = e->next = g_new(struct V9fsDirent, 1); - } - e->next = NULL; - /* qid[13] offset[8] type[1] name[s] */ - v9fs_memread(req, &e->qid, 13); - v9fs_uint64_read(req, &e->offset); - v9fs_uint8_read(req, &e->type); - v9fs_string_read(req, &slen, &e->name); - } - - if (nentries) { - *nentries = n; - } - - v9fs_req_free(req); -} - -static void v9fs_free_dirents(struct V9fsDirent *e) -{ - struct V9fsDirent *next = NULL; - - for (; e; e = next) { - next = e->next; - g_free(e->name); - g_free(e); - } -} - -/* size[4] Tlopen tag[2] fid[4] flags[4] */ -static P9Req *v9fs_tlopen(QVirtio9P *v9p, uint32_t fid, uint32_t flags, - uint16_t tag) -{ - P9Req *req; - - req = v9fs_req_init(v9p, 4 + 4, P9_TLOPEN, tag); - v9fs_uint32_write(req, fid); - v9fs_uint32_write(req, flags); - v9fs_req_send(req); - return req; -} - -/* size[4] Rlopen tag[2] qid[13] iounit[4] */ -static void v9fs_rlopen(P9Req *req, v9fs_qid *qid, uint32_t *iounit) -{ - v9fs_req_recv(req, P9_RLOPEN); - if (qid) { - v9fs_memread(req, qid, 13); - } else { - v9fs_memskip(req, 13); - } - if (iounit) { - v9fs_uint32_read(req, iounit); - } - v9fs_req_free(req); -} - -/* size[4] Twrite tag[2] fid[4] offset[8] count[4] data[count] */ -static P9Req *v9fs_twrite(QVirtio9P *v9p, uint32_t fid, uint64_t offset, - uint32_t count, const void *data, uint16_t tag) -{ - P9Req *req; - uint32_t body_size = 4 + 8 + 4; - - g_assert_cmpint(body_size, <=, UINT32_MAX - count); - body_size += count; - req = v9fs_req_init(v9p, body_size, P9_TWRITE, tag); - v9fs_uint32_write(req, fid); - v9fs_uint64_write(req, offset); - v9fs_uint32_write(req, count); - v9fs_memwrite(req, data, count); - v9fs_req_send(req); - return req; -} - -/* size[4] Rwrite tag[2] count[4] */ -static void v9fs_rwrite(P9Req *req, uint32_t *count) -{ - v9fs_req_recv(req, P9_RWRITE); - if (count) { - v9fs_uint32_read(req, count); - } - v9fs_req_free(req); -} - -/* size[4] Tflush tag[2] oldtag[2] */ -static P9Req *v9fs_tflush(QVirtio9P *v9p, uint16_t oldtag, uint16_t tag) -{ - P9Req *req; - - req = v9fs_req_init(v9p, 2, P9_TFLUSH, tag); - v9fs_uint32_write(req, oldtag); - v9fs_req_send(req); - return req; -} - -/* size[4] Rflush tag[2] */ -static void v9fs_rflush(P9Req *req) -{ - v9fs_req_recv(req, P9_RFLUSH); - v9fs_req_free(req); -} - static void do_version(QVirtio9P *v9p) { const char *version = "9P2000.L"; @@ -717,7 +157,7 @@ static void do_walk_expect_error(QVirtio9P *v9p, const char *path, uint32_t err) static void fs_version(void *obj, void *data, QGuestAllocator *t_alloc) { - alloc = t_alloc; + v9fs_set_allocator(t_alloc); do_version(obj); } @@ -738,14 +178,14 @@ static void do_attach(QVirtio9P *v9p) static void fs_attach(void *obj, void *data, QGuestAllocator *t_alloc) { - alloc = t_alloc; + v9fs_set_allocator(t_alloc); do_attach(obj); } static void fs_walk(void *obj, void *data, QGuestAllocator *t_alloc) { QVirtio9P *v9p = obj; - alloc = t_alloc; + v9fs_set_allocator(t_alloc); char *wnames[P9_MAXWELEM]; uint16_t nwqid; g_autofree v9fs_qid *wqid = NULL; @@ -778,169 +218,11 @@ static bool fs_dirents_contain_name(struct V9fsDirent *e, const char* name) return false; } -/* size[4] Tmkdir tag[2] dfid[4] name[s] mode[4] gid[4] */ -static P9Req *v9fs_tmkdir(QVirtio9P *v9p, uint32_t dfid, const char *name, - uint32_t mode, uint32_t gid, uint16_t tag) -{ - P9Req *req; - - uint32_t body_size = 4 + 4 + 4; - uint16_t string_size = v9fs_string_size(name); - - g_assert_cmpint(body_size, <=, UINT32_MAX - string_size); - body_size += string_size; - - req = v9fs_req_init(v9p, body_size, P9_TMKDIR, tag); - v9fs_uint32_write(req, dfid); - v9fs_string_write(req, name); - v9fs_uint32_write(req, mode); - v9fs_uint32_write(req, gid); - v9fs_req_send(req); - return req; -} - -/* size[4] Rmkdir tag[2] qid[13] */ -static void v9fs_rmkdir(P9Req *req, v9fs_qid *qid) -{ - v9fs_req_recv(req, P9_RMKDIR); - if (qid) { - v9fs_memread(req, qid, 13); - } else { - v9fs_memskip(req, 13); - } - v9fs_req_free(req); -} - -/* size[4] Tlcreate tag[2] fid[4] name[s] flags[4] mode[4] gid[4] */ -static P9Req *v9fs_tlcreate(QVirtio9P *v9p, uint32_t fid, const char *name, - uint32_t flags, uint32_t mode, uint32_t gid, - uint16_t tag) -{ - P9Req *req; - - uint32_t body_size = 4 + 4 + 4 + 4; - uint16_t string_size = v9fs_string_size(name); - - g_assert_cmpint(body_size, <=, UINT32_MAX - string_size); - body_size += string_size; - - req = v9fs_req_init(v9p, body_size, P9_TLCREATE, tag); - v9fs_uint32_write(req, fid); - v9fs_string_write(req, name); - v9fs_uint32_write(req, flags); - v9fs_uint32_write(req, mode); - v9fs_uint32_write(req, gid); - v9fs_req_send(req); - return req; -} - -/* size[4] Rlcreate tag[2] qid[13] iounit[4] */ -static void v9fs_rlcreate(P9Req *req, v9fs_qid *qid, uint32_t *iounit) -{ - v9fs_req_recv(req, P9_RLCREATE); - if (qid) { - v9fs_memread(req, qid, 13); - } else { - v9fs_memskip(req, 13); - } - if (iounit) { - v9fs_uint32_read(req, iounit); - } - v9fs_req_free(req); -} - -/* size[4] Tsymlink tag[2] fid[4] name[s] symtgt[s] gid[4] */ -static P9Req *v9fs_tsymlink(QVirtio9P *v9p, uint32_t fid, const char *name, - const char *symtgt, uint32_t gid, uint16_t tag) -{ - P9Req *req; - - uint32_t body_size = 4 + 4; - uint16_t string_size = v9fs_string_size(name) + v9fs_string_size(symtgt); - - g_assert_cmpint(body_size, <=, UINT32_MAX - string_size); - body_size += string_size; - - req = v9fs_req_init(v9p, body_size, P9_TSYMLINK, tag); - v9fs_uint32_write(req, fid); - v9fs_string_write(req, name); - v9fs_string_write(req, symtgt); - v9fs_uint32_write(req, gid); - v9fs_req_send(req); - return req; -} - -/* size[4] Rsymlink tag[2] qid[13] */ -static void v9fs_rsymlink(P9Req *req, v9fs_qid *qid) -{ - v9fs_req_recv(req, P9_RSYMLINK); - if (qid) { - v9fs_memread(req, qid, 13); - } else { - v9fs_memskip(req, 13); - } - v9fs_req_free(req); -} - -/* size[4] Tlink tag[2] dfid[4] fid[4] name[s] */ -static P9Req *v9fs_tlink(QVirtio9P *v9p, uint32_t dfid, uint32_t fid, - const char *name, uint16_t tag) -{ - P9Req *req; - - uint32_t body_size = 4 + 4; - uint16_t string_size = v9fs_string_size(name); - - g_assert_cmpint(body_size, <=, UINT32_MAX - string_size); - body_size += string_size; - - req = v9fs_req_init(v9p, body_size, P9_TLINK, tag); - v9fs_uint32_write(req, dfid); - v9fs_uint32_write(req, fid); - v9fs_string_write(req, name); - v9fs_req_send(req); - return req; -} - -/* size[4] Rlink tag[2] */ -static void v9fs_rlink(P9Req *req) -{ - v9fs_req_recv(req, P9_RLINK); - v9fs_req_free(req); -} - -/* size[4] Tunlinkat tag[2] dirfd[4] name[s] flags[4] */ -static P9Req *v9fs_tunlinkat(QVirtio9P *v9p, uint32_t dirfd, const char *name, - uint32_t flags, uint16_t tag) -{ - P9Req *req; - - uint32_t body_size = 4 + 4; - uint16_t string_size = v9fs_string_size(name); - - g_assert_cmpint(body_size, <=, UINT32_MAX - string_size); - body_size += string_size; - - req = v9fs_req_init(v9p, body_size, P9_TUNLINKAT, tag); - v9fs_uint32_write(req, dirfd); - v9fs_string_write(req, name); - v9fs_uint32_write(req, flags); - v9fs_req_send(req); - return req; -} - -/* size[4] Runlinkat tag[2] */ -static void v9fs_runlinkat(P9Req *req) -{ - v9fs_req_recv(req, P9_RUNLINKAT); - v9fs_req_free(req); -} - /* basic readdir test where reply fits into a single response message */ static void fs_readdir(void *obj, void *data, QGuestAllocator *t_alloc) { QVirtio9P *v9p = obj; - alloc = t_alloc; + v9fs_set_allocator(t_alloc); char *const wnames[] = { g_strdup(QTEST_V9FS_SYNTH_READDIR_DIR) }; uint16_t nqid; v9fs_qid qid; @@ -1073,7 +355,7 @@ static void do_readdir_split(QVirtio9P *v9p, uint32_t count) static void fs_walk_no_slash(void *obj, void *data, QGuestAllocator *t_alloc) { QVirtio9P *v9p = obj; - alloc = t_alloc; + v9fs_set_allocator(t_alloc); char *const wnames[] = { g_strdup(" /") }; P9Req *req; uint32_t err; @@ -1091,7 +373,7 @@ static void fs_walk_no_slash(void *obj, void *data, QGuestAllocator *t_alloc) static void fs_walk_nonexistent(void *obj, void *data, QGuestAllocator *t_alloc) { QVirtio9P *v9p = obj; - alloc = t_alloc; + v9fs_set_allocator(t_alloc); do_attach(v9p); /* @@ -1105,7 +387,7 @@ static void fs_walk_2nd_nonexistent(void *obj, void *data, QGuestAllocator *t_alloc) { QVirtio9P *v9p = obj; - alloc = t_alloc; + v9fs_set_allocator(t_alloc); v9fs_qid root_qid; uint16_t nwqid; uint32_t fid, err; @@ -1137,7 +419,7 @@ static void fs_walk_2nd_nonexistent(void *obj, void *data, static void fs_walk_none(void *obj, void *data, QGuestAllocator *t_alloc) { QVirtio9P *v9p = obj; - alloc = t_alloc; + v9fs_set_allocator(t_alloc); v9fs_qid root_qid; g_autofree v9fs_qid *wqid = NULL; P9Req *req; @@ -1165,7 +447,7 @@ static void fs_walk_none(void *obj, void *data, QGuestAllocator *t_alloc) static void fs_walk_dotdot(void *obj, void *data, QGuestAllocator *t_alloc) { QVirtio9P *v9p = obj; - alloc = t_alloc; + v9fs_set_allocator(t_alloc); char *const wnames[] = { g_strdup("..") }; v9fs_qid root_qid; g_autofree v9fs_qid *wqid = NULL; @@ -1188,7 +470,7 @@ static void fs_walk_dotdot(void *obj, void *data, QGuestAllocator *t_alloc) static void fs_lopen(void *obj, void *data, QGuestAllocator *t_alloc) { QVirtio9P *v9p = obj; - alloc = t_alloc; + v9fs_set_allocator(t_alloc); char *const wnames[] = { g_strdup(QTEST_V9FS_SYNTH_LOPEN_FILE) }; P9Req *req; @@ -1207,7 +489,7 @@ static void fs_lopen(void *obj, void *data, QGuestAllocator *t_alloc) static void fs_write(void *obj, void *data, QGuestAllocator *t_alloc) { QVirtio9P *v9p = obj; - alloc = t_alloc; + v9fs_set_allocator(t_alloc); static const uint32_t write_count = P9_MAX_SIZE / 2; char *const wnames[] = { g_strdup(QTEST_V9FS_SYNTH_WRITE_FILE) }; g_autofree char *buf = g_malloc0(write_count); @@ -1234,7 +516,7 @@ static void fs_write(void *obj, void *data, QGuestAllocator *t_alloc) static void fs_flush_success(void *obj, void *data, QGuestAllocator *t_alloc) { QVirtio9P *v9p = obj; - alloc = t_alloc; + v9fs_set_allocator(t_alloc); char *const wnames[] = { g_strdup(QTEST_V9FS_SYNTH_FLUSH_FILE) }; P9Req *req, *flush_req; uint32_t reply_len; @@ -1271,7 +553,7 @@ static void fs_flush_success(void *obj, void *data, QGuestAllocator *t_alloc) static void fs_flush_ignored(void *obj, void *data, QGuestAllocator *t_alloc) { QVirtio9P *v9p = obj; - alloc = t_alloc; + v9fs_set_allocator(t_alloc); char *const wnames[] = { g_strdup(QTEST_V9FS_SYNTH_FLUSH_FILE) }; P9Req *req, *flush_req; uint32_t count; @@ -1383,21 +665,21 @@ static void do_unlinkat(QVirtio9P *v9p, const char *atpath, const char *rpath, static void fs_readdir_split_128(void *obj, void *data, QGuestAllocator *t_alloc) { - alloc = t_alloc; + v9fs_set_allocator(t_alloc); do_readdir_split(obj, 128); } static void fs_readdir_split_256(void *obj, void *data, QGuestAllocator *t_alloc) { - alloc = t_alloc; + v9fs_set_allocator(t_alloc); do_readdir_split(obj, 256); } static void fs_readdir_split_512(void *obj, void *data, QGuestAllocator *t_alloc) { - alloc = t_alloc; + v9fs_set_allocator(t_alloc); do_readdir_split(obj, 512); } @@ -1407,7 +689,7 @@ static void fs_readdir_split_512(void *obj, void *data, static void fs_create_dir(void *obj, void *data, QGuestAllocator *t_alloc) { QVirtio9P *v9p = obj; - alloc = t_alloc; + v9fs_set_allocator(t_alloc); struct stat st; g_autofree char *root_path = virtio_9p_test_path(""); g_autofree char *new_dir = virtio_9p_test_path("01"); @@ -1426,7 +708,7 @@ static void fs_create_dir(void *obj, void *data, QGuestAllocator *t_alloc) static void fs_unlinkat_dir(void *obj, void *data, QGuestAllocator *t_alloc) { QVirtio9P *v9p = obj; - alloc = t_alloc; + v9fs_set_allocator(t_alloc); struct stat st; g_autofree char *root_path = virtio_9p_test_path(""); g_autofree char *new_dir = virtio_9p_test_path("02"); @@ -1449,7 +731,7 @@ static void fs_unlinkat_dir(void *obj, void *data, QGuestAllocator *t_alloc) static void fs_create_file(void *obj, void *data, QGuestAllocator *t_alloc) { QVirtio9P *v9p = obj; - alloc = t_alloc; + v9fs_set_allocator(t_alloc); struct stat st; g_autofree char *new_file = virtio_9p_test_path("03/1st_file"); @@ -1466,7 +748,7 @@ static void fs_create_file(void *obj, void *data, QGuestAllocator *t_alloc) static void fs_unlinkat_file(void *obj, void *data, QGuestAllocator *t_alloc) { QVirtio9P *v9p = obj; - alloc = t_alloc; + v9fs_set_allocator(t_alloc); struct stat st; g_autofree char *new_file = virtio_9p_test_path("04/doa_file"); @@ -1487,7 +769,7 @@ static void fs_unlinkat_file(void *obj, void *data, QGuestAllocator *t_alloc) static void fs_symlink_file(void *obj, void *data, QGuestAllocator *t_alloc) { QVirtio9P *v9p = obj; - alloc = t_alloc; + v9fs_set_allocator(t_alloc); struct stat st; g_autofree char *real_file = virtio_9p_test_path("05/real_file"); g_autofree char *symlink_file = virtio_9p_test_path("05/symlink_file"); @@ -1508,7 +790,7 @@ static void fs_unlinkat_symlink(void *obj, void *data, QGuestAllocator *t_alloc) { QVirtio9P *v9p = obj; - alloc = t_alloc; + v9fs_set_allocator(t_alloc); struct stat st; g_autofree char *real_file = virtio_9p_test_path("06/real_file"); g_autofree char *symlink_file = virtio_9p_test_path("06/symlink_file"); @@ -1530,7 +812,7 @@ static void fs_unlinkat_symlink(void *obj, void *data, static void fs_hardlink_file(void *obj, void *data, QGuestAllocator *t_alloc) { QVirtio9P *v9p = obj; - alloc = t_alloc; + v9fs_set_allocator(t_alloc); struct stat st_real, st_link; g_autofree char *real_file = virtio_9p_test_path("07/real_file"); g_autofree char *hardlink_file = virtio_9p_test_path("07/hardlink_file"); @@ -1555,7 +837,7 @@ static void fs_unlinkat_hardlink(void *obj, void *data, QGuestAllocator *t_alloc) { QVirtio9P *v9p = obj; - alloc = t_alloc; + v9fs_set_allocator(t_alloc); struct stat st_real, st_link; g_autofree char *real_file = virtio_9p_test_path("08/real_file"); g_autofree char *hardlink_file = virtio_9p_test_path("08/hardlink_file"); From f5265c8f917ea8c71a30e549b7e3017c1038db63 Mon Sep 17 00:00:00 2001 From: Linus Heckemann Date: Tue, 4 Oct 2022 12:41:21 +0200 Subject: [PATCH 064/705] 9pfs: use GHashTable for fid table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous implementation would iterate over the fid table for lookup operations, resulting in an operation with O(n) complexity on the number of open files and poor cache locality -- for every open, stat, read, write, etc operation. This change uses a hashtable for this instead, significantly improving the performance of the 9p filesystem. The runtime of NixOS's simple installer test, which copies ~122k files totalling ~1.8GiB from 9p, decreased by a factor of about 10. Signed-off-by: Linus Heckemann Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Greg Kurz [CS: - Retain BUG_ON(f->clunked) in get_fid(). - Add TODO comment in clunk_fid(). ] Message-Id: <20221004104121.713689-1-git@sphalerite.org> [CS: - Drop unnecessary goto and out: label. ] Signed-off-by: Christian Schoenebeck --- hw/9pfs/9p.c | 196 +++++++++++++++++++++++++++++---------------------- hw/9pfs/9p.h | 2 +- 2 files changed, 113 insertions(+), 85 deletions(-) diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c index aebadeaa03..9bf13133e5 100644 --- a/hw/9pfs/9p.c +++ b/hw/9pfs/9p.c @@ -256,7 +256,8 @@ static size_t v9fs_string_size(V9fsString *str) } /* - * returns 0 if fid got re-opened, 1 if not, < 0 on error */ + * returns 0 if fid got re-opened, 1 if not, < 0 on error + */ static int coroutine_fn v9fs_reopen_fid(V9fsPDU *pdu, V9fsFidState *f) { int err = 1; @@ -282,33 +283,32 @@ static V9fsFidState *coroutine_fn get_fid(V9fsPDU *pdu, int32_t fid) V9fsFidState *f; V9fsState *s = pdu->s; - QSIMPLEQ_FOREACH(f, &s->fid_list, next) { + f = g_hash_table_lookup(s->fids, GINT_TO_POINTER(fid)); + if (f) { BUG_ON(f->clunked); - if (f->fid == fid) { - /* - * Update the fid ref upfront so that - * we don't get reclaimed when we yield - * in open later. - */ - f->ref++; - /* - * check whether we need to reopen the - * file. We might have closed the fd - * while trying to free up some file - * descriptors. - */ - err = v9fs_reopen_fid(pdu, f); - if (err < 0) { - f->ref--; - return NULL; - } - /* - * Mark the fid as referenced so that the LRU - * reclaim won't close the file descriptor - */ - f->flags |= FID_REFERENCED; - return f; + /* + * Update the fid ref upfront so that + * we don't get reclaimed when we yield + * in open later. + */ + f->ref++; + /* + * check whether we need to reopen the + * file. We might have closed the fd + * while trying to free up some file + * descriptors. + */ + err = v9fs_reopen_fid(pdu, f); + if (err < 0) { + f->ref--; + return NULL; } + /* + * Mark the fid as referenced so that the LRU + * reclaim won't close the file descriptor + */ + f->flags |= FID_REFERENCED; + return f; } return NULL; } @@ -317,12 +317,11 @@ static V9fsFidState *alloc_fid(V9fsState *s, int32_t fid) { V9fsFidState *f; - QSIMPLEQ_FOREACH(f, &s->fid_list, next) { + f = g_hash_table_lookup(s->fids, GINT_TO_POINTER(fid)); + if (f) { /* If fid is already there return NULL */ BUG_ON(f->clunked); - if (f->fid == fid) { - return NULL; - } + return NULL; } f = g_new0(V9fsFidState, 1); f->fid = fid; @@ -333,7 +332,7 @@ static V9fsFidState *alloc_fid(V9fsState *s, int32_t fid) * reclaim won't close the file descriptor */ f->flags |= FID_REFERENCED; - QSIMPLEQ_INSERT_TAIL(&s->fid_list, f, next); + g_hash_table_insert(s->fids, GINT_TO_POINTER(fid), f); v9fs_readdir_init(s->proto_version, &f->fs.dir); v9fs_readdir_init(s->proto_version, &f->fs_reclaim.dir); @@ -424,12 +423,12 @@ static V9fsFidState *clunk_fid(V9fsState *s, int32_t fid) { V9fsFidState *fidp; - QSIMPLEQ_FOREACH(fidp, &s->fid_list, next) { - if (fidp->fid == fid) { - QSIMPLEQ_REMOVE(&s->fid_list, fidp, V9fsFidState, next); - fidp->clunked = true; - return fidp; - } + /* TODO: Use g_hash_table_steal_extended() instead? */ + fidp = g_hash_table_lookup(s->fids, GINT_TO_POINTER(fid)); + if (fidp) { + g_hash_table_remove(s->fids, GINT_TO_POINTER(fid)); + fidp->clunked = true; + return fidp; } return NULL; } @@ -439,10 +438,15 @@ void coroutine_fn v9fs_reclaim_fd(V9fsPDU *pdu) int reclaim_count = 0; V9fsState *s = pdu->s; V9fsFidState *f; + GHashTableIter iter; + gpointer fid; + + g_hash_table_iter_init(&iter, s->fids); + QSLIST_HEAD(, V9fsFidState) reclaim_list = QSLIST_HEAD_INITIALIZER(reclaim_list); - QSIMPLEQ_FOREACH(f, &s->fid_list, next) { + while (g_hash_table_iter_next(&iter, &fid, (gpointer *) &f)) { /* * Unlink fids cannot be reclaimed. Check * for them and skip them. Also skip fids @@ -514,72 +518,85 @@ void coroutine_fn v9fs_reclaim_fd(V9fsPDU *pdu) } } +/* + * This is used when a path is removed from the directory tree. Any + * fids that still reference it must not be closed from then on, since + * they cannot be reopened. + */ static int coroutine_fn v9fs_mark_fids_unreclaim(V9fsPDU *pdu, V9fsPath *path) { - int err; + int err = 0; V9fsState *s = pdu->s; - V9fsFidState *fidp, *fidp_next; + V9fsFidState *fidp; + gpointer fid; + GHashTableIter iter; + /* + * The most common case is probably that we have exactly one + * fid for the given path, so preallocate exactly one. + */ + g_autoptr(GArray) to_reopen = g_array_sized_new(FALSE, FALSE, + sizeof(V9fsFidState *), 1); + gint i; - fidp = QSIMPLEQ_FIRST(&s->fid_list); - if (!fidp) { - return 0; - } + g_hash_table_iter_init(&iter, s->fids); /* - * v9fs_reopen_fid() can yield : a reference on the fid must be held - * to ensure its pointer remains valid and we can safely pass it to - * QSIMPLEQ_NEXT(). The corresponding put_fid() can also yield so - * we must keep a reference on the next fid as well. So the logic here - * is to get a reference on a fid and only put it back during the next - * iteration after we could get a reference on the next fid. Start with - * the first one. + * We iterate over the fid table looking for the entries we need + * to reopen, and store them in to_reopen. This is because + * v9fs_reopen_fid() and put_fid() yield. This allows the fid table + * to be modified in the meantime, invalidating our iterator. */ - for (fidp->ref++; fidp; fidp = fidp_next) { + while (g_hash_table_iter_next(&iter, &fid, (gpointer *) &fidp)) { if (fidp->path.size == path->size && !memcmp(fidp->path.data, path->data, path->size)) { - /* Mark the fid non reclaimable. */ - fidp->flags |= FID_NON_RECLAIMABLE; - - /* reopen the file/dir if already closed */ - err = v9fs_reopen_fid(pdu, fidp); - if (err < 0) { - put_fid(pdu, fidp); - return err; - } - } - - fidp_next = QSIMPLEQ_NEXT(fidp, next); - - if (fidp_next) { /* - * Ensure the next fid survives a potential clunk request during - * put_fid() below and v9fs_reopen_fid() in the next iteration. + * Ensure the fid survives a potential clunk request during + * v9fs_reopen_fid or put_fid. */ - fidp_next->ref++; + fidp->ref++; + fidp->flags |= FID_NON_RECLAIMABLE; + g_array_append_val(to_reopen, fidp); } - - /* We're done with this fid */ - put_fid(pdu, fidp); } - return 0; + for (i = 0; i < to_reopen->len; i++) { + fidp = g_array_index(to_reopen, V9fsFidState*, i); + /* reopen the file/dir if already closed */ + err = v9fs_reopen_fid(pdu, fidp); + if (err < 0) { + break; + } + } + + for (i = 0; i < to_reopen->len; i++) { + put_fid(pdu, g_array_index(to_reopen, V9fsFidState*, i)); + } + return err; } static void coroutine_fn virtfs_reset(V9fsPDU *pdu) { V9fsState *s = pdu->s; V9fsFidState *fidp; + GList *freeing; + /* + * Get a list of all the values (fid states) in the table, which + * we then... + */ + g_autoptr(GList) fids = g_hash_table_get_values(s->fids); - /* Free all fids */ - while (!QSIMPLEQ_EMPTY(&s->fid_list)) { - /* Get fid */ - fidp = QSIMPLEQ_FIRST(&s->fid_list); + /* ... remove from the table, taking over ownership. */ + g_hash_table_steal_all(s->fids); + + /* + * This allows us to release our references to them asynchronously without + * iterating over the hash table and risking iterator invalidation + * through concurrent modifications. + */ + for (freeing = fids; freeing; freeing = freeing->next) { + fidp = freeing->data; fidp->ref++; - - /* Clunk fid */ - QSIMPLEQ_REMOVE(&s->fid_list, fidp, V9fsFidState, next); fidp->clunked = true; - put_fid(pdu, fidp); } } @@ -3205,6 +3222,8 @@ static int coroutine_fn v9fs_complete_rename(V9fsPDU *pdu, V9fsFidState *fidp, V9fsFidState *tfidp; V9fsState *s = pdu->s; V9fsFidState *dirfidp = NULL; + GHashTableIter iter; + gpointer fid; v9fs_path_init(&new_path); if (newdirfid != -1) { @@ -3238,11 +3257,13 @@ static int coroutine_fn v9fs_complete_rename(V9fsPDU *pdu, V9fsFidState *fidp, if (err < 0) { goto out; } + /* * Fixup fid's pointing to the old name to * start pointing to the new name */ - QSIMPLEQ_FOREACH(tfidp, &s->fid_list, next) { + g_hash_table_iter_init(&iter, s->fids); + while (g_hash_table_iter_next(&iter, &fid, (gpointer *) &tfidp)) { if (v9fs_path_is_ancestor(&fidp->path, &tfidp->path)) { /* replace the name */ v9fs_fix_path(&tfidp->path, &new_path, strlen(fidp->path.data)); @@ -3320,6 +3341,8 @@ static int coroutine_fn v9fs_fix_fid_paths(V9fsPDU *pdu, V9fsPath *olddir, V9fsPath oldpath, newpath; V9fsState *s = pdu->s; int err; + GHashTableIter iter; + gpointer fid; v9fs_path_init(&oldpath); v9fs_path_init(&newpath); @@ -3336,7 +3359,8 @@ static int coroutine_fn v9fs_fix_fid_paths(V9fsPDU *pdu, V9fsPath *olddir, * Fixup fid's pointing to the old name to * start pointing to the new name */ - QSIMPLEQ_FOREACH(tfidp, &s->fid_list, next) { + g_hash_table_iter_init(&iter, s->fids); + while (g_hash_table_iter_next(&iter, &fid, (gpointer *) &tfidp)) { if (v9fs_path_is_ancestor(&oldpath, &tfidp->path)) { /* replace the name */ v9fs_fix_path(&tfidp->path, &newpath, strlen(oldpath.data)); @@ -4226,7 +4250,7 @@ int v9fs_device_realize_common(V9fsState *s, const V9fsTransport *t, s->ctx.fmode = fse->fmode; s->ctx.dmode = fse->dmode; - QSIMPLEQ_INIT(&s->fid_list); + s->fids = g_hash_table_new(NULL, NULL); qemu_co_rwlock_init(&s->rename_lock); if (s->ops->init(&s->ctx, errp) < 0) { @@ -4286,6 +4310,10 @@ void v9fs_device_unrealize_common(V9fsState *s) if (s->ctx.fst) { fsdev_throttle_cleanup(s->ctx.fst); } + if (s->fids) { + g_hash_table_destroy(s->fids); + s->fids = NULL; + } g_free(s->tag); qp_table_destroy(&s->qpd_table); qp_table_destroy(&s->qpp_table); diff --git a/hw/9pfs/9p.h b/hw/9pfs/9p.h index a523ac34a9..2fce4140d1 100644 --- a/hw/9pfs/9p.h +++ b/hw/9pfs/9p.h @@ -339,7 +339,7 @@ typedef struct { struct V9fsState { QLIST_HEAD(, V9fsPDU) free_list; QLIST_HEAD(, V9fsPDU) active_list; - QSIMPLEQ_HEAD(, V9fsFidState) fid_list; + GHashTable *fids; FileOperations *ops; FsContext ctx; char *tag; From 569f3b63ad5f65d0f86724766fedfffffe0feda3 Mon Sep 17 00:00:00 2001 From: Christian Schoenebeck Date: Tue, 4 Oct 2022 22:53:23 +0200 Subject: [PATCH 065/705] tests/9p: merge *walk*() functions Introduce declarative function calls. There are currently 4 different functions for sending a 9p 'Twalk' request: v9fs_twalk(), do_walk(), do_walk_rqids() and do_walk_expect_error(). They are all doing the same thing, just in a slightly different way and with slightly different function arguments. Merge those 4 functions into a single function by using a struct for function call arguments and use designated initializers when calling this function to turn usage into a declarative approach, which is better readable and easier to maintain. Also move private functions genfid(), split() and split_free() from virtio-9p-test.c to virtio-9p-client.c. Based-on: Signed-off-by: Christian Schoenebeck Message-Id: <607969dbfbc63c1be008df9131133711b046e979.1664917004.git.qemu_oss@crudebyte.com> --- tests/qtest/libqos/virtio-9p-client.c | 114 ++++++++++++++-- tests/qtest/libqos/virtio-9p-client.h | 37 ++++- tests/qtest/virtio-9p-test.c | 187 +++++++++----------------- 3 files changed, 198 insertions(+), 140 deletions(-) diff --git a/tests/qtest/libqos/virtio-9p-client.c b/tests/qtest/libqos/virtio-9p-client.c index f5c35fd722..a95bbad9c8 100644 --- a/tests/qtest/libqos/virtio-9p-client.c +++ b/tests/qtest/libqos/virtio-9p-client.c @@ -23,6 +23,65 @@ void v9fs_set_allocator(QGuestAllocator *t_alloc) alloc = t_alloc; } +/* + * Used to auto generate new fids. Start with arbitrary high value to avoid + * collision with hard coded fids in basic test code. + */ +static uint32_t fid_generator = 1000; + +static uint32_t genfid(void) +{ + return fid_generator++; +} + +/** + * Splits the @a in string by @a delim into individual (non empty) strings + * and outputs them to @a out. The output array @a out is NULL terminated. + * + * Output array @a out must be freed by calling split_free(). + * + * @returns number of individual elements in output array @a out (without the + * final NULL terminating element) + */ +static int split(const char *in, const char *delim, char ***out) +{ + int n = 0, i = 0; + char *tmp, *p; + + tmp = g_strdup(in); + for (p = strtok(tmp, delim); p != NULL; p = strtok(NULL, delim)) { + if (strlen(p) > 0) { + ++n; + } + } + g_free(tmp); + + *out = g_new0(char *, n + 1); /* last element NULL delimiter */ + + tmp = g_strdup(in); + for (p = strtok(tmp, delim); p != NULL; p = strtok(NULL, delim)) { + if (strlen(p) > 0) { + (*out)[i++] = g_strdup(p); + } + } + g_free(tmp); + + return n; +} + +static void split_free(char ***out) +{ + int i; + if (!*out) { + return; + } + for (i = 0; (*out)[i]; ++i) { + g_free((*out)[i]); + } + g_free(*out); + *out = NULL; +} + void v9fs_memwrite(P9Req *req, const void *addr, size_t len) { qtest_memwrite(req->qts, req->t_msg + req->t_off, addr, len); @@ -294,28 +353,61 @@ void v9fs_rattach(P9Req *req, v9fs_qid *qid) } /* size[4] Twalk tag[2] fid[4] newfid[4] nwname[2] nwname*(wname[s]) */ -P9Req *v9fs_twalk(QVirtio9P *v9p, uint32_t fid, uint32_t newfid, - uint16_t nwname, char *const wnames[], uint16_t tag) +TWalkRes v9fs_twalk(TWalkOpt opt) { P9Req *req; int i; uint32_t body_size = 4 + 4 + 2; + uint32_t err; + char **wnames = NULL; - for (i = 0; i < nwname; i++) { - uint16_t wname_size = v9fs_string_size(wnames[i]); + g_assert(opt.client); + /* expecting either high- or low-level path, both not both */ + g_assert(!opt.path || !(opt.nwname || opt.wnames)); + /* expecting either Rwalk or Rlerror, but obviously not both */ + g_assert(!opt.expectErr || !(opt.rwalk.nwqid || opt.rwalk.wqid)); + + if (!opt.newfid) { + opt.newfid = genfid(); + } + + if (opt.path) { + opt.nwname = split(opt.path, "/", &wnames); + opt.wnames = wnames; + } + + for (i = 0; i < opt.nwname; i++) { + uint16_t wname_size = v9fs_string_size(opt.wnames[i]); g_assert_cmpint(body_size, <=, UINT32_MAX - wname_size); body_size += wname_size; } - req = v9fs_req_init(v9p, body_size, P9_TWALK, tag); - v9fs_uint32_write(req, fid); - v9fs_uint32_write(req, newfid); - v9fs_uint16_write(req, nwname); - for (i = 0; i < nwname; i++) { - v9fs_string_write(req, wnames[i]); + req = v9fs_req_init(opt.client, body_size, P9_TWALK, opt.tag); + v9fs_uint32_write(req, opt.fid); + v9fs_uint32_write(req, opt.newfid); + v9fs_uint16_write(req, opt.nwname); + for (i = 0; i < opt.nwname; i++) { + v9fs_string_write(req, opt.wnames[i]); } v9fs_req_send(req); - return req; + + if (!opt.requestOnly) { + v9fs_req_wait_for_reply(req, NULL); + if (opt.expectErr) { + v9fs_rlerror(req, &err); + g_assert_cmpint(err, ==, opt.expectErr); + } else { + v9fs_rwalk(req, opt.rwalk.nwqid, opt.rwalk.wqid); + } + req = NULL; /* request was freed */ + } + + split_free(&wnames); + + return (TWalkRes) { + .newfid = opt.newfid, + .req = req, + }; } /* size[4] Rwalk tag[2] nwqid[2] nwqid*(wqid[13]) */ diff --git a/tests/qtest/libqos/virtio-9p-client.h b/tests/qtest/libqos/virtio-9p-client.h index c502d12a66..8c6abbb173 100644 --- a/tests/qtest/libqos/virtio-9p-client.h +++ b/tests/qtest/libqos/virtio-9p-client.h @@ -72,6 +72,40 @@ struct V9fsDirent { struct V9fsDirent *next; }; +/* options for 'Twalk' 9p request */ +typedef struct TWalkOpt { + /* 9P client being used (mandatory) */ + QVirtio9P *client; + /* user supplied tag number being returned with response (optional) */ + uint16_t tag; + /* file ID of directory from where walk should start (optional) */ + uint32_t fid; + /* file ID for target directory being walked to (optional) */ + uint32_t newfid; + /* low level variant of path to walk to (optional) */ + uint16_t nwname; + char **wnames; + /* high level variant of path to walk to (optional) */ + const char *path; + /* data being received from 9p server as 'Rwalk' response (optional) */ + struct { + uint16_t *nwqid; + v9fs_qid **wqid; + } rwalk; + /* only send Twalk request but not wait for a reply? (optional) */ + bool requestOnly; + /* do we expect an Rlerror response, if yes which error code? (optional) */ + uint32_t expectErr; +} TWalkOpt; + +/* result of 'Twalk' 9p request */ +typedef struct TWalkRes { + /* file ID of target directory been walked to */ + uint32_t newfid; + /* if requestOnly was set: request object for further processing */ + P9Req *req; +} TWalkRes; + void v9fs_set_allocator(QGuestAllocator *t_alloc); void v9fs_memwrite(P9Req *req, const void *addr, size_t len); void v9fs_memskip(P9Req *req, size_t len); @@ -99,8 +133,7 @@ void v9fs_rversion(P9Req *req, uint16_t *len, char **version); P9Req *v9fs_tattach(QVirtio9P *v9p, uint32_t fid, uint32_t n_uname, uint16_t tag); void v9fs_rattach(P9Req *req, v9fs_qid *qid); -P9Req *v9fs_twalk(QVirtio9P *v9p, uint32_t fid, uint32_t newfid, - uint16_t nwname, char *const wnames[], uint16_t tag); +TWalkRes v9fs_twalk(TWalkOpt opt); void v9fs_rwalk(P9Req *req, uint16_t *nwqid, v9fs_qid **wqid); P9Req *v9fs_tgetattr(QVirtio9P *v9p, uint32_t fid, uint64_t request_mask, uint16_t tag); diff --git a/tests/qtest/virtio-9p-test.c b/tests/qtest/virtio-9p-test.c index 498c32e21b..cf5d6146ad 100644 --- a/tests/qtest/virtio-9p-test.c +++ b/tests/qtest/virtio-9p-test.c @@ -16,61 +16,7 @@ #include "qemu/module.h" #include "libqos/virtio-9p-client.h" -/* - * Used to auto generate new fids. Start with arbitrary high value to avoid - * collision with hard coded fids in basic test code. - */ -static uint32_t fid_generator = 1000; - -static uint32_t genfid(void) -{ - return fid_generator++; -} - -/** - * Splits the @a in string by @a delim into individual (non empty) strings - * and outputs them to @a out. The output array @a out is NULL terminated. - * - * Output array @a out must be freed by calling split_free(). - * - * @returns number of individual elements in output array @a out (without the - * final NULL terminating element) - */ -static int split(const char *in, const char *delim, char ***out) -{ - int n = 0, i = 0; - char *tmp, *p; - - tmp = g_strdup(in); - for (p = strtok(tmp, delim); p != NULL; p = strtok(NULL, delim)) { - if (strlen(p) > 0) { - ++n; - } - } - g_free(tmp); - - *out = g_new0(char *, n + 1); /* last element NULL delimiter */ - - tmp = g_strdup(in); - for (p = strtok(tmp, delim); p != NULL; p = strtok(NULL, delim)) { - if (strlen(p) > 0) { - (*out)[i++] = g_strdup(p); - } - } - g_free(tmp); - - return n; -} - -static void split_free(char ***out) -{ - int i; - for (i = 0; (*out)[i]; ++i) { - g_free((*out)[i]); - } - g_free(*out); - *out = NULL; -} +#define twalk(...) v9fs_twalk((TWalkOpt) __VA_ARGS__) static void pci_config(void *obj, void *data, QGuestAllocator *t_alloc) { @@ -109,52 +55,6 @@ static void do_version(QVirtio9P *v9p) g_assert_cmpmem(server_version, server_len, version, strlen(version)); } -/* - * utility function: walk to requested dir and return fid for that dir and - * the QIDs of server response - */ -static uint32_t do_walk_rqids(QVirtio9P *v9p, const char *path, uint16_t *nwqid, - v9fs_qid **wqid) -{ - char **wnames; - P9Req *req; - const uint32_t fid = genfid(); - - int nwnames = split(path, "/", &wnames); - - req = v9fs_twalk(v9p, 0, fid, nwnames, wnames, 0); - v9fs_req_wait_for_reply(req, NULL); - v9fs_rwalk(req, nwqid, wqid); - - split_free(&wnames); - return fid; -} - -/* utility function: walk to requested dir and return fid for that dir */ -static uint32_t do_walk(QVirtio9P *v9p, const char *path) -{ - return do_walk_rqids(v9p, path, NULL, NULL); -} - -/* utility function: walk to requested dir and expect passed error response */ -static void do_walk_expect_error(QVirtio9P *v9p, const char *path, uint32_t err) -{ - char **wnames; - P9Req *req; - uint32_t _err; - const uint32_t fid = genfid(); - - int nwnames = split(path, "/", &wnames); - - req = v9fs_twalk(v9p, 0, fid, nwnames, wnames, 0); - v9fs_req_wait_for_reply(req, NULL); - v9fs_rlerror(req, &_err); - - g_assert_cmpint(_err, ==, err); - - split_free(&wnames); -} - static void fs_version(void *obj, void *data, QGuestAllocator *t_alloc) { v9fs_set_allocator(t_alloc); @@ -197,7 +97,10 @@ static void fs_walk(void *obj, void *data, QGuestAllocator *t_alloc) } do_attach(v9p); - req = v9fs_twalk(v9p, 0, 1, P9_MAXWELEM, wnames, 0); + req = twalk({ + .client = v9p, .fid = 0, .newfid = 1, + .nwname = P9_MAXWELEM, .wnames = wnames, .requestOnly = true + }).req; v9fs_req_wait_for_reply(req, NULL); v9fs_rwalk(req, &nwqid, &wqid); @@ -223,7 +126,7 @@ static void fs_readdir(void *obj, void *data, QGuestAllocator *t_alloc) { QVirtio9P *v9p = obj; v9fs_set_allocator(t_alloc); - char *const wnames[] = { g_strdup(QTEST_V9FS_SYNTH_READDIR_DIR) }; + char *wnames[] = { g_strdup(QTEST_V9FS_SYNTH_READDIR_DIR) }; uint16_t nqid; v9fs_qid qid; uint32_t count, nentries; @@ -231,7 +134,10 @@ static void fs_readdir(void *obj, void *data, QGuestAllocator *t_alloc) P9Req *req; do_attach(v9p); - req = v9fs_twalk(v9p, 0, 1, 1, wnames, 0); + req = twalk({ + .client = v9p, .fid = 0, .newfid = 1, + .nwname = 1, .wnames = wnames, .requestOnly = true + }).req; v9fs_req_wait_for_reply(req, NULL); v9fs_rwalk(req, &nqid, NULL); g_assert_cmpint(nqid, ==, 1); @@ -275,7 +181,7 @@ static void fs_readdir(void *obj, void *data, QGuestAllocator *t_alloc) /* readdir test where overall request is split over several messages */ static void do_readdir_split(QVirtio9P *v9p, uint32_t count) { - char *const wnames[] = { g_strdup(QTEST_V9FS_SYNTH_READDIR_DIR) }; + char *wnames[] = { g_strdup(QTEST_V9FS_SYNTH_READDIR_DIR) }; uint16_t nqid; v9fs_qid qid; uint32_t nentries, npartialentries; @@ -292,7 +198,10 @@ static void do_readdir_split(QVirtio9P *v9p, uint32_t count) nentries = 0; tail = NULL; - req = v9fs_twalk(v9p, 0, fid, 1, wnames, 0); + req = twalk({ + .client = v9p, .fid = 0, .newfid = fid, + .nwname = 1, .wnames = wnames, .requestOnly = true + }).req; v9fs_req_wait_for_reply(req, NULL); v9fs_rwalk(req, &nqid, NULL); g_assert_cmpint(nqid, ==, 1); @@ -356,12 +265,15 @@ static void fs_walk_no_slash(void *obj, void *data, QGuestAllocator *t_alloc) { QVirtio9P *v9p = obj; v9fs_set_allocator(t_alloc); - char *const wnames[] = { g_strdup(" /") }; + char *wnames[] = { g_strdup(" /") }; P9Req *req; uint32_t err; do_attach(v9p); - req = v9fs_twalk(v9p, 0, 1, 1, wnames, 0); + req = twalk({ + .client = v9p, .fid = 0, .newfid = 1, .nwname = 1, .wnames = wnames, + .requestOnly = true + }).req; v9fs_req_wait_for_reply(req, NULL); v9fs_rlerror(req, &err); @@ -380,7 +292,7 @@ static void fs_walk_nonexistent(void *obj, void *data, QGuestAllocator *t_alloc) * The 9p2000 protocol spec says: "If the first element cannot be walked * for any reason, Rerror is returned." */ - do_walk_expect_error(v9p, "non-existent", ENOENT); + twalk({ .client = v9p, .path = "non-existent", .expectErr = ENOENT }); } static void fs_walk_2nd_nonexistent(void *obj, void *data, @@ -398,7 +310,10 @@ static void fs_walk_2nd_nonexistent(void *obj, void *data, ); do_attach_rqid(v9p, &root_qid); - fid = do_walk_rqids(v9p, path, &nwqid, &wqid); + fid = twalk({ + .client = v9p, .path = path, + .rwalk.nwqid = &nwqid, .rwalk.wqid = &wqid + }).newfid; /* * The 9p2000 protocol spec says: "nwqid is therefore either nwname or the * index of the first elementwise walk that failed." @@ -430,7 +345,10 @@ static void fs_walk_none(void *obj, void *data, QGuestAllocator *t_alloc) v9fs_req_wait_for_reply(req, NULL); v9fs_rattach(req, &root_qid); - req = v9fs_twalk(v9p, 0, 1, 0, NULL, 0); + req = twalk({ + .client = v9p, .fid = 0, .newfid = 1, .nwname = 0, .wnames = NULL, + .requestOnly = true + }).req; v9fs_req_wait_for_reply(req, NULL); v9fs_rwalk(req, NULL, &wqid); @@ -448,7 +366,7 @@ static void fs_walk_dotdot(void *obj, void *data, QGuestAllocator *t_alloc) { QVirtio9P *v9p = obj; v9fs_set_allocator(t_alloc); - char *const wnames[] = { g_strdup("..") }; + char *wnames[] = { g_strdup("..") }; v9fs_qid root_qid; g_autofree v9fs_qid *wqid = NULL; P9Req *req; @@ -458,7 +376,10 @@ static void fs_walk_dotdot(void *obj, void *data, QGuestAllocator *t_alloc) v9fs_req_wait_for_reply(req, NULL); v9fs_rattach(req, &root_qid); - req = v9fs_twalk(v9p, 0, 1, 1, wnames, 0); + req = twalk({ + .client = v9p, .fid = 0, .newfid = 1, .nwname = 1, .wnames = wnames, + .requestOnly = true + }).req; v9fs_req_wait_for_reply(req, NULL); v9fs_rwalk(req, NULL, &wqid); /* We now we'll get one qid */ @@ -471,11 +392,14 @@ static void fs_lopen(void *obj, void *data, QGuestAllocator *t_alloc) { QVirtio9P *v9p = obj; v9fs_set_allocator(t_alloc); - char *const wnames[] = { g_strdup(QTEST_V9FS_SYNTH_LOPEN_FILE) }; + char *wnames[] = { g_strdup(QTEST_V9FS_SYNTH_LOPEN_FILE) }; P9Req *req; do_attach(v9p); - req = v9fs_twalk(v9p, 0, 1, 1, wnames, 0); + req = twalk({ + .client = v9p, .fid = 0, .newfid = 1, .nwname = 1, .wnames = wnames, + .requestOnly = true + }).req; v9fs_req_wait_for_reply(req, NULL); v9fs_rwalk(req, NULL, NULL); @@ -491,13 +415,16 @@ static void fs_write(void *obj, void *data, QGuestAllocator *t_alloc) QVirtio9P *v9p = obj; v9fs_set_allocator(t_alloc); static const uint32_t write_count = P9_MAX_SIZE / 2; - char *const wnames[] = { g_strdup(QTEST_V9FS_SYNTH_WRITE_FILE) }; + char *wnames[] = { g_strdup(QTEST_V9FS_SYNTH_WRITE_FILE) }; g_autofree char *buf = g_malloc0(write_count); uint32_t count; P9Req *req; do_attach(v9p); - req = v9fs_twalk(v9p, 0, 1, 1, wnames, 0); + req = twalk({ + .client = v9p, .fid = 0, .newfid = 1, .nwname = 1, .wnames = wnames, + .requestOnly = true + }).req; v9fs_req_wait_for_reply(req, NULL); v9fs_rwalk(req, NULL, NULL); @@ -517,13 +444,16 @@ static void fs_flush_success(void *obj, void *data, QGuestAllocator *t_alloc) { QVirtio9P *v9p = obj; v9fs_set_allocator(t_alloc); - char *const wnames[] = { g_strdup(QTEST_V9FS_SYNTH_FLUSH_FILE) }; + char *wnames[] = { g_strdup(QTEST_V9FS_SYNTH_FLUSH_FILE) }; P9Req *req, *flush_req; uint32_t reply_len; uint8_t should_block; do_attach(v9p); - req = v9fs_twalk(v9p, 0, 1, 1, wnames, 0); + req = twalk({ + .client = v9p, .fid = 0, .newfid = 1, .nwname = 1, .wnames = wnames, + .requestOnly = true + }).req; v9fs_req_wait_for_reply(req, NULL); v9fs_rwalk(req, NULL, NULL); @@ -554,13 +484,16 @@ static void fs_flush_ignored(void *obj, void *data, QGuestAllocator *t_alloc) { QVirtio9P *v9p = obj; v9fs_set_allocator(t_alloc); - char *const wnames[] = { g_strdup(QTEST_V9FS_SYNTH_FLUSH_FILE) }; + char *wnames[] = { g_strdup(QTEST_V9FS_SYNTH_FLUSH_FILE) }; P9Req *req, *flush_req; uint32_t count; uint8_t should_block; do_attach(v9p); - req = v9fs_twalk(v9p, 0, 1, 1, wnames, 0); + req = twalk({ + .client = v9p, .fid = 0, .newfid = 1, .nwname = 1, .wnames = wnames, + .requestOnly = true + }).req; v9fs_req_wait_for_reply(req, NULL); v9fs_rwalk(req, NULL, NULL); @@ -593,7 +526,7 @@ static void do_mkdir(QVirtio9P *v9p, const char *path, const char *cname) uint32_t fid; P9Req *req; - fid = do_walk(v9p, path); + fid = twalk({ .client = v9p, .path = path }).newfid; req = v9fs_tmkdir(v9p, fid, name, 0750, 0, 0); v9fs_req_wait_for_reply(req, NULL); @@ -608,7 +541,7 @@ static uint32_t do_lcreate(QVirtio9P *v9p, const char *path, uint32_t fid; P9Req *req; - fid = do_walk(v9p, path); + fid = twalk({ .client = v9p, .path = path }).newfid; req = v9fs_tlcreate(v9p, fid, name, 0, 0750, 0, 0); v9fs_req_wait_for_reply(req, NULL); @@ -626,7 +559,7 @@ static void do_symlink(QVirtio9P *v9p, const char *path, const char *clink, uint32_t fid; P9Req *req; - fid = do_walk(v9p, path); + fid = twalk({ .client = v9p, .path = path }).newfid; req = v9fs_tsymlink(v9p, fid, name, dst, 0, 0); v9fs_req_wait_for_reply(req, NULL); @@ -640,8 +573,8 @@ static void do_hardlink(QVirtio9P *v9p, const char *path, const char *clink, uint32_t dfid, fid; P9Req *req; - dfid = do_walk(v9p, path); - fid = do_walk(v9p, to); + dfid = twalk({ .client = v9p, .path = path }).newfid; + fid = twalk({ .client = v9p, .path = to }).newfid; req = v9fs_tlink(v9p, dfid, fid, clink, 0); v9fs_req_wait_for_reply(req, NULL); @@ -655,7 +588,7 @@ static void do_unlinkat(QVirtio9P *v9p, const char *atpath, const char *rpath, uint32_t fid; P9Req *req; - fid = do_walk(v9p, atpath); + fid = twalk({ .client = v9p, .path = atpath }).newfid; req = v9fs_tunlinkat(v9p, fid, name, flags, 0); v9fs_req_wait_for_reply(req, NULL); From 3f3e9232207fc4f0e5cb5cf63f11ed9449efeefa Mon Sep 17 00:00:00 2001 From: Christian Schoenebeck Date: Tue, 4 Oct 2022 22:53:29 +0200 Subject: [PATCH 066/705] tests/9p: simplify callers of twalk() Now as twalk() is using a declarative approach, simplify the code of callers of this function. Signed-off-by: Christian Schoenebeck Message-Id: <8b9d3c656ad43b6c953d6bdacd8d9f4c8e599b2a.1664917004.git.qemu_oss@crudebyte.com> --- tests/qtest/virtio-9p-test.c | 92 +++++++++++++----------------------- 1 file changed, 32 insertions(+), 60 deletions(-) diff --git a/tests/qtest/virtio-9p-test.c b/tests/qtest/virtio-9p-test.c index cf5d6146ad..3c326451b1 100644 --- a/tests/qtest/virtio-9p-test.c +++ b/tests/qtest/virtio-9p-test.c @@ -90,19 +90,17 @@ static void fs_walk(void *obj, void *data, QGuestAllocator *t_alloc) uint16_t nwqid; g_autofree v9fs_qid *wqid = NULL; int i; - P9Req *req; for (i = 0; i < P9_MAXWELEM; i++) { wnames[i] = g_strdup_printf(QTEST_V9FS_SYNTH_WALK_FILE, i); } do_attach(v9p); - req = twalk({ + twalk({ .client = v9p, .fid = 0, .newfid = 1, - .nwname = P9_MAXWELEM, .wnames = wnames, .requestOnly = true - }).req; - v9fs_req_wait_for_reply(req, NULL); - v9fs_rwalk(req, &nwqid, &wqid); + .nwname = P9_MAXWELEM, .wnames = wnames, + .rwalk = { .nwqid = &nwqid, .wqid = &wqid } + }); g_assert_cmpint(nwqid, ==, P9_MAXWELEM); @@ -134,12 +132,10 @@ static void fs_readdir(void *obj, void *data, QGuestAllocator *t_alloc) P9Req *req; do_attach(v9p); - req = twalk({ + twalk({ .client = v9p, .fid = 0, .newfid = 1, - .nwname = 1, .wnames = wnames, .requestOnly = true - }).req; - v9fs_req_wait_for_reply(req, NULL); - v9fs_rwalk(req, &nqid, NULL); + .nwname = 1, .wnames = wnames, .rwalk.nwqid = &nqid + }); g_assert_cmpint(nqid, ==, 1); req = v9fs_tlopen(v9p, 1, O_DIRECTORY, 0); @@ -198,12 +194,10 @@ static void do_readdir_split(QVirtio9P *v9p, uint32_t count) nentries = 0; tail = NULL; - req = twalk({ + twalk({ .client = v9p, .fid = 0, .newfid = fid, - .nwname = 1, .wnames = wnames, .requestOnly = true - }).req; - v9fs_req_wait_for_reply(req, NULL); - v9fs_rwalk(req, &nqid, NULL); + .nwname = 1, .wnames = wnames, .rwalk.nwqid = &nqid + }); g_assert_cmpint(nqid, ==, 1); req = v9fs_tlopen(v9p, fid, O_DIRECTORY, 0); @@ -266,18 +260,12 @@ static void fs_walk_no_slash(void *obj, void *data, QGuestAllocator *t_alloc) QVirtio9P *v9p = obj; v9fs_set_allocator(t_alloc); char *wnames[] = { g_strdup(" /") }; - P9Req *req; - uint32_t err; do_attach(v9p); - req = twalk({ + twalk({ .client = v9p, .fid = 0, .newfid = 1, .nwname = 1, .wnames = wnames, - .requestOnly = true - }).req; - v9fs_req_wait_for_reply(req, NULL); - v9fs_rlerror(req, &err); - - g_assert_cmpint(err, ==, ENOENT); + .expectErr = ENOENT + }); g_free(wnames[0]); } @@ -312,7 +300,7 @@ static void fs_walk_2nd_nonexistent(void *obj, void *data, do_attach_rqid(v9p, &root_qid); fid = twalk({ .client = v9p, .path = path, - .rwalk.nwqid = &nwqid, .rwalk.wqid = &wqid + .rwalk = { .nwqid = &nwqid, .wqid = &wqid } }).newfid; /* * The 9p2000 protocol spec says: "nwqid is therefore either nwname or the @@ -345,12 +333,10 @@ static void fs_walk_none(void *obj, void *data, QGuestAllocator *t_alloc) v9fs_req_wait_for_reply(req, NULL); v9fs_rattach(req, &root_qid); - req = twalk({ + twalk({ .client = v9p, .fid = 0, .newfid = 1, .nwname = 0, .wnames = NULL, - .requestOnly = true - }).req; - v9fs_req_wait_for_reply(req, NULL); - v9fs_rwalk(req, NULL, &wqid); + .rwalk.wqid = &wqid + }); /* special case: no QID is returned if nwname=0 was sent */ g_assert(wqid == NULL); @@ -376,12 +362,10 @@ static void fs_walk_dotdot(void *obj, void *data, QGuestAllocator *t_alloc) v9fs_req_wait_for_reply(req, NULL); v9fs_rattach(req, &root_qid); - req = twalk({ + twalk({ .client = v9p, .fid = 0, .newfid = 1, .nwname = 1, .wnames = wnames, - .requestOnly = true - }).req; - v9fs_req_wait_for_reply(req, NULL); - v9fs_rwalk(req, NULL, &wqid); /* We now we'll get one qid */ + .rwalk.wqid = &wqid /* We now we'll get one qid */ + }); g_assert_cmpmem(&root_qid, 13, wqid[0], 13); @@ -396,12 +380,9 @@ static void fs_lopen(void *obj, void *data, QGuestAllocator *t_alloc) P9Req *req; do_attach(v9p); - req = twalk({ - .client = v9p, .fid = 0, .newfid = 1, .nwname = 1, .wnames = wnames, - .requestOnly = true - }).req; - v9fs_req_wait_for_reply(req, NULL); - v9fs_rwalk(req, NULL, NULL); + twalk({ + .client = v9p, .fid = 0, .newfid = 1, .nwname = 1, .wnames = wnames + }); req = v9fs_tlopen(v9p, 1, O_WRONLY, 0); v9fs_req_wait_for_reply(req, NULL); @@ -421,12 +402,9 @@ static void fs_write(void *obj, void *data, QGuestAllocator *t_alloc) P9Req *req; do_attach(v9p); - req = twalk({ - .client = v9p, .fid = 0, .newfid = 1, .nwname = 1, .wnames = wnames, - .requestOnly = true - }).req; - v9fs_req_wait_for_reply(req, NULL); - v9fs_rwalk(req, NULL, NULL); + twalk({ + .client = v9p, .fid = 0, .newfid = 1, .nwname = 1, .wnames = wnames + }); req = v9fs_tlopen(v9p, 1, O_WRONLY, 0); v9fs_req_wait_for_reply(req, NULL); @@ -450,12 +428,9 @@ static void fs_flush_success(void *obj, void *data, QGuestAllocator *t_alloc) uint8_t should_block; do_attach(v9p); - req = twalk({ - .client = v9p, .fid = 0, .newfid = 1, .nwname = 1, .wnames = wnames, - .requestOnly = true - }).req; - v9fs_req_wait_for_reply(req, NULL); - v9fs_rwalk(req, NULL, NULL); + twalk({ + .client = v9p, .fid = 0, .newfid = 1, .nwname = 1, .wnames = wnames + }); req = v9fs_tlopen(v9p, 1, O_WRONLY, 0); v9fs_req_wait_for_reply(req, NULL); @@ -490,12 +465,9 @@ static void fs_flush_ignored(void *obj, void *data, QGuestAllocator *t_alloc) uint8_t should_block; do_attach(v9p); - req = twalk({ - .client = v9p, .fid = 0, .newfid = 1, .nwname = 1, .wnames = wnames, - .requestOnly = true - }).req; - v9fs_req_wait_for_reply(req, NULL); - v9fs_rwalk(req, NULL, NULL); + twalk({ + .client = v9p, .fid = 0, .newfid = 1, .nwname = 1, .wnames = wnames + }); req = v9fs_tlopen(v9p, 1, O_WRONLY, 0); v9fs_req_wait_for_reply(req, NULL); From bee8fda2f9841cc8d76fbe60f65f9aeb29fce1c2 Mon Sep 17 00:00:00 2001 From: Christian Schoenebeck Date: Tue, 4 Oct 2022 22:53:33 +0200 Subject: [PATCH 067/705] tests/9p: merge v9fs_tversion() and do_version() As with previous patches, unify functions v9fs_tversion() and do_version() into a single function v9fs_tversion() by using a declarative function arguments approach. Signed-off-by: Christian Schoenebeck Message-Id: <2d253491aaffd267ec295f056dda47456692cd0c.1664917004.git.qemu_oss@crudebyte.com> --- tests/qtest/libqos/virtio-9p-client.c | 47 +++++++++++++++++++++++---- tests/qtest/libqos/virtio-9p-client.h | 25 ++++++++++++-- tests/qtest/virtio-9p-test.c | 23 +++---------- 3 files changed, 68 insertions(+), 27 deletions(-) diff --git a/tests/qtest/libqos/virtio-9p-client.c b/tests/qtest/libqos/virtio-9p-client.c index a95bbad9c8..e8364f8d64 100644 --- a/tests/qtest/libqos/virtio-9p-client.c +++ b/tests/qtest/libqos/virtio-9p-client.c @@ -291,21 +291,54 @@ void v9fs_rlerror(P9Req *req, uint32_t *err) } /* size[4] Tversion tag[2] msize[4] version[s] */ -P9Req *v9fs_tversion(QVirtio9P *v9p, uint32_t msize, const char *version, - uint16_t tag) +TVersionRes v9fs_tversion(TVersionOpt opt) { P9Req *req; + uint32_t err; uint32_t body_size = 4; - uint16_t string_size = v9fs_string_size(version); + uint16_t string_size; + uint16_t server_len; + g_autofree char *server_version = NULL; + g_assert(opt.client); + + if (!opt.msize) { + opt.msize = P9_MAX_SIZE; + } + + if (!opt.tag) { + opt.tag = P9_NOTAG; + } + + if (!opt.version) { + opt.version = "9P2000.L"; + } + + string_size = v9fs_string_size(opt.version); g_assert_cmpint(body_size, <=, UINT32_MAX - string_size); body_size += string_size; - req = v9fs_req_init(v9p, body_size, P9_TVERSION, tag); + req = v9fs_req_init(opt.client, body_size, P9_TVERSION, opt.tag); - v9fs_uint32_write(req, msize); - v9fs_string_write(req, version); + v9fs_uint32_write(req, opt.msize); + v9fs_string_write(req, opt.version); v9fs_req_send(req); - return req; + + if (!opt.requestOnly) { + v9fs_req_wait_for_reply(req, NULL); + if (opt.expectErr) { + v9fs_rlerror(req, &err); + g_assert_cmpint(err, ==, opt.expectErr); + } else { + v9fs_rversion(req, &server_len, &server_version); + g_assert_cmpmem(server_version, server_len, + opt.version, strlen(opt.version)); + } + req = NULL; /* request was freed */ + } + + return (TVersionRes) { + .req = req, + }; } /* size[4] Rversion tag[2] msize[4] version[s] */ diff --git a/tests/qtest/libqos/virtio-9p-client.h b/tests/qtest/libqos/virtio-9p-client.h index 8c6abbb173..fcde849b5d 100644 --- a/tests/qtest/libqos/virtio-9p-client.h +++ b/tests/qtest/libqos/virtio-9p-client.h @@ -106,6 +106,28 @@ typedef struct TWalkRes { P9Req *req; } TWalkRes; +/* options for 'Tversion' 9p request */ +typedef struct TVersionOpt { + /* 9P client being used (mandatory) */ + QVirtio9P *client; + /* user supplied tag number being returned with response (optional) */ + uint16_t tag; + /* maximum message size that can be handled by client (optional) */ + uint32_t msize; + /* protocol version (optional) */ + const char *version; + /* only send Tversion request but not wait for a reply? (optional) */ + bool requestOnly; + /* do we expect an Rlerror response, if yes which error code? (optional) */ + uint32_t expectErr; +} TVersionOpt; + +/* result of 'Tversion' 9p request */ +typedef struct TVersionRes { + /* if requestOnly was set: request object for further processing */ + P9Req *req; +} TVersionRes; + void v9fs_set_allocator(QGuestAllocator *t_alloc); void v9fs_memwrite(P9Req *req, const void *addr, size_t len); void v9fs_memskip(P9Req *req, size_t len); @@ -127,8 +149,7 @@ void v9fs_req_wait_for_reply(P9Req *req, uint32_t *len); void v9fs_req_recv(P9Req *req, uint8_t id); void v9fs_req_free(P9Req *req); void v9fs_rlerror(P9Req *req, uint32_t *err); -P9Req *v9fs_tversion(QVirtio9P *v9p, uint32_t msize, const char *version, - uint16_t tag); +TVersionRes v9fs_tversion(TVersionOpt); void v9fs_rversion(P9Req *req, uint16_t *len, char **version); P9Req *v9fs_tattach(QVirtio9P *v9p, uint32_t fid, uint32_t n_uname, uint16_t tag); diff --git a/tests/qtest/virtio-9p-test.c b/tests/qtest/virtio-9p-test.c index 3c326451b1..f2907c8026 100644 --- a/tests/qtest/virtio-9p-test.c +++ b/tests/qtest/virtio-9p-test.c @@ -17,6 +17,7 @@ #include "libqos/virtio-9p-client.h" #define twalk(...) v9fs_twalk((TWalkOpt) __VA_ARGS__) +#define tversion(...) v9fs_tversion((TVersionOpt) __VA_ARGS__) static void pci_config(void *obj, void *data, QGuestAllocator *t_alloc) { @@ -41,31 +42,17 @@ static inline bool is_same_qid(v9fs_qid a, v9fs_qid b) return a[0] == b[0] && memcmp(&a[5], &b[5], 8) == 0; } -static void do_version(QVirtio9P *v9p) -{ - const char *version = "9P2000.L"; - uint16_t server_len; - g_autofree char *server_version = NULL; - P9Req *req; - - req = v9fs_tversion(v9p, P9_MAX_SIZE, version, P9_NOTAG); - v9fs_req_wait_for_reply(req, NULL); - v9fs_rversion(req, &server_len, &server_version); - - g_assert_cmpmem(server_version, server_len, version, strlen(version)); -} - static void fs_version(void *obj, void *data, QGuestAllocator *t_alloc) { v9fs_set_allocator(t_alloc); - do_version(obj); + tversion({ .client = obj }); } static void do_attach_rqid(QVirtio9P *v9p, v9fs_qid *qid) { P9Req *req; - do_version(v9p); + tversion({ .client = v9p }); req = v9fs_tattach(v9p, 0, getuid(), 0); v9fs_req_wait_for_reply(req, NULL); v9fs_rattach(req, qid); @@ -328,7 +315,7 @@ static void fs_walk_none(void *obj, void *data, QGuestAllocator *t_alloc) P9Req *req; struct v9fs_attr attr; - do_version(v9p); + tversion({ .client = v9p }); req = v9fs_tattach(v9p, 0, getuid(), 0); v9fs_req_wait_for_reply(req, NULL); v9fs_rattach(req, &root_qid); @@ -357,7 +344,7 @@ static void fs_walk_dotdot(void *obj, void *data, QGuestAllocator *t_alloc) g_autofree v9fs_qid *wqid = NULL; P9Req *req; - do_version(v9p); + tversion({ .client = v9p }); req = v9fs_tattach(v9p, 0, getuid(), 0); v9fs_req_wait_for_reply(req, NULL); v9fs_rattach(req, &root_qid); From 74a160aba921a2ca37b026dbfcdd03386bc05e85 Mon Sep 17 00:00:00 2001 From: Christian Schoenebeck Date: Tue, 4 Oct 2022 22:53:36 +0200 Subject: [PATCH 068/705] tests/9p: merge v9fs_tattach(), do_attach(), do_attach_rqid() As with previous patches, unify those 3 functions into a single function v9fs_tattach() by using a declarative function arguments approach. Signed-off-by: Christian Schoenebeck Message-Id: --- tests/qtest/libqos/virtio-9p-client.c | 40 ++++++++++++++--- tests/qtest/libqos/virtio-9p-client.h | 30 ++++++++++++- tests/qtest/virtio-9p-test.c | 62 +++++++++++---------------- 3 files changed, 88 insertions(+), 44 deletions(-) diff --git a/tests/qtest/libqos/virtio-9p-client.c b/tests/qtest/libqos/virtio-9p-client.c index e8364f8d64..5e6bd6120c 100644 --- a/tests/qtest/libqos/virtio-9p-client.c +++ b/tests/qtest/libqos/virtio-9p-client.c @@ -359,20 +359,48 @@ void v9fs_rversion(P9Req *req, uint16_t *len, char **version) } /* size[4] Tattach tag[2] fid[4] afid[4] uname[s] aname[s] n_uname[4] */ -P9Req *v9fs_tattach(QVirtio9P *v9p, uint32_t fid, uint32_t n_uname, - uint16_t tag) +TAttachRes v9fs_tattach(TAttachOpt opt) { + uint32_t err; const char *uname = ""; /* ignored by QEMU */ const char *aname = ""; /* ignored by QEMU */ - P9Req *req = v9fs_req_init(v9p, 4 + 4 + 2 + 2 + 4, P9_TATTACH, tag); - v9fs_uint32_write(req, fid); + g_assert(opt.client); + /* expecting either Rattach or Rlerror, but obviously not both */ + g_assert(!opt.expectErr || !opt.rattach.qid); + + if (!opt.requestOnly) { + v9fs_tversion((TVersionOpt) { .client = opt.client }); + } + + if (!opt.n_uname) { + opt.n_uname = getuid(); + } + + P9Req *req = v9fs_req_init(opt.client, 4 + 4 + 2 + 2 + 4, P9_TATTACH, + opt.tag); + + v9fs_uint32_write(req, opt.fid); v9fs_uint32_write(req, P9_NOFID); v9fs_string_write(req, uname); v9fs_string_write(req, aname); - v9fs_uint32_write(req, n_uname); + v9fs_uint32_write(req, opt.n_uname); v9fs_req_send(req); - return req; + + if (!opt.requestOnly) { + v9fs_req_wait_for_reply(req, NULL); + if (opt.expectErr) { + v9fs_rlerror(req, &err); + g_assert_cmpint(err, ==, opt.expectErr); + } else { + v9fs_rattach(req, opt.rattach.qid); + } + req = NULL; /* request was freed */ + } + + return (TAttachRes) { + .req = req, + }; } /* size[4] Rattach tag[2] qid[13] */ diff --git a/tests/qtest/libqos/virtio-9p-client.h b/tests/qtest/libqos/virtio-9p-client.h index fcde849b5d..64b97b229b 100644 --- a/tests/qtest/libqos/virtio-9p-client.h +++ b/tests/qtest/libqos/virtio-9p-client.h @@ -128,6 +128,33 @@ typedef struct TVersionRes { P9Req *req; } TVersionRes; +/* options for 'Tattach' 9p request */ +typedef struct TAttachOpt { + /* 9P client being used (mandatory) */ + QVirtio9P *client; + /* user supplied tag number being returned with response (optional) */ + uint16_t tag; + /* file ID to be associated with root of file tree (optional) */ + uint32_t fid; + /* numerical uid of user being introduced to server (optional) */ + uint32_t n_uname; + /* data being received from 9p server as 'Rattach' response (optional) */ + struct { + /* server's idea of the root of the file tree */ + v9fs_qid *qid; + } rattach; + /* only send Tattach request but not wait for a reply? (optional) */ + bool requestOnly; + /* do we expect an Rlerror response, if yes which error code? (optional) */ + uint32_t expectErr; +} TAttachOpt; + +/* result of 'Tattach' 9p request */ +typedef struct TAttachRes { + /* if requestOnly was set: request object for further processing */ + P9Req *req; +} TAttachRes; + void v9fs_set_allocator(QGuestAllocator *t_alloc); void v9fs_memwrite(P9Req *req, const void *addr, size_t len); void v9fs_memskip(P9Req *req, size_t len); @@ -151,8 +178,7 @@ void v9fs_req_free(P9Req *req); void v9fs_rlerror(P9Req *req, uint32_t *err); TVersionRes v9fs_tversion(TVersionOpt); void v9fs_rversion(P9Req *req, uint16_t *len, char **version); -P9Req *v9fs_tattach(QVirtio9P *v9p, uint32_t fid, uint32_t n_uname, - uint16_t tag); +TAttachRes v9fs_tattach(TAttachOpt); void v9fs_rattach(P9Req *req, v9fs_qid *qid); TWalkRes v9fs_twalk(TWalkOpt opt); void v9fs_rwalk(P9Req *req, uint16_t *nwqid, v9fs_qid **wqid); diff --git a/tests/qtest/virtio-9p-test.c b/tests/qtest/virtio-9p-test.c index f2907c8026..271c42f6f9 100644 --- a/tests/qtest/virtio-9p-test.c +++ b/tests/qtest/virtio-9p-test.c @@ -18,6 +18,7 @@ #define twalk(...) v9fs_twalk((TWalkOpt) __VA_ARGS__) #define tversion(...) v9fs_tversion((TVersionOpt) __VA_ARGS__) +#define tattach(...) v9fs_tattach((TAttachOpt) __VA_ARGS__) static void pci_config(void *obj, void *data, QGuestAllocator *t_alloc) { @@ -48,25 +49,10 @@ static void fs_version(void *obj, void *data, QGuestAllocator *t_alloc) tversion({ .client = obj }); } -static void do_attach_rqid(QVirtio9P *v9p, v9fs_qid *qid) -{ - P9Req *req; - - tversion({ .client = v9p }); - req = v9fs_tattach(v9p, 0, getuid(), 0); - v9fs_req_wait_for_reply(req, NULL); - v9fs_rattach(req, qid); -} - -static void do_attach(QVirtio9P *v9p) -{ - do_attach_rqid(v9p, NULL); -} - static void fs_attach(void *obj, void *data, QGuestAllocator *t_alloc) { v9fs_set_allocator(t_alloc); - do_attach(obj); + tattach({ .client = obj }); } static void fs_walk(void *obj, void *data, QGuestAllocator *t_alloc) @@ -82,7 +68,7 @@ static void fs_walk(void *obj, void *data, QGuestAllocator *t_alloc) wnames[i] = g_strdup_printf(QTEST_V9FS_SYNTH_WALK_FILE, i); } - do_attach(v9p); + tattach({ .client = v9p }); twalk({ .client = v9p, .fid = 0, .newfid = 1, .nwname = P9_MAXWELEM, .wnames = wnames, @@ -118,7 +104,7 @@ static void fs_readdir(void *obj, void *data, QGuestAllocator *t_alloc) struct V9fsDirent *entries = NULL; P9Req *req; - do_attach(v9p); + tattach({ .client = v9p }); twalk({ .client = v9p, .fid = 0, .newfid = 1, .nwname = 1, .wnames = wnames, .rwalk.nwqid = &nqid @@ -173,7 +159,7 @@ static void do_readdir_split(QVirtio9P *v9p, uint32_t count) int fid; uint64_t offset; - do_attach(v9p); + tattach({ .client = v9p }); fid = 1; offset = 0; @@ -248,7 +234,7 @@ static void fs_walk_no_slash(void *obj, void *data, QGuestAllocator *t_alloc) v9fs_set_allocator(t_alloc); char *wnames[] = { g_strdup(" /") }; - do_attach(v9p); + tattach({ .client = v9p }); twalk({ .client = v9p, .fid = 0, .newfid = 1, .nwname = 1, .wnames = wnames, .expectErr = ENOENT @@ -262,7 +248,7 @@ static void fs_walk_nonexistent(void *obj, void *data, QGuestAllocator *t_alloc) QVirtio9P *v9p = obj; v9fs_set_allocator(t_alloc); - do_attach(v9p); + tattach({ .client = v9p }); /* * The 9p2000 protocol spec says: "If the first element cannot be walked * for any reason, Rerror is returned." @@ -284,7 +270,7 @@ static void fs_walk_2nd_nonexistent(void *obj, void *data, QTEST_V9FS_SYNTH_WALK_FILE "/non-existent", 0 ); - do_attach_rqid(v9p, &root_qid); + tattach({ .client = v9p, .rattach.qid = &root_qid }); fid = twalk({ .client = v9p, .path = path, .rwalk = { .nwqid = &nwqid, .wqid = &wqid } @@ -316,7 +302,9 @@ static void fs_walk_none(void *obj, void *data, QGuestAllocator *t_alloc) struct v9fs_attr attr; tversion({ .client = v9p }); - req = v9fs_tattach(v9p, 0, getuid(), 0); + req = tattach({ + .client = v9p, .fid = 0, .n_uname = getuid(), .requestOnly = true + }).req; v9fs_req_wait_for_reply(req, NULL); v9fs_rattach(req, &root_qid); @@ -345,7 +333,9 @@ static void fs_walk_dotdot(void *obj, void *data, QGuestAllocator *t_alloc) P9Req *req; tversion({ .client = v9p }); - req = v9fs_tattach(v9p, 0, getuid(), 0); + req = tattach((TAttachOpt) { + .client = v9p, .fid = 0, .n_uname = getuid(), .requestOnly = true + }).req; v9fs_req_wait_for_reply(req, NULL); v9fs_rattach(req, &root_qid); @@ -366,7 +356,7 @@ static void fs_lopen(void *obj, void *data, QGuestAllocator *t_alloc) char *wnames[] = { g_strdup(QTEST_V9FS_SYNTH_LOPEN_FILE) }; P9Req *req; - do_attach(v9p); + tattach({ .client = v9p }); twalk({ .client = v9p, .fid = 0, .newfid = 1, .nwname = 1, .wnames = wnames }); @@ -388,7 +378,7 @@ static void fs_write(void *obj, void *data, QGuestAllocator *t_alloc) uint32_t count; P9Req *req; - do_attach(v9p); + tattach({ .client = v9p }); twalk({ .client = v9p, .fid = 0, .newfid = 1, .nwname = 1, .wnames = wnames }); @@ -414,7 +404,7 @@ static void fs_flush_success(void *obj, void *data, QGuestAllocator *t_alloc) uint32_t reply_len; uint8_t should_block; - do_attach(v9p); + tattach({ .client = v9p }); twalk({ .client = v9p, .fid = 0, .newfid = 1, .nwname = 1, .wnames = wnames }); @@ -451,7 +441,7 @@ static void fs_flush_ignored(void *obj, void *data, QGuestAllocator *t_alloc) uint32_t count; uint8_t should_block; - do_attach(v9p); + tattach({ .client = v9p }); twalk({ .client = v9p, .fid = 0, .newfid = 1, .nwname = 1, .wnames = wnames }); @@ -588,7 +578,7 @@ static void fs_create_dir(void *obj, void *data, QGuestAllocator *t_alloc) g_assert(root_path != NULL); - do_attach(v9p); + tattach({ .client = v9p }); do_mkdir(v9p, "/", "01"); /* check if created directory really exists now ... */ @@ -607,7 +597,7 @@ static void fs_unlinkat_dir(void *obj, void *data, QGuestAllocator *t_alloc) g_assert(root_path != NULL); - do_attach(v9p); + tattach({ .client = v9p }); do_mkdir(v9p, "/", "02"); /* check if created directory really exists now ... */ @@ -627,7 +617,7 @@ static void fs_create_file(void *obj, void *data, QGuestAllocator *t_alloc) struct stat st; g_autofree char *new_file = virtio_9p_test_path("03/1st_file"); - do_attach(v9p); + tattach({ .client = v9p }); do_mkdir(v9p, "/", "03"); do_lcreate(v9p, "03", "1st_file"); @@ -644,7 +634,7 @@ static void fs_unlinkat_file(void *obj, void *data, QGuestAllocator *t_alloc) struct stat st; g_autofree char *new_file = virtio_9p_test_path("04/doa_file"); - do_attach(v9p); + tattach({ .client = v9p }); do_mkdir(v9p, "/", "04"); do_lcreate(v9p, "04", "doa_file"); @@ -666,7 +656,7 @@ static void fs_symlink_file(void *obj, void *data, QGuestAllocator *t_alloc) g_autofree char *real_file = virtio_9p_test_path("05/real_file"); g_autofree char *symlink_file = virtio_9p_test_path("05/symlink_file"); - do_attach(v9p); + tattach({ .client = v9p }); do_mkdir(v9p, "/", "05"); do_lcreate(v9p, "05", "real_file"); g_assert(stat(real_file, &st) == 0); @@ -687,7 +677,7 @@ static void fs_unlinkat_symlink(void *obj, void *data, g_autofree char *real_file = virtio_9p_test_path("06/real_file"); g_autofree char *symlink_file = virtio_9p_test_path("06/symlink_file"); - do_attach(v9p); + tattach({ .client = v9p }); do_mkdir(v9p, "/", "06"); do_lcreate(v9p, "06", "real_file"); g_assert(stat(real_file, &st) == 0); @@ -709,7 +699,7 @@ static void fs_hardlink_file(void *obj, void *data, QGuestAllocator *t_alloc) g_autofree char *real_file = virtio_9p_test_path("07/real_file"); g_autofree char *hardlink_file = virtio_9p_test_path("07/hardlink_file"); - do_attach(v9p); + tattach({ .client = v9p }); do_mkdir(v9p, "/", "07"); do_lcreate(v9p, "07", "real_file"); g_assert(stat(real_file, &st_real) == 0); @@ -734,7 +724,7 @@ static void fs_unlinkat_hardlink(void *obj, void *data, g_autofree char *real_file = virtio_9p_test_path("08/real_file"); g_autofree char *hardlink_file = virtio_9p_test_path("08/hardlink_file"); - do_attach(v9p); + tattach({ .client = v9p }); do_mkdir(v9p, "/", "08"); do_lcreate(v9p, "08", "real_file"); g_assert(stat(real_file, &st_real) == 0); From 1125ddf66f47dc4986d97948253890fdb3c0a6d6 Mon Sep 17 00:00:00 2001 From: Christian Schoenebeck Date: Tue, 4 Oct 2022 22:53:38 +0200 Subject: [PATCH 069/705] tests/9p: simplify callers of tattach() Now as tattach() is using a declarative approach, simplify the code of callers of this function. Signed-off-by: Christian Schoenebeck Message-Id: <9b50e5b89a0072e84a9191d18c19a53546a28bba.1664917004.git.qemu_oss@crudebyte.com> --- tests/qtest/virtio-9p-test.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/tests/qtest/virtio-9p-test.c b/tests/qtest/virtio-9p-test.c index 271c42f6f9..46bb189b81 100644 --- a/tests/qtest/virtio-9p-test.c +++ b/tests/qtest/virtio-9p-test.c @@ -302,11 +302,10 @@ static void fs_walk_none(void *obj, void *data, QGuestAllocator *t_alloc) struct v9fs_attr attr; tversion({ .client = v9p }); - req = tattach({ - .client = v9p, .fid = 0, .n_uname = getuid(), .requestOnly = true - }).req; - v9fs_req_wait_for_reply(req, NULL); - v9fs_rattach(req, &root_qid); + tattach({ + .client = v9p, .fid = 0, .n_uname = getuid(), + .rattach.qid = &root_qid + }); twalk({ .client = v9p, .fid = 0, .newfid = 1, .nwname = 0, .wnames = NULL, @@ -330,14 +329,12 @@ static void fs_walk_dotdot(void *obj, void *data, QGuestAllocator *t_alloc) char *wnames[] = { g_strdup("..") }; v9fs_qid root_qid; g_autofree v9fs_qid *wqid = NULL; - P9Req *req; tversion({ .client = v9p }); - req = tattach((TAttachOpt) { - .client = v9p, .fid = 0, .n_uname = getuid(), .requestOnly = true - }).req; - v9fs_req_wait_for_reply(req, NULL); - v9fs_rattach(req, &root_qid); + tattach({ + .client = v9p, .fid = 0, .n_uname = getuid(), + .rattach.qid = &root_qid + }); twalk({ .client = v9p, .fid = 0, .newfid = 1, .nwname = 1, .wnames = wnames, From 2af5be47b9ba264f31f5594e587207cd854e01cc Mon Sep 17 00:00:00 2001 From: Christian Schoenebeck Date: Tue, 4 Oct 2022 22:53:41 +0200 Subject: [PATCH 070/705] tests/9p: convert v9fs_tgetattr() to declarative arguments Use declarative function arguments for function v9fs_tgetattr(). Signed-off-by: Christian Schoenebeck Message-Id: --- tests/qtest/libqos/virtio-9p-client.c | 32 ++++++++++++++++++++++----- tests/qtest/libqos/virtio-9p-client.h | 30 +++++++++++++++++++++++-- tests/qtest/virtio-9p-test.c | 11 +++++++-- 3 files changed, 63 insertions(+), 10 deletions(-) diff --git a/tests/qtest/libqos/virtio-9p-client.c b/tests/qtest/libqos/virtio-9p-client.c index 5e6bd6120c..29916a23b5 100644 --- a/tests/qtest/libqos/virtio-9p-client.c +++ b/tests/qtest/libqos/virtio-9p-client.c @@ -489,16 +489,36 @@ void v9fs_rwalk(P9Req *req, uint16_t *nwqid, v9fs_qid **wqid) } /* size[4] Tgetattr tag[2] fid[4] request_mask[8] */ -P9Req *v9fs_tgetattr(QVirtio9P *v9p, uint32_t fid, uint64_t request_mask, - uint16_t tag) +TGetAttrRes v9fs_tgetattr(TGetAttrOpt opt) { P9Req *req; + uint32_t err; - req = v9fs_req_init(v9p, 4 + 8, P9_TGETATTR, tag); - v9fs_uint32_write(req, fid); - v9fs_uint64_write(req, request_mask); + g_assert(opt.client); + /* expecting either Rgetattr or Rlerror, but obviously not both */ + g_assert(!opt.expectErr || !opt.rgetattr.attr); + + if (!opt.request_mask) { + opt.request_mask = P9_GETATTR_ALL; + } + + req = v9fs_req_init(opt.client, 4 + 8, P9_TGETATTR, opt.tag); + v9fs_uint32_write(req, opt.fid); + v9fs_uint64_write(req, opt.request_mask); v9fs_req_send(req); - return req; + + if (!opt.requestOnly) { + v9fs_req_wait_for_reply(req, NULL); + if (opt.expectErr) { + v9fs_rlerror(req, &err); + g_assert_cmpint(err, ==, opt.expectErr); + } else { + v9fs_rgetattr(req, opt.rgetattr.attr); + } + req = NULL; /* request was freed */ + } + + return (TGetAttrRes) { .req = req }; } /* diff --git a/tests/qtest/libqos/virtio-9p-client.h b/tests/qtest/libqos/virtio-9p-client.h index 64b97b229b..f7b1bfc79a 100644 --- a/tests/qtest/libqos/virtio-9p-client.h +++ b/tests/qtest/libqos/virtio-9p-client.h @@ -63,6 +63,7 @@ typedef struct v9fs_attr { } v9fs_attr; #define P9_GETATTR_BASIC 0x000007ffULL /* Mask for fields up to BLOCKS */ +#define P9_GETATTR_ALL 0x00003fffULL /* Mask for ALL fields */ struct V9fsDirent { v9fs_qid qid; @@ -155,6 +156,32 @@ typedef struct TAttachRes { P9Req *req; } TAttachRes; +/* options for 'Tgetattr' 9p request */ +typedef struct TGetAttrOpt { + /* 9P client being used (mandatory) */ + QVirtio9P *client; + /* user supplied tag number being returned with response (optional) */ + uint16_t tag; + /* file ID of file/dir whose attributes shall be retrieved (required) */ + uint32_t fid; + /* bitmask indicating attribute fields to be retrieved (optional) */ + uint64_t request_mask; + /* data being received from 9p server as 'Rgetattr' response (optional) */ + struct { + v9fs_attr *attr; + } rgetattr; + /* only send Tgetattr request but not wait for a reply? (optional) */ + bool requestOnly; + /* do we expect an Rlerror response, if yes which error code? (optional) */ + uint32_t expectErr; +} TGetAttrOpt; + +/* result of 'Tgetattr' 9p request */ +typedef struct TGetAttrRes { + /* if requestOnly was set: request object for further processing */ + P9Req *req; +} TGetAttrRes; + void v9fs_set_allocator(QGuestAllocator *t_alloc); void v9fs_memwrite(P9Req *req, const void *addr, size_t len); void v9fs_memskip(P9Req *req, size_t len); @@ -182,8 +209,7 @@ TAttachRes v9fs_tattach(TAttachOpt); void v9fs_rattach(P9Req *req, v9fs_qid *qid); TWalkRes v9fs_twalk(TWalkOpt opt); void v9fs_rwalk(P9Req *req, uint16_t *nwqid, v9fs_qid **wqid); -P9Req *v9fs_tgetattr(QVirtio9P *v9p, uint32_t fid, uint64_t request_mask, - uint16_t tag); +TGetAttrRes v9fs_tgetattr(TGetAttrOpt); void v9fs_rgetattr(P9Req *req, v9fs_attr *attr); P9Req *v9fs_treaddir(QVirtio9P *v9p, uint32_t fid, uint64_t offset, uint32_t count, uint16_t tag); diff --git a/tests/qtest/virtio-9p-test.c b/tests/qtest/virtio-9p-test.c index 46bb189b81..9c1219db33 100644 --- a/tests/qtest/virtio-9p-test.c +++ b/tests/qtest/virtio-9p-test.c @@ -19,6 +19,7 @@ #define twalk(...) v9fs_twalk((TWalkOpt) __VA_ARGS__) #define tversion(...) v9fs_tversion((TVersionOpt) __VA_ARGS__) #define tattach(...) v9fs_tattach((TAttachOpt) __VA_ARGS__) +#define tgetattr(...) v9fs_tgetattr((TGetAttrOpt) __VA_ARGS__) static void pci_config(void *obj, void *data, QGuestAllocator *t_alloc) { @@ -285,7 +286,10 @@ static void fs_walk_2nd_nonexistent(void *obj, void *data, g_assert(wqid && wqid[0] && !is_same_qid(root_qid, wqid[0])); /* expect fid being unaffected by walk above */ - req = v9fs_tgetattr(v9p, fid, P9_GETATTR_BASIC, 0); + req = tgetattr({ + .client = v9p, .fid = fid, .request_mask = P9_GETATTR_BASIC, + .requestOnly = true + }).req; v9fs_req_wait_for_reply(req, NULL); v9fs_rlerror(req, &err); @@ -315,7 +319,10 @@ static void fs_walk_none(void *obj, void *data, QGuestAllocator *t_alloc) /* special case: no QID is returned if nwname=0 was sent */ g_assert(wqid == NULL); - req = v9fs_tgetattr(v9p, 1, P9_GETATTR_BASIC, 0); + req = tgetattr({ + .client = v9p, .fid = 1, .request_mask = P9_GETATTR_BASIC, + .requestOnly = true + }).req; v9fs_req_wait_for_reply(req, NULL); v9fs_rgetattr(req, &attr); From 28c736709b82c8f47edf3cb18b9fb601fdab9151 Mon Sep 17 00:00:00 2001 From: Christian Schoenebeck Date: Tue, 4 Oct 2022 22:53:44 +0200 Subject: [PATCH 071/705] tests/9p: simplify callers of tgetattr() Now as tgetattr() is using a declarative approach, simplify the code of callers of this function. Signed-off-by: Christian Schoenebeck Message-Id: <60c6a083f320b86f3172951445df7bbc895932e2.1664917004.git.qemu_oss@crudebyte.com> --- tests/qtest/virtio-9p-test.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/tests/qtest/virtio-9p-test.c b/tests/qtest/virtio-9p-test.c index 9c1219db33..ae1220d0cb 100644 --- a/tests/qtest/virtio-9p-test.c +++ b/tests/qtest/virtio-9p-test.c @@ -264,8 +264,7 @@ static void fs_walk_2nd_nonexistent(void *obj, void *data, v9fs_set_allocator(t_alloc); v9fs_qid root_qid; uint16_t nwqid; - uint32_t fid, err; - P9Req *req; + uint32_t fid; g_autofree v9fs_qid *wqid = NULL; g_autofree char *path = g_strdup_printf( QTEST_V9FS_SYNTH_WALK_FILE "/non-existent", 0 @@ -286,14 +285,10 @@ static void fs_walk_2nd_nonexistent(void *obj, void *data, g_assert(wqid && wqid[0] && !is_same_qid(root_qid, wqid[0])); /* expect fid being unaffected by walk above */ - req = tgetattr({ + tgetattr({ .client = v9p, .fid = fid, .request_mask = P9_GETATTR_BASIC, - .requestOnly = true - }).req; - v9fs_req_wait_for_reply(req, NULL); - v9fs_rlerror(req, &err); - - g_assert_cmpint(err, ==, ENOENT); + .expectErr = ENOENT + }); } static void fs_walk_none(void *obj, void *data, QGuestAllocator *t_alloc) @@ -302,7 +297,6 @@ static void fs_walk_none(void *obj, void *data, QGuestAllocator *t_alloc) v9fs_set_allocator(t_alloc); v9fs_qid root_qid; g_autofree v9fs_qid *wqid = NULL; - P9Req *req; struct v9fs_attr attr; tversion({ .client = v9p }); @@ -319,12 +313,10 @@ static void fs_walk_none(void *obj, void *data, QGuestAllocator *t_alloc) /* special case: no QID is returned if nwname=0 was sent */ g_assert(wqid == NULL); - req = tgetattr({ + tgetattr({ .client = v9p, .fid = 1, .request_mask = P9_GETATTR_BASIC, - .requestOnly = true - }).req; - v9fs_req_wait_for_reply(req, NULL); - v9fs_rgetattr(req, &attr); + .rgetattr.attr = &attr + }); g_assert(is_same_qid(root_qid, attr.qid)); } From 1ebacc40ca925626cf601543326066434c7c1a7f Mon Sep 17 00:00:00 2001 From: Christian Schoenebeck Date: Tue, 4 Oct 2022 22:53:47 +0200 Subject: [PATCH 072/705] tests/9p: convert v9fs_treaddir() to declarative arguments Use declarative function arguments for function v9fs_treaddir(). Signed-off-by: Christian Schoenebeck Message-Id: --- tests/qtest/libqos/virtio-9p-client.c | 32 ++++++++++++++++++++------ tests/qtest/libqos/virtio-9p-client.h | 33 +++++++++++++++++++++++++-- tests/qtest/virtio-9p-test.c | 11 +++++++-- 3 files changed, 65 insertions(+), 11 deletions(-) diff --git a/tests/qtest/libqos/virtio-9p-client.c b/tests/qtest/libqos/virtio-9p-client.c index 29916a23b5..047c8993b6 100644 --- a/tests/qtest/libqos/virtio-9p-client.c +++ b/tests/qtest/libqos/virtio-9p-client.c @@ -557,17 +557,35 @@ void v9fs_rgetattr(P9Req *req, v9fs_attr *attr) } /* size[4] Treaddir tag[2] fid[4] offset[8] count[4] */ -P9Req *v9fs_treaddir(QVirtio9P *v9p, uint32_t fid, uint64_t offset, - uint32_t count, uint16_t tag) +TReadDirRes v9fs_treaddir(TReadDirOpt opt) { P9Req *req; + uint32_t err; - req = v9fs_req_init(v9p, 4 + 8 + 4, P9_TREADDIR, tag); - v9fs_uint32_write(req, fid); - v9fs_uint64_write(req, offset); - v9fs_uint32_write(req, count); + g_assert(opt.client); + /* expecting either Rreaddir or Rlerror, but obviously not both */ + g_assert(!opt.expectErr || !(opt.rreaddir.count || + opt.rreaddir.nentries || opt.rreaddir.entries)); + + req = v9fs_req_init(opt.client, 4 + 8 + 4, P9_TREADDIR, opt.tag); + v9fs_uint32_write(req, opt.fid); + v9fs_uint64_write(req, opt.offset); + v9fs_uint32_write(req, opt.count); v9fs_req_send(req); - return req; + + if (!opt.requestOnly) { + v9fs_req_wait_for_reply(req, NULL); + if (opt.expectErr) { + v9fs_rlerror(req, &err); + g_assert_cmpint(err, ==, opt.expectErr); + } else { + v9fs_rreaddir(req, opt.rreaddir.count, opt.rreaddir.nentries, + opt.rreaddir.entries); + } + req = NULL; /* request was freed */ + } + + return (TReadDirRes) { .req = req }; } /* size[4] Rreaddir tag[2] count[4] data[count] */ diff --git a/tests/qtest/libqos/virtio-9p-client.h b/tests/qtest/libqos/virtio-9p-client.h index f7b1bfc79a..2bf649085f 100644 --- a/tests/qtest/libqos/virtio-9p-client.h +++ b/tests/qtest/libqos/virtio-9p-client.h @@ -182,6 +182,36 @@ typedef struct TGetAttrRes { P9Req *req; } TGetAttrRes; +/* options for 'Treaddir' 9p request */ +typedef struct TReadDirOpt { + /* 9P client being used (mandatory) */ + QVirtio9P *client; + /* user supplied tag number being returned with response (optional) */ + uint16_t tag; + /* file ID of directory whose entries shall be retrieved (required) */ + uint32_t fid; + /* offset in entries stream, i.e. for multiple requests (optional) */ + uint64_t offset; + /* maximum bytes to be returned by server (required) */ + uint32_t count; + /* data being received from 9p server as 'Rreaddir' response (optional) */ + struct { + uint32_t *count; + uint32_t *nentries; + struct V9fsDirent **entries; + } rreaddir; + /* only send Treaddir request but not wait for a reply? (optional) */ + bool requestOnly; + /* do we expect an Rlerror response, if yes which error code? (optional) */ + uint32_t expectErr; +} TReadDirOpt; + +/* result of 'Treaddir' 9p request */ +typedef struct TReadDirRes { + /* if requestOnly was set: request object for further processing */ + P9Req *req; +} TReadDirRes; + void v9fs_set_allocator(QGuestAllocator *t_alloc); void v9fs_memwrite(P9Req *req, const void *addr, size_t len); void v9fs_memskip(P9Req *req, size_t len); @@ -211,8 +241,7 @@ TWalkRes v9fs_twalk(TWalkOpt opt); void v9fs_rwalk(P9Req *req, uint16_t *nwqid, v9fs_qid **wqid); TGetAttrRes v9fs_tgetattr(TGetAttrOpt); void v9fs_rgetattr(P9Req *req, v9fs_attr *attr); -P9Req *v9fs_treaddir(QVirtio9P *v9p, uint32_t fid, uint64_t offset, - uint32_t count, uint16_t tag); +TReadDirRes v9fs_treaddir(TReadDirOpt); void v9fs_rreaddir(P9Req *req, uint32_t *count, uint32_t *nentries, struct V9fsDirent **entries); void v9fs_free_dirents(struct V9fsDirent *e); diff --git a/tests/qtest/virtio-9p-test.c b/tests/qtest/virtio-9p-test.c index ae1220d0cb..e5c174c218 100644 --- a/tests/qtest/virtio-9p-test.c +++ b/tests/qtest/virtio-9p-test.c @@ -20,6 +20,7 @@ #define tversion(...) v9fs_tversion((TVersionOpt) __VA_ARGS__) #define tattach(...) v9fs_tattach((TAttachOpt) __VA_ARGS__) #define tgetattr(...) v9fs_tgetattr((TGetAttrOpt) __VA_ARGS__) +#define treaddir(...) v9fs_treaddir((TReadDirOpt) __VA_ARGS__) static void pci_config(void *obj, void *data, QGuestAllocator *t_alloc) { @@ -119,7 +120,10 @@ static void fs_readdir(void *obj, void *data, QGuestAllocator *t_alloc) /* * submit count = msize - 11, because 11 is the header size of Rreaddir */ - req = v9fs_treaddir(v9p, 1, 0, P9_MAX_SIZE - 11, 0); + req = treaddir({ + .client = v9p, .fid = 1, .offset = 0, .count = P9_MAX_SIZE - 11, + .requestOnly = true + }).req; v9fs_req_wait_for_reply(req, NULL); v9fs_rreaddir(req, &count, &nentries, &entries); @@ -186,7 +190,10 @@ static void do_readdir_split(QVirtio9P *v9p, uint32_t count) npartialentries = 0; partialentries = NULL; - req = v9fs_treaddir(v9p, fid, offset, count, 0); + req = treaddir({ + .client = v9p, .fid = fid, .offset = offset, .count = count, + .requestOnly = true + }).req; v9fs_req_wait_for_reply(req, NULL); v9fs_rreaddir(req, &count, &npartialentries, &partialentries); if (npartialentries > 0 && partialentries) { From a9a53769318503c4d8884e642e00603ea6885cb1 Mon Sep 17 00:00:00 2001 From: Christian Schoenebeck Date: Tue, 4 Oct 2022 22:53:49 +0200 Subject: [PATCH 073/705] tests/9p: simplify callers of treaddir() Now as treaddir() is using a declarative approach, simplify the code of callers of this function. Signed-off-by: Christian Schoenebeck Message-Id: <7cec6f2c7011a481806c34908893b7282702a7a6.1664917004.git.qemu_oss@crudebyte.com> --- tests/qtest/virtio-9p-test.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/tests/qtest/virtio-9p-test.c b/tests/qtest/virtio-9p-test.c index e5c174c218..99e24fce0b 100644 --- a/tests/qtest/virtio-9p-test.c +++ b/tests/qtest/virtio-9p-test.c @@ -120,12 +120,12 @@ static void fs_readdir(void *obj, void *data, QGuestAllocator *t_alloc) /* * submit count = msize - 11, because 11 is the header size of Rreaddir */ - req = treaddir({ + treaddir({ .client = v9p, .fid = 1, .offset = 0, .count = P9_MAX_SIZE - 11, - .requestOnly = true - }).req; - v9fs_req_wait_for_reply(req, NULL); - v9fs_rreaddir(req, &count, &nentries, &entries); + .rreaddir = { + .count = &count, .nentries = &nentries, .entries = &entries + } + }); /* * Assuming msize (P9_MAX_SIZE) is large enough so we can retrieve all @@ -190,12 +190,13 @@ static void do_readdir_split(QVirtio9P *v9p, uint32_t count) npartialentries = 0; partialentries = NULL; - req = treaddir({ + treaddir({ .client = v9p, .fid = fid, .offset = offset, .count = count, - .requestOnly = true - }).req; - v9fs_req_wait_for_reply(req, NULL); - v9fs_rreaddir(req, &count, &npartialentries, &partialentries); + .rreaddir = { + .count = &count, .nentries = &npartialentries, + .entries = &partialentries + } + }); if (npartialentries > 0 && partialentries) { if (!entries) { entries = partialentries; From 3878ce4cc2f1cb9e802076c827834c34d3788b78 Mon Sep 17 00:00:00 2001 From: Christian Schoenebeck Date: Tue, 4 Oct 2022 22:53:52 +0200 Subject: [PATCH 074/705] tests/9p: convert v9fs_tlopen() to declarative arguments Use declarative function arguments for function v9fs_tlopen(). Signed-off-by: Christian Schoenebeck Message-Id: <765ab515353c56f88f0a163631f626a44e9565d6.1664917004.git.qemu_oss@crudebyte.com> --- tests/qtest/libqos/virtio-9p-client.c | 28 +++++++++++++++++++------ tests/qtest/libqos/virtio-9p-client.h | 30 +++++++++++++++++++++++++-- tests/qtest/virtio-9p-test.c | 25 ++++++++++++++++------ 3 files changed, 69 insertions(+), 14 deletions(-) diff --git a/tests/qtest/libqos/virtio-9p-client.c b/tests/qtest/libqos/virtio-9p-client.c index 047c8993b6..15fde54d63 100644 --- a/tests/qtest/libqos/virtio-9p-client.c +++ b/tests/qtest/libqos/virtio-9p-client.c @@ -643,16 +643,32 @@ void v9fs_free_dirents(struct V9fsDirent *e) } /* size[4] Tlopen tag[2] fid[4] flags[4] */ -P9Req *v9fs_tlopen(QVirtio9P *v9p, uint32_t fid, uint32_t flags, - uint16_t tag) +TLOpenRes v9fs_tlopen(TLOpenOpt opt) { P9Req *req; + uint32_t err; - req = v9fs_req_init(v9p, 4 + 4, P9_TLOPEN, tag); - v9fs_uint32_write(req, fid); - v9fs_uint32_write(req, flags); + g_assert(opt.client); + /* expecting either Rlopen or Rlerror, but obviously not both */ + g_assert(!opt.expectErr || !(opt.rlopen.qid || opt.rlopen.iounit)); + + req = v9fs_req_init(opt.client, 4 + 4, P9_TLOPEN, opt.tag); + v9fs_uint32_write(req, opt.fid); + v9fs_uint32_write(req, opt.flags); v9fs_req_send(req); - return req; + + if (!opt.requestOnly) { + v9fs_req_wait_for_reply(req, NULL); + if (opt.expectErr) { + v9fs_rlerror(req, &err); + g_assert_cmpint(err, ==, opt.expectErr); + } else { + v9fs_rlopen(req, opt.rlopen.qid, opt.rlopen.iounit); + } + req = NULL; /* request was freed */ + } + + return (TLOpenRes) { .req = req }; } /* size[4] Rlopen tag[2] qid[13] iounit[4] */ diff --git a/tests/qtest/libqos/virtio-9p-client.h b/tests/qtest/libqos/virtio-9p-client.h index 2bf649085f..3b70aef51e 100644 --- a/tests/qtest/libqos/virtio-9p-client.h +++ b/tests/qtest/libqos/virtio-9p-client.h @@ -212,6 +212,33 @@ typedef struct TReadDirRes { P9Req *req; } TReadDirRes; +/* options for 'Tlopen' 9p request */ +typedef struct TLOpenOpt { + /* 9P client being used (mandatory) */ + QVirtio9P *client; + /* user supplied tag number being returned with response (optional) */ + uint16_t tag; + /* file ID of file / directory to be opened (required) */ + uint32_t fid; + /* Linux open(2) flags such as O_RDONLY, O_RDWR, O_WRONLY (optional) */ + uint32_t flags; + /* data being received from 9p server as 'Rlopen' response (optional) */ + struct { + v9fs_qid *qid; + uint32_t *iounit; + } rlopen; + /* only send Tlopen request but not wait for a reply? (optional) */ + bool requestOnly; + /* do we expect an Rlerror response, if yes which error code? (optional) */ + uint32_t expectErr; +} TLOpenOpt; + +/* result of 'Tlopen' 9p request */ +typedef struct TLOpenRes { + /* if requestOnly was set: request object for further processing */ + P9Req *req; +} TLOpenRes; + void v9fs_set_allocator(QGuestAllocator *t_alloc); void v9fs_memwrite(P9Req *req, const void *addr, size_t len); void v9fs_memskip(P9Req *req, size_t len); @@ -245,8 +272,7 @@ TReadDirRes v9fs_treaddir(TReadDirOpt); void v9fs_rreaddir(P9Req *req, uint32_t *count, uint32_t *nentries, struct V9fsDirent **entries); void v9fs_free_dirents(struct V9fsDirent *e); -P9Req *v9fs_tlopen(QVirtio9P *v9p, uint32_t fid, uint32_t flags, - uint16_t tag); +TLOpenRes v9fs_tlopen(TLOpenOpt); void v9fs_rlopen(P9Req *req, v9fs_qid *qid, uint32_t *iounit); P9Req *v9fs_twrite(QVirtio9P *v9p, uint32_t fid, uint64_t offset, uint32_t count, const void *data, uint16_t tag); diff --git a/tests/qtest/virtio-9p-test.c b/tests/qtest/virtio-9p-test.c index 99e24fce0b..0455c3a094 100644 --- a/tests/qtest/virtio-9p-test.c +++ b/tests/qtest/virtio-9p-test.c @@ -21,6 +21,7 @@ #define tattach(...) v9fs_tattach((TAttachOpt) __VA_ARGS__) #define tgetattr(...) v9fs_tgetattr((TGetAttrOpt) __VA_ARGS__) #define treaddir(...) v9fs_treaddir((TReadDirOpt) __VA_ARGS__) +#define tlopen(...) v9fs_tlopen((TLOpenOpt) __VA_ARGS__) static void pci_config(void *obj, void *data, QGuestAllocator *t_alloc) { @@ -113,7 +114,9 @@ static void fs_readdir(void *obj, void *data, QGuestAllocator *t_alloc) }); g_assert_cmpint(nqid, ==, 1); - req = v9fs_tlopen(v9p, 1, O_DIRECTORY, 0); + req = tlopen({ + .client = v9p, .fid = 1, .flags = O_DIRECTORY, .requestOnly = true + }).req; v9fs_req_wait_for_reply(req, NULL); v9fs_rlopen(req, &qid, NULL); @@ -178,7 +181,9 @@ static void do_readdir_split(QVirtio9P *v9p, uint32_t count) }); g_assert_cmpint(nqid, ==, 1); - req = v9fs_tlopen(v9p, fid, O_DIRECTORY, 0); + req = tlopen({ + .client = v9p, .fid = fid, .flags = O_DIRECTORY, .requestOnly = true + }).req; v9fs_req_wait_for_reply(req, NULL); v9fs_rlopen(req, &qid, NULL); @@ -365,7 +370,9 @@ static void fs_lopen(void *obj, void *data, QGuestAllocator *t_alloc) .client = v9p, .fid = 0, .newfid = 1, .nwname = 1, .wnames = wnames }); - req = v9fs_tlopen(v9p, 1, O_WRONLY, 0); + req = tlopen({ + .client = v9p, .fid = 1, .flags = O_WRONLY, .requestOnly = true + }).req; v9fs_req_wait_for_reply(req, NULL); v9fs_rlopen(req, NULL, NULL); @@ -387,7 +394,9 @@ static void fs_write(void *obj, void *data, QGuestAllocator *t_alloc) .client = v9p, .fid = 0, .newfid = 1, .nwname = 1, .wnames = wnames }); - req = v9fs_tlopen(v9p, 1, O_WRONLY, 0); + req = tlopen({ + .client = v9p, .fid = 1, .flags = O_WRONLY, .requestOnly = true + }).req; v9fs_req_wait_for_reply(req, NULL); v9fs_rlopen(req, NULL, NULL); @@ -413,7 +422,9 @@ static void fs_flush_success(void *obj, void *data, QGuestAllocator *t_alloc) .client = v9p, .fid = 0, .newfid = 1, .nwname = 1, .wnames = wnames }); - req = v9fs_tlopen(v9p, 1, O_WRONLY, 0); + req = tlopen({ + .client = v9p, .fid = 1, .flags = O_WRONLY, .requestOnly = true + }).req; v9fs_req_wait_for_reply(req, NULL); v9fs_rlopen(req, NULL, NULL); @@ -450,7 +461,9 @@ static void fs_flush_ignored(void *obj, void *data, QGuestAllocator *t_alloc) .client = v9p, .fid = 0, .newfid = 1, .nwname = 1, .wnames = wnames }); - req = v9fs_tlopen(v9p, 1, O_WRONLY, 0); + req = tlopen({ + .client = v9p, .fid = 1, .flags = O_WRONLY, .requestOnly = true + }).req; v9fs_req_wait_for_reply(req, NULL); v9fs_rlopen(req, NULL, NULL); From 0e4c4ff02aecaa3cea3e583d07509378b7783307 Mon Sep 17 00:00:00 2001 From: Christian Schoenebeck Date: Tue, 4 Oct 2022 22:53:55 +0200 Subject: [PATCH 075/705] tests/9p: simplify callers of tlopen() Now as tlopen() is using a declarative approach, simplify the code of callers of this function. Signed-off-by: Christian Schoenebeck Message-Id: --- tests/qtest/virtio-9p-test.c | 43 +++++++++--------------------------- 1 file changed, 10 insertions(+), 33 deletions(-) diff --git a/tests/qtest/virtio-9p-test.c b/tests/qtest/virtio-9p-test.c index 0455c3a094..60a030b877 100644 --- a/tests/qtest/virtio-9p-test.c +++ b/tests/qtest/virtio-9p-test.c @@ -105,7 +105,6 @@ static void fs_readdir(void *obj, void *data, QGuestAllocator *t_alloc) v9fs_qid qid; uint32_t count, nentries; struct V9fsDirent *entries = NULL; - P9Req *req; tattach({ .client = v9p }); twalk({ @@ -114,11 +113,9 @@ static void fs_readdir(void *obj, void *data, QGuestAllocator *t_alloc) }); g_assert_cmpint(nqid, ==, 1); - req = tlopen({ - .client = v9p, .fid = 1, .flags = O_DIRECTORY, .requestOnly = true - }).req; - v9fs_req_wait_for_reply(req, NULL); - v9fs_rlopen(req, &qid, NULL); + tlopen({ + .client = v9p, .fid = 1, .flags = O_DIRECTORY, .rlopen.qid = &qid + }); /* * submit count = msize - 11, because 11 is the header size of Rreaddir @@ -163,7 +160,6 @@ static void do_readdir_split(QVirtio9P *v9p, uint32_t count) v9fs_qid qid; uint32_t nentries, npartialentries; struct V9fsDirent *entries, *tail, *partialentries; - P9Req *req; int fid; uint64_t offset; @@ -181,11 +177,9 @@ static void do_readdir_split(QVirtio9P *v9p, uint32_t count) }); g_assert_cmpint(nqid, ==, 1); - req = tlopen({ - .client = v9p, .fid = fid, .flags = O_DIRECTORY, .requestOnly = true - }).req; - v9fs_req_wait_for_reply(req, NULL); - v9fs_rlopen(req, &qid, NULL); + tlopen({ + .client = v9p, .fid = fid, .flags = O_DIRECTORY, .rlopen.qid = &qid + }); /* * send as many Treaddir requests as required to get all directory @@ -363,18 +357,13 @@ static void fs_lopen(void *obj, void *data, QGuestAllocator *t_alloc) QVirtio9P *v9p = obj; v9fs_set_allocator(t_alloc); char *wnames[] = { g_strdup(QTEST_V9FS_SYNTH_LOPEN_FILE) }; - P9Req *req; tattach({ .client = v9p }); twalk({ .client = v9p, .fid = 0, .newfid = 1, .nwname = 1, .wnames = wnames }); - req = tlopen({ - .client = v9p, .fid = 1, .flags = O_WRONLY, .requestOnly = true - }).req; - v9fs_req_wait_for_reply(req, NULL); - v9fs_rlopen(req, NULL, NULL); + tlopen({ .client = v9p, .fid = 1, .flags = O_WRONLY }); g_free(wnames[0]); } @@ -394,11 +383,7 @@ static void fs_write(void *obj, void *data, QGuestAllocator *t_alloc) .client = v9p, .fid = 0, .newfid = 1, .nwname = 1, .wnames = wnames }); - req = tlopen({ - .client = v9p, .fid = 1, .flags = O_WRONLY, .requestOnly = true - }).req; - v9fs_req_wait_for_reply(req, NULL); - v9fs_rlopen(req, NULL, NULL); + tlopen({ .client = v9p, .fid = 1, .flags = O_WRONLY }); req = v9fs_twrite(v9p, 1, 0, write_count, buf, 0); v9fs_req_wait_for_reply(req, NULL); @@ -422,11 +407,7 @@ static void fs_flush_success(void *obj, void *data, QGuestAllocator *t_alloc) .client = v9p, .fid = 0, .newfid = 1, .nwname = 1, .wnames = wnames }); - req = tlopen({ - .client = v9p, .fid = 1, .flags = O_WRONLY, .requestOnly = true - }).req; - v9fs_req_wait_for_reply(req, NULL); - v9fs_rlopen(req, NULL, NULL); + tlopen({ .client = v9p, .fid = 1, .flags = O_WRONLY }); /* This will cause the 9p server to try to write data to the backend, * until the write request gets cancelled. @@ -461,11 +442,7 @@ static void fs_flush_ignored(void *obj, void *data, QGuestAllocator *t_alloc) .client = v9p, .fid = 0, .newfid = 1, .nwname = 1, .wnames = wnames }); - req = tlopen({ - .client = v9p, .fid = 1, .flags = O_WRONLY, .requestOnly = true - }).req; - v9fs_req_wait_for_reply(req, NULL); - v9fs_rlopen(req, NULL, NULL); + tlopen({ .client = v9p, .fid = 1, .flags = O_WRONLY }); /* This will cause the write request to complete right away, before it * could be actually cancelled. From ac9e4e6185f0f5090d18dce2dd3f60d9660be496 Mon Sep 17 00:00:00 2001 From: Christian Schoenebeck Date: Tue, 4 Oct 2022 22:53:58 +0200 Subject: [PATCH 076/705] tests/9p: convert v9fs_twrite() to declarative arguments Use declarative function arguments for function v9fs_twrite(). Signed-off-by: Christian Schoenebeck Message-Id: --- tests/qtest/libqos/virtio-9p-client.c | 38 ++++++++++++++++++++------- tests/qtest/libqos/virtio-9p-client.h | 31 ++++++++++++++++++++-- tests/qtest/virtio-9p-test.c | 18 ++++++++++--- 3 files changed, 72 insertions(+), 15 deletions(-) diff --git a/tests/qtest/libqos/virtio-9p-client.c b/tests/qtest/libqos/virtio-9p-client.c index 15fde54d63..9ae347fad5 100644 --- a/tests/qtest/libqos/virtio-9p-client.c +++ b/tests/qtest/libqos/virtio-9p-client.c @@ -687,21 +687,39 @@ void v9fs_rlopen(P9Req *req, v9fs_qid *qid, uint32_t *iounit) } /* size[4] Twrite tag[2] fid[4] offset[8] count[4] data[count] */ -P9Req *v9fs_twrite(QVirtio9P *v9p, uint32_t fid, uint64_t offset, - uint32_t count, const void *data, uint16_t tag) +TWriteRes v9fs_twrite(TWriteOpt opt) { P9Req *req; + uint32_t err; uint32_t body_size = 4 + 8 + 4; + uint32_t written = 0; - g_assert_cmpint(body_size, <=, UINT32_MAX - count); - body_size += count; - req = v9fs_req_init(v9p, body_size, P9_TWRITE, tag); - v9fs_uint32_write(req, fid); - v9fs_uint64_write(req, offset); - v9fs_uint32_write(req, count); - v9fs_memwrite(req, data, count); + g_assert(opt.client); + + g_assert_cmpint(body_size, <=, UINT32_MAX - opt.count); + body_size += opt.count; + req = v9fs_req_init(opt.client, body_size, P9_TWRITE, opt.tag); + v9fs_uint32_write(req, opt.fid); + v9fs_uint64_write(req, opt.offset); + v9fs_uint32_write(req, opt.count); + v9fs_memwrite(req, opt.data, opt.count); v9fs_req_send(req); - return req; + + if (!opt.requestOnly) { + v9fs_req_wait_for_reply(req, NULL); + if (opt.expectErr) { + v9fs_rlerror(req, &err); + g_assert_cmpint(err, ==, opt.expectErr); + } else { + v9fs_rwrite(req, &written); + } + req = NULL; /* request was freed */ + } + + return (TWriteRes) { + .req = req, + .count = written + }; } /* size[4] Rwrite tag[2] count[4] */ diff --git a/tests/qtest/libqos/virtio-9p-client.h b/tests/qtest/libqos/virtio-9p-client.h index 3b70aef51e..dda371c054 100644 --- a/tests/qtest/libqos/virtio-9p-client.h +++ b/tests/qtest/libqos/virtio-9p-client.h @@ -239,6 +239,34 @@ typedef struct TLOpenRes { P9Req *req; } TLOpenRes; +/* options for 'Twrite' 9p request */ +typedef struct TWriteOpt { + /* 9P client being used (mandatory) */ + QVirtio9P *client; + /* user supplied tag number being returned with response (optional) */ + uint16_t tag; + /* file ID of file to write to (required) */ + uint32_t fid; + /* start position of write from beginning of file (optional) */ + uint64_t offset; + /* how many bytes to write */ + uint32_t count; + /* data to be written */ + const void *data; + /* only send Twrite request but not wait for a reply? (optional) */ + bool requestOnly; + /* do we expect an Rlerror response, if yes which error code? (optional) */ + uint32_t expectErr; +} TWriteOpt; + +/* result of 'Twrite' 9p request */ +typedef struct TWriteRes { + /* if requestOnly was set: request object for further processing */ + P9Req *req; + /* amount of bytes written */ + uint32_t count; +} TWriteRes; + void v9fs_set_allocator(QGuestAllocator *t_alloc); void v9fs_memwrite(P9Req *req, const void *addr, size_t len); void v9fs_memskip(P9Req *req, size_t len); @@ -274,8 +302,7 @@ void v9fs_rreaddir(P9Req *req, uint32_t *count, uint32_t *nentries, void v9fs_free_dirents(struct V9fsDirent *e); TLOpenRes v9fs_tlopen(TLOpenOpt); void v9fs_rlopen(P9Req *req, v9fs_qid *qid, uint32_t *iounit); -P9Req *v9fs_twrite(QVirtio9P *v9p, uint32_t fid, uint64_t offset, - uint32_t count, const void *data, uint16_t tag); +TWriteRes v9fs_twrite(TWriteOpt); void v9fs_rwrite(P9Req *req, uint32_t *count); P9Req *v9fs_tflush(QVirtio9P *v9p, uint16_t oldtag, uint16_t tag); void v9fs_rflush(P9Req *req); diff --git a/tests/qtest/virtio-9p-test.c b/tests/qtest/virtio-9p-test.c index 60a030b877..a5b9284acb 100644 --- a/tests/qtest/virtio-9p-test.c +++ b/tests/qtest/virtio-9p-test.c @@ -22,6 +22,7 @@ #define tgetattr(...) v9fs_tgetattr((TGetAttrOpt) __VA_ARGS__) #define treaddir(...) v9fs_treaddir((TReadDirOpt) __VA_ARGS__) #define tlopen(...) v9fs_tlopen((TLOpenOpt) __VA_ARGS__) +#define twrite(...) v9fs_twrite((TWriteOpt) __VA_ARGS__) static void pci_config(void *obj, void *data, QGuestAllocator *t_alloc) { @@ -385,7 +386,10 @@ static void fs_write(void *obj, void *data, QGuestAllocator *t_alloc) tlopen({ .client = v9p, .fid = 1, .flags = O_WRONLY }); - req = v9fs_twrite(v9p, 1, 0, write_count, buf, 0); + req = twrite({ + .client = v9p, .fid = 1, .offset = 0, .count = write_count, + .data = buf, .requestOnly = true + }).req; v9fs_req_wait_for_reply(req, NULL); v9fs_rwrite(req, &count); g_assert_cmpint(count, ==, write_count); @@ -413,7 +417,11 @@ static void fs_flush_success(void *obj, void *data, QGuestAllocator *t_alloc) * until the write request gets cancelled. */ should_block = 1; - req = v9fs_twrite(v9p, 1, 0, sizeof(should_block), &should_block, 0); + req = twrite({ + .client = v9p, .fid = 1, .offset = 0, + .count = sizeof(should_block), .data = &should_block, + .requestOnly = true + }).req; flush_req = v9fs_tflush(v9p, req->tag, 1); @@ -448,7 +456,11 @@ static void fs_flush_ignored(void *obj, void *data, QGuestAllocator *t_alloc) * could be actually cancelled. */ should_block = 0; - req = v9fs_twrite(v9p, 1, 0, sizeof(should_block), &should_block, 0); + req = twrite({ + .client = v9p, .fid = 1, .offset = 0, + .count = sizeof(should_block), .data = &should_block, + .requestOnly = true + }).req; flush_req = v9fs_tflush(v9p, req->tag, 1); From bb286ff8e85dcc222c93c9f3a164034561d1f585 Mon Sep 17 00:00:00 2001 From: Christian Schoenebeck Date: Tue, 4 Oct 2022 22:54:00 +0200 Subject: [PATCH 077/705] tests/9p: simplify callers of twrite() Now as twrite() is using a declarative approach, simplify the code of callers of this function. Signed-off-by: Christian Schoenebeck Message-Id: <7f280ec6a1f9d8afed46567a796562c4dc28afa9.1664917004.git.qemu_oss@crudebyte.com> --- tests/qtest/virtio-9p-test.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/tests/qtest/virtio-9p-test.c b/tests/qtest/virtio-9p-test.c index a5b9284acb..5ad7bebec7 100644 --- a/tests/qtest/virtio-9p-test.c +++ b/tests/qtest/virtio-9p-test.c @@ -377,7 +377,6 @@ static void fs_write(void *obj, void *data, QGuestAllocator *t_alloc) char *wnames[] = { g_strdup(QTEST_V9FS_SYNTH_WRITE_FILE) }; g_autofree char *buf = g_malloc0(write_count); uint32_t count; - P9Req *req; tattach({ .client = v9p }); twalk({ @@ -386,12 +385,10 @@ static void fs_write(void *obj, void *data, QGuestAllocator *t_alloc) tlopen({ .client = v9p, .fid = 1, .flags = O_WRONLY }); - req = twrite({ + count = twrite({ .client = v9p, .fid = 1, .offset = 0, .count = write_count, - .data = buf, .requestOnly = true - }).req; - v9fs_req_wait_for_reply(req, NULL); - v9fs_rwrite(req, &count); + .data = buf + }).count; g_assert_cmpint(count, ==, write_count); g_free(wnames[0]); From d89146fd16775aa734b1e67b8fdee0301ad80cf5 Mon Sep 17 00:00:00 2001 From: Christian Schoenebeck Date: Tue, 4 Oct 2022 22:54:03 +0200 Subject: [PATCH 078/705] tests/9p: convert v9fs_tflush() to declarative arguments Use declarative function arguments for function v9fs_tflush(). Signed-off-by: Christian Schoenebeck Message-Id: <91b7b154298c500d100b05137146c2905c3acdec.1664917004.git.qemu_oss@crudebyte.com> --- tests/qtest/libqos/virtio-9p-client.c | 23 +++++++++++++++++++---- tests/qtest/libqos/virtio-9p-client.h | 22 +++++++++++++++++++++- tests/qtest/virtio-9p-test.c | 9 +++++++-- 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/tests/qtest/libqos/virtio-9p-client.c b/tests/qtest/libqos/virtio-9p-client.c index 9ae347fad5..3be0ffc7da 100644 --- a/tests/qtest/libqos/virtio-9p-client.c +++ b/tests/qtest/libqos/virtio-9p-client.c @@ -733,14 +733,29 @@ void v9fs_rwrite(P9Req *req, uint32_t *count) } /* size[4] Tflush tag[2] oldtag[2] */ -P9Req *v9fs_tflush(QVirtio9P *v9p, uint16_t oldtag, uint16_t tag) +TFlushRes v9fs_tflush(TFlushOpt opt) { P9Req *req; + uint32_t err; - req = v9fs_req_init(v9p, 2, P9_TFLUSH, tag); - v9fs_uint32_write(req, oldtag); + g_assert(opt.client); + + req = v9fs_req_init(opt.client, 2, P9_TFLUSH, opt.tag); + v9fs_uint32_write(req, opt.oldtag); v9fs_req_send(req); - return req; + + if (!opt.requestOnly) { + v9fs_req_wait_for_reply(req, NULL); + if (opt.expectErr) { + v9fs_rlerror(req, &err); + g_assert_cmpint(err, ==, opt.expectErr); + } else { + v9fs_rflush(req); + } + req = NULL; /* request was freed */ + } + + return (TFlushRes) { .req = req }; } /* size[4] Rflush tag[2] */ diff --git a/tests/qtest/libqos/virtio-9p-client.h b/tests/qtest/libqos/virtio-9p-client.h index dda371c054..b22b54c720 100644 --- a/tests/qtest/libqos/virtio-9p-client.h +++ b/tests/qtest/libqos/virtio-9p-client.h @@ -267,6 +267,26 @@ typedef struct TWriteRes { uint32_t count; } TWriteRes; +/* options for 'Tflush' 9p request */ +typedef struct TFlushOpt { + /* 9P client being used (mandatory) */ + QVirtio9P *client; + /* user supplied tag number being returned with response (optional) */ + uint16_t tag; + /* message to flush (required) */ + uint16_t oldtag; + /* only send Tflush request but not wait for a reply? (optional) */ + bool requestOnly; + /* do we expect an Rlerror response, if yes which error code? (optional) */ + uint32_t expectErr; +} TFlushOpt; + +/* result of 'Tflush' 9p request */ +typedef struct TFlushRes { + /* if requestOnly was set: request object for further processing */ + P9Req *req; +} TFlushRes; + void v9fs_set_allocator(QGuestAllocator *t_alloc); void v9fs_memwrite(P9Req *req, const void *addr, size_t len); void v9fs_memskip(P9Req *req, size_t len); @@ -304,7 +324,7 @@ TLOpenRes v9fs_tlopen(TLOpenOpt); void v9fs_rlopen(P9Req *req, v9fs_qid *qid, uint32_t *iounit); TWriteRes v9fs_twrite(TWriteOpt); void v9fs_rwrite(P9Req *req, uint32_t *count); -P9Req *v9fs_tflush(QVirtio9P *v9p, uint16_t oldtag, uint16_t tag); +TFlushRes v9fs_tflush(TFlushOpt); void v9fs_rflush(P9Req *req); P9Req *v9fs_tmkdir(QVirtio9P *v9p, uint32_t dfid, const char *name, uint32_t mode, uint32_t gid, uint16_t tag); diff --git a/tests/qtest/virtio-9p-test.c b/tests/qtest/virtio-9p-test.c index 5ad7bebec7..5544998bac 100644 --- a/tests/qtest/virtio-9p-test.c +++ b/tests/qtest/virtio-9p-test.c @@ -23,6 +23,7 @@ #define treaddir(...) v9fs_treaddir((TReadDirOpt) __VA_ARGS__) #define tlopen(...) v9fs_tlopen((TLOpenOpt) __VA_ARGS__) #define twrite(...) v9fs_twrite((TWriteOpt) __VA_ARGS__) +#define tflush(...) v9fs_tflush((TFlushOpt) __VA_ARGS__) static void pci_config(void *obj, void *data, QGuestAllocator *t_alloc) { @@ -420,7 +421,9 @@ static void fs_flush_success(void *obj, void *data, QGuestAllocator *t_alloc) .requestOnly = true }).req; - flush_req = v9fs_tflush(v9p, req->tag, 1); + flush_req = tflush({ + .client = v9p, .oldtag = req->tag, .tag = 1, .requestOnly = true + }).req; /* The write request is supposed to be flushed: the server should just * mark the write request as used and reply to the flush request. @@ -459,7 +462,9 @@ static void fs_flush_ignored(void *obj, void *data, QGuestAllocator *t_alloc) .requestOnly = true }).req; - flush_req = v9fs_tflush(v9p, req->tag, 1); + flush_req = tflush({ + .client = v9p, .oldtag = req->tag, .tag = 1, .requestOnly = true + }).req; /* The write request is supposed to complete. The server should * reply to the write request and the flush request. From e11680102af6a9f42ab198a77015696820a1993e Mon Sep 17 00:00:00 2001 From: Christian Schoenebeck Date: Tue, 4 Oct 2022 22:54:06 +0200 Subject: [PATCH 079/705] tests/9p: merge v9fs_tmkdir() and do_mkdir() As with previous patches, unify those 2 functions into a single function v9fs_tmkdir() by using a declarative function arguments approach. Signed-off-by: Christian Schoenebeck Message-Id: --- tests/qtest/libqos/virtio-9p-client.c | 42 ++++++++++++++++++++++----- tests/qtest/libqos/virtio-9p-client.h | 36 +++++++++++++++++++++-- tests/qtest/virtio-9p-test.c | 30 ++++++------------- 3 files changed, 78 insertions(+), 30 deletions(-) diff --git a/tests/qtest/libqos/virtio-9p-client.c b/tests/qtest/libqos/virtio-9p-client.c index 3be0ffc7da..c374ba2048 100644 --- a/tests/qtest/libqos/virtio-9p-client.c +++ b/tests/qtest/libqos/virtio-9p-client.c @@ -766,10 +766,26 @@ void v9fs_rflush(P9Req *req) } /* size[4] Tmkdir tag[2] dfid[4] name[s] mode[4] gid[4] */ -P9Req *v9fs_tmkdir(QVirtio9P *v9p, uint32_t dfid, const char *name, - uint32_t mode, uint32_t gid, uint16_t tag) +TMkdirRes v9fs_tmkdir(TMkdirOpt opt) { P9Req *req; + uint32_t err; + g_autofree char *name = g_strdup(opt.name); + + g_assert(opt.client); + /* expecting either hi-level atPath or low-level dfid, but not both */ + g_assert(!opt.atPath || !opt.dfid); + /* expecting either Rmkdir or Rlerror, but obviously not both */ + g_assert(!opt.expectErr || !opt.rmkdir.qid); + + if (opt.atPath) { + opt.dfid = v9fs_twalk((TWalkOpt) { .client = opt.client, + .path = opt.atPath }).newfid; + } + + if (!opt.mode) { + opt.mode = 0750; + } uint32_t body_size = 4 + 4 + 4; uint16_t string_size = v9fs_string_size(name); @@ -777,13 +793,25 @@ P9Req *v9fs_tmkdir(QVirtio9P *v9p, uint32_t dfid, const char *name, g_assert_cmpint(body_size, <=, UINT32_MAX - string_size); body_size += string_size; - req = v9fs_req_init(v9p, body_size, P9_TMKDIR, tag); - v9fs_uint32_write(req, dfid); + req = v9fs_req_init(opt.client, body_size, P9_TMKDIR, opt.tag); + v9fs_uint32_write(req, opt.dfid); v9fs_string_write(req, name); - v9fs_uint32_write(req, mode); - v9fs_uint32_write(req, gid); + v9fs_uint32_write(req, opt.mode); + v9fs_uint32_write(req, opt.gid); v9fs_req_send(req); - return req; + + if (!opt.requestOnly) { + v9fs_req_wait_for_reply(req, NULL); + if (opt.expectErr) { + v9fs_rlerror(req, &err); + g_assert_cmpint(err, ==, opt.expectErr); + } else { + v9fs_rmkdir(req, opt.rmkdir.qid); + } + req = NULL; /* request was freed */ + } + + return (TMkdirRes) { .req = req }; } /* size[4] Rmkdir tag[2] qid[13] */ diff --git a/tests/qtest/libqos/virtio-9p-client.h b/tests/qtest/libqos/virtio-9p-client.h index b22b54c720..ae44f95a4d 100644 --- a/tests/qtest/libqos/virtio-9p-client.h +++ b/tests/qtest/libqos/virtio-9p-client.h @@ -287,6 +287,39 @@ typedef struct TFlushRes { P9Req *req; } TFlushRes; +/* options for 'Tmkdir' 9p request */ +typedef struct TMkdirOpt { + /* 9P client being used (mandatory) */ + QVirtio9P *client; + /* user supplied tag number being returned with response (optional) */ + uint16_t tag; + /* low level variant of directory where new one shall be created */ + uint32_t dfid; + /* high-level variant of directory where new one shall be created */ + const char *atPath; + /* New directory's name (required) */ + const char *name; + /* Linux mkdir(2) mode bits (optional) */ + uint32_t mode; + /* effective group ID of caller */ + uint32_t gid; + /* data being received from 9p server as 'Rmkdir' response (optional) */ + struct { + /* QID of newly created directory */ + v9fs_qid *qid; + } rmkdir; + /* only send Tmkdir request but not wait for a reply? (optional) */ + bool requestOnly; + /* do we expect an Rlerror response, if yes which error code? (optional) */ + uint32_t expectErr; +} TMkdirOpt; + +/* result of 'TMkdir' 9p request */ +typedef struct TMkdirRes { + /* if requestOnly was set: request object for further processing */ + P9Req *req; +} TMkdirRes; + void v9fs_set_allocator(QGuestAllocator *t_alloc); void v9fs_memwrite(P9Req *req, const void *addr, size_t len); void v9fs_memskip(P9Req *req, size_t len); @@ -326,8 +359,7 @@ TWriteRes v9fs_twrite(TWriteOpt); void v9fs_rwrite(P9Req *req, uint32_t *count); TFlushRes v9fs_tflush(TFlushOpt); void v9fs_rflush(P9Req *req); -P9Req *v9fs_tmkdir(QVirtio9P *v9p, uint32_t dfid, const char *name, - uint32_t mode, uint32_t gid, uint16_t tag); +TMkdirRes v9fs_tmkdir(TMkdirOpt); void v9fs_rmkdir(P9Req *req, v9fs_qid *qid); P9Req *v9fs_tlcreate(QVirtio9P *v9p, uint32_t fid, const char *name, uint32_t flags, uint32_t mode, uint32_t gid, diff --git a/tests/qtest/virtio-9p-test.c b/tests/qtest/virtio-9p-test.c index 5544998bac..6d75afee87 100644 --- a/tests/qtest/virtio-9p-test.c +++ b/tests/qtest/virtio-9p-test.c @@ -24,6 +24,7 @@ #define tlopen(...) v9fs_tlopen((TLOpenOpt) __VA_ARGS__) #define twrite(...) v9fs_twrite((TWriteOpt) __VA_ARGS__) #define tflush(...) v9fs_tflush((TFlushOpt) __VA_ARGS__) +#define tmkdir(...) v9fs_tmkdir((TMkdirOpt) __VA_ARGS__) static void pci_config(void *obj, void *data, QGuestAllocator *t_alloc) { @@ -477,19 +478,6 @@ static void fs_flush_ignored(void *obj, void *data, QGuestAllocator *t_alloc) g_free(wnames[0]); } -static void do_mkdir(QVirtio9P *v9p, const char *path, const char *cname) -{ - g_autofree char *name = g_strdup(cname); - uint32_t fid; - P9Req *req; - - fid = twalk({ .client = v9p, .path = path }).newfid; - - req = v9fs_tmkdir(v9p, fid, name, 0750, 0, 0); - v9fs_req_wait_for_reply(req, NULL); - v9fs_rmkdir(req, NULL); -} - /* create a regular file with Tlcreate and return file's fid */ static uint32_t do_lcreate(QVirtio9P *v9p, const char *path, const char *cname) @@ -587,7 +575,7 @@ static void fs_create_dir(void *obj, void *data, QGuestAllocator *t_alloc) g_assert(root_path != NULL); tattach({ .client = v9p }); - do_mkdir(v9p, "/", "01"); + tmkdir({ .client = v9p, .atPath = "/", .name = "01" }); /* check if created directory really exists now ... */ g_assert(stat(new_dir, &st) == 0); @@ -606,7 +594,7 @@ static void fs_unlinkat_dir(void *obj, void *data, QGuestAllocator *t_alloc) g_assert(root_path != NULL); tattach({ .client = v9p }); - do_mkdir(v9p, "/", "02"); + tmkdir({ .client = v9p, .atPath = "/", .name = "02" }); /* check if created directory really exists now ... */ g_assert(stat(new_dir, &st) == 0); @@ -626,7 +614,7 @@ static void fs_create_file(void *obj, void *data, QGuestAllocator *t_alloc) g_autofree char *new_file = virtio_9p_test_path("03/1st_file"); tattach({ .client = v9p }); - do_mkdir(v9p, "/", "03"); + tmkdir({ .client = v9p, .atPath = "/", .name = "03" }); do_lcreate(v9p, "03", "1st_file"); /* check if created file exists now ... */ @@ -643,7 +631,7 @@ static void fs_unlinkat_file(void *obj, void *data, QGuestAllocator *t_alloc) g_autofree char *new_file = virtio_9p_test_path("04/doa_file"); tattach({ .client = v9p }); - do_mkdir(v9p, "/", "04"); + tmkdir({ .client = v9p, .atPath = "/", .name = "04" }); do_lcreate(v9p, "04", "doa_file"); /* check if created file exists now ... */ @@ -665,7 +653,7 @@ static void fs_symlink_file(void *obj, void *data, QGuestAllocator *t_alloc) g_autofree char *symlink_file = virtio_9p_test_path("05/symlink_file"); tattach({ .client = v9p }); - do_mkdir(v9p, "/", "05"); + tmkdir({ .client = v9p, .atPath = "/", .name = "05" }); do_lcreate(v9p, "05", "real_file"); g_assert(stat(real_file, &st) == 0); g_assert((st.st_mode & S_IFMT) == S_IFREG); @@ -686,7 +674,7 @@ static void fs_unlinkat_symlink(void *obj, void *data, g_autofree char *symlink_file = virtio_9p_test_path("06/symlink_file"); tattach({ .client = v9p }); - do_mkdir(v9p, "/", "06"); + tmkdir({ .client = v9p, .atPath = "/", .name = "06" }); do_lcreate(v9p, "06", "real_file"); g_assert(stat(real_file, &st) == 0); g_assert((st.st_mode & S_IFMT) == S_IFREG); @@ -708,7 +696,7 @@ static void fs_hardlink_file(void *obj, void *data, QGuestAllocator *t_alloc) g_autofree char *hardlink_file = virtio_9p_test_path("07/hardlink_file"); tattach({ .client = v9p }); - do_mkdir(v9p, "/", "07"); + tmkdir({ .client = v9p, .atPath = "/", .name = "07" }); do_lcreate(v9p, "07", "real_file"); g_assert(stat(real_file, &st_real) == 0); g_assert((st_real.st_mode & S_IFMT) == S_IFREG); @@ -733,7 +721,7 @@ static void fs_unlinkat_hardlink(void *obj, void *data, g_autofree char *hardlink_file = virtio_9p_test_path("08/hardlink_file"); tattach({ .client = v9p }); - do_mkdir(v9p, "/", "08"); + tmkdir({ .client = v9p, .atPath = "/", .name = "08" }); do_lcreate(v9p, "08", "real_file"); g_assert(stat(real_file, &st_real) == 0); g_assert((st_real.st_mode & S_IFMT) == S_IFREG); From bd4660d49ac64886fb27649138e52d81be161fee Mon Sep 17 00:00:00 2001 From: Christian Schoenebeck Date: Tue, 4 Oct 2022 22:54:09 +0200 Subject: [PATCH 080/705] tests/9p: merge v9fs_tlcreate() and do_lcreate() As with previous patches, unify those 2 functions into a single function v9fs_tlcreate() by using a declarative function arguments approach. Signed-off-by: Christian Schoenebeck Message-Id: <4c01b2caa5f5b54a2020fc92701deadd2abf0571.1664917004.git.qemu_oss@crudebyte.com> --- tests/qtest/libqos/virtio-9p-client.c | 45 +++++++++++++++++++++------ tests/qtest/libqos/virtio-9p-client.h | 39 +++++++++++++++++++++-- tests/qtest/virtio-9p-test.c | 30 +++++------------- 3 files changed, 79 insertions(+), 35 deletions(-) diff --git a/tests/qtest/libqos/virtio-9p-client.c b/tests/qtest/libqos/virtio-9p-client.c index c374ba2048..5c805a133c 100644 --- a/tests/qtest/libqos/virtio-9p-client.c +++ b/tests/qtest/libqos/virtio-9p-client.c @@ -827,11 +827,26 @@ void v9fs_rmkdir(P9Req *req, v9fs_qid *qid) } /* size[4] Tlcreate tag[2] fid[4] name[s] flags[4] mode[4] gid[4] */ -P9Req *v9fs_tlcreate(QVirtio9P *v9p, uint32_t fid, const char *name, - uint32_t flags, uint32_t mode, uint32_t gid, - uint16_t tag) +TlcreateRes v9fs_tlcreate(TlcreateOpt opt) { P9Req *req; + uint32_t err; + g_autofree char *name = g_strdup(opt.name); + + g_assert(opt.client); + /* expecting either hi-level atPath or low-level fid, but not both */ + g_assert(!opt.atPath || !opt.fid); + /* expecting either Rlcreate or Rlerror, but obviously not both */ + g_assert(!opt.expectErr || !(opt.rlcreate.qid || opt.rlcreate.iounit)); + + if (opt.atPath) { + opt.fid = v9fs_twalk((TWalkOpt) { .client = opt.client, + .path = opt.atPath }).newfid; + } + + if (!opt.mode) { + opt.mode = 0750; + } uint32_t body_size = 4 + 4 + 4 + 4; uint16_t string_size = v9fs_string_size(name); @@ -839,14 +854,26 @@ P9Req *v9fs_tlcreate(QVirtio9P *v9p, uint32_t fid, const char *name, g_assert_cmpint(body_size, <=, UINT32_MAX - string_size); body_size += string_size; - req = v9fs_req_init(v9p, body_size, P9_TLCREATE, tag); - v9fs_uint32_write(req, fid); + req = v9fs_req_init(opt.client, body_size, P9_TLCREATE, opt.tag); + v9fs_uint32_write(req, opt.fid); v9fs_string_write(req, name); - v9fs_uint32_write(req, flags); - v9fs_uint32_write(req, mode); - v9fs_uint32_write(req, gid); + v9fs_uint32_write(req, opt.flags); + v9fs_uint32_write(req, opt.mode); + v9fs_uint32_write(req, opt.gid); v9fs_req_send(req); - return req; + + if (!opt.requestOnly) { + v9fs_req_wait_for_reply(req, NULL); + if (opt.expectErr) { + v9fs_rlerror(req, &err); + g_assert_cmpint(err, ==, opt.expectErr); + } else { + v9fs_rlcreate(req, opt.rlcreate.qid, opt.rlcreate.iounit); + } + req = NULL; /* request was freed */ + } + + return (TlcreateRes) { .req = req }; } /* size[4] Rlcreate tag[2] qid[13] iounit[4] */ diff --git a/tests/qtest/libqos/virtio-9p-client.h b/tests/qtest/libqos/virtio-9p-client.h index ae44f95a4d..8916b1c7aa 100644 --- a/tests/qtest/libqos/virtio-9p-client.h +++ b/tests/qtest/libqos/virtio-9p-client.h @@ -320,6 +320,41 @@ typedef struct TMkdirRes { P9Req *req; } TMkdirRes; +/* options for 'Tlcreate' 9p request */ +typedef struct TlcreateOpt { + /* 9P client being used (mandatory) */ + QVirtio9P *client; + /* user supplied tag number being returned with response (optional) */ + uint16_t tag; + /* low-level variant of directory where new file shall be created */ + uint32_t fid; + /* high-level variant of directory where new file shall be created */ + const char *atPath; + /* name of new file (required) */ + const char *name; + /* Linux kernel intent bits */ + uint32_t flags; + /* Linux create(2) mode bits */ + uint32_t mode; + /* effective group ID of caller */ + uint32_t gid; + /* data being received from 9p server as 'Rlcreate' response (optional) */ + struct { + v9fs_qid *qid; + uint32_t *iounit; + } rlcreate; + /* only send Tlcreate request but not wait for a reply? (optional) */ + bool requestOnly; + /* do we expect an Rlerror response, if yes which error code? (optional) */ + uint32_t expectErr; +} TlcreateOpt; + +/* result of 'Tlcreate' 9p request */ +typedef struct TlcreateRes { + /* if requestOnly was set: request object for further processing */ + P9Req *req; +} TlcreateRes; + void v9fs_set_allocator(QGuestAllocator *t_alloc); void v9fs_memwrite(P9Req *req, const void *addr, size_t len); void v9fs_memskip(P9Req *req, size_t len); @@ -361,9 +396,7 @@ TFlushRes v9fs_tflush(TFlushOpt); void v9fs_rflush(P9Req *req); TMkdirRes v9fs_tmkdir(TMkdirOpt); void v9fs_rmkdir(P9Req *req, v9fs_qid *qid); -P9Req *v9fs_tlcreate(QVirtio9P *v9p, uint32_t fid, const char *name, - uint32_t flags, uint32_t mode, uint32_t gid, - uint16_t tag); +TlcreateRes v9fs_tlcreate(TlcreateOpt); void v9fs_rlcreate(P9Req *req, v9fs_qid *qid, uint32_t *iounit); P9Req *v9fs_tsymlink(QVirtio9P *v9p, uint32_t fid, const char *name, const char *symtgt, uint32_t gid, uint16_t tag); diff --git a/tests/qtest/virtio-9p-test.c b/tests/qtest/virtio-9p-test.c index 6d75afee87..d13b27bd2e 100644 --- a/tests/qtest/virtio-9p-test.c +++ b/tests/qtest/virtio-9p-test.c @@ -25,6 +25,7 @@ #define twrite(...) v9fs_twrite((TWriteOpt) __VA_ARGS__) #define tflush(...) v9fs_tflush((TFlushOpt) __VA_ARGS__) #define tmkdir(...) v9fs_tmkdir((TMkdirOpt) __VA_ARGS__) +#define tlcreate(...) v9fs_tlcreate((TlcreateOpt) __VA_ARGS__) static void pci_config(void *obj, void *data, QGuestAllocator *t_alloc) { @@ -478,23 +479,6 @@ static void fs_flush_ignored(void *obj, void *data, QGuestAllocator *t_alloc) g_free(wnames[0]); } -/* create a regular file with Tlcreate and return file's fid */ -static uint32_t do_lcreate(QVirtio9P *v9p, const char *path, - const char *cname) -{ - g_autofree char *name = g_strdup(cname); - uint32_t fid; - P9Req *req; - - fid = twalk({ .client = v9p, .path = path }).newfid; - - req = v9fs_tlcreate(v9p, fid, name, 0, 0750, 0, 0); - v9fs_req_wait_for_reply(req, NULL); - v9fs_rlcreate(req, NULL, NULL); - - return fid; -} - /* create symlink named @a clink in directory @a path pointing to @a to */ static void do_symlink(QVirtio9P *v9p, const char *path, const char *clink, const char *to) @@ -615,7 +599,7 @@ static void fs_create_file(void *obj, void *data, QGuestAllocator *t_alloc) tattach({ .client = v9p }); tmkdir({ .client = v9p, .atPath = "/", .name = "03" }); - do_lcreate(v9p, "03", "1st_file"); + tlcreate({ .client = v9p, .atPath = "03", .name = "1st_file" }); /* check if created file exists now ... */ g_assert(stat(new_file, &st) == 0); @@ -632,7 +616,7 @@ static void fs_unlinkat_file(void *obj, void *data, QGuestAllocator *t_alloc) tattach({ .client = v9p }); tmkdir({ .client = v9p, .atPath = "/", .name = "04" }); - do_lcreate(v9p, "04", "doa_file"); + tlcreate({ .client = v9p, .atPath = "04", .name = "doa_file" }); /* check if created file exists now ... */ g_assert(stat(new_file, &st) == 0); @@ -654,7 +638,7 @@ static void fs_symlink_file(void *obj, void *data, QGuestAllocator *t_alloc) tattach({ .client = v9p }); tmkdir({ .client = v9p, .atPath = "/", .name = "05" }); - do_lcreate(v9p, "05", "real_file"); + tlcreate({ .client = v9p, .atPath = "05", .name = "real_file" }); g_assert(stat(real_file, &st) == 0); g_assert((st.st_mode & S_IFMT) == S_IFREG); @@ -675,7 +659,7 @@ static void fs_unlinkat_symlink(void *obj, void *data, tattach({ .client = v9p }); tmkdir({ .client = v9p, .atPath = "/", .name = "06" }); - do_lcreate(v9p, "06", "real_file"); + tlcreate({ .client = v9p, .atPath = "06", .name = "real_file" }); g_assert(stat(real_file, &st) == 0); g_assert((st.st_mode & S_IFMT) == S_IFREG); @@ -697,7 +681,7 @@ static void fs_hardlink_file(void *obj, void *data, QGuestAllocator *t_alloc) tattach({ .client = v9p }); tmkdir({ .client = v9p, .atPath = "/", .name = "07" }); - do_lcreate(v9p, "07", "real_file"); + tlcreate({ .client = v9p, .atPath = "07", .name = "real_file" }); g_assert(stat(real_file, &st_real) == 0); g_assert((st_real.st_mode & S_IFMT) == S_IFREG); @@ -722,7 +706,7 @@ static void fs_unlinkat_hardlink(void *obj, void *data, tattach({ .client = v9p }); tmkdir({ .client = v9p, .atPath = "/", .name = "08" }); - do_lcreate(v9p, "08", "real_file"); + tlcreate({ .client = v9p, .atPath = "08", .name = "real_file" }); g_assert(stat(real_file, &st_real) == 0); g_assert((st_real.st_mode & S_IFMT) == S_IFREG); From 9beabfa52cb17fad0e8211031f301f12281d65f8 Mon Sep 17 00:00:00 2001 From: Christian Schoenebeck Date: Tue, 4 Oct 2022 22:54:11 +0200 Subject: [PATCH 081/705] tests/9p: merge v9fs_tsymlink() and do_symlink() As with previous patches, unify those 2 functions into a single function v9fs_tsymlink() by using a declarative function arguments approach. Signed-off-by: Christian Schoenebeck Message-Id: <563f3ad04fe596ce0ae1e2654d1d08237f18c830.1664917004.git.qemu_oss@crudebyte.com> --- tests/qtest/libqos/virtio-9p-client.c | 37 ++++++++++++++++++++++----- tests/qtest/libqos/virtio-9p-client.h | 35 +++++++++++++++++++++++-- tests/qtest/virtio-9p-test.c | 27 +++++++------------ 3 files changed, 73 insertions(+), 26 deletions(-) diff --git a/tests/qtest/libqos/virtio-9p-client.c b/tests/qtest/libqos/virtio-9p-client.c index 5c805a133c..89eaf50355 100644 --- a/tests/qtest/libqos/virtio-9p-client.c +++ b/tests/qtest/libqos/virtio-9p-client.c @@ -892,10 +892,23 @@ void v9fs_rlcreate(P9Req *req, v9fs_qid *qid, uint32_t *iounit) } /* size[4] Tsymlink tag[2] fid[4] name[s] symtgt[s] gid[4] */ -P9Req *v9fs_tsymlink(QVirtio9P *v9p, uint32_t fid, const char *name, - const char *symtgt, uint32_t gid, uint16_t tag) +TsymlinkRes v9fs_tsymlink(TsymlinkOpt opt) { P9Req *req; + uint32_t err; + g_autofree char *name = g_strdup(opt.name); + g_autofree char *symtgt = g_strdup(opt.symtgt); + + g_assert(opt.client); + /* expecting either hi-level atPath or low-level fid, but not both */ + g_assert(!opt.atPath || !opt.fid); + /* expecting either Rsymlink or Rlerror, but obviously not both */ + g_assert(!opt.expectErr || !opt.rsymlink.qid); + + if (opt.atPath) { + opt.fid = v9fs_twalk((TWalkOpt) { .client = opt.client, + .path = opt.atPath }).newfid; + } uint32_t body_size = 4 + 4; uint16_t string_size = v9fs_string_size(name) + v9fs_string_size(symtgt); @@ -903,13 +916,25 @@ P9Req *v9fs_tsymlink(QVirtio9P *v9p, uint32_t fid, const char *name, g_assert_cmpint(body_size, <=, UINT32_MAX - string_size); body_size += string_size; - req = v9fs_req_init(v9p, body_size, P9_TSYMLINK, tag); - v9fs_uint32_write(req, fid); + req = v9fs_req_init(opt.client, body_size, P9_TSYMLINK, opt.tag); + v9fs_uint32_write(req, opt.fid); v9fs_string_write(req, name); v9fs_string_write(req, symtgt); - v9fs_uint32_write(req, gid); + v9fs_uint32_write(req, opt.gid); v9fs_req_send(req); - return req; + + if (!opt.requestOnly) { + v9fs_req_wait_for_reply(req, NULL); + if (opt.expectErr) { + v9fs_rlerror(req, &err); + g_assert_cmpint(err, ==, opt.expectErr); + } else { + v9fs_rsymlink(req, opt.rsymlink.qid); + } + req = NULL; /* request was freed */ + } + + return (TsymlinkRes) { .req = req }; } /* size[4] Rsymlink tag[2] qid[13] */ diff --git a/tests/qtest/libqos/virtio-9p-client.h b/tests/qtest/libqos/virtio-9p-client.h index 8916b1c7aa..b905a54966 100644 --- a/tests/qtest/libqos/virtio-9p-client.h +++ b/tests/qtest/libqos/virtio-9p-client.h @@ -355,6 +355,38 @@ typedef struct TlcreateRes { P9Req *req; } TlcreateRes; +/* options for 'Tsymlink' 9p request */ +typedef struct TsymlinkOpt { + /* 9P client being used (mandatory) */ + QVirtio9P *client; + /* user supplied tag number being returned with response (optional) */ + uint16_t tag; + /* low-level variant of directory where symlink shall be created */ + uint32_t fid; + /* high-level variant of directory where symlink shall be created */ + const char *atPath; + /* name of symlink (required) */ + const char *name; + /* where symlink will point to (required) */ + const char *symtgt; + /* effective group ID of caller */ + uint32_t gid; + /* data being received from 9p server as 'Rsymlink' response (optional) */ + struct { + v9fs_qid *qid; + } rsymlink; + /* only send Tsymlink request but not wait for a reply? (optional) */ + bool requestOnly; + /* do we expect an Rlerror response, if yes which error code? (optional) */ + uint32_t expectErr; +} TsymlinkOpt; + +/* result of 'Tsymlink' 9p request */ +typedef struct TsymlinkRes { + /* if requestOnly was set: request object for further processing */ + P9Req *req; +} TsymlinkRes; + void v9fs_set_allocator(QGuestAllocator *t_alloc); void v9fs_memwrite(P9Req *req, const void *addr, size_t len); void v9fs_memskip(P9Req *req, size_t len); @@ -398,8 +430,7 @@ TMkdirRes v9fs_tmkdir(TMkdirOpt); void v9fs_rmkdir(P9Req *req, v9fs_qid *qid); TlcreateRes v9fs_tlcreate(TlcreateOpt); void v9fs_rlcreate(P9Req *req, v9fs_qid *qid, uint32_t *iounit); -P9Req *v9fs_tsymlink(QVirtio9P *v9p, uint32_t fid, const char *name, - const char *symtgt, uint32_t gid, uint16_t tag); +TsymlinkRes v9fs_tsymlink(TsymlinkOpt); void v9fs_rsymlink(P9Req *req, v9fs_qid *qid); P9Req *v9fs_tlink(QVirtio9P *v9p, uint32_t dfid, uint32_t fid, const char *name, uint16_t tag); diff --git a/tests/qtest/virtio-9p-test.c b/tests/qtest/virtio-9p-test.c index d13b27bd2e..c7213d6caf 100644 --- a/tests/qtest/virtio-9p-test.c +++ b/tests/qtest/virtio-9p-test.c @@ -26,6 +26,7 @@ #define tflush(...) v9fs_tflush((TFlushOpt) __VA_ARGS__) #define tmkdir(...) v9fs_tmkdir((TMkdirOpt) __VA_ARGS__) #define tlcreate(...) v9fs_tlcreate((TlcreateOpt) __VA_ARGS__) +#define tsymlink(...) v9fs_tsymlink((TsymlinkOpt) __VA_ARGS__) static void pci_config(void *obj, void *data, QGuestAllocator *t_alloc) { @@ -479,22 +480,6 @@ static void fs_flush_ignored(void *obj, void *data, QGuestAllocator *t_alloc) g_free(wnames[0]); } -/* create symlink named @a clink in directory @a path pointing to @a to */ -static void do_symlink(QVirtio9P *v9p, const char *path, const char *clink, - const char *to) -{ - g_autofree char *name = g_strdup(clink); - g_autofree char *dst = g_strdup(to); - uint32_t fid; - P9Req *req; - - fid = twalk({ .client = v9p, .path = path }).newfid; - - req = v9fs_tsymlink(v9p, fid, name, dst, 0, 0); - v9fs_req_wait_for_reply(req, NULL); - v9fs_rsymlink(req, NULL); -} - /* create a hard link named @a clink in directory @a path pointing to @a to */ static void do_hardlink(QVirtio9P *v9p, const char *path, const char *clink, const char *to) @@ -642,7 +627,10 @@ static void fs_symlink_file(void *obj, void *data, QGuestAllocator *t_alloc) g_assert(stat(real_file, &st) == 0); g_assert((st.st_mode & S_IFMT) == S_IFREG); - do_symlink(v9p, "05", "symlink_file", "real_file"); + tsymlink({ + .client = v9p, .atPath = "05", .name = "symlink_file", + .symtgt = "real_file" + }); /* check if created link exists now */ g_assert(stat(symlink_file, &st) == 0); @@ -663,7 +651,10 @@ static void fs_unlinkat_symlink(void *obj, void *data, g_assert(stat(real_file, &st) == 0); g_assert((st.st_mode & S_IFMT) == S_IFREG); - do_symlink(v9p, "06", "symlink_file", "real_file"); + tsymlink({ + .client = v9p, .atPath = "06", .name = "symlink_file", + .symtgt = "real_file" + }); g_assert(stat(symlink_file, &st) == 0); do_unlinkat(v9p, "06", "symlink_file", 0); From d41a9462ea15f0e3ef789d496032536c33098275 Mon Sep 17 00:00:00 2001 From: Christian Schoenebeck Date: Tue, 4 Oct 2022 22:54:14 +0200 Subject: [PATCH 082/705] tests/9p: merge v9fs_tlink() and do_hardlink() As with previous patches, unify those 2 functions into a single function v9fs_tlink() by using a declarative function arguments approach. Signed-off-by: Christian Schoenebeck Message-Id: --- tests/qtest/libqos/virtio-9p-client.c | 43 ++++++++++++++++++++++----- tests/qtest/libqos/virtio-9p-client.h | 31 +++++++++++++++++-- tests/qtest/virtio-9p-test.c | 26 ++++++---------- 3 files changed, 73 insertions(+), 27 deletions(-) diff --git a/tests/qtest/libqos/virtio-9p-client.c b/tests/qtest/libqos/virtio-9p-client.c index 89eaf50355..a2770719b9 100644 --- a/tests/qtest/libqos/virtio-9p-client.c +++ b/tests/qtest/libqos/virtio-9p-client.c @@ -950,23 +950,50 @@ void v9fs_rsymlink(P9Req *req, v9fs_qid *qid) } /* size[4] Tlink tag[2] dfid[4] fid[4] name[s] */ -P9Req *v9fs_tlink(QVirtio9P *v9p, uint32_t dfid, uint32_t fid, - const char *name, uint16_t tag) +TlinkRes v9fs_tlink(TlinkOpt opt) { P9Req *req; + uint32_t err; + + g_assert(opt.client); + /* expecting either hi-level atPath or low-level dfid, but not both */ + g_assert(!opt.atPath || !opt.dfid); + /* expecting either hi-level toPath or low-level fid, but not both */ + g_assert(!opt.toPath || !opt.fid); + + if (opt.atPath) { + opt.dfid = v9fs_twalk((TWalkOpt) { .client = opt.client, + .path = opt.atPath }).newfid; + } + if (opt.toPath) { + opt.fid = v9fs_twalk((TWalkOpt) { .client = opt.client, + .path = opt.toPath }).newfid; + } uint32_t body_size = 4 + 4; - uint16_t string_size = v9fs_string_size(name); + uint16_t string_size = v9fs_string_size(opt.name); g_assert_cmpint(body_size, <=, UINT32_MAX - string_size); body_size += string_size; - req = v9fs_req_init(v9p, body_size, P9_TLINK, tag); - v9fs_uint32_write(req, dfid); - v9fs_uint32_write(req, fid); - v9fs_string_write(req, name); + req = v9fs_req_init(opt.client, body_size, P9_TLINK, opt.tag); + v9fs_uint32_write(req, opt.dfid); + v9fs_uint32_write(req, opt.fid); + v9fs_string_write(req, opt.name); v9fs_req_send(req); - return req; + + if (!opt.requestOnly) { + v9fs_req_wait_for_reply(req, NULL); + if (opt.expectErr) { + v9fs_rlerror(req, &err); + g_assert_cmpint(err, ==, opt.expectErr); + } else { + v9fs_rlink(req); + } + req = NULL; /* request was freed */ + } + + return (TlinkRes) { .req = req }; } /* size[4] Rlink tag[2] */ diff --git a/tests/qtest/libqos/virtio-9p-client.h b/tests/qtest/libqos/virtio-9p-client.h index b905a54966..49ffd0fc51 100644 --- a/tests/qtest/libqos/virtio-9p-client.h +++ b/tests/qtest/libqos/virtio-9p-client.h @@ -387,6 +387,34 @@ typedef struct TsymlinkRes { P9Req *req; } TsymlinkRes; +/* options for 'Tlink' 9p request */ +typedef struct TlinkOpt { + /* 9P client being used (mandatory) */ + QVirtio9P *client; + /* user supplied tag number being returned with response (optional) */ + uint16_t tag; + /* low-level variant of directory where hard link shall be created */ + uint32_t dfid; + /* high-level variant of directory where hard link shall be created */ + const char *atPath; + /* low-level variant of target referenced by new hard link */ + uint32_t fid; + /* high-level variant of target referenced by new hard link */ + const char *toPath; + /* name of hard link (required) */ + const char *name; + /* only send Tlink request but not wait for a reply? (optional) */ + bool requestOnly; + /* do we expect an Rlerror response, if yes which error code? (optional) */ + uint32_t expectErr; +} TlinkOpt; + +/* result of 'Tlink' 9p request */ +typedef struct TlinkRes { + /* if requestOnly was set: request object for further processing */ + P9Req *req; +} TlinkRes; + void v9fs_set_allocator(QGuestAllocator *t_alloc); void v9fs_memwrite(P9Req *req, const void *addr, size_t len); void v9fs_memskip(P9Req *req, size_t len); @@ -432,8 +460,7 @@ TlcreateRes v9fs_tlcreate(TlcreateOpt); void v9fs_rlcreate(P9Req *req, v9fs_qid *qid, uint32_t *iounit); TsymlinkRes v9fs_tsymlink(TsymlinkOpt); void v9fs_rsymlink(P9Req *req, v9fs_qid *qid); -P9Req *v9fs_tlink(QVirtio9P *v9p, uint32_t dfid, uint32_t fid, - const char *name, uint16_t tag); +TlinkRes v9fs_tlink(TlinkOpt); void v9fs_rlink(P9Req *req); P9Req *v9fs_tunlinkat(QVirtio9P *v9p, uint32_t dirfd, const char *name, uint32_t flags, uint16_t tag); diff --git a/tests/qtest/virtio-9p-test.c b/tests/qtest/virtio-9p-test.c index c7213d6caf..185eaf8b1e 100644 --- a/tests/qtest/virtio-9p-test.c +++ b/tests/qtest/virtio-9p-test.c @@ -27,6 +27,7 @@ #define tmkdir(...) v9fs_tmkdir((TMkdirOpt) __VA_ARGS__) #define tlcreate(...) v9fs_tlcreate((TlcreateOpt) __VA_ARGS__) #define tsymlink(...) v9fs_tsymlink((TsymlinkOpt) __VA_ARGS__) +#define tlink(...) v9fs_tlink((TlinkOpt) __VA_ARGS__) static void pci_config(void *obj, void *data, QGuestAllocator *t_alloc) { @@ -480,21 +481,6 @@ static void fs_flush_ignored(void *obj, void *data, QGuestAllocator *t_alloc) g_free(wnames[0]); } -/* create a hard link named @a clink in directory @a path pointing to @a to */ -static void do_hardlink(QVirtio9P *v9p, const char *path, const char *clink, - const char *to) -{ - uint32_t dfid, fid; - P9Req *req; - - dfid = twalk({ .client = v9p, .path = path }).newfid; - fid = twalk({ .client = v9p, .path = to }).newfid; - - req = v9fs_tlink(v9p, dfid, fid, clink, 0); - v9fs_req_wait_for_reply(req, NULL); - v9fs_rlink(req); -} - static void do_unlinkat(QVirtio9P *v9p, const char *atpath, const char *rpath, uint32_t flags) { @@ -676,7 +662,10 @@ static void fs_hardlink_file(void *obj, void *data, QGuestAllocator *t_alloc) g_assert(stat(real_file, &st_real) == 0); g_assert((st_real.st_mode & S_IFMT) == S_IFREG); - do_hardlink(v9p, "07", "hardlink_file", "07/real_file"); + tlink({ + .client = v9p, .atPath = "07", .name = "hardlink_file", + .toPath = "07/real_file" + }); /* check if link exists now ... */ g_assert(stat(hardlink_file, &st_link) == 0); @@ -701,7 +690,10 @@ static void fs_unlinkat_hardlink(void *obj, void *data, g_assert(stat(real_file, &st_real) == 0); g_assert((st_real.st_mode & S_IFMT) == S_IFREG); - do_hardlink(v9p, "08", "hardlink_file", "08/real_file"); + tlink({ + .client = v9p, .atPath = "08", .name = "hardlink_file", + .toPath = "08/real_file" + }); g_assert(stat(hardlink_file, &st_link) == 0); do_unlinkat(v9p, "08", "hardlink_file", 0); From 43e0d9fb358b01539d0de9494208e80ff84b5456 Mon Sep 17 00:00:00 2001 From: Christian Schoenebeck Date: Tue, 4 Oct 2022 22:54:16 +0200 Subject: [PATCH 083/705] tests/9p: merge v9fs_tunlinkat() and do_unlinkat() As with previous patches, unify those 2 functions into a single function v9fs_tunlinkat() by using a declarative function arguments approach. Signed-off-by: Christian Schoenebeck Message-Id: <1dea593edd464908d92501933c068388c01f1744.1664917004.git.qemu_oss@crudebyte.com> --- tests/qtest/libqos/virtio-9p-client.c | 37 +++++++++++++++++++++------ tests/qtest/libqos/virtio-9p-client.h | 29 +++++++++++++++++++-- tests/qtest/virtio-9p-test.c | 26 ++++++------------- 3 files changed, 64 insertions(+), 28 deletions(-) diff --git a/tests/qtest/libqos/virtio-9p-client.c b/tests/qtest/libqos/virtio-9p-client.c index a2770719b9..e017e030ec 100644 --- a/tests/qtest/libqos/virtio-9p-client.c +++ b/tests/qtest/libqos/virtio-9p-client.c @@ -1004,23 +1004,44 @@ void v9fs_rlink(P9Req *req) } /* size[4] Tunlinkat tag[2] dirfd[4] name[s] flags[4] */ -P9Req *v9fs_tunlinkat(QVirtio9P *v9p, uint32_t dirfd, const char *name, - uint32_t flags, uint16_t tag) +TunlinkatRes v9fs_tunlinkat(TunlinkatOpt opt) { P9Req *req; + uint32_t err; + + g_assert(opt.client); + /* expecting either hi-level atPath or low-level dirfd, but not both */ + g_assert(!opt.atPath || !opt.dirfd); + + if (opt.atPath) { + opt.dirfd = v9fs_twalk((TWalkOpt) { .client = opt.client, + .path = opt.atPath }).newfid; + } uint32_t body_size = 4 + 4; - uint16_t string_size = v9fs_string_size(name); + uint16_t string_size = v9fs_string_size(opt.name); g_assert_cmpint(body_size, <=, UINT32_MAX - string_size); body_size += string_size; - req = v9fs_req_init(v9p, body_size, P9_TUNLINKAT, tag); - v9fs_uint32_write(req, dirfd); - v9fs_string_write(req, name); - v9fs_uint32_write(req, flags); + req = v9fs_req_init(opt.client, body_size, P9_TUNLINKAT, opt.tag); + v9fs_uint32_write(req, opt.dirfd); + v9fs_string_write(req, opt.name); + v9fs_uint32_write(req, opt.flags); v9fs_req_send(req); - return req; + + if (!opt.requestOnly) { + v9fs_req_wait_for_reply(req, NULL); + if (opt.expectErr) { + v9fs_rlerror(req, &err); + g_assert_cmpint(err, ==, opt.expectErr); + } else { + v9fs_runlinkat(req); + } + req = NULL; /* request was freed */ + } + + return (TunlinkatRes) { .req = req }; } /* size[4] Runlinkat tag[2] */ diff --git a/tests/qtest/libqos/virtio-9p-client.h b/tests/qtest/libqos/virtio-9p-client.h index 49ffd0fc51..78228eb97d 100644 --- a/tests/qtest/libqos/virtio-9p-client.h +++ b/tests/qtest/libqos/virtio-9p-client.h @@ -415,6 +415,32 @@ typedef struct TlinkRes { P9Req *req; } TlinkRes; +/* options for 'Tunlinkat' 9p request */ +typedef struct TunlinkatOpt { + /* 9P client being used (mandatory) */ + QVirtio9P *client; + /* user supplied tag number being returned with response (optional) */ + uint16_t tag; + /* low-level variant of directory where name shall be unlinked */ + uint32_t dirfd; + /* high-level variant of directory where name shall be unlinked */ + const char *atPath; + /* name of directory entry to be unlinked (required) */ + const char *name; + /* Linux unlinkat(2) flags */ + uint32_t flags; + /* only send Tunlinkat request but not wait for a reply? (optional) */ + bool requestOnly; + /* do we expect an Rlerror response, if yes which error code? (optional) */ + uint32_t expectErr; +} TunlinkatOpt; + +/* result of 'Tunlinkat' 9p request */ +typedef struct TunlinkatRes { + /* if requestOnly was set: request object for further processing */ + P9Req *req; +} TunlinkatRes; + void v9fs_set_allocator(QGuestAllocator *t_alloc); void v9fs_memwrite(P9Req *req, const void *addr, size_t len); void v9fs_memskip(P9Req *req, size_t len); @@ -462,8 +488,7 @@ TsymlinkRes v9fs_tsymlink(TsymlinkOpt); void v9fs_rsymlink(P9Req *req, v9fs_qid *qid); TlinkRes v9fs_tlink(TlinkOpt); void v9fs_rlink(P9Req *req); -P9Req *v9fs_tunlinkat(QVirtio9P *v9p, uint32_t dirfd, const char *name, - uint32_t flags, uint16_t tag); +TunlinkatRes v9fs_tunlinkat(TunlinkatOpt); void v9fs_runlinkat(P9Req *req); #endif diff --git a/tests/qtest/virtio-9p-test.c b/tests/qtest/virtio-9p-test.c index 185eaf8b1e..65e69491e5 100644 --- a/tests/qtest/virtio-9p-test.c +++ b/tests/qtest/virtio-9p-test.c @@ -28,6 +28,7 @@ #define tlcreate(...) v9fs_tlcreate((TlcreateOpt) __VA_ARGS__) #define tsymlink(...) v9fs_tsymlink((TsymlinkOpt) __VA_ARGS__) #define tlink(...) v9fs_tlink((TlinkOpt) __VA_ARGS__) +#define tunlinkat(...) v9fs_tunlinkat((TunlinkatOpt) __VA_ARGS__) static void pci_config(void *obj, void *data, QGuestAllocator *t_alloc) { @@ -481,20 +482,6 @@ static void fs_flush_ignored(void *obj, void *data, QGuestAllocator *t_alloc) g_free(wnames[0]); } -static void do_unlinkat(QVirtio9P *v9p, const char *atpath, const char *rpath, - uint32_t flags) -{ - g_autofree char *name = g_strdup(rpath); - uint32_t fid; - P9Req *req; - - fid = twalk({ .client = v9p, .path = atpath }).newfid; - - req = v9fs_tunlinkat(v9p, fid, name, flags, 0); - v9fs_req_wait_for_reply(req, NULL); - v9fs_runlinkat(req); -} - static void fs_readdir_split_128(void *obj, void *data, QGuestAllocator *t_alloc) { @@ -556,7 +543,10 @@ static void fs_unlinkat_dir(void *obj, void *data, QGuestAllocator *t_alloc) /* ... and is actually a directory */ g_assert((st.st_mode & S_IFMT) == S_IFDIR); - do_unlinkat(v9p, "/", "02", P9_DOTL_AT_REMOVEDIR); + tunlinkat({ + .client = v9p, .atPath = "/", .name = "02", + .flags = P9_DOTL_AT_REMOVEDIR + }); /* directory should be gone now */ g_assert(stat(new_dir, &st) != 0); } @@ -594,7 +584,7 @@ static void fs_unlinkat_file(void *obj, void *data, QGuestAllocator *t_alloc) /* ... and is a regular file */ g_assert((st.st_mode & S_IFMT) == S_IFREG); - do_unlinkat(v9p, "04", "doa_file", 0); + tunlinkat({ .client = v9p, .atPath = "04", .name = "doa_file" }); /* file should be gone now */ g_assert(stat(new_file, &st) != 0); } @@ -643,7 +633,7 @@ static void fs_unlinkat_symlink(void *obj, void *data, }); g_assert(stat(symlink_file, &st) == 0); - do_unlinkat(v9p, "06", "symlink_file", 0); + tunlinkat({ .client = v9p, .atPath = "06", .name = "symlink_file" }); /* symlink should be gone now */ g_assert(stat(symlink_file, &st) != 0); } @@ -696,7 +686,7 @@ static void fs_unlinkat_hardlink(void *obj, void *data, }); g_assert(stat(hardlink_file, &st_link) == 0); - do_unlinkat(v9p, "08", "hardlink_file", 0); + tunlinkat({ .client = v9p, .atPath = "08", .name = "hardlink_file" }); /* symlink should be gone now */ g_assert(stat(hardlink_file, &st_link) != 0); /* and old file should still exist */ From 3ce77865bf813f313cf79c00fd951bfc95a50165 Mon Sep 17 00:00:00 2001 From: Christian Schoenebeck Date: Tue, 4 Oct 2022 22:54:30 +0200 Subject: [PATCH 084/705] tests/9p: remove unnecessary g_strdup() calls This is a leftover from before the recent function merge and refactoring patches: As these functions do not return control to the caller in between, it is not necessary to duplicate strings passed to them. Signed-off-by: Christian Schoenebeck Message-Id: <0f80141cde3904ed0591354059da49d1d60bcdbc.1664917004.git.qemu_oss@crudebyte.com> --- tests/qtest/libqos/virtio-9p-client.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/tests/qtest/libqos/virtio-9p-client.c b/tests/qtest/libqos/virtio-9p-client.c index e017e030ec..e4a368e036 100644 --- a/tests/qtest/libqos/virtio-9p-client.c +++ b/tests/qtest/libqos/virtio-9p-client.c @@ -770,7 +770,6 @@ TMkdirRes v9fs_tmkdir(TMkdirOpt opt) { P9Req *req; uint32_t err; - g_autofree char *name = g_strdup(opt.name); g_assert(opt.client); /* expecting either hi-level atPath or low-level dfid, but not both */ @@ -788,14 +787,14 @@ TMkdirRes v9fs_tmkdir(TMkdirOpt opt) } uint32_t body_size = 4 + 4 + 4; - uint16_t string_size = v9fs_string_size(name); + uint16_t string_size = v9fs_string_size(opt.name); g_assert_cmpint(body_size, <=, UINT32_MAX - string_size); body_size += string_size; req = v9fs_req_init(opt.client, body_size, P9_TMKDIR, opt.tag); v9fs_uint32_write(req, opt.dfid); - v9fs_string_write(req, name); + v9fs_string_write(req, opt.name); v9fs_uint32_write(req, opt.mode); v9fs_uint32_write(req, opt.gid); v9fs_req_send(req); @@ -831,7 +830,6 @@ TlcreateRes v9fs_tlcreate(TlcreateOpt opt) { P9Req *req; uint32_t err; - g_autofree char *name = g_strdup(opt.name); g_assert(opt.client); /* expecting either hi-level atPath or low-level fid, but not both */ @@ -849,14 +847,14 @@ TlcreateRes v9fs_tlcreate(TlcreateOpt opt) } uint32_t body_size = 4 + 4 + 4 + 4; - uint16_t string_size = v9fs_string_size(name); + uint16_t string_size = v9fs_string_size(opt.name); g_assert_cmpint(body_size, <=, UINT32_MAX - string_size); body_size += string_size; req = v9fs_req_init(opt.client, body_size, P9_TLCREATE, opt.tag); v9fs_uint32_write(req, opt.fid); - v9fs_string_write(req, name); + v9fs_string_write(req, opt.name); v9fs_uint32_write(req, opt.flags); v9fs_uint32_write(req, opt.mode); v9fs_uint32_write(req, opt.gid); @@ -896,8 +894,6 @@ TsymlinkRes v9fs_tsymlink(TsymlinkOpt opt) { P9Req *req; uint32_t err; - g_autofree char *name = g_strdup(opt.name); - g_autofree char *symtgt = g_strdup(opt.symtgt); g_assert(opt.client); /* expecting either hi-level atPath or low-level fid, but not both */ @@ -911,15 +907,16 @@ TsymlinkRes v9fs_tsymlink(TsymlinkOpt opt) } uint32_t body_size = 4 + 4; - uint16_t string_size = v9fs_string_size(name) + v9fs_string_size(symtgt); + uint16_t string_size = v9fs_string_size(opt.name) + + v9fs_string_size(opt.symtgt); g_assert_cmpint(body_size, <=, UINT32_MAX - string_size); body_size += string_size; req = v9fs_req_init(opt.client, body_size, P9_TSYMLINK, opt.tag); v9fs_uint32_write(req, opt.fid); - v9fs_string_write(req, name); - v9fs_string_write(req, symtgt); + v9fs_string_write(req, opt.name); + v9fs_string_write(req, opt.symtgt); v9fs_uint32_write(req, opt.gid); v9fs_req_send(req); From d0180f0acb142ca78e30857b8d8511ee9f3bd764 Mon Sep 17 00:00:00 2001 From: Julia Suvorova Date: Sun, 23 Oct 2022 21:58:12 +0200 Subject: [PATCH 085/705] hw/mem/nvdimm: fix error message for 'unarmed' flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the ACPI specification [1], the 'unarmed' bit is set when a device cannot accept a persistent write. This means that when a memdev is read-only, the 'unarmed' flag must be turned on. The logic is correct, just changing the error message. [1] ACPI NFIT NVDIMM Region Mapping Structure "NVDIMM State Flags" Bit 3 Fixes: dbd730e859 ("nvdimm: check -object memory-backend-file, readonly=on option") Signed-off-by: Julia Suvorova Reviewed-by: Stefan Hajnoczi Reviewed-by: Pankaj Gupta Reviewed-by: Philippe Mathieu-Daudé Acked-by: David Hildenbrand Message-Id: <20221023195812.15523-1-jusual@redhat.com> Signed-off-by: David Hildenbrand --- hw/mem/nvdimm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/mem/nvdimm.c b/hw/mem/nvdimm.c index 7c7d777781..31080c22c9 100644 --- a/hw/mem/nvdimm.c +++ b/hw/mem/nvdimm.c @@ -149,7 +149,7 @@ static void nvdimm_prepare_memory_region(NVDIMMDevice *nvdimm, Error **errp) if (!nvdimm->unarmed && memory_region_is_rom(mr)) { HostMemoryBackend *hostmem = dimm->hostmem; - error_setg(errp, "'unarmed' property must be off since memdev %s " + error_setg(errp, "'unarmed' property must be 'on' since memdev %s " "is read-only", object_get_canonical_path_component(OBJECT(hostmem))); return; From c1dadb8462ff5021218f2c1aa015594952f441ca Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Mon, 24 Oct 2022 15:28:02 +0800 Subject: [PATCH 086/705] treewide: Remove the unnecessary space before semicolon %s/return ;/return; Signed-off-by: Bin Meng Reviewed-by: Peter Maydell Reviewed-by: Christian Schoenebeck Message-Id: <20221024072802.457832-1-bmeng@tinylab.org> Signed-off-by: Laurent Vivier --- hw/9pfs/9p.c | 2 +- hw/dma/pl330.c | 2 +- hw/net/can/can_sja1000.c | 2 +- hw/timer/renesas_cmt.c | 2 +- hw/timer/renesas_tmr.c | 8 ++++---- hw/virtio/virtio-pci.c | 2 +- include/hw/elf_ops.h | 2 +- target/riscv/vector_helper.c | 2 +- target/rx/op_helper.c | 4 ++-- ui/vnc-jobs.c | 2 +- ui/vnc.c | 2 +- 11 files changed, 15 insertions(+), 15 deletions(-) diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c index aebadeaa03..76c591a01b 100644 --- a/hw/9pfs/9p.c +++ b/hw/9pfs/9p.c @@ -1786,7 +1786,7 @@ static void coroutine_fn v9fs_walk(void *opaque) err = pdu_unmarshal(pdu, offset, "ddw", &fid, &newfid, &nwnames); if (err < 0) { pdu_complete(pdu, err); - return ; + return; } offset += err; diff --git a/hw/dma/pl330.c b/hw/dma/pl330.c index 08e5938ec7..e5d521c329 100644 --- a/hw/dma/pl330.c +++ b/hw/dma/pl330.c @@ -1328,7 +1328,7 @@ static void pl330_debug_exec(PL330State *s) } if (!insn) { pl330_fault(ch, PL330_FAULT_UNDEF_INSTR | PL330_FAULT_DBG_INSTR); - return ; + return; } ch->stall = 0; insn->exec(ch, opcode, args, insn->size - 1); diff --git a/hw/net/can/can_sja1000.c b/hw/net/can/can_sja1000.c index e0f76d3eb3..73201f9139 100644 --- a/hw/net/can/can_sja1000.c +++ b/hw/net/can/can_sja1000.c @@ -431,7 +431,7 @@ void can_sja_mem_write(CanSJA1000State *s, hwaddr addr, uint64_t val, (unsigned long long)val, (unsigned int)addr); if (addr > CAN_SJA_MEM_SIZE) { - return ; + return; } if (s->clock & 0x80) { /* PeliCAN Mode */ diff --git a/hw/timer/renesas_cmt.c b/hw/timer/renesas_cmt.c index 2e0fd21a36..69eabc678a 100644 --- a/hw/timer/renesas_cmt.c +++ b/hw/timer/renesas_cmt.c @@ -57,7 +57,7 @@ static void update_events(RCMTState *cmt, int ch) if ((cmt->cmstr & (1 << ch)) == 0) { /* count disable, so not happened next event. */ - return ; + return; } next_time = cmt->cmcor[ch] - cmt->cmcnt[ch]; next_time *= NANOSECONDS_PER_SECOND; diff --git a/hw/timer/renesas_tmr.c b/hw/timer/renesas_tmr.c index d96002e1ee..c15f654738 100644 --- a/hw/timer/renesas_tmr.c +++ b/hw/timer/renesas_tmr.c @@ -67,18 +67,18 @@ static void update_events(RTMRState *tmr, int ch) int i, event; if (tmr->tccr[ch] == 0) { - return ; + return; } if (FIELD_EX8(tmr->tccr[ch], TCCR, CSS) == 0) { /* external clock mode */ /* event not happened */ - return ; + return; } if (FIELD_EX8(tmr->tccr[0], TCCR, CSS) == CSS_CASCADING) { /* cascading mode */ if (ch == 1) { tmr->next[ch] = none; - return ; + return; } diff[cmia] = concat_reg(tmr->tcora) - concat_reg(tmr->tcnt); diff[cmib] = concat_reg(tmr->tcorb) - concat_reg(tmr->tcnt); @@ -384,7 +384,7 @@ static void timer_events(RTMRState *tmr, int ch) tmr->tcorb[ch]) & 0xff; } else { if (ch == 1) { - return ; + return; } tcnt = issue_event(tmr, ch, 16, concat_reg(tmr->tcnt), diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index e7d80242b7..34db51e241 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -1675,7 +1675,7 @@ static void virtio_pci_device_plugged(DeviceState *d, Error **errp) if (virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM)) { error_setg(errp, "VIRTIO_F_IOMMU_PLATFORM was supported by" " neither legacy nor transitional device"); - return ; + return; } /* * Legacy and transitional devices use specific subsystem IDs. diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h index 7c3b1d0f6c..fbe0b1e956 100644 --- a/include/hw/elf_ops.h +++ b/include/hw/elf_ops.h @@ -117,7 +117,7 @@ static void glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab, shdr_table = load_at(fd, ehdr->e_shoff, sizeof(struct elf_shdr) * ehdr->e_shnum); if (!shdr_table) { - return ; + return; } if (must_swab) { diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index b94f809eb3..0020b9a95d 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -211,7 +211,7 @@ static void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt, return; } if (tot - cnt == 0) { - return ; + return; } memset(base + cnt, -1, tot - cnt); } diff --git a/target/rx/op_helper.c b/target/rx/op_helper.c index 9ca32dcc82..acce650185 100644 --- a/target/rx/op_helper.c +++ b/target/rx/op_helper.c @@ -286,7 +286,7 @@ void helper_suntil(CPURXState *env, uint32_t sz) uint32_t tmp; tcg_debug_assert(sz < 3); if (env->regs[3] == 0) { - return ; + return; } do { tmp = cpu_ldufn[sz](env, env->regs[1], GETPC()); @@ -305,7 +305,7 @@ void helper_swhile(CPURXState *env, uint32_t sz) uint32_t tmp; tcg_debug_assert(sz < 3); if (env->regs[3] == 0) { - return ; + return; } do { tmp = cpu_ldufn[sz](env, env->regs[1], GETPC()); diff --git a/ui/vnc-jobs.c b/ui/vnc-jobs.c index 4562bf8928..886f9bf611 100644 --- a/ui/vnc-jobs.c +++ b/ui/vnc-jobs.c @@ -373,7 +373,7 @@ void vnc_start_worker_thread(void) VncJobQueue *q; if (vnc_worker_thread_running()) - return ; + return; q = vnc_queue_init(); qemu_thread_create(&q->thread, "vnc_worker", vnc_worker_thread, q, diff --git a/ui/vnc.c b/ui/vnc.c index acb3629cd8..88f55cbf3c 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -3085,7 +3085,7 @@ static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv) rect = vnc_stat_rect(vd, x, y); if (rect->updated) { - return ; + return; } rect->times[rect->idx] = *tv; rect->idx = (rect->idx + 1) % ARRAY_SIZE(rect->times); From cf6280b99b42630d74c197fb2cd68d1a5d8673f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Volker=20R=C3=BCmelin?= Date: Sat, 22 Oct 2022 16:12:04 +0200 Subject: [PATCH 087/705] ui: remove useless typecasts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 8f9abdf586 ("chardev: src buffer const for write functions") changed the type of the second parameter of qemu_chr_be_write() from uint8_t * to const uint8_t *. Remove the now useless type casts from qemu_chr_be_write() function calls in ui/console.c and ui/gtk.c. Cc: qemu-trivial@nongnu.org Signed-off-by: Volker Rümelin Reviewed-by: Markus Armbruster Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Claudio Fontana Message-Id: <20221022141204.29358-1-vr_qemu@t-online.de> Signed-off-by: Laurent Vivier --- ui/console.c | 2 +- ui/gtk.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/console.c b/ui/console.c index 49da6a91df..65c117874c 100644 --- a/ui/console.c +++ b/ui/console.c @@ -1297,7 +1297,7 @@ static void kbd_send_chars(QemuConsole *s) uint32_t size; buf = fifo8_pop_buf(&s->out_fifo, MIN(len, avail), &size); - qemu_chr_be_write(s->chr, (uint8_t *)buf, size); + qemu_chr_be_write(s->chr, buf, size); len = qemu_chr_be_can_write(s->chr); avail -= size; } diff --git a/ui/gtk.c b/ui/gtk.c index 92daaa6a6e..7ec21f7798 100644 --- a/ui/gtk.c +++ b/ui/gtk.c @@ -1763,7 +1763,7 @@ static void gd_vc_send_chars(VirtualConsole *vc) uint32_t size; buf = fifo8_pop_buf(&vc->vte.out_fifo, MIN(len, avail), &size); - qemu_chr_be_write(vc->vte.chr, (uint8_t *)buf, size); + qemu_chr_be_write(vc->vte.chr, buf, size); len = qemu_chr_be_can_write(vc->vte.chr); avail -= size; } From 046ab3b80891f4aa6d0cfd7db15c622b1933e598 Mon Sep 17 00:00:00 2001 From: Matheus Tavares Bernardino Date: Fri, 21 Oct 2022 14:36:06 -0300 Subject: [PATCH 088/705] accel/tcg/tcg-accel-ops-rr: fix trivial typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matheus Tavares Bernardino Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Claudio Fontana Message-Id: <5dc556dbe241ae03859b7890d1998de5c77b7c6c.1666373742.git.quic_mathbern@quicinc.com> Signed-off-by: Laurent Vivier --- accel/tcg/tcg-accel-ops-rr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accel/tcg/tcg-accel-ops-rr.c b/accel/tcg/tcg-accel-ops-rr.c index cc8adc2380..cc912df108 100644 --- a/accel/tcg/tcg-accel-ops-rr.c +++ b/accel/tcg/tcg-accel-ops-rr.c @@ -51,7 +51,7 @@ void rr_kick_vcpu_thread(CPUState *unused) * * The kick timer is responsible for moving single threaded vCPU * emulation on to the next vCPU. If more than one vCPU is running a - * timer event with force a cpu->exit so the next vCPU can get + * timer event we force a cpu->exit so the next vCPU can get * scheduled. * * The timer is removed if all vCPUs are idle and restarted again once From e41ed29bcee5cb16715317bcf290f6b5c196eb0a Mon Sep 17 00:00:00 2001 From: Janosch Frank Date: Mon, 17 Oct 2022 08:38:13 +0000 Subject: [PATCH 089/705] dump: Use a buffer for ELF section data and headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently we're writing the NULL section header if we overflow the physical header number in the ELF header. But in the future we'll add custom section headers AND section data. To facilitate this we need to rearange section handling a bit. As with the other ELF headers we split the code into a prepare and a write step. Signed-off-by: Janosch Frank Reviewed-by: Marc-André Lureau Message-Id: <20221017083822.43118-2-frankja@linux.ibm.com> --- dump/dump.c | 79 +++++++++++++++++++++++++++++-------------- include/sysemu/dump.h | 2 ++ 2 files changed, 55 insertions(+), 26 deletions(-) diff --git a/dump/dump.c b/dump/dump.c index 236559b03a..e7a3b54ebe 100644 --- a/dump/dump.c +++ b/dump/dump.c @@ -380,31 +380,60 @@ static void write_elf_phdr_note(DumpState *s, Error **errp) } } -static void write_elf_section(DumpState *s, int type, Error **errp) +static void prepare_elf_section_hdr_zero(DumpState *s) { - Elf32_Shdr shdr32; - Elf64_Shdr shdr64; - int shdr_size; - void *shdr; + if (dump_is_64bit(s)) { + Elf64_Shdr *shdr64 = s->elf_section_hdrs; + + shdr64->sh_info = cpu_to_dump32(s, s->phdr_num); + } else { + Elf32_Shdr *shdr32 = s->elf_section_hdrs; + + shdr32->sh_info = cpu_to_dump32(s, s->phdr_num); + } +} + +static void prepare_elf_section_hdrs(DumpState *s) +{ + size_t len, sizeof_shdr; + + /* + * Section ordering: + * - HDR zero + */ + sizeof_shdr = dump_is_64bit(s) ? sizeof(Elf64_Shdr) : sizeof(Elf32_Shdr); + len = sizeof_shdr * s->shdr_num; + s->elf_section_hdrs = g_malloc0(len); + + /* + * The first section header is ALWAYS a special initial section + * header. + * + * The header should be 0 with one exception being that if + * phdr_num is PN_XNUM then the sh_info field contains the real + * number of segment entries. + * + * As we zero allocate the buffer we will only need to modify + * sh_info for the PN_XNUM case. + */ + if (s->phdr_num >= PN_XNUM) { + prepare_elf_section_hdr_zero(s); + } +} + +static void write_elf_section_headers(DumpState *s, Error **errp) +{ + size_t sizeof_shdr = dump_is_64bit(s) ? sizeof(Elf64_Shdr) : sizeof(Elf32_Shdr); int ret; - if (type == 0) { - shdr_size = sizeof(Elf32_Shdr); - memset(&shdr32, 0, shdr_size); - shdr32.sh_info = cpu_to_dump32(s, s->phdr_num); - shdr = &shdr32; - } else { - shdr_size = sizeof(Elf64_Shdr); - memset(&shdr64, 0, shdr_size); - shdr64.sh_info = cpu_to_dump32(s, s->phdr_num); - shdr = &shdr64; + prepare_elf_section_hdrs(s); + + ret = fd_write_vmcore(s->elf_section_hdrs, s->shdr_num * sizeof_shdr, s); + if (ret < 0) { + error_setg_errno(errp, -ret, "dump: failed to write section headers"); } - ret = fd_write_vmcore(shdr, shdr_size, s); - if (ret < 0) { - error_setg_errno(errp, -ret, - "dump: failed to write section header table"); - } + g_free(s->elf_section_hdrs); } static void write_data(DumpState *s, void *buf, int length, Error **errp) @@ -591,12 +620,10 @@ static void dump_begin(DumpState *s, Error **errp) return; } - /* write section to vmcore */ - if (s->shdr_num) { - write_elf_section(s, 1, errp); - if (*errp) { - return; - } + /* write section headers to vmcore */ + write_elf_section_headers(s, errp); + if (*errp) { + return; } /* write notes to vmcore */ diff --git a/include/sysemu/dump.h b/include/sysemu/dump.h index b62513d87d..9995f65dc8 100644 --- a/include/sysemu/dump.h +++ b/include/sysemu/dump.h @@ -177,6 +177,8 @@ typedef struct DumpState { int64_t filter_area_begin; /* Start address of partial guest memory area */ int64_t filter_area_length; /* Length of partial guest memory area */ + void *elf_section_hdrs; /* Pointer to section header buffer */ + uint8_t *note_buf; /* buffer for notes */ size_t note_buf_offset; /* the writing place in note_buf */ uint32_t nr_cpus; /* number of guest's cpu */ From cb415fd61e48d52f81dcf38956e3f913651cff1c Mon Sep 17 00:00:00 2001 From: Janosch Frank Date: Mon, 17 Oct 2022 08:38:14 +0000 Subject: [PATCH 090/705] dump: Write ELF section headers right after ELF header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Let's start bundling the writes of the headers and of the data so we have a clear ordering between them. Since the ELF header uses offsets to the headers we can freely order them. Signed-off-by: Janosch Frank Reviewed-by: Marc-André Lureau Message-Id: <20221017083822.43118-3-frankja@linux.ibm.com> --- dump/dump.c | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/dump/dump.c b/dump/dump.c index e7a3b54ebe..b168a25321 100644 --- a/dump/dump.c +++ b/dump/dump.c @@ -583,6 +583,8 @@ static void dump_begin(DumpState *s, Error **errp) * -------------- * | elf header | * -------------- + * | sctn_hdr | + * -------------- * | PT_NOTE | * -------------- * | PT_LOAD | @@ -591,8 +593,6 @@ static void dump_begin(DumpState *s, Error **errp) * -------------- * | PT_LOAD | * -------------- - * | sec_hdr | - * -------------- * | elf note | * -------------- * | memory | @@ -608,6 +608,12 @@ static void dump_begin(DumpState *s, Error **errp) return; } + /* write section headers to vmcore */ + write_elf_section_headers(s, errp); + if (*errp) { + return; + } + /* write PT_NOTE to vmcore */ write_elf_phdr_note(s, errp); if (*errp) { @@ -620,12 +626,6 @@ static void dump_begin(DumpState *s, Error **errp) return; } - /* write section headers to vmcore */ - write_elf_section_headers(s, errp); - if (*errp) { - return; - } - /* write notes to vmcore */ write_elf_notes(s, errp); } @@ -1868,16 +1868,13 @@ static void dump_init(DumpState *s, int fd, bool has_format, } if (dump_is_64bit(s)) { - s->phdr_offset = sizeof(Elf64_Ehdr); - s->shdr_offset = s->phdr_offset + sizeof(Elf64_Phdr) * s->phdr_num; - s->note_offset = s->shdr_offset + sizeof(Elf64_Shdr) * s->shdr_num; - s->memory_offset = s->note_offset + s->note_size; + s->shdr_offset = sizeof(Elf64_Ehdr); + s->phdr_offset = s->shdr_offset + sizeof(Elf64_Shdr) * s->shdr_num; + s->note_offset = s->phdr_offset + sizeof(Elf64_Phdr) * s->phdr_num; } else { - - s->phdr_offset = sizeof(Elf32_Ehdr); - s->shdr_offset = s->phdr_offset + sizeof(Elf32_Phdr) * s->phdr_num; - s->note_offset = s->shdr_offset + sizeof(Elf32_Shdr) * s->shdr_num; - s->memory_offset = s->note_offset + s->note_size; + s->shdr_offset = sizeof(Elf32_Ehdr); + s->phdr_offset = s->shdr_offset + sizeof(Elf32_Shdr) * s->shdr_num; + s->note_offset = s->phdr_offset + sizeof(Elf32_Phdr) * s->phdr_num; } return; From 8384b73c46fd474847d7e74d121318e344edc3c4 Mon Sep 17 00:00:00 2001 From: Janosch Frank Date: Mon, 17 Oct 2022 08:38:15 +0000 Subject: [PATCH 091/705] dump: Reorder struct DumpState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Let's move ELF related members into one block and guest memory related ones into another to improve readability. Signed-off-by: Janosch Frank Reviewed-by: Richard Henderson Reviewed-by: Marc-André Lureau Message-Id: <20221017083822.43118-4-frankja@linux.ibm.com> --- include/sysemu/dump.h | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/include/sysemu/dump.h b/include/sysemu/dump.h index 9995f65dc8..9ed811b313 100644 --- a/include/sysemu/dump.h +++ b/include/sysemu/dump.h @@ -154,15 +154,8 @@ typedef struct DumpState { GuestPhysBlockList guest_phys_blocks; ArchDumpInfo dump_info; MemoryMappingList list; - uint32_t phdr_num; - uint32_t shdr_num; bool resume; bool detached; - ssize_t note_size; - hwaddr shdr_offset; - hwaddr phdr_offset; - hwaddr section_offset; - hwaddr note_offset; hwaddr memory_offset; int fd; @@ -177,6 +170,15 @@ typedef struct DumpState { int64_t filter_area_begin; /* Start address of partial guest memory area */ int64_t filter_area_length; /* Length of partial guest memory area */ + /* Elf dump related data */ + uint32_t phdr_num; + uint32_t shdr_num; + ssize_t note_size; + hwaddr shdr_offset; + hwaddr phdr_offset; + hwaddr section_offset; + hwaddr note_offset; + void *elf_section_hdrs; /* Pointer to section header buffer */ uint8_t *note_buf; /* buffer for notes */ From 13fd417ddc81a1685c6a8f4e1c80bbfe7150f164 Mon Sep 17 00:00:00 2001 From: Janosch Frank Date: Mon, 17 Oct 2022 08:38:16 +0000 Subject: [PATCH 092/705] dump: Reintroduce memory_offset and section_offset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit section_offset will later be used to store the offset to the section data which will be stored last. For now memory_offset is only needed to make section_offset look nicer. Signed-off-by: Janosch Frank Reviewed-by: Marc-André Lureau Message-Id: <20221017083822.43118-5-frankja@linux.ibm.com> --- dump/dump.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dump/dump.c b/dump/dump.c index b168a25321..626f7b2fd0 100644 --- a/dump/dump.c +++ b/dump/dump.c @@ -1876,6 +1876,8 @@ static void dump_init(DumpState *s, int fd, bool has_format, s->phdr_offset = s->shdr_offset + sizeof(Elf32_Shdr) * s->shdr_num; s->note_offset = s->phdr_offset + sizeof(Elf32_Phdr) * s->phdr_num; } + s->memory_offset = s->note_offset + s->note_size; + s->section_offset = s->memory_offset + s->total_size; return; From 9b72224f44612ddd5b434a1bccf79346946d11da Mon Sep 17 00:00:00 2001 From: Janosch Frank Date: Mon, 17 Oct 2022 11:32:10 +0000 Subject: [PATCH 093/705] dump: Add architecture section and section string table support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add hooks which architectures can use to add arbitrary data to custom sections. Also add a section name string table in order to identify section contents Signed-off-by: Janosch Frank Reviewed-by: Marc-André Lureau Message-Id: <20221017113210.41674-1-frankja@linux.ibm.com> --- dump/dump.c | 190 +++++++++++++++++++++++++++++++------ include/sysemu/dump-arch.h | 3 + include/sysemu/dump.h | 3 + 3 files changed, 168 insertions(+), 28 deletions(-) diff --git a/dump/dump.c b/dump/dump.c index 626f7b2fd0..9428d1fde9 100644 --- a/dump/dump.c +++ b/dump/dump.c @@ -103,6 +103,7 @@ static int dump_cleanup(DumpState *s) memory_mapping_list_free(&s->list); close(s->fd); g_free(s->guest_note); + g_array_unref(s->string_table_buf); s->guest_note = NULL; if (s->resume) { if (s->detached) { @@ -152,11 +153,10 @@ static void prepare_elf64_header(DumpState *s, Elf64_Ehdr *elf_header) elf_header->e_phoff = cpu_to_dump64(s, s->phdr_offset); elf_header->e_phentsize = cpu_to_dump16(s, sizeof(Elf64_Phdr)); elf_header->e_phnum = cpu_to_dump16(s, phnum); - if (s->shdr_num) { - elf_header->e_shoff = cpu_to_dump64(s, s->shdr_offset); - elf_header->e_shentsize = cpu_to_dump16(s, sizeof(Elf64_Shdr)); - elf_header->e_shnum = cpu_to_dump16(s, s->shdr_num); - } + elf_header->e_shoff = cpu_to_dump64(s, s->shdr_offset); + elf_header->e_shentsize = cpu_to_dump16(s, sizeof(Elf64_Shdr)); + elf_header->e_shnum = cpu_to_dump16(s, s->shdr_num); + elf_header->e_shstrndx = cpu_to_dump16(s, s->shdr_num - 1); } static void prepare_elf32_header(DumpState *s, Elf32_Ehdr *elf_header) @@ -180,11 +180,10 @@ static void prepare_elf32_header(DumpState *s, Elf32_Ehdr *elf_header) elf_header->e_phoff = cpu_to_dump32(s, s->phdr_offset); elf_header->e_phentsize = cpu_to_dump16(s, sizeof(Elf32_Phdr)); elf_header->e_phnum = cpu_to_dump16(s, phnum); - if (s->shdr_num) { - elf_header->e_shoff = cpu_to_dump32(s, s->shdr_offset); - elf_header->e_shentsize = cpu_to_dump16(s, sizeof(Elf32_Shdr)); - elf_header->e_shnum = cpu_to_dump16(s, s->shdr_num); - } + elf_header->e_shoff = cpu_to_dump32(s, s->shdr_offset); + elf_header->e_shentsize = cpu_to_dump16(s, sizeof(Elf32_Shdr)); + elf_header->e_shnum = cpu_to_dump16(s, s->shdr_num); + elf_header->e_shstrndx = cpu_to_dump16(s, s->shdr_num - 1); } static void write_elf_header(DumpState *s, Error **errp) @@ -195,6 +194,8 @@ static void write_elf_header(DumpState *s, Error **errp) void *header_ptr; int ret; + /* The NULL header and the shstrtab are always defined */ + assert(s->shdr_num >= 2); if (dump_is_64bit(s)) { prepare_elf64_header(s, &elf64_header); header_size = sizeof(elf64_header); @@ -393,17 +394,49 @@ static void prepare_elf_section_hdr_zero(DumpState *s) } } -static void prepare_elf_section_hdrs(DumpState *s) +static void prepare_elf_section_hdr_string(DumpState *s, void *buff) +{ + uint64_t index = s->string_table_buf->len; + const char strtab[] = ".shstrtab"; + Elf32_Shdr shdr32 = {}; + Elf64_Shdr shdr64 = {}; + int shdr_size; + void *shdr; + + g_array_append_vals(s->string_table_buf, strtab, sizeof(strtab)); + if (dump_is_64bit(s)) { + shdr_size = sizeof(Elf64_Shdr); + shdr64.sh_type = SHT_STRTAB; + shdr64.sh_offset = s->section_offset + s->elf_section_data_size; + shdr64.sh_name = index; + shdr64.sh_size = s->string_table_buf->len; + shdr = &shdr64; + } else { + shdr_size = sizeof(Elf32_Shdr); + shdr32.sh_type = SHT_STRTAB; + shdr32.sh_offset = s->section_offset + s->elf_section_data_size; + shdr32.sh_name = index; + shdr32.sh_size = s->string_table_buf->len; + shdr = &shdr32; + } + memcpy(buff, shdr, shdr_size); +} + +static bool prepare_elf_section_hdrs(DumpState *s, Error **errp) { size_t len, sizeof_shdr; + void *buff_hdr; /* * Section ordering: * - HDR zero + * - Arch section hdrs + * - String table hdr */ sizeof_shdr = dump_is_64bit(s) ? sizeof(Elf64_Shdr) : sizeof(Elf32_Shdr); len = sizeof_shdr * s->shdr_num; s->elf_section_hdrs = g_malloc0(len); + buff_hdr = s->elf_section_hdrs; /* * The first section header is ALWAYS a special initial section @@ -419,6 +452,26 @@ static void prepare_elf_section_hdrs(DumpState *s) if (s->phdr_num >= PN_XNUM) { prepare_elf_section_hdr_zero(s); } + buff_hdr += sizeof_shdr; + + /* Add architecture defined section headers */ + if (s->dump_info.arch_sections_write_hdr_fn + && s->shdr_num > 2) { + buff_hdr += s->dump_info.arch_sections_write_hdr_fn(s, buff_hdr); + + if (s->shdr_num >= SHN_LORESERVE) { + error_setg_errno(errp, EINVAL, + "dump: too many architecture defined sections"); + return false; + } + } + + /* + * String table is the last section since strings are added via + * arch_sections_write_hdr(). + */ + prepare_elf_section_hdr_string(s, buff_hdr); + return true; } static void write_elf_section_headers(DumpState *s, Error **errp) @@ -426,7 +479,9 @@ static void write_elf_section_headers(DumpState *s, Error **errp) size_t sizeof_shdr = dump_is_64bit(s) ? sizeof(Elf64_Shdr) : sizeof(Elf32_Shdr); int ret; - prepare_elf_section_hdrs(s); + if (!prepare_elf_section_hdrs(s, errp)) { + return; + } ret = fd_write_vmcore(s->elf_section_hdrs, s->shdr_num * sizeof_shdr, s); if (ret < 0) { @@ -436,6 +491,29 @@ static void write_elf_section_headers(DumpState *s, Error **errp) g_free(s->elf_section_hdrs); } +static void write_elf_sections(DumpState *s, Error **errp) +{ + int ret; + + if (s->elf_section_data_size) { + /* Write architecture section data */ + ret = fd_write_vmcore(s->elf_section_data, + s->elf_section_data_size, s); + if (ret < 0) { + error_setg_errno(errp, -ret, + "dump: failed to write architecture section data"); + return; + } + } + + /* Write string table */ + ret = fd_write_vmcore(s->string_table_buf->data, + s->string_table_buf->len, s); + if (ret < 0) { + error_setg_errno(errp, -ret, "dump: failed to write string table data"); + } +} + static void write_data(DumpState *s, void *buf, int length, Error **errp) { int ret; @@ -692,6 +770,31 @@ static void dump_iterate(DumpState *s, Error **errp) } } +static void dump_end(DumpState *s, Error **errp) +{ + int rc; + ERRP_GUARD(); + + if (s->elf_section_data_size) { + s->elf_section_data = g_malloc0(s->elf_section_data_size); + } + + /* Adds the architecture defined section data to s->elf_section_data */ + if (s->dump_info.arch_sections_write_fn && + s->elf_section_data_size) { + rc = s->dump_info.arch_sections_write_fn(s, s->elf_section_data); + if (rc) { + error_setg_errno(errp, rc, + "dump: failed to get arch section data"); + g_free(s->elf_section_data); + return; + } + } + + /* write sections to vmcore */ + write_elf_sections(s, errp); +} + static void create_vmcore(DumpState *s, Error **errp) { ERRP_GUARD(); @@ -701,7 +804,14 @@ static void create_vmcore(DumpState *s, Error **errp) return; } + /* Iterate over memory and dump it to file */ dump_iterate(s, errp); + if (*errp) { + return; + } + + /* Write the section data */ + dump_end(s, errp); } static int write_start_flat_header(int fd) @@ -1711,6 +1821,14 @@ static void dump_init(DumpState *s, int fd, bool has_format, s->filter_area_begin = begin; s->filter_area_length = length; + /* First index is 0, it's the special null name */ + s->string_table_buf = g_array_new(FALSE, TRUE, 1); + /* + * Allocate the null name, due to the clearing option set to true + * it will be 0. + */ + g_array_set_size(s->string_table_buf, 1); + memory_mapping_list_init(&s->list); guest_phys_blocks_init(&s->guest_phys_blocks); @@ -1847,26 +1965,42 @@ static void dump_init(DumpState *s, int fd, bool has_format, } /* - * calculate phdr_num - * - * the type of ehdr->e_phnum is uint16_t, so we should avoid overflow + * The first section header is always a special one in which most + * fields are 0. The section header string table is also always + * set. */ - s->phdr_num = 1; /* PT_NOTE */ - if (s->list.num < UINT16_MAX - 2) { - s->shdr_num = 0; - s->phdr_num += s->list.num; - } else { - /* sh_info of section 0 holds the real number of phdrs */ - s->shdr_num = 1; + s->shdr_num = 2; - /* the type of shdr->sh_info is uint32_t, so we should avoid overflow */ - if (s->list.num <= UINT32_MAX - 1) { - s->phdr_num += s->list.num; - } else { - s->phdr_num = UINT32_MAX; - } + /* + * Adds the number of architecture sections to shdr_num and sets + * elf_section_data_size so we know the offsets and sizes of all + * parts. + */ + if (s->dump_info.arch_sections_add_fn) { + s->dump_info.arch_sections_add_fn(s); } + /* + * calculate shdr_num so we know the offsets and sizes of all + * parts. + * Calculate phdr_num + * + * The absolute maximum amount of phdrs is UINT32_MAX - 1 as + * sh_info is 32 bit. There's special handling once we go over + * UINT16_MAX - 1 but that is handled in the ehdr and section + * code. + */ + s->phdr_num = 1; /* Reserve PT_NOTE */ + if (s->list.num <= UINT32_MAX - 1) { + s->phdr_num += s->list.num; + } else { + s->phdr_num = UINT32_MAX; + } + + /* + * Now that the number of section and program headers is known we + * can calculate the offsets of the headers and data. + */ if (dump_is_64bit(s)) { s->shdr_offset = sizeof(Elf64_Ehdr); s->phdr_offset = s->shdr_offset + sizeof(Elf64_Shdr) * s->shdr_num; diff --git a/include/sysemu/dump-arch.h b/include/sysemu/dump-arch.h index e25b02e990..59bbc9be38 100644 --- a/include/sysemu/dump-arch.h +++ b/include/sysemu/dump-arch.h @@ -21,6 +21,9 @@ typedef struct ArchDumpInfo { uint32_t page_size; /* The target's page size. If it's variable and * unknown, then this should be the maximum. */ uint64_t phys_base; /* The target's physmem base. */ + void (*arch_sections_add_fn)(DumpState *s); + uint64_t (*arch_sections_write_hdr_fn)(DumpState *s, uint8_t *buff); + int (*arch_sections_write_fn)(DumpState *s, uint8_t *buff); } ArchDumpInfo; struct GuestPhysBlockList; /* memory_mapping.h */ diff --git a/include/sysemu/dump.h b/include/sysemu/dump.h index 9ed811b313..38ccac7190 100644 --- a/include/sysemu/dump.h +++ b/include/sysemu/dump.h @@ -180,6 +180,9 @@ typedef struct DumpState { hwaddr note_offset; void *elf_section_hdrs; /* Pointer to section header buffer */ + void *elf_section_data; /* Pointer to section data buffer */ + uint64_t elf_section_data_size; /* Size of section data */ + GArray *string_table_buf; /* String table data buffer */ uint8_t *note_buf; /* buffer for notes */ size_t note_buf_offset; /* the writing place in note_buf */ From bd5ccd61080abf976a6a6cc2d09d31299bea0cee Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Mon, 24 Oct 2022 22:18:09 +0200 Subject: [PATCH 094/705] linux-user: Add guest memory layout to exception dump When the emulation stops with a hard exception it's very useful for debugging purposes to dump the current guest memory layout (for an example see /proc/self/maps) beside the CPU registers. The open_self_maps() function provides such a memory dump, but since it's located in the syscall.c file, various changes (add #includes, make this function externally visible, ...) are needed to be able to call it from the existing EXCP_DUMP() macro. This patch takes another approach by re-defining EXCP_DUMP() to call target_exception_dump(), which is in syscall.c, consolidates the log print functions and allows to add the call to dump the memory layout. Beside a reduced code footprint, this approach keeps the changes across the various callers minimal, and keeps EXCP_DUMP() highlighted as important macro/function. Signed-off-by: Helge Deller Reviewed-by: Richard Henderson Message-Id: [lv: remove pc declaration and setting] Signed-off-by: Laurent Vivier --- linux-user/cpu_loop-common.h | 15 +++------------ linux-user/i386/cpu_loop.c | 6 ++---- linux-user/syscall.c | 28 ++++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 16 deletions(-) diff --git a/linux-user/cpu_loop-common.h b/linux-user/cpu_loop-common.h index 36ff5b14f2..e644d2ef90 100644 --- a/linux-user/cpu_loop-common.h +++ b/linux-user/cpu_loop-common.h @@ -23,18 +23,9 @@ #include "exec/log.h" #include "special-errno.h" -#define EXCP_DUMP(env, fmt, ...) \ -do { \ - CPUState *cs = env_cpu(env); \ - fprintf(stderr, fmt , ## __VA_ARGS__); \ - fprintf(stderr, "Failing executable: %s\n", exec_path); \ - cpu_dump_state(cs, stderr, 0); \ - if (qemu_log_separate()) { \ - qemu_log(fmt, ## __VA_ARGS__); \ - qemu_log("Failing executable: %s\n", exec_path); \ - log_cpu_state(cs, 0); \ - } \ -} while (0) +void target_exception_dump(CPUArchState *env, const char *fmt, int code); +#define EXCP_DUMP(env, fmt, code) \ + target_exception_dump(env, fmt, code) void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs); #endif diff --git a/linux-user/i386/cpu_loop.c b/linux-user/i386/cpu_loop.c index 42837399bc..865413c08f 100644 --- a/linux-user/i386/cpu_loop.c +++ b/linux-user/i386/cpu_loop.c @@ -201,7 +201,6 @@ void cpu_loop(CPUX86State *env) { CPUState *cs = env_cpu(env); int trapnr; - abi_ulong pc; abi_ulong ret; for(;;) { @@ -307,9 +306,8 @@ void cpu_loop(CPUX86State *env) cpu_exec_step_atomic(cs); break; default: - pc = env->segs[R_CS].base + env->eip; - EXCP_DUMP(env, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n", - (long)pc, trapnr); + EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", + trapnr); abort(); } process_pending_signals(env); diff --git a/linux-user/syscall.c b/linux-user/syscall.c index e985ad167f..8402c1399d 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -183,6 +183,7 @@ struct file_clone_range { #include "qapi/error.h" #include "fd-trans.h" #include "tcg/tcg.h" +#include "cpu_loop-common.h" #ifndef CLONE_IO #define CLONE_IO 0x80000000 /* Clone io context */ @@ -8169,6 +8170,33 @@ static int is_proc_myself(const char *filename, const char *entry) return 0; } +static void excp_dump_file(FILE *logfile, CPUArchState *env, + const char *fmt, int code) +{ + if (logfile) { + CPUState *cs = env_cpu(env); + + fprintf(logfile, fmt, code); + fprintf(logfile, "Failing executable: %s\n", exec_path); + cpu_dump_state(cs, logfile, 0); + open_self_maps(env, fileno(logfile)); + } +} + +void target_exception_dump(CPUArchState *env, const char *fmt, int code) +{ + /* dump to console */ + excp_dump_file(stderr, env, fmt, code); + + /* dump to log file */ + if (qemu_log_separate()) { + FILE *logfile = qemu_log_trylock(); + + excp_dump_file(logfile, env, fmt, code); + qemu_log_unlock(logfile); + } +} + #if HOST_BIG_ENDIAN != TARGET_BIG_ENDIAN || \ defined(TARGET_SPARC) || defined(TARGET_M68K) || defined(TARGET_HPPA) static int is_proc(const char *filename, const char *entry) From 0585105c806d3bf301eebc33115a0790fcfc1d9c Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 21 Oct 2022 17:34:09 +0100 Subject: [PATCH 095/705] Revert "accel/tcg: Init TCG cflags in vCPU thread handler" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit a82fd5a4ec24d was intended to be a code cleanup, but unfortunately it has a bug. It moves the initialization of the TCG cflags from the "start a new vcpu" function to the thread handler; this is fine when each vcpu has its own thread, but when we are doing round-robin of vcpus on a single thread we end up only initializing the cflags for CPU 0, not for any of the others. The most obvious effect of this bug is that running in icount mode with more than one CPU is broken; typically the guest hangs shortly after it brings up the secondary CPUs. This reverts commit a82fd5a4ec24d923ff1e6da128c0fd4a74079d99. Cc: qemu-stable@nongnu.org Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Signed-off-by: Peter Maydell Message-Id: <20221021163409.3674911-1-peter.maydell@linaro.org> Signed-off-by: Richard Henderson --- accel/tcg/tcg-accel-ops-mttcg.c | 5 +++-- accel/tcg/tcg-accel-ops-rr.c | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/accel/tcg/tcg-accel-ops-mttcg.c b/accel/tcg/tcg-accel-ops-mttcg.c index ba997f6cfe..d50239e0e2 100644 --- a/accel/tcg/tcg-accel-ops-mttcg.c +++ b/accel/tcg/tcg-accel-ops-mttcg.c @@ -70,8 +70,6 @@ static void *mttcg_cpu_thread_fn(void *arg) assert(tcg_enabled()); g_assert(!icount_enabled()); - tcg_cpu_init_cflags(cpu, current_machine->smp.max_cpus > 1); - rcu_register_thread(); force_rcu.notifier.notify = mttcg_force_rcu; force_rcu.cpu = cpu; @@ -141,6 +139,9 @@ void mttcg_start_vcpu_thread(CPUState *cpu) { char thread_name[VCPU_THREAD_NAME_SIZE]; + g_assert(tcg_enabled()); + tcg_cpu_init_cflags(cpu, current_machine->smp.max_cpus > 1); + cpu->thread = g_new0(QemuThread, 1); cpu->halt_cond = g_malloc0(sizeof(QemuCond)); qemu_cond_init(cpu->halt_cond); diff --git a/accel/tcg/tcg-accel-ops-rr.c b/accel/tcg/tcg-accel-ops-rr.c index cc8adc2380..1a72149f0e 100644 --- a/accel/tcg/tcg-accel-ops-rr.c +++ b/accel/tcg/tcg-accel-ops-rr.c @@ -152,9 +152,7 @@ static void *rr_cpu_thread_fn(void *arg) Notifier force_rcu; CPUState *cpu = arg; - g_assert(tcg_enabled()); - tcg_cpu_init_cflags(cpu, false); - + assert(tcg_enabled()); rcu_register_thread(); force_rcu.notify = rr_force_rcu; rcu_add_force_rcu_notifier(&force_rcu); @@ -277,6 +275,9 @@ void rr_start_vcpu_thread(CPUState *cpu) static QemuCond *single_tcg_halt_cond; static QemuThread *single_tcg_cpu_thread; + g_assert(tcg_enabled()); + tcg_cpu_init_cflags(cpu, false); + if (!single_tcg_cpu_thread) { cpu->thread = g_new0(QemuThread, 1); cpu->halt_cond = g_new0(QemuCond, 1); From f072a1ae7fb47db75eb3c6b960759c908884f585 Mon Sep 17 00:00:00 2001 From: Qi Hu Date: Sat, 15 Oct 2022 17:27:54 +0800 Subject: [PATCH 096/705] tcg/loongarch64: Add direct jump support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Similar to the ARM64, LoongArch has PC-relative instructions such as PCADDU18I. These instructions can be used to support direct jump for LoongArch. Additionally, if instruction "B offset" can cover the target address(target is within ±128MB range), a single "B offset" plus a nop will be used by "tb_target_set_jump_target". Signed-off-by: Qi Hu Reviewed-by: Richard Henderson Reviewed-by: WANG Xuerui Message-Id: <20221015092754.91971-1-huqi@loongson.cn> Signed-off-by: Richard Henderson --- tcg/loongarch64/tcg-target.c.inc | 48 +++++++++++++++++++++++++++++--- tcg/loongarch64/tcg-target.h | 9 ++++-- 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc index a3debf6da7..d326e28740 100644 --- a/tcg/loongarch64/tcg-target.c.inc +++ b/tcg/loongarch64/tcg-target.c.inc @@ -1031,6 +1031,36 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args) #endif } +/* LoongArch uses `andi zero, zero, 0` as NOP. */ +#define NOP OPC_ANDI +static void tcg_out_nop(TCGContext *s) +{ + tcg_out32(s, NOP); +} + +void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx, + uintptr_t jmp_rw, uintptr_t addr) +{ + tcg_insn_unit i1, i2; + ptrdiff_t upper, lower; + ptrdiff_t offset = (ptrdiff_t)(addr - jmp_rx) >> 2; + + if (offset == sextreg(offset, 0, 26)) { + i1 = encode_sd10k16_insn(OPC_B, offset); + i2 = NOP; + } else { + tcg_debug_assert(offset == sextreg(offset, 0, 36)); + lower = (int16_t)offset; + upper = (offset - lower) >> 16; + + i1 = encode_dsj20_insn(OPC_PCADDU18I, TCG_REG_TMP0, upper); + i2 = encode_djsk16_insn(OPC_JIRL, TCG_REG_ZERO, TCG_REG_TMP0, lower); + } + uint64_t pair = ((uint64_t)i2 << 32) | i1; + qatomic_set((uint64_t *)jmp_rw, pair); + flush_idcache_range(jmp_rx, jmp_rw, 8); +} + /* * Entry-points */ @@ -1058,10 +1088,20 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, break; case INDEX_op_goto_tb: - assert(s->tb_jmp_insn_offset == 0); - /* indirect jump method */ - tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP0, TCG_REG_ZERO, - (uintptr_t)(s->tb_jmp_target_addr + a0)); + tcg_debug_assert(s->tb_jmp_insn_offset != NULL); + /* + * Ensure that patch area is 8-byte aligned so that an + * atomic write can be used to patch the target address. + */ + if ((uintptr_t)s->code_ptr & 7) { + tcg_out_nop(s); + } + s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s); + /* + * actual branch destination will be patched by + * tb_target_set_jmp_target later + */ + tcg_out_opc_pcaddu18i(s, TCG_REG_TMP0, 0); tcg_out_opc_jirl(s, TCG_REG_ZERO, TCG_REG_TMP0, 0); set_jmp_reset_offset(s, a0); break; diff --git a/tcg/loongarch64/tcg-target.h b/tcg/loongarch64/tcg-target.h index d58a6162f2..a659c8d6fd 100644 --- a/tcg/loongarch64/tcg-target.h +++ b/tcg/loongarch64/tcg-target.h @@ -42,7 +42,11 @@ #define TCG_TARGET_INSN_UNIT_SIZE 4 #define TCG_TARGET_NB_REGS 32 -#define MAX_CODE_GEN_BUFFER_SIZE SIZE_MAX +/* + * PCADDU18I + JIRL sequence can give 20 + 16 + 2 = 38 bits + * signed offset, which is +/- 128 GiB. + */ +#define MAX_CODE_GEN_BUFFER_SIZE (128 * GiB) typedef enum { TCG_REG_ZERO, @@ -123,7 +127,7 @@ typedef enum { #define TCG_TARGET_HAS_clz_i32 1 #define TCG_TARGET_HAS_ctz_i32 1 #define TCG_TARGET_HAS_ctpop_i32 0 -#define TCG_TARGET_HAS_direct_jump 0 +#define TCG_TARGET_HAS_direct_jump 1 #define TCG_TARGET_HAS_brcond2 0 #define TCG_TARGET_HAS_setcond2 0 #define TCG_TARGET_HAS_qemu_st8_i32 0 @@ -166,7 +170,6 @@ typedef enum { #define TCG_TARGET_HAS_muluh_i64 1 #define TCG_TARGET_HAS_mulsh_i64 1 -/* not defined -- call should be eliminated at compile time */ void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t); #define TCG_TARGET_DEFAULT_MO (0) From 122167659c50958f98cb2a153de97541f03462ff Mon Sep 17 00:00:00 2001 From: Qi Hu Date: Mon, 17 Oct 2022 10:08:26 +0800 Subject: [PATCH 097/705] tcg/aarch64: Remove unused code in tcg_out_op MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AArch64 defines the TCG_TARGET_HAS_direct_jump. So the "else" block is useless in the case of "INDEX_op_goto_tb" in function "tcg_out_op". Add an assertion and delete these codes for clarity. Suggested-by: WANG Xuerui Signed-off-by: Qi Hu Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20221017020826.990729-1-huqi@loongson.cn> Signed-off-by: Richard Henderson --- tcg/aarch64/tcg-target.c.inc | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc index d997f7922a..344b63e20f 100644 --- a/tcg/aarch64/tcg-target.c.inc +++ b/tcg/aarch64/tcg-target.c.inc @@ -1916,24 +1916,21 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, break; case INDEX_op_goto_tb: - if (s->tb_jmp_insn_offset != NULL) { - /* TCG_TARGET_HAS_direct_jump */ - /* Ensure that ADRP+ADD are 8-byte aligned so that an atomic - write can be used to patch the target address. */ - if ((uintptr_t)s->code_ptr & 7) { - tcg_out32(s, NOP); - } - s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s); - /* actual branch destination will be patched by - tb_target_set_jmp_target later. */ - tcg_out_insn(s, 3406, ADRP, TCG_REG_TMP, 0); - tcg_out_insn(s, 3401, ADDI, TCG_TYPE_I64, TCG_REG_TMP, TCG_REG_TMP, 0); - } else { - /* !TCG_TARGET_HAS_direct_jump */ - tcg_debug_assert(s->tb_jmp_target_addr != NULL); - intptr_t offset = tcg_pcrel_diff(s, (s->tb_jmp_target_addr + a0)) >> 2; - tcg_out_insn(s, 3305, LDR, offset, TCG_REG_TMP); + tcg_debug_assert(s->tb_jmp_insn_offset != NULL); + /* + * Ensure that ADRP+ADD are 8-byte aligned so that an atomic + * write can be used to patch the target address. + */ + if ((uintptr_t)s->code_ptr & 7) { + tcg_out32(s, NOP); } + s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s); + /* + * actual branch destination will be patched by + * tb_target_set_jmp_target later + */ + tcg_out_insn(s, 3406, ADRP, TCG_REG_TMP, 0); + tcg_out_insn(s, 3401, ADDI, TCG_TYPE_I64, TCG_REG_TMP, TCG_REG_TMP, 0); tcg_out_insn(s, 3207, BR, TCG_REG_TMP); set_jmp_reset_offset(s, a0); break; From 69993c4e627a4e4d4d084bef643b446c97fee0f5 Mon Sep 17 00:00:00 2001 From: Leandro Lupori Date: Tue, 25 Oct 2022 17:24:22 -0300 Subject: [PATCH 098/705] accel/tcg: Add a quicker check for breakpoints Profiling QEMU during Fedora 35 for PPC64 boot revealed that a considerable amount of time was being spent in check_for_breakpoints() (0.61% of total time on PPC64 and 2.19% on amd64), even though it was just checking that its queue was empty and returning, when no breakpoints were set. It turns out this function is not inlined by the compiler and it's always called by helper_lookup_tb_ptr(), one of the most called functions. By leaving only the check for empty queue in check_for_breakpoints() and moving the remaining code to check_for_breakpoints_slow(), called only when the queue is not empty, it's possible to avoid the call overhead. An improvement of about 3% in total time was measured on POWER9. Signed-off-by: Leandro Lupori Reviewed-by: Richard Henderson Message-Id: <20221025202424.195984-2-leandro.lupori@eldorado.org.br> Signed-off-by: Richard Henderson --- accel/tcg/cpu-exec.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c index f9e5cc9ba0..bb4b9e92ce 100644 --- a/accel/tcg/cpu-exec.c +++ b/accel/tcg/cpu-exec.c @@ -304,16 +304,12 @@ static void log_cpu_exec(target_ulong pc, CPUState *cpu, } } -static bool check_for_breakpoints(CPUState *cpu, target_ulong pc, - uint32_t *cflags) +static bool check_for_breakpoints_slow(CPUState *cpu, target_ulong pc, + uint32_t *cflags) { CPUBreakpoint *bp; bool match_page = false; - if (likely(QTAILQ_EMPTY(&cpu->breakpoints))) { - return false; - } - /* * Singlestep overrides breakpoints. * This requirement is visible in the record-replay tests, where @@ -374,6 +370,13 @@ static bool check_for_breakpoints(CPUState *cpu, target_ulong pc, return false; } +static inline bool check_for_breakpoints(CPUState *cpu, target_ulong pc, + uint32_t *cflags) +{ + return unlikely(!QTAILQ_EMPTY(&cpu->breakpoints)) && + check_for_breakpoints_slow(cpu, pc, cflags); +} + /** * helper_lookup_tb_ptr: quick check for next tb * @env: current cpu state From d44e3737f937c0d0da1ad18d7b48bfc3ed885e1a Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 22 Oct 2022 21:34:12 +1000 Subject: [PATCH 099/705] include/qemu/osdep: Add qemu_build_assert MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This differs from assert, in that with optimization enabled it triggers at build-time. It differs from QEMU_BUILD_BUG_ON, aka _Static_assert, in that it is sensitive to control flow and is subject to dead-code elimination. Acked-by: Paolo Bonzini Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- include/qemu/osdep.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index b1c161c035..2276094729 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -186,6 +186,14 @@ void QEMU_ERROR("code path is reachable") #define qemu_build_not_reached() g_assert_not_reached() #endif +/** + * qemu_build_assert() + * + * The compiler, during optimization, is expected to prove that the + * assertion is true. + */ +#define qemu_build_assert(test) while (!(test)) qemu_build_not_reached() + /* * According to waitpid man page: * WCOREDUMP From 590536369f8eb2f3410fa3a1af329891f3fc58e3 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 22 Oct 2022 22:05:16 +1000 Subject: [PATCH 100/705] include/qemu/atomic: Use qemu_build_assert MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change from QEMU_BUILD_BUG_ON, which requires ifdefs to avoid problematic code, to qemu_build_assert, which can use C ifs. Acked-by: Paolo Bonzini Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- include/qemu/atomic.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/include/qemu/atomic.h b/include/qemu/atomic.h index 7e8fc8e7cd..874134fd19 100644 --- a/include/qemu/atomic.h +++ b/include/qemu/atomic.h @@ -133,7 +133,7 @@ #define qatomic_read(ptr) \ ({ \ - QEMU_BUILD_BUG_ON(sizeof(*ptr) > ATOMIC_REG_SIZE); \ + qemu_build_assert(sizeof(*ptr) <= ATOMIC_REG_SIZE); \ qatomic_read__nocheck(ptr); \ }) @@ -141,7 +141,7 @@ __atomic_store_n(ptr, i, __ATOMIC_RELAXED) #define qatomic_set(ptr, i) do { \ - QEMU_BUILD_BUG_ON(sizeof(*ptr) > ATOMIC_REG_SIZE); \ + qemu_build_assert(sizeof(*ptr) <= ATOMIC_REG_SIZE); \ qatomic_set__nocheck(ptr, i); \ } while(0) @@ -159,27 +159,27 @@ #define qatomic_rcu_read(ptr) \ ({ \ - QEMU_BUILD_BUG_ON(sizeof(*ptr) > ATOMIC_REG_SIZE); \ + qemu_build_assert(sizeof(*ptr) <= ATOMIC_REG_SIZE); \ typeof_strip_qual(*ptr) _val; \ qatomic_rcu_read__nocheck(ptr, &_val); \ _val; \ }) #define qatomic_rcu_set(ptr, i) do { \ - QEMU_BUILD_BUG_ON(sizeof(*ptr) > ATOMIC_REG_SIZE); \ + qemu_build_assert(sizeof(*ptr) <= ATOMIC_REG_SIZE); \ __atomic_store_n(ptr, i, __ATOMIC_RELEASE); \ } while(0) #define qatomic_load_acquire(ptr) \ ({ \ - QEMU_BUILD_BUG_ON(sizeof(*ptr) > ATOMIC_REG_SIZE); \ + qemu_build_assert(sizeof(*ptr) <= ATOMIC_REG_SIZE); \ typeof_strip_qual(*ptr) _val; \ __atomic_load(ptr, &_val, __ATOMIC_ACQUIRE); \ _val; \ }) #define qatomic_store_release(ptr, i) do { \ - QEMU_BUILD_BUG_ON(sizeof(*ptr) > ATOMIC_REG_SIZE); \ + qemu_build_assert(sizeof(*ptr) <= ATOMIC_REG_SIZE); \ __atomic_store_n(ptr, i, __ATOMIC_RELEASE); \ } while(0) @@ -191,7 +191,7 @@ }) #define qatomic_xchg(ptr, i) ({ \ - QEMU_BUILD_BUG_ON(sizeof(*ptr) > ATOMIC_REG_SIZE); \ + qemu_build_assert(sizeof(*ptr) <= ATOMIC_REG_SIZE); \ qatomic_xchg__nocheck(ptr, i); \ }) @@ -204,7 +204,7 @@ }) #define qatomic_cmpxchg(ptr, old, new) ({ \ - QEMU_BUILD_BUG_ON(sizeof(*ptr) > ATOMIC_REG_SIZE); \ + qemu_build_assert(sizeof(*ptr) <= ATOMIC_REG_SIZE); \ qatomic_cmpxchg__nocheck(ptr, old, new); \ }) From 7ed9e721cce2ccf6a1da22cd0e713c2a0d187457 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 22 Oct 2022 23:04:11 +1000 Subject: [PATCH 101/705] include/qemu/thread: Use qatomic_* functions Use qatomic_*, which expands to __atomic_* in preference to the "legacy" __sync_* functions. Acked-by: Paolo Bonzini Signed-off-by: Richard Henderson --- include/qemu/thread.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/qemu/thread.h b/include/qemu/thread.h index af19f2b3fc..20641e5844 100644 --- a/include/qemu/thread.h +++ b/include/qemu/thread.h @@ -227,7 +227,7 @@ struct QemuSpin { static inline void qemu_spin_init(QemuSpin *spin) { - __sync_lock_release(&spin->value); + qatomic_set(&spin->value, 0); #ifdef CONFIG_TSAN __tsan_mutex_create(spin, __tsan_mutex_not_static); #endif @@ -246,7 +246,7 @@ static inline void qemu_spin_lock(QemuSpin *spin) #ifdef CONFIG_TSAN __tsan_mutex_pre_lock(spin, 0); #endif - while (unlikely(__sync_lock_test_and_set(&spin->value, true))) { + while (unlikely(qatomic_xchg(&spin->value, 1))) { while (qatomic_read(&spin->value)) { cpu_relax(); } @@ -261,7 +261,7 @@ static inline bool qemu_spin_trylock(QemuSpin *spin) #ifdef CONFIG_TSAN __tsan_mutex_pre_lock(spin, __tsan_mutex_try_lock); #endif - bool busy = __sync_lock_test_and_set(&spin->value, true); + bool busy = qatomic_xchg(&spin->value, true); #ifdef CONFIG_TSAN unsigned flags = __tsan_mutex_try_lock; flags |= busy ? __tsan_mutex_try_lock_failed : 0; @@ -280,7 +280,7 @@ static inline void qemu_spin_unlock(QemuSpin *spin) #ifdef CONFIG_TSAN __tsan_mutex_pre_unlock(spin, 0); #endif - __sync_lock_release(&spin->value); + qatomic_store_release(&spin->value, 0); #ifdef CONFIG_TSAN __tsan_mutex_post_unlock(spin, 0); #endif From 50d4c8c1d433ae843a6b86a65467c507095f65f1 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 17 Sep 2022 14:25:12 +0200 Subject: [PATCH 102/705] accel/tcg: Make page_alloc_target_data allocation constant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use a constant target data allocation size for all pages. This will be necessary to reduce overhead of page tracking. Since TARGET_PAGE_DATA_SIZE is now required, we can use this to omit data tracking for targets that don't require it. Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- accel/tcg/translate-all.c | 8 ++++++-- include/exec/cpu-all.h | 9 ++++----- target/arm/cpu.h | 8 ++++++++ target/arm/internals.h | 4 ---- target/arm/mte_helper.c | 3 +-- 5 files changed, 19 insertions(+), 13 deletions(-) diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 4ed75a13e1..64a2601f9f 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -2271,6 +2271,7 @@ void page_set_flags(target_ulong start, target_ulong end, int flags) void page_reset_target_data(target_ulong start, target_ulong end) { +#ifdef TARGET_PAGE_DATA_SIZE target_ulong addr, len; /* @@ -2293,15 +2294,17 @@ void page_reset_target_data(target_ulong start, target_ulong end) g_free(p->target_data); p->target_data = NULL; } +#endif } +#ifdef TARGET_PAGE_DATA_SIZE void *page_get_target_data(target_ulong address) { PageDesc *p = page_find(address >> TARGET_PAGE_BITS); return p ? p->target_data : NULL; } -void *page_alloc_target_data(target_ulong address, size_t size) +void *page_alloc_target_data(target_ulong address) { PageDesc *p = page_find(address >> TARGET_PAGE_BITS); void *ret = NULL; @@ -2309,11 +2312,12 @@ void *page_alloc_target_data(target_ulong address, size_t size) if (p->flags & PAGE_VALID) { ret = p->target_data; if (!ret) { - p->target_data = ret = g_malloc0(size); + p->target_data = ret = g_malloc0(TARGET_PAGE_DATA_SIZE); } } return ret; } +#endif /* TARGET_PAGE_DATA_SIZE */ int page_check_range(target_ulong start, target_ulong len, int flags) { diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h index 16b7df41bf..854adc4ac2 100644 --- a/include/exec/cpu-all.h +++ b/include/exec/cpu-all.h @@ -281,19 +281,18 @@ void page_reset_target_data(target_ulong start, target_ulong end); int page_check_range(target_ulong start, target_ulong len, int flags); /** - * page_alloc_target_data(address, size) + * page_alloc_target_data(address) * @address: guest virtual address - * @size: size of data to allocate * - * Allocate @size bytes of out-of-band data to associate with the - * guest page at @address. If the page is not mapped, NULL will + * Allocate TARGET_PAGE_DATA_SIZE bytes of out-of-band data to associate + * with the guest page at @address. If the page is not mapped, NULL will * be returned. If there is existing data associated with @address, * no new memory will be allocated. * * The memory will be freed when the guest page is deallocated, * e.g. with the munmap system call. */ -void *page_alloc_target_data(target_ulong address, size_t size); +void *page_alloc_target_data(target_ulong address); /** * page_get_target_data(address) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 64fc03214c..db9ec6a038 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -3410,6 +3410,14 @@ extern const uint64_t pred_esz_masks[5]; #define PAGE_MTE PAGE_TARGET_2 #define PAGE_TARGET_STICKY PAGE_MTE +/* We associate one allocation tag per 16 bytes, the minimum. */ +#define LOG2_TAG_GRANULE 4 +#define TAG_GRANULE (1 << LOG2_TAG_GRANULE) + +#ifdef CONFIG_USER_ONLY +#define TARGET_PAGE_DATA_SIZE (TARGET_PAGE_SIZE >> (LOG2_TAG_GRANULE + 1)) +#endif + #ifdef TARGET_TAGGED_ADDRESSES /** * cpu_untagged_addr: diff --git a/target/arm/internals.h b/target/arm/internals.h index c3c3920ded..b26c9ca17b 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -1164,10 +1164,6 @@ void arm_log_exception(CPUState *cs); */ #define GMID_EL1_BS 6 -/* We associate one allocation tag per 16 bytes, the minimum. */ -#define LOG2_TAG_GRANULE 4 -#define TAG_GRANULE (1 << LOG2_TAG_GRANULE) - /* * SVE predicates are 1/8 the size of SVE vectors, and cannot use * the same simd_desc() encoding due to restrictions on size. diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c index e85208339e..a9c5fc2cb2 100644 --- a/target/arm/mte_helper.c +++ b/target/arm/mte_helper.c @@ -96,8 +96,7 @@ static uint8_t *allocation_tag_mem(CPUARMState *env, int ptr_mmu_idx, tags = page_get_target_data(clean_ptr); if (tags == NULL) { - size_t alloc_size = TARGET_PAGE_SIZE >> (LOG2_TAG_GRANULE + 1); - tags = page_alloc_target_data(clean_ptr, alloc_size); + tags = page_alloc_target_data(clean_ptr); assert(tags != NULL); } From f5e80399748c735d7bddab12f734348942992276 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sun, 18 Sep 2022 13:46:21 +0200 Subject: [PATCH 103/705] accel/tcg: Remove disabled debug in translate-all.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These items printf, and could be replaced with proper tracepoints if we really cared. Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- accel/tcg/translate-all.c | 109 -------------------------------------- 1 file changed, 109 deletions(-) diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 64a2601f9f..42385fa032 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -63,33 +63,7 @@ #include "tb-context.h" #include "internal.h" -/* #define DEBUG_TB_INVALIDATE */ -/* #define DEBUG_TB_FLUSH */ /* make various TB consistency checks */ -/* #define DEBUG_TB_CHECK */ - -#ifdef DEBUG_TB_INVALIDATE -#define DEBUG_TB_INVALIDATE_GATE 1 -#else -#define DEBUG_TB_INVALIDATE_GATE 0 -#endif - -#ifdef DEBUG_TB_FLUSH -#define DEBUG_TB_FLUSH_GATE 1 -#else -#define DEBUG_TB_FLUSH_GATE 0 -#endif - -#if !defined(CONFIG_USER_ONLY) -/* TB consistency checks only implemented for usermode emulation. */ -#undef DEBUG_TB_CHECK -#endif - -#ifdef DEBUG_TB_CHECK -#define DEBUG_TB_CHECK_GATE 1 -#else -#define DEBUG_TB_CHECK_GATE 0 -#endif /* Access to the various translations structures need to be serialised via locks * for consistency. @@ -940,15 +914,6 @@ static void page_flush_tb(void) } } -static gboolean tb_host_size_iter(gpointer key, gpointer value, gpointer data) -{ - const TranslationBlock *tb = value; - size_t *size = data; - - *size += tb->tc.size; - return false; -} - /* flush all the translation blocks */ static void do_tb_flush(CPUState *cpu, run_on_cpu_data tb_flush_count) { @@ -963,15 +928,6 @@ static void do_tb_flush(CPUState *cpu, run_on_cpu_data tb_flush_count) } did_flush = true; - if (DEBUG_TB_FLUSH_GATE) { - size_t nb_tbs = tcg_nb_tbs(); - size_t host_size = 0; - - tcg_tb_foreach(tb_host_size_iter, &host_size); - printf("qemu: flush code_size=%zu nb_tbs=%zu avg_tb_size=%zu\n", - tcg_code_size(), nb_tbs, nb_tbs > 0 ? host_size / nb_tbs : 0); - } - CPU_FOREACH(cpu) { tcg_flush_jmp_cache(cpu); } @@ -1005,57 +961,6 @@ void tb_flush(CPUState *cpu) } } -/* - * Formerly ifdef DEBUG_TB_CHECK. These debug functions are user-mode-only, - * so in order to prevent bit rot we compile them unconditionally in user-mode, - * and let the optimizer get rid of them by wrapping their user-only callers - * with if (DEBUG_TB_CHECK_GATE). - */ -#ifdef CONFIG_USER_ONLY - -static void do_tb_invalidate_check(void *p, uint32_t hash, void *userp) -{ - TranslationBlock *tb = p; - target_ulong addr = *(target_ulong *)userp; - - if (!(addr + TARGET_PAGE_SIZE <= tb_pc(tb) || - addr >= tb_pc(tb) + tb->size)) { - printf("ERROR invalidate: address=" TARGET_FMT_lx - " PC=%08lx size=%04x\n", addr, (long)tb_pc(tb), tb->size); - } -} - -/* verify that all the pages have correct rights for code - * - * Called with mmap_lock held. - */ -static void tb_invalidate_check(target_ulong address) -{ - address &= TARGET_PAGE_MASK; - qht_iter(&tb_ctx.htable, do_tb_invalidate_check, &address); -} - -static void do_tb_page_check(void *p, uint32_t hash, void *userp) -{ - TranslationBlock *tb = p; - int flags1, flags2; - - flags1 = page_get_flags(tb_pc(tb)); - flags2 = page_get_flags(tb_pc(tb) + tb->size - 1); - if ((flags1 & PAGE_WRITE) || (flags2 & PAGE_WRITE)) { - printf("ERROR page flags: PC=%08lx size=%04x f1=%x f2=%x\n", - (long)tb_pc(tb), tb->size, flags1, flags2); - } -} - -/* verify that all the pages have correct rights for code */ -static void tb_page_check(void) -{ - qht_iter(&tb_ctx.htable, do_tb_page_check, NULL); -} - -#endif /* CONFIG_USER_ONLY */ - /* * user-mode: call with mmap_lock held * !user-mode: call with @pd->lock held @@ -1339,12 +1244,6 @@ tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc, page_unlock(p2); } page_unlock(p); - -#ifdef CONFIG_USER_ONLY - if (DEBUG_TB_CHECK_GATE) { - tb_page_check(); - } -#endif return tb; } @@ -2400,9 +2299,6 @@ void page_protect(tb_page_addr_t page_addr) } mprotect(g2h_untagged(page_addr), qemu_host_page_size, (prot & PAGE_BITS) & ~PAGE_WRITE); - if (DEBUG_TB_INVALIDATE_GATE) { - printf("protecting code page: 0x" TB_PAGE_ADDR_FMT "\n", page_addr); - } } } @@ -2458,11 +2354,6 @@ int page_unprotect(target_ulong address, uintptr_t pc) /* and since the content will be modified, we must invalidate the corresponding translated code. */ current_tb_invalidated |= tb_invalidate_phys_page(addr, pc); -#ifdef CONFIG_USER_ONLY - if (DEBUG_TB_CHECK_GATE) { - tb_invalidate_check(addr); - } -#endif } mprotect((void *)g2h_untagged(host_start), qemu_host_page_size, prot & PAGE_BITS); From 55098769bfdefaed29796bc5104cfc8a202962fc Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 19 Sep 2022 12:28:15 +0200 Subject: [PATCH 104/705] accel/tcg: Split out PageDesc to internal.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- accel/tcg/internal.h | 31 +++++++++++++++++++++++++++++++ accel/tcg/translate-all.c | 31 +------------------------------ 2 files changed, 32 insertions(+), 30 deletions(-) diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h index dc800fd485..62da49ed52 100644 --- a/accel/tcg/internal.h +++ b/accel/tcg/internal.h @@ -11,6 +11,37 @@ #include "exec/exec-all.h" +/* + * Access to the various translations structures need to be serialised + * via locks for consistency. In user-mode emulation access to the + * memory related structures are protected with mmap_lock. + * In !user-mode we use per-page locks. + */ +#ifdef CONFIG_SOFTMMU +#define assert_memory_lock() +#else +#define assert_memory_lock() tcg_debug_assert(have_mmap_lock()) +#endif + +typedef struct PageDesc { + /* list of TBs intersecting this ram page */ + uintptr_t first_tb; +#ifdef CONFIG_USER_ONLY + unsigned long flags; + void *target_data; +#endif +#ifdef CONFIG_SOFTMMU + QemuSpin lock; +#endif +} PageDesc; + +PageDesc *page_find_alloc(tb_page_addr_t index, bool alloc); + +static inline PageDesc *page_find(tb_page_addr_t index) +{ + return page_find_alloc(index, false); +} + TranslationBlock *tb_gen_code(CPUState *cpu, target_ulong pc, target_ulong cs_base, uint32_t flags, int cflags); diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 42385fa032..86848c6743 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -65,30 +65,6 @@ /* make various TB consistency checks */ -/* Access to the various translations structures need to be serialised via locks - * for consistency. - * In user-mode emulation access to the memory related structures are protected - * with mmap_lock. - * In !user-mode we use per-page locks. - */ -#ifdef CONFIG_SOFTMMU -#define assert_memory_lock() -#else -#define assert_memory_lock() tcg_debug_assert(have_mmap_lock()) -#endif - -typedef struct PageDesc { - /* list of TBs intersecting this ram page */ - uintptr_t first_tb; -#ifdef CONFIG_USER_ONLY - unsigned long flags; - void *target_data; -#endif -#ifdef CONFIG_SOFTMMU - QemuSpin lock; -#endif -} PageDesc; - /** * struct page_entry - page descriptor entry * @pd: pointer to the &struct PageDesc of the page this entry represents @@ -445,7 +421,7 @@ void page_init(void) #endif } -static PageDesc *page_find_alloc(tb_page_addr_t index, bool alloc) +PageDesc *page_find_alloc(tb_page_addr_t index, bool alloc) { PageDesc *pd; void **lp; @@ -511,11 +487,6 @@ static PageDesc *page_find_alloc(tb_page_addr_t index, bool alloc) return pd + (index & (V_L2_SIZE - 1)); } -static inline PageDesc *page_find(tb_page_addr_t index) -{ - return page_find_alloc(index, false); -} - static void page_lock_pair(PageDesc **ret_p1, tb_page_addr_t phys1, PageDesc **ret_p2, tb_page_addr_t phys2, bool alloc); From 8a14b62c3fc89a46fbf61c9cc96cb470a6ad9de5 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 20 Sep 2022 07:17:44 +0200 Subject: [PATCH 105/705] accel/tcg: Split out tb-maint.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move all of the TranslationBlock flushing and page linking code from translate-all.c to tb-maint.c. Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- accel/tcg/internal.h | 55 +++ accel/tcg/meson.build | 1 + accel/tcg/tb-maint.c | 735 ++++++++++++++++++++++++++++++++++++ accel/tcg/translate-all.c | 766 +------------------------------------- 4 files changed, 802 insertions(+), 755 deletions(-) create mode 100644 accel/tcg/tb-maint.c diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h index 62da49ed52..a77b110b78 100644 --- a/accel/tcg/internal.h +++ b/accel/tcg/internal.h @@ -35,6 +35,27 @@ typedef struct PageDesc { #endif } PageDesc; +/* Size of the L2 (and L3, etc) page tables. */ +#define V_L2_BITS 10 +#define V_L2_SIZE (1 << V_L2_BITS) + +/* + * L1 Mapping properties + */ +extern int v_l1_size; +extern int v_l1_shift; +extern int v_l2_levels; + +/* + * The bottom level has pointers to PageDesc, and is indexed by + * anything from 4 to (V_L2_BITS + 3) bits, depending on target page size. + */ +#define V_L1_MIN_BITS 4 +#define V_L1_MAX_BITS (V_L2_BITS + 3) +#define V_L1_MAX_SIZE (1 << V_L1_MAX_BITS) + +extern void *l1_map[V_L1_MAX_SIZE]; + PageDesc *page_find_alloc(tb_page_addr_t index, bool alloc); static inline PageDesc *page_find(tb_page_addr_t index) @@ -42,12 +63,46 @@ static inline PageDesc *page_find(tb_page_addr_t index) return page_find_alloc(index, false); } +/* list iterators for lists of tagged pointers in TranslationBlock */ +#define TB_FOR_EACH_TAGGED(head, tb, n, field) \ + for (n = (head) & 1, tb = (TranslationBlock *)((head) & ~1); \ + tb; tb = (TranslationBlock *)tb->field[n], n = (uintptr_t)tb & 1, \ + tb = (TranslationBlock *)((uintptr_t)tb & ~1)) + +#define PAGE_FOR_EACH_TB(pagedesc, tb, n) \ + TB_FOR_EACH_TAGGED((pagedesc)->first_tb, tb, n, page_next) + +#define TB_FOR_EACH_JMP(head_tb, tb, n) \ + TB_FOR_EACH_TAGGED((head_tb)->jmp_list_head, tb, n, jmp_list_next) + +/* In user-mode page locks aren't used; mmap_lock is enough */ +#ifdef CONFIG_USER_ONLY +#define assert_page_locked(pd) tcg_debug_assert(have_mmap_lock()) +static inline void page_lock(PageDesc *pd) { } +static inline void page_unlock(PageDesc *pd) { } +#else +#ifdef CONFIG_DEBUG_TCG +void do_assert_page_locked(const PageDesc *pd, const char *file, int line); +#define assert_page_locked(pd) do_assert_page_locked(pd, __FILE__, __LINE__) +#else +#define assert_page_locked(pd) +#endif +void page_lock(PageDesc *pd); +void page_unlock(PageDesc *pd); +#endif + TranslationBlock *tb_gen_code(CPUState *cpu, target_ulong pc, target_ulong cs_base, uint32_t flags, int cflags); G_NORETURN void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr); void page_init(void); void tb_htable_init(void); +void tb_reset_jump(TranslationBlock *tb, int n); +TranslationBlock *tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc, + tb_page_addr_t phys_page2); +bool tb_invalidate_phys_page(tb_page_addr_t addr, uintptr_t pc); +int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, + uintptr_t searched_pc, bool reset_icount); /* Return the current PC from CPU, which may be cached in TB. */ static inline target_ulong log_pc(CPUState *cpu, const TranslationBlock *tb) diff --git a/accel/tcg/meson.build b/accel/tcg/meson.build index 7a0a79d731..75e1dffb4d 100644 --- a/accel/tcg/meson.build +++ b/accel/tcg/meson.build @@ -3,6 +3,7 @@ tcg_ss.add(files( 'tcg-all.c', 'cpu-exec-common.c', 'cpu-exec.c', + 'tb-maint.c', 'tcg-runtime-gvec.c', 'tcg-runtime.c', 'translate-all.c', diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c new file mode 100644 index 0000000000..66c1900ae6 --- /dev/null +++ b/accel/tcg/tb-maint.c @@ -0,0 +1,735 @@ +/* + * Translation Block Maintaince + * + * Copyright (c) 2003 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "qemu/osdep.h" +#include "exec/cputlb.h" +#include "exec/log.h" +#include "exec/translate-all.h" +#include "sysemu/tcg.h" +#include "tcg/tcg.h" +#include "tb-hash.h" +#include "tb-context.h" +#include "internal.h" + +/* FIXME: tb_invalidate_phys_range is declared in different places. */ +#ifdef CONFIG_USER_ONLY +#include "exec/exec-all.h" +#else +#include "exec/ram_addr.h" +#endif + +static bool tb_cmp(const void *ap, const void *bp) +{ + const TranslationBlock *a = ap; + const TranslationBlock *b = bp; + + return ((TARGET_TB_PCREL || tb_pc(a) == tb_pc(b)) && + a->cs_base == b->cs_base && + a->flags == b->flags && + (tb_cflags(a) & ~CF_INVALID) == (tb_cflags(b) & ~CF_INVALID) && + a->trace_vcpu_dstate == b->trace_vcpu_dstate && + a->page_addr[0] == b->page_addr[0] && + a->page_addr[1] == b->page_addr[1]); +} + +void tb_htable_init(void) +{ + unsigned int mode = QHT_MODE_AUTO_RESIZE; + + qht_init(&tb_ctx.htable, tb_cmp, CODE_GEN_HTABLE_SIZE, mode); +} + +/* Set to NULL all the 'first_tb' fields in all PageDescs. */ +static void page_flush_tb_1(int level, void **lp) +{ + int i; + + if (*lp == NULL) { + return; + } + if (level == 0) { + PageDesc *pd = *lp; + + for (i = 0; i < V_L2_SIZE; ++i) { + page_lock(&pd[i]); + pd[i].first_tb = (uintptr_t)NULL; + page_unlock(&pd[i]); + } + } else { + void **pp = *lp; + + for (i = 0; i < V_L2_SIZE; ++i) { + page_flush_tb_1(level - 1, pp + i); + } + } +} + +static void page_flush_tb(void) +{ + int i, l1_sz = v_l1_size; + + for (i = 0; i < l1_sz; i++) { + page_flush_tb_1(v_l2_levels, l1_map + i); + } +} + +/* flush all the translation blocks */ +static void do_tb_flush(CPUState *cpu, run_on_cpu_data tb_flush_count) +{ + bool did_flush = false; + + mmap_lock(); + /* If it is already been done on request of another CPU, just retry. */ + if (tb_ctx.tb_flush_count != tb_flush_count.host_int) { + goto done; + } + did_flush = true; + + CPU_FOREACH(cpu) { + tcg_flush_jmp_cache(cpu); + } + + qht_reset_size(&tb_ctx.htable, CODE_GEN_HTABLE_SIZE); + page_flush_tb(); + + tcg_region_reset_all(); + /* XXX: flush processor icache at this point if cache flush is expensive */ + qatomic_mb_set(&tb_ctx.tb_flush_count, tb_ctx.tb_flush_count + 1); + +done: + mmap_unlock(); + if (did_flush) { + qemu_plugin_flush_cb(); + } +} + +void tb_flush(CPUState *cpu) +{ + if (tcg_enabled()) { + unsigned tb_flush_count = qatomic_mb_read(&tb_ctx.tb_flush_count); + + if (cpu_in_exclusive_context(cpu)) { + do_tb_flush(cpu, RUN_ON_CPU_HOST_INT(tb_flush_count)); + } else { + async_safe_run_on_cpu(cpu, do_tb_flush, + RUN_ON_CPU_HOST_INT(tb_flush_count)); + } + } +} + +/* + * user-mode: call with mmap_lock held + * !user-mode: call with @pd->lock held + */ +static inline void tb_page_remove(PageDesc *pd, TranslationBlock *tb) +{ + TranslationBlock *tb1; + uintptr_t *pprev; + unsigned int n1; + + assert_page_locked(pd); + pprev = &pd->first_tb; + PAGE_FOR_EACH_TB(pd, tb1, n1) { + if (tb1 == tb) { + *pprev = tb1->page_next[n1]; + return; + } + pprev = &tb1->page_next[n1]; + } + g_assert_not_reached(); +} + +/* remove @orig from its @n_orig-th jump list */ +static inline void tb_remove_from_jmp_list(TranslationBlock *orig, int n_orig) +{ + uintptr_t ptr, ptr_locked; + TranslationBlock *dest; + TranslationBlock *tb; + uintptr_t *pprev; + int n; + + /* mark the LSB of jmp_dest[] so that no further jumps can be inserted */ + ptr = qatomic_or_fetch(&orig->jmp_dest[n_orig], 1); + dest = (TranslationBlock *)(ptr & ~1); + if (dest == NULL) { + return; + } + + qemu_spin_lock(&dest->jmp_lock); + /* + * While acquiring the lock, the jump might have been removed if the + * destination TB was invalidated; check again. + */ + ptr_locked = qatomic_read(&orig->jmp_dest[n_orig]); + if (ptr_locked != ptr) { + qemu_spin_unlock(&dest->jmp_lock); + /* + * The only possibility is that the jump was unlinked via + * tb_jump_unlink(dest). Seeing here another destination would be a bug, + * because we set the LSB above. + */ + g_assert(ptr_locked == 1 && dest->cflags & CF_INVALID); + return; + } + /* + * We first acquired the lock, and since the destination pointer matches, + * we know for sure that @orig is in the jmp list. + */ + pprev = &dest->jmp_list_head; + TB_FOR_EACH_JMP(dest, tb, n) { + if (tb == orig && n == n_orig) { + *pprev = tb->jmp_list_next[n]; + /* no need to set orig->jmp_dest[n]; setting the LSB was enough */ + qemu_spin_unlock(&dest->jmp_lock); + return; + } + pprev = &tb->jmp_list_next[n]; + } + g_assert_not_reached(); +} + +/* + * Reset the jump entry 'n' of a TB so that it is not chained to another TB. + */ +void tb_reset_jump(TranslationBlock *tb, int n) +{ + uintptr_t addr = (uintptr_t)(tb->tc.ptr + tb->jmp_reset_offset[n]); + tb_set_jmp_target(tb, n, addr); +} + +/* remove any jumps to the TB */ +static inline void tb_jmp_unlink(TranslationBlock *dest) +{ + TranslationBlock *tb; + int n; + + qemu_spin_lock(&dest->jmp_lock); + + TB_FOR_EACH_JMP(dest, tb, n) { + tb_reset_jump(tb, n); + qatomic_and(&tb->jmp_dest[n], (uintptr_t)NULL | 1); + /* No need to clear the list entry; setting the dest ptr is enough */ + } + dest->jmp_list_head = (uintptr_t)NULL; + + qemu_spin_unlock(&dest->jmp_lock); +} + +static void tb_jmp_cache_inval_tb(TranslationBlock *tb) +{ + CPUState *cpu; + + if (TARGET_TB_PCREL) { + /* A TB may be at any virtual address */ + CPU_FOREACH(cpu) { + tcg_flush_jmp_cache(cpu); + } + } else { + uint32_t h = tb_jmp_cache_hash_func(tb_pc(tb)); + + CPU_FOREACH(cpu) { + CPUJumpCache *jc = cpu->tb_jmp_cache; + + if (qatomic_read(&jc->array[h].tb) == tb) { + qatomic_set(&jc->array[h].tb, NULL); + } + } + } +} + +/* + * In user-mode, call with mmap_lock held. + * In !user-mode, if @rm_from_page_list is set, call with the TB's pages' + * locks held. + */ +static void do_tb_phys_invalidate(TranslationBlock *tb, bool rm_from_page_list) +{ + PageDesc *p; + uint32_t h; + tb_page_addr_t phys_pc; + uint32_t orig_cflags = tb_cflags(tb); + + assert_memory_lock(); + + /* make sure no further incoming jumps will be chained to this TB */ + qemu_spin_lock(&tb->jmp_lock); + qatomic_set(&tb->cflags, tb->cflags | CF_INVALID); + qemu_spin_unlock(&tb->jmp_lock); + + /* remove the TB from the hash list */ + phys_pc = tb->page_addr[0]; + h = tb_hash_func(phys_pc, (TARGET_TB_PCREL ? 0 : tb_pc(tb)), + tb->flags, orig_cflags, tb->trace_vcpu_dstate); + if (!qht_remove(&tb_ctx.htable, tb, h)) { + return; + } + + /* remove the TB from the page list */ + if (rm_from_page_list) { + p = page_find(tb->page_addr[0] >> TARGET_PAGE_BITS); + tb_page_remove(p, tb); + if (tb->page_addr[1] != -1) { + p = page_find(tb->page_addr[1] >> TARGET_PAGE_BITS); + tb_page_remove(p, tb); + } + } + + /* remove the TB from the hash list */ + tb_jmp_cache_inval_tb(tb); + + /* suppress this TB from the two jump lists */ + tb_remove_from_jmp_list(tb, 0); + tb_remove_from_jmp_list(tb, 1); + + /* suppress any remaining jumps to this TB */ + tb_jmp_unlink(tb); + + qatomic_set(&tb_ctx.tb_phys_invalidate_count, + tb_ctx.tb_phys_invalidate_count + 1); +} + +static void tb_phys_invalidate__locked(TranslationBlock *tb) +{ + qemu_thread_jit_write(); + do_tb_phys_invalidate(tb, true); + qemu_thread_jit_execute(); +} + +static void page_lock_pair(PageDesc **ret_p1, tb_page_addr_t phys1, + PageDesc **ret_p2, tb_page_addr_t phys2, bool alloc) +{ + PageDesc *p1, *p2; + tb_page_addr_t page1; + tb_page_addr_t page2; + + assert_memory_lock(); + g_assert(phys1 != -1); + + page1 = phys1 >> TARGET_PAGE_BITS; + page2 = phys2 >> TARGET_PAGE_BITS; + + p1 = page_find_alloc(page1, alloc); + if (ret_p1) { + *ret_p1 = p1; + } + if (likely(phys2 == -1)) { + page_lock(p1); + return; + } else if (page1 == page2) { + page_lock(p1); + if (ret_p2) { + *ret_p2 = p1; + } + return; + } + p2 = page_find_alloc(page2, alloc); + if (ret_p2) { + *ret_p2 = p2; + } + if (page1 < page2) { + page_lock(p1); + page_lock(p2); + } else { + page_lock(p2); + page_lock(p1); + } +} + +#ifdef CONFIG_USER_ONLY +static inline void page_lock_tb(const TranslationBlock *tb) { } +static inline void page_unlock_tb(const TranslationBlock *tb) { } +#else +/* lock the page(s) of a TB in the correct acquisition order */ +static void page_lock_tb(const TranslationBlock *tb) +{ + page_lock_pair(NULL, tb->page_addr[0], NULL, tb->page_addr[1], false); +} + +static void page_unlock_tb(const TranslationBlock *tb) +{ + PageDesc *p1 = page_find(tb->page_addr[0] >> TARGET_PAGE_BITS); + + page_unlock(p1); + if (unlikely(tb->page_addr[1] != -1)) { + PageDesc *p2 = page_find(tb->page_addr[1] >> TARGET_PAGE_BITS); + + if (p2 != p1) { + page_unlock(p2); + } + } +} +#endif + +/* + * Invalidate one TB. + * Called with mmap_lock held in user-mode. + */ +void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr) +{ + if (page_addr == -1 && tb->page_addr[0] != -1) { + page_lock_tb(tb); + do_tb_phys_invalidate(tb, true); + page_unlock_tb(tb); + } else { + do_tb_phys_invalidate(tb, false); + } +} + +/* + * Add the tb in the target page and protect it if necessary. + * Called with mmap_lock held for user-mode emulation. + * Called with @p->lock held in !user-mode. + */ +static inline void tb_page_add(PageDesc *p, TranslationBlock *tb, + unsigned int n, tb_page_addr_t page_addr) +{ +#ifndef CONFIG_USER_ONLY + bool page_already_protected; +#endif + + assert_page_locked(p); + + tb->page_addr[n] = page_addr; + tb->page_next[n] = p->first_tb; +#ifndef CONFIG_USER_ONLY + page_already_protected = p->first_tb != (uintptr_t)NULL; +#endif + p->first_tb = (uintptr_t)tb | n; + +#if defined(CONFIG_USER_ONLY) + /* translator_loop() must have made all TB pages non-writable */ + assert(!(p->flags & PAGE_WRITE)); +#else + /* + * If some code is already present, then the pages are already + * protected. So we handle the case where only the first TB is + * allocated in a physical page. + */ + if (!page_already_protected) { + tlb_protect_code(page_addr); + } +#endif +} + +/* + * Add a new TB and link it to the physical page tables. phys_page2 is + * (-1) to indicate that only one page contains the TB. + * + * Called with mmap_lock held for user-mode emulation. + * + * Returns a pointer @tb, or a pointer to an existing TB that matches @tb. + * Note that in !user-mode, another thread might have already added a TB + * for the same block of guest code that @tb corresponds to. In that case, + * the caller should discard the original @tb, and use instead the returned TB. + */ +TranslationBlock *tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc, + tb_page_addr_t phys_page2) +{ + PageDesc *p; + PageDesc *p2 = NULL; + void *existing_tb = NULL; + uint32_t h; + + assert_memory_lock(); + tcg_debug_assert(!(tb->cflags & CF_INVALID)); + + /* + * Add the TB to the page list, acquiring first the pages's locks. + * We keep the locks held until after inserting the TB in the hash table, + * so that if the insertion fails we know for sure that the TBs are still + * in the page descriptors. + * Note that inserting into the hash table first isn't an option, since + * we can only insert TBs that are fully initialized. + */ + page_lock_pair(&p, phys_pc, &p2, phys_page2, true); + tb_page_add(p, tb, 0, phys_pc); + if (p2) { + tb_page_add(p2, tb, 1, phys_page2); + } else { + tb->page_addr[1] = -1; + } + + /* add in the hash table */ + h = tb_hash_func(phys_pc, (TARGET_TB_PCREL ? 0 : tb_pc(tb)), + tb->flags, tb->cflags, tb->trace_vcpu_dstate); + qht_insert(&tb_ctx.htable, tb, h, &existing_tb); + + /* remove TB from the page(s) if we couldn't insert it */ + if (unlikely(existing_tb)) { + tb_page_remove(p, tb); + if (p2) { + tb_page_remove(p2, tb); + } + tb = existing_tb; + } + + if (p2 && p2 != p) { + page_unlock(p2); + } + page_unlock(p); + return tb; +} + +/* + * @p must be non-NULL. + * user-mode: call with mmap_lock held. + * !user-mode: call with all @pages locked. + */ +static void +tb_invalidate_phys_page_range__locked(struct page_collection *pages, + PageDesc *p, tb_page_addr_t start, + tb_page_addr_t end, + uintptr_t retaddr) +{ + TranslationBlock *tb; + tb_page_addr_t tb_start, tb_end; + int n; +#ifdef TARGET_HAS_PRECISE_SMC + CPUState *cpu = current_cpu; + CPUArchState *env = NULL; + bool current_tb_not_found = retaddr != 0; + bool current_tb_modified = false; + TranslationBlock *current_tb = NULL; + target_ulong current_pc = 0; + target_ulong current_cs_base = 0; + uint32_t current_flags = 0; +#endif /* TARGET_HAS_PRECISE_SMC */ + + assert_page_locked(p); + +#if defined(TARGET_HAS_PRECISE_SMC) + if (cpu != NULL) { + env = cpu->env_ptr; + } +#endif + + /* + * We remove all the TBs in the range [start, end[. + * XXX: see if in some cases it could be faster to invalidate all the code + */ + PAGE_FOR_EACH_TB(p, tb, n) { + assert_page_locked(p); + /* NOTE: this is subtle as a TB may span two physical pages */ + if (n == 0) { + /* NOTE: tb_end may be after the end of the page, but + it is not a problem */ + tb_start = tb->page_addr[0]; + tb_end = tb_start + tb->size; + } else { + tb_start = tb->page_addr[1]; + tb_end = tb_start + ((tb->page_addr[0] + tb->size) + & ~TARGET_PAGE_MASK); + } + if (!(tb_end <= start || tb_start >= end)) { +#ifdef TARGET_HAS_PRECISE_SMC + if (current_tb_not_found) { + current_tb_not_found = false; + /* now we have a real cpu fault */ + current_tb = tcg_tb_lookup(retaddr); + } + if (current_tb == tb && + (tb_cflags(current_tb) & CF_COUNT_MASK) != 1) { + /* + * If we are modifying the current TB, we must stop + * its execution. We could be more precise by checking + * that the modification is after the current PC, but it + * would require a specialized function to partially + * restore the CPU state. + */ + current_tb_modified = true; + cpu_restore_state_from_tb(cpu, current_tb, retaddr, true); + cpu_get_tb_cpu_state(env, ¤t_pc, ¤t_cs_base, + ¤t_flags); + } +#endif /* TARGET_HAS_PRECISE_SMC */ + tb_phys_invalidate__locked(tb); + } + } +#if !defined(CONFIG_USER_ONLY) + /* if no code remaining, no need to continue to use slow writes */ + if (!p->first_tb) { + tlb_unprotect_code(start); + } +#endif +#ifdef TARGET_HAS_PRECISE_SMC + if (current_tb_modified) { + page_collection_unlock(pages); + /* Force execution of one insn next time. */ + cpu->cflags_next_tb = 1 | CF_NOIRQ | curr_cflags(cpu); + mmap_unlock(); + cpu_loop_exit_noexc(cpu); + } +#endif +} + +/* + * Invalidate all TBs which intersect with the target physical address range + * [start;end[. NOTE: start and end must refer to the *same* physical page. + * 'is_cpu_write_access' should be true if called from a real cpu write + * access: the virtual CPU will exit the current TB if code is modified inside + * this TB. + * + * Called with mmap_lock held for user-mode emulation + */ +void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end) +{ + struct page_collection *pages; + PageDesc *p; + + assert_memory_lock(); + + p = page_find(start >> TARGET_PAGE_BITS); + if (p == NULL) { + return; + } + pages = page_collection_lock(start, end); + tb_invalidate_phys_page_range__locked(pages, p, start, end, 0); + page_collection_unlock(pages); +} + +/* + * Invalidate all TBs which intersect with the target physical address range + * [start;end[. NOTE: start and end may refer to *different* physical pages. + * 'is_cpu_write_access' should be true if called from a real cpu write + * access: the virtual CPU will exit the current TB if code is modified inside + * this TB. + * + * Called with mmap_lock held for user-mode emulation. + */ +#ifdef CONFIG_SOFTMMU +void tb_invalidate_phys_range(ram_addr_t start, ram_addr_t end) +#else +void tb_invalidate_phys_range(target_ulong start, target_ulong end) +#endif +{ + struct page_collection *pages; + tb_page_addr_t next; + + assert_memory_lock(); + + pages = page_collection_lock(start, end); + for (next = (start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; + start < end; + start = next, next += TARGET_PAGE_SIZE) { + PageDesc *pd = page_find(start >> TARGET_PAGE_BITS); + tb_page_addr_t bound = MIN(next, end); + + if (pd == NULL) { + continue; + } + tb_invalidate_phys_page_range__locked(pages, pd, start, bound, 0); + } + page_collection_unlock(pages); +} + +#ifdef CONFIG_SOFTMMU +/* + * len must be <= 8 and start must be a multiple of len. + * Called via softmmu_template.h when code areas are written to with + * iothread mutex not held. + * + * Call with all @pages in the range [@start, @start + len[ locked. + */ +void tb_invalidate_phys_page_fast(struct page_collection *pages, + tb_page_addr_t start, int len, + uintptr_t retaddr) +{ + PageDesc *p; + + assert_memory_lock(); + + p = page_find(start >> TARGET_PAGE_BITS); + if (!p) { + return; + } + + assert_page_locked(p); + tb_invalidate_phys_page_range__locked(pages, p, start, start + len, + retaddr); +} +#else +/* + * Called with mmap_lock held. If pc is not 0 then it indicates the + * host PC of the faulting store instruction that caused this invalidate. + * Returns true if the caller needs to abort execution of the current + * TB (because it was modified by this store and the guest CPU has + * precise-SMC semantics). + */ +bool tb_invalidate_phys_page(tb_page_addr_t addr, uintptr_t pc) +{ + TranslationBlock *tb; + PageDesc *p; + int n; +#ifdef TARGET_HAS_PRECISE_SMC + TranslationBlock *current_tb = NULL; + CPUState *cpu = current_cpu; + CPUArchState *env = NULL; + int current_tb_modified = 0; + target_ulong current_pc = 0; + target_ulong current_cs_base = 0; + uint32_t current_flags = 0; +#endif + + assert_memory_lock(); + + addr &= TARGET_PAGE_MASK; + p = page_find(addr >> TARGET_PAGE_BITS); + if (!p) { + return false; + } + +#ifdef TARGET_HAS_PRECISE_SMC + if (p->first_tb && pc != 0) { + current_tb = tcg_tb_lookup(pc); + } + if (cpu != NULL) { + env = cpu->env_ptr; + } +#endif + assert_page_locked(p); + PAGE_FOR_EACH_TB(p, tb, n) { +#ifdef TARGET_HAS_PRECISE_SMC + if (current_tb == tb && + (tb_cflags(current_tb) & CF_COUNT_MASK) != 1) { + /* + * If we are modifying the current TB, we must stop its execution. + * We could be more precise by checking that the modification is + * after the current PC, but it would require a specialized + * function to partially restore the CPU state. + */ + current_tb_modified = 1; + cpu_restore_state_from_tb(cpu, current_tb, pc, true); + cpu_get_tb_cpu_state(env, ¤t_pc, ¤t_cs_base, + ¤t_flags); + } +#endif /* TARGET_HAS_PRECISE_SMC */ + tb_phys_invalidate(tb, addr); + } + p->first_tb = (uintptr_t)NULL; +#ifdef TARGET_HAS_PRECISE_SMC + if (current_tb_modified) { + /* Force execution of one insn next time. */ + cpu->cflags_next_tb = 1 | CF_NOIRQ | curr_cflags(cpu); + return true; + } +#endif + + return false; +} +#endif diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 86848c6743..5e28e9fccd 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -109,18 +109,6 @@ struct page_collection { struct page_entry *max; }; -/* list iterators for lists of tagged pointers in TranslationBlock */ -#define TB_FOR_EACH_TAGGED(head, tb, n, field) \ - for (n = (head) & 1, tb = (TranslationBlock *)((head) & ~1); \ - tb; tb = (TranslationBlock *)tb->field[n], n = (uintptr_t)tb & 1, \ - tb = (TranslationBlock *)((uintptr_t)tb & ~1)) - -#define PAGE_FOR_EACH_TB(pagedesc, tb, n) \ - TB_FOR_EACH_TAGGED((pagedesc)->first_tb, tb, n, page_next) - -#define TB_FOR_EACH_JMP(head_tb, tb, n) \ - TB_FOR_EACH_TAGGED((head_tb)->jmp_list_head, tb, n, jmp_list_next) - /* * In system mode we want L1_MAP to be based on ram offsets, * while in user mode we want it to be based on virtual addresses. @@ -138,10 +126,6 @@ struct page_collection { # define L1_MAP_ADDR_SPACE_BITS MIN(HOST_LONG_BITS, TARGET_ABI_BITS) #endif -/* Size of the L2 (and L3, etc) page tables. */ -#define V_L2_BITS 10 -#define V_L2_SIZE (1 << V_L2_BITS) - /* Make sure all possible CPU event bits fit in tb->trace_vcpu_dstate */ QEMU_BUILD_BUG_ON(CPU_TRACE_DSTATE_MAX_EVENTS > sizeof_field(TranslationBlock, trace_vcpu_dstate) @@ -150,18 +134,11 @@ QEMU_BUILD_BUG_ON(CPU_TRACE_DSTATE_MAX_EVENTS > /* * L1 Mapping properties */ -static int v_l1_size; -static int v_l1_shift; -static int v_l2_levels; +int v_l1_size; +int v_l1_shift; +int v_l2_levels; -/* The bottom level has pointers to PageDesc, and is indexed by - * anything from 4 to (V_L2_BITS + 3) bits, depending on target page size. - */ -#define V_L1_MIN_BITS 4 -#define V_L1_MAX_BITS (V_L2_BITS + 3) -#define V_L1_MAX_SIZE (1 << V_L1_MAX_BITS) - -static void *l1_map[V_L1_MAX_SIZE]; +void *l1_map[V_L1_MAX_SIZE]; TBContext tb_ctx; @@ -274,8 +251,8 @@ static int encode_search(TranslationBlock *tb, uint8_t *block) * When reset_icount is true, current TB will be interrupted and * icount should be recalculated. */ -static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, - uintptr_t searched_pc, bool reset_icount) +int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, + uintptr_t searched_pc, bool reset_icount) { target_ulong data[TARGET_INSN_START_WORDS]; uintptr_t host_pc = (uintptr_t)tb->tc.ptr; @@ -487,26 +464,8 @@ PageDesc *page_find_alloc(tb_page_addr_t index, bool alloc) return pd + (index & (V_L2_SIZE - 1)); } -static void page_lock_pair(PageDesc **ret_p1, tb_page_addr_t phys1, - PageDesc **ret_p2, tb_page_addr_t phys2, bool alloc); - /* In user-mode page locks aren't used; mmap_lock is enough */ #ifdef CONFIG_USER_ONLY - -#define assert_page_locked(pd) tcg_debug_assert(have_mmap_lock()) - -static inline void page_lock(PageDesc *pd) -{ } - -static inline void page_unlock(PageDesc *pd) -{ } - -static inline void page_lock_tb(const TranslationBlock *tb) -{ } - -static inline void page_unlock_tb(const TranslationBlock *tb) -{ } - struct page_collection * page_collection_lock(tb_page_addr_t start, tb_page_addr_t end) { @@ -555,8 +514,7 @@ static void page_unlock__debug(const PageDesc *pd) g_assert(removed); } -static void -do_assert_page_locked(const PageDesc *pd, const char *file, int line) +void do_assert_page_locked(const PageDesc *pd, const char *file, int line) { if (unlikely(!page_is_locked(pd))) { error_report("assert_page_lock: PageDesc %p not locked @ %s:%d", @@ -565,8 +523,6 @@ do_assert_page_locked(const PageDesc *pd, const char *file, int line) } } -#define assert_page_locked(pd) do_assert_page_locked(pd, __FILE__, __LINE__) - void assert_no_pages_locked(void) { ht_pages_locked_debug_init(); @@ -575,50 +531,23 @@ void assert_no_pages_locked(void) #else /* !CONFIG_DEBUG_TCG */ -#define assert_page_locked(pd) - -static inline void page_lock__debug(const PageDesc *pd) -{ -} - -static inline void page_unlock__debug(const PageDesc *pd) -{ -} +static inline void page_lock__debug(const PageDesc *pd) { } +static inline void page_unlock__debug(const PageDesc *pd) { } #endif /* CONFIG_DEBUG_TCG */ -static inline void page_lock(PageDesc *pd) +void page_lock(PageDesc *pd) { page_lock__debug(pd); qemu_spin_lock(&pd->lock); } -static inline void page_unlock(PageDesc *pd) +void page_unlock(PageDesc *pd) { qemu_spin_unlock(&pd->lock); page_unlock__debug(pd); } -/* lock the page(s) of a TB in the correct acquisition order */ -static inline void page_lock_tb(const TranslationBlock *tb) -{ - page_lock_pair(NULL, tb->page_addr[0], NULL, tb->page_addr[1], false); -} - -static inline void page_unlock_tb(const TranslationBlock *tb) -{ - PageDesc *p1 = page_find(tb->page_addr[0] >> TARGET_PAGE_BITS); - - page_unlock(p1); - if (unlikely(tb->page_addr[1] != -1)) { - PageDesc *p2 = page_find(tb->page_addr[1] >> TARGET_PAGE_BITS); - - if (p2 != p1) { - page_unlock(p2); - } - } -} - static inline struct page_entry * page_entry_new(PageDesc *pd, tb_page_addr_t index) { @@ -790,434 +719,6 @@ void page_collection_unlock(struct page_collection *set) #endif /* !CONFIG_USER_ONLY */ -static void page_lock_pair(PageDesc **ret_p1, tb_page_addr_t phys1, - PageDesc **ret_p2, tb_page_addr_t phys2, bool alloc) -{ - PageDesc *p1, *p2; - tb_page_addr_t page1; - tb_page_addr_t page2; - - assert_memory_lock(); - g_assert(phys1 != -1); - - page1 = phys1 >> TARGET_PAGE_BITS; - page2 = phys2 >> TARGET_PAGE_BITS; - - p1 = page_find_alloc(page1, alloc); - if (ret_p1) { - *ret_p1 = p1; - } - if (likely(phys2 == -1)) { - page_lock(p1); - return; - } else if (page1 == page2) { - page_lock(p1); - if (ret_p2) { - *ret_p2 = p1; - } - return; - } - p2 = page_find_alloc(page2, alloc); - if (ret_p2) { - *ret_p2 = p2; - } - if (page1 < page2) { - page_lock(p1); - page_lock(p2); - } else { - page_lock(p2); - page_lock(p1); - } -} - -static bool tb_cmp(const void *ap, const void *bp) -{ - const TranslationBlock *a = ap; - const TranslationBlock *b = bp; - - return ((TARGET_TB_PCREL || tb_pc(a) == tb_pc(b)) && - a->cs_base == b->cs_base && - a->flags == b->flags && - (tb_cflags(a) & ~CF_INVALID) == (tb_cflags(b) & ~CF_INVALID) && - a->trace_vcpu_dstate == b->trace_vcpu_dstate && - a->page_addr[0] == b->page_addr[0] && - a->page_addr[1] == b->page_addr[1]); -} - -void tb_htable_init(void) -{ - unsigned int mode = QHT_MODE_AUTO_RESIZE; - - qht_init(&tb_ctx.htable, tb_cmp, CODE_GEN_HTABLE_SIZE, mode); -} - -/* Set to NULL all the 'first_tb' fields in all PageDescs. */ -static void page_flush_tb_1(int level, void **lp) -{ - int i; - - if (*lp == NULL) { - return; - } - if (level == 0) { - PageDesc *pd = *lp; - - for (i = 0; i < V_L2_SIZE; ++i) { - page_lock(&pd[i]); - pd[i].first_tb = (uintptr_t)NULL; - page_unlock(&pd[i]); - } - } else { - void **pp = *lp; - - for (i = 0; i < V_L2_SIZE; ++i) { - page_flush_tb_1(level - 1, pp + i); - } - } -} - -static void page_flush_tb(void) -{ - int i, l1_sz = v_l1_size; - - for (i = 0; i < l1_sz; i++) { - page_flush_tb_1(v_l2_levels, l1_map + i); - } -} - -/* flush all the translation blocks */ -static void do_tb_flush(CPUState *cpu, run_on_cpu_data tb_flush_count) -{ - bool did_flush = false; - - mmap_lock(); - /* If it is already been done on request of another CPU, - * just retry. - */ - if (tb_ctx.tb_flush_count != tb_flush_count.host_int) { - goto done; - } - did_flush = true; - - CPU_FOREACH(cpu) { - tcg_flush_jmp_cache(cpu); - } - - qht_reset_size(&tb_ctx.htable, CODE_GEN_HTABLE_SIZE); - page_flush_tb(); - - tcg_region_reset_all(); - /* XXX: flush processor icache at this point if cache flush is - expensive */ - qatomic_mb_set(&tb_ctx.tb_flush_count, tb_ctx.tb_flush_count + 1); - -done: - mmap_unlock(); - if (did_flush) { - qemu_plugin_flush_cb(); - } -} - -void tb_flush(CPUState *cpu) -{ - if (tcg_enabled()) { - unsigned tb_flush_count = qatomic_mb_read(&tb_ctx.tb_flush_count); - - if (cpu_in_exclusive_context(cpu)) { - do_tb_flush(cpu, RUN_ON_CPU_HOST_INT(tb_flush_count)); - } else { - async_safe_run_on_cpu(cpu, do_tb_flush, - RUN_ON_CPU_HOST_INT(tb_flush_count)); - } - } -} - -/* - * user-mode: call with mmap_lock held - * !user-mode: call with @pd->lock held - */ -static inline void tb_page_remove(PageDesc *pd, TranslationBlock *tb) -{ - TranslationBlock *tb1; - uintptr_t *pprev; - unsigned int n1; - - assert_page_locked(pd); - pprev = &pd->first_tb; - PAGE_FOR_EACH_TB(pd, tb1, n1) { - if (tb1 == tb) { - *pprev = tb1->page_next[n1]; - return; - } - pprev = &tb1->page_next[n1]; - } - g_assert_not_reached(); -} - -/* remove @orig from its @n_orig-th jump list */ -static inline void tb_remove_from_jmp_list(TranslationBlock *orig, int n_orig) -{ - uintptr_t ptr, ptr_locked; - TranslationBlock *dest; - TranslationBlock *tb; - uintptr_t *pprev; - int n; - - /* mark the LSB of jmp_dest[] so that no further jumps can be inserted */ - ptr = qatomic_or_fetch(&orig->jmp_dest[n_orig], 1); - dest = (TranslationBlock *)(ptr & ~1); - if (dest == NULL) { - return; - } - - qemu_spin_lock(&dest->jmp_lock); - /* - * While acquiring the lock, the jump might have been removed if the - * destination TB was invalidated; check again. - */ - ptr_locked = qatomic_read(&orig->jmp_dest[n_orig]); - if (ptr_locked != ptr) { - qemu_spin_unlock(&dest->jmp_lock); - /* - * The only possibility is that the jump was unlinked via - * tb_jump_unlink(dest). Seeing here another destination would be a bug, - * because we set the LSB above. - */ - g_assert(ptr_locked == 1 && dest->cflags & CF_INVALID); - return; - } - /* - * We first acquired the lock, and since the destination pointer matches, - * we know for sure that @orig is in the jmp list. - */ - pprev = &dest->jmp_list_head; - TB_FOR_EACH_JMP(dest, tb, n) { - if (tb == orig && n == n_orig) { - *pprev = tb->jmp_list_next[n]; - /* no need to set orig->jmp_dest[n]; setting the LSB was enough */ - qemu_spin_unlock(&dest->jmp_lock); - return; - } - pprev = &tb->jmp_list_next[n]; - } - g_assert_not_reached(); -} - -/* reset the jump entry 'n' of a TB so that it is not chained to - another TB */ -static inline void tb_reset_jump(TranslationBlock *tb, int n) -{ - uintptr_t addr = (uintptr_t)(tb->tc.ptr + tb->jmp_reset_offset[n]); - tb_set_jmp_target(tb, n, addr); -} - -/* remove any jumps to the TB */ -static inline void tb_jmp_unlink(TranslationBlock *dest) -{ - TranslationBlock *tb; - int n; - - qemu_spin_lock(&dest->jmp_lock); - - TB_FOR_EACH_JMP(dest, tb, n) { - tb_reset_jump(tb, n); - qatomic_and(&tb->jmp_dest[n], (uintptr_t)NULL | 1); - /* No need to clear the list entry; setting the dest ptr is enough */ - } - dest->jmp_list_head = (uintptr_t)NULL; - - qemu_spin_unlock(&dest->jmp_lock); -} - -static void tb_jmp_cache_inval_tb(TranslationBlock *tb) -{ - CPUState *cpu; - - if (TARGET_TB_PCREL) { - /* A TB may be at any virtual address */ - CPU_FOREACH(cpu) { - tcg_flush_jmp_cache(cpu); - } - } else { - uint32_t h = tb_jmp_cache_hash_func(tb_pc(tb)); - - CPU_FOREACH(cpu) { - CPUJumpCache *jc = cpu->tb_jmp_cache; - - if (qatomic_read(&jc->array[h].tb) == tb) { - qatomic_set(&jc->array[h].tb, NULL); - } - } - } -} - -/* - * In user-mode, call with mmap_lock held. - * In !user-mode, if @rm_from_page_list is set, call with the TB's pages' - * locks held. - */ -static void do_tb_phys_invalidate(TranslationBlock *tb, bool rm_from_page_list) -{ - PageDesc *p; - uint32_t h; - tb_page_addr_t phys_pc; - uint32_t orig_cflags = tb_cflags(tb); - - assert_memory_lock(); - - /* make sure no further incoming jumps will be chained to this TB */ - qemu_spin_lock(&tb->jmp_lock); - qatomic_set(&tb->cflags, tb->cflags | CF_INVALID); - qemu_spin_unlock(&tb->jmp_lock); - - /* remove the TB from the hash list */ - phys_pc = tb->page_addr[0]; - h = tb_hash_func(phys_pc, (TARGET_TB_PCREL ? 0 : tb_pc(tb)), - tb->flags, orig_cflags, tb->trace_vcpu_dstate); - if (!qht_remove(&tb_ctx.htable, tb, h)) { - return; - } - - /* remove the TB from the page list */ - if (rm_from_page_list) { - p = page_find(tb->page_addr[0] >> TARGET_PAGE_BITS); - tb_page_remove(p, tb); - if (tb->page_addr[1] != -1) { - p = page_find(tb->page_addr[1] >> TARGET_PAGE_BITS); - tb_page_remove(p, tb); - } - } - - /* remove the TB from the hash list */ - tb_jmp_cache_inval_tb(tb); - - /* suppress this TB from the two jump lists */ - tb_remove_from_jmp_list(tb, 0); - tb_remove_from_jmp_list(tb, 1); - - /* suppress any remaining jumps to this TB */ - tb_jmp_unlink(tb); - - qatomic_set(&tb_ctx.tb_phys_invalidate_count, - tb_ctx.tb_phys_invalidate_count + 1); -} - -static void tb_phys_invalidate__locked(TranslationBlock *tb) -{ - qemu_thread_jit_write(); - do_tb_phys_invalidate(tb, true); - qemu_thread_jit_execute(); -} - -/* invalidate one TB - * - * Called with mmap_lock held in user-mode. - */ -void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr) -{ - if (page_addr == -1 && tb->page_addr[0] != -1) { - page_lock_tb(tb); - do_tb_phys_invalidate(tb, true); - page_unlock_tb(tb); - } else { - do_tb_phys_invalidate(tb, false); - } -} - -/* add the tb in the target page and protect it if necessary - * - * Called with mmap_lock held for user-mode emulation. - * Called with @p->lock held in !user-mode. - */ -static inline void tb_page_add(PageDesc *p, TranslationBlock *tb, - unsigned int n, tb_page_addr_t page_addr) -{ -#ifndef CONFIG_USER_ONLY - bool page_already_protected; -#endif - - assert_page_locked(p); - - tb->page_addr[n] = page_addr; - tb->page_next[n] = p->first_tb; -#ifndef CONFIG_USER_ONLY - page_already_protected = p->first_tb != (uintptr_t)NULL; -#endif - p->first_tb = (uintptr_t)tb | n; - -#if defined(CONFIG_USER_ONLY) - /* translator_loop() must have made all TB pages non-writable */ - assert(!(p->flags & PAGE_WRITE)); -#else - /* if some code is already present, then the pages are already - protected. So we handle the case where only the first TB is - allocated in a physical page */ - if (!page_already_protected) { - tlb_protect_code(page_addr); - } -#endif -} - -/* - * Add a new TB and link it to the physical page tables. phys_page2 is - * (-1) to indicate that only one page contains the TB. - * - * Called with mmap_lock held for user-mode emulation. - * - * Returns a pointer @tb, or a pointer to an existing TB that matches @tb. - * Note that in !user-mode, another thread might have already added a TB - * for the same block of guest code that @tb corresponds to. In that case, - * the caller should discard the original @tb, and use instead the returned TB. - */ -static TranslationBlock * -tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc, - tb_page_addr_t phys_page2) -{ - PageDesc *p; - PageDesc *p2 = NULL; - void *existing_tb = NULL; - uint32_t h; - - assert_memory_lock(); - tcg_debug_assert(!(tb->cflags & CF_INVALID)); - - /* - * Add the TB to the page list, acquiring first the pages's locks. - * We keep the locks held until after inserting the TB in the hash table, - * so that if the insertion fails we know for sure that the TBs are still - * in the page descriptors. - * Note that inserting into the hash table first isn't an option, since - * we can only insert TBs that are fully initialized. - */ - page_lock_pair(&p, phys_pc, &p2, phys_page2, true); - tb_page_add(p, tb, 0, phys_pc); - if (p2) { - tb_page_add(p2, tb, 1, phys_page2); - } else { - tb->page_addr[1] = -1; - } - - /* add in the hash table */ - h = tb_hash_func(phys_pc, (TARGET_TB_PCREL ? 0 : tb_pc(tb)), - tb->flags, tb->cflags, tb->trace_vcpu_dstate); - qht_insert(&tb_ctx.htable, tb, h, &existing_tb); - - /* remove TB from the page(s) if we couldn't insert it */ - if (unlikely(existing_tb)) { - tb_page_remove(p, tb); - if (p2) { - tb_page_remove(p2, tb); - } - tb = existing_tb; - } - - if (p2 && p2 != p) { - page_unlock(p2); - } - page_unlock(p); - return tb; -} - /* Called with mmap_lock held for user mode emulation. */ TranslationBlock *tb_gen_code(CPUState *cpu, target_ulong pc, target_ulong cs_base, @@ -1497,251 +998,6 @@ TranslationBlock *tb_gen_code(CPUState *cpu, return tb; } -/* - * @p must be non-NULL. - * user-mode: call with mmap_lock held. - * !user-mode: call with all @pages locked. - */ -static void -tb_invalidate_phys_page_range__locked(struct page_collection *pages, - PageDesc *p, tb_page_addr_t start, - tb_page_addr_t end, - uintptr_t retaddr) -{ - TranslationBlock *tb; - tb_page_addr_t tb_start, tb_end; - int n; -#ifdef TARGET_HAS_PRECISE_SMC - CPUState *cpu = current_cpu; - CPUArchState *env = NULL; - bool current_tb_not_found = retaddr != 0; - bool current_tb_modified = false; - TranslationBlock *current_tb = NULL; - target_ulong current_pc = 0; - target_ulong current_cs_base = 0; - uint32_t current_flags = 0; -#endif /* TARGET_HAS_PRECISE_SMC */ - - assert_page_locked(p); - -#if defined(TARGET_HAS_PRECISE_SMC) - if (cpu != NULL) { - env = cpu->env_ptr; - } -#endif - - /* we remove all the TBs in the range [start, end[ */ - /* XXX: see if in some cases it could be faster to invalidate all - the code */ - PAGE_FOR_EACH_TB(p, tb, n) { - assert_page_locked(p); - /* NOTE: this is subtle as a TB may span two physical pages */ - if (n == 0) { - /* NOTE: tb_end may be after the end of the page, but - it is not a problem */ - tb_start = tb->page_addr[0]; - tb_end = tb_start + tb->size; - } else { - tb_start = tb->page_addr[1]; - tb_end = tb_start + ((tb->page_addr[0] + tb->size) - & ~TARGET_PAGE_MASK); - } - if (!(tb_end <= start || tb_start >= end)) { -#ifdef TARGET_HAS_PRECISE_SMC - if (current_tb_not_found) { - current_tb_not_found = false; - /* now we have a real cpu fault */ - current_tb = tcg_tb_lookup(retaddr); - } - if (current_tb == tb && - (tb_cflags(current_tb) & CF_COUNT_MASK) != 1) { - /* - * If we are modifying the current TB, we must stop - * its execution. We could be more precise by checking - * that the modification is after the current PC, but it - * would require a specialized function to partially - * restore the CPU state. - */ - current_tb_modified = true; - cpu_restore_state_from_tb(cpu, current_tb, retaddr, true); - cpu_get_tb_cpu_state(env, ¤t_pc, ¤t_cs_base, - ¤t_flags); - } -#endif /* TARGET_HAS_PRECISE_SMC */ - tb_phys_invalidate__locked(tb); - } - } -#if !defined(CONFIG_USER_ONLY) - /* if no code remaining, no need to continue to use slow writes */ - if (!p->first_tb) { - tlb_unprotect_code(start); - } -#endif -#ifdef TARGET_HAS_PRECISE_SMC - if (current_tb_modified) { - page_collection_unlock(pages); - /* Force execution of one insn next time. */ - cpu->cflags_next_tb = 1 | CF_NOIRQ | curr_cflags(cpu); - mmap_unlock(); - cpu_loop_exit_noexc(cpu); - } -#endif -} - -/* - * Invalidate all TBs which intersect with the target physical address range - * [start;end[. NOTE: start and end must refer to the *same* physical page. - * 'is_cpu_write_access' should be true if called from a real cpu write - * access: the virtual CPU will exit the current TB if code is modified inside - * this TB. - * - * Called with mmap_lock held for user-mode emulation - */ -void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end) -{ - struct page_collection *pages; - PageDesc *p; - - assert_memory_lock(); - - p = page_find(start >> TARGET_PAGE_BITS); - if (p == NULL) { - return; - } - pages = page_collection_lock(start, end); - tb_invalidate_phys_page_range__locked(pages, p, start, end, 0); - page_collection_unlock(pages); -} - -/* - * Invalidate all TBs which intersect with the target physical address range - * [start;end[. NOTE: start and end may refer to *different* physical pages. - * 'is_cpu_write_access' should be true if called from a real cpu write - * access: the virtual CPU will exit the current TB if code is modified inside - * this TB. - * - * Called with mmap_lock held for user-mode emulation. - */ -#ifdef CONFIG_SOFTMMU -void tb_invalidate_phys_range(ram_addr_t start, ram_addr_t end) -#else -void tb_invalidate_phys_range(target_ulong start, target_ulong end) -#endif -{ - struct page_collection *pages; - tb_page_addr_t next; - - assert_memory_lock(); - - pages = page_collection_lock(start, end); - for (next = (start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; - start < end; - start = next, next += TARGET_PAGE_SIZE) { - PageDesc *pd = page_find(start >> TARGET_PAGE_BITS); - tb_page_addr_t bound = MIN(next, end); - - if (pd == NULL) { - continue; - } - tb_invalidate_phys_page_range__locked(pages, pd, start, bound, 0); - } - page_collection_unlock(pages); -} - -#ifdef CONFIG_SOFTMMU -/* len must be <= 8 and start must be a multiple of len. - * Called via softmmu_template.h when code areas are written to with - * iothread mutex not held. - * - * Call with all @pages in the range [@start, @start + len[ locked. - */ -void tb_invalidate_phys_page_fast(struct page_collection *pages, - tb_page_addr_t start, int len, - uintptr_t retaddr) -{ - PageDesc *p; - - assert_memory_lock(); - - p = page_find(start >> TARGET_PAGE_BITS); - if (!p) { - return; - } - - assert_page_locked(p); - tb_invalidate_phys_page_range__locked(pages, p, start, start + len, - retaddr); -} -#else -/* Called with mmap_lock held. If pc is not 0 then it indicates the - * host PC of the faulting store instruction that caused this invalidate. - * Returns true if the caller needs to abort execution of the current - * TB (because it was modified by this store and the guest CPU has - * precise-SMC semantics). - */ -static bool tb_invalidate_phys_page(tb_page_addr_t addr, uintptr_t pc) -{ - TranslationBlock *tb; - PageDesc *p; - int n; -#ifdef TARGET_HAS_PRECISE_SMC - TranslationBlock *current_tb = NULL; - CPUState *cpu = current_cpu; - CPUArchState *env = NULL; - int current_tb_modified = 0; - target_ulong current_pc = 0; - target_ulong current_cs_base = 0; - uint32_t current_flags = 0; -#endif - - assert_memory_lock(); - - addr &= TARGET_PAGE_MASK; - p = page_find(addr >> TARGET_PAGE_BITS); - if (!p) { - return false; - } - -#ifdef TARGET_HAS_PRECISE_SMC - if (p->first_tb && pc != 0) { - current_tb = tcg_tb_lookup(pc); - } - if (cpu != NULL) { - env = cpu->env_ptr; - } -#endif - assert_page_locked(p); - PAGE_FOR_EACH_TB(p, tb, n) { -#ifdef TARGET_HAS_PRECISE_SMC - if (current_tb == tb && - (tb_cflags(current_tb) & CF_COUNT_MASK) != 1) { - /* If we are modifying the current TB, we must stop - its execution. We could be more precise by checking - that the modification is after the current PC, but it - would require a specialized function to partially - restore the CPU state */ - - current_tb_modified = 1; - cpu_restore_state_from_tb(cpu, current_tb, pc, true); - cpu_get_tb_cpu_state(env, ¤t_pc, ¤t_cs_base, - ¤t_flags); - } -#endif /* TARGET_HAS_PRECISE_SMC */ - tb_phys_invalidate(tb, addr); - } - p->first_tb = (uintptr_t)NULL; -#ifdef TARGET_HAS_PRECISE_SMC - if (current_tb_modified) { - /* Force execution of one insn next time. */ - cpu->cflags_next_tb = 1 | CF_NOIRQ | curr_cflags(cpu); - return true; - } -#endif - - return false; -} -#endif - /* user-mode: call with mmap_lock held */ void tb_check_watchpoint(CPUState *cpu, uintptr_t retaddr) { From cc05368ad999a5e06890a829b2ccba7ae4e0fe8b Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 5 Oct 2022 15:08:34 -0700 Subject: [PATCH 106/705] accel/tcg: Move assert_no_pages_locked to internal.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are no users outside of accel/tcg; this function does not need to be defined in exec-all.h. Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- accel/tcg/internal.h | 5 +++++ include/exec/exec-all.h | 8 -------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h index a77b110b78..1a704ee14f 100644 --- a/accel/tcg/internal.h +++ b/accel/tcg/internal.h @@ -90,6 +90,11 @@ void do_assert_page_locked(const PageDesc *pd, const char *file, int line); void page_lock(PageDesc *pd); void page_unlock(PageDesc *pd); #endif +#if !defined(CONFIG_USER_ONLY) && defined(CONFIG_DEBUG_TCG) +void assert_no_pages_locked(void); +#else +static inline void assert_no_pages_locked(void) { } +#endif TranslationBlock *tb_gen_code(CPUState *cpu, target_ulong pc, target_ulong cs_base, uint32_t flags, diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index e5f8b224a5..b5bde1b56a 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -642,14 +642,6 @@ extern __thread uintptr_t tci_tb_ptr; smaller than 4 bytes, so we don't worry about special-casing this. */ #define GETPC_ADJ 2 -#if !defined(CONFIG_USER_ONLY) && defined(CONFIG_DEBUG_TCG) -void assert_no_pages_locked(void); -#else -static inline void assert_no_pages_locked(void) -{ -} -#endif - #if !defined(CONFIG_USER_ONLY) /** From 8516e2a92c9011fed1d1601dd69872dba083d5c6 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 20 Sep 2022 07:48:43 +0200 Subject: [PATCH 107/705] accel/tcg: Drop cpu_get_tb_cpu_state from TARGET_HAS_PRECISE_SMC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The results of the calls to cpu_get_tb_cpu_state, current_{pc,cs_base,flags}, are not used. In tb_invalidate_phys_page, use bool for current_tb_modified. Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- accel/tcg/tb-maint.c | 25 ++----------------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c index 66c1900ae6..9af5cb49e0 100644 --- a/accel/tcg/tb-maint.c +++ b/accel/tcg/tb-maint.c @@ -502,23 +502,13 @@ tb_invalidate_phys_page_range__locked(struct page_collection *pages, int n; #ifdef TARGET_HAS_PRECISE_SMC CPUState *cpu = current_cpu; - CPUArchState *env = NULL; bool current_tb_not_found = retaddr != 0; bool current_tb_modified = false; TranslationBlock *current_tb = NULL; - target_ulong current_pc = 0; - target_ulong current_cs_base = 0; - uint32_t current_flags = 0; #endif /* TARGET_HAS_PRECISE_SMC */ assert_page_locked(p); -#if defined(TARGET_HAS_PRECISE_SMC) - if (cpu != NULL) { - env = cpu->env_ptr; - } -#endif - /* * We remove all the TBs in the range [start, end[. * XXX: see if in some cases it could be faster to invalidate all the code @@ -554,8 +544,6 @@ tb_invalidate_phys_page_range__locked(struct page_collection *pages, */ current_tb_modified = true; cpu_restore_state_from_tb(cpu, current_tb, retaddr, true); - cpu_get_tb_cpu_state(env, ¤t_pc, ¤t_cs_base, - ¤t_flags); } #endif /* TARGET_HAS_PRECISE_SMC */ tb_phys_invalidate__locked(tb); @@ -679,11 +667,7 @@ bool tb_invalidate_phys_page(tb_page_addr_t addr, uintptr_t pc) #ifdef TARGET_HAS_PRECISE_SMC TranslationBlock *current_tb = NULL; CPUState *cpu = current_cpu; - CPUArchState *env = NULL; - int current_tb_modified = 0; - target_ulong current_pc = 0; - target_ulong current_cs_base = 0; - uint32_t current_flags = 0; + bool current_tb_modified = false; #endif assert_memory_lock(); @@ -698,9 +682,6 @@ bool tb_invalidate_phys_page(tb_page_addr_t addr, uintptr_t pc) if (p->first_tb && pc != 0) { current_tb = tcg_tb_lookup(pc); } - if (cpu != NULL) { - env = cpu->env_ptr; - } #endif assert_page_locked(p); PAGE_FOR_EACH_TB(p, tb, n) { @@ -713,10 +694,8 @@ bool tb_invalidate_phys_page(tb_page_addr_t addr, uintptr_t pc) * after the current PC, but it would require a specialized * function to partially restore the CPU state. */ - current_tb_modified = 1; + current_tb_modified = true; cpu_restore_state_from_tb(cpu, current_tb, pc, true); - cpu_get_tb_cpu_state(env, ¤t_pc, ¤t_cs_base, - ¤t_flags); } #endif /* TARGET_HAS_PRECISE_SMC */ tb_phys_invalidate(tb, addr); From 4c88475c9fe501b5c886a963647670f929c65400 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 20 Sep 2022 13:09:45 +0200 Subject: [PATCH 108/705] accel/tcg: Remove duplicate store to tb->page_addr[] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When we added the fast path, we initialized page_addr[] early. These stores in and around tb_page_add() are redundant; remove them. Fixes: 50627f1b7b1 ("accel/tcg: Add fast path for translator_ld*") Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- accel/tcg/tb-maint.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c index 9af5cb49e0..7f4e1e1299 100644 --- a/accel/tcg/tb-maint.c +++ b/accel/tcg/tb-maint.c @@ -405,7 +405,6 @@ static inline void tb_page_add(PageDesc *p, TranslationBlock *tb, assert_page_locked(p); - tb->page_addr[n] = page_addr; tb->page_next[n] = p->first_tb; #ifndef CONFIG_USER_ONLY page_already_protected = p->first_tb != (uintptr_t)NULL; @@ -461,8 +460,6 @@ TranslationBlock *tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc, tb_page_add(p, tb, 0, phys_pc); if (p2) { tb_page_add(p2, tb, 1, phys_page2); - } else { - tb->page_addr[1] = -1; } /* add in the hash table */ From 28905cfbd521c40ebc6d7b4c5941c0ec1ca935eb Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 20 Sep 2022 13:21:40 +0200 Subject: [PATCH 109/705] accel/tcg: Introduce tb_{set_}page_addr{0,1} MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This data structure will be replaced for user-only: add accessors. Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- accel/tcg/cpu-exec.c | 9 +++++---- accel/tcg/tb-maint.c | 29 +++++++++++++++-------------- accel/tcg/translate-all.c | 16 ++++++++-------- accel/tcg/translator.c | 9 +++++---- include/exec/exec-all.h | 22 ++++++++++++++++++++++ 5 files changed, 55 insertions(+), 30 deletions(-) diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c index bb4b9e92ce..82b06c1824 100644 --- a/accel/tcg/cpu-exec.c +++ b/accel/tcg/cpu-exec.c @@ -187,13 +187,14 @@ static bool tb_lookup_cmp(const void *p, const void *d) const struct tb_desc *desc = d; if ((TARGET_TB_PCREL || tb_pc(tb) == desc->pc) && - tb->page_addr[0] == desc->page_addr0 && + tb_page_addr0(tb) == desc->page_addr0 && tb->cs_base == desc->cs_base && tb->flags == desc->flags && tb->trace_vcpu_dstate == desc->trace_vcpu_dstate && tb_cflags(tb) == desc->cflags) { /* check next page if needed */ - if (tb->page_addr[1] == -1) { + tb_page_addr_t tb_phys_page1 = tb_page_addr1(tb); + if (tb_phys_page1 == -1) { return true; } else { tb_page_addr_t phys_page1; @@ -210,7 +211,7 @@ static bool tb_lookup_cmp(const void *p, const void *d) */ virt_page1 = TARGET_PAGE_ALIGN(desc->pc); phys_page1 = get_page_addr_code(desc->env, virt_page1); - if (tb->page_addr[1] == phys_page1) { + if (tb_phys_page1 == phys_page1) { return true; } } @@ -1019,7 +1020,7 @@ int cpu_exec(CPUState *cpu) * direct jump to a TB spanning two pages because the mapping * for the second page can change. */ - if (tb->page_addr[1] != -1) { + if (tb_page_addr1(tb) != -1) { last_tb = NULL; } #endif diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c index 7f4e1e1299..15ec2f741d 100644 --- a/accel/tcg/tb-maint.c +++ b/accel/tcg/tb-maint.c @@ -44,8 +44,8 @@ static bool tb_cmp(const void *ap, const void *bp) a->flags == b->flags && (tb_cflags(a) & ~CF_INVALID) == (tb_cflags(b) & ~CF_INVALID) && a->trace_vcpu_dstate == b->trace_vcpu_dstate && - a->page_addr[0] == b->page_addr[0] && - a->page_addr[1] == b->page_addr[1]); + tb_page_addr0(a) == tb_page_addr0(b) && + tb_page_addr1(a) == tb_page_addr1(b)); } void tb_htable_init(void) @@ -273,7 +273,7 @@ static void do_tb_phys_invalidate(TranslationBlock *tb, bool rm_from_page_list) qemu_spin_unlock(&tb->jmp_lock); /* remove the TB from the hash list */ - phys_pc = tb->page_addr[0]; + phys_pc = tb_page_addr0(tb); h = tb_hash_func(phys_pc, (TARGET_TB_PCREL ? 0 : tb_pc(tb)), tb->flags, orig_cflags, tb->trace_vcpu_dstate); if (!qht_remove(&tb_ctx.htable, tb, h)) { @@ -282,10 +282,11 @@ static void do_tb_phys_invalidate(TranslationBlock *tb, bool rm_from_page_list) /* remove the TB from the page list */ if (rm_from_page_list) { - p = page_find(tb->page_addr[0] >> TARGET_PAGE_BITS); + p = page_find(phys_pc >> TARGET_PAGE_BITS); tb_page_remove(p, tb); - if (tb->page_addr[1] != -1) { - p = page_find(tb->page_addr[1] >> TARGET_PAGE_BITS); + phys_pc = tb_page_addr1(tb); + if (phys_pc != -1) { + p = page_find(phys_pc >> TARGET_PAGE_BITS); tb_page_remove(p, tb); } } @@ -358,16 +359,16 @@ static inline void page_unlock_tb(const TranslationBlock *tb) { } /* lock the page(s) of a TB in the correct acquisition order */ static void page_lock_tb(const TranslationBlock *tb) { - page_lock_pair(NULL, tb->page_addr[0], NULL, tb->page_addr[1], false); + page_lock_pair(NULL, tb_page_addr0(tb), NULL, tb_page_addr1(tb), false); } static void page_unlock_tb(const TranslationBlock *tb) { - PageDesc *p1 = page_find(tb->page_addr[0] >> TARGET_PAGE_BITS); + PageDesc *p1 = page_find(tb_page_addr0(tb) >> TARGET_PAGE_BITS); page_unlock(p1); - if (unlikely(tb->page_addr[1] != -1)) { - PageDesc *p2 = page_find(tb->page_addr[1] >> TARGET_PAGE_BITS); + if (unlikely(tb_page_addr1(tb) != -1)) { + PageDesc *p2 = page_find(tb_page_addr1(tb) >> TARGET_PAGE_BITS); if (p2 != p1) { page_unlock(p2); @@ -382,7 +383,7 @@ static void page_unlock_tb(const TranslationBlock *tb) */ void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr) { - if (page_addr == -1 && tb->page_addr[0] != -1) { + if (page_addr == -1 && tb_page_addr0(tb) != -1) { page_lock_tb(tb); do_tb_phys_invalidate(tb, true); page_unlock_tb(tb); @@ -516,11 +517,11 @@ tb_invalidate_phys_page_range__locked(struct page_collection *pages, if (n == 0) { /* NOTE: tb_end may be after the end of the page, but it is not a problem */ - tb_start = tb->page_addr[0]; + tb_start = tb_page_addr0(tb); tb_end = tb_start + tb->size; } else { - tb_start = tb->page_addr[1]; - tb_end = tb_start + ((tb->page_addr[0] + tb->size) + tb_start = tb_page_addr1(tb); + tb_end = tb_start + ((tb_page_addr0(tb) + tb->size) & ~TARGET_PAGE_MASK); } if (!(tb_end <= start || tb_start >= end)) { diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 5e28e9fccd..bef4c56cff 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -698,9 +698,9 @@ page_collection_lock(tb_page_addr_t start, tb_page_addr_t end) } assert_page_locked(pd); PAGE_FOR_EACH_TB(pd, tb, n) { - if (page_trylock_add(set, tb->page_addr[0]) || - (tb->page_addr[1] != -1 && - page_trylock_add(set, tb->page_addr[1]))) { + if (page_trylock_add(set, tb_page_addr0(tb)) || + (tb_page_addr1(tb) != -1 && + page_trylock_add(set, tb_page_addr1(tb)))) { /* drop all locks, and reacquire in order */ g_tree_foreach(set->tree, page_entry_unlock, NULL); goto retry; @@ -771,8 +771,8 @@ TranslationBlock *tb_gen_code(CPUState *cpu, tb->flags = flags; tb->cflags = cflags; tb->trace_vcpu_dstate = *cpu->trace_dstate; - tb->page_addr[0] = phys_pc; - tb->page_addr[1] = -1; + tb_set_page_addr0(tb, phys_pc); + tb_set_page_addr1(tb, -1); tcg_ctx->tb_cflags = cflags; tb_overflow: @@ -970,7 +970,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu, * a temporary one-insn TB, and we have nothing left to do. Return early * before attempting to link to other TBs or add to the lookup table. */ - if (tb->page_addr[0] == -1) { + if (tb_page_addr0(tb) == -1) { return tb; } @@ -985,7 +985,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu, * No explicit memory barrier is required -- tb_link_page() makes the * TB visible in a consistent state. */ - existing_tb = tb_link_page(tb, tb->page_addr[0], tb->page_addr[1]); + existing_tb = tb_link_page(tb, tb_page_addr0(tb), tb_page_addr1(tb)); /* if the TB already exists, discard what we just translated */ if (unlikely(existing_tb != tb)) { uintptr_t orig_aligned = (uintptr_t)gen_code_buf; @@ -1140,7 +1140,7 @@ static gboolean tb_tree_stats_iter(gpointer key, gpointer value, gpointer data) if (tb->size > tst->max_target_size) { tst->max_target_size = tb->size; } - if (tb->page_addr[1] != -1) { + if (tb_page_addr1(tb) != -1) { tst->cross_page++; } if (tb->jmp_reset_offset[0] != TB_JMP_RESET_OFFSET_INVALID) { diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c index 8e78fd7a9c..061519691f 100644 --- a/accel/tcg/translator.c +++ b/accel/tcg/translator.c @@ -157,7 +157,7 @@ static void *translator_access(CPUArchState *env, DisasContextBase *db, tb = db->tb; /* Use slow path if first page is MMIO. */ - if (unlikely(tb->page_addr[0] == -1)) { + if (unlikely(tb_page_addr0(tb) == -1)) { return NULL; } @@ -169,13 +169,14 @@ static void *translator_access(CPUArchState *env, DisasContextBase *db, host = db->host_addr[1]; base = TARGET_PAGE_ALIGN(db->pc_first); if (host == NULL) { - tb->page_addr[1] = + tb_page_addr_t phys_page = get_page_addr_code_hostp(env, base, &db->host_addr[1]); + /* We cannot handle MMIO as second page. */ + assert(phys_page != -1); + tb_set_page_addr1(tb, phys_page); #ifdef CONFIG_USER_ONLY page_protect(end); #endif - /* We cannot handle MMIO as second page. */ - assert(tb->page_addr[1] != -1); host = db->host_addr[1]; } diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index b5bde1b56a..5900f4637b 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -610,6 +610,28 @@ static inline uint32_t tb_cflags(const TranslationBlock *tb) return qatomic_read(&tb->cflags); } +static inline tb_page_addr_t tb_page_addr0(const TranslationBlock *tb) +{ + return tb->page_addr[0]; +} + +static inline tb_page_addr_t tb_page_addr1(const TranslationBlock *tb) +{ + return tb->page_addr[1]; +} + +static inline void tb_set_page_addr0(TranslationBlock *tb, + tb_page_addr_t addr) +{ + tb->page_addr[0] = addr; +} + +static inline void tb_set_page_addr1(TranslationBlock *tb, + tb_page_addr_t addr) +{ + tb->page_addr[1] = addr; +} + /* current cflags for hashing/comparison */ uint32_t curr_cflags(CPUState *cpu); From 67aabbb312eda2316011aab5b54c37d08c82f933 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 5 Oct 2022 09:18:39 -0700 Subject: [PATCH 110/705] accel/tcg: Rename tb_invalidate_phys_page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename to tb_invalidate_phys_page_unwind to emphasize that we also detect invalidating the current TB, and also to free up that name for other usage. Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- accel/tcg/internal.h | 2 +- accel/tcg/tb-maint.c | 2 +- accel/tcg/translate-all.c | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h index 1a704ee14f..1227bb69bd 100644 --- a/accel/tcg/internal.h +++ b/accel/tcg/internal.h @@ -105,7 +105,7 @@ void tb_htable_init(void); void tb_reset_jump(TranslationBlock *tb, int n); TranslationBlock *tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc, tb_page_addr_t phys_page2); -bool tb_invalidate_phys_page(tb_page_addr_t addr, uintptr_t pc); +bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc); int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, uintptr_t searched_pc, bool reset_icount); diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c index 15ec2f741d..92170cbbc1 100644 --- a/accel/tcg/tb-maint.c +++ b/accel/tcg/tb-maint.c @@ -657,7 +657,7 @@ void tb_invalidate_phys_page_fast(struct page_collection *pages, * TB (because it was modified by this store and the guest CPU has * precise-SMC semantics). */ -bool tb_invalidate_phys_page(tb_page_addr_t addr, uintptr_t pc) +bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc) { TranslationBlock *tb; PageDesc *p; diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index bef4c56cff..aa8d213514 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -1382,7 +1382,7 @@ void page_set_flags(target_ulong start, target_ulong end, int flags) if (!(p->flags & PAGE_WRITE) && (flags & PAGE_WRITE) && p->first_tb) { - tb_invalidate_phys_page(addr, 0); + tb_invalidate_phys_page_unwind(addr, 0); } if (reset_target_data) { g_free(p->target_data); @@ -1580,7 +1580,8 @@ int page_unprotect(target_ulong address, uintptr_t pc) /* and since the content will be modified, we must invalidate the corresponding translated code. */ - current_tb_invalidated |= tb_invalidate_phys_page(addr, pc); + current_tb_invalidated |= + tb_invalidate_phys_page_unwind(addr, pc); } mprotect((void *)g2h_untagged(host_start), qemu_host_page_size, prot & PAGE_BITS); From d6d1fd29733c1b575bd928066024be6f2bb05d42 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 5 Oct 2022 09:26:26 -0700 Subject: [PATCH 111/705] accel/tcg: Rename tb_invalidate_phys_page_range and drop end parameter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This function is is never called with a real range, only for a single page. Drop the second parameter and rename to tb_invalidate_phys_page. Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- accel/tcg/tb-maint.c | 15 ++++++++------- cpu.c | 4 ++-- include/exec/translate-all.h | 2 +- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c index 92170cbbc1..bac43774c0 100644 --- a/accel/tcg/tb-maint.c +++ b/accel/tcg/tb-maint.c @@ -565,25 +565,26 @@ tb_invalidate_phys_page_range__locked(struct page_collection *pages, } /* - * Invalidate all TBs which intersect with the target physical address range - * [start;end[. NOTE: start and end must refer to the *same* physical page. - * 'is_cpu_write_access' should be true if called from a real cpu write - * access: the virtual CPU will exit the current TB if code is modified inside - * this TB. + * Invalidate all TBs which intersect with the target physical + * address page @addr. * * Called with mmap_lock held for user-mode emulation */ -void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end) +void tb_invalidate_phys_page(tb_page_addr_t addr) { struct page_collection *pages; + tb_page_addr_t start, end; PageDesc *p; assert_memory_lock(); - p = page_find(start >> TARGET_PAGE_BITS); + p = page_find(addr >> TARGET_PAGE_BITS); if (p == NULL) { return; } + + start = addr & TARGET_PAGE_MASK; + end = start + TARGET_PAGE_SIZE; pages = page_collection_lock(start, end); tb_invalidate_phys_page_range__locked(pages, p, start, end, 0); page_collection_unlock(pages); diff --git a/cpu.c b/cpu.c index 14365e36f3..2a09b05205 100644 --- a/cpu.c +++ b/cpu.c @@ -277,7 +277,7 @@ void list_cpus(const char *optarg) void tb_invalidate_phys_addr(target_ulong addr) { mmap_lock(); - tb_invalidate_phys_page_range(addr, addr + 1); + tb_invalidate_phys_page(addr); mmap_unlock(); } #else @@ -298,7 +298,7 @@ void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr, MemTxAttrs attrs) return; } ram_addr = memory_region_get_ram_addr(mr) + addr; - tb_invalidate_phys_page_range(ram_addr, ram_addr + 1); + tb_invalidate_phys_page(ram_addr); } #endif diff --git a/include/exec/translate-all.h b/include/exec/translate-all.h index 9f646389af..3e9cb91565 100644 --- a/include/exec/translate-all.h +++ b/include/exec/translate-all.h @@ -29,7 +29,7 @@ void page_collection_unlock(struct page_collection *set); void tb_invalidate_phys_page_fast(struct page_collection *pages, tb_page_addr_t start, int len, uintptr_t retaddr); -void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end); +void tb_invalidate_phys_page(tb_page_addr_t addr); void tb_check_watchpoint(CPUState *cpu, uintptr_t retaddr); #ifdef CONFIG_USER_ONLY From 65cd34e8c445079279abf16d127f138141a360e4 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 5 Oct 2022 13:50:32 -0700 Subject: [PATCH 112/705] accel/tcg: Unify declarations of tb_invalidate_phys_range MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We missed this function when we introduced tb_page_addr_t. Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- accel/tcg/tb-maint.c | 13 ++----------- include/exec/exec-all.h | 2 +- include/exec/ram_addr.h | 2 -- 3 files changed, 3 insertions(+), 14 deletions(-) diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c index bac43774c0..c8e921089d 100644 --- a/accel/tcg/tb-maint.c +++ b/accel/tcg/tb-maint.c @@ -20,6 +20,7 @@ #include "qemu/osdep.h" #include "exec/cputlb.h" #include "exec/log.h" +#include "exec/exec-all.h" #include "exec/translate-all.h" #include "sysemu/tcg.h" #include "tcg/tcg.h" @@ -27,12 +28,6 @@ #include "tb-context.h" #include "internal.h" -/* FIXME: tb_invalidate_phys_range is declared in different places. */ -#ifdef CONFIG_USER_ONLY -#include "exec/exec-all.h" -#else -#include "exec/ram_addr.h" -#endif static bool tb_cmp(const void *ap, const void *bp) { @@ -599,11 +594,7 @@ void tb_invalidate_phys_page(tb_page_addr_t addr) * * Called with mmap_lock held for user-mode emulation. */ -#ifdef CONFIG_SOFTMMU -void tb_invalidate_phys_range(ram_addr_t start, ram_addr_t end) -#else -void tb_invalidate_phys_range(target_ulong start, target_ulong end) -#endif +void tb_invalidate_phys_range(tb_page_addr_t start, tb_page_addr_t end) { struct page_collection *pages; tb_page_addr_t next; diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 5900f4637b..5ae484e34d 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -638,12 +638,12 @@ uint32_t curr_cflags(CPUState *cpu); /* TranslationBlock invalidate API */ #if defined(CONFIG_USER_ONLY) void tb_invalidate_phys_addr(target_ulong addr); -void tb_invalidate_phys_range(target_ulong start, target_ulong end); #else void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr, MemTxAttrs attrs); #endif void tb_flush(CPUState *cpu); void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr); +void tb_invalidate_phys_range(tb_page_addr_t start, tb_page_addr_t end); void tb_set_jmp_target(TranslationBlock *tb, int n, uintptr_t addr); /* GETPC is the true target of the return instruction that we'll execute. */ diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h index f3e0c78161..1500680458 100644 --- a/include/exec/ram_addr.h +++ b/include/exec/ram_addr.h @@ -147,8 +147,6 @@ static inline void qemu_ram_block_writeback(RAMBlock *block) #define DIRTY_CLIENTS_ALL ((1 << DIRTY_MEMORY_NUM) - 1) #define DIRTY_CLIENTS_NOCODE (DIRTY_CLIENTS_ALL & ~(1 << DIRTY_MEMORY_CODE)) -void tb_invalidate_phys_range(ram_addr_t start, ram_addr_t end); - static inline bool cpu_physical_memory_get_dirty(ram_addr_t start, ram_addr_t length, unsigned client) From 24ace1ac3cf4d64bc76b543224c1c0379fa34b51 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 5 Oct 2022 09:27:52 -0700 Subject: [PATCH 113/705] accel/tcg: Use tb_invalidate_phys_page in page_set_flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We do not require detection of overlapping TBs here, so use the more appropriate function. Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- accel/tcg/translate-all.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index aa8d213514..8d5233fa9e 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -1382,7 +1382,7 @@ void page_set_flags(target_ulong start, target_ulong end, int flags) if (!(p->flags & PAGE_WRITE) && (flags & PAGE_WRITE) && p->first_tb) { - tb_invalidate_phys_page_unwind(addr, 0); + tb_invalidate_phys_page(addr); } if (reset_target_data) { g_free(p->target_data); From 8f39e01db9f82033543f707f7b06f81cb675ff67 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 5 Oct 2022 09:44:52 -0700 Subject: [PATCH 114/705] accel/tcg: Call tb_invalidate_phys_page for PAGE_RESET MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When PAGE_RESET is set, we are replacing pages with new content, which means that we need to invalidate existing cached data, such as TranslationBlocks. Perform the reset invalidate while we're doing other invalidates, which allows us to remove the separate invalidates from the user-only mmap/munmap/mprotect routines. In addition, restrict invalidation to PAGE_EXEC pages. Since cdf713085131, we have validated PAGE_EXEC is present before translation, which means we can assume that if the bit is not present, there are no translations to invalidate. Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- accel/tcg/translate-all.c | 19 +++++++++++-------- bsd-user/mmap.c | 2 -- linux-user/mmap.c | 4 ---- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 8d5233fa9e..478301f227 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -1352,7 +1352,7 @@ int page_get_flags(target_ulong address) void page_set_flags(target_ulong start, target_ulong end, int flags) { target_ulong addr, len; - bool reset_target_data; + bool reset; /* This function should never be called with addresses outside the guest address space. If this assert fires, it probably indicates @@ -1369,7 +1369,7 @@ void page_set_flags(target_ulong start, target_ulong end, int flags) if (flags & PAGE_WRITE) { flags |= PAGE_WRITE_ORG; } - reset_target_data = !(flags & PAGE_VALID) || (flags & PAGE_RESET); + reset = !(flags & PAGE_VALID) || (flags & PAGE_RESET); flags &= ~PAGE_RESET; for (addr = start, len = end - start; @@ -1377,14 +1377,17 @@ void page_set_flags(target_ulong start, target_ulong end, int flags) len -= TARGET_PAGE_SIZE, addr += TARGET_PAGE_SIZE) { PageDesc *p = page_find_alloc(addr >> TARGET_PAGE_BITS, true); - /* If the write protection bit is set, then we invalidate - the code inside. */ - if (!(p->flags & PAGE_WRITE) && - (flags & PAGE_WRITE) && - p->first_tb) { + /* + * If the page was executable, but is reset, or is no longer + * executable, or has become writable, then invalidate any code. + */ + if ((p->flags & PAGE_EXEC) + && (reset || + !(flags & PAGE_EXEC) || + (flags & ~p->flags & PAGE_WRITE))) { tb_invalidate_phys_page(addr); } - if (reset_target_data) { + if (reset) { g_free(p->target_data); p->target_data = NULL; p->flags = flags; diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c index e54e26de17..d6c5a344c9 100644 --- a/bsd-user/mmap.c +++ b/bsd-user/mmap.c @@ -663,7 +663,6 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, page_dump(stdout); printf("\n"); #endif - tb_invalidate_phys_range(start, start + len); mmap_unlock(); return start; fail: @@ -769,7 +768,6 @@ int target_munmap(abi_ulong start, abi_ulong len) if (ret == 0) { page_set_flags(start, start + len, 0); - tb_invalidate_phys_range(start, start + len); } mmap_unlock(); return ret; diff --git a/linux-user/mmap.c b/linux-user/mmap.c index 28f3bc85ed..10f5079331 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c @@ -182,7 +182,6 @@ int target_mprotect(abi_ulong start, abi_ulong len, int target_prot) } page_set_flags(start, start + len, page_flags); - tb_invalidate_phys_range(start, start + len); ret = 0; error: @@ -662,7 +661,6 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot, qemu_log_unlock(f); } } - tb_invalidate_phys_range(start, start + len); mmap_unlock(); return start; fail: @@ -766,7 +764,6 @@ int target_munmap(abi_ulong start, abi_ulong len) if (ret == 0) { page_set_flags(start, start + len, 0); - tb_invalidate_phys_range(start, start + len); } mmap_unlock(); return ret; @@ -856,7 +853,6 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size, page_set_flags(new_addr, new_addr + new_size, prot | PAGE_VALID | PAGE_RESET); } - tb_invalidate_phys_range(new_addr, new_addr + new_size); mmap_unlock(); return new_addr; } From 43301e05669e19f41fb8530e77ac0c8953195bbf Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 5 Oct 2022 12:56:14 -0700 Subject: [PATCH 115/705] accel/tcg: Use page_reset_target_data in page_set_flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the existing function for clearing target data. Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- accel/tcg/translate-all.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 478301f227..41b6d5fe26 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -1370,6 +1370,9 @@ void page_set_flags(target_ulong start, target_ulong end, int flags) flags |= PAGE_WRITE_ORG; } reset = !(flags & PAGE_VALID) || (flags & PAGE_RESET); + if (reset) { + page_reset_target_data(start, end); + } flags &= ~PAGE_RESET; for (addr = start, len = end - start; @@ -1387,14 +1390,8 @@ void page_set_flags(target_ulong start, target_ulong end, int flags) (flags & ~p->flags & PAGE_WRITE))) { tb_invalidate_phys_page(addr); } - if (reset) { - g_free(p->target_data); - p->target_data = NULL; - p->flags = flags; - } else { - /* Using mprotect on a page does not change sticky bits. */ - p->flags = (p->flags & PAGE_STICKY) | flags; - } + /* Using mprotect on a page does not change sticky bits. */ + p->flags = (reset ? 0 : p->flags & PAGE_STICKY) | flags; } } From e786509f29c3b4ea7e295f79e8e73e7a3b2f2818 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 5 Oct 2022 12:56:46 -0700 Subject: [PATCH 116/705] accel/tcg: Use tb_invalidate_phys_range in page_set_flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Flush translation blocks in bulk, rather than page-by-page. Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- accel/tcg/translate-all.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 41b6d5fe26..eea24dea96 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -1352,7 +1352,7 @@ int page_get_flags(target_ulong address) void page_set_flags(target_ulong start, target_ulong end, int flags) { target_ulong addr, len; - bool reset; + bool reset, inval_tb = false; /* This function should never be called with addresses outside the guest address space. If this assert fires, it probably indicates @@ -1388,11 +1388,15 @@ void page_set_flags(target_ulong start, target_ulong end, int flags) && (reset || !(flags & PAGE_EXEC) || (flags & ~p->flags & PAGE_WRITE))) { - tb_invalidate_phys_page(addr); + inval_tb = true; } /* Using mprotect on a page does not change sticky bits. */ p->flags = (reset ? 0 : p->flags & PAGE_STICKY) | flags; } + + if (inval_tb) { + tb_invalidate_phys_range(start, end); + } } void page_reset_target_data(target_ulong start, target_ulong end) From 0fe6108432ebbabbe12e53fba462770acb858a87 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 4 Oct 2022 15:24:36 -0700 Subject: [PATCH 117/705] accel/tcg: Move TARGET_PAGE_DATA_SIZE impl to user-exec.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since "target data" is always user-only, move it out of translate-all.c to user-exec.c. Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- accel/tcg/translate-all.c | 50 --------------------------------------- accel/tcg/user-exec.c | 50 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 50 deletions(-) diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index eea24dea96..433fa247f4 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -1399,56 +1399,6 @@ void page_set_flags(target_ulong start, target_ulong end, int flags) } } -void page_reset_target_data(target_ulong start, target_ulong end) -{ -#ifdef TARGET_PAGE_DATA_SIZE - target_ulong addr, len; - - /* - * This function should never be called with addresses outside the - * guest address space. If this assert fires, it probably indicates - * a missing call to h2g_valid. - */ - assert(end - 1 <= GUEST_ADDR_MAX); - assert(start < end); - assert_memory_lock(); - - start = start & TARGET_PAGE_MASK; - end = TARGET_PAGE_ALIGN(end); - - for (addr = start, len = end - start; - len != 0; - len -= TARGET_PAGE_SIZE, addr += TARGET_PAGE_SIZE) { - PageDesc *p = page_find_alloc(addr >> TARGET_PAGE_BITS, 1); - - g_free(p->target_data); - p->target_data = NULL; - } -#endif -} - -#ifdef TARGET_PAGE_DATA_SIZE -void *page_get_target_data(target_ulong address) -{ - PageDesc *p = page_find(address >> TARGET_PAGE_BITS); - return p ? p->target_data : NULL; -} - -void *page_alloc_target_data(target_ulong address) -{ - PageDesc *p = page_find(address >> TARGET_PAGE_BITS); - void *ret = NULL; - - if (p->flags & PAGE_VALID) { - ret = p->target_data; - if (!ret) { - p->target_data = ret = g_malloc0(TARGET_PAGE_DATA_SIZE); - } - } - return ret; -} -#endif /* TARGET_PAGE_DATA_SIZE */ - int page_check_range(target_ulong start, target_ulong len, int flags) { PageDesc *p; diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c index 521aa8b61e..927b91900f 100644 --- a/accel/tcg/user-exec.c +++ b/accel/tcg/user-exec.c @@ -210,6 +210,56 @@ tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, target_ulong addr, return addr; } +void page_reset_target_data(target_ulong start, target_ulong end) +{ +#ifdef TARGET_PAGE_DATA_SIZE + target_ulong addr, len; + + /* + * This function should never be called with addresses outside the + * guest address space. If this assert fires, it probably indicates + * a missing call to h2g_valid. + */ + assert(end - 1 <= GUEST_ADDR_MAX); + assert(start < end); + assert_memory_lock(); + + start = start & TARGET_PAGE_MASK; + end = TARGET_PAGE_ALIGN(end); + + for (addr = start, len = end - start; + len != 0; + len -= TARGET_PAGE_SIZE, addr += TARGET_PAGE_SIZE) { + PageDesc *p = page_find_alloc(addr >> TARGET_PAGE_BITS, 1); + + g_free(p->target_data); + p->target_data = NULL; + } +#endif +} + +#ifdef TARGET_PAGE_DATA_SIZE +void *page_get_target_data(target_ulong address) +{ + PageDesc *p = page_find(address >> TARGET_PAGE_BITS); + return p ? p->target_data : NULL; +} + +void *page_alloc_target_data(target_ulong address) +{ + PageDesc *p = page_find(address >> TARGET_PAGE_BITS); + void *ret = NULL; + + if (p->flags & PAGE_VALID) { + ret = p->target_data; + if (!ret) { + p->target_data = ret = g_malloc0(TARGET_PAGE_DATA_SIZE); + } + } + return ret; +} +#endif + /* The softmmu versions of these helpers are in cputlb.c. */ /* From 8269c01417a3e0bdb444b1bdac1d9b6c8bc9e667 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 4 Oct 2022 15:40:22 -0700 Subject: [PATCH 118/705] accel/tcg: Simplify page_get/alloc_target_data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the only user, Arm MTE, always requires allocation, merge the get and alloc functions to always produce a non-null result. Also assume that the user has already checked page validity. Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- accel/tcg/user-exec.c | 16 ++++------------ include/exec/cpu-all.h | 21 ++++++--------------- target/arm/mte_helper.c | 4 ---- 3 files changed, 10 insertions(+), 31 deletions(-) diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c index 927b91900f..fb7d6ee9e9 100644 --- a/accel/tcg/user-exec.c +++ b/accel/tcg/user-exec.c @@ -242,19 +242,11 @@ void page_reset_target_data(target_ulong start, target_ulong end) void *page_get_target_data(target_ulong address) { PageDesc *p = page_find(address >> TARGET_PAGE_BITS); - return p ? p->target_data : NULL; -} + void *ret = p->target_data; -void *page_alloc_target_data(target_ulong address) -{ - PageDesc *p = page_find(address >> TARGET_PAGE_BITS); - void *ret = NULL; - - if (p->flags & PAGE_VALID) { - ret = p->target_data; - if (!ret) { - p->target_data = ret = g_malloc0(TARGET_PAGE_DATA_SIZE); - } + if (!ret) { + ret = g_malloc0(TARGET_PAGE_DATA_SIZE); + p->target_data = ret; } return ret; } diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h index 854adc4ac2..2eb1176538 100644 --- a/include/exec/cpu-all.h +++ b/include/exec/cpu-all.h @@ -281,27 +281,18 @@ void page_reset_target_data(target_ulong start, target_ulong end); int page_check_range(target_ulong start, target_ulong len, int flags); /** - * page_alloc_target_data(address) + * page_get_target_data(address) * @address: guest virtual address * - * Allocate TARGET_PAGE_DATA_SIZE bytes of out-of-band data to associate - * with the guest page at @address. If the page is not mapped, NULL will - * be returned. If there is existing data associated with @address, - * no new memory will be allocated. + * Return TARGET_PAGE_DATA_SIZE bytes of out-of-band data to associate + * with the guest page at @address, allocating it if necessary. The + * caller should already have verified that the address is valid. * * The memory will be freed when the guest page is deallocated, * e.g. with the munmap system call. */ -void *page_alloc_target_data(target_ulong address); - -/** - * page_get_target_data(address) - * @address: guest virtual address - * - * Return any out-of-bound memory assocated with the guest page - * at @address, as per page_alloc_target_data. - */ -void *page_get_target_data(target_ulong address); +void *page_get_target_data(target_ulong address) + __attribute__((returns_nonnull)); #endif CPUArchState *cpu_copy(CPUArchState *env); diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c index a9c5fc2cb2..86b3754838 100644 --- a/target/arm/mte_helper.c +++ b/target/arm/mte_helper.c @@ -95,10 +95,6 @@ static uint8_t *allocation_tag_mem(CPUARMState *env, int ptr_mmu_idx, } tags = page_get_target_data(clean_ptr); - if (tags == NULL) { - tags = page_alloc_target_data(clean_ptr); - assert(tags != NULL); - } index = extract32(ptr, LOG2_TAG_GRANULE + 1, TARGET_PAGE_BITS - LOG2_TAG_GRANULE - 1); From d29256896f563683419ae4af04d94d7d0f07c225 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 19:43:40 +1000 Subject: [PATCH 119/705] accel/tcg: Add restore_state_to_opc to TCGCPUOps Add a tcg_ops hook to replace the restore_state_to_opc function call. Because these generic hooks cannot depend on target-specific types, temporarily, copy the current target_ulong data[] into uint64_t d64[]. Reviewed-by: Claudio Fontana Signed-off-by: Richard Henderson --- accel/tcg/translate-all.c | 24 ++++++++++++++++++++++-- include/exec/exec-all.h | 2 +- include/hw/core/tcg-cpu-ops.h | 11 +++++++++++ 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 433fa247f4..4d8783efc7 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -256,7 +256,6 @@ int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, { target_ulong data[TARGET_INSN_START_WORDS]; uintptr_t host_pc = (uintptr_t)tb->tc.ptr; - CPUArchState *env = cpu->env_ptr; const uint8_t *p = tb->tc.ptr + tb->tc.size; int i, j, num_insns = tb->icount; #ifdef CONFIG_PROFILER @@ -295,7 +294,20 @@ int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, and shift if to the number of actually executed instructions */ cpu_neg(cpu)->icount_decr.u16.low += num_insns - i; } - restore_state_to_opc(env, tb, data); + + { + const struct TCGCPUOps *ops = cpu->cc->tcg_ops; + __typeof(ops->restore_state_to_opc) restore = ops->restore_state_to_opc; + if (restore) { + uint64_t d64[TARGET_INSN_START_WORDS]; + for (i = 0; i < TARGET_INSN_START_WORDS; ++i) { + d64[i] = data[i]; + } + restore(cpu, tb, d64); + } else { + restore_state_to_opc(cpu->env_ptr, tb, data); + } + } #ifdef CONFIG_PROFILER qatomic_set(&prof->restore_time, @@ -307,6 +319,14 @@ int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit) { + /* + * The pc update associated with restore without exit will + * break the relative pc adjustments performed by TARGET_TB_PCREL. + */ + if (TARGET_TB_PCREL) { + assert(will_exit); + } + /* * The host_pc has to be in the rx region of the code buffer. * If it is not we will not be able to resolve it here. diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 5ae484e34d..3b5e84240b 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -40,7 +40,7 @@ typedef ram_addr_t tb_page_addr_t; #endif void restore_state_to_opc(CPUArchState *env, TranslationBlock *tb, - target_ulong *data); + target_ulong *data) __attribute__((weak)); /** * cpu_restore_state: diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h index 78c6c6635d..20e3c0ffbb 100644 --- a/include/hw/core/tcg-cpu-ops.h +++ b/include/hw/core/tcg-cpu-ops.h @@ -31,6 +31,17 @@ struct TCGCPUOps { * function to restore all the state, and register it here. */ void (*synchronize_from_tb)(CPUState *cpu, const TranslationBlock *tb); + /** + * @restore_state_to_opc: Synchronize state from INDEX_op_start_insn + * + * This is called when we unwind state in the middle of a TB, + * usually before raising an exception. Set all part of the CPU + * state which are tracked insn-by-insn in the target-specific + * arguments to start_insn, passed as @data. + */ + void (*restore_state_to_opc)(CPUState *cpu, const TranslationBlock *tb, + const uint64_t *data); + /** @cpu_exec_enter: Callback for cpu_exec preparation */ void (*cpu_exec_enter)(CPUState *cpu); /** @cpu_exec_exit: Callback for cpu_exec cleanup */ From c0cd068f32bb056d02c3ab0c62ebd08bbda83b84 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 19:44:20 +1000 Subject: [PATCH 120/705] target/alpha: Convert to tcg_ops restore_state_to_opc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/alpha/cpu.c | 9 +++++++++ target/alpha/translate.c | 6 ------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c index 979a629d59..270ae787b1 100644 --- a/target/alpha/cpu.c +++ b/target/alpha/cpu.c @@ -40,6 +40,14 @@ static vaddr alpha_cpu_get_pc(CPUState *cs) return cpu->env.pc; } +static void alpha_restore_state_to_opc(CPUState *cs, + const TranslationBlock *tb, + const uint64_t *data) +{ + AlphaCPU *cpu = ALPHA_CPU(cs); + + cpu->env.pc = data[0]; +} static bool alpha_cpu_has_work(CPUState *cs) { @@ -226,6 +234,7 @@ static const struct SysemuCPUOps alpha_sysemu_ops = { static const struct TCGCPUOps alpha_tcg_ops = { .initialize = alpha_translate_init, + .restore_state_to_opc = alpha_restore_state_to_opc, #ifdef CONFIG_USER_ONLY .record_sigsegv = alpha_cpu_record_sigsegv, diff --git a/target/alpha/translate.c b/target/alpha/translate.c index 6766350f56..f9bcdeb717 100644 --- a/target/alpha/translate.c +++ b/target/alpha/translate.c @@ -3049,9 +3049,3 @@ void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns, DisasContext dc; translator_loop(cpu, tb, max_insns, pc, host_pc, &alpha_tr_ops, &dc.base); } - -void restore_state_to_opc(CPUAlphaState *env, TranslationBlock *tb, - target_ulong *data) -{ - env->pc = data[0]; -} From 56c6c98df85cb03b1e72ef92111c4f9dde542d74 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 19:59:18 +1000 Subject: [PATCH 121/705] target/arm: Convert to tcg_ops restore_state_to_opc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/arm/cpu.c | 26 ++++++++++++++++++++++++++ target/arm/translate.c | 22 ---------------------- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 0bc5e9b125..0a7bfbf999 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -90,6 +90,31 @@ void arm_cpu_synchronize_from_tb(CPUState *cs, } } } + +static void arm_restore_state_to_opc(CPUState *cs, + const TranslationBlock *tb, + const uint64_t *data) +{ + CPUARMState *env = cs->env_ptr; + + if (is_a64(env)) { + if (TARGET_TB_PCREL) { + env->pc = (env->pc & TARGET_PAGE_MASK) | data[0]; + } else { + env->pc = data[0]; + } + env->condexec_bits = 0; + env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT; + } else { + if (TARGET_TB_PCREL) { + env->regs[15] = (env->regs[15] & TARGET_PAGE_MASK) | data[0]; + } else { + env->regs[15] = data[0]; + } + env->condexec_bits = data[1]; + env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT; + } +} #endif /* CONFIG_TCG */ static bool arm_cpu_has_work(CPUState *cs) @@ -2152,6 +2177,7 @@ static const struct TCGCPUOps arm_tcg_ops = { .initialize = arm_translate_init, .synchronize_from_tb = arm_cpu_synchronize_from_tb, .debug_excp_handler = arm_debug_excp_handler, + .restore_state_to_opc = arm_restore_state_to_opc, #ifdef CONFIG_USER_ONLY .record_sigsegv = arm_cpu_record_sigsegv, diff --git a/target/arm/translate.c b/target/arm/translate.c index d1b868430e..74a903072f 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -9939,25 +9939,3 @@ void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns, translator_loop(cpu, tb, max_insns, pc, host_pc, ops, &dc.base); } - -void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, - target_ulong *data) -{ - if (is_a64(env)) { - if (TARGET_TB_PCREL) { - env->pc = (env->pc & TARGET_PAGE_MASK) | data[0]; - } else { - env->pc = data[0]; - } - env->condexec_bits = 0; - env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT; - } else { - if (TARGET_TB_PCREL) { - env->regs[15] = (env->regs[15] & TARGET_PAGE_MASK) | data[0]; - } else { - env->regs[15] = data[0]; - } - env->condexec_bits = data[1]; - env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT; - } -} From f06c1ad4c62b8c91608c36cd3c870524979a278e Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 20:05:02 +1000 Subject: [PATCH 122/705] target/avr: Convert to tcg_ops restore_state_to_opc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/avr/cpu.c | 11 +++++++++++ target/avr/translate.c | 6 ------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/target/avr/cpu.c b/target/avr/cpu.c index 0d2861179d..c7295b488d 100644 --- a/target/avr/cpu.c +++ b/target/avr/cpu.c @@ -57,6 +57,16 @@ static void avr_cpu_synchronize_from_tb(CPUState *cs, env->pc_w = tb_pc(tb) / 2; /* internally PC points to words */ } +static void avr_restore_state_to_opc(CPUState *cs, + const TranslationBlock *tb, + const uint64_t *data) +{ + AVRCPU *cpu = AVR_CPU(cs); + CPUAVRState *env = &cpu->env; + + env->pc_w = data[0]; +} + static void avr_cpu_reset(DeviceState *ds) { CPUState *cs = CPU(ds); @@ -202,6 +212,7 @@ static const struct SysemuCPUOps avr_sysemu_ops = { static const struct TCGCPUOps avr_tcg_ops = { .initialize = avr_cpu_tcg_init, .synchronize_from_tb = avr_cpu_synchronize_from_tb, + .restore_state_to_opc = avr_restore_state_to_opc, .cpu_exec_interrupt = avr_cpu_exec_interrupt, .tlb_fill = avr_cpu_tlb_fill, .do_interrupt = avr_cpu_do_interrupt, diff --git a/target/avr/translate.c b/target/avr/translate.c index e65b6008c0..2bed56f135 100644 --- a/target/avr/translate.c +++ b/target/avr/translate.c @@ -3055,9 +3055,3 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns, DisasContext dc = { }; translator_loop(cs, tb, max_insns, pc, host_pc, &avr_tr_ops, &dc.base); } - -void restore_state_to_opc(CPUAVRState *env, TranslationBlock *tb, - target_ulong *data) -{ - env->pc_w = data[0]; -} From 4060474284cd6c7012c50dda743c6c151b92be87 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 20:08:21 +1000 Subject: [PATCH 123/705] target/cris: Convert to tcg_ops restore_state_to_opc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/cris/cpu.c | 11 +++++++++++ target/cris/translate.c | 6 ------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/target/cris/cpu.c b/target/cris/cpu.c index 22f5c70f39..fb05dc6f9a 100644 --- a/target/cris/cpu.c +++ b/target/cris/cpu.c @@ -42,6 +42,15 @@ static vaddr cris_cpu_get_pc(CPUState *cs) return cpu->env.pc; } +static void cris_restore_state_to_opc(CPUState *cs, + const TranslationBlock *tb, + const uint64_t *data) +{ + CRISCPU *cpu = CRIS_CPU(cs); + + cpu->env.pc = data[0]; +} + static bool cris_cpu_has_work(CPUState *cs) { return cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI); @@ -212,6 +221,7 @@ static const struct SysemuCPUOps cris_sysemu_ops = { static const struct TCGCPUOps crisv10_tcg_ops = { .initialize = cris_initialize_crisv10_tcg, + .restore_state_to_opc = cris_restore_state_to_opc, #ifndef CONFIG_USER_ONLY .tlb_fill = cris_cpu_tlb_fill, @@ -222,6 +232,7 @@ static const struct TCGCPUOps crisv10_tcg_ops = { static const struct TCGCPUOps crisv32_tcg_ops = { .initialize = cris_initialize_tcg, + .restore_state_to_opc = cris_restore_state_to_opc, #ifndef CONFIG_USER_ONLY .tlb_fill = cris_cpu_tlb_fill, diff --git a/target/cris/translate.c b/target/cris/translate.c index 73385b0b3c..fbc3fd5865 100644 --- a/target/cris/translate.c +++ b/target/cris/translate.c @@ -3392,9 +3392,3 @@ void cris_initialize_tcg(void) pregnames_v32[i]); } } - -void restore_state_to_opc(CPUCRISState *env, TranslationBlock *tb, - target_ulong *data) -{ - env->pc = data[0]; -} From 9015781416012af1e44b4710a15a2bf1fe800bb5 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 20:10:03 +1000 Subject: [PATCH 124/705] target/hexagon: Convert to tcg_ops restore_state_to_opc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/hexagon/cpu.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c index fa6d722555..03221fbdc2 100644 --- a/target/hexagon/cpu.c +++ b/target/hexagon/cpu.c @@ -271,9 +271,13 @@ static bool hexagon_cpu_has_work(CPUState *cs) return true; } -void restore_state_to_opc(CPUHexagonState *env, TranslationBlock *tb, - target_ulong *data) +static void hexagon_restore_state_to_opc(CPUState *cs, + const TranslationBlock *tb, + const uint64_t *data) { + HexagonCPU *cpu = HEXAGON_CPU(cs); + CPUHexagonState *env = &cpu->env; + env->gpr[HEX_REG_PC] = data[0]; } @@ -327,6 +331,7 @@ static void hexagon_cpu_init(Object *obj) static const struct TCGCPUOps hexagon_tcg_ops = { .initialize = hexagon_translate_init, .synchronize_from_tb = hexagon_cpu_synchronize_from_tb, + .restore_state_to_opc = hexagon_restore_state_to_opc, }; static void hexagon_cpu_class_init(ObjectClass *c, void *data) From e9cc3aca111e286a444ac2d82ae92dceac7e6d7a Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 20:13:57 +1000 Subject: [PATCH 125/705] target/hppa: Convert to tcg_ops restore_state_to_opc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/hppa/cpu.c | 19 +++++++++++++++++++ target/hppa/translate.c | 13 ------------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c index e677ca09d4..55c190280e 100644 --- a/target/hppa/cpu.c +++ b/target/hppa/cpu.c @@ -68,6 +68,24 @@ static void hppa_cpu_synchronize_from_tb(CPUState *cs, cpu->env.psw_n = (tb->flags & PSW_N) != 0; } +static void hppa_restore_state_to_opc(CPUState *cs, + const TranslationBlock *tb, + const uint64_t *data) +{ + HPPACPU *cpu = HPPA_CPU(cs); + + cpu->env.iaoq_f = data[0]; + if (data[1] != (target_ureg)-1) { + cpu->env.iaoq_b = data[1]; + } + /* + * Since we were executing the instruction at IAOQ_F, and took some + * sort of action that provoked the cpu_restore_state, we can infer + * that the instruction was not nullified. + */ + cpu->env.psw_n = 0; +} + static bool hppa_cpu_has_work(CPUState *cs) { return cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI); @@ -153,6 +171,7 @@ static const struct SysemuCPUOps hppa_sysemu_ops = { static const struct TCGCPUOps hppa_tcg_ops = { .initialize = hppa_translate_init, .synchronize_from_tb = hppa_cpu_synchronize_from_tb, + .restore_state_to_opc = hppa_restore_state_to_opc, #ifndef CONFIG_USER_ONLY .tlb_fill = hppa_cpu_tlb_fill, diff --git a/target/hppa/translate.c b/target/hppa/translate.c index 8b861957e0..1af77473da 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -4346,16 +4346,3 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns, DisasContext ctx; translator_loop(cs, tb, max_insns, pc, host_pc, &hppa_tr_ops, &ctx.base); } - -void restore_state_to_opc(CPUHPPAState *env, TranslationBlock *tb, - target_ulong *data) -{ - env->iaoq_f = data[0]; - if (data[1] != (target_ureg)-1) { - env->iaoq_b = data[1]; - } - /* Since we were executing the instruction at IAOQ_F, and took some - sort of action that provoked the cpu_restore_state, we can infer - that the instruction was not nullified. */ - env->psw_n = 0; -} From 434382e640ba1b6fdd06f70e0fe70270bab9cce3 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 20:18:03 +1000 Subject: [PATCH 126/705] target/i386: Convert to tcg_ops restore_state_to_opc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/i386/tcg/tcg-cpu.c | 19 +++++++++++++++++++ target/i386/tcg/translate.c | 15 --------------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/target/i386/tcg/tcg-cpu.c b/target/i386/tcg/tcg-cpu.c index 828244abe2..79ac5908f7 100644 --- a/target/i386/tcg/tcg-cpu.c +++ b/target/i386/tcg/tcg-cpu.c @@ -56,6 +56,24 @@ static void x86_cpu_synchronize_from_tb(CPUState *cs, } } +static void x86_restore_state_to_opc(CPUState *cs, + const TranslationBlock *tb, + const uint64_t *data) +{ + X86CPU *cpu = X86_CPU(cs); + CPUX86State *env = &cpu->env; + int cc_op = data[1]; + + if (TARGET_TB_PCREL) { + env->eip = (env->eip & TARGET_PAGE_MASK) | data[0]; + } else { + env->eip = data[0] - tb->cs_base; + } + if (cc_op != CC_OP_DYNAMIC) { + env->cc_op = cc_op; + } +} + #ifndef CONFIG_USER_ONLY static bool x86_debug_check_breakpoint(CPUState *cs) { @@ -72,6 +90,7 @@ static bool x86_debug_check_breakpoint(CPUState *cs) static const struct TCGCPUOps x86_tcg_ops = { .initialize = tcg_x86_init, .synchronize_from_tb = x86_cpu_synchronize_from_tb, + .restore_state_to_opc = x86_restore_state_to_opc, .cpu_exec_enter = x86_cpu_exec_enter, .cpu_exec_exit = x86_cpu_exec_exit, #ifdef CONFIG_USER_ONLY diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c index 85be2e58c2..546c427c23 100644 --- a/target/i386/tcg/translate.c +++ b/target/i386/tcg/translate.c @@ -7023,18 +7023,3 @@ void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns, translator_loop(cpu, tb, max_insns, pc, host_pc, &i386_tr_ops, &dc.base); } - -void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb, - target_ulong *data) -{ - int cc_op = data[1]; - - if (TARGET_TB_PCREL) { - env->eip = (env->eip & TARGET_PAGE_MASK) | data[0]; - } else { - env->eip = data[0] - tb->cs_base; - } - if (cc_op != CC_OP_DYNAMIC) { - env->cc_op = cc_op; - } -} From ab27940f8e6a0e092c72b0602c5a8cc379f26d99 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 20:24:10 +1000 Subject: [PATCH 127/705] target/loongarch: Convert to tcg_ops restore_state_to_opc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/loongarch/cpu.c | 11 +++++++++++ target/loongarch/translate.c | 6 ------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 1722ed2a4d..49393d95d8 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -319,6 +319,16 @@ static void loongarch_cpu_synchronize_from_tb(CPUState *cs, env->pc = tb_pc(tb); } + +static void loongarch_restore_state_to_opc(CPUState *cs, + const TranslationBlock *tb, + const uint64_t *data) +{ + LoongArchCPU *cpu = LOONGARCH_CPU(cs); + CPULoongArchState *env = &cpu->env; + + env->pc = data[0]; +} #endif /* CONFIG_TCG */ static bool loongarch_cpu_has_work(CPUState *cs) @@ -651,6 +661,7 @@ void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int flags) static struct TCGCPUOps loongarch_tcg_ops = { .initialize = loongarch_translate_init, .synchronize_from_tb = loongarch_cpu_synchronize_from_tb, + .restore_state_to_opc = loongarch_restore_state_to_opc, #ifndef CONFIG_USER_ONLY .tlb_fill = loongarch_cpu_tlb_fill, diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c index 95b37ea180..6091772349 100644 --- a/target/loongarch/translate.c +++ b/target/loongarch/translate.c @@ -272,9 +272,3 @@ void loongarch_translate_init(void) cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPULoongArchState, llval), "llval"); } - -void restore_state_to_opc(CPULoongArchState *env, TranslationBlock *tb, - target_ulong *data) -{ - env->pc = data[0]; -} From 584fd3422f83350f93bd332bd6b10effaf150cf9 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 20:26:33 +1000 Subject: [PATCH 128/705] target/m68k: Convert to tcg_ops restore_state_to_opc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/m68k/cpu.c | 14 ++++++++++++++ target/m68k/translate.c | 10 ---------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c index 1e902e1ef0..b67ddea2ae 100644 --- a/target/m68k/cpu.c +++ b/target/m68k/cpu.c @@ -38,6 +38,19 @@ static vaddr m68k_cpu_get_pc(CPUState *cs) return cpu->env.pc; } +static void m68k_restore_state_to_opc(CPUState *cs, + const TranslationBlock *tb, + const uint64_t *data) +{ + M68kCPU *cpu = M68K_CPU(cs); + int cc_op = data[1]; + + cpu->env.pc = data[0]; + if (cc_op != CC_OP_DYNAMIC) { + cpu->env.cc_op = cc_op; + } +} + static bool m68k_cpu_has_work(CPUState *cs) { return cs->interrupt_request & CPU_INTERRUPT_HARD; @@ -524,6 +537,7 @@ static const struct SysemuCPUOps m68k_sysemu_ops = { static const struct TCGCPUOps m68k_tcg_ops = { .initialize = m68k_tcg_init, + .restore_state_to_opc = m68k_restore_state_to_opc, #ifndef CONFIG_USER_ONLY .tlb_fill = m68k_cpu_tlb_fill, diff --git a/target/m68k/translate.c b/target/m68k/translate.c index 9df17aa4b2..5cbde4be34 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c @@ -6479,13 +6479,3 @@ void m68k_cpu_dump_state(CPUState *cs, FILE *f, int flags) env->mmu.mmusr, env->mmu.ar); #endif } - -void restore_state_to_opc(CPUM68KState *env, TranslationBlock *tb, - target_ulong *data) -{ - int cc_op = data[1]; - env->pc = data[0]; - if (cc_op != CC_OP_DYNAMIC) { - env->cc_op = cc_op; - } -} From 52b8d9a630c2e8f54b23857264365202aa760967 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 20:29:48 +1000 Subject: [PATCH 129/705] target/microblaze: Convert to tcg_ops restore_state_to_opc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/microblaze/cpu.c | 11 +++++++++++ target/microblaze/translate.c | 7 ------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c index c10b8ac029..89e493f3ff 100644 --- a/target/microblaze/cpu.c +++ b/target/microblaze/cpu.c @@ -100,6 +100,16 @@ static void mb_cpu_synchronize_from_tb(CPUState *cs, cpu->env.iflags = tb->flags & IFLAGS_TB_MASK; } +static void mb_restore_state_to_opc(CPUState *cs, + const TranslationBlock *tb, + const uint64_t *data) +{ + MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs); + + cpu->env.pc = data[0]; + cpu->env.iflags = data[1]; +} + static bool mb_cpu_has_work(CPUState *cs) { return cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI); @@ -373,6 +383,7 @@ static const struct SysemuCPUOps mb_sysemu_ops = { static const struct TCGCPUOps mb_tcg_ops = { .initialize = mb_tcg_init, .synchronize_from_tb = mb_cpu_synchronize_from_tb, + .restore_state_to_opc = mb_restore_state_to_opc, #ifndef CONFIG_USER_ONLY .tlb_fill = mb_cpu_tlb_fill, diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c index c5546f93aa..974f21eb31 100644 --- a/target/microblaze/translate.c +++ b/target/microblaze/translate.c @@ -1946,10 +1946,3 @@ void mb_tcg_init(void) cpu_res_addr = tcg_global_mem_new(cpu_env, offsetof(CPUMBState, res_addr), "res_addr"); } - -void restore_state_to_opc(CPUMBState *env, TranslationBlock *tb, - target_ulong *data) -{ - env->pc = data[0]; - env->iflags = data[1]; -} From 3766855c9b729411ac898fe874cecf6f44a7eecf Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 20:35:06 +1000 Subject: [PATCH 130/705] target/mips: Convert to tcg_ops restore_state_to_opc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/mips/cpu.c | 1 + target/mips/tcg/tcg-internal.h | 3 +++ target/mips/tcg/translate.c | 8 ++++++-- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/target/mips/cpu.c b/target/mips/cpu.c index da58eb8892..e997c1b9cb 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c @@ -538,6 +538,7 @@ static const struct SysemuCPUOps mips_sysemu_ops = { static const struct TCGCPUOps mips_tcg_ops = { .initialize = mips_tcg_init, .synchronize_from_tb = mips_cpu_synchronize_from_tb, + .restore_state_to_opc = mips_restore_state_to_opc, #if !defined(CONFIG_USER_ONLY) .tlb_fill = mips_cpu_tlb_fill, diff --git a/target/mips/tcg/tcg-internal.h b/target/mips/tcg/tcg-internal.h index 1d27fa2ff9..aef032c48d 100644 --- a/target/mips/tcg/tcg-internal.h +++ b/target/mips/tcg/tcg-internal.h @@ -21,6 +21,9 @@ void mips_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb); G_NORETURN void mips_cpu_do_unaligned_access(CPUState *cpu, vaddr addr, MMUAccessType access_type, int mmu_idx, uintptr_t retaddr); +void mips_restore_state_to_opc(CPUState *cs, + const TranslationBlock *tb, + const uint64_t *data); const char *mips_exception_name(int32_t exception); diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c index c3f92ea652..2f2d707a12 100644 --- a/target/mips/tcg/translate.c +++ b/target/mips/tcg/translate.c @@ -16229,9 +16229,13 @@ void mips_tcg_init(void) } } -void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, - target_ulong *data) +void mips_restore_state_to_opc(CPUState *cs, + const TranslationBlock *tb, + const uint64_t *data) { + MIPSCPU *cpu = MIPS_CPU(cs); + CPUMIPSState *env = &cpu->env; + env->active_tc.PC = data[0]; env->hflags &= ~MIPS_HFLAG_BMASK; env->hflags |= data[1]; From fbd5bd4ebcc8235475263a88e190444c264206b4 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 20:36:57 +1000 Subject: [PATCH 131/705] target/nios2: Convert to tcg_ops restore_state_to_opc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/nios2/cpu.c | 11 +++++++++++ target/nios2/translate.c | 6 ------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/target/nios2/cpu.c b/target/nios2/cpu.c index 2b28429c08..9a5351bc81 100644 --- a/target/nios2/cpu.c +++ b/target/nios2/cpu.c @@ -42,6 +42,16 @@ static vaddr nios2_cpu_get_pc(CPUState *cs) return env->pc; } +static void nios2_restore_state_to_opc(CPUState *cs, + const TranslationBlock *tb, + const uint64_t *data) +{ + Nios2CPU *cpu = NIOS2_CPU(cs); + CPUNios2State *env = &cpu->env; + + env->pc = data[0]; +} + static bool nios2_cpu_has_work(CPUState *cs) { return cs->interrupt_request & CPU_INTERRUPT_HARD; @@ -346,6 +356,7 @@ static const struct SysemuCPUOps nios2_sysemu_ops = { static const struct TCGCPUOps nios2_tcg_ops = { .initialize = nios2_tcg_init, + .restore_state_to_opc = nios2_restore_state_to_opc, #ifndef CONFIG_USER_ONLY .tlb_fill = nios2_cpu_tlb_fill, diff --git a/target/nios2/translate.c b/target/nios2/translate.c index 8dc0a32c6c..4db8b47744 100644 --- a/target/nios2/translate.c +++ b/target/nios2/translate.c @@ -1110,9 +1110,3 @@ void nios2_tcg_init(void) cpu_pc = tcg_global_mem_new(cpu_env, offsetof(CPUNios2State, pc), "pc"); } - -void restore_state_to_opc(CPUNios2State *env, TranslationBlock *tb, - target_ulong *data) -{ - env->pc = data[0]; -} From 3eb2c184bf900e17c1f8f0a09fba26e7c954cca0 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 20:40:30 +1000 Subject: [PATCH 132/705] target/openrisc: Convert to tcg_ops restore_state_to_opc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/openrisc/cpu.c | 13 +++++++++++++ target/openrisc/translate.c | 10 ---------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c index f6fd437785..de0176cd20 100644 --- a/target/openrisc/cpu.c +++ b/target/openrisc/cpu.c @@ -46,6 +46,18 @@ static void openrisc_cpu_synchronize_from_tb(CPUState *cs, cpu->env.pc = tb_pc(tb); } +static void openrisc_restore_state_to_opc(CPUState *cs, + const TranslationBlock *tb, + const uint64_t *data) +{ + OpenRISCCPU *cpu = OPENRISC_CPU(cs); + + cpu->env.pc = data[0]; + cpu->env.dflag = data[1] & 1; + if (data[1] & 2) { + cpu->env.ppc = cpu->env.pc - 4; + } +} static bool openrisc_cpu_has_work(CPUState *cs) { @@ -203,6 +215,7 @@ static const struct SysemuCPUOps openrisc_sysemu_ops = { static const struct TCGCPUOps openrisc_tcg_ops = { .initialize = openrisc_translate_init, .synchronize_from_tb = openrisc_cpu_synchronize_from_tb, + .restore_state_to_opc = openrisc_restore_state_to_opc, #ifndef CONFIG_USER_ONLY .tlb_fill = openrisc_cpu_tlb_fill, diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c index 8154f9d744..2f3d7c5fd1 100644 --- a/target/openrisc/translate.c +++ b/target/openrisc/translate.c @@ -1726,13 +1726,3 @@ void openrisc_cpu_dump_state(CPUState *cs, FILE *f, int flags) (i % 4) == 3 ? '\n' : ' '); } } - -void restore_state_to_opc(CPUOpenRISCState *env, TranslationBlock *tb, - target_ulong *data) -{ - env->pc = data[0]; - env->dflag = data[1] & 1; - if (data[1] & 2) { - env->ppc = env->pc - 4; - } -} From 61bd1d29421ad0304fa7043a2e4968b652c4223f Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 20:44:45 +1000 Subject: [PATCH 133/705] target/ppc: Convert to tcg_ops restore_state_to_opc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/ppc/cpu_init.c | 10 ++++++++++ target/ppc/translate.c | 6 ------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index 763a8431be..335351c226 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -7221,6 +7221,15 @@ static vaddr ppc_cpu_get_pc(CPUState *cs) return cpu->env.nip; } +static void ppc_restore_state_to_opc(CPUState *cs, + const TranslationBlock *tb, + const uint64_t *data) +{ + PowerPCCPU *cpu = POWERPC_CPU(cs); + + cpu->env.nip = data[0]; +} + static bool ppc_cpu_has_work(CPUState *cs) { PowerPCCPU *cpu = POWERPC_CPU(cs); @@ -7446,6 +7455,7 @@ static const struct SysemuCPUOps ppc_sysemu_ops = { static const struct TCGCPUOps ppc_tcg_ops = { .initialize = ppc_translate_init, + .restore_state_to_opc = ppc_restore_state_to_opc, #ifdef CONFIG_USER_ONLY .record_sigsegv = ppc_cpu_record_sigsegv, diff --git a/target/ppc/translate.c b/target/ppc/translate.c index e810842925..7228857e23 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -7739,9 +7739,3 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns, translator_loop(cs, tb, max_insns, pc, host_pc, &ppc_tr_ops, &ctx.base); } - -void restore_state_to_opc(CPUPPCState *env, TranslationBlock *tb, - target_ulong *data) -{ - env->nip = data[0]; -} From ad1e84f5046c3dded43e0b056095938ce127a758 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 20:49:27 +1000 Subject: [PATCH 134/705] target/riscv: Convert to tcg_ops restore_state_to_opc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/riscv/cpu.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index e6d9c706bb..d14e95c9dc 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -503,10 +503,14 @@ static bool riscv_cpu_has_work(CPUState *cs) #endif } -void restore_state_to_opc(CPURISCVState *env, TranslationBlock *tb, - target_ulong *data) +static void riscv_restore_state_to_opc(CPUState *cs, + const TranslationBlock *tb, + const uint64_t *data) { + RISCVCPU *cpu = RISCV_CPU(cs); + CPURISCVState *env = &cpu->env; RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL); + if (xl == MXL_RV32) { env->pc = (int32_t)data[0]; } else { @@ -1138,6 +1142,7 @@ static const struct SysemuCPUOps riscv_sysemu_ops = { static const struct TCGCPUOps riscv_tcg_ops = { .initialize = riscv_translate_init, .synchronize_from_tb = riscv_cpu_synchronize_from_tb, + .restore_state_to_opc = riscv_restore_state_to_opc, #ifndef CONFIG_USER_ONLY .tlb_fill = riscv_cpu_tlb_fill, From 5439d7a68ce3449d4091e0b4c084579b9467a683 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 20:52:08 +1000 Subject: [PATCH 135/705] target/rx: Convert to tcg_ops restore_state_to_opc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/rx/cpu.c | 10 ++++++++++ target/rx/translate.c | 6 ------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/target/rx/cpu.c b/target/rx/cpu.c index 2f28099723..9003c6e9fe 100644 --- a/target/rx/cpu.c +++ b/target/rx/cpu.c @@ -47,6 +47,15 @@ static void rx_cpu_synchronize_from_tb(CPUState *cs, cpu->env.pc = tb_pc(tb); } +static void rx_restore_state_to_opc(CPUState *cs, + const TranslationBlock *tb, + const uint64_t *data) +{ + RXCPU *cpu = RX_CPU(cs); + + cpu->env.pc = data[0]; +} + static bool rx_cpu_has_work(CPUState *cs) { return cs->interrupt_request & @@ -192,6 +201,7 @@ static const struct SysemuCPUOps rx_sysemu_ops = { static const struct TCGCPUOps rx_tcg_ops = { .initialize = rx_translate_init, .synchronize_from_tb = rx_cpu_synchronize_from_tb, + .restore_state_to_opc = rx_restore_state_to_opc, .tlb_fill = rx_cpu_tlb_fill, #ifndef CONFIG_USER_ONLY diff --git a/target/rx/translate.c b/target/rx/translate.c index ea5653bc95..87a3f54adb 100644 --- a/target/rx/translate.c +++ b/target/rx/translate.c @@ -2371,12 +2371,6 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns, translator_loop(cs, tb, max_insns, pc, host_pc, &rx_tr_ops, &dc.base); } -void restore_state_to_opc(CPURXState *env, TranslationBlock *tb, - target_ulong *data) -{ - env->pc = data[0]; -} - #define ALLOC_REGISTER(sym, name) \ cpu_##sym = tcg_global_mem_new_i32(cpu_env, \ offsetof(CPURXState, sym), name) From 3479783b3960a76c04aa76fce7869f94e864e6b0 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 20:56:41 +1000 Subject: [PATCH 136/705] target/s390x: Convert to tcg_ops restore_state_to_opc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/s390x/cpu.c | 1 + target/s390x/s390x-internal.h | 4 +++- target/s390x/tcg/translate.c | 7 +++++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c index df00040e95..96562c516d 100644 --- a/target/s390x/cpu.c +++ b/target/s390x/cpu.c @@ -272,6 +272,7 @@ static void s390_cpu_reset_full(DeviceState *dev) static const struct TCGCPUOps s390_tcg_ops = { .initialize = s390x_translate_init, + .restore_state_to_opc = s390x_restore_state_to_opc, #ifdef CONFIG_USER_ONLY .record_sigsegv = s390_cpu_record_sigsegv, diff --git a/target/s390x/s390x-internal.h b/target/s390x/s390x-internal.h index b5ae0ae364..5d4361d35b 100644 --- a/target/s390x/s390x-internal.h +++ b/target/s390x/s390x-internal.h @@ -398,7 +398,9 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, /* translate.c */ void s390x_translate_init(void); - +void s390x_restore_state_to_opc(CPUState *cs, + const TranslationBlock *tb, + const uint64_t *data); /* sigp.c */ int handle_sigp(CPUS390XState *env, uint8_t order, uint64_t r1, uint64_t r3); diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c index 1d2dddab1c..5798928473 100644 --- a/target/s390x/tcg/translate.c +++ b/target/s390x/tcg/translate.c @@ -6691,9 +6691,12 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns, translator_loop(cs, tb, max_insns, pc, host_pc, &s390x_tr_ops, &dc.base); } -void restore_state_to_opc(CPUS390XState *env, TranslationBlock *tb, - target_ulong *data) +void s390x_restore_state_to_opc(CPUState *cs, + const TranslationBlock *tb, + const uint64_t *data) { + S390CPU *cpu = S390_CPU(cs); + CPUS390XState *env = &cpu->env; int cc_op = data[1]; env->psw.addr = data[0]; From e7977326cd6648183ececce211c6330d4b9465df Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 20:58:40 +1000 Subject: [PATCH 137/705] target/sh4: Convert to tcg_ops restore_state_to_opc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/sh4/cpu.c | 16 ++++++++++++++++ target/sh4/translate.c | 10 ---------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c index 56c50530da..453268392b 100644 --- a/target/sh4/cpu.c +++ b/target/sh4/cpu.c @@ -50,6 +50,21 @@ static void superh_cpu_synchronize_from_tb(CPUState *cs, cpu->env.flags = tb->flags; } +static void superh_restore_state_to_opc(CPUState *cs, + const TranslationBlock *tb, + const uint64_t *data) +{ + SuperHCPU *cpu = SUPERH_CPU(cs); + + cpu->env.pc = data[0]; + cpu->env.flags = data[1]; + /* + * Theoretically delayed_pc should also be restored. In practice the + * branch instruction is re-executed after exception, so the delayed + * branch target will be recomputed. + */ +} + #ifndef CONFIG_USER_ONLY static bool superh_io_recompile_replay_branch(CPUState *cs, const TranslationBlock *tb) @@ -243,6 +258,7 @@ static const struct SysemuCPUOps sh4_sysemu_ops = { static const struct TCGCPUOps superh_tcg_ops = { .initialize = sh4_translate_init, .synchronize_from_tb = superh_cpu_synchronize_from_tb, + .restore_state_to_opc = superh_restore_state_to_opc, #ifndef CONFIG_USER_ONLY .tlb_fill = superh_cpu_tlb_fill, diff --git a/target/sh4/translate.c b/target/sh4/translate.c index 26231b2a5a..7db3468b01 100644 --- a/target/sh4/translate.c +++ b/target/sh4/translate.c @@ -2381,13 +2381,3 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns, translator_loop(cs, tb, max_insns, pc, host_pc, &sh4_tr_ops, &ctx.base); } - -void restore_state_to_opc(CPUSH4State *env, TranslationBlock *tb, - target_ulong *data) -{ - env->pc = data[0]; - env->flags = data[1]; - /* Theoretically delayed_pc should also be restored. In practice the - branch instruction is re-executed after exception, so the delayed - branch target will be recomputed. */ -} From f36aaa53c66c613228c1a9f517cb357160049b25 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 21:03:29 +1000 Subject: [PATCH 138/705] target/sparc: Convert to tcg_ops restore_state_to_opc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/sparc/cpu.c | 1 + target/sparc/cpu.h | 3 +++ target/sparc/translate.c | 7 +++++-- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c index 1f9ef7afd8..4c3d08a875 100644 --- a/target/sparc/cpu.c +++ b/target/sparc/cpu.c @@ -872,6 +872,7 @@ static const struct SysemuCPUOps sparc_sysemu_ops = { static const struct TCGCPUOps sparc_tcg_ops = { .initialize = sparc_tcg_init, .synchronize_from_tb = sparc_cpu_synchronize_from_tb, + .restore_state_to_opc = sparc_restore_state_to_opc, #ifndef CONFIG_USER_ONLY .tlb_fill = sparc_cpu_tlb_fill, diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h index f80ea2e8cf..e478c5eb16 100644 --- a/target/sparc/cpu.h +++ b/target/sparc/cpu.h @@ -600,6 +600,9 @@ int sparc_cpu_memory_rw_debug(CPUState *cpu, vaddr addr, /* translate.c */ void sparc_tcg_init(void); +void sparc_restore_state_to_opc(CPUState *cs, + const TranslationBlock *tb, + const uint64_t *data); /* cpu-exec.c */ diff --git a/target/sparc/translate.c b/target/sparc/translate.c index 2cbbe2396a..34858eb95f 100644 --- a/target/sparc/translate.c +++ b/target/sparc/translate.c @@ -6011,9 +6011,12 @@ void sparc_tcg_init(void) } } -void restore_state_to_opc(CPUSPARCState *env, TranslationBlock *tb, - target_ulong *data) +void sparc_restore_state_to_opc(CPUState *cs, + const TranslationBlock *tb, + const uint64_t *data) { + SPARCCPU *cpu = SPARC_CPU(cs); + CPUSPARCState *env = &cpu->env; target_ulong pc = data[0]; target_ulong npc = data[1]; From b765e427b0050c497bd0393ef1f0cbd223bd90ba Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 21:06:03 +1000 Subject: [PATCH 139/705] target/tricore: Convert to tcg_ops restore_state_to_opc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/tricore/cpu.c | 11 +++++++++++ target/tricore/translate.c | 6 ------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/target/tricore/cpu.c b/target/tricore/cpu.c index ab7a1e3a6d..2c54a2825f 100644 --- a/target/tricore/cpu.c +++ b/target/tricore/cpu.c @@ -58,6 +58,16 @@ static void tricore_cpu_synchronize_from_tb(CPUState *cs, env->PC = tb_pc(tb); } +static void tricore_restore_state_to_opc(CPUState *cs, + const TranslationBlock *tb, + const uint64_t *data) +{ + TriCoreCPU *cpu = TRICORE_CPU(cs); + CPUTriCoreState *env = &cpu->env; + + env->PC = data[0]; +} + static void tricore_cpu_reset(DeviceState *dev) { CPUState *s = CPU(dev); @@ -161,6 +171,7 @@ static const struct SysemuCPUOps tricore_sysemu_ops = { static const struct TCGCPUOps tricore_tcg_ops = { .initialize = tricore_tcg_init, .synchronize_from_tb = tricore_cpu_synchronize_from_tb, + .restore_state_to_opc = tricore_restore_state_to_opc, .tlb_fill = tricore_cpu_tlb_fill, }; diff --git a/target/tricore/translate.c b/target/tricore/translate.c index a0558ead71..c5b7bfbf20 100644 --- a/target/tricore/translate.c +++ b/target/tricore/translate.c @@ -8886,12 +8886,6 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns, &tricore_tr_ops, &ctx.base); } -void -restore_state_to_opc(CPUTriCoreState *env, TranslationBlock *tb, - target_ulong *data) -{ - env->PC = data[0]; -} /* * * Initialization From 044dcfc5aab2f2679148c9eca41441dd6cf276a0 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 21:08:38 +1000 Subject: [PATCH 140/705] target/xtensa: Convert to tcg_ops restore_state_to_opc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/xtensa/cpu.c | 10 ++++++++++ target/xtensa/translate.c | 6 ------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c index cbbe0e84a2..09923301c4 100644 --- a/target/xtensa/cpu.c +++ b/target/xtensa/cpu.c @@ -51,6 +51,15 @@ static vaddr xtensa_cpu_get_pc(CPUState *cs) return cpu->env.pc; } +static void xtensa_restore_state_to_opc(CPUState *cs, + const TranslationBlock *tb, + const uint64_t *data) +{ + XtensaCPU *cpu = XTENSA_CPU(cs); + + cpu->env.pc = data[0]; +} + static bool xtensa_cpu_has_work(CPUState *cs) { #ifndef CONFIG_USER_ONLY @@ -215,6 +224,7 @@ static const struct SysemuCPUOps xtensa_sysemu_ops = { static const struct TCGCPUOps xtensa_tcg_ops = { .initialize = xtensa_translate_init, .debug_excp_handler = xtensa_breakpoint_handler, + .restore_state_to_opc = xtensa_restore_state_to_opc, #ifndef CONFIG_USER_ONLY .tlb_fill = xtensa_cpu_tlb_fill, diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c index bdd4690a5c..77bcd71030 100644 --- a/target/xtensa/translate.c +++ b/target/xtensa/translate.c @@ -1355,12 +1355,6 @@ void xtensa_cpu_dump_state(CPUState *cs, FILE *f, int flags) } } -void restore_state_to_opc(CPUXtensaState *env, TranslationBlock *tb, - target_ulong *data) -{ - env->pc = data[0]; -} - static void translate_abs(DisasContext *dc, const OpcodeArg arg[], const uint32_t par[]) { From 04f105758b0089f73ee47260671580cde35f96cc Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 21:17:39 +1000 Subject: [PATCH 141/705] accel/tcg: Remove restore_state_to_opc function All targets have been updated. Use the tcg_ops target hook exclusively, which allows the compat code to be removed. Reviewed-by: Claudio Fontana Signed-off-by: Richard Henderson --- accel/tcg/translate-all.c | 16 ++-------------- include/exec/exec-all.h | 3 --- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 4d8783efc7..f185356a36 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -254,7 +254,7 @@ static int encode_search(TranslationBlock *tb, uint8_t *block) int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, uintptr_t searched_pc, bool reset_icount) { - target_ulong data[TARGET_INSN_START_WORDS]; + uint64_t data[TARGET_INSN_START_WORDS]; uintptr_t host_pc = (uintptr_t)tb->tc.ptr; const uint8_t *p = tb->tc.ptr + tb->tc.size; int i, j, num_insns = tb->icount; @@ -295,19 +295,7 @@ int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, cpu_neg(cpu)->icount_decr.u16.low += num_insns - i; } - { - const struct TCGCPUOps *ops = cpu->cc->tcg_ops; - __typeof(ops->restore_state_to_opc) restore = ops->restore_state_to_opc; - if (restore) { - uint64_t d64[TARGET_INSN_START_WORDS]; - for (i = 0; i < TARGET_INSN_START_WORDS; ++i) { - d64[i] = data[i]; - } - restore(cpu, tb, d64); - } else { - restore_state_to_opc(cpu->env_ptr, tb, data); - } - } + cpu->cc->tcg_ops->restore_state_to_opc(cpu, tb, data); #ifdef CONFIG_PROFILER qatomic_set(&prof->restore_time, diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 3b5e84240b..e948992a80 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -39,9 +39,6 @@ typedef ram_addr_t tb_page_addr_t; #define TB_PAGE_ADDR_FMT RAM_ADDR_FMT #endif -void restore_state_to_opc(CPUArchState *env, TranslationBlock *tb, - target_ulong *data) __attribute__((weak)); - /** * cpu_restore_state: * @cpu: the vCPU state is to be restore to From ad3b2e693daac6ed92db7361236028851d37c77c Mon Sep 17 00:00:00 2001 From: Janosch Frank Date: Mon, 17 Oct 2022 08:38:18 +0000 Subject: [PATCH 142/705] s390x: Add protected dump cap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a protected dump capability for later feature checking. Signed-off-by: Janosch Frank Reviewed-by: Steffen Eiden Reviewed-by: Thomas Huth Reviewed-by: Janis Schoetterl-Glausch Message-Id: <20221017083822.43118-7-frankja@linux.ibm.com> [ Marc-André - Add missing stubs when !kvm ] Signed-off-by: Marc-André Lureau --- target/s390x/kvm/kvm.c | 7 +++++++ target/s390x/kvm/kvm_s390x.h | 1 + target/s390x/kvm/meson.build | 2 ++ target/s390x/kvm/stubs.c | 12 ++++++++++++ 4 files changed, 22 insertions(+) create mode 100644 target/s390x/kvm/stubs.c diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c index 508c24cfec..04cae0b999 100644 --- a/target/s390x/kvm/kvm.c +++ b/target/s390x/kvm/kvm.c @@ -158,6 +158,7 @@ static int cap_hpage_1m; static int cap_vcpu_resets; static int cap_protected; static int cap_zpci_op; +static int cap_protected_dump; static bool mem_op_storage_key_support; @@ -364,6 +365,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s) cap_vcpu_resets = kvm_check_extension(s, KVM_CAP_S390_VCPU_RESETS); cap_protected = kvm_check_extension(s, KVM_CAP_S390_PROTECTED); cap_zpci_op = kvm_check_extension(s, KVM_CAP_S390_ZPCI_OP); + cap_protected_dump = kvm_check_extension(s, KVM_CAP_S390_PROTECTED_DUMP); kvm_vm_enable_cap(s, KVM_CAP_S390_USER_SIGP, 0); kvm_vm_enable_cap(s, KVM_CAP_S390_VECTOR_REGISTERS, 0); @@ -2045,6 +2047,11 @@ int kvm_s390_assign_subch_ioeventfd(EventNotifier *notifier, uint32_t sch, return kvm_vm_ioctl(kvm_state, KVM_IOEVENTFD, &kick); } +int kvm_s390_get_protected_dump(void) +{ + return cap_protected_dump; +} + int kvm_s390_get_ri(void) { return cap_ri; diff --git a/target/s390x/kvm/kvm_s390x.h b/target/s390x/kvm/kvm_s390x.h index aaae8570de..f9785564d0 100644 --- a/target/s390x/kvm/kvm_s390x.h +++ b/target/s390x/kvm/kvm_s390x.h @@ -26,6 +26,7 @@ int kvm_s390_set_cpu_state(S390CPU *cpu, uint8_t cpu_state); void kvm_s390_vcpu_interrupt_pre_save(S390CPU *cpu); int kvm_s390_vcpu_interrupt_post_load(S390CPU *cpu); int kvm_s390_get_hpage_1m(void); +int kvm_s390_get_protected_dump(void); int kvm_s390_get_ri(void); int kvm_s390_get_zpci_op(void); int kvm_s390_get_clock(uint8_t *tod_high, uint64_t *tod_clock); diff --git a/target/s390x/kvm/meson.build b/target/s390x/kvm/meson.build index d1356356b1..aef52b6686 100644 --- a/target/s390x/kvm/meson.build +++ b/target/s390x/kvm/meson.build @@ -1,6 +1,8 @@ s390x_ss.add(when: 'CONFIG_KVM', if_true: files( 'kvm.c' +), if_false: files( + 'stubs.c' )) # Newer kernels on s390 check for an S390_PGSTE program header and diff --git a/target/s390x/kvm/stubs.c b/target/s390x/kvm/stubs.c new file mode 100644 index 0000000000..5fd63b9a7e --- /dev/null +++ b/target/s390x/kvm/stubs.c @@ -0,0 +1,12 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" + +#include "kvm_s390x.h" + +int kvm_s390_get_protected_dump(void) +{ + return false; +} From 03d83ecfae46bf5e0074cb5808043b30df34064b Mon Sep 17 00:00:00 2001 From: Janosch Frank Date: Mon, 17 Oct 2022 08:38:19 +0000 Subject: [PATCH 143/705] s390x: Introduce PV query interface Introduce an interface over which we can get information about UV data. Signed-off-by: Janosch Frank Reviewed-by: Steffen Eiden Reviewed-by: Janis Schoetterl-Glausch Acked-by: Thomas Huth Message-Id: <20221017083822.43118-8-frankja@linux.ibm.com> --- hw/s390x/pv.c | 61 ++++++++++++++++++++++++++++++++++++++ hw/s390x/s390-virtio-ccw.c | 6 ++++ include/hw/s390x/pv.h | 10 +++++++ 3 files changed, 77 insertions(+) diff --git a/hw/s390x/pv.c b/hw/s390x/pv.c index 401b63d6cb..4c012f2eeb 100644 --- a/hw/s390x/pv.c +++ b/hw/s390x/pv.c @@ -20,6 +20,11 @@ #include "exec/confidential-guest-support.h" #include "hw/s390x/ipl.h" #include "hw/s390x/pv.h" +#include "target/s390x/kvm/kvm_s390x.h" + +static bool info_valid; +static struct kvm_s390_pv_info_vm info_vm; +static struct kvm_s390_pv_info_dump info_dump; static int __s390_pv_cmd(uint32_t cmd, const char *cmdname, void *data) { @@ -56,6 +61,42 @@ static int __s390_pv_cmd(uint32_t cmd, const char *cmdname, void *data) } \ } +int s390_pv_query_info(void) +{ + struct kvm_s390_pv_info info = { + .header.id = KVM_PV_INFO_VM, + .header.len_max = sizeof(info.header) + sizeof(info.vm), + }; + int rc; + + /* Info API's first user is dump so they are bundled */ + if (!kvm_s390_get_protected_dump()) { + return 0; + } + + rc = s390_pv_cmd(KVM_PV_INFO, &info); + if (rc) { + error_report("KVM PV INFO cmd %x failed: %s", + info.header.id, strerror(-rc)); + return rc; + } + memcpy(&info_vm, &info.vm, sizeof(info.vm)); + + info.header.id = KVM_PV_INFO_DUMP; + info.header.len_max = sizeof(info.header) + sizeof(info.dump); + rc = s390_pv_cmd(KVM_PV_INFO, &info); + if (rc) { + error_report("KVM PV INFO cmd %x failed: %s", + info.header.id, strerror(-rc)); + return rc; + } + + memcpy(&info_dump, &info.dump, sizeof(info.dump)); + info_valid = true; + + return rc; +} + int s390_pv_vm_enable(void) { return s390_pv_cmd(KVM_PV_ENABLE, NULL); @@ -114,6 +155,26 @@ void s390_pv_inject_reset_error(CPUState *cs) env->regs[r1 + 1] = DIAG_308_RC_INVAL_FOR_PV; } +uint64_t kvm_s390_pv_dmp_get_size_cpu(void) +{ + return info_dump.dump_cpu_buffer_len; +} + +uint64_t kvm_s390_pv_dmp_get_size_completion_data(void) +{ + return info_dump.dump_config_finalize_len; +} + +uint64_t kvm_s390_pv_dmp_get_size_mem_state(void) +{ + return info_dump.dump_config_mem_buffer_per_1m; +} + +bool kvm_s390_pv_info_basic_valid(void) +{ + return info_valid; +} + #define TYPE_S390_PV_GUEST "s390-pv-guest" OBJECT_DECLARE_SIMPLE_TYPE(S390PVGuest, S390_PV_GUEST) diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index 03855c7231..1cc20d8717 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -366,6 +366,12 @@ static int s390_machine_protect(S390CcwMachineState *ms) ms->pv = true; + /* Will return 0 if API is not available since it's not vital */ + rc = s390_pv_query_info(); + if (rc) { + goto out_err; + } + /* Set SE header and unpack */ rc = s390_ipl_prepare_pv_header(); if (rc) { diff --git a/include/hw/s390x/pv.h b/include/hw/s390x/pv.h index 1f1f545bfc..e5ea0eca16 100644 --- a/include/hw/s390x/pv.h +++ b/include/hw/s390x/pv.h @@ -38,6 +38,7 @@ static inline bool s390_is_pv(void) return ccw->pv; } +int s390_pv_query_info(void); int s390_pv_vm_enable(void); void s390_pv_vm_disable(void); int s390_pv_set_sec_parms(uint64_t origin, uint64_t length); @@ -46,8 +47,13 @@ void s390_pv_prep_reset(void); int s390_pv_verify(void); void s390_pv_unshare(void); void s390_pv_inject_reset_error(CPUState *cs); +uint64_t kvm_s390_pv_dmp_get_size_cpu(void); +uint64_t kvm_s390_pv_dmp_get_size_mem_state(void); +uint64_t kvm_s390_pv_dmp_get_size_completion_data(void); +bool kvm_s390_pv_info_basic_valid(void); #else /* CONFIG_KVM */ static inline bool s390_is_pv(void) { return false; } +static inline int s390_pv_query_info(void) { return 0; } static inline int s390_pv_vm_enable(void) { return 0; } static inline void s390_pv_vm_disable(void) {} static inline int s390_pv_set_sec_parms(uint64_t origin, uint64_t length) { return 0; } @@ -56,6 +62,10 @@ static inline void s390_pv_prep_reset(void) {} static inline int s390_pv_verify(void) { return 0; } static inline void s390_pv_unshare(void) {} static inline void s390_pv_inject_reset_error(CPUState *cs) {}; +static inline uint64_t kvm_s390_pv_dmp_get_size_cpu(void) { return 0; } +static inline uint64_t kvm_s390_pv_dmp_get_size_mem_state(void) { return 0; } +static inline uint64_t kvm_s390_pv_dmp_get_size_completion_data(void) { return 0; } +static inline bool kvm_s390_pv_info_basic_valid(void) { return false; } #endif /* CONFIG_KVM */ int s390_pv_kvm_init(ConfidentialGuestSupport *cgs, Error **errp); From 5433669c7a1884cc0394c360148965edf7519884 Mon Sep 17 00:00:00 2001 From: Janosch Frank Date: Mon, 17 Oct 2022 08:38:20 +0000 Subject: [PATCH 144/705] include/elf.h: add s390x note types Adding two s390x note types Signed-off-by: Janosch Frank Reviewed-by: Thomas Huth Message-Id: <20221017083822.43118-9-frankja@linux.ibm.com> --- include/elf.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/elf.h b/include/elf.h index 3d6b9062c0..8bf1e72720 100644 --- a/include/elf.h +++ b/include/elf.h @@ -1650,6 +1650,8 @@ typedef struct elf64_shdr { #define NT_TASKSTRUCT 4 #define NT_AUXV 6 #define NT_PRXFPREG 0x46e62b7f /* copied from gdb5.1/include/elf/common.h */ +#define NT_S390_PV_CPU_DATA 0x30e /* s390 protvirt cpu dump data */ +#define NT_S390_RI_CB 0x30d /* s390 runtime instrumentation */ #define NT_S390_GS_CB 0x30b /* s390 guarded storage registers */ #define NT_S390_VXRS_HIGH 0x30a /* s390 vector registers 16-31 */ #define NT_S390_VXRS_LOW 0x309 /* s390 vector registers 0-15 (lower half) */ From 753ca06f4706cd6e57750a606afb08c5c5299643 Mon Sep 17 00:00:00 2001 From: Janosch Frank Date: Mon, 17 Oct 2022 08:38:21 +0000 Subject: [PATCH 145/705] s390x: Add KVM PV dump interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Let's add a few bits of code which hide the new KVM PV dump API from us via new functions. Signed-off-by: Janosch Frank Reviewed-by: Janis Schoetterl-Glausch Reviewed-by: Steffen Eiden [ Marc-André: fix up for compilation issue ] Signed-off-by: Marc-André Lureau Message-Id: <20221017083822.43118-10-frankja@linux.ibm.com> --- hw/s390x/pv.c | 51 +++++++++++++++++++++++++++++++++++++++++++ include/hw/s390x/pv.h | 9 ++++++++ 2 files changed, 60 insertions(+) diff --git a/hw/s390x/pv.c b/hw/s390x/pv.c index 4c012f2eeb..728ba24547 100644 --- a/hw/s390x/pv.c +++ b/hw/s390x/pv.c @@ -175,6 +175,57 @@ bool kvm_s390_pv_info_basic_valid(void) return info_valid; } +static int s390_pv_dump_cmd(uint64_t subcmd, uint64_t uaddr, uint64_t gaddr, + uint64_t len) +{ + struct kvm_s390_pv_dmp dmp = { + .subcmd = subcmd, + .buff_addr = uaddr, + .buff_len = len, + .gaddr = gaddr, + }; + int ret; + + ret = s390_pv_cmd(KVM_PV_DUMP, (void *)&dmp); + if (ret) { + error_report("KVM DUMP command %ld failed", subcmd); + } + return ret; +} + +int kvm_s390_dump_cpu(S390CPU *cpu, void *buff) +{ + struct kvm_s390_pv_dmp dmp = { + .subcmd = KVM_PV_DUMP_CPU, + .buff_addr = (uint64_t)buff, + .gaddr = 0, + .buff_len = info_dump.dump_cpu_buffer_len, + }; + struct kvm_pv_cmd pv = { + .cmd = KVM_PV_DUMP, + .data = (uint64_t)&dmp, + }; + + return kvm_vcpu_ioctl(CPU(cpu), KVM_S390_PV_CPU_COMMAND, &pv); +} + +int kvm_s390_dump_init(void) +{ + return s390_pv_dump_cmd(KVM_PV_DUMP_INIT, 0, 0, 0); +} + +int kvm_s390_dump_mem_state(uint64_t gaddr, size_t len, void *dest) +{ + return s390_pv_dump_cmd(KVM_PV_DUMP_CONFIG_STOR_STATE, (uint64_t)dest, + gaddr, len); +} + +int kvm_s390_dump_completion_data(void *buff) +{ + return s390_pv_dump_cmd(KVM_PV_DUMP_COMPLETE, (uint64_t)buff, 0, + info_dump.dump_config_finalize_len); +} + #define TYPE_S390_PV_GUEST "s390-pv-guest" OBJECT_DECLARE_SIMPLE_TYPE(S390PVGuest, S390_PV_GUEST) diff --git a/include/hw/s390x/pv.h b/include/hw/s390x/pv.h index e5ea0eca16..9360aa1091 100644 --- a/include/hw/s390x/pv.h +++ b/include/hw/s390x/pv.h @@ -51,6 +51,10 @@ uint64_t kvm_s390_pv_dmp_get_size_cpu(void); uint64_t kvm_s390_pv_dmp_get_size_mem_state(void); uint64_t kvm_s390_pv_dmp_get_size_completion_data(void); bool kvm_s390_pv_info_basic_valid(void); +int kvm_s390_dump_init(void); +int kvm_s390_dump_cpu(S390CPU *cpu, void *buff); +int kvm_s390_dump_mem_state(uint64_t addr, size_t len, void *dest); +int kvm_s390_dump_completion_data(void *buff); #else /* CONFIG_KVM */ static inline bool s390_is_pv(void) { return false; } static inline int s390_pv_query_info(void) { return 0; } @@ -66,6 +70,11 @@ static inline uint64_t kvm_s390_pv_dmp_get_size_cpu(void) { return 0; } static inline uint64_t kvm_s390_pv_dmp_get_size_mem_state(void) { return 0; } static inline uint64_t kvm_s390_pv_dmp_get_size_completion_data(void) { return 0; } static inline bool kvm_s390_pv_info_basic_valid(void) { return false; } +static inline int kvm_s390_dump_init(void) { return 0; } +static inline int kvm_s390_dump_cpu(S390CPU *cpu, void *buff) { return 0; } +static inline int kvm_s390_dump_mem_state(uint64_t addr, size_t len, + void *dest) { return 0; } +static inline int kvm_s390_dump_completion_data(void *buff) { return 0; } #endif /* CONFIG_KVM */ int s390_pv_kvm_init(ConfidentialGuestSupport *cgs, Error **errp); From 113d8f4e95cf0450bea421263de6ec016c779ad0 Mon Sep 17 00:00:00 2001 From: Janosch Frank Date: Mon, 17 Oct 2022 08:38:22 +0000 Subject: [PATCH 146/705] s390x: pv: Add dump support Sometimes dumping a guest from the outside is the only way to get the data that is needed. This can be the case if a dumping mechanism like KDUMP hasn't been configured or data needs to be fetched at a specific point. Dumping a protected guest from the outside without help from fw/hw doesn't yield sufficient data to be useful. Hence we now introduce PV dump support. The PV dump support works by integrating the firmware into the dump process. New Ultravisor calls are used to initiate the dump process, dump cpu data, dump memory state and lastly complete the dump process. The UV calls are exposed by KVM via the new KVM_PV_DUMP command and its subcommands. The guest's data is fully encrypted and can only be decrypted by the entity that owns the customer communication key for the dumped guest. Also dumping needs to be allowed via a flag in the SE header. On the QEMU side of things we store the PV dump data in the newly introduced architecture ELF sections (storage state and completion data) and the cpu notes (for cpu dump data). Users can use the zgetdump tool to convert the encrypted QEMU dump to an unencrypted one. Signed-off-by: Janosch Frank Reviewed-by: Steffen Eiden Message-Id: <20221017083822.43118-11-frankja@linux.ibm.com> --- dump/dump.c | 12 +- include/sysemu/dump.h | 5 + target/s390x/arch_dump.c | 262 +++++++++++++++++++++++++++++++++++---- 3 files changed, 246 insertions(+), 33 deletions(-) diff --git a/dump/dump.c b/dump/dump.c index 9428d1fde9..df117c847f 100644 --- a/dump/dump.c +++ b/dump/dump.c @@ -708,9 +708,9 @@ static void dump_begin(DumpState *s, Error **errp) write_elf_notes(s, errp); } -static int64_t dump_filtered_memblock_size(GuestPhysBlock *block, - int64_t filter_area_start, - int64_t filter_area_length) +int64_t dump_filtered_memblock_size(GuestPhysBlock *block, + int64_t filter_area_start, + int64_t filter_area_length) { int64_t size, left, right; @@ -728,9 +728,9 @@ static int64_t dump_filtered_memblock_size(GuestPhysBlock *block, return size; } -static int64_t dump_filtered_memblock_start(GuestPhysBlock *block, - int64_t filter_area_start, - int64_t filter_area_length) +int64_t dump_filtered_memblock_start(GuestPhysBlock *block, + int64_t filter_area_start, + int64_t filter_area_length) { if (filter_area_length) { /* return -1 if the block is not within filter area */ diff --git a/include/sysemu/dump.h b/include/sysemu/dump.h index 38ccac7190..4ffed0b659 100644 --- a/include/sysemu/dump.h +++ b/include/sysemu/dump.h @@ -215,4 +215,9 @@ typedef struct DumpState { uint16_t cpu_to_dump16(DumpState *s, uint16_t val); uint32_t cpu_to_dump32(DumpState *s, uint32_t val); uint64_t cpu_to_dump64(DumpState *s, uint64_t val); + +int64_t dump_filtered_memblock_size(GuestPhysBlock *block, int64_t filter_area_start, + int64_t filter_area_length); +int64_t dump_filtered_memblock_start(GuestPhysBlock *block, int64_t filter_area_start, + int64_t filter_area_length); #endif diff --git a/target/s390x/arch_dump.c b/target/s390x/arch_dump.c index f60a14920d..a2329141e8 100644 --- a/target/s390x/arch_dump.c +++ b/target/s390x/arch_dump.c @@ -12,11 +12,13 @@ */ #include "qemu/osdep.h" +#include "qemu/units.h" #include "cpu.h" #include "s390x-internal.h" #include "elf.h" #include "sysemu/dump.h" - +#include "hw/s390x/pv.h" +#include "kvm/kvm_s390x.h" struct S390xUserRegsStruct { uint64_t psw[2]; @@ -76,9 +78,16 @@ typedef struct noteStruct { uint64_t todcmp; uint32_t todpreg; uint64_t ctrs[16]; + uint8_t dynamic[1]; /* + * Would be a flexible array member, if + * that was legal inside a union. Real + * size comes from PV info interface. + */ } contents; } QEMU_PACKED Note; +static bool pv_dump_initialized; + static void s390x_write_elf64_prstatus(Note *note, S390CPU *cpu, int id) { int i; @@ -177,28 +186,39 @@ static void s390x_write_elf64_prefix(Note *note, S390CPU *cpu, int id) note->contents.prefix = cpu_to_be32((uint32_t)(cpu->env.psa)); } +static void s390x_write_elf64_pv(Note *note, S390CPU *cpu, int id) +{ + note->hdr.n_type = cpu_to_be32(NT_S390_PV_CPU_DATA); + if (!pv_dump_initialized) { + return; + } + kvm_s390_dump_cpu(cpu, ¬e->contents.dynamic); +} typedef struct NoteFuncDescStruct { int contents_size; + uint64_t (*note_size_func)(void); /* NULL for non-dynamic sized contents */ void (*note_contents_func)(Note *note, S390CPU *cpu, int id); + bool pvonly; } NoteFuncDesc; static const NoteFuncDesc note_core[] = { - {sizeof_field(Note, contents.prstatus), s390x_write_elf64_prstatus}, - {sizeof_field(Note, contents.fpregset), s390x_write_elf64_fpregset}, - { 0, NULL} + {sizeof_field(Note, contents.prstatus), NULL, s390x_write_elf64_prstatus, false}, + {sizeof_field(Note, contents.fpregset), NULL, s390x_write_elf64_fpregset, false}, + { 0, NULL, NULL, false} }; static const NoteFuncDesc note_linux[] = { - {sizeof_field(Note, contents.prefix), s390x_write_elf64_prefix}, - {sizeof_field(Note, contents.ctrs), s390x_write_elf64_ctrs}, - {sizeof_field(Note, contents.timer), s390x_write_elf64_timer}, - {sizeof_field(Note, contents.todcmp), s390x_write_elf64_todcmp}, - {sizeof_field(Note, contents.todpreg), s390x_write_elf64_todpreg}, - {sizeof_field(Note, contents.vregslo), s390x_write_elf64_vregslo}, - {sizeof_field(Note, contents.vregshi), s390x_write_elf64_vregshi}, - {sizeof_field(Note, contents.gscb), s390x_write_elf64_gscb}, - { 0, NULL} + {sizeof_field(Note, contents.prefix), NULL, s390x_write_elf64_prefix, false}, + {sizeof_field(Note, contents.ctrs), NULL, s390x_write_elf64_ctrs, false}, + {sizeof_field(Note, contents.timer), NULL, s390x_write_elf64_timer, false}, + {sizeof_field(Note, contents.todcmp), NULL, s390x_write_elf64_todcmp, false}, + {sizeof_field(Note, contents.todpreg), NULL, s390x_write_elf64_todpreg, false}, + {sizeof_field(Note, contents.vregslo), NULL, s390x_write_elf64_vregslo, false}, + {sizeof_field(Note, contents.vregshi), NULL, s390x_write_elf64_vregshi, false}, + {sizeof_field(Note, contents.gscb), NULL, s390x_write_elf64_gscb, false}, + {0, kvm_s390_pv_dmp_get_size_cpu, s390x_write_elf64_pv, true}, + { 0, NULL, NULL, false} }; static int s390x_write_elf64_notes(const char *note_name, @@ -207,22 +227,41 @@ static int s390x_write_elf64_notes(const char *note_name, DumpState *s, const NoteFuncDesc *funcs) { - Note note; + Note note, *notep; const NoteFuncDesc *nf; - int note_size; + int note_size, content_size; int ret = -1; assert(strlen(note_name) < sizeof(note.name)); for (nf = funcs; nf->note_contents_func; nf++) { - memset(¬e, 0, sizeof(note)); - note.hdr.n_namesz = cpu_to_be32(strlen(note_name) + 1); - note.hdr.n_descsz = cpu_to_be32(nf->contents_size); - g_strlcpy(note.name, note_name, sizeof(note.name)); - (*nf->note_contents_func)(¬e, cpu, id); + notep = ¬e; + if (nf->pvonly && !s390_is_pv()) { + continue; + } - note_size = sizeof(note) - sizeof(note.contents) + nf->contents_size; - ret = f(¬e, note_size, s); + content_size = nf->note_size_func ? nf->note_size_func() : nf->contents_size; + note_size = sizeof(note) - sizeof(notep->contents) + content_size; + + /* Notes with dynamic sizes need to allocate a note */ + if (nf->note_size_func) { + notep = g_malloc(note_size); + } + + memset(notep, 0, sizeof(note)); + + /* Setup note header data */ + notep->hdr.n_descsz = cpu_to_be32(content_size); + notep->hdr.n_namesz = cpu_to_be32(strlen(note_name) + 1); + g_strlcpy(notep->name, note_name, sizeof(notep->name)); + + /* Get contents and write them out */ + (*nf->note_contents_func)(notep, cpu, id); + ret = f(notep, note_size, s); + + if (nf->note_size_func) { + g_free(notep); + } if (ret < 0) { return -1; @@ -247,13 +286,179 @@ int s390_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs, return s390x_write_elf64_notes("LINUX", f, cpu, cpuid, s, note_linux); } +/* PV dump section size functions */ +static uint64_t get_mem_state_size_from_len(uint64_t len) +{ + return (len / (MiB)) * kvm_s390_pv_dmp_get_size_mem_state(); +} + +static uint64_t get_size_mem_state(DumpState *s) +{ + return get_mem_state_size_from_len(s->total_size); +} + +static uint64_t get_size_completion_data(DumpState *s) +{ + return kvm_s390_pv_dmp_get_size_completion_data(); +} + +/* PV dump section data functions*/ +static int get_data_completion(DumpState *s, uint8_t *buff) +{ + int rc; + + if (!pv_dump_initialized) { + return 0; + } + rc = kvm_s390_dump_completion_data(buff); + if (!rc) { + pv_dump_initialized = false; + } + return rc; +} + +static int get_mem_state(DumpState *s, uint8_t *buff) +{ + int64_t memblock_size, memblock_start; + GuestPhysBlock *block; + uint64_t off; + int rc; + + QTAILQ_FOREACH(block, &s->guest_phys_blocks.head, next) { + memblock_start = dump_filtered_memblock_start(block, s->filter_area_begin, + s->filter_area_length); + if (memblock_start == -1) { + continue; + } + + memblock_size = dump_filtered_memblock_size(block, s->filter_area_begin, + s->filter_area_length); + + off = get_mem_state_size_from_len(block->target_start); + + rc = kvm_s390_dump_mem_state(block->target_start, + get_mem_state_size_from_len(memblock_size), + buff + off); + if (rc) { + return rc; + } + } + + return 0; +} + +static struct sections { + uint64_t (*sections_size_func)(DumpState *s); + int (*sections_contents_func)(DumpState *s, uint8_t *buff); + char sctn_str[12]; +} sections[] = { + { get_size_mem_state, get_mem_state, "pv_mem_meta"}, + { get_size_completion_data, get_data_completion, "pv_compl"}, + {NULL , NULL, ""} +}; + +static uint64_t arch_sections_write_hdr(DumpState *s, uint8_t *buff) +{ + Elf64_Shdr *shdr = (void *)buff; + struct sections *sctn = sections; + uint64_t off = s->section_offset; + + if (!pv_dump_initialized) { + return 0; + } + + for (; sctn->sections_size_func; off += shdr->sh_size, sctn++, shdr++) { + memset(shdr, 0, sizeof(*shdr)); + shdr->sh_type = SHT_PROGBITS; + shdr->sh_offset = off; + shdr->sh_size = sctn->sections_size_func(s); + shdr->sh_name = s->string_table_buf->len; + g_array_append_vals(s->string_table_buf, sctn->sctn_str, sizeof(sctn->sctn_str)); + } + + return (uintptr_t)shdr - (uintptr_t)buff; +} + + +/* Add arch specific number of sections and their respective sizes */ +static void arch_sections_add(DumpState *s) +{ + struct sections *sctn = sections; + + /* + * We only do a PV dump if we are running a PV guest, KVM supports + * the dump API and we got valid dump length information. + */ + if (!s390_is_pv() || !kvm_s390_get_protected_dump() || + !kvm_s390_pv_info_basic_valid()) { + return; + } + + /* + * Start the UV dump process by doing the initialize dump call via + * KVM as the proxy. + */ + if (!kvm_s390_dump_init()) { + pv_dump_initialized = true; + } else { + /* + * Dump init failed, maybe the guest owner disabled dumping. + * We'll continue the non-PV dump process since this is no + * reason to crash qemu. + */ + return; + } + + for (; sctn->sections_size_func; sctn++) { + s->shdr_num += 1; + s->elf_section_data_size += sctn->sections_size_func(s); + } +} + +/* + * After the PV dump has been initialized, the CPU data has been + * fetched and memory has been dumped, we need to grab the tweak data + * and the completion data. + */ +static int arch_sections_write(DumpState *s, uint8_t *buff) +{ + struct sections *sctn = sections; + int rc; + + if (!pv_dump_initialized) { + return -EINVAL; + } + + for (; sctn->sections_size_func; sctn++) { + rc = sctn->sections_contents_func(s, buff); + buff += sctn->sections_size_func(s); + if (rc) { + return rc; + } + } + return 0; +} + int cpu_get_dump_info(ArchDumpInfo *info, const struct GuestPhysBlockList *guest_phys_blocks) { info->d_machine = EM_S390; info->d_endian = ELFDATA2MSB; info->d_class = ELFCLASS64; - + /* + * This is evaluated for each dump so we can freely switch + * between PV and non-PV. + */ + if (s390_is_pv() && kvm_s390_get_protected_dump() && + kvm_s390_pv_info_basic_valid()) { + info->arch_sections_add_fn = *arch_sections_add; + info->arch_sections_write_hdr_fn = *arch_sections_write_hdr; + info->arch_sections_write_fn = *arch_sections_write; + } else { + info->arch_sections_add_fn = NULL; + info->arch_sections_write_hdr_fn = NULL; + info->arch_sections_write_fn = NULL; + } return 0; } @@ -261,7 +466,7 @@ ssize_t cpu_get_note_size(int class, int machine, int nr_cpus) { int name_size = 8; /* "LINUX" or "CORE" + pad */ size_t elf_note_size = 0; - int note_head_size; + int note_head_size, content_size; const NoteFuncDesc *nf; assert(class == ELFCLASS64); @@ -270,12 +475,15 @@ ssize_t cpu_get_note_size(int class, int machine, int nr_cpus) note_head_size = sizeof(Elf64_Nhdr); for (nf = note_core; nf->note_contents_func; nf++) { - elf_note_size = elf_note_size + note_head_size + name_size + - nf->contents_size; + elf_note_size = elf_note_size + note_head_size + name_size + nf->contents_size; } for (nf = note_linux; nf->note_contents_func; nf++) { + if (nf->pvonly && !s390_is_pv()) { + continue; + } + content_size = nf->contents_size ? nf->contents_size : nf->note_size_func(); elf_note_size = elf_note_size + note_head_size + name_size + - nf->contents_size; + content_size; } return (elf_note_size) * nr_cpus; From e38c24cb580735883769558801d9e2f2ba9f04c1 Mon Sep 17 00:00:00 2001 From: Viktor Prutyanov Date: Thu, 20 Oct 2022 02:59:48 +0300 Subject: [PATCH 147/705] dump/win_dump: limit number of processed PRCBs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When number of CPUs utilized by guest Windows is less than defined in QEMU (i.e., desktop versions of Windows severely limits number of CPU sockets), patch_and_save_context routine accesses non-existent PRCB and fails. So, limit number of processed PRCBs by NumberProcessors taken from guest Windows driver. Signed-off-by: Viktor Prutyanov Reviewed-by: Marc-André Lureau Message-Id: <20221019235948.656411-1-viktor.prutyanov@redhat.com> --- dump/win_dump.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dump/win_dump.c b/dump/win_dump.c index fd91350fbb..f20b6051b6 100644 --- a/dump/win_dump.c +++ b/dump/win_dump.c @@ -273,6 +273,13 @@ static void patch_and_save_context(WinDumpHeader *h, bool x64, uint64_t Context; WinContext ctx; + if (i >= WIN_DUMP_FIELD(NumberProcessors)) { + warn_report("win-dump: number of QEMU CPUs is bigger than" + " NumberProcessors (%u) in guest Windows", + WIN_DUMP_FIELD(NumberProcessors)); + return; + } + if (cpu_read_ptr(x64, first_cpu, KiProcessorBlock + i * win_dump_ptr_size(x64), &Prcb)) { From bf98afc75efedf10965a3f2d98aa43c234cf69ed Mon Sep 17 00:00:00 2001 From: Jungmin Park Date: Wed, 24 Aug 2022 21:37:06 +0900 Subject: [PATCH 148/705] crypto/luks: Support creating LUKS image on Darwin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the user creates a LUKS-encrypted qcow2 image using the qemu-img program, the passphrase is hashed using PBKDF2 with a dynamic number of iterations. The number of iterations is determined by measuring thread cpu time usage, such that it takes approximately 2 seconds to compute the hash. Because Darwin doesn't implement getrusage(RUSAGE_THREAD), we get an error message: > qemu-img: test.qcow2: Unable to calculate thread CPU usage on this platform for this command: > qemu-img create --object secret,id=key,data=1234 -f qcow2 -o 'encrypt.format=luks,encrypt.key-secret=key' test.qcow2 100M This patch implements qcrypto_pbkdf2_get_thread_cpu() for Darwin so that the above command works. Signed-off-by: Jungmin Park Signed-off-by: Daniel P. Berrangé --- crypto/pbkdf.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/crypto/pbkdf.c b/crypto/pbkdf.c index 3775ddc6c5..8d198c152c 100644 --- a/crypto/pbkdf.c +++ b/crypto/pbkdf.c @@ -24,6 +24,11 @@ #ifndef _WIN32 #include #endif +#ifdef CONFIG_DARWIN +#include +#include +#include +#endif static int qcrypto_pbkdf2_get_thread_cpu(unsigned long long *val_ms, @@ -45,6 +50,24 @@ static int qcrypto_pbkdf2_get_thread_cpu(unsigned long long *val_ms, /* QuadPart is units of 100ns and we want ms as unit */ *val_ms = thread_time.QuadPart / 10000ll; return 0; +#elif defined(CONFIG_DARWIN) + mach_port_t thread; + kern_return_t kr; + mach_msg_type_number_t count; + thread_basic_info_data_t info; + + thread = mach_thread_self(); + count = THREAD_BASIC_INFO_COUNT; + kr = thread_info(thread, THREAD_BASIC_INFO, (thread_info_t)&info, &count); + mach_port_deallocate(mach_task_self(), thread); + if (kr != KERN_SUCCESS || (info.flags & TH_FLAGS_IDLE) != 0) { + error_setg_errno(errp, errno, "Unable to get thread CPU usage"); + return -1; + } + + *val_ms = ((info.user_time.seconds * 1000ll) + + (info.user_time.microseconds / 1000)); + return 0; #elif defined(RUSAGE_THREAD) struct rusage ru; if (getrusage(RUSAGE_THREAD, &ru) < 0) { From 926a895c2cfcd621373eb86288dd83d08cb53f15 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Tue, 27 Sep 2022 19:05:42 +0800 Subject: [PATCH 149/705] util/qemu-sockets: Use g_get_tmp_dir() to get the directory for temporary files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the existing logic to get the directory for temporary files with g_get_tmp_dir(), which works for win32 too. Signed-off-by: Bin Meng Reviewed-by: Marc-André Lureau Signed-off-by: Daniel P. Berrangé --- util/qemu-sockets.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c index 83f4bd6fd2..0c41ca9e42 100644 --- a/util/qemu-sockets.c +++ b/util/qemu-sockets.c @@ -919,9 +919,8 @@ static int unix_listen_saddr(UnixSocketAddress *saddr, if (saddr->path[0] || abstract) { path = saddr->path; } else { - const char *tmpdir = getenv("TMPDIR"); - tmpdir = tmpdir ? tmpdir : "/tmp"; - path = pathbuf = g_strdup_printf("%s/qemu-socket-XXXXXX", tmpdir); + path = pathbuf = g_strdup_printf("%s/qemu-socket-XXXXXX", + g_get_tmp_dir()); } pathlen = strlen(path); From 985be62d4481e11830485a25a47a932e5829d223 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 6 Oct 2022 23:19:23 +0800 Subject: [PATCH 150/705] io/channel-watch: Drop a superfluous '#ifdef WIN32' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the win32 version qio_channel_create_socket_watch() body there is no need to do a '#ifdef WIN32'. Signed-off-by: Bin Meng Reviewed-by: Marc-André Lureau Signed-off-by: Daniel P. Berrangé --- io/channel-watch.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/io/channel-watch.c b/io/channel-watch.c index 0289b3647c..89f3c8a88a 100644 --- a/io/channel-watch.c +++ b/io/channel-watch.c @@ -285,11 +285,9 @@ GSource *qio_channel_create_socket_watch(QIOChannel *ioc, GSource *source; QIOChannelSocketSource *ssource; -#ifdef WIN32 WSAEventSelect(socket, ioc->event, FD_READ | FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_WRITE | FD_OOB); -#endif source = g_source_new(&qio_channel_socket_source_funcs, sizeof(QIOChannelSocketSource)); From 6c822a031b9e87fea8303373d6501f6d6a3c1e31 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 6 Oct 2022 23:19:24 +0800 Subject: [PATCH 151/705] io/channel-watch: Drop the unnecessary cast MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no need to do a type cast on ssource->socket as it is already declared as a SOCKET. Suggested-by: Marc-André Lureau Signed-off-by: Bin Meng Reviewed-by: Marc-André Lureau Signed-off-by: Daniel P. Berrangé --- io/channel-watch.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/io/channel-watch.c b/io/channel-watch.c index 89f3c8a88a..43d38494f7 100644 --- a/io/channel-watch.c +++ b/io/channel-watch.c @@ -130,13 +130,13 @@ qio_channel_socket_source_check(GSource *source) FD_ZERO(&wfds); FD_ZERO(&xfds); if (ssource->condition & G_IO_IN) { - FD_SET((SOCKET)ssource->socket, &rfds); + FD_SET(ssource->socket, &rfds); } if (ssource->condition & G_IO_OUT) { - FD_SET((SOCKET)ssource->socket, &wfds); + FD_SET(ssource->socket, &wfds); } if (ssource->condition & G_IO_PRI) { - FD_SET((SOCKET)ssource->socket, &xfds); + FD_SET(ssource->socket, &xfds); } ssource->revents = 0; if (select(0, &rfds, &wfds, &xfds, &tv0) == 0) { From 23f77f05f2faa8ff3028fef388322f7b4f09533e Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 6 Oct 2022 23:19:25 +0800 Subject: [PATCH 152/705] io/channel-watch: Fix socket watch on Windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Random failure was observed when running qtests on Windows due to "Broken pipe" detected by qmp_fd_receive(). What happened is that the qtest executable sends testing data over a socket to the QEMU under test but no response is received. The errno of the recv() call from the qtest executable indicates ETIMEOUT, due to the qmp chardev's tcp_chr_read() is never called to receive testing data hence no response is sent to the other side. tcp_chr_read() is registered as the callback of the socket watch GSource. The reason of the callback not being called by glib, is that the source check fails to indicate the source is ready. There are two socket watch sources created to monitor the same socket event object from the char-socket backend in update_ioc_handlers(). During the source check phase, qio_channel_socket_source_check() calls WSAEnumNetworkEvents() to discover occurrences of network events for the indicated socket, clear internal network event records, and reset the event object. Testing shows that if we don't reset the event object by not passing the event handle to WSAEnumNetworkEvents() the symptom goes away and qtest runs very stably. It seems we don't need to call WSAEnumNetworkEvents() at all, as we don't parse the result of WSANETWORKEVENTS returned from this API. We use select() to poll the socket status. Fix this instability by dropping the WSAEnumNetworkEvents() call. Some side notes: During the testing, I removed the following codes in update_ioc_handlers(): remove_hup_source(s); s->hup_source = qio_channel_create_watch(s->ioc, G_IO_HUP); g_source_set_callback(s->hup_source, (GSourceFunc)tcp_chr_hup, chr, NULL); g_source_attach(s->hup_source, chr->gcontext); and such change also makes the symptom go away. And if I moved the above codes to the beginning, before the call to io_add_watch_poll(), the symptom also goes away. It seems two sources watching on the same socket event object is the key that leads to the instability. The order of adding a source watch seems to also play a role but I can't explain why. Hopefully a Windows and glib expert could explain this behavior. Signed-off-by: Bin Meng Signed-off-by: Daniel P. Berrangé --- io/channel-watch.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/io/channel-watch.c b/io/channel-watch.c index 43d38494f7..ad7c568a84 100644 --- a/io/channel-watch.c +++ b/io/channel-watch.c @@ -115,17 +115,13 @@ static gboolean qio_channel_socket_source_check(GSource *source) { static struct timeval tv0; - QIOChannelSocketSource *ssource = (QIOChannelSocketSource *)source; - WSANETWORKEVENTS ev; fd_set rfds, wfds, xfds; if (!ssource->condition) { return 0; } - WSAEnumNetworkEvents(ssource->socket, ssource->ioc->event, &ev); - FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&xfds); From 73422d9524376526ab5950b3be3098901cd605d6 Mon Sep 17 00:00:00 2001 From: Michal Privoznik Date: Wed, 26 Oct 2022 09:30:24 +0200 Subject: [PATCH 153/705] seccomp: Get actual errno value from failed seccomp functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Upon failure, a libseccomp API returns actual errno value very rarely. Fortunately, after its commit 34bf78ab (contained in 2.5.0 release), the SCMP_FLTATR_API_SYSRAWRC attribute can be set which makes subsequent APIs return true errno on failure. This is especially critical when seccomp_load() fails, because generic -ECANCELED says nothing. Signed-off-by: Michal Privoznik Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Daniel P. Berrangé --- meson.build | 9 +++++++++ softmmu/qemu-seccomp.c | 13 +++++++++++++ 2 files changed, 22 insertions(+) diff --git a/meson.build b/meson.build index b686dfef75..5f114c89d9 100644 --- a/meson.build +++ b/meson.build @@ -636,10 +636,16 @@ if vmnet.found() and not cc.has_header_symbol('vmnet/vmnet.h', endif seccomp = not_found +seccomp_has_sysrawrc = false if not get_option('seccomp').auto() or have_system or have_tools seccomp = dependency('libseccomp', version: '>=2.3.0', required: get_option('seccomp'), method: 'pkg-config', kwargs: static_kwargs) + if seccomp.found() + seccomp_has_sysrawrc = cc.has_header_symbol('seccomp.h', + 'SCMP_FLTATR_API_SYSRAWRC', + dependencies: seccomp) + endif endif libcap_ng = not_found @@ -1849,6 +1855,9 @@ config_host_data.set('CONFIG_RDMA', rdma.found()) config_host_data.set('CONFIG_SDL', sdl.found()) config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found()) config_host_data.set('CONFIG_SECCOMP', seccomp.found()) +if seccomp.found() + config_host_data.set('CONFIG_SECCOMP_SYSRAWRC', seccomp_has_sysrawrc) +endif config_host_data.set('CONFIG_SNAPPY', snappy.found()) config_host_data.set('CONFIG_TPM', have_tpm) config_host_data.set('CONFIG_USB_LIBUSB', libusb.found()) diff --git a/softmmu/qemu-seccomp.c b/softmmu/qemu-seccomp.c index deaf8a4ef5..d66a2a1226 100644 --- a/softmmu/qemu-seccomp.c +++ b/softmmu/qemu-seccomp.c @@ -312,6 +312,19 @@ static int seccomp_start(uint32_t seccomp_opts, Error **errp) goto seccomp_return; } +#if defined(CONFIG_SECCOMP_SYSRAWRC) + /* + * This must be the first seccomp_attr_set() call to have full + * error propagation from subsequent seccomp APIs. + */ + rc = seccomp_attr_set(ctx, SCMP_FLTATR_API_SYSRAWRC, 1); + if (rc != 0) { + error_setg_errno(errp, -rc, + "failed to set seccomp rawrc attribute"); + goto seccomp_return; + } +#endif + rc = seccomp_attr_set(ctx, SCMP_FLTATR_CTL_TSYNC, 1); if (rc != 0) { error_setg_errno(errp, -rc, From c6cd588bb3a29a831c862780631a7d2145ade5de Mon Sep 17 00:00:00 2001 From: Alexander Ivanov Date: Mon, 17 Oct 2022 09:28:19 +0200 Subject: [PATCH 154/705] qga: Add initial FreeBSD support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix device path. - Fix virtio-serial channel initialization. - Make the code buildable in FreeBSD. Reviewed-by: Konstantin Kostiuk Acked-by: Marc-André Lureau Signed-off-by: Alexander Ivanov Signed-off-by: Konstantin Kostiuk --- meson.build | 2 +- qga/channel-posix.c | 19 +++++++++++++++++++ qga/commands-posix.c | 8 ++++++++ qga/main.c | 6 +++++- 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/meson.build b/meson.build index b686dfef75..71fe72ea06 100644 --- a/meson.build +++ b/meson.build @@ -75,7 +75,7 @@ have_tools = get_option('tools') \ .allowed() have_ga = get_option('guest_agent') \ .disable_auto_if(not have_system and not have_tools) \ - .require(targetos in ['sunos', 'linux', 'windows'], + .require(targetos in ['sunos', 'linux', 'windows', 'freebsd'], error_message: 'unsupported OS for QEMU guest agent') \ .allowed() have_block = have_system or have_tools diff --git a/qga/channel-posix.c b/qga/channel-posix.c index 6796a02cff..568350ded4 100644 --- a/qga/channel-posix.c +++ b/qga/channel-posix.c @@ -149,6 +149,25 @@ static gboolean ga_channel_open(GAChannel *c, const gchar *path, return false; } #endif +#ifdef __FreeBSD__ + /* + * In the default state channel sends echo of every command to a + * client. The client programm doesn't expect this and raises an + * error. Suppress echo by resetting ECHO terminal flag. + */ + struct termios tio; + if (tcgetattr(fd, &tio) < 0) { + error_setg_errno(errp, errno, "error getting channel termios attrs"); + close(fd); + return false; + } + tio.c_lflag &= ~ECHO; + if (tcsetattr(fd, TCSAFLUSH, &tio) < 0) { + error_setg_errno(errp, errno, "error setting channel termios attrs"); + close(fd); + return false; + } +#endif /* __FreeBSD__ */ ret = ga_channel_client_add(c, fd); if (ret) { error_setg(errp, "error adding channel to main loop"); diff --git a/qga/commands-posix.c b/qga/commands-posix.c index eea819cff0..16d67e9f6d 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -51,6 +51,14 @@ #endif #endif +#ifdef __FreeBSD__ +/* + * The code under HAVE_GETIFADDRS condition can't be compiled in FreeBSD. + * Fix it in one of the following patches. + */ +#undef HAVE_GETIFADDRS +#endif + #ifdef HAVE_GETIFADDRS #include #include diff --git a/qga/main.c b/qga/main.c index 5a9d8252e0..0d27c97d38 100644 --- a/qga/main.c +++ b/qga/main.c @@ -45,9 +45,13 @@ #endif #ifndef _WIN32 +#ifdef __FreeBSD__ +#define QGA_VIRTIO_PATH_DEFAULT "/dev/vtcon/org.qemu.guest_agent.0" +#else /* __FreeBSD__ */ #define QGA_VIRTIO_PATH_DEFAULT "/dev/virtio-ports/org.qemu.guest_agent.0" -#define QGA_STATE_RELATIVE_DIR "run" +#endif /* __FreeBSD__ */ #define QGA_SERIAL_PATH_DEFAULT "/dev/ttyS0" +#define QGA_STATE_RELATIVE_DIR "run" #else #define QGA_VIRTIO_PATH_DEFAULT "\\\\.\\Global\\org.qemu.guest_agent.0" #define QGA_STATE_RELATIVE_DIR "qemu-ga" From 518b0d800b5ab046b72fac423ace7549ab187329 Mon Sep 17 00:00:00 2001 From: Alexander Ivanov Date: Mon, 17 Oct 2022 09:28:20 +0200 Subject: [PATCH 155/705] qga: Move Linux-specific FS freeze/thaw code to a separate file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the next patches we are going to add FreeBSD support for QEMU Guest Agent. In the result, code in commands-posix.c will be too cumbersome. Move Linux-specific FS freeze/thaw code to a separate file commands-linux.c keeping common POSIX code in commands-posix.c. Reviewed-by: Konstantin Kostiuk Reviewed-by: Marc-André Lureau Signed-off-by: Alexander Ivanov Signed-off-by: Konstantin Kostiuk --- qga/commands-common.h | 34 +++++ qga/commands-linux.c | 286 +++++++++++++++++++++++++++++++++++++++++ qga/commands-posix.c | 287 +++--------------------------------------- qga/meson.build | 3 + 4 files changed, 338 insertions(+), 272 deletions(-) create mode 100644 qga/commands-linux.c diff --git a/qga/commands-common.h b/qga/commands-common.h index d0e4a9696f..cb51b1c6e9 100644 --- a/qga/commands-common.h +++ b/qga/commands-common.h @@ -10,6 +10,40 @@ #define QGA_COMMANDS_COMMON_H #include "qga-qapi-types.h" +#include "guest-agent-core.h" +#include "qemu/queue.h" + +#if defined(__linux__) +#include +#ifdef FIFREEZE +#define CONFIG_FSFREEZE +#endif +#ifdef FITRIM +#define CONFIG_FSTRIM +#endif +#endif /* __linux__ */ + +#if defined(CONFIG_FSFREEZE) || defined(CONFIG_FSTRIM) +typedef struct FsMount { + char *dirname; + char *devtype; + unsigned int devmajor, devminor; + QTAILQ_ENTRY(FsMount) next; +} FsMount; + +typedef QTAILQ_HEAD(FsMountList, FsMount) FsMountList; + +bool build_fs_mount_list(FsMountList *mounts, Error **errp); +void free_fs_mount_list(FsMountList *mounts); +#endif /* CONFIG_FSFREEZE || CONFIG_FSTRIM */ + +#if defined(CONFIG_FSFREEZE) +int64_t qmp_guest_fsfreeze_do_freeze_list(bool has_mountpoints, + strList *mountpoints, + FsMountList mounts, + Error **errp); +int qmp_guest_fsfreeze_do_thaw(Error **errp); +#endif /* CONFIG_FSFREEZE */ typedef struct GuestFileHandle GuestFileHandle; diff --git a/qga/commands-linux.c b/qga/commands-linux.c new file mode 100644 index 0000000000..214e408fcd --- /dev/null +++ b/qga/commands-linux.c @@ -0,0 +1,286 @@ +/* + * QEMU Guest Agent Linux-specific command implementations + * + * Copyright IBM Corp. 2011 + * + * Authors: + * Michael Roth + * Michal Privoznik + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "commands-common.h" +#include "cutils.h" +#include +#include + +#if defined(CONFIG_FSFREEZE) || defined(CONFIG_FSTRIM) +static int dev_major_minor(const char *devpath, + unsigned int *devmajor, unsigned int *devminor) +{ + struct stat st; + + *devmajor = 0; + *devminor = 0; + + if (stat(devpath, &st) < 0) { + slog("failed to stat device file '%s': %s", devpath, strerror(errno)); + return -1; + } + if (S_ISDIR(st.st_mode)) { + /* It is bind mount */ + return -2; + } + if (S_ISBLK(st.st_mode)) { + *devmajor = major(st.st_rdev); + *devminor = minor(st.st_rdev); + return 0; + } + return -1; +} + +static bool build_fs_mount_list_from_mtab(FsMountList *mounts, Error **errp) +{ + struct mntent *ment; + FsMount *mount; + char const *mtab = "/proc/self/mounts"; + FILE *fp; + unsigned int devmajor, devminor; + + fp = setmntent(mtab, "r"); + if (!fp) { + error_setg(errp, "failed to open mtab file: '%s'", mtab); + return false; + } + + while ((ment = getmntent(fp))) { + /* + * An entry which device name doesn't start with a '/' is + * either a dummy file system or a network file system. + * Add special handling for smbfs and cifs as is done by + * coreutils as well. + */ + if ((ment->mnt_fsname[0] != '/') || + (strcmp(ment->mnt_type, "smbfs") == 0) || + (strcmp(ment->mnt_type, "cifs") == 0)) { + continue; + } + if (dev_major_minor(ment->mnt_fsname, &devmajor, &devminor) == -2) { + /* Skip bind mounts */ + continue; + } + + mount = g_new0(FsMount, 1); + mount->dirname = g_strdup(ment->mnt_dir); + mount->devtype = g_strdup(ment->mnt_type); + mount->devmajor = devmajor; + mount->devminor = devminor; + + QTAILQ_INSERT_TAIL(mounts, mount, next); + } + + endmntent(fp); + return true; +} + +static void decode_mntname(char *name, int len) +{ + int i, j = 0; + for (i = 0; i <= len; i++) { + if (name[i] != '\\') { + name[j++] = name[i]; + } else if (name[i + 1] == '\\') { + name[j++] = '\\'; + i++; + } else if (name[i + 1] >= '0' && name[i + 1] <= '3' && + name[i + 2] >= '0' && name[i + 2] <= '7' && + name[i + 3] >= '0' && name[i + 3] <= '7') { + name[j++] = (name[i + 1] - '0') * 64 + + (name[i + 2] - '0') * 8 + + (name[i + 3] - '0'); + i += 3; + } else { + name[j++] = name[i]; + } + } +} + +/* + * Walk the mount table and build a list of local file systems + */ +bool build_fs_mount_list(FsMountList *mounts, Error **errp) +{ + FsMount *mount; + char const *mountinfo = "/proc/self/mountinfo"; + FILE *fp; + char *line = NULL, *dash; + size_t n; + char check; + unsigned int devmajor, devminor; + int ret, dir_s, dir_e, type_s, type_e, dev_s, dev_e; + + fp = fopen(mountinfo, "r"); + if (!fp) { + return build_fs_mount_list_from_mtab(mounts, errp); + } + + while (getline(&line, &n, fp) != -1) { + ret = sscanf(line, "%*u %*u %u:%u %*s %n%*s%n%c", + &devmajor, &devminor, &dir_s, &dir_e, &check); + if (ret < 3) { + continue; + } + dash = strstr(line + dir_e, " - "); + if (!dash) { + continue; + } + ret = sscanf(dash, " - %n%*s%n %n%*s%n%c", + &type_s, &type_e, &dev_s, &dev_e, &check); + if (ret < 1) { + continue; + } + line[dir_e] = 0; + dash[type_e] = 0; + dash[dev_e] = 0; + decode_mntname(line + dir_s, dir_e - dir_s); + decode_mntname(dash + dev_s, dev_e - dev_s); + if (devmajor == 0) { + /* btrfs reports major number = 0 */ + if (strcmp("btrfs", dash + type_s) != 0 || + dev_major_minor(dash + dev_s, &devmajor, &devminor) < 0) { + continue; + } + } + + mount = g_new0(FsMount, 1); + mount->dirname = g_strdup(line + dir_s); + mount->devtype = g_strdup(dash + type_s); + mount->devmajor = devmajor; + mount->devminor = devminor; + + QTAILQ_INSERT_TAIL(mounts, mount, next); + } + free(line); + + fclose(fp); + return true; +} +#endif /* CONFIG_FSFREEZE || CONFIG_FSTRIM */ + +#ifdef CONFIG_FSFREEZE +/* + * Walk list of mounted file systems in the guest, and freeze the ones which + * are real local file systems. + */ +int64_t qmp_guest_fsfreeze_do_freeze_list(bool has_mountpoints, + strList *mountpoints, + FsMountList mounts, + Error **errp) +{ + struct FsMount *mount; + strList *list; + int fd, ret, i = 0; + + QTAILQ_FOREACH_REVERSE(mount, &mounts, next) { + /* To issue fsfreeze in the reverse order of mounts, check if the + * mount is listed in the list here */ + if (has_mountpoints) { + for (list = mountpoints; list; list = list->next) { + if (strcmp(list->value, mount->dirname) == 0) { + break; + } + } + if (!list) { + continue; + } + } + + fd = qga_open_cloexec(mount->dirname, O_RDONLY, 0); + if (fd == -1) { + error_setg_errno(errp, errno, "failed to open %s", mount->dirname); + return -1; + } + + /* we try to cull filesystems we know won't work in advance, but other + * filesystems may not implement fsfreeze for less obvious reasons. + * these will report EOPNOTSUPP. we simply ignore these when tallying + * the number of frozen filesystems. + * if a filesystem is mounted more than once (aka bind mount) a + * consecutive attempt to freeze an already frozen filesystem will + * return EBUSY. + * + * any other error means a failure to freeze a filesystem we + * expect to be freezable, so return an error in those cases + * and return system to thawed state. + */ + ret = ioctl(fd, FIFREEZE); + if (ret == -1) { + if (errno != EOPNOTSUPP && errno != EBUSY) { + error_setg_errno(errp, errno, "failed to freeze %s", + mount->dirname); + close(fd); + return -1; + } + } else { + i++; + } + close(fd); + } + return i; +} + +int qmp_guest_fsfreeze_do_thaw(Error **errp) +{ + int ret; + FsMountList mounts; + FsMount *mount; + int fd, i = 0, logged; + Error *local_err = NULL; + + QTAILQ_INIT(&mounts); + if (!build_fs_mount_list(&mounts, &local_err)) { + error_propagate(errp, local_err); + return -1; + } + + QTAILQ_FOREACH(mount, &mounts, next) { + logged = false; + fd = qga_open_cloexec(mount->dirname, O_RDONLY, 0); + if (fd == -1) { + continue; + } + /* we have no way of knowing whether a filesystem was actually unfrozen + * as a result of a successful call to FITHAW, only that if an error + * was returned the filesystem was *not* unfrozen by that particular + * call. + * + * since multiple preceding FIFREEZEs require multiple calls to FITHAW + * to unfreeze, continuing issuing FITHAW until an error is returned, + * in which case either the filesystem is in an unfreezable state, or, + * more likely, it was thawed previously (and remains so afterward). + * + * also, since the most recent successful call is the one that did + * the actual unfreeze, we can use this to provide an accurate count + * of the number of filesystems unfrozen by guest-fsfreeze-thaw, which + * may * be useful for determining whether a filesystem was unfrozen + * during the freeze/thaw phase by a process other than qemu-ga. + */ + do { + ret = ioctl(fd, FITHAW); + if (ret == 0 && !logged) { + i++; + logged = true; + } + } while (ret == 0); + close(fd); + } + + free_fs_mount_list(&mounts); + + return i; +} +#endif /* CONFIG_FSFREEZE */ diff --git a/qga/commands-posix.c b/qga/commands-posix.c index 16d67e9f6d..d24f2fafd8 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -16,11 +16,9 @@ #include #include #include -#include "guest-agent-core.h" #include "qga-qapi-commands.h" #include "qapi/error.h" #include "qapi/qmp/qerror.h" -#include "qemu/queue.h" #include "qemu/host-utils.h" #include "qemu/sockets.h" #include "qemu/base64.h" @@ -629,16 +627,7 @@ void qmp_guest_file_flush(int64_t handle, Error **errp) #if defined(__linux__) #if defined(CONFIG_FSFREEZE) || defined(CONFIG_FSTRIM) -typedef struct FsMount { - char *dirname; - char *devtype; - unsigned int devmajor, devminor; - QTAILQ_ENTRY(FsMount) next; -} FsMount; - -typedef QTAILQ_HEAD(FsMountList, FsMount) FsMountList; - -static void free_fs_mount_list(FsMountList *mounts) +void free_fs_mount_list(FsMountList *mounts) { FsMount *mount, *temp; @@ -653,157 +642,6 @@ static void free_fs_mount_list(FsMountList *mounts) g_free(mount); } } - -static int dev_major_minor(const char *devpath, - unsigned int *devmajor, unsigned int *devminor) -{ - struct stat st; - - *devmajor = 0; - *devminor = 0; - - if (stat(devpath, &st) < 0) { - slog("failed to stat device file '%s': %s", devpath, strerror(errno)); - return -1; - } - if (S_ISDIR(st.st_mode)) { - /* It is bind mount */ - return -2; - } - if (S_ISBLK(st.st_mode)) { - *devmajor = major(st.st_rdev); - *devminor = minor(st.st_rdev); - return 0; - } - return -1; -} - -/* - * Walk the mount table and build a list of local file systems - */ -static bool build_fs_mount_list_from_mtab(FsMountList *mounts, Error **errp) -{ - struct mntent *ment; - FsMount *mount; - char const *mtab = "/proc/self/mounts"; - FILE *fp; - unsigned int devmajor, devminor; - - fp = setmntent(mtab, "r"); - if (!fp) { - error_setg(errp, "failed to open mtab file: '%s'", mtab); - return false; - } - - while ((ment = getmntent(fp))) { - /* - * An entry which device name doesn't start with a '/' is - * either a dummy file system or a network file system. - * Add special handling for smbfs and cifs as is done by - * coreutils as well. - */ - if ((ment->mnt_fsname[0] != '/') || - (strcmp(ment->mnt_type, "smbfs") == 0) || - (strcmp(ment->mnt_type, "cifs") == 0)) { - continue; - } - if (dev_major_minor(ment->mnt_fsname, &devmajor, &devminor) == -2) { - /* Skip bind mounts */ - continue; - } - - mount = g_new0(FsMount, 1); - mount->dirname = g_strdup(ment->mnt_dir); - mount->devtype = g_strdup(ment->mnt_type); - mount->devmajor = devmajor; - mount->devminor = devminor; - - QTAILQ_INSERT_TAIL(mounts, mount, next); - } - - endmntent(fp); - return true; -} - -static void decode_mntname(char *name, int len) -{ - int i, j = 0; - for (i = 0; i <= len; i++) { - if (name[i] != '\\') { - name[j++] = name[i]; - } else if (name[i + 1] == '\\') { - name[j++] = '\\'; - i++; - } else if (name[i + 1] >= '0' && name[i + 1] <= '3' && - name[i + 2] >= '0' && name[i + 2] <= '7' && - name[i + 3] >= '0' && name[i + 3] <= '7') { - name[j++] = (name[i + 1] - '0') * 64 + - (name[i + 2] - '0') * 8 + - (name[i + 3] - '0'); - i += 3; - } else { - name[j++] = name[i]; - } - } -} - -static bool build_fs_mount_list(FsMountList *mounts, Error **errp) -{ - FsMount *mount; - char const *mountinfo = "/proc/self/mountinfo"; - FILE *fp; - char *line = NULL, *dash; - size_t n; - char check; - unsigned int devmajor, devminor; - int ret, dir_s, dir_e, type_s, type_e, dev_s, dev_e; - - fp = fopen(mountinfo, "r"); - if (!fp) { - return build_fs_mount_list_from_mtab(mounts, errp); - } - - while (getline(&line, &n, fp) != -1) { - ret = sscanf(line, "%*u %*u %u:%u %*s %n%*s%n%c", - &devmajor, &devminor, &dir_s, &dir_e, &check); - if (ret < 3) { - continue; - } - dash = strstr(line + dir_e, " - "); - if (!dash) { - continue; - } - ret = sscanf(dash, " - %n%*s%n %n%*s%n%c", - &type_s, &type_e, &dev_s, &dev_e, &check); - if (ret < 1) { - continue; - } - line[dir_e] = 0; - dash[type_e] = 0; - dash[dev_e] = 0; - decode_mntname(line + dir_s, dir_e - dir_s); - decode_mntname(dash + dev_s, dev_e - dev_s); - if (devmajor == 0) { - /* btrfs reports major number = 0 */ - if (strcmp("btrfs", dash + type_s) != 0 || - dev_major_minor(dash + dev_s, &devmajor, &devminor) < 0) { - continue; - } - } - - mount = g_new0(FsMount, 1); - mount->dirname = g_strdup(line + dir_s); - mount->devtype = g_strdup(dash + type_s); - mount->devmajor = devmajor; - mount->devminor = devminor; - - QTAILQ_INSERT_TAIL(mounts, mount, next); - } - free(line); - - fclose(fp); - return true; -} #endif #if defined(CONFIG_FSFREEZE) @@ -1708,20 +1546,13 @@ int64_t qmp_guest_fsfreeze_freeze(Error **errp) return qmp_guest_fsfreeze_freeze_list(false, NULL, errp); } -/* - * Walk list of mounted file systems in the guest, and freeze the ones which - * are real local file systems. - */ int64_t qmp_guest_fsfreeze_freeze_list(bool has_mountpoints, strList *mountpoints, Error **errp) { - int ret = 0, i = 0; - strList *list; + int ret; FsMountList mounts; - struct FsMount *mount; Error *local_err = NULL; - int fd; slog("guest-fsfreeze called"); @@ -1740,122 +1571,34 @@ int64_t qmp_guest_fsfreeze_freeze_list(bool has_mountpoints, /* cannot risk guest agent blocking itself on a write in this state */ ga_set_frozen(ga_state); - QTAILQ_FOREACH_REVERSE(mount, &mounts, next) { - /* To issue fsfreeze in the reverse order of mounts, check if the - * mount is listed in the list here */ - if (has_mountpoints) { - for (list = mountpoints; list; list = list->next) { - if (strcmp(list->value, mount->dirname) == 0) { - break; - } - } - if (!list) { - continue; - } - } - - fd = qga_open_cloexec(mount->dirname, O_RDONLY, 0); - if (fd == -1) { - error_setg_errno(errp, errno, "failed to open %s", mount->dirname); - goto error; - } - - /* we try to cull filesystems we know won't work in advance, but other - * filesystems may not implement fsfreeze for less obvious reasons. - * these will report EOPNOTSUPP. we simply ignore these when tallying - * the number of frozen filesystems. - * if a filesystem is mounted more than once (aka bind mount) a - * consecutive attempt to freeze an already frozen filesystem will - * return EBUSY. - * - * any other error means a failure to freeze a filesystem we - * expect to be freezable, so return an error in those cases - * and return system to thawed state. - */ - ret = ioctl(fd, FIFREEZE); - if (ret == -1) { - if (errno != EOPNOTSUPP && errno != EBUSY) { - error_setg_errno(errp, errno, "failed to freeze %s", - mount->dirname); - close(fd); - goto error; - } - } else { - i++; - } - close(fd); - } + ret = qmp_guest_fsfreeze_do_freeze_list(has_mountpoints, mountpoints, + mounts, errp); free_fs_mount_list(&mounts); /* We may not issue any FIFREEZE here. * Just unset ga_state here and ready for the next call. */ - if (i == 0) { + if (ret == 0) { ga_unset_frozen(ga_state); + } else if (ret < 0) { + qmp_guest_fsfreeze_thaw(NULL); } - return i; - -error: - free_fs_mount_list(&mounts); - qmp_guest_fsfreeze_thaw(NULL); - return 0; + return ret; } -/* - * Walk list of frozen file systems in the guest, and thaw them. - */ int64_t qmp_guest_fsfreeze_thaw(Error **errp) { int ret; - FsMountList mounts; - FsMount *mount; - int fd, i = 0, logged; - Error *local_err = NULL; - QTAILQ_INIT(&mounts); - if (!build_fs_mount_list(&mounts, &local_err)) { - error_propagate(errp, local_err); - return 0; + ret = qmp_guest_fsfreeze_do_thaw(errp); + if (ret >= 0) { + ga_unset_frozen(ga_state); + execute_fsfreeze_hook(FSFREEZE_HOOK_THAW, errp); + } else { + ret = 0; } - QTAILQ_FOREACH(mount, &mounts, next) { - logged = false; - fd = qga_open_cloexec(mount->dirname, O_RDONLY, 0); - if (fd == -1) { - continue; - } - /* we have no way of knowing whether a filesystem was actually unfrozen - * as a result of a successful call to FITHAW, only that if an error - * was returned the filesystem was *not* unfrozen by that particular - * call. - * - * since multiple preceding FIFREEZEs require multiple calls to FITHAW - * to unfreeze, continuing issuing FITHAW until an error is returned, - * in which case either the filesystem is in an unfreezable state, or, - * more likely, it was thawed previously (and remains so afterward). - * - * also, since the most recent successful call is the one that did - * the actual unfreeze, we can use this to provide an accurate count - * of the number of filesystems unfrozen by guest-fsfreeze-thaw, which - * may * be useful for determining whether a filesystem was unfrozen - * during the freeze/thaw phase by a process other than qemu-ga. - */ - do { - ret = ioctl(fd, FITHAW); - if (ret == 0 && !logged) { - i++; - logged = true; - } - } while (ret == 0); - close(fd); - } - - ga_unset_frozen(ga_state); - free_fs_mount_list(&mounts); - - execute_fsfreeze_hook(FSFREEZE_HOOK_THAW, errp); - - return i; + return ret; } static void guest_fsfreeze_cleanup(void) diff --git a/qga/meson.build b/qga/meson.build index a0ffd6d268..932b4e7ca8 100644 --- a/qga/meson.build +++ b/qga/meson.build @@ -72,6 +72,9 @@ qga_ss.add(when: 'CONFIG_POSIX', if_true: files( 'commands-posix.c', 'commands-posix-ssh.c', )) +qga_ss.add(when: 'CONFIG_LINUX', if_true: files( + 'commands-linux.c', +)) qga_ss.add(when: 'CONFIG_WIN32', if_true: files( 'channel-win32.c', 'commands-win32.c', From bad0001eeb34484c4595c3862e14a4ee22a3abee Mon Sep 17 00:00:00 2001 From: Alexander Ivanov Date: Mon, 17 Oct 2022 09:28:21 +0200 Subject: [PATCH 156/705] qga: Add UFS freeze/thaw support for FreeBSD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit UFS supports FS freezing through ioctl UFSSUSPEND on /dev/ufssuspend. Frozen FS can be thawed by closing /dev/ufssuspend file descriptior. Use getmntinfo to get a list of mounted FS. Reviewed-by: Konstantin Kostiuk Reviewed-by: Marc-André Lureau Signed-off-by: Alexander Ivanov Signed-off-by: Konstantin Kostiuk --- qga/commands-bsd.c | 169 +++++++++++++++++++++++ qga/commands-common.h | 11 ++ qga/commands-posix.c | 308 ++++++++++++++++++++---------------------- qga/main.c | 7 +- qga/meson.build | 3 + 5 files changed, 334 insertions(+), 164 deletions(-) create mode 100644 qga/commands-bsd.c diff --git a/qga/commands-bsd.c b/qga/commands-bsd.c new file mode 100644 index 0000000000..ca06692179 --- /dev/null +++ b/qga/commands-bsd.c @@ -0,0 +1,169 @@ +/* + * QEMU Guest Agent BSD-specific command implementations + * + * Copyright (c) Virtuozzo International GmbH. + * + * Authors: + * Alexander Ivanov + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qga-qapi-commands.h" +#include "qapi/qmp/qerror.h" +#include "qapi/error.h" +#include "qemu/queue.h" +#include "commands-common.h" +#include +#include +#include +#include +#include + +#if defined(CONFIG_FSFREEZE) || defined(CONFIG_FSTRIM) +bool build_fs_mount_list(FsMountList *mounts, Error **errp) +{ + FsMount *mount; + struct statfs *mntbuf, *mntp; + struct stat statbuf; + int i, count, ret; + + count = getmntinfo(&mntbuf, MNT_NOWAIT); + if (count == 0) { + error_setg_errno(errp, errno, "getmntinfo failed"); + return false; + } + + for (i = 0; i < count; i++) { + mntp = &mntbuf[i]; + ret = stat(mntp->f_mntonname, &statbuf); + if (ret != 0) { + error_setg_errno(errp, errno, "stat failed on %s", + mntp->f_mntonname); + return false; + } + + mount = g_new0(FsMount, 1); + + mount->dirname = g_strdup(mntp->f_mntonname); + mount->devtype = g_strdup(mntp->f_fstypename); + mount->devmajor = major(mount->dev); + mount->devminor = minor(mount->dev); + mount->fsid = mntp->f_fsid; + mount->dev = statbuf.st_dev; + + QTAILQ_INSERT_TAIL(mounts, mount, next); + } + return true; +} +#endif /* CONFIG_FSFREEZE || CONFIG_FSTRIM */ + +#if defined(CONFIG_FSFREEZE) +static int ufssuspend_fd = -1; +static int ufssuspend_cnt; + +int64_t qmp_guest_fsfreeze_do_freeze_list(bool has_mountpoints, + strList *mountpoints, + FsMountList mounts, + Error **errp) +{ + int ret; + strList *list; + struct FsMount *mount; + + if (ufssuspend_fd != -1) { + error_setg(errp, "filesystems have already frozen"); + return -1; + } + + ufssuspend_cnt = 0; + ufssuspend_fd = qemu_open(_PATH_UFSSUSPEND, O_RDWR, errp); + if (ufssuspend_fd == -1) { + return -1; + } + + QTAILQ_FOREACH_REVERSE(mount, &mounts, next) { + /* + * To issue fsfreeze in the reverse order of mounts, check if the + * mount is listed in the list here + */ + if (has_mountpoints) { + for (list = mountpoints; list; list = list->next) { + if (g_str_equal(list->value, mount->dirname)) { + break; + } + } + if (!list) { + continue; + } + } + + /* Only UFS supports suspend */ + if (!g_str_equal(mount->devtype, "ufs")) { + continue; + } + + ret = ioctl(ufssuspend_fd, UFSSUSPEND, &mount->fsid); + if (ret == -1) { + /* + * ioctl returns EBUSY for all the FS except the first one + * that was suspended + */ + if (errno == EBUSY) { + continue; + } + error_setg_errno(errp, errno, "failed to freeze %s", + mount->dirname); + goto error; + } + ufssuspend_cnt++; + } + return ufssuspend_cnt; +error: + close(ufssuspend_fd); + ufssuspend_fd = -1; + return -1; + +} + +/* + * We don't need to call UFSRESUME ioctl because all the frozen FS + * are thawed on /dev/ufssuspend closing. + */ +int qmp_guest_fsfreeze_do_thaw(Error **errp) +{ + int ret = ufssuspend_cnt; + ufssuspend_cnt = 0; + if (ufssuspend_fd != -1) { + close(ufssuspend_fd); + ufssuspend_fd = -1; + } + return ret; +} + +GuestFilesystemInfoList *qmp_guest_get_fsinfo(Error **errp) +{ + error_setg(errp, QERR_UNSUPPORTED); + return NULL; +} + +GuestDiskInfoList *qmp_guest_get_disks(Error **errp) +{ + error_setg(errp, QERR_UNSUPPORTED); + return NULL; +} + +GuestDiskStatsInfoList *qmp_guest_get_diskstats(Error **errp) +{ + error_setg(errp, QERR_UNSUPPORTED); + return NULL; +} + +GuestCpuStatsList *qmp_guest_get_cpustats(Error **errp) +{ + error_setg(errp, QERR_UNSUPPORTED); + return NULL; +} +#endif /* CONFIG_FSFREEZE */ diff --git a/qga/commands-common.h b/qga/commands-common.h index cb51b1c6e9..d0583c6ddb 100644 --- a/qga/commands-common.h +++ b/qga/commands-common.h @@ -23,11 +23,22 @@ #endif #endif /* __linux__ */ +#ifdef __FreeBSD__ +#include +#ifdef UFSSUSPEND +#define CONFIG_FSFREEZE +#endif +#endif /* __FreeBSD__ */ + #if defined(CONFIG_FSFREEZE) || defined(CONFIG_FSTRIM) typedef struct FsMount { char *dirname; char *devtype; unsigned int devmajor, devminor; +#if defined(__FreeBSD__) + dev_t dev; + fsid_t fsid; +#endif QTAILQ_ENTRY(FsMount) next; } FsMount; diff --git a/qga/commands-posix.c b/qga/commands-posix.c index d24f2fafd8..6875ea8888 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -33,20 +33,12 @@ #if defined(__linux__) #include -#include #include #include #ifdef CONFIG_LIBUDEV #include #endif - -#ifdef FIFREEZE -#define CONFIG_FSFREEZE -#endif -#ifdef FITRIM -#define CONFIG_FSTRIM -#endif #endif #ifdef __FreeBSD__ @@ -623,9 +615,6 @@ void qmp_guest_file_flush(int64_t handle, Error **errp) } } -/* linux-specific implementations. avoid this if at all possible. */ -#if defined(__linux__) - #if defined(CONFIG_FSFREEZE) || defined(CONFIG_FSTRIM) void free_fs_mount_list(FsMountList *mounts) { @@ -644,6 +633,156 @@ void free_fs_mount_list(FsMountList *mounts) } #endif +#if defined(CONFIG_FSFREEZE) +typedef enum { + FSFREEZE_HOOK_THAW = 0, + FSFREEZE_HOOK_FREEZE, +} FsfreezeHookArg; + +static const char *fsfreeze_hook_arg_string[] = { + "thaw", + "freeze", +}; + +static void execute_fsfreeze_hook(FsfreezeHookArg arg, Error **errp) +{ + int status; + pid_t pid; + const char *hook; + const char *arg_str = fsfreeze_hook_arg_string[arg]; + Error *local_err = NULL; + + hook = ga_fsfreeze_hook(ga_state); + if (!hook) { + return; + } + if (access(hook, X_OK) != 0) { + error_setg_errno(errp, errno, "can't access fsfreeze hook '%s'", hook); + return; + } + + slog("executing fsfreeze hook with arg '%s'", arg_str); + pid = fork(); + if (pid == 0) { + setsid(); + reopen_fd_to_null(0); + reopen_fd_to_null(1); + reopen_fd_to_null(2); + + execl(hook, hook, arg_str, NULL); + _exit(EXIT_FAILURE); + } else if (pid < 0) { + error_setg_errno(errp, errno, "failed to create child process"); + return; + } + + ga_wait_child(pid, &status, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + if (!WIFEXITED(status)) { + error_setg(errp, "fsfreeze hook has terminated abnormally"); + return; + } + + status = WEXITSTATUS(status); + if (status) { + error_setg(errp, "fsfreeze hook has failed with status %d", status); + return; + } +} + +/* + * Return status of freeze/thaw + */ +GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **errp) +{ + if (ga_is_frozen(ga_state)) { + return GUEST_FSFREEZE_STATUS_FROZEN; + } + + return GUEST_FSFREEZE_STATUS_THAWED; +} + +int64_t qmp_guest_fsfreeze_freeze(Error **errp) +{ + return qmp_guest_fsfreeze_freeze_list(false, NULL, errp); +} + +int64_t qmp_guest_fsfreeze_freeze_list(bool has_mountpoints, + strList *mountpoints, + Error **errp) +{ + int ret; + FsMountList mounts; + Error *local_err = NULL; + + slog("guest-fsfreeze called"); + + execute_fsfreeze_hook(FSFREEZE_HOOK_FREEZE, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return -1; + } + + QTAILQ_INIT(&mounts); + if (!build_fs_mount_list(&mounts, &local_err)) { + error_propagate(errp, local_err); + return -1; + } + + /* cannot risk guest agent blocking itself on a write in this state */ + ga_set_frozen(ga_state); + + ret = qmp_guest_fsfreeze_do_freeze_list(has_mountpoints, mountpoints, + mounts, errp); + + free_fs_mount_list(&mounts); + /* We may not issue any FIFREEZE here. + * Just unset ga_state here and ready for the next call. + */ + if (ret == 0) { + ga_unset_frozen(ga_state); + } else if (ret < 0) { + qmp_guest_fsfreeze_thaw(NULL); + } + return ret; +} + +int64_t qmp_guest_fsfreeze_thaw(Error **errp) +{ + int ret; + + ret = qmp_guest_fsfreeze_do_thaw(errp); + if (ret >= 0) { + ga_unset_frozen(ga_state); + execute_fsfreeze_hook(FSFREEZE_HOOK_THAW, errp); + } else { + ret = 0; + } + + return ret; +} + +static void guest_fsfreeze_cleanup(void) +{ + Error *err = NULL; + + if (ga_is_frozen(ga_state) == GUEST_FSFREEZE_STATUS_FROZEN) { + qmp_guest_fsfreeze_thaw(&err); + if (err) { + slog("failed to clean up frozen filesystems: %s", + error_get_pretty(err)); + error_free(err); + } + } +} +#endif + +/* linux-specific implementations. avoid this if at all possible. */ +#if defined(__linux__) #if defined(CONFIG_FSFREEZE) static char *get_pci_driver(char const *syspath, int pathlen, Error **errp) @@ -1467,153 +1606,6 @@ GuestFilesystemInfoList *qmp_guest_get_fsinfo(Error **errp) free_fs_mount_list(&mounts); return ret; } - - -typedef enum { - FSFREEZE_HOOK_THAW = 0, - FSFREEZE_HOOK_FREEZE, -} FsfreezeHookArg; - -static const char *fsfreeze_hook_arg_string[] = { - "thaw", - "freeze", -}; - -static void execute_fsfreeze_hook(FsfreezeHookArg arg, Error **errp) -{ - int status; - pid_t pid; - const char *hook; - const char *arg_str = fsfreeze_hook_arg_string[arg]; - Error *local_err = NULL; - - hook = ga_fsfreeze_hook(ga_state); - if (!hook) { - return; - } - if (access(hook, X_OK) != 0) { - error_setg_errno(errp, errno, "can't access fsfreeze hook '%s'", hook); - return; - } - - slog("executing fsfreeze hook with arg '%s'", arg_str); - pid = fork(); - if (pid == 0) { - setsid(); - reopen_fd_to_null(0); - reopen_fd_to_null(1); - reopen_fd_to_null(2); - - execl(hook, hook, arg_str, NULL); - _exit(EXIT_FAILURE); - } else if (pid < 0) { - error_setg_errno(errp, errno, "failed to create child process"); - return; - } - - ga_wait_child(pid, &status, &local_err); - if (local_err) { - error_propagate(errp, local_err); - return; - } - - if (!WIFEXITED(status)) { - error_setg(errp, "fsfreeze hook has terminated abnormally"); - return; - } - - status = WEXITSTATUS(status); - if (status) { - error_setg(errp, "fsfreeze hook has failed with status %d", status); - return; - } -} - -/* - * Return status of freeze/thaw - */ -GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **errp) -{ - if (ga_is_frozen(ga_state)) { - return GUEST_FSFREEZE_STATUS_FROZEN; - } - - return GUEST_FSFREEZE_STATUS_THAWED; -} - -int64_t qmp_guest_fsfreeze_freeze(Error **errp) -{ - return qmp_guest_fsfreeze_freeze_list(false, NULL, errp); -} - -int64_t qmp_guest_fsfreeze_freeze_list(bool has_mountpoints, - strList *mountpoints, - Error **errp) -{ - int ret; - FsMountList mounts; - Error *local_err = NULL; - - slog("guest-fsfreeze called"); - - execute_fsfreeze_hook(FSFREEZE_HOOK_FREEZE, &local_err); - if (local_err) { - error_propagate(errp, local_err); - return -1; - } - - QTAILQ_INIT(&mounts); - if (!build_fs_mount_list(&mounts, &local_err)) { - error_propagate(errp, local_err); - return -1; - } - - /* cannot risk guest agent blocking itself on a write in this state */ - ga_set_frozen(ga_state); - - ret = qmp_guest_fsfreeze_do_freeze_list(has_mountpoints, mountpoints, - mounts, errp); - - free_fs_mount_list(&mounts); - /* We may not issue any FIFREEZE here. - * Just unset ga_state here and ready for the next call. - */ - if (ret == 0) { - ga_unset_frozen(ga_state); - } else if (ret < 0) { - qmp_guest_fsfreeze_thaw(NULL); - } - return ret; -} - -int64_t qmp_guest_fsfreeze_thaw(Error **errp) -{ - int ret; - - ret = qmp_guest_fsfreeze_do_thaw(errp); - if (ret >= 0) { - ga_unset_frozen(ga_state); - execute_fsfreeze_hook(FSFREEZE_HOOK_THAW, errp); - } else { - ret = 0; - } - - return ret; -} - -static void guest_fsfreeze_cleanup(void) -{ - Error *err = NULL; - - if (ga_is_frozen(ga_state) == GUEST_FSFREEZE_STATUS_FROZEN) { - qmp_guest_fsfreeze_thaw(&err); - if (err) { - slog("failed to clean up frozen filesystems: %s", - error_get_pretty(err)); - error_free(err); - } - } -} #endif /* CONFIG_FSFREEZE */ #if defined(CONFIG_FSTRIM) diff --git a/qga/main.c b/qga/main.c index 0d27c97d38..b3580508fa 100644 --- a/qga/main.c +++ b/qga/main.c @@ -37,12 +37,7 @@ #include "qga/service-win32.h" #include "qga/vss-win32.h" #endif -#ifdef __linux__ -#include -#ifdef FIFREEZE -#define CONFIG_FSFREEZE -#endif -#endif +#include "commands-common.h" #ifndef _WIN32 #ifdef __FreeBSD__ diff --git a/qga/meson.build b/qga/meson.build index 932b4e7ca8..3cfb9166e5 100644 --- a/qga/meson.build +++ b/qga/meson.build @@ -75,6 +75,9 @@ qga_ss.add(when: 'CONFIG_POSIX', if_true: files( qga_ss.add(when: 'CONFIG_LINUX', if_true: files( 'commands-linux.c', )) +qga_ss.add(when: 'CONFIG_BSD', if_true: files( + 'commands-bsd.c', +)) qga_ss.add(when: 'CONFIG_WIN32', if_true: files( 'channel-win32.c', 'commands-win32.c', From e40762fcd6266450778f615e73d218e4100147b7 Mon Sep 17 00:00:00 2001 From: Alexander Ivanov Date: Mon, 17 Oct 2022 09:28:22 +0200 Subject: [PATCH 157/705] qga: Add shutdown/halt/reboot support for FreeBSD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add appropriate shutdown command arguments to qmp_guest_shutdown() for FreeBSD. Reviewed-by: Konstantin Kostiuk Reviewed-by: Marc-André Lureau Signed-off-by: Alexander Ivanov Signed-off-by: Konstantin Kostiuk --- qga/commands-posix.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/qga/commands-posix.c b/qga/commands-posix.c index 6875ea8888..b0b467ebdb 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -90,6 +90,10 @@ void qmp_guest_shutdown(bool has_mode, const char *mode, Error **errp) const char *powerdown_flag = "-i5"; const char *halt_flag = "-i0"; const char *reboot_flag = "-i6"; +#elif defined(CONFIG_BSD) + const char *powerdown_flag = "-p"; + const char *halt_flag = "-h"; + const char *reboot_flag = "-r"; #else const char *powerdown_flag = "-P"; const char *halt_flag = "-H"; @@ -120,6 +124,9 @@ void qmp_guest_shutdown(bool has_mode, const char *mode, Error **errp) #ifdef CONFIG_SOLARIS execl("/sbin/shutdown", "shutdown", shutdown_flag, "-g0", "-y", "hypervisor initiated shutdown", (char *)NULL); +#elif defined(CONFIG_BSD) + execl("/sbin/shutdown", "shutdown", shutdown_flag, "+0", + "hypervisor initiated shutdown", (char *)NULL); #else execl("/sbin/shutdown", "shutdown", "-h", shutdown_flag, "+0", "hypervisor initiated shutdown", (char *)NULL); From 4fd0642e84e2dc25033090cad73f1ef1904e1600 Mon Sep 17 00:00:00 2001 From: Alexander Ivanov Date: Mon, 17 Oct 2022 09:28:23 +0200 Subject: [PATCH 158/705] qga: Add support for user password setting in FreeBSD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move qmp_guest_set_user_password() from __linux__ condition to (__linux__ || __FreeBSD__) condition. Add command and arguments for password setting in FreeBSD. Reviewed-by: Konstantin Kostiuk Reviewed-by: Marc-André Lureau Signed-off-by: Alexander Ivanov Signed-off-by: Konstantin Kostiuk --- qga/commands-posix.c | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/qga/commands-posix.c b/qga/commands-posix.c index b0b467ebdb..e0ee0bea00 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -2122,7 +2122,9 @@ int64_t qmp_guest_set_vcpus(GuestLogicalProcessorList *vcpus, Error **errp) return processed; } +#endif /* __linux__ */ +#if defined(__linux__) || defined(__FreeBSD__) void qmp_guest_set_user_password(const char *username, const char *password, bool crypted, @@ -2156,10 +2158,15 @@ void qmp_guest_set_user_password(const char *username, goto out; } +#ifdef __FreeBSD__ + chpasswddata = g_strdup(rawpasswddata); + passwd_path = g_find_program_in_path("pw"); +#else chpasswddata = g_strdup_printf("%s:%s\n", username, rawpasswddata); - chpasswdlen = strlen(chpasswddata); - passwd_path = g_find_program_in_path("chpasswd"); +#endif + + chpasswdlen = strlen(chpasswddata); if (!passwd_path) { error_setg(errp, "cannot find 'passwd' program in PATH"); @@ -2180,11 +2187,17 @@ void qmp_guest_set_user_password(const char *username, reopen_fd_to_null(1); reopen_fd_to_null(2); +#ifdef __FreeBSD__ + const char *h_arg; + h_arg = (crypted) ? "-H" : "-h"; + execl(passwd_path, "pw", "usermod", "-n", username, h_arg, "0", NULL); +#else if (crypted) { execl(passwd_path, "chpasswd", "-e", NULL); } else { execl(passwd_path, "chpasswd", NULL); } +#endif _exit(EXIT_FAILURE); } else if (pid < 0) { error_setg_errno(errp, errno, "failed to create child process"); @@ -2227,7 +2240,17 @@ out: close(datafd[1]); } } +#else /* __linux__ || __FreeBSD__ */ +void qmp_guest_set_user_password(const char *username, + const char *password, + bool crypted, + Error **errp) +{ + error_setg(errp, QERR_UNSUPPORTED); +} +#endif /* __linux__ || __FreeBSD__ */ +#ifdef __linux__ static void ga_read_sysfs_file(int dirfd, const char *pathname, char *buf, int size, Error **errp) { @@ -2764,14 +2787,6 @@ int64_t qmp_guest_set_vcpus(GuestLogicalProcessorList *vcpus, Error **errp) return -1; } -void qmp_guest_set_user_password(const char *username, - const char *password, - bool crypted, - Error **errp) -{ - error_setg(errp, QERR_UNSUPPORTED); -} - GuestMemoryBlockList *qmp_guest_get_memory_blocks(Error **errp) { error_setg(errp, QERR_UNSUPPORTED); From a1241094223d69d72bebc5ed7a5f6f57cbc7986c Mon Sep 17 00:00:00 2001 From: Alexander Ivanov Date: Mon, 17 Oct 2022 09:28:24 +0200 Subject: [PATCH 159/705] qga: Move HW address getting to a separate function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the next patch FreeBSD support for guest-network-get-interfaces will be added. Previously move Linux-specific code of HW address getting to a separate functions and add a dumb function to commands-bsd.c. Reviewed-by: Konstantin Kostiuk Reviewed-by: Marc-André Lureau Signed-off-by: Alexander Ivanov Signed-off-by: Konstantin Kostiuk --- qga/commands-bsd.c | 16 +++++++ qga/commands-common.h | 6 +++ qga/commands-posix.c | 98 ++++++++++++++++++++++++------------------- 3 files changed, 78 insertions(+), 42 deletions(-) diff --git a/qga/commands-bsd.c b/qga/commands-bsd.c index ca06692179..ebf0fb8b0f 100644 --- a/qga/commands-bsd.c +++ b/qga/commands-bsd.c @@ -167,3 +167,19 @@ GuestCpuStatsList *qmp_guest_get_cpustats(Error **errp) return NULL; } #endif /* CONFIG_FSFREEZE */ + +#ifdef HAVE_GETIFADDRS +/* + * Fill "buf" with MAC address by ifaddrs. Pointer buf must point to a + * buffer with ETHER_ADDR_LEN length at least. + * + * Returns false in case of an error, otherwise true. "obtained" arguument + * is true if a MAC address was obtained successful, otherwise false. + */ +bool guest_get_hw_addr(struct ifaddrs *ifa, unsigned char *buf, + bool *obtained, Error **errp) +{ + *obtained = false; + return true; +} +#endif /* HAVE_GETIFADDRS */ diff --git a/qga/commands-common.h b/qga/commands-common.h index d0583c6ddb..8c1c56aac9 100644 --- a/qga/commands-common.h +++ b/qga/commands-common.h @@ -56,6 +56,12 @@ int64_t qmp_guest_fsfreeze_do_freeze_list(bool has_mountpoints, int qmp_guest_fsfreeze_do_thaw(Error **errp); #endif /* CONFIG_FSFREEZE */ +#ifdef HAVE_GETIFADDRS +#include +bool guest_get_hw_addr(struct ifaddrs *ifa, unsigned char *buf, + bool *obtained, Error **errp); +#endif + typedef struct GuestFileHandle GuestFileHandle; GuestFileHandle *guest_file_handle_find(int64_t id, Error **errp); diff --git a/qga/commands-posix.c b/qga/commands-posix.c index e0ee0bea00..32493d6383 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -41,20 +41,12 @@ #endif #endif -#ifdef __FreeBSD__ -/* - * The code under HAVE_GETIFADDRS condition can't be compiled in FreeBSD. - * Fix it in one of the following patches. - */ -#undef HAVE_GETIFADDRS -#endif - #ifdef HAVE_GETIFADDRS #include #include #include +#include #include -#include #ifdef CONFIG_SOLARIS #include #endif @@ -2889,6 +2881,57 @@ static int guest_get_network_stats(const char *name, return -1; } +#ifndef __FreeBSD__ +/* + * Fill "buf" with MAC address by ifaddrs. Pointer buf must point to a + * buffer with ETHER_ADDR_LEN length at least. + * + * Returns false in case of an error, otherwise true. "obtained" argument + * is true if a MAC address was obtained successful, otherwise false. + */ +bool guest_get_hw_addr(struct ifaddrs *ifa, unsigned char *buf, + bool *obtained, Error **errp) +{ + struct ifreq ifr; + int sock; + + *obtained = false; + + /* we haven't obtained HW address yet */ + sock = socket(PF_INET, SOCK_STREAM, 0); + if (sock == -1) { + error_setg_errno(errp, errno, "failed to create socket"); + return false; + } + + memset(&ifr, 0, sizeof(ifr)); + pstrcpy(ifr.ifr_name, IF_NAMESIZE, ifa->ifa_name); + if (ioctl(sock, SIOCGIFHWADDR, &ifr) == -1) { + /* + * We can't get the hw addr of this interface, but that's not a + * fatal error. + */ + if (errno == EADDRNOTAVAIL) { + /* The interface doesn't have a hw addr (e.g. loopback). */ + g_debug("failed to get MAC address of %s: %s", + ifa->ifa_name, strerror(errno)); + } else{ + g_warning("failed to get MAC address of %s: %s", + ifa->ifa_name, strerror(errno)); + } + } else { +#ifdef CONFIG_SOLARIS + memcpy(buf, &ifr.ifr_addr.sa_data, ETHER_ADDR_LEN); +#else + memcpy(buf, &ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN); +#endif + *obtained = true; + } + close(sock); + return true; +} +#endif /* __FreeBSD__ */ + /* * Build information about guest interfaces */ @@ -2909,9 +2952,8 @@ GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp) GuestNetworkInterfaceStat *interface_stat = NULL; char addr4[INET_ADDRSTRLEN]; char addr6[INET6_ADDRSTRLEN]; - int sock; - struct ifreq ifr; - unsigned char *mac_addr; + unsigned char mac_addr[ETHER_ADDR_LEN]; + bool obtained; void *p; g_debug("Processing %s interface", ifa->ifa_name); @@ -2926,45 +2968,17 @@ GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp) } if (!info->has_hardware_address) { - /* we haven't obtained HW address yet */ - sock = socket(PF_INET, SOCK_STREAM, 0); - if (sock == -1) { - error_setg_errno(errp, errno, "failed to create socket"); + if (!guest_get_hw_addr(ifa, mac_addr, &obtained, errp)) { goto error; } - - memset(&ifr, 0, sizeof(ifr)); - pstrcpy(ifr.ifr_name, IF_NAMESIZE, info->name); - if (ioctl(sock, SIOCGIFHWADDR, &ifr) == -1) { - /* - * We can't get the hw addr of this interface, but that's not a - * fatal error. Don't set info->hardware_address, but keep - * going. - */ - if (errno == EADDRNOTAVAIL) { - /* The interface doesn't have a hw addr (e.g. loopback). */ - g_debug("failed to get MAC address of %s: %s", - ifa->ifa_name, strerror(errno)); - } else{ - g_warning("failed to get MAC address of %s: %s", - ifa->ifa_name, strerror(errno)); - } - - } else { -#ifdef CONFIG_SOLARIS - mac_addr = (unsigned char *) &ifr.ifr_addr.sa_data; -#else - mac_addr = (unsigned char *) &ifr.ifr_hwaddr.sa_data; -#endif + if (obtained) { info->hardware_address = g_strdup_printf("%02x:%02x:%02x:%02x:%02x:%02x", (int) mac_addr[0], (int) mac_addr[1], (int) mac_addr[2], (int) mac_addr[3], (int) mac_addr[4], (int) mac_addr[5]); - info->has_hardware_address = true; } - close(sock); } if (ifa->ifa_addr && From ffb01cc5d6698855103d57281ddfe94b1f3fa3d4 Mon Sep 17 00:00:00 2001 From: Alexander Ivanov Date: Mon, 17 Oct 2022 09:28:25 +0200 Subject: [PATCH 160/705] qga: Add HW address getting for FreeBSD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace a dumb function in commands-bsd.c by the code of HW address getting. Reviewed-by: Konstantin Kostiuk Reviewed-by: Marc-André Lureau Signed-off-by: Alexander Ivanov Signed-off-by: Konstantin Kostiuk --- qga/commands-bsd.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/qga/commands-bsd.c b/qga/commands-bsd.c index ebf0fb8b0f..15cade2d4c 100644 --- a/qga/commands-bsd.c +++ b/qga/commands-bsd.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #if defined(CONFIG_FSFREEZE) || defined(CONFIG_FSTRIM) @@ -179,7 +181,20 @@ GuestCpuStatsList *qmp_guest_get_cpustats(Error **errp) bool guest_get_hw_addr(struct ifaddrs *ifa, unsigned char *buf, bool *obtained, Error **errp) { + struct sockaddr_dl *sdp; + *obtained = false; + + if (ifa->ifa_addr->sa_family != AF_LINK) { + /* We can get HW address only for AF_LINK family. */ + g_debug("failed to get MAC address of %s", ifa->ifa_name); + return true; + } + + sdp = (struct sockaddr_dl *)ifa->ifa_addr; + memcpy(buf, sdp->sdl_data + sdp->sdl_nlen, ETHER_ADDR_LEN); + *obtained = true; + return true; } #endif /* HAVE_GETIFADDRS */ From 3845ffff8b783680d12a005b493c0959a995f800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Forsman?= Date: Fri, 21 Oct 2022 00:03:46 +0200 Subject: [PATCH 161/705] qga: add channel path to error messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's useful to know which device was used if/when it fails. channel-win32.c had this since 2015, with c69403fcd4a0cb89f838a212ab71e4a1a3464c95 ("qemu-ga: debug printouts to help troubleshoot installation"), this brings channel-posix.c up to speed. Signed-off-by: Bjørn Forsman Reviewed-by: Konstantin Kostiuk Signed-off-by: Konstantin Kostiuk --- qga/channel-posix.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qga/channel-posix.c b/qga/channel-posix.c index 568350ded4..0c5175d957 100644 --- a/qga/channel-posix.c +++ b/qga/channel-posix.c @@ -138,7 +138,7 @@ static gboolean ga_channel_open(GAChannel *c, const gchar *path, 0 ); if (fd == -1) { - error_setg_errno(errp, errno, "error opening channel"); + error_setg_errno(errp, errno, "error opening channel '%s'", path); return false; } #ifdef CONFIG_SOLARIS @@ -182,7 +182,7 @@ static gboolean ga_channel_open(GAChannel *c, const gchar *path, assert(fd < 0); fd = qga_open_cloexec(path, O_RDWR | O_NOCTTY | O_NONBLOCK, 0); if (fd == -1) { - error_setg_errno(errp, errno, "error opening channel"); + error_setg_errno(errp, errno, "error opening channel '%s'", path); return false; } tcgetattr(fd, &tio); From 0421b563ab4d947a388078331c057daa9b979f41 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Thu, 13 Oct 2022 14:58:56 -0400 Subject: [PATCH 162/705] coroutine: add flag to re-queue at front of CoQueue When a coroutine wakes up it may determine that it must re-queue. Normally coroutines are pushed onto the back of the CoQueue, but for fairness it may be necessary to push it onto the front of the CoQueue. Add a flag to specify that the coroutine should be pushed onto the front of the CoQueue. A later patch will use this to ensure fairness in the bounce buffer CoQueue used by the blkio BlockDriver. Signed-off-by: Stefan Hajnoczi Message-id: 20221013185908.1297568-2-stefanha@redhat.com Signed-off-by: Stefan Hajnoczi --- include/qemu/coroutine.h | 15 +++++++++++++-- util/qemu-coroutine-lock.c | 9 +++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h index aae33cce17..608fe45dcf 100644 --- a/include/qemu/coroutine.h +++ b/include/qemu/coroutine.h @@ -198,14 +198,25 @@ typedef struct CoQueue { */ void qemu_co_queue_init(CoQueue *queue); +typedef enum { + /* + * Enqueue at front instead of back. Use this to re-queue a request when + * its wait condition is not satisfied after being woken up. + */ + CO_QUEUE_WAIT_FRONT = 0x1, +} CoQueueWaitFlags; + /** * Adds the current coroutine to the CoQueue and transfers control to the * caller of the coroutine. The mutex is unlocked during the wait and * locked again afterwards. */ #define qemu_co_queue_wait(queue, lock) \ - qemu_co_queue_wait_impl(queue, QEMU_MAKE_LOCKABLE(lock)) -void coroutine_fn qemu_co_queue_wait_impl(CoQueue *queue, QemuLockable *lock); + qemu_co_queue_wait_impl(queue, QEMU_MAKE_LOCKABLE(lock), 0) +#define qemu_co_queue_wait_flags(queue, lock, flags) \ + qemu_co_queue_wait_impl(queue, QEMU_MAKE_LOCKABLE(lock), (flags)) +void coroutine_fn qemu_co_queue_wait_impl(CoQueue *queue, QemuLockable *lock, + CoQueueWaitFlags flags); /** * Removes the next coroutine from the CoQueue, and queue it to run after diff --git a/util/qemu-coroutine-lock.c b/util/qemu-coroutine-lock.c index 15c82d9348..45c6b57374 100644 --- a/util/qemu-coroutine-lock.c +++ b/util/qemu-coroutine-lock.c @@ -39,10 +39,15 @@ void qemu_co_queue_init(CoQueue *queue) QSIMPLEQ_INIT(&queue->entries); } -void coroutine_fn qemu_co_queue_wait_impl(CoQueue *queue, QemuLockable *lock) +void coroutine_fn qemu_co_queue_wait_impl(CoQueue *queue, QemuLockable *lock, + CoQueueWaitFlags flags) { Coroutine *self = qemu_coroutine_self(); - QSIMPLEQ_INSERT_TAIL(&queue->entries, self, co_queue_next); + if (flags & CO_QUEUE_WAIT_FRONT) { + QSIMPLEQ_INSERT_HEAD(&queue->entries, self, co_queue_next); + } else { + QSIMPLEQ_INSERT_TAIL(&queue->entries, self, co_queue_next); + } if (lock) { qemu_lockable_unlock(lock); From fd66dbd424f5c90fcff3d27afed2c6c59d8be3ac Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Thu, 13 Oct 2022 14:58:57 -0400 Subject: [PATCH 163/705] blkio: add libblkio block driver libblkio (https://gitlab.com/libblkio/libblkio/) is a library for high-performance disk I/O. It currently supports io_uring, virtio-blk-vhost-user, and virtio-blk-vhost-vdpa with additional drivers under development. One of the reasons for developing libblkio is that other applications besides QEMU can use it. This will be particularly useful for virtio-blk-vhost-user which applications may wish to use for connecting to qemu-storage-daemon. libblkio also gives us an opportunity to develop in Rust behind a C API that is easy to consume from QEMU. This commit adds io_uring, nvme-io_uring, virtio-blk-vhost-user, and virtio-blk-vhost-vdpa BlockDrivers to QEMU using libblkio. It will be easy to add other libblkio drivers since they will share the majority of code. For now I/O buffers are copied through bounce buffers if the libblkio driver requires it. Later commits add an optimization for pre-registering guest RAM to avoid bounce buffers. The syntax is: --blockdev io_uring,node-name=drive0,filename=test.img,readonly=on|off,cache.direct=on|off --blockdev nvme-io_uring,node-name=drive0,filename=/dev/ng0n1,readonly=on|off,cache.direct=on --blockdev virtio-blk-vhost-vdpa,node-name=drive0,path=/dev/vdpa...,readonly=on|off,cache.direct=on --blockdev virtio-blk-vhost-user,node-name=drive0,path=vhost-user-blk.sock,readonly=on|off,cache.direct=on Signed-off-by: Stefan Hajnoczi Acked-by: Markus Armbruster Reviewed-by: Stefano Garzarella Message-id: 20221013185908.1297568-3-stefanha@redhat.com Signed-off-by: Stefan Hajnoczi --- MAINTAINERS | 6 + block/blkio.c | 831 ++++++++++++++++++++++++++++++++++ block/meson.build | 1 + meson.build | 9 + meson_options.txt | 2 + qapi/block-core.json | 77 +++- scripts/meson-buildoptions.sh | 3 + tests/qtest/modules-test.c | 3 + 8 files changed, 928 insertions(+), 4 deletions(-) create mode 100644 block/blkio.c diff --git a/MAINTAINERS b/MAINTAINERS index e3d5b7e09c..8b4363c0ff 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3415,6 +3415,12 @@ L: qemu-block@nongnu.org S: Maintained F: block/vdi.c +blkio +M: Stefan Hajnoczi +L: qemu-block@nongnu.org +S: Maintained +F: block/blkio.c + iSCSI M: Ronnie Sahlberg M: Paolo Bonzini diff --git a/block/blkio.c b/block/blkio.c new file mode 100644 index 0000000000..b0cfd74b36 --- /dev/null +++ b/block/blkio.c @@ -0,0 +1,831 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * libblkio BlockDriver + * + * Copyright Red Hat, Inc. + * + * Author: + * Stefan Hajnoczi + */ + +#include "qemu/osdep.h" +#include +#include "block/block_int.h" +#include "qapi/error.h" +#include "qapi/qmp/qdict.h" +#include "qemu/module.h" + +/* + * Keep the QEMU BlockDriver names identical to the libblkio driver names. + * Using macros instead of typing out the string literals avoids typos. + */ +#define DRIVER_IO_URING "io_uring" +#define DRIVER_NVME_IO_URING "nvme-io_uring" +#define DRIVER_VIRTIO_BLK_VHOST_USER "virtio-blk-vhost-user" +#define DRIVER_VIRTIO_BLK_VHOST_VDPA "virtio-blk-vhost-vdpa" + +/* + * Allocated bounce buffers are kept in a list sorted by buffer address. + */ +typedef struct BlkioBounceBuf { + QLIST_ENTRY(BlkioBounceBuf) next; + + /* The bounce buffer */ + struct iovec buf; +} BlkioBounceBuf; + +typedef struct { + /* + * libblkio is not thread-safe so this lock protects ->blkio and + * ->blkioq. + */ + QemuMutex blkio_lock; + struct blkio *blkio; + struct blkioq *blkioq; /* make this multi-queue in the future... */ + int completion_fd; + + /* + * Polling fetches the next completion into this field. + * + * No lock is necessary since only one thread calls aio_poll() and invokes + * fd and poll handlers. + */ + struct blkio_completion poll_completion; + + /* + * Protects ->bounce_pool, ->bounce_bufs, ->bounce_available. + * + * Lock ordering: ->bounce_lock before ->blkio_lock. + */ + CoMutex bounce_lock; + + /* Bounce buffer pool */ + struct blkio_mem_region bounce_pool; + + /* Sorted list of allocated bounce buffers */ + QLIST_HEAD(, BlkioBounceBuf) bounce_bufs; + + /* Queue for coroutines waiting for bounce buffer space */ + CoQueue bounce_available; + + /* The value of the "mem-region-alignment" property */ + size_t mem_region_alignment; + + /* Can we skip adding/deleting blkio_mem_regions? */ + bool needs_mem_regions; +} BDRVBlkioState; + +/* Called with s->bounce_lock held */ +static int blkio_resize_bounce_pool(BDRVBlkioState *s, int64_t bytes) +{ + /* There can be no allocated bounce buffers during resize */ + assert(QLIST_EMPTY(&s->bounce_bufs)); + + /* Pad size to reduce frequency of resize calls */ + bytes += 128 * 1024; + + WITH_QEMU_LOCK_GUARD(&s->blkio_lock) { + int ret; + + if (s->bounce_pool.addr) { + blkio_unmap_mem_region(s->blkio, &s->bounce_pool); + blkio_free_mem_region(s->blkio, &s->bounce_pool); + memset(&s->bounce_pool, 0, sizeof(s->bounce_pool)); + } + + /* Automatically freed when s->blkio is destroyed */ + ret = blkio_alloc_mem_region(s->blkio, &s->bounce_pool, bytes); + if (ret < 0) { + return ret; + } + + ret = blkio_map_mem_region(s->blkio, &s->bounce_pool); + if (ret < 0) { + blkio_free_mem_region(s->blkio, &s->bounce_pool); + memset(&s->bounce_pool, 0, sizeof(s->bounce_pool)); + return ret; + } + } + + return 0; +} + +/* Called with s->bounce_lock held */ +static bool +blkio_do_alloc_bounce_buffer(BDRVBlkioState *s, BlkioBounceBuf *bounce, + int64_t bytes) +{ + void *addr = s->bounce_pool.addr; + BlkioBounceBuf *cur = NULL; + BlkioBounceBuf *prev = NULL; + ptrdiff_t space; + + /* + * This is just a linear search over the holes between requests. An + * efficient allocator would be nice. + */ + QLIST_FOREACH(cur, &s->bounce_bufs, next) { + space = cur->buf.iov_base - addr; + if (bytes <= space) { + QLIST_INSERT_BEFORE(cur, bounce, next); + bounce->buf.iov_base = addr; + bounce->buf.iov_len = bytes; + return true; + } + + addr = cur->buf.iov_base + cur->buf.iov_len; + prev = cur; + } + + /* Is there space after the last request? */ + space = s->bounce_pool.addr + s->bounce_pool.len - addr; + if (bytes > space) { + return false; + } + if (prev) { + QLIST_INSERT_AFTER(prev, bounce, next); + } else { + QLIST_INSERT_HEAD(&s->bounce_bufs, bounce, next); + } + bounce->buf.iov_base = addr; + bounce->buf.iov_len = bytes; + return true; +} + +static int coroutine_fn +blkio_alloc_bounce_buffer(BDRVBlkioState *s, BlkioBounceBuf *bounce, + int64_t bytes) +{ + /* + * Ensure fairness: first time around we join the back of the queue, + * subsequently we join the front so we don't lose our place. + */ + CoQueueWaitFlags wait_flags = 0; + + QEMU_LOCK_GUARD(&s->bounce_lock); + + /* Ensure fairness: don't even try if other requests are already waiting */ + if (!qemu_co_queue_empty(&s->bounce_available)) { + qemu_co_queue_wait_flags(&s->bounce_available, &s->bounce_lock, + wait_flags); + wait_flags = CO_QUEUE_WAIT_FRONT; + } + + while (true) { + if (blkio_do_alloc_bounce_buffer(s, bounce, bytes)) { + /* Kick the next queued request since there may be space */ + qemu_co_queue_next(&s->bounce_available); + return 0; + } + + /* + * If there are no in-flight requests then the pool was simply too + * small. + */ + if (QLIST_EMPTY(&s->bounce_bufs)) { + bool ok; + int ret; + + ret = blkio_resize_bounce_pool(s, bytes); + if (ret < 0) { + /* Kick the next queued request since that may fail too */ + qemu_co_queue_next(&s->bounce_available); + return ret; + } + + ok = blkio_do_alloc_bounce_buffer(s, bounce, bytes); + assert(ok); /* must have space this time */ + return 0; + } + + qemu_co_queue_wait_flags(&s->bounce_available, &s->bounce_lock, + wait_flags); + wait_flags = CO_QUEUE_WAIT_FRONT; + } +} + +static void coroutine_fn blkio_free_bounce_buffer(BDRVBlkioState *s, + BlkioBounceBuf *bounce) +{ + QEMU_LOCK_GUARD(&s->bounce_lock); + + QLIST_REMOVE(bounce, next); + + /* Wake up waiting coroutines since space may now be available */ + qemu_co_queue_next(&s->bounce_available); +} + +/* For async to .bdrv_co_*() conversion */ +typedef struct { + Coroutine *coroutine; + int ret; +} BlkioCoData; + +static void blkio_completion_fd_read(void *opaque) +{ + BlockDriverState *bs = opaque; + BDRVBlkioState *s = bs->opaque; + uint64_t val; + int ret; + + /* Polling may have already fetched a completion */ + if (s->poll_completion.user_data != NULL) { + BlkioCoData *cod = s->poll_completion.user_data; + cod->ret = s->poll_completion.ret; + + /* Clear it in case aio_co_wake() enters a nested event loop */ + s->poll_completion.user_data = NULL; + + aio_co_wake(cod->coroutine); + } + + /* Reset completion fd status */ + ret = read(s->completion_fd, &val, sizeof(val)); + + /* Ignore errors, there's nothing we can do */ + (void)ret; + + /* + * Reading one completion at a time makes nested event loop re-entrancy + * simple. Change this loop to get multiple completions in one go if it + * becomes a performance bottleneck. + */ + while (true) { + struct blkio_completion completion; + + WITH_QEMU_LOCK_GUARD(&s->blkio_lock) { + ret = blkioq_do_io(s->blkioq, &completion, 0, 1, NULL); + } + if (ret != 1) { + break; + } + + BlkioCoData *cod = completion.user_data; + cod->ret = completion.ret; + aio_co_wake(cod->coroutine); + } +} + +static bool blkio_completion_fd_poll(void *opaque) +{ + BlockDriverState *bs = opaque; + BDRVBlkioState *s = bs->opaque; + int ret; + + /* Just in case we already fetched a completion */ + if (s->poll_completion.user_data != NULL) { + return true; + } + + WITH_QEMU_LOCK_GUARD(&s->blkio_lock) { + ret = blkioq_do_io(s->blkioq, &s->poll_completion, 0, 1, NULL); + } + return ret == 1; +} + +static void blkio_completion_fd_poll_ready(void *opaque) +{ + blkio_completion_fd_read(opaque); +} + +static void blkio_attach_aio_context(BlockDriverState *bs, + AioContext *new_context) +{ + BDRVBlkioState *s = bs->opaque; + + aio_set_fd_handler(new_context, + s->completion_fd, + false, + blkio_completion_fd_read, + NULL, + blkio_completion_fd_poll, + blkio_completion_fd_poll_ready, + bs); +} + +static void blkio_detach_aio_context(BlockDriverState *bs) +{ + BDRVBlkioState *s = bs->opaque; + + aio_set_fd_handler(bdrv_get_aio_context(bs), + s->completion_fd, + false, NULL, NULL, NULL, NULL, NULL); +} + +/* Call with s->blkio_lock held to submit I/O after enqueuing a new request */ +static void blkio_submit_io(BlockDriverState *bs) +{ + if (qatomic_read(&bs->io_plugged) == 0) { + BDRVBlkioState *s = bs->opaque; + + blkioq_do_io(s->blkioq, NULL, 0, 0, NULL); + } +} + +static int coroutine_fn +blkio_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes) +{ + BDRVBlkioState *s = bs->opaque; + BlkioCoData cod = { + .coroutine = qemu_coroutine_self(), + }; + + WITH_QEMU_LOCK_GUARD(&s->blkio_lock) { + blkioq_discard(s->blkioq, offset, bytes, &cod, 0); + blkio_submit_io(bs); + } + + qemu_coroutine_yield(); + return cod.ret; +} + +static int coroutine_fn +blkio_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, + QEMUIOVector *qiov, BdrvRequestFlags flags) +{ + BlkioCoData cod = { + .coroutine = qemu_coroutine_self(), + }; + BDRVBlkioState *s = bs->opaque; + bool use_bounce_buffer = s->needs_mem_regions; + BlkioBounceBuf bounce; + struct iovec *iov = qiov->iov; + int iovcnt = qiov->niov; + + if (use_bounce_buffer) { + int ret = blkio_alloc_bounce_buffer(s, &bounce, bytes); + if (ret < 0) { + return ret; + } + + iov = &bounce.buf; + iovcnt = 1; + } + + WITH_QEMU_LOCK_GUARD(&s->blkio_lock) { + blkioq_readv(s->blkioq, offset, iov, iovcnt, &cod, 0); + blkio_submit_io(bs); + } + + qemu_coroutine_yield(); + + if (use_bounce_buffer) { + if (cod.ret == 0) { + qemu_iovec_from_buf(qiov, 0, + bounce.buf.iov_base, + bounce.buf.iov_len); + } + + blkio_free_bounce_buffer(s, &bounce); + } + + return cod.ret; +} + +static int coroutine_fn blkio_co_pwritev(BlockDriverState *bs, int64_t offset, + int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags) +{ + uint32_t blkio_flags = (flags & BDRV_REQ_FUA) ? BLKIO_REQ_FUA : 0; + BlkioCoData cod = { + .coroutine = qemu_coroutine_self(), + }; + BDRVBlkioState *s = bs->opaque; + bool use_bounce_buffer = s->needs_mem_regions; + BlkioBounceBuf bounce; + struct iovec *iov = qiov->iov; + int iovcnt = qiov->niov; + + if (use_bounce_buffer) { + int ret = blkio_alloc_bounce_buffer(s, &bounce, bytes); + if (ret < 0) { + return ret; + } + + qemu_iovec_to_buf(qiov, 0, bounce.buf.iov_base, bytes); + iov = &bounce.buf; + iovcnt = 1; + } + + WITH_QEMU_LOCK_GUARD(&s->blkio_lock) { + blkioq_writev(s->blkioq, offset, iov, iovcnt, &cod, blkio_flags); + blkio_submit_io(bs); + } + + qemu_coroutine_yield(); + + if (use_bounce_buffer) { + blkio_free_bounce_buffer(s, &bounce); + } + + return cod.ret; +} + +static int coroutine_fn blkio_co_flush(BlockDriverState *bs) +{ + BDRVBlkioState *s = bs->opaque; + BlkioCoData cod = { + .coroutine = qemu_coroutine_self(), + }; + + WITH_QEMU_LOCK_GUARD(&s->blkio_lock) { + blkioq_flush(s->blkioq, &cod, 0); + blkio_submit_io(bs); + } + + qemu_coroutine_yield(); + return cod.ret; +} + +static int coroutine_fn blkio_co_pwrite_zeroes(BlockDriverState *bs, + int64_t offset, int64_t bytes, BdrvRequestFlags flags) +{ + BDRVBlkioState *s = bs->opaque; + BlkioCoData cod = { + .coroutine = qemu_coroutine_self(), + }; + uint32_t blkio_flags = 0; + + if (flags & BDRV_REQ_FUA) { + blkio_flags |= BLKIO_REQ_FUA; + } + if (!(flags & BDRV_REQ_MAY_UNMAP)) { + blkio_flags |= BLKIO_REQ_NO_UNMAP; + } + if (flags & BDRV_REQ_NO_FALLBACK) { + blkio_flags |= BLKIO_REQ_NO_FALLBACK; + } + + WITH_QEMU_LOCK_GUARD(&s->blkio_lock) { + blkioq_write_zeroes(s->blkioq, offset, bytes, &cod, blkio_flags); + blkio_submit_io(bs); + } + + qemu_coroutine_yield(); + return cod.ret; +} + +static void blkio_io_unplug(BlockDriverState *bs) +{ + BDRVBlkioState *s = bs->opaque; + + WITH_QEMU_LOCK_GUARD(&s->blkio_lock) { + blkio_submit_io(bs); + } +} + +static int blkio_io_uring_open(BlockDriverState *bs, QDict *options, int flags, + Error **errp) +{ + const char *filename = qdict_get_str(options, "filename"); + BDRVBlkioState *s = bs->opaque; + int ret; + + ret = blkio_set_str(s->blkio, "path", filename); + qdict_del(options, "filename"); + if (ret < 0) { + error_setg_errno(errp, -ret, "failed to set path: %s", + blkio_get_error_msg()); + return ret; + } + + if (flags & BDRV_O_NOCACHE) { + ret = blkio_set_bool(s->blkio, "direct", true); + if (ret < 0) { + error_setg_errno(errp, -ret, "failed to set direct: %s", + blkio_get_error_msg()); + return ret; + } + } + + return 0; +} + +static int blkio_nvme_io_uring(BlockDriverState *bs, QDict *options, int flags, + Error **errp) +{ + const char *filename = qdict_get_str(options, "filename"); + BDRVBlkioState *s = bs->opaque; + int ret; + + ret = blkio_set_str(s->blkio, "path", filename); + qdict_del(options, "filename"); + if (ret < 0) { + error_setg_errno(errp, -ret, "failed to set path: %s", + blkio_get_error_msg()); + return ret; + } + + if (!(flags & BDRV_O_NOCACHE)) { + error_setg(errp, "cache.direct=off is not supported"); + return -EINVAL; + } + + return 0; +} + +static int blkio_virtio_blk_common_open(BlockDriverState *bs, + QDict *options, int flags, Error **errp) +{ + const char *path = qdict_get_try_str(options, "path"); + BDRVBlkioState *s = bs->opaque; + int ret; + + if (!path) { + error_setg(errp, "missing 'path' option"); + return -EINVAL; + } + + ret = blkio_set_str(s->blkio, "path", path); + qdict_del(options, "path"); + if (ret < 0) { + error_setg_errno(errp, -ret, "failed to set path: %s", + blkio_get_error_msg()); + return ret; + } + + if (!(flags & BDRV_O_NOCACHE)) { + error_setg(errp, "cache.direct=off is not supported"); + return -EINVAL; + } + return 0; +} + +static int blkio_file_open(BlockDriverState *bs, QDict *options, int flags, + Error **errp) +{ + const char *blkio_driver = bs->drv->protocol_name; + BDRVBlkioState *s = bs->opaque; + int ret; + + ret = blkio_create(blkio_driver, &s->blkio); + if (ret < 0) { + error_setg_errno(errp, -ret, "blkio_create failed: %s", + blkio_get_error_msg()); + return ret; + } + + if (strcmp(blkio_driver, DRIVER_IO_URING) == 0) { + ret = blkio_io_uring_open(bs, options, flags, errp); + } else if (strcmp(blkio_driver, DRIVER_NVME_IO_URING) == 0) { + ret = blkio_nvme_io_uring(bs, options, flags, errp); + } else if (strcmp(blkio_driver, DRIVER_VIRTIO_BLK_VHOST_USER) == 0) { + ret = blkio_virtio_blk_common_open(bs, options, flags, errp); + } else if (strcmp(blkio_driver, DRIVER_VIRTIO_BLK_VHOST_VDPA) == 0) { + ret = blkio_virtio_blk_common_open(bs, options, flags, errp); + } else { + g_assert_not_reached(); + } + if (ret < 0) { + blkio_destroy(&s->blkio); + return ret; + } + + if (!(flags & BDRV_O_RDWR)) { + ret = blkio_set_bool(s->blkio, "read-only", true); + if (ret < 0) { + error_setg_errno(errp, -ret, "failed to set read-only: %s", + blkio_get_error_msg()); + blkio_destroy(&s->blkio); + return ret; + } + } + + ret = blkio_connect(s->blkio); + if (ret < 0) { + error_setg_errno(errp, -ret, "blkio_connect failed: %s", + blkio_get_error_msg()); + blkio_destroy(&s->blkio); + return ret; + } + + ret = blkio_get_bool(s->blkio, + "needs-mem-regions", + &s->needs_mem_regions); + if (ret < 0) { + error_setg_errno(errp, -ret, + "failed to get needs-mem-regions: %s", + blkio_get_error_msg()); + blkio_destroy(&s->blkio); + return ret; + } + + ret = blkio_get_uint64(s->blkio, + "mem-region-alignment", + &s->mem_region_alignment); + if (ret < 0) { + error_setg_errno(errp, -ret, + "failed to get mem-region-alignment: %s", + blkio_get_error_msg()); + blkio_destroy(&s->blkio); + return ret; + } + + ret = blkio_start(s->blkio); + if (ret < 0) { + error_setg_errno(errp, -ret, "blkio_start failed: %s", + blkio_get_error_msg()); + blkio_destroy(&s->blkio); + return ret; + } + + bs->supported_write_flags = BDRV_REQ_FUA; + bs->supported_zero_flags = BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | + BDRV_REQ_NO_FALLBACK; + + qemu_mutex_init(&s->blkio_lock); + qemu_co_mutex_init(&s->bounce_lock); + qemu_co_queue_init(&s->bounce_available); + QLIST_INIT(&s->bounce_bufs); + s->blkioq = blkio_get_queue(s->blkio, 0); + s->completion_fd = blkioq_get_completion_fd(s->blkioq); + + blkio_attach_aio_context(bs, bdrv_get_aio_context(bs)); + return 0; +} + +static void blkio_close(BlockDriverState *bs) +{ + BDRVBlkioState *s = bs->opaque; + + /* There is no destroy() API for s->bounce_lock */ + + qemu_mutex_destroy(&s->blkio_lock); + blkio_detach_aio_context(bs); + blkio_destroy(&s->blkio); +} + +static int64_t blkio_getlength(BlockDriverState *bs) +{ + BDRVBlkioState *s = bs->opaque; + uint64_t capacity; + int ret; + + WITH_QEMU_LOCK_GUARD(&s->blkio_lock) { + ret = blkio_get_uint64(s->blkio, "capacity", &capacity); + } + if (ret < 0) { + return -ret; + } + + return capacity; +} + +static int blkio_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) +{ + return 0; +} + +static void blkio_refresh_limits(BlockDriverState *bs, Error **errp) +{ + BDRVBlkioState *s = bs->opaque; + QEMU_LOCK_GUARD(&s->blkio_lock); + int value; + int ret; + + ret = blkio_get_int(s->blkio, "request-alignment", &value); + if (ret < 0) { + error_setg_errno(errp, -ret, "failed to get \"request-alignment\": %s", + blkio_get_error_msg()); + return; + } + bs->bl.request_alignment = value; + if (bs->bl.request_alignment < 1 || + bs->bl.request_alignment >= INT_MAX || + !is_power_of_2(bs->bl.request_alignment)) { + error_setg(errp, "invalid \"request-alignment\" value %" PRIu32 ", " + "must be a power of 2 less than INT_MAX", + bs->bl.request_alignment); + return; + } + + ret = blkio_get_int(s->blkio, "optimal-io-size", &value); + if (ret < 0) { + error_setg_errno(errp, -ret, "failed to get \"optimal-io-size\": %s", + blkio_get_error_msg()); + return; + } + bs->bl.opt_transfer = value; + if (bs->bl.opt_transfer > INT_MAX || + (bs->bl.opt_transfer % bs->bl.request_alignment)) { + error_setg(errp, "invalid \"optimal-io-size\" value %" PRIu32 ", must " + "be a multiple of %" PRIu32, bs->bl.opt_transfer, + bs->bl.request_alignment); + return; + } + + ret = blkio_get_int(s->blkio, "max-transfer", &value); + if (ret < 0) { + error_setg_errno(errp, -ret, "failed to get \"max-transfer\": %s", + blkio_get_error_msg()); + return; + } + bs->bl.max_transfer = value; + if ((bs->bl.max_transfer % bs->bl.request_alignment) || + (bs->bl.opt_transfer && (bs->bl.max_transfer % bs->bl.opt_transfer))) { + error_setg(errp, "invalid \"max-transfer\" value %" PRIu32 ", must be " + "a multiple of %" PRIu32 " and %" PRIu32 " (if non-zero)", + bs->bl.max_transfer, bs->bl.request_alignment, + bs->bl.opt_transfer); + return; + } + + ret = blkio_get_int(s->blkio, "buf-alignment", &value); + if (ret < 0) { + error_setg_errno(errp, -ret, "failed to get \"buf-alignment\": %s", + blkio_get_error_msg()); + return; + } + if (value < 1) { + error_setg(errp, "invalid \"buf-alignment\" value %d, must be " + "positive", value); + return; + } + bs->bl.min_mem_alignment = value; + + ret = blkio_get_int(s->blkio, "optimal-buf-alignment", &value); + if (ret < 0) { + error_setg_errno(errp, -ret, + "failed to get \"optimal-buf-alignment\": %s", + blkio_get_error_msg()); + return; + } + if (value < 1) { + error_setg(errp, "invalid \"optimal-buf-alignment\" value %d, " + "must be positive", value); + return; + } + bs->bl.opt_mem_alignment = value; + + ret = blkio_get_int(s->blkio, "max-segments", &value); + if (ret < 0) { + error_setg_errno(errp, -ret, "failed to get \"max-segments\": %s", + blkio_get_error_msg()); + return; + } + if (value < 1) { + error_setg(errp, "invalid \"max-segments\" value %d, must be positive", + value); + return; + } + bs->bl.max_iov = value; +} + +/* + * TODO + * Missing libblkio APIs: + * - block_status + * - co_invalidate_cache + * + * Out of scope? + * - create + * - truncate + */ + +#define BLKIO_DRIVER(name, ...) \ + { \ + .format_name = name, \ + .protocol_name = name, \ + .instance_size = sizeof(BDRVBlkioState), \ + .bdrv_file_open = blkio_file_open, \ + .bdrv_close = blkio_close, \ + .bdrv_getlength = blkio_getlength, \ + .bdrv_get_info = blkio_get_info, \ + .bdrv_attach_aio_context = blkio_attach_aio_context, \ + .bdrv_detach_aio_context = blkio_detach_aio_context, \ + .bdrv_co_pdiscard = blkio_co_pdiscard, \ + .bdrv_co_preadv = blkio_co_preadv, \ + .bdrv_co_pwritev = blkio_co_pwritev, \ + .bdrv_co_flush_to_disk = blkio_co_flush, \ + .bdrv_co_pwrite_zeroes = blkio_co_pwrite_zeroes, \ + .bdrv_io_unplug = blkio_io_unplug, \ + .bdrv_refresh_limits = blkio_refresh_limits, \ + __VA_ARGS__ \ + } + +static BlockDriver bdrv_io_uring = BLKIO_DRIVER( + DRIVER_IO_URING, + .bdrv_needs_filename = true, +); + +static BlockDriver bdrv_nvme_io_uring = BLKIO_DRIVER( + DRIVER_NVME_IO_URING, + .bdrv_needs_filename = true, +); + +static BlockDriver bdrv_virtio_blk_vhost_user = BLKIO_DRIVER( + DRIVER_VIRTIO_BLK_VHOST_USER +); + +static BlockDriver bdrv_virtio_blk_vhost_vdpa = BLKIO_DRIVER( + DRIVER_VIRTIO_BLK_VHOST_VDPA +); + +static void bdrv_blkio_init(void) +{ + bdrv_register(&bdrv_io_uring); + bdrv_register(&bdrv_nvme_io_uring); + bdrv_register(&bdrv_virtio_blk_vhost_user); + bdrv_register(&bdrv_virtio_blk_vhost_vdpa); +} + +block_init(bdrv_blkio_init); diff --git a/block/meson.build b/block/meson.build index 60bc305597..500878f082 100644 --- a/block/meson.build +++ b/block/meson.build @@ -92,6 +92,7 @@ block_modules = {} modsrc = [] foreach m : [ + [blkio, 'blkio', files('blkio.c')], [curl, 'curl', files('curl.c')], [glusterfs, 'gluster', files('gluster.c')], [libiscsi, 'iscsi', [files('iscsi.c'), libm]], diff --git a/meson.build b/meson.build index b686dfef75..1e9068adf6 100644 --- a/meson.build +++ b/meson.build @@ -771,6 +771,13 @@ if not get_option('virglrenderer').auto() or have_system or have_vhost_user_gpu required: get_option('virglrenderer'), kwargs: static_kwargs) endif +blkio = not_found +if not get_option('blkio').auto() or have_block + blkio = dependency('blkio', + method: 'pkg-config', + required: get_option('blkio'), + kwargs: static_kwargs) +endif curl = not_found if not get_option('curl').auto() or have_block curl = dependency('libcurl', version: '>=7.29.0', @@ -1815,6 +1822,7 @@ config_host_data.set('CONFIG_LIBUDEV', libudev.found()) config_host_data.set('CONFIG_LZO', lzo.found()) config_host_data.set('CONFIG_MPATH', mpathpersist.found()) config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api) +config_host_data.set('CONFIG_BLKIO', blkio.found()) config_host_data.set('CONFIG_CURL', curl.found()) config_host_data.set('CONFIG_CURSES', curses.found()) config_host_data.set('CONFIG_GBM', gbm.found()) @@ -3869,6 +3877,7 @@ summary_info += {'PAM': pam} summary_info += {'iconv support': iconv} summary_info += {'curses support': curses} summary_info += {'virgl support': virgl} +summary_info += {'blkio support': blkio} summary_info += {'curl support': curl} summary_info += {'Multipath support': mpathpersist} summary_info += {'PNG support': png} diff --git a/meson_options.txt b/meson_options.txt index 79c6af18d5..66128178bf 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -117,6 +117,8 @@ option('bzip2', type : 'feature', value : 'auto', description: 'bzip2 support for DMG images') option('cap_ng', type : 'feature', value : 'auto', description: 'cap_ng support') +option('blkio', type : 'feature', value : 'auto', + description: 'libblkio block device driver') option('bpf', type : 'feature', value : 'auto', description: 'eBPF support') option('cocoa', type : 'feature', value : 'auto', diff --git a/qapi/block-core.json b/qapi/block-core.json index 882b266532..cb5079e645 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -2951,11 +2951,18 @@ 'file', 'snapshot-access', 'ftp', 'ftps', 'gluster', {'name': 'host_cdrom', 'if': 'HAVE_HOST_BLOCK_DEVICE' }, {'name': 'host_device', 'if': 'HAVE_HOST_BLOCK_DEVICE' }, - 'http', 'https', 'iscsi', - 'luks', 'nbd', 'nfs', 'null-aio', 'null-co', 'nvme', 'parallels', - 'preallocate', 'qcow', 'qcow2', 'qed', 'quorum', 'raw', 'rbd', + 'http', 'https', + { 'name': 'io_uring', 'if': 'CONFIG_BLKIO' }, + 'iscsi', + 'luks', 'nbd', 'nfs', 'null-aio', 'null-co', 'nvme', + { 'name': 'nvme-io_uring', 'if': 'CONFIG_BLKIO' }, + 'parallels', 'preallocate', 'qcow', 'qcow2', 'qed', 'quorum', + 'raw', 'rbd', { 'name': 'replication', 'if': 'CONFIG_REPLICATION' }, - 'ssh', 'throttle', 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat' ] } + 'ssh', 'throttle', 'vdi', 'vhdx', + { 'name': 'virtio-blk-vhost-user', 'if': 'CONFIG_BLKIO' }, + { 'name': 'virtio-blk-vhost-vdpa', 'if': 'CONFIG_BLKIO' }, + 'vmdk', 'vpc', 'vvfat' ] } ## # @BlockdevOptionsFile: @@ -3678,6 +3685,58 @@ '*debug': 'int', '*logfile': 'str' } } +## +# @BlockdevOptionsIoUring: +# +# Driver specific block device options for the io_uring backend. +# +# @filename: path to the image file +# +# Since: 7.2 +## +{ 'struct': 'BlockdevOptionsIoUring', + 'data': { 'filename': 'str' }, + 'if': 'CONFIG_BLKIO' } + +## +# @BlockdevOptionsNvmeIoUring: +# +# Driver specific block device options for the nvme-io_uring backend. +# +# @filename: path to the image file +# +# Since: 7.2 +## +{ 'struct': 'BlockdevOptionsNvmeIoUring', + 'data': { 'filename': 'str' }, + 'if': 'CONFIG_BLKIO' } + +## +# @BlockdevOptionsVirtioBlkVhostUser: +# +# Driver specific block device options for the virtio-blk-vhost-user backend. +# +# @path: path to the vhost-user UNIX domain socket. +# +# Since: 7.2 +## +{ 'struct': 'BlockdevOptionsVirtioBlkVhostUser', + 'data': { 'path': 'str' }, + 'if': 'CONFIG_BLKIO' } + +## +# @BlockdevOptionsVirtioBlkVhostVdpa: +# +# Driver specific block device options for the virtio-blk-vhost-vdpa backend. +# +# @path: path to the vhost-vdpa character device. +# +# Since: 7.2 +## +{ 'struct': 'BlockdevOptionsVirtioBlkVhostVdpa', + 'data': { 'path': 'str' }, + 'if': 'CONFIG_BLKIO' } + ## # @IscsiTransport: # @@ -4305,6 +4364,8 @@ 'if': 'HAVE_HOST_BLOCK_DEVICE' }, 'http': 'BlockdevOptionsCurlHttp', 'https': 'BlockdevOptionsCurlHttps', + 'io_uring': { 'type': 'BlockdevOptionsIoUring', + 'if': 'CONFIG_BLKIO' }, 'iscsi': 'BlockdevOptionsIscsi', 'luks': 'BlockdevOptionsLUKS', 'nbd': 'BlockdevOptionsNbd', @@ -4312,6 +4373,8 @@ 'null-aio': 'BlockdevOptionsNull', 'null-co': 'BlockdevOptionsNull', 'nvme': 'BlockdevOptionsNVMe', + 'nvme-io_uring': { 'type': 'BlockdevOptionsNvmeIoUring', + 'if': 'CONFIG_BLKIO' }, 'parallels': 'BlockdevOptionsGenericFormat', 'preallocate':'BlockdevOptionsPreallocate', 'qcow2': 'BlockdevOptionsQcow2', @@ -4327,6 +4390,12 @@ 'throttle': 'BlockdevOptionsThrottle', 'vdi': 'BlockdevOptionsGenericFormat', 'vhdx': 'BlockdevOptionsGenericFormat', + 'virtio-blk-vhost-user': + { 'type': 'BlockdevOptionsVirtioBlkVhostUser', + 'if': 'CONFIG_BLKIO' }, + 'virtio-blk-vhost-vdpa': + { 'type': 'BlockdevOptionsVirtioBlkVhostVdpa', + 'if': 'CONFIG_BLKIO' }, 'vmdk': 'BlockdevOptionsGenericCOWFormat', 'vpc': 'BlockdevOptionsGenericFormat', 'vvfat': 'BlockdevOptionsVVFAT' diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh index eb3267bef5..2cb0de5601 100644 --- a/scripts/meson-buildoptions.sh +++ b/scripts/meson-buildoptions.sh @@ -67,6 +67,7 @@ meson_options_help() { printf "%s\n" ' auth-pam PAM access control' printf "%s\n" ' avx2 AVX2 optimizations' printf "%s\n" ' avx512f AVX512F optimizations' + printf "%s\n" ' blkio libblkio block device driver' printf "%s\n" ' bochs bochs image format support' printf "%s\n" ' bpf eBPF support' printf "%s\n" ' brlapi brlapi character device driver' @@ -198,6 +199,8 @@ _meson_option_parse() { --disable-gcov) printf "%s" -Db_coverage=false ;; --enable-lto) printf "%s" -Db_lto=true ;; --disable-lto) printf "%s" -Db_lto=false ;; + --enable-blkio) printf "%s" -Dblkio=enabled ;; + --disable-blkio) printf "%s" -Dblkio=disabled ;; --block-drv-ro-whitelist=*) quote_sh "-Dblock_drv_ro_whitelist=$2" ;; --block-drv-rw-whitelist=*) quote_sh "-Dblock_drv_rw_whitelist=$2" ;; --enable-block-drv-whitelist-in-tools) printf "%s" -Dblock_drv_whitelist_in_tools=true ;; diff --git a/tests/qtest/modules-test.c b/tests/qtest/modules-test.c index 88217686e1..be2575ae6d 100644 --- a/tests/qtest/modules-test.c +++ b/tests/qtest/modules-test.c @@ -16,6 +16,9 @@ static void test_modules_load(const void *data) int main(int argc, char *argv[]) { const char *modules[] = { +#ifdef CONFIG_BLKIO + "block-", "blkio", +#endif #ifdef CONFIG_CURL "block-", "curl", #endif From 1f0fea38f46a786dd87407997e8bfbccca5e458f Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Thu, 13 Oct 2022 14:58:58 -0400 Subject: [PATCH 164/705] numa: call ->ram_block_removed() in ram_block_notifer_remove() When a RAMBlockNotifier is added, ->ram_block_added() is called with all existing RAMBlocks. There is no equivalent ->ram_block_removed() call when a RAMBlockNotifier is removed. The util/vfio-helpers.c code (the sole user of RAMBlockNotifier) is fine with this asymmetry because it does not rely on RAMBlockNotifier for cleanup. It walks its internal list of DMA mappings and unmaps them by itself. Future users of RAMBlockNotifier may not have an internal data structure that records added RAMBlocks so they will need ->ram_block_removed() callbacks. This patch makes ram_block_notifier_remove() symmetric with respect to callbacks. Now util/vfio-helpers.c needs to unmap remaining DMA mappings after ram_block_notifier_remove() has been called. This is necessary since users like block/nvme.c may create additional DMA mappings that do not originate from the RAMBlockNotifier. Reviewed-by: David Hildenbrand Signed-off-by: Stefan Hajnoczi Message-id: 20221013185908.1297568-4-stefanha@redhat.com Signed-off-by: Stefan Hajnoczi --- hw/core/numa.c | 17 +++++++++++++++++ util/vfio-helpers.c | 5 ++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/hw/core/numa.c b/hw/core/numa.c index 26d8e5f616..31e6fe1caa 100644 --- a/hw/core/numa.c +++ b/hw/core/numa.c @@ -822,6 +822,19 @@ static int ram_block_notify_add_single(RAMBlock *rb, void *opaque) return 0; } +static int ram_block_notify_remove_single(RAMBlock *rb, void *opaque) +{ + const ram_addr_t max_size = qemu_ram_get_max_length(rb); + const ram_addr_t size = qemu_ram_get_used_length(rb); + void *host = qemu_ram_get_host_addr(rb); + RAMBlockNotifier *notifier = opaque; + + if (host) { + notifier->ram_block_removed(notifier, host, size, max_size); + } + return 0; +} + void ram_block_notifier_add(RAMBlockNotifier *n) { QLIST_INSERT_HEAD(&ram_list.ramblock_notifiers, n, next); @@ -835,6 +848,10 @@ void ram_block_notifier_add(RAMBlockNotifier *n) void ram_block_notifier_remove(RAMBlockNotifier *n) { QLIST_REMOVE(n, next); + + if (n->ram_block_removed) { + qemu_ram_foreach_block(ram_block_notify_remove_single, n); + } } void ram_block_notify_add(void *host, size_t size, size_t max_size) diff --git a/util/vfio-helpers.c b/util/vfio-helpers.c index 5ba01177bf..0d1520caac 100644 --- a/util/vfio-helpers.c +++ b/util/vfio-helpers.c @@ -847,10 +847,13 @@ void qemu_vfio_close(QEMUVFIOState *s) if (!s) { return; } + + ram_block_notifier_remove(&s->ram_notifier); + for (i = 0; i < s->nr_mappings; ++i) { qemu_vfio_undo_mapping(s, &s->mappings[i], NULL); } - ram_block_notifier_remove(&s->ram_notifier); + g_free(s->usable_iova_ranges); s->nb_iova_ranges = 0; qemu_vfio_reset(s); From 4f384011c5a37f80dc6cadefffac61ffb1c3aa1e Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Thu, 13 Oct 2022 14:58:59 -0400 Subject: [PATCH 165/705] block: pass size to bdrv_unregister_buf() The only implementor of bdrv_register_buf() is block/nvme.c, where the size is not needed when unregistering a buffer. This is because util/vfio-helpers.c can look up mappings by address. Future block drivers that implement bdrv_register_buf() may not be able to do their job given only the buffer address. Add a size argument to bdrv_unregister_buf(). Also document the assumptions about bdrv_register_buf()/bdrv_unregister_buf() calls. The same values that were given to bdrv_register_buf() must be given to bdrv_unregister_buf(). gcc 11.2.1 emits a spurious warning that img_bench()'s buf_size local variable might be uninitialized, so it's necessary to silence the compiler. Signed-off-by: Stefan Hajnoczi Reviewed-by: Stefano Garzarella Message-id: 20221013185908.1297568-5-stefanha@redhat.com Signed-off-by: Stefan Hajnoczi --- block/block-backend.c | 4 ++-- block/io.c | 6 +++--- block/nvme.c | 2 +- include/block/block-global-state.h | 5 ++++- include/block/block_int-common.h | 2 +- include/sysemu/block-backend-global-state.h | 2 +- qemu-img.c | 4 ++-- 7 files changed, 14 insertions(+), 11 deletions(-) diff --git a/block/block-backend.c b/block/block-backend.c index aa4adf06ae..ae42474891 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -2551,10 +2551,10 @@ void blk_register_buf(BlockBackend *blk, void *host, size_t size) bdrv_register_buf(blk_bs(blk), host, size); } -void blk_unregister_buf(BlockBackend *blk, void *host) +void blk_unregister_buf(BlockBackend *blk, void *host, size_t size) { GLOBAL_STATE_CODE(); - bdrv_unregister_buf(blk_bs(blk), host); + bdrv_unregister_buf(blk_bs(blk), host, size); } int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in, diff --git a/block/io.c b/block/io.c index d30073036e..cca402bf7b 100644 --- a/block/io.c +++ b/block/io.c @@ -3275,16 +3275,16 @@ void bdrv_register_buf(BlockDriverState *bs, void *host, size_t size) } } -void bdrv_unregister_buf(BlockDriverState *bs, void *host) +void bdrv_unregister_buf(BlockDriverState *bs, void *host, size_t size) { BdrvChild *child; GLOBAL_STATE_CODE(); if (bs->drv && bs->drv->bdrv_unregister_buf) { - bs->drv->bdrv_unregister_buf(bs, host); + bs->drv->bdrv_unregister_buf(bs, host, size); } QLIST_FOREACH(child, &bs->children, next) { - bdrv_unregister_buf(child->bs, host); + bdrv_unregister_buf(child->bs, host, size); } } diff --git a/block/nvme.c b/block/nvme.c index 2b24f95164..94b76b16f2 100644 --- a/block/nvme.c +++ b/block/nvme.c @@ -1602,7 +1602,7 @@ static void nvme_register_buf(BlockDriverState *bs, void *host, size_t size) } } -static void nvme_unregister_buf(BlockDriverState *bs, void *host) +static void nvme_unregister_buf(BlockDriverState *bs, void *host, size_t size) { BDRVNVMeState *s = bs->opaque; diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h index 21265e3966..7901f35863 100644 --- a/include/block/block-global-state.h +++ b/include/block/block-global-state.h @@ -243,9 +243,12 @@ void bdrv_del_child(BlockDriverState *parent, BdrvChild *child, Error **errp); * Register/unregister a buffer for I/O. For example, VFIO drivers are * interested to know the memory areas that would later be used for I/O, so * that they can prepare IOMMU mapping etc., to get better performance. + * + * Buffers must not overlap and they must be unregistered with the same values that they were registered with. */ void bdrv_register_buf(BlockDriverState *bs, void *host, size_t size); -void bdrv_unregister_buf(BlockDriverState *bs, void *host); +void bdrv_unregister_buf(BlockDriverState *bs, void *host, size_t size); void bdrv_cancel_in_flight(BlockDriverState *bs); diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h index 8947abab76..b7a7cbd3a5 100644 --- a/include/block/block_int-common.h +++ b/include/block/block_int-common.h @@ -435,7 +435,7 @@ struct BlockDriver { * DMA mapping for hot buffers. */ void (*bdrv_register_buf)(BlockDriverState *bs, void *host, size_t size); - void (*bdrv_unregister_buf)(BlockDriverState *bs, void *host); + void (*bdrv_unregister_buf)(BlockDriverState *bs, void *host, size_t size); /* * This field is modified only under the BQL, and is part of diff --git a/include/sysemu/block-backend-global-state.h b/include/sysemu/block-backend-global-state.h index 415f0c91d7..97f7dad2c3 100644 --- a/include/sysemu/block-backend-global-state.h +++ b/include/sysemu/block-backend-global-state.h @@ -107,7 +107,7 @@ void blk_io_limits_update_group(BlockBackend *blk, const char *group); void blk_set_force_allow_inactivate(BlockBackend *blk); void blk_register_buf(BlockBackend *blk, void *host, size_t size); -void blk_unregister_buf(BlockBackend *blk, void *host); +void blk_unregister_buf(BlockBackend *blk, void *host, size_t size); const BdrvChild *blk_root(BlockBackend *blk); diff --git a/qemu-img.c b/qemu-img.c index ace3adf8ae..9fe94df650 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -4371,7 +4371,7 @@ static int img_bench(int argc, char **argv) struct timeval t1, t2; int i; bool force_share = false; - size_t buf_size; + size_t buf_size = 0; for (;;) { static const struct option long_options[] = { @@ -4593,7 +4593,7 @@ static int img_bench(int argc, char **argv) out: if (data.buf) { - blk_unregister_buf(blk, data.buf); + blk_unregister_buf(blk, data.buf, buf_size); } qemu_vfree(data.buf); blk_unref(blk); From 98b3ddc78bf3380ec976d924aedb7f3fa2e9dbef Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Thu, 13 Oct 2022 14:59:00 -0400 Subject: [PATCH 166/705] block: use BdrvRequestFlags type for supported flag fields Use the enum type so GDB displays the enum members instead of printing a numeric constant. Signed-off-by: Stefan Hajnoczi Reviewed-by: Stefano Garzarella Message-id: 20221013185908.1297568-6-stefanha@redhat.com Signed-off-by: Stefan Hajnoczi --- include/block/block_int-common.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h index b7a7cbd3a5..19798d0e77 100644 --- a/include/block/block_int-common.h +++ b/include/block/block_int-common.h @@ -1051,7 +1051,7 @@ struct BlockDriverState { /* * Flags honored during pread */ - unsigned int supported_read_flags; + BdrvRequestFlags supported_read_flags; /* * Flags honored during pwrite (so far: BDRV_REQ_FUA, * BDRV_REQ_WRITE_UNCHANGED). @@ -1069,12 +1069,12 @@ struct BlockDriverState { * flag), or they have to explicitly take the WRITE permission for * their children. */ - unsigned int supported_write_flags; + BdrvRequestFlags supported_write_flags; /* * Flags honored during pwrite_zeroes (so far: BDRV_REQ_FUA, * BDRV_REQ_MAY_UNMAP, BDRV_REQ_WRITE_UNCHANGED) */ - unsigned int supported_zero_flags; + BdrvRequestFlags supported_zero_flags; /* * Flags honoured during truncate (so far: BDRV_REQ_ZERO_WRITE). * @@ -1082,7 +1082,7 @@ struct BlockDriverState { * that any added space reads as all zeros. If this can't be guaranteed, * the operation must fail. */ - unsigned int supported_truncate_flags; + BdrvRequestFlags supported_truncate_flags; /* the following member gives a name to every node on the bs graph. */ char node_name[32]; From e8b6535533be4269e4b7bd23d4bb17dd976dc7a3 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Thu, 13 Oct 2022 14:59:01 -0400 Subject: [PATCH 167/705] block: add BDRV_REQ_REGISTERED_BUF request flag Block drivers may optimize I/O requests accessing buffers previously registered with bdrv_register_buf(). Checking whether all elements of a request's QEMUIOVector are within previously registered buffers is expensive, so we need a hint from the user to avoid costly checks. Add a BDRV_REQ_REGISTERED_BUF request flag to indicate that all QEMUIOVector elements in an I/O request are known to be within previously registered buffers. Always pass the flag through to driver read/write functions. There is little harm in passing the flag to a driver that does not use it. Passing the flag to drivers avoids changes across many block drivers. Filter drivers would need to explicitly support the flag and pass through to their children when the children support it. That's a lot of code changes and it's hard to remember to do that everywhere, leading to silent reduced performance when the flag is accidentally dropped. The only problematic scenario with the approach in this patch is when a driver passes the flag through to internal I/O requests that don't use the same I/O buffer. In that case the hint may be set when it should actually be clear. This is a rare case though so the risk is low. Some drivers have assert(!flags), which no longer works when BDRV_REQ_REGISTERED_BUF is passed in. These assertions aren't very useful anyway since the functions are called almost exclusively by bdrv_driver_preadv/pwritev() so if we get flags handling right there then the assertion is not needed. Signed-off-by: Stefan Hajnoczi Message-id: 20221013185908.1297568-7-stefanha@redhat.com Signed-off-by: Stefan Hajnoczi --- block.c | 14 +++++++++ block/blkverify.c | 4 +-- block/crypto.c | 4 +-- block/file-posix.c | 1 - block/gluster.c | 1 - block/io.c | 61 ++++++++++++++++++++++-------------- block/mirror.c | 2 ++ block/nbd.c | 1 - block/parallels.c | 1 - block/qcow.c | 2 -- block/qed.c | 1 - block/raw-format.c | 2 ++ block/replication.c | 1 - block/ssh.c | 1 - block/vhdx.c | 1 - include/block/block-common.h | 9 ++++++ 16 files changed, 69 insertions(+), 37 deletions(-) diff --git a/block.c b/block.c index 1fbf6b9e69..c69be2cfe3 100644 --- a/block.c +++ b/block.c @@ -1641,6 +1641,20 @@ static int bdrv_open_driver(BlockDriverState *bs, BlockDriver *drv, goto open_failed; } + assert(!(bs->supported_read_flags & ~BDRV_REQ_MASK)); + assert(!(bs->supported_write_flags & ~BDRV_REQ_MASK)); + + /* + * Always allow the BDRV_REQ_REGISTERED_BUF optimization hint. This saves + * drivers that pass read/write requests through to a child the trouble of + * declaring support explicitly. + * + * Drivers must not propagate this flag accidentally when they initiate I/O + * to a bounce buffer. That case should be rare though. + */ + bs->supported_read_flags |= BDRV_REQ_REGISTERED_BUF; + bs->supported_write_flags |= BDRV_REQ_REGISTERED_BUF; + ret = refresh_total_sectors(bs, bs->total_sectors); if (ret < 0) { error_setg_errno(errp, -ret, "Could not refresh total sector count"); diff --git a/block/blkverify.c b/block/blkverify.c index 020b1ae7b6..f36fd6aeb2 100644 --- a/block/blkverify.c +++ b/block/blkverify.c @@ -235,8 +235,8 @@ blkverify_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, qemu_iovec_init(&raw_qiov, qiov->niov); qemu_iovec_clone(&raw_qiov, qiov, buf); - ret = blkverify_co_prwv(bs, &r, offset, bytes, qiov, &raw_qiov, flags, - false); + ret = blkverify_co_prwv(bs, &r, offset, bytes, qiov, &raw_qiov, + flags & ~BDRV_REQ_REGISTERED_BUF, false); cmp_offset = qemu_iovec_compare(qiov, &raw_qiov); if (cmp_offset != -1) { diff --git a/block/crypto.c b/block/crypto.c index 7a57774b76..c7365598a7 100644 --- a/block/crypto.c +++ b/block/crypto.c @@ -410,7 +410,6 @@ block_crypto_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block); uint64_t payload_offset = qcrypto_block_get_payload_offset(crypto->block); - assert(!flags); assert(payload_offset < INT64_MAX); assert(QEMU_IS_ALIGNED(offset, sector_size)); assert(QEMU_IS_ALIGNED(bytes, sector_size)); @@ -473,7 +472,8 @@ block_crypto_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, uint64_t sector_size = qcrypto_block_get_sector_size(crypto->block); uint64_t payload_offset = qcrypto_block_get_payload_offset(crypto->block); - assert(!(flags & ~BDRV_REQ_FUA)); + flags &= ~BDRV_REQ_REGISTERED_BUF; + assert(payload_offset < INT64_MAX); assert(QEMU_IS_ALIGNED(offset, sector_size)); assert(QEMU_IS_ALIGNED(bytes, sector_size)); diff --git a/block/file-posix.c b/block/file-posix.c index 23acffb9a4..b9647c5ffc 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -2133,7 +2133,6 @@ static int coroutine_fn raw_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags) { - assert(flags == 0); return raw_co_prw(bs, offset, bytes, qiov, QEMU_AIO_WRITE); } diff --git a/block/gluster.c b/block/gluster.c index bb1144cf6a..7c90f7ba4b 100644 --- a/block/gluster.c +++ b/block/gluster.c @@ -1236,7 +1236,6 @@ static coroutine_fn int qemu_gluster_co_writev(BlockDriverState *bs, QEMUIOVector *qiov, int flags) { - assert(!flags); return qemu_gluster_co_rw(bs, sector_num, nb_sectors, qiov, 1); } diff --git a/block/io.c b/block/io.c index cca402bf7b..4207648db6 100644 --- a/block/io.c +++ b/block/io.c @@ -1130,8 +1130,7 @@ static int coroutine_fn bdrv_driver_preadv(BlockDriverState *bs, int ret; bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort); - assert(!(flags & ~BDRV_REQ_MASK)); - assert(!(flags & BDRV_REQ_NO_FALLBACK)); + assert(!(flags & ~bs->supported_read_flags)); if (!drv) { return -ENOMEDIUM; @@ -1195,23 +1194,29 @@ static int coroutine_fn bdrv_driver_pwritev(BlockDriverState *bs, BdrvRequestFlags flags) { BlockDriver *drv = bs->drv; + bool emulate_fua = false; int64_t sector_num; unsigned int nb_sectors; QEMUIOVector local_qiov; int ret; bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort); - assert(!(flags & ~BDRV_REQ_MASK)); - assert(!(flags & BDRV_REQ_NO_FALLBACK)); if (!drv) { return -ENOMEDIUM; } + if ((flags & BDRV_REQ_FUA) && + (~bs->supported_write_flags & BDRV_REQ_FUA)) { + flags &= ~BDRV_REQ_FUA; + emulate_fua = true; + } + + flags &= bs->supported_write_flags; + if (drv->bdrv_co_pwritev_part) { ret = drv->bdrv_co_pwritev_part(bs, offset, bytes, qiov, qiov_offset, - flags & bs->supported_write_flags); - flags &= ~bs->supported_write_flags; + flags); goto emulate_flags; } @@ -1221,9 +1226,7 @@ static int coroutine_fn bdrv_driver_pwritev(BlockDriverState *bs, } if (drv->bdrv_co_pwritev) { - ret = drv->bdrv_co_pwritev(bs, offset, bytes, qiov, - flags & bs->supported_write_flags); - flags &= ~bs->supported_write_flags; + ret = drv->bdrv_co_pwritev(bs, offset, bytes, qiov, flags); goto emulate_flags; } @@ -1233,10 +1236,8 @@ static int coroutine_fn bdrv_driver_pwritev(BlockDriverState *bs, .coroutine = qemu_coroutine_self(), }; - acb = drv->bdrv_aio_pwritev(bs, offset, bytes, qiov, - flags & bs->supported_write_flags, + acb = drv->bdrv_aio_pwritev(bs, offset, bytes, qiov, flags, bdrv_co_io_em_complete, &co); - flags &= ~bs->supported_write_flags; if (acb == NULL) { ret = -EIO; } else { @@ -1254,12 +1255,10 @@ static int coroutine_fn bdrv_driver_pwritev(BlockDriverState *bs, assert(bytes <= BDRV_REQUEST_MAX_BYTES); assert(drv->bdrv_co_writev); - ret = drv->bdrv_co_writev(bs, sector_num, nb_sectors, qiov, - flags & bs->supported_write_flags); - flags &= ~bs->supported_write_flags; + ret = drv->bdrv_co_writev(bs, sector_num, nb_sectors, qiov, flags); emulate_flags: - if (ret == 0 && (flags & BDRV_REQ_FUA)) { + if (ret == 0 && emulate_fua) { ret = bdrv_co_flush(bs); } @@ -1487,11 +1486,14 @@ static int coroutine_fn bdrv_aligned_preadv(BdrvChild *child, max_transfer = QEMU_ALIGN_DOWN(MIN_NON_ZERO(bs->bl.max_transfer, INT_MAX), align); - /* TODO: We would need a per-BDS .supported_read_flags and + /* + * TODO: We would need a per-BDS .supported_read_flags and * potential fallback support, if we ever implement any read flags * to pass through to drivers. For now, there aren't any - * passthrough flags. */ - assert(!(flags & ~(BDRV_REQ_COPY_ON_READ | BDRV_REQ_PREFETCH))); + * passthrough flags except the BDRV_REQ_REGISTERED_BUF optimization hint. + */ + assert(!(flags & ~(BDRV_REQ_COPY_ON_READ | BDRV_REQ_PREFETCH | + BDRV_REQ_REGISTERED_BUF))); /* Handle Copy on Read and associated serialisation */ if (flags & BDRV_REQ_COPY_ON_READ) { @@ -1532,7 +1534,7 @@ static int coroutine_fn bdrv_aligned_preadv(BdrvChild *child, goto out; } - assert(!(flags & ~bs->supported_read_flags)); + assert(!(flags & ~(bs->supported_read_flags | BDRV_REQ_REGISTERED_BUF))); max_bytes = ROUND_UP(MAX(0, total_bytes - offset), align); if (bytes <= max_bytes && bytes <= max_transfer) { @@ -1721,7 +1723,8 @@ static void bdrv_padding_destroy(BdrvRequestPadding *pad) static int bdrv_pad_request(BlockDriverState *bs, QEMUIOVector **qiov, size_t *qiov_offset, int64_t *offset, int64_t *bytes, - BdrvRequestPadding *pad, bool *padded) + BdrvRequestPadding *pad, bool *padded, + BdrvRequestFlags *flags) { int ret; @@ -1749,6 +1752,10 @@ static int bdrv_pad_request(BlockDriverState *bs, if (padded) { *padded = true; } + if (flags) { + /* Can't use optimization hint with bounce buffer */ + *flags &= ~BDRV_REQ_REGISTERED_BUF; + } return 0; } @@ -1803,7 +1810,7 @@ int coroutine_fn bdrv_co_preadv_part(BdrvChild *child, } ret = bdrv_pad_request(bs, &qiov, &qiov_offset, &offset, &bytes, &pad, - NULL); + NULL, &flags); if (ret < 0) { goto fail; } @@ -1848,6 +1855,11 @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs, return -ENOTSUP; } + /* By definition there is no user buffer so this flag doesn't make sense */ + if (flags & BDRV_REQ_REGISTERED_BUF) { + return -EINVAL; + } + /* Invalidate the cached block-status data range if this write overlaps */ bdrv_bsc_invalidate_range(bs, offset, bytes); @@ -2133,6 +2145,9 @@ static int coroutine_fn bdrv_co_do_zero_pwritev(BdrvChild *child, bool padding; BdrvRequestPadding pad; + /* This flag doesn't make sense for padding or zero writes */ + flags &= ~BDRV_REQ_REGISTERED_BUF; + padding = bdrv_init_padding(bs, offset, bytes, &pad); if (padding) { assert(!(flags & BDRV_REQ_NO_WAIT)); @@ -2250,7 +2265,7 @@ int coroutine_fn bdrv_co_pwritev_part(BdrvChild *child, * alignment only if there is no ZERO flag. */ ret = bdrv_pad_request(bs, &qiov, &qiov_offset, &offset, &bytes, &pad, - &padded); + &padded, &flags); if (ret < 0) { return ret; } diff --git a/block/mirror.c b/block/mirror.c index 80c0109d39..bed089d2e0 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -1486,6 +1486,8 @@ static int coroutine_fn bdrv_mirror_top_pwritev(BlockDriverState *bs, qemu_iovec_init(&bounce_qiov, 1); qemu_iovec_add(&bounce_qiov, bounce_buf, bytes); qiov = &bounce_qiov; + + flags &= ~BDRV_REQ_REGISTERED_BUF; } ret = bdrv_mirror_top_do_write(bs, MIRROR_METHOD_COPY, offset, bytes, qiov, diff --git a/block/nbd.c b/block/nbd.c index 494b9d683e..7d485c86d2 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -1222,7 +1222,6 @@ static int coroutine_fn nbd_client_co_preadv(BlockDriverState *bs, int64_t offse }; assert(bytes <= NBD_MAX_BUFFER_SIZE); - assert(!flags); if (!bytes) { return 0; diff --git a/block/parallels.c b/block/parallels.c index c1523e7dab..dd15a44100 100644 --- a/block/parallels.c +++ b/block/parallels.c @@ -329,7 +329,6 @@ static coroutine_fn int parallels_co_writev(BlockDriverState *bs, QEMUIOVector hd_qiov; int ret = 0; - assert(!flags); qemu_iovec_init(&hd_qiov, qiov->niov); while (nb_sectors > 0) { diff --git a/block/qcow.c b/block/qcow.c index 311aaa8705..e9180c7b61 100644 --- a/block/qcow.c +++ b/block/qcow.c @@ -628,7 +628,6 @@ static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, int64_t offset, uint8_t *buf; void *orig_buf; - assert(!flags); if (qiov->niov > 1) { buf = orig_buf = qemu_try_blockalign(bs, qiov->size); if (buf == NULL) { @@ -725,7 +724,6 @@ static coroutine_fn int qcow_co_pwritev(BlockDriverState *bs, int64_t offset, uint8_t *buf; void *orig_buf; - assert(!flags); s->cluster_cache_offset = -1; /* disable compressed cache */ /* We must always copy the iov when encrypting, so we diff --git a/block/qed.c b/block/qed.c index bda00e6257..99a9ec9b57 100644 --- a/block/qed.c +++ b/block/qed.c @@ -1395,7 +1395,6 @@ static int coroutine_fn bdrv_qed_co_writev(BlockDriverState *bs, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov, int flags) { - assert(!flags); return qed_co_request(bs, sector_num, qiov, nb_sectors, QED_AIOCB_WRITE); } diff --git a/block/raw-format.c b/block/raw-format.c index f337ac7569..c8dc9bc850 100644 --- a/block/raw-format.c +++ b/block/raw-format.c @@ -258,6 +258,8 @@ static int coroutine_fn raw_co_pwritev(BlockDriverState *bs, int64_t offset, qemu_iovec_add(&local_qiov, buf, 512); qemu_iovec_concat(&local_qiov, qiov, 512, qiov->size - 512); qiov = &local_qiov; + + flags &= ~BDRV_REQ_REGISTERED_BUF; } ret = raw_adjust_offset(bs, &offset, bytes, true); diff --git a/block/replication.c b/block/replication.c index c67f931f37..13f1d39571 100644 --- a/block/replication.c +++ b/block/replication.c @@ -261,7 +261,6 @@ static coroutine_fn int replication_co_writev(BlockDriverState *bs, int ret; int64_t n; - assert(!flags); ret = replication_get_io_status(s); if (ret < 0) { goto out; diff --git a/block/ssh.c b/block/ssh.c index a2dc646536..a3cddc392c 100644 --- a/block/ssh.c +++ b/block/ssh.c @@ -1196,7 +1196,6 @@ static coroutine_fn int ssh_co_writev(BlockDriverState *bs, BDRVSSHState *s = bs->opaque; int ret; - assert(!flags); qemu_co_mutex_lock(&s->lock); ret = ssh_write(s, bs, sector_num * BDRV_SECTOR_SIZE, nb_sectors * BDRV_SECTOR_SIZE, qiov); diff --git a/block/vhdx.c b/block/vhdx.c index e10e78ebfd..e2344ee0b7 100644 --- a/block/vhdx.c +++ b/block/vhdx.c @@ -1342,7 +1342,6 @@ static coroutine_fn int vhdx_co_writev(BlockDriverState *bs, int64_t sector_num, uint64_t bat_prior_offset = 0; bool bat_update = false; - assert(!flags); qemu_iovec_init(&hd_qiov, qiov->niov); qemu_co_mutex_lock(&s->lock); diff --git a/include/block/block-common.h b/include/block/block-common.h index fdb7306e78..061606e867 100644 --- a/include/block/block-common.h +++ b/include/block/block-common.h @@ -80,6 +80,15 @@ typedef enum { */ BDRV_REQ_MAY_UNMAP = 0x4, + /* + * An optimization hint when all QEMUIOVector elements are within + * previously registered bdrv_register_buf() memory ranges. + * + * Code that replaces the user's QEMUIOVector elements with bounce buffers + * must take care to clear this flag. + */ + BDRV_REQ_REGISTERED_BUF = 0x8, + BDRV_REQ_FUA = 0x10, BDRV_REQ_WRITE_COMPRESSED = 0x20, From f4ec04bae9577eaa55ac35f3971dc3086a4a9192 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Thu, 13 Oct 2022 14:59:02 -0400 Subject: [PATCH 168/705] block: return errors from bdrv_register_buf() Registering an I/O buffer is only a performance optimization hint but it is still necessary to return errors when it fails. Later patches will need to detect errors when registering buffers but an immediate advantage is that error_report() calls are no longer needed in block driver .bdrv_register_buf() functions. Signed-off-by: Stefan Hajnoczi Message-id: 20221013185908.1297568-8-stefanha@redhat.com Signed-off-by: Stefan Hajnoczi --- block/block-backend.c | 4 +-- block/io.c | 34 +++++++++++++++++++-- block/nvme.c | 18 +++++------ include/block/block-global-state.h | 5 ++- include/block/block_int-common.h | 5 ++- include/sysemu/block-backend-global-state.h | 2 +- qemu-img.c | 2 +- 7 files changed, 52 insertions(+), 18 deletions(-) diff --git a/block/block-backend.c b/block/block-backend.c index ae42474891..4f59664397 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -2545,10 +2545,10 @@ static void blk_root_drained_end(BdrvChild *child, int *drained_end_counter) } } -void blk_register_buf(BlockBackend *blk, void *host, size_t size) +bool blk_register_buf(BlockBackend *blk, void *host, size_t size, Error **errp) { GLOBAL_STATE_CODE(); - bdrv_register_buf(blk_bs(blk), host, size); + return bdrv_register_buf(blk_bs(blk), host, size, errp); } void blk_unregister_buf(BlockBackend *blk, void *host, size_t size) diff --git a/block/io.c b/block/io.c index 4207648db6..a9673465dd 100644 --- a/block/io.c +++ b/block/io.c @@ -3277,17 +3277,45 @@ void bdrv_io_unplug(BlockDriverState *bs) } } -void bdrv_register_buf(BlockDriverState *bs, void *host, size_t size) +/* Helper that undoes bdrv_register_buf() when it fails partway through */ +static void bdrv_register_buf_rollback(BlockDriverState *bs, + void *host, + size_t size, + BdrvChild *final_child) +{ + BdrvChild *child; + + QLIST_FOREACH(child, &bs->children, next) { + if (child == final_child) { + break; + } + + bdrv_unregister_buf(child->bs, host, size); + } + + if (bs->drv && bs->drv->bdrv_unregister_buf) { + bs->drv->bdrv_unregister_buf(bs, host, size); + } +} + +bool bdrv_register_buf(BlockDriverState *bs, void *host, size_t size, + Error **errp) { BdrvChild *child; GLOBAL_STATE_CODE(); if (bs->drv && bs->drv->bdrv_register_buf) { - bs->drv->bdrv_register_buf(bs, host, size); + if (!bs->drv->bdrv_register_buf(bs, host, size, errp)) { + return false; + } } QLIST_FOREACH(child, &bs->children, next) { - bdrv_register_buf(child->bs, host, size); + if (!bdrv_register_buf(child->bs, host, size, errp)) { + bdrv_register_buf_rollback(bs, host, size, child); + return false; + } } + return true; } void bdrv_unregister_buf(BlockDriverState *bs, void *host, size_t size) diff --git a/block/nvme.c b/block/nvme.c index 94b76b16f2..656624c585 100644 --- a/block/nvme.c +++ b/block/nvme.c @@ -1587,19 +1587,19 @@ static void nvme_aio_unplug(BlockDriverState *bs) } } -static void nvme_register_buf(BlockDriverState *bs, void *host, size_t size) +static bool nvme_register_buf(BlockDriverState *bs, void *host, size_t size, + Error **errp) { int ret; - Error *local_err = NULL; BDRVNVMeState *s = bs->opaque; - ret = qemu_vfio_dma_map(s->vfio, host, size, false, NULL, &local_err); - if (ret) { - /* FIXME: we may run out of IOVA addresses after repeated - * bdrv_register_buf/bdrv_unregister_buf, because nvme_vfio_dma_unmap - * doesn't reclaim addresses for fixed mappings. */ - error_reportf_err(local_err, "nvme_register_buf failed: "); - } + /* + * FIXME: we may run out of IOVA addresses after repeated + * bdrv_register_buf/bdrv_unregister_buf, because nvme_vfio_dma_unmap + * doesn't reclaim addresses for fixed mappings. + */ + ret = qemu_vfio_dma_map(s->vfio, host, size, false, NULL, errp); + return ret == 0; } static void nvme_unregister_buf(BlockDriverState *bs, void *host, size_t size) diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h index 7901f35863..eba4ed23b4 100644 --- a/include/block/block-global-state.h +++ b/include/block/block-global-state.h @@ -246,8 +246,11 @@ void bdrv_del_child(BlockDriverState *parent, BdrvChild *child, Error **errp); * * Buffers must not overlap and they must be unregistered with the same values that they were registered with. + * + * Returns: true on success, false on failure */ -void bdrv_register_buf(BlockDriverState *bs, void *host, size_t size); +bool bdrv_register_buf(BlockDriverState *bs, void *host, size_t size, + Error **errp); void bdrv_unregister_buf(BlockDriverState *bs, void *host, size_t size); void bdrv_cancel_in_flight(BlockDriverState *bs); diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h index 19798d0e77..9c569be162 100644 --- a/include/block/block_int-common.h +++ b/include/block/block_int-common.h @@ -433,8 +433,11 @@ struct BlockDriver { * that it can do IOMMU mapping with VFIO etc., in order to get better * performance. In the case of VFIO drivers, this callback is used to do * DMA mapping for hot buffers. + * + * Returns: true on success, false on failure */ - void (*bdrv_register_buf)(BlockDriverState *bs, void *host, size_t size); + bool (*bdrv_register_buf)(BlockDriverState *bs, void *host, size_t size, + Error **errp); void (*bdrv_unregister_buf)(BlockDriverState *bs, void *host, size_t size); /* diff --git a/include/sysemu/block-backend-global-state.h b/include/sysemu/block-backend-global-state.h index 97f7dad2c3..6858e39cb6 100644 --- a/include/sysemu/block-backend-global-state.h +++ b/include/sysemu/block-backend-global-state.h @@ -106,7 +106,7 @@ void blk_io_limits_enable(BlockBackend *blk, const char *group); void blk_io_limits_update_group(BlockBackend *blk, const char *group); void blk_set_force_allow_inactivate(BlockBackend *blk); -void blk_register_buf(BlockBackend *blk, void *host, size_t size); +bool blk_register_buf(BlockBackend *blk, void *host, size_t size, Error **errp); void blk_unregister_buf(BlockBackend *blk, void *host, size_t size); const BdrvChild *blk_root(BlockBackend *blk); diff --git a/qemu-img.c b/qemu-img.c index 9fe94df650..a3b64c88af 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -4570,7 +4570,7 @@ static int img_bench(int argc, char **argv) data.buf = blk_blockalign(blk, buf_size); memset(data.buf, pattern, data.nrreq * data.bufsize); - blk_register_buf(blk, data.buf, buf_size); + blk_register_buf(blk, data.buf, buf_size, &error_fatal); data.qiov = g_new(QEMUIOVector, data.nrreq); for (i = 0; i < data.nrreq; i++) { From 4fdd0a1a7ea174c5ee573e49c11f7d3bce00984d Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Thu, 13 Oct 2022 14:59:03 -0400 Subject: [PATCH 169/705] numa: use QLIST_FOREACH_SAFE() for RAM block notifiers Make list traversal work when a callback removes a notifier mid-traversal. This is a cleanup to prevent bugs in the future. Signed-off-by: Stefan Hajnoczi Reviewed-by: David Hildenbrand Message-id: 20221013185908.1297568-9-stefanha@redhat.com Signed-off-by: Stefan Hajnoczi --- hw/core/numa.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/hw/core/numa.c b/hw/core/numa.c index 31e6fe1caa..ea24a5fa8c 100644 --- a/hw/core/numa.c +++ b/hw/core/numa.c @@ -857,8 +857,9 @@ void ram_block_notifier_remove(RAMBlockNotifier *n) void ram_block_notify_add(void *host, size_t size, size_t max_size) { RAMBlockNotifier *notifier; + RAMBlockNotifier *next; - QLIST_FOREACH(notifier, &ram_list.ramblock_notifiers, next) { + QLIST_FOREACH_SAFE(notifier, &ram_list.ramblock_notifiers, next, next) { if (notifier->ram_block_added) { notifier->ram_block_added(notifier, host, size, max_size); } @@ -868,8 +869,9 @@ void ram_block_notify_add(void *host, size_t size, size_t max_size) void ram_block_notify_remove(void *host, size_t size, size_t max_size) { RAMBlockNotifier *notifier; + RAMBlockNotifier *next; - QLIST_FOREACH(notifier, &ram_list.ramblock_notifiers, next) { + QLIST_FOREACH_SAFE(notifier, &ram_list.ramblock_notifiers, next, next) { if (notifier->ram_block_removed) { notifier->ram_block_removed(notifier, host, size, max_size); } @@ -879,8 +881,9 @@ void ram_block_notify_remove(void *host, size_t size, size_t max_size) void ram_block_notify_resize(void *host, size_t old_size, size_t new_size) { RAMBlockNotifier *notifier; + RAMBlockNotifier *next; - QLIST_FOREACH(notifier, &ram_list.ramblock_notifiers, next) { + QLIST_FOREACH_SAFE(notifier, &ram_list.ramblock_notifiers, next, next) { if (notifier->ram_block_resized) { notifier->ram_block_resized(notifier, host, old_size, new_size); } From 7f9241d805b4711a4f7dc5489df0e7e30b8c1496 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Thu, 13 Oct 2022 14:59:04 -0400 Subject: [PATCH 170/705] block: add BlockRAMRegistrar Emulated devices and other BlockBackend users wishing to take advantage of blk_register_buf() all have the same repetitive job: register RAMBlocks with the BlockBackend using RAMBlockNotifier. Add a BlockRAMRegistrar API to do this. A later commit will use this from hw/block/virtio-blk.c. Signed-off-by: Stefan Hajnoczi Reviewed-by: Stefano Garzarella Message-id: 20221013185908.1297568-10-stefanha@redhat.com Signed-off-by: Stefan Hajnoczi --- MAINTAINERS | 1 + block/block-ram-registrar.c | 58 ++++++++++++++++++++++++++++ block/meson.build | 1 + include/sysemu/block-ram-registrar.h | 37 ++++++++++++++++++ 4 files changed, 97 insertions(+) create mode 100644 block/block-ram-registrar.c create mode 100644 include/sysemu/block-ram-registrar.h diff --git a/MAINTAINERS b/MAINTAINERS index 8b4363c0ff..cda146ebbb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2510,6 +2510,7 @@ F: block* F: block/ F: hw/block/ F: include/block/ +F: include/sysemu/block-*.h F: qemu-img* F: docs/tools/qemu-img.rst F: qemu-io* diff --git a/block/block-ram-registrar.c b/block/block-ram-registrar.c new file mode 100644 index 0000000000..25dbafa789 --- /dev/null +++ b/block/block-ram-registrar.c @@ -0,0 +1,58 @@ +/* + * BlockBackend RAM Registrar + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "sysemu/block-backend.h" +#include "sysemu/block-ram-registrar.h" +#include "qapi/error.h" + +static void ram_block_added(RAMBlockNotifier *n, void *host, size_t size, + size_t max_size) +{ + BlockRAMRegistrar *r = container_of(n, BlockRAMRegistrar, notifier); + Error *err = NULL; + + if (!r->ok) { + return; /* don't try again if we've already failed */ + } + + if (!blk_register_buf(r->blk, host, max_size, &err)) { + error_report_err(err); + ram_block_notifier_remove(&r->notifier); + r->ok = false; + } +} + +static void ram_block_removed(RAMBlockNotifier *n, void *host, size_t size, + size_t max_size) +{ + BlockRAMRegistrar *r = container_of(n, BlockRAMRegistrar, notifier); + blk_unregister_buf(r->blk, host, max_size); +} + +void blk_ram_registrar_init(BlockRAMRegistrar *r, BlockBackend *blk) +{ + r->blk = blk; + r->notifier = (RAMBlockNotifier){ + .ram_block_added = ram_block_added, + .ram_block_removed = ram_block_removed, + + /* + * .ram_block_resized() is not necessary because we use the max_size + * value that does not change across resize. + */ + }; + r->ok = true; + + ram_block_notifier_add(&r->notifier); +} + +void blk_ram_registrar_destroy(BlockRAMRegistrar *r) +{ + if (r->ok) { + ram_block_notifier_remove(&r->notifier); + } +} diff --git a/block/meson.build b/block/meson.build index 500878f082..b7c68b83a3 100644 --- a/block/meson.build +++ b/block/meson.build @@ -46,6 +46,7 @@ block_ss.add(files( ), zstd, zlib, gnutls) softmmu_ss.add(when: 'CONFIG_TCG', if_true: files('blkreplay.c')) +softmmu_ss.add(files('block-ram-registrar.c')) if get_option('qcow1').allowed() block_ss.add(files('qcow.c')) diff --git a/include/sysemu/block-ram-registrar.h b/include/sysemu/block-ram-registrar.h new file mode 100644 index 0000000000..d8b2f7942b --- /dev/null +++ b/include/sysemu/block-ram-registrar.h @@ -0,0 +1,37 @@ +/* + * BlockBackend RAM Registrar + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef BLOCK_RAM_REGISTRAR_H +#define BLOCK_RAM_REGISTRAR_H + +#include "exec/ramlist.h" + +/** + * struct BlockRAMRegistrar: + * + * Keeps RAMBlock memory registered with a BlockBackend using + * blk_register_buf() including hotplugged memory. + * + * Emulated devices or other BlockBackend users initialize a BlockRAMRegistrar + * with blk_ram_registrar_init() before submitting I/O requests with the + * BDRV_REQ_REGISTERED_BUF flag set. + */ +typedef struct { + BlockBackend *blk; + RAMBlockNotifier notifier; + bool ok; +} BlockRAMRegistrar; + +void blk_ram_registrar_init(BlockRAMRegistrar *r, BlockBackend *blk); +void blk_ram_registrar_destroy(BlockRAMRegistrar *r); + +/* Have all RAMBlocks been registered successfully? */ +static inline bool blk_ram_registrar_ok(BlockRAMRegistrar *r) +{ + return r->ok; +} + +#endif /* BLOCK_RAM_REGISTRAR_H */ From 6d998f3cbfebabea7882848a65c38f454d2a37c4 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Thu, 13 Oct 2022 14:59:05 -0400 Subject: [PATCH 171/705] exec/cpu-common: add qemu_ram_get_fd() Add a function to get the file descriptor for a RAMBlock. Device emulation code typically uses the MemoryRegion APIs but vhost-style code may use RAMBlock directly for sharing guest memory with another process. This new API will be used by the libblkio block driver so it can share guest memory via .bdrv_register_buf(). Signed-off-by: Stefan Hajnoczi Message-id: 20221013185908.1297568-11-stefanha@redhat.com Signed-off-by: Stefan Hajnoczi --- include/exec/cpu-common.h | 1 + softmmu/physmem.c | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h index c493510ee9..6feaa40ca7 100644 --- a/include/exec/cpu-common.h +++ b/include/exec/cpu-common.h @@ -92,6 +92,7 @@ void qemu_ram_set_uf_zeroable(RAMBlock *rb); bool qemu_ram_is_migratable(RAMBlock *rb); void qemu_ram_set_migratable(RAMBlock *rb); void qemu_ram_unset_migratable(RAMBlock *rb); +int qemu_ram_get_fd(RAMBlock *rb); size_t qemu_ram_pagesize(RAMBlock *block); size_t qemu_ram_pagesize_largest(void); diff --git a/softmmu/physmem.c b/softmmu/physmem.c index 56e03e07b5..d9578ccfd4 100644 --- a/softmmu/physmem.c +++ b/softmmu/physmem.c @@ -1748,6 +1748,11 @@ void qemu_ram_unset_migratable(RAMBlock *rb) rb->flags &= ~RAM_MIGRATABLE; } +int qemu_ram_get_fd(RAMBlock *rb) +{ + return rb->fd; +} + /* Called with iothread lock held. */ void qemu_ram_set_idstr(RAMBlock *new_block, const char *name, DeviceState *dev) { From 701bff24deba59a095c6b5cade15e764d56909f6 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Thu, 13 Oct 2022 14:59:06 -0400 Subject: [PATCH 172/705] stubs: add qemu_ram_block_from_host() and qemu_ram_get_fd() The blkio block driver will need to look up the file descriptor for a given pointer. This is possible in softmmu builds where the RAMBlock API is available for querying guest RAM. Add stubs so tools like qemu-img that link the block layer still build successfully. In this case there is no guest RAM but that is fine. Bounce buffers and their file descriptors will be allocated with libblkio's blkio_alloc_mem_region() so we won't rely on QEMU's qemu_ram_get_fd() in that case. Signed-off-by: Stefan Hajnoczi Message-id: 20221013185908.1297568-12-stefanha@redhat.com Signed-off-by: Stefan Hajnoczi --- stubs/meson.build | 1 + stubs/physmem.c | 13 +++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 stubs/physmem.c diff --git a/stubs/meson.build b/stubs/meson.build index d8f3fd5c44..4314161f5f 100644 --- a/stubs/meson.build +++ b/stubs/meson.build @@ -29,6 +29,7 @@ stub_ss.add(files('migr-blocker.c')) stub_ss.add(files('module-opts.c')) stub_ss.add(files('monitor.c')) stub_ss.add(files('monitor-core.c')) +stub_ss.add(files('physmem.c')) stub_ss.add(files('qemu-timer-notify-cb.c')) stub_ss.add(files('qmp_memory_device.c')) stub_ss.add(files('qmp-command-available.c')) diff --git a/stubs/physmem.c b/stubs/physmem.c new file mode 100644 index 0000000000..1fc5f2df29 --- /dev/null +++ b/stubs/physmem.c @@ -0,0 +1,13 @@ +#include "qemu/osdep.h" +#include "exec/cpu-common.h" + +RAMBlock *qemu_ram_block_from_host(void *ptr, bool round_offset, + ram_addr_t *offset) +{ + return NULL; +} + +int qemu_ram_get_fd(RAMBlock *rb) +{ + return -1; +} From c5640b3e2f1146e8eea9f9f62db87713388d8bc8 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Thu, 13 Oct 2022 14:59:07 -0400 Subject: [PATCH 173/705] blkio: implement BDRV_REQ_REGISTERED_BUF optimization Avoid bounce buffers when QEMUIOVector elements are within previously registered bdrv_register_buf() buffers. The idea is that emulated storage controllers will register guest RAM using bdrv_register_buf() and set the BDRV_REQ_REGISTERED_BUF on I/O requests. Therefore no blkio_map_mem_region() calls are necessary in the performance-critical I/O code path. This optimization doesn't apply if the I/O buffer is internally allocated by QEMU (e.g. qcow2 metadata). There we still take the slow path because BDRV_REQ_REGISTERED_BUF is not set. Signed-off-by: Stefan Hajnoczi Reviewed-by: Stefano Garzarella Message-id: 20221013185908.1297568-13-stefanha@redhat.com Signed-off-by: Stefan Hajnoczi --- block/blkio.c | 183 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 180 insertions(+), 3 deletions(-) diff --git a/block/blkio.c b/block/blkio.c index b0cfd74b36..82f26eedd2 100644 --- a/block/blkio.c +++ b/block/blkio.c @@ -11,9 +11,13 @@ #include "qemu/osdep.h" #include #include "block/block_int.h" +#include "exec/memory.h" +#include "exec/cpu-common.h" /* for qemu_ram_get_fd() */ #include "qapi/error.h" +#include "qemu/error-report.h" #include "qapi/qmp/qdict.h" #include "qemu/module.h" +#include "exec/memory.h" /* for ram_block_discard_disable() */ /* * Keep the QEMU BlockDriver names identical to the libblkio driver names. @@ -73,6 +77,12 @@ typedef struct { /* Can we skip adding/deleting blkio_mem_regions? */ bool needs_mem_regions; + + /* Are file descriptors necessary for blkio_mem_regions? */ + bool needs_mem_region_fd; + + /* Are madvise(MADV_DONTNEED)-style operations unavailable? */ + bool may_pin_mem_regions; } BDRVBlkioState; /* Called with s->bounce_lock held */ @@ -347,7 +357,8 @@ blkio_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, .coroutine = qemu_coroutine_self(), }; BDRVBlkioState *s = bs->opaque; - bool use_bounce_buffer = s->needs_mem_regions; + bool use_bounce_buffer = + s->needs_mem_regions && !(flags & BDRV_REQ_REGISTERED_BUF); BlkioBounceBuf bounce; struct iovec *iov = qiov->iov; int iovcnt = qiov->niov; @@ -390,7 +401,8 @@ static int coroutine_fn blkio_co_pwritev(BlockDriverState *bs, int64_t offset, .coroutine = qemu_coroutine_self(), }; BDRVBlkioState *s = bs->opaque; - bool use_bounce_buffer = s->needs_mem_regions; + bool use_bounce_buffer = + s->needs_mem_regions && !(flags & BDRV_REQ_REGISTERED_BUF); BlkioBounceBuf bounce; struct iovec *iov = qiov->iov; int iovcnt = qiov->niov; @@ -473,6 +485,130 @@ static void blkio_io_unplug(BlockDriverState *bs) } } +typedef enum { + BMRR_OK, + BMRR_SKIP, + BMRR_FAIL, +} BlkioMemRegionResult; + +/* + * Produce a struct blkio_mem_region for a given address and size. + * + * This function produces identical results when called multiple times with the + * same arguments. This property is necessary because blkio_unmap_mem_region() + * must receive the same struct blkio_mem_region field values that were passed + * to blkio_map_mem_region(). + */ +static BlkioMemRegionResult +blkio_mem_region_from_host(BlockDriverState *bs, + void *host, size_t size, + struct blkio_mem_region *region, + Error **errp) +{ + BDRVBlkioState *s = bs->opaque; + int fd = -1; + ram_addr_t fd_offset = 0; + + if (((uintptr_t)host | size) % s->mem_region_alignment) { + error_setg(errp, "unaligned buf %p with size %zu", host, size); + return BMRR_FAIL; + } + + /* Attempt to find the fd for the underlying memory */ + if (s->needs_mem_region_fd) { + RAMBlock *ram_block; + RAMBlock *end_block; + ram_addr_t offset; + + /* + * bdrv_register_buf() is called with the BQL held so mr lives at least + * until this function returns. + */ + ram_block = qemu_ram_block_from_host(host, false, &fd_offset); + if (ram_block) { + fd = qemu_ram_get_fd(ram_block); + } + if (fd == -1) { + /* + * Ideally every RAMBlock would have an fd. pc-bios and other + * things don't. Luckily they are usually not I/O buffers and we + * can just ignore them. + */ + return BMRR_SKIP; + } + + /* Make sure the fd covers the entire range */ + end_block = qemu_ram_block_from_host(host + size - 1, false, &offset); + if (ram_block != end_block) { + error_setg(errp, "registered buffer at %p with size %zu extends " + "beyond RAMBlock", host, size); + return BMRR_FAIL; + } + } + + *region = (struct blkio_mem_region){ + .addr = host, + .len = size, + .fd = fd, + .fd_offset = fd_offset, + }; + return BMRR_OK; +} + +static bool blkio_register_buf(BlockDriverState *bs, void *host, size_t size, + Error **errp) +{ + BDRVBlkioState *s = bs->opaque; + struct blkio_mem_region region; + BlkioMemRegionResult region_result; + int ret; + + /* + * Mapping memory regions conflicts with RAM discard (virtio-mem) when + * there is pinning, so only do it when necessary. + */ + if (!s->needs_mem_regions && s->may_pin_mem_regions) { + return true; + } + + region_result = blkio_mem_region_from_host(bs, host, size, ®ion, errp); + if (region_result == BMRR_SKIP) { + return true; + } else if (region_result != BMRR_OK) { + return false; + } + + WITH_QEMU_LOCK_GUARD(&s->blkio_lock) { + ret = blkio_map_mem_region(s->blkio, ®ion); + } + + if (ret < 0) { + error_setg(errp, "Failed to add blkio mem region %p with size %zu: %s", + host, size, blkio_get_error_msg()); + return false; + } + return true; +} + +static void blkio_unregister_buf(BlockDriverState *bs, void *host, size_t size) +{ + BDRVBlkioState *s = bs->opaque; + struct blkio_mem_region region; + + /* See blkio_register_buf() */ + if (!s->needs_mem_regions && s->may_pin_mem_regions) { + return; + } + + if (blkio_mem_region_from_host(bs, host, size, ®ion, NULL) != BMRR_OK) { + return; + } + + WITH_QEMU_LOCK_GUARD(&s->blkio_lock) { + blkio_unmap_mem_region(s->blkio, ®ion); + } +} + static int blkio_io_uring_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) { @@ -609,6 +745,17 @@ static int blkio_file_open(BlockDriverState *bs, QDict *options, int flags, return ret; } + ret = blkio_get_bool(s->blkio, + "needs-mem-region-fd", + &s->needs_mem_region_fd); + if (ret < 0) { + error_setg_errno(errp, -ret, + "failed to get needs-mem-region-fd: %s", + blkio_get_error_msg()); + blkio_destroy(&s->blkio); + return ret; + } + ret = blkio_get_uint64(s->blkio, "mem-region-alignment", &s->mem_region_alignment); @@ -620,15 +767,39 @@ static int blkio_file_open(BlockDriverState *bs, QDict *options, int flags, return ret; } + ret = blkio_get_bool(s->blkio, + "may-pin-mem-regions", + &s->may_pin_mem_regions); + if (ret < 0) { + /* Be conservative (assume pinning) if the property is not supported */ + s->may_pin_mem_regions = s->needs_mem_regions; + } + + /* + * Notify if libblkio drivers pin memory and prevent features like + * virtio-mem from working. + */ + if (s->may_pin_mem_regions) { + ret = ram_block_discard_disable(true); + if (ret < 0) { + error_setg_errno(errp, -ret, "ram_block_discard_disable() failed"); + blkio_destroy(&s->blkio); + return ret; + } + } + ret = blkio_start(s->blkio); if (ret < 0) { error_setg_errno(errp, -ret, "blkio_start failed: %s", blkio_get_error_msg()); blkio_destroy(&s->blkio); + if (s->may_pin_mem_regions) { + ram_block_discard_disable(false); + } return ret; } - bs->supported_write_flags = BDRV_REQ_FUA; + bs->supported_write_flags = BDRV_REQ_FUA | BDRV_REQ_REGISTERED_BUF; bs->supported_zero_flags = BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK; @@ -652,6 +823,10 @@ static void blkio_close(BlockDriverState *bs) qemu_mutex_destroy(&s->blkio_lock); blkio_detach_aio_context(bs); blkio_destroy(&s->blkio); + + if (s->may_pin_mem_regions) { + ram_block_discard_disable(false); + } } static int64_t blkio_getlength(BlockDriverState *bs) @@ -799,6 +974,8 @@ static void blkio_refresh_limits(BlockDriverState *bs, Error **errp) .bdrv_co_pwrite_zeroes = blkio_co_pwrite_zeroes, \ .bdrv_io_unplug = blkio_io_unplug, \ .bdrv_refresh_limits = blkio_refresh_limits, \ + .bdrv_register_buf = blkio_register_buf, \ + .bdrv_unregister_buf = blkio_unregister_buf, \ __VA_ARGS__ \ } From baf422684d73c7bf38e2c18815e18d44fcf395b6 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Thu, 13 Oct 2022 14:59:08 -0400 Subject: [PATCH 174/705] virtio-blk: use BDRV_REQ_REGISTERED_BUF optimization hint Register guest RAM using BlockRAMRegistrar and set the BDRV_REQ_REGISTERED_BUF flag so block drivers can optimize memory accesses in I/O requests. This is for vdpa-blk, vhost-user-blk, and other I/O interfaces that rely on DMA mapping/unmapping. Signed-off-by: Stefan Hajnoczi Reviewed-by: Stefano Garzarella Message-id: 20221013185908.1297568-14-stefanha@redhat.com Signed-off-by: Stefan Hajnoczi --- hw/block/virtio-blk.c | 39 ++++++++++++++++++++++------------ include/hw/virtio/virtio-blk.h | 2 ++ 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index 8131ec2dbc..f717550fdc 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -21,6 +21,7 @@ #include "hw/block/block.h" #include "hw/qdev-properties.h" #include "sysemu/blockdev.h" +#include "sysemu/block-ram-registrar.h" #include "sysemu/sysemu.h" #include "sysemu/runstate.h" #include "hw/virtio/virtio-blk.h" @@ -362,12 +363,14 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req) } } -static inline void submit_requests(BlockBackend *blk, MultiReqBuffer *mrb, +static inline void submit_requests(VirtIOBlock *s, MultiReqBuffer *mrb, int start, int num_reqs, int niov) { + BlockBackend *blk = s->blk; QEMUIOVector *qiov = &mrb->reqs[start]->qiov; int64_t sector_num = mrb->reqs[start]->sector_num; bool is_write = mrb->is_write; + BdrvRequestFlags flags = 0; if (num_reqs > 1) { int i; @@ -398,12 +401,18 @@ static inline void submit_requests(BlockBackend *blk, MultiReqBuffer *mrb, num_reqs - 1); } + if (blk_ram_registrar_ok(&s->blk_ram_registrar)) { + flags |= BDRV_REQ_REGISTERED_BUF; + } + if (is_write) { - blk_aio_pwritev(blk, sector_num << BDRV_SECTOR_BITS, qiov, 0, - virtio_blk_rw_complete, mrb->reqs[start]); + blk_aio_pwritev(blk, sector_num << BDRV_SECTOR_BITS, qiov, + flags, virtio_blk_rw_complete, + mrb->reqs[start]); } else { - blk_aio_preadv(blk, sector_num << BDRV_SECTOR_BITS, qiov, 0, - virtio_blk_rw_complete, mrb->reqs[start]); + blk_aio_preadv(blk, sector_num << BDRV_SECTOR_BITS, qiov, + flags, virtio_blk_rw_complete, + mrb->reqs[start]); } } @@ -425,14 +434,14 @@ static int multireq_compare(const void *a, const void *b) } } -static void virtio_blk_submit_multireq(BlockBackend *blk, MultiReqBuffer *mrb) +static void virtio_blk_submit_multireq(VirtIOBlock *s, MultiReqBuffer *mrb) { int i = 0, start = 0, num_reqs = 0, niov = 0, nb_sectors = 0; uint32_t max_transfer; int64_t sector_num = 0; if (mrb->num_reqs == 1) { - submit_requests(blk, mrb, 0, 1, -1); + submit_requests(s, mrb, 0, 1, -1); mrb->num_reqs = 0; return; } @@ -452,11 +461,11 @@ static void virtio_blk_submit_multireq(BlockBackend *blk, MultiReqBuffer *mrb) * 3. merge would exceed maximum transfer length of backend device */ if (sector_num + nb_sectors != req->sector_num || - niov > blk_get_max_iov(blk) - req->qiov.niov || + niov > blk_get_max_iov(s->blk) - req->qiov.niov || req->qiov.size > max_transfer || nb_sectors > (max_transfer - req->qiov.size) / BDRV_SECTOR_SIZE) { - submit_requests(blk, mrb, start, num_reqs, niov); + submit_requests(s, mrb, start, num_reqs, niov); num_reqs = 0; } } @@ -472,7 +481,7 @@ static void virtio_blk_submit_multireq(BlockBackend *blk, MultiReqBuffer *mrb) num_reqs++; } - submit_requests(blk, mrb, start, num_reqs, niov); + submit_requests(s, mrb, start, num_reqs, niov); mrb->num_reqs = 0; } @@ -487,7 +496,7 @@ static void virtio_blk_handle_flush(VirtIOBlockReq *req, MultiReqBuffer *mrb) * Make sure all outstanding writes are posted to the backing device. */ if (mrb->is_write && mrb->num_reqs > 0) { - virtio_blk_submit_multireq(s->blk, mrb); + virtio_blk_submit_multireq(s, mrb); } blk_aio_flush(s->blk, virtio_blk_flush_complete, req); } @@ -667,7 +676,7 @@ static int virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb) if (mrb->num_reqs > 0 && (mrb->num_reqs == VIRTIO_BLK_MAX_MERGE_REQS || is_write != mrb->is_write || !s->conf.request_merging)) { - virtio_blk_submit_multireq(s->blk, mrb); + virtio_blk_submit_multireq(s, mrb); } assert(mrb->num_reqs < VIRTIO_BLK_MAX_MERGE_REQS); @@ -774,7 +783,7 @@ void virtio_blk_handle_vq(VirtIOBlock *s, VirtQueue *vq) } while (!virtio_queue_empty(vq)); if (mrb.num_reqs) { - virtio_blk_submit_multireq(s->blk, &mrb); + virtio_blk_submit_multireq(s, &mrb); } blk_io_unplug(s->blk); @@ -823,7 +832,7 @@ void virtio_blk_process_queued_requests(VirtIOBlock *s, bool is_bh) } if (mrb.num_reqs) { - virtio_blk_submit_multireq(s->blk, &mrb); + virtio_blk_submit_multireq(s, &mrb); } if (is_bh) { blk_dec_in_flight(s->conf.conf.blk); @@ -1205,6 +1214,7 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp) } s->change = qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s); + blk_ram_registrar_init(&s->blk_ram_registrar, s->blk); blk_set_dev_ops(s->blk, &virtio_block_ops, s); blk_iostatus_enable(s->blk); @@ -1230,6 +1240,7 @@ static void virtio_blk_device_unrealize(DeviceState *dev) virtio_del_queue(vdev, i); } qemu_coroutine_dec_pool_size(conf->num_queues * conf->queue_size / 2); + blk_ram_registrar_destroy(&s->blk_ram_registrar); qemu_del_vm_change_state_handler(s->change); blockdev_mark_auto_del(s->blk); virtio_cleanup(vdev); diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h index d311c57cca..7f589b4146 100644 --- a/include/hw/virtio/virtio-blk.h +++ b/include/hw/virtio/virtio-blk.h @@ -19,6 +19,7 @@ #include "hw/block/block.h" #include "sysemu/iothread.h" #include "sysemu/block-backend.h" +#include "sysemu/block-ram-registrar.h" #include "qom/object.h" #define TYPE_VIRTIO_BLK "virtio-blk-device" @@ -64,6 +65,7 @@ struct VirtIOBlock { struct VirtIOBlockDataPlane *dataplane; uint64_t host_features; size_t config_size; + BlockRAMRegistrar blk_ram_registrar; }; typedef struct VirtIOBlockReq { From 41bf9322a0f8378b1194324cf7c6048253673046 Mon Sep 17 00:00:00 2001 From: Muhammad Moinur Rahman Date: Wed, 12 Oct 2022 12:52:22 -0600 Subject: [PATCH 175/705] bsd-user: Catch up with sys/param.h requirement for machine/pmap.h Some versions of FreeBSD now require sys/param.h for machine/pmap.h on x86. Include them here to meet that requirement. It does no harm on older versions, so there's no need to #ifdef it. Signed-off-by: Muhammad Moinur Rahman Reviewed-by: John Baldwin Signed-off-by: Warner Losh --- bsd-user/host/i386/host-signal.h | 1 + bsd-user/host/x86_64/host-signal.h | 1 + 2 files changed, 2 insertions(+) diff --git a/bsd-user/host/i386/host-signal.h b/bsd-user/host/i386/host-signal.h index 169e61b154..ffdfaba534 100644 --- a/bsd-user/host/i386/host-signal.h +++ b/bsd-user/host/i386/host-signal.h @@ -9,6 +9,7 @@ #ifndef I386_HOST_SIGNAL_H #define I386_HOST_SIGNAL_H +#include #include #include #include diff --git a/bsd-user/host/x86_64/host-signal.h b/bsd-user/host/x86_64/host-signal.h index 47ca19f881..32ac4e4180 100644 --- a/bsd-user/host/x86_64/host-signal.h +++ b/bsd-user/host/x86_64/host-signal.h @@ -9,6 +9,7 @@ #ifndef X86_64_HOST_SIGNAL_H #define X86_64_HOST_SIGNAL_H +#include #include #include #include From 3f7febc93785bf0e622072b01f846d2acbcd9c0b Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 12 Oct 2022 17:37:58 +0200 Subject: [PATCH 176/705] qom: Improve error messages when property has no getter or setter When you try to set a property that has no setter, the error message blames "insufficient permission": $ qemu-system-x86_64 -S -display none -nodefaults -monitor stdio QEMU 7.1.50 monitor - type 'help' for more information (qemu) qom-set /machine type q35 Error: Insufficient permission to perform this operation This implies it could work with "sufficient permission". It can't. Change the error message to: Error: Property 'pc-i440fx-7.2-machine.type' is not writable Do the same for getting a property that has no getter. Signed-off-by: Markus Armbruster Message-Id: <20221012153801.2604340-2-armbru@redhat.com> Reviewed-by: David Hildenbrand --- qom/object.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/qom/object.c b/qom/object.c index d34608558e..e5cef30f6d 100644 --- a/qom/object.c +++ b/qom/object.c @@ -1383,7 +1383,8 @@ bool object_property_get(Object *obj, const char *name, Visitor *v, } if (!prop->get) { - error_setg(errp, QERR_PERMISSION_DENIED); + error_setg(errp, "Property '%s.%s' is not readable", + object_get_typename(obj), name); return false; } prop->get(obj, v, name, prop->opaque, &err); @@ -1402,7 +1403,8 @@ bool object_property_set(Object *obj, const char *name, Visitor *v, } if (!prop->set) { - error_setg(errp, QERR_PERMISSION_DENIED); + error_setg(errp, "Property '%s.%s' is not writable", + object_get_typename(obj), name); return false; } prop->set(obj, v, name, prop->opaque, errp); From ff924448849f4fca48df15ecad67dc93854392e5 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 12 Oct 2022 17:37:59 +0200 Subject: [PATCH 177/705] backends: Improve error messages when property can no longer be set When you try to set virtio-rng property "filename" after the backend has been completed with user_creatable_complete(), the error message blames "insufficient permission": $ qemu-system-x86_64 -S -display none -nodefaults -monitor stdio -object rng-random,id=rng0 -device virtio-rng,id=vrng0,rng=rng0 QEMU 7.1.50 monitor - type 'help' for more information (qemu) qom-set /objects/rng0 filename /dev/random Error: Insufficient permission to perform this operation This implies it could work with "sufficient permission". It can't. Change the error message to: Error: Property 'filename' can no longer be set Same for cryptodev-vhost-user property "chardev", rng-egd property "chardev", and vhost-user-backend property "chardev". Signed-off-by: Markus Armbruster Message-Id: <20221012153801.2604340-3-armbru@redhat.com> Acked-by: Michael S. Tsirkin [Commit message tidied up] --- backends/cryptodev-vhost-user.c | 2 +- backends/rng-egd.c | 2 +- backends/rng-random.c | 2 +- backends/vhost-user.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/backends/cryptodev-vhost-user.c b/backends/cryptodev-vhost-user.c index 5443a59153..f9c5867e38 100644 --- a/backends/cryptodev-vhost-user.c +++ b/backends/cryptodev-vhost-user.c @@ -339,7 +339,7 @@ static void cryptodev_vhost_user_set_chardev(Object *obj, CRYPTODEV_BACKEND_VHOST_USER(obj); if (s->opened) { - error_setg(errp, QERR_PERMISSION_DENIED); + error_setg(errp, "Property 'chardev' can no longer be set"); } else { g_free(s->chr_name); s->chr_name = g_strdup(value); diff --git a/backends/rng-egd.c b/backends/rng-egd.c index 4de142b9dc..684c3cf3d6 100644 --- a/backends/rng-egd.c +++ b/backends/rng-egd.c @@ -116,7 +116,7 @@ static void rng_egd_set_chardev(Object *obj, const char *value, Error **errp) RngEgd *s = RNG_EGD(b); if (b->opened) { - error_setg(errp, QERR_PERMISSION_DENIED); + error_setg(errp, "Property 'chardev' can no longer be set"); } else { g_free(s->chr_name); s->chr_name = g_strdup(value); diff --git a/backends/rng-random.c b/backends/rng-random.c index 7add272edd..80eb5be138 100644 --- a/backends/rng-random.c +++ b/backends/rng-random.c @@ -96,7 +96,7 @@ static void rng_random_set_filename(Object *obj, const char *filename, RngRandom *s = RNG_RANDOM(obj); if (b->opened) { - error_setg(errp, QERR_PERMISSION_DENIED); + error_setg(errp, "Property 'filename' can no longer be set"); return; } diff --git a/backends/vhost-user.c b/backends/vhost-user.c index 10b39992d2..5dedb2d987 100644 --- a/backends/vhost-user.c +++ b/backends/vhost-user.c @@ -141,7 +141,7 @@ static void set_chardev(Object *obj, const char *value, Error **errp) Chardev *chr; if (b->completed) { - error_setg(errp, QERR_PERMISSION_DENIED); + error_setg(errp, "Property 'chardev' can no longer be set"); return; } From 8d095933148a0a88ecf1b6bccbbe4ce6c248e2cd Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 12 Oct 2022 17:38:00 +0200 Subject: [PATCH 178/705] qtest: Improve error messages when property can not be set right now When you try to set qtest property "log" while the qtest object is active, the error message blames "insufficient permission": $ qemu-system-x86_64 -S -display none -nodefaults -monitor stdio -chardev socket,id=chrqt0,path=qtest.socket,server=on,wait=off -object qtest,id=qt0,chardev=chrqt0,log=/dev/null QEMU 7.1.50 monitor - type 'help' for more information (qemu) qom-set /objects/qt0 log qtest.log Error: Insufficient permission to perform this operation This implies it could work with "sufficient permission". It can't. Change the error message to: Error: Property 'log' can not be set now Same for property "chardev". Signed-off-by: Markus Armbruster Message-Id: <20221012153801.2604340-4-armbru@redhat.com> --- softmmu/qtest.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/softmmu/qtest.c b/softmmu/qtest.c index f8acef2628..afea7693d0 100644 --- a/softmmu/qtest.c +++ b/softmmu/qtest.c @@ -977,7 +977,7 @@ static void qtest_set_log(Object *obj, const char *value, Error **errp) QTest *q = QTEST(obj); if (qtest == q) { - error_setg(errp, QERR_PERMISSION_DENIED); + error_setg(errp, "Property 'log' can not be set now"); } else { g_free(q->log); q->log = g_strdup(value); @@ -997,7 +997,7 @@ static void qtest_set_chardev(Object *obj, const char *value, Error **errp) Chardev *chr; if (qtest == q) { - error_setg(errp, QERR_PERMISSION_DENIED); + error_setg(errp, "Property 'chardev' can not be set now"); return; } From 0dddb0fc80f83d3bb469dc220ba8e2496b27a205 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 12 Oct 2022 17:38:01 +0200 Subject: [PATCH 179/705] qerror: QERR_PERMISSION_DENIED is no longer used, drop Signed-off-by: Markus Armbruster Message-Id: <20221012153801.2604340-5-armbru@redhat.com> --- include/qapi/qmp/qerror.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/qapi/qmp/qerror.h b/include/qapi/qmp/qerror.h index 596fce0c54..87ca83b155 100644 --- a/include/qapi/qmp/qerror.h +++ b/include/qapi/qmp/qerror.h @@ -50,9 +50,6 @@ #define QERR_MISSING_PARAMETER \ "Parameter '%s' is missing" -#define QERR_PERMISSION_DENIED \ - "Insufficient permission to perform this operation" - #define QERR_PROPERTY_VALUE_BAD \ "Property '%s.%s' doesn't take value '%s'" From 36c182bbe680d64f0868522bb9256b5b8eccf280 Mon Sep 17 00:00:00 2001 From: Claudio Imbrenda Date: Mon, 10 Oct 2022 17:10:41 +0200 Subject: [PATCH 180/705] s390x/pv: remove semicolon from macro definition Remove spurious semicolon at the end of the macro s390_pv_cmd Signed-off-by: Claudio Imbrenda Acked-by: Cornelia Huck Message-Id: <20221010151041.89071-1-imbrenda@linux.ibm.com> Signed-off-by: Thomas Huth --- hw/s390x/pv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/s390x/pv.c b/hw/s390x/pv.c index 728ba24547..8dfe92d8df 100644 --- a/hw/s390x/pv.c +++ b/hw/s390x/pv.c @@ -50,7 +50,7 @@ static int __s390_pv_cmd(uint32_t cmd, const char *cmdname, void *data) * This macro lets us pass the command as a string to the function so * we can print it on an error. */ -#define s390_pv_cmd(cmd, data) __s390_pv_cmd(cmd, #cmd, data); +#define s390_pv_cmd(cmd, data) __s390_pv_cmd(cmd, #cmd, data) #define s390_pv_cmd_exit(cmd, data) \ { \ int rc; \ From d001a81256d1291319e13711f73d1f436beb81af Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Mon, 10 Oct 2022 18:09:57 +0200 Subject: [PATCH 181/705] s390x: step down as general arch maintainer I haven't really been working on s390x for some time now, and in practice, I don't have time for it, either. So let's remove myself from this entry. Signed-off-by: Cornelia Huck Message-Id: <20221010160957.40779-1-cohuck@redhat.com> Signed-off-by: Thomas Huth --- MAINTAINERS | 2 -- 1 file changed, 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 32e495e165..17ff0a0138 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -84,7 +84,6 @@ T: git https://github.com/vivier/qemu.git trivial-patches Architecture support -------------------- S390 general architecture support -M: Cornelia Huck M: Thomas Huth S: Supported F: configs/devices/s390x-softmmu/default.mak @@ -106,7 +105,6 @@ F: docs/system/target-s390x.rst F: docs/system/s390x/ F: tests/migration/s390x/ K: ^Subject:.*(?i)s390x? -T: git https://gitlab.com/cohuck/qemu.git s390-next L: qemu-s390x@nongnu.org MIPS general architecture support From 38621181ae3cbec62e3490fbc14f6ac01642d07a Mon Sep 17 00:00:00 2001 From: Nico Boehr Date: Wed, 12 Oct 2022 14:32:29 +0200 Subject: [PATCH 182/705] s390x/tod-kvm: don't save/restore the TOD in PV guests Under PV, the guest's TOD clock is under control of the ultravisor and the hypervisor cannot change it. With upcoming kernel changes[1], the Linux kernel will reject QEMU's request to adjust the guest's clock in this case, so don't attempt to set the clock. This avoids the following warning message on save/restore of a PV guest: warning: Unable to set KVM guest TOD clock: Operation not supported [1] https://lore.kernel.org/all/20221011160712.928239-2-nrb@linux.ibm.com/ Fixes: c3347ed0d2ee ("s390x: protvirt: Support unpack facility") Signed-off-by: Nico Boehr Message-Id: <20221012123229.1196007-1-nrb@linux.ibm.com> [thuth: Add curly braces] Signed-off-by: Thomas Huth --- hw/s390x/tod-kvm.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/hw/s390x/tod-kvm.c b/hw/s390x/tod-kvm.c index 9d0cbfbce2..e2202dae2d 100644 --- a/hw/s390x/tod-kvm.c +++ b/hw/s390x/tod-kvm.c @@ -13,6 +13,7 @@ #include "qemu/module.h" #include "sysemu/runstate.h" #include "hw/s390x/tod.h" +#include "hw/s390x/pv.h" #include "kvm/kvm_s390x.h" static void kvm_s390_get_tod_raw(S390TOD *tod, Error **errp) @@ -84,6 +85,14 @@ static void kvm_s390_tod_vm_state_change(void *opaque, bool running, S390TODState *td = opaque; Error *local_err = NULL; + /* + * Under PV, the clock is under ultravisor control, hence we cannot restore + * it on resume. + */ + if (s390_is_pv()) { + return; + } + if (running && td->stopped) { /* Set the old TOD when running the VM - start the TOD clock. */ kvm_s390_set_tod_raw(&td->base, &local_err); From 117ea96089e36a4d31a42f96062b950641ba1698 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Wed, 12 Oct 2022 20:27:53 +0200 Subject: [PATCH 183/705] tests/tcg/s390x: Test compiler flags only once, not every time MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is common practice, see the Makefile.target in the aarch64 folder for example. Suggested-by: Alex Bennée Message-Id: <20221012182755.1014853-2-thuth@redhat.com> Reviewed-by: Richard Henderson Reviewed-by: David Hildenbrand Signed-off-by: Thomas Huth --- tests/tcg/s390x/Makefile.target | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/tests/tcg/s390x/Makefile.target b/tests/tcg/s390x/Makefile.target index c830313e67..29c8af8207 100644 --- a/tests/tcg/s390x/Makefile.target +++ b/tests/tcg/s390x/Makefile.target @@ -1,6 +1,13 @@ S390X_SRC=$(SRC_PATH)/tests/tcg/s390x VPATH+=$(S390X_SRC) CFLAGS+=-march=zEC12 -m64 + +config-cc.mak: Makefile + $(quiet-@)( \ + $(call cc-option,-march=z14, CROSS_CC_HAS_Z14); \ + $(call cc-option,-march=z15, CROSS_CC_HAS_Z15)) 3> config-cc.mak +-include config-cc.mak + TESTS+=hello-s390x TESTS+=csst TESTS+=ipm @@ -18,20 +25,20 @@ TESTS+=signals-s390x TESTS+=branch-relative-long TESTS+=noexec +ifneq ($(CROSS_CC_HAS_Z14),) Z14_TESTS=vfminmax vfminmax: LDFLAGS+=-lm $(Z14_TESTS): CFLAGS+=-march=z14 -O2 +TESTS+=$(Z14_TESTS) +endif -TESTS+=$(if $(shell $(CC) -march=z14 -S -o /dev/null -xc /dev/null \ - >/dev/null 2>&1 && echo OK),$(Z14_TESTS)) - -VECTOR_TESTS=vxeh2_vs -VECTOR_TESTS+=vxeh2_vcvt -VECTOR_TESTS+=vxeh2_vlstr -$(VECTOR_TESTS): CFLAGS+=-march=z15 -O2 - -TESTS+=$(if $(shell $(CC) -march=z15 -S -o /dev/null -xc /dev/null \ - >/dev/null 2>&1 && echo OK),$(VECTOR_TESTS)) +ifneq ($(CROSS_CC_HAS_Z15),) +Z15_TESTS=vxeh2_vs +Z15_TESTS+=vxeh2_vcvt +Z15_TESTS+=vxeh2_vlstr +$(Z15_TESTS): CFLAGS+=-march=z15 -O2 +TESTS+=$(Z15_TESTS) +endif ifneq ($(HAVE_GDB_BIN),) GDB_SCRIPT=$(SRC_PATH)/tests/guest-debug/run-test.py From f7d81a351d6122440f9190adba69da3f81b7b186 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Wed, 12 Oct 2022 20:27:54 +0200 Subject: [PATCH 184/705] target/s390x: Fix emulation of the VISTR instruction The element size is encoded in the M3 field, not in the M4 field. Fixes: be6324c6b734 ("s390x/tcg: Implement VECTOR ISOLATE STRING") Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1248 Message-Id: <20221012182755.1014853-3-thuth@redhat.com> Reviewed-by: Richard Henderson Reviewed-by: David Hildenbrand Signed-off-by: Thomas Huth --- target/s390x/tcg/translate_vx.c.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/s390x/tcg/translate_vx.c.inc b/target/s390x/tcg/translate_vx.c.inc index 3526ba3e3b..b69c1a111c 100644 --- a/target/s390x/tcg/translate_vx.c.inc +++ b/target/s390x/tcg/translate_vx.c.inc @@ -2723,7 +2723,7 @@ static DisasJumpType op_vfene(DisasContext *s, DisasOps *o) static DisasJumpType op_vistr(DisasContext *s, DisasOps *o) { - const uint8_t es = get_field(s, m4); + const uint8_t es = get_field(s, m3); const uint8_t m5 = get_field(s, m5); static gen_helper_gvec_2 * const g[3] = { gen_helper_gvec_vistr8, From 6556aadc18c560e493b29dd99cae2cbf86d214cb Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Fri, 14 Oct 2022 15:47:14 +0200 Subject: [PATCH 185/705] util: Cleanup and rename os_mem_prealloc() Let's * give the function a "qemu_*" style name * make sure the parameters in the implementation match the prototype * rename smp_cpus to max_threads, which makes the semantics of that parameter clearer ... and add a function documentation. Reviewed-by: Michal Privoznik Message-Id: <20221014134720.168738-2-david@redhat.com> Signed-off-by: David Hildenbrand --- backends/hostmem.c | 6 +++--- hw/virtio/virtio-mem.c | 2 +- include/qemu/osdep.h | 17 +++++++++++++++-- softmmu/cpus.c | 2 +- util/oslib-posix.c | 24 ++++++++++++------------ util/oslib-win32.c | 8 ++++---- 6 files changed, 36 insertions(+), 23 deletions(-) diff --git a/backends/hostmem.c b/backends/hostmem.c index 4428e06738..491cb10b97 100644 --- a/backends/hostmem.c +++ b/backends/hostmem.c @@ -232,7 +232,7 @@ static void host_memory_backend_set_prealloc(Object *obj, bool value, void *ptr = memory_region_get_ram_ptr(&backend->mr); uint64_t sz = memory_region_size(&backend->mr); - os_mem_prealloc(fd, ptr, sz, backend->prealloc_threads, &local_err); + qemu_prealloc_mem(fd, ptr, sz, backend->prealloc_threads, &local_err); if (local_err) { error_propagate(errp, local_err); return; @@ -383,8 +383,8 @@ host_memory_backend_memory_complete(UserCreatable *uc, Error **errp) * specified NUMA policy in place. */ if (backend->prealloc) { - os_mem_prealloc(memory_region_get_fd(&backend->mr), ptr, sz, - backend->prealloc_threads, &local_err); + qemu_prealloc_mem(memory_region_get_fd(&backend->mr), ptr, sz, + backend->prealloc_threads, &local_err); if (local_err) { goto out; } diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c index 30d03e987a..0e9ef4ff19 100644 --- a/hw/virtio/virtio-mem.c +++ b/hw/virtio/virtio-mem.c @@ -467,7 +467,7 @@ static int virtio_mem_set_block_state(VirtIOMEM *vmem, uint64_t start_gpa, int fd = memory_region_get_fd(&vmem->memdev->mr); Error *local_err = NULL; - os_mem_prealloc(fd, area, size, 1, &local_err); + qemu_prealloc_mem(fd, area, size, 1, &local_err); if (local_err) { static bool warned; diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index b1c161c035..e556e45143 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -568,8 +568,21 @@ unsigned long qemu_getauxval(unsigned long type); void qemu_set_tty_echo(int fd, bool echo); -void os_mem_prealloc(int fd, char *area, size_t sz, int smp_cpus, - Error **errp); +/** + * qemu_prealloc_mem: + * @fd: the fd mapped into the area, -1 for anonymous memory + * @area: start address of the are to preallocate + * @sz: the size of the area to preallocate + * @max_threads: maximum number of threads to use + * @errp: returns an error if this function fails + * + * Preallocate memory (populate/prefault page tables writable) for the virtual + * memory area starting at @area with the size of @sz. After a successful call, + * each page in the area was faulted in writable at least once, for example, + * after allocating file blocks for mapped files. + */ +void qemu_prealloc_mem(int fd, char *area, size_t sz, int max_threads, + Error **errp); /** * qemu_get_pid_name: diff --git a/softmmu/cpus.c b/softmmu/cpus.c index 61b27ff59d..01c94fd298 100644 --- a/softmmu/cpus.c +++ b/softmmu/cpus.c @@ -354,7 +354,7 @@ static void qemu_init_sigbus(void) /* * ALERT: when modifying this, take care that SIGBUS forwarding in - * os_mem_prealloc() will continue working as expected. + * qemu_prealloc_mem() will continue working as expected. */ memset(&action, 0, sizeof(action)); action.sa_flags = SA_SIGINFO; diff --git a/util/oslib-posix.c b/util/oslib-posix.c index 827a7aadba..905cbc27cc 100644 --- a/util/oslib-posix.c +++ b/util/oslib-posix.c @@ -329,7 +329,7 @@ static void sigbus_handler(int signal) return; } #endif /* CONFIG_LINUX */ - warn_report("os_mem_prealloc: unrelated SIGBUS detected and ignored"); + warn_report("qemu_prealloc_mem: unrelated SIGBUS detected and ignored"); } static void *do_touch_pages(void *arg) @@ -399,13 +399,13 @@ static void *do_madv_populate_write_pages(void *arg) } static inline int get_memset_num_threads(size_t hpagesize, size_t numpages, - int smp_cpus) + int max_threads) { long host_procs = sysconf(_SC_NPROCESSORS_ONLN); int ret = 1; if (host_procs > 0) { - ret = MIN(MIN(host_procs, MAX_MEM_PREALLOC_THREAD_COUNT), smp_cpus); + ret = MIN(MIN(host_procs, MAX_MEM_PREALLOC_THREAD_COUNT), max_threads); } /* Especially with gigantic pages, don't create more threads than pages. */ @@ -418,11 +418,11 @@ static inline int get_memset_num_threads(size_t hpagesize, size_t numpages, } static int touch_all_pages(char *area, size_t hpagesize, size_t numpages, - int smp_cpus, bool use_madv_populate_write) + int max_threads, bool use_madv_populate_write) { static gsize initialized = 0; MemsetContext context = { - .num_threads = get_memset_num_threads(hpagesize, numpages, smp_cpus), + .num_threads = get_memset_num_threads(hpagesize, numpages, max_threads), }; size_t numpages_per_thread, leftover; void *(*touch_fn)(void *); @@ -494,13 +494,13 @@ static bool madv_populate_write_possible(char *area, size_t pagesize) errno != EINVAL; } -void os_mem_prealloc(int fd, char *area, size_t memory, int smp_cpus, - Error **errp) +void qemu_prealloc_mem(int fd, char *area, size_t sz, int max_threads, + Error **errp) { static gsize initialized; int ret; size_t hpagesize = qemu_fd_getpagesize(fd); - size_t numpages = DIV_ROUND_UP(memory, hpagesize); + size_t numpages = DIV_ROUND_UP(sz, hpagesize); bool use_madv_populate_write; struct sigaction act; @@ -530,24 +530,24 @@ void os_mem_prealloc(int fd, char *area, size_t memory, int smp_cpus, if (ret) { qemu_mutex_unlock(&sigbus_mutex); error_setg_errno(errp, errno, - "os_mem_prealloc: failed to install signal handler"); + "qemu_prealloc_mem: failed to install signal handler"); return; } } /* touch pages simultaneously */ - ret = touch_all_pages(area, hpagesize, numpages, smp_cpus, + ret = touch_all_pages(area, hpagesize, numpages, max_threads, use_madv_populate_write); if (ret) { error_setg_errno(errp, -ret, - "os_mem_prealloc: preallocating memory failed"); + "qemu_prealloc_mem: preallocating memory failed"); } if (!use_madv_populate_write) { ret = sigaction(SIGBUS, &sigbus_oldact, NULL); if (ret) { /* Terminate QEMU since it can't recover from error */ - perror("os_mem_prealloc: failed to reinstall signal handler"); + perror("qemu_prealloc_mem: failed to reinstall signal handler"); exit(1); } qemu_mutex_unlock(&sigbus_mutex); diff --git a/util/oslib-win32.c b/util/oslib-win32.c index 5723d3eb4c..e1cb725ecc 100644 --- a/util/oslib-win32.c +++ b/util/oslib-win32.c @@ -268,14 +268,14 @@ int getpagesize(void) return system_info.dwPageSize; } -void os_mem_prealloc(int fd, char *area, size_t memory, int smp_cpus, - Error **errp) +void qemu_prealloc_mem(int fd, char *area, size_t sz, int max_threads, + Error **errp) { int i; size_t pagesize = qemu_real_host_page_size(); - memory = (memory + pagesize - 1) & -pagesize; - for (i = 0; i < memory / pagesize; i++) { + sz = (sz + pagesize - 1) & -pagesize; + for (i = 0; i < sz / pagesize; i++) { memset(area + pagesize * i, 0, 1); } } From 7730f32c281f6005b5d35e0ba4b537a47d2dbf32 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Fri, 14 Oct 2022 15:47:15 +0200 Subject: [PATCH 186/705] util: Introduce qemu_thread_set_affinity() and qemu_thread_get_affinity() Usually, we let upper layers handle CPU pinning, because pthread_setaffinity_np() (-> sched_setaffinity()) is blocked via seccomp when starting QEMU with -sandbox enable=on,resourcecontrol=deny However, we want to configure and observe the CPU affinity of threads from QEMU directly in some cases when the sandbox option is either not enabled or not active yet. So let's add a way to configure CPU pinning via qemu_thread_set_affinity() and obtain CPU affinity via qemu_thread_get_affinity() and implement them under POSIX using pthread_setaffinity_np() + pthread_getaffinity_np(). Implementation under Windows is possible using SetProcessAffinityMask() + GetProcessAffinityMask(), however, that is left as future work. Reviewed-by: Michal Privoznik Message-Id: <20221014134720.168738-3-david@redhat.com> Signed-off-by: David Hildenbrand --- include/qemu/thread.h | 4 +++ meson.build | 16 +++++++++ util/qemu-thread-posix.c | 70 ++++++++++++++++++++++++++++++++++++++++ util/qemu-thread-win32.c | 12 +++++++ 4 files changed, 102 insertions(+) diff --git a/include/qemu/thread.h b/include/qemu/thread.h index af19f2b3fc..79e507c7f0 100644 --- a/include/qemu/thread.h +++ b/include/qemu/thread.h @@ -185,6 +185,10 @@ void qemu_event_destroy(QemuEvent *ev); void qemu_thread_create(QemuThread *thread, const char *name, void *(*start_routine)(void *), void *arg, int mode); +int qemu_thread_set_affinity(QemuThread *thread, unsigned long *host_cpus, + unsigned long nbits); +int qemu_thread_get_affinity(QemuThread *thread, unsigned long **host_cpus, + unsigned long *nbits); void *qemu_thread_join(QemuThread *thread); void qemu_thread_get_self(QemuThread *thread); bool qemu_thread_is_self(QemuThread *thread); diff --git a/meson.build b/meson.build index b686dfef75..3e0aa4925d 100644 --- a/meson.build +++ b/meson.build @@ -2114,7 +2114,23 @@ config_host_data.set('CONFIG_PTHREAD_CONDATTR_SETCLOCK', cc.links(gnu_source_pre pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); return 0; }''', dependencies: threads)) +config_host_data.set('CONFIG_PTHREAD_AFFINITY_NP', cc.links(gnu_source_prefix + ''' + #include + static void *f(void *p) { return NULL; } + int main(void) + { + int setsize = CPU_ALLOC_SIZE(64); + pthread_t thread; + cpu_set_t *cpuset; + pthread_create(&thread, 0, f, 0); + cpuset = CPU_ALLOC(64); + CPU_ZERO_S(setsize, cpuset); + pthread_setaffinity_np(thread, setsize, cpuset); + pthread_getaffinity_np(thread, setsize, cpuset); + CPU_FREE(cpuset); + return 0; + }''', dependencies: threads)) config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + ''' #include #include diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c index ac1d56e673..bae938c670 100644 --- a/util/qemu-thread-posix.c +++ b/util/qemu-thread-posix.c @@ -16,6 +16,7 @@ #include "qemu/notify.h" #include "qemu-thread-common.h" #include "qemu/tsan.h" +#include "qemu/bitmap.h" static bool name_threads; @@ -552,6 +553,75 @@ void qemu_thread_create(QemuThread *thread, const char *name, pthread_attr_destroy(&attr); } +int qemu_thread_set_affinity(QemuThread *thread, unsigned long *host_cpus, + unsigned long nbits) +{ +#if defined(CONFIG_PTHREAD_AFFINITY_NP) + const size_t setsize = CPU_ALLOC_SIZE(nbits); + unsigned long value; + cpu_set_t *cpuset; + int err; + + cpuset = CPU_ALLOC(nbits); + g_assert(cpuset); + + CPU_ZERO_S(setsize, cpuset); + value = find_first_bit(host_cpus, nbits); + while (value < nbits) { + CPU_SET_S(value, setsize, cpuset); + value = find_next_bit(host_cpus, nbits, value + 1); + } + + err = pthread_setaffinity_np(thread->thread, setsize, cpuset); + CPU_FREE(cpuset); + return err; +#else + return -ENOSYS; +#endif +} + +int qemu_thread_get_affinity(QemuThread *thread, unsigned long **host_cpus, + unsigned long *nbits) +{ +#if defined(CONFIG_PTHREAD_AFFINITY_NP) + unsigned long tmpbits; + cpu_set_t *cpuset; + size_t setsize; + int i, err; + + tmpbits = CPU_SETSIZE; + while (true) { + setsize = CPU_ALLOC_SIZE(tmpbits); + cpuset = CPU_ALLOC(tmpbits); + g_assert(cpuset); + + err = pthread_getaffinity_np(thread->thread, setsize, cpuset); + if (err) { + CPU_FREE(cpuset); + if (err != -EINVAL) { + return err; + } + tmpbits *= 2; + } else { + break; + } + } + + /* Convert the result into a proper bitmap. */ + *nbits = tmpbits; + *host_cpus = bitmap_new(tmpbits); + for (i = 0; i < tmpbits; i++) { + if (CPU_ISSET(i, cpuset)) { + set_bit(i, *host_cpus); + } + } + CPU_FREE(cpuset); + return 0; +#else + return -ENOSYS; +#endif +} + void qemu_thread_get_self(QemuThread *thread) { thread->thread = pthread_self(); diff --git a/util/qemu-thread-win32.c b/util/qemu-thread-win32.c index b9a467d7db..69db254ac7 100644 --- a/util/qemu-thread-win32.c +++ b/util/qemu-thread-win32.c @@ -477,6 +477,18 @@ void qemu_thread_create(QemuThread *thread, const char *name, thread->data = data; } +int qemu_thread_set_affinity(QemuThread *thread, unsigned long *host_cpus, + unsigned long nbits) +{ + return -ENOSYS; +} + +int qemu_thread_get_affinity(QemuThread *thread, unsigned long **host_cpus, + unsigned long *nbits) +{ + return -ENOSYS; +} + void qemu_thread_get_self(QemuThread *thread) { thread->data = qemu_thread_data; From e2de2c497e5744bc2c009aadd0af7633f2947948 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Fri, 14 Oct 2022 15:47:16 +0200 Subject: [PATCH 187/705] util: Introduce ThreadContext user-creatable object Setting the CPU affinity of QEMU threads is a bit problematic, because QEMU doesn't always have permissions to set the CPU affinity itself, for example, with seccomp after initialized by QEMU: -sandbox enable=on,resourcecontrol=deny General information about CPU affinities can be found in the man page of taskset: CPU affinity is a scheduler property that "bonds" a process to a given set of CPUs on the system. The Linux scheduler will honor the given CPU affinity and the process will not run on any other CPUs. While upper layers are already aware of how to handle CPU affinities for long-lived threads like iothreads or vcpu threads, especially short-lived threads, as used for memory-backend preallocation, are more involved to handle. These threads are created on demand and upper layers are not even able to identify and configure them. Introduce the concept of a ThreadContext, that is essentially a thread used for creating new threads. All threads created via that context thread inherit the configured CPU affinity. Consequently, it's sufficient to create a ThreadContext and configure it once, and have all threads created via that ThreadContext inherit the same CPU affinity. The CPU affinity of a ThreadContext can be configured two ways: (1) Obtaining the thread id via the "thread-id" property and setting the CPU affinity manually (e.g., via taskset). (2) Setting the "cpu-affinity" property and letting QEMU try set the CPU affinity itself. This will fail if QEMU doesn't have permissions to do so anymore after seccomp was initialized. A simple QEMU example to set the CPU affinity to host CPU 0,1,6,7 would be: qemu-system-x86_64 -S \ -object thread-context,id=tc1,cpu-affinity=0-1,cpu-affinity=6-7 And we can query it via HMP/QMP: (qemu) qom-get tc1 cpu-affinity [ 0, 1, 6, 7 ] But note that due to dynamic library loading this example will not work before we actually make use of thread_context_create_thread() in QEMU code, because the type will otherwise not get registered. We'll wire this up next to make it work. In general, the interface behaves like pthread_setaffinity_np(): host CPU numbers that are currently not available are ignored; only host CPU numbers that are impossible with the current kernel will fail. If the list of host CPU numbers does not include a single CPU that is available, setting the CPU affinity will fail. A ThreadContext can be reused, simply by reconfiguring the CPU affinity. Note that the CPU affinity of previously created threads will not get adjusted. Reviewed-by: Michal Privoznik Acked-by: Markus Armbruster Message-Id: <20221014134720.168738-4-david@redhat.com> Signed-off-by: David Hildenbrand --- include/qemu/thread-context.h | 57 +++++++ qapi/qom.json | 17 +++ util/meson.build | 1 + util/oslib-posix.c | 1 + util/thread-context.c | 278 ++++++++++++++++++++++++++++++++++ 5 files changed, 354 insertions(+) create mode 100644 include/qemu/thread-context.h create mode 100644 util/thread-context.c diff --git a/include/qemu/thread-context.h b/include/qemu/thread-context.h new file mode 100644 index 0000000000..2ebd6b7fe1 --- /dev/null +++ b/include/qemu/thread-context.h @@ -0,0 +1,57 @@ +/* + * QEMU Thread Context + * + * Copyright Red Hat Inc., 2022 + * + * Authors: + * David Hildenbrand + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef SYSEMU_THREAD_CONTEXT_H +#define SYSEMU_THREAD_CONTEXT_H + +#include "qapi/qapi-types-machine.h" +#include "qemu/thread.h" +#include "qom/object.h" + +#define TYPE_THREAD_CONTEXT "thread-context" +OBJECT_DECLARE_TYPE(ThreadContext, ThreadContextClass, + THREAD_CONTEXT) + +struct ThreadContextClass { + ObjectClass parent_class; +}; + +struct ThreadContext { + /* private */ + Object parent; + + /* private */ + unsigned int thread_id; + QemuThread thread; + + /* Semaphore to wait for context thread action. */ + QemuSemaphore sem; + /* Semaphore to wait for action in context thread. */ + QemuSemaphore sem_thread; + /* Mutex to synchronize requests. */ + QemuMutex mutex; + + /* Commands for the thread to execute. */ + int thread_cmd; + void *thread_cmd_data; + + /* CPU affinity bitmap used for initialization. */ + unsigned long *init_cpu_bitmap; + int init_cpu_nbits; +}; + +void thread_context_create_thread(ThreadContext *tc, QemuThread *thread, + const char *name, + void *(*start_routine)(void *), void *arg, + int mode); + +#endif /* SYSEMU_THREAD_CONTEXT_H */ diff --git a/qapi/qom.json b/qapi/qom.json index 80dd419b39..8013ba4b82 100644 --- a/qapi/qom.json +++ b/qapi/qom.json @@ -830,6 +830,21 @@ 'reduced-phys-bits': 'uint32', '*kernel-hashes': 'bool' } } +## +# @ThreadContextProperties: +# +# Properties for thread context objects. +# +# @cpu-affinity: the list of host CPU numbers used as CPU affinity for all +# threads created in the thread context (default: QEMU main +# thread CPU affinity) +# +# Since: 7.2 +## +{ 'struct': 'ThreadContextProperties', + 'data': { '*cpu-affinity': ['uint16'] } } + + ## # @ObjectType: # @@ -882,6 +897,7 @@ { 'name': 'secret_keyring', 'if': 'CONFIG_SECRET_KEYRING' }, 'sev-guest', + 'thread-context', 's390-pv-guest', 'throttle-group', 'tls-creds-anon', @@ -948,6 +964,7 @@ 'secret_keyring': { 'type': 'SecretKeyringProperties', 'if': 'CONFIG_SECRET_KEYRING' }, 'sev-guest': 'SevGuestProperties', + 'thread-context': 'ThreadContextProperties', 'throttle-group': 'ThrottleGroupProperties', 'tls-creds-anon': 'TlsCredsAnonProperties', 'tls-creds-psk': 'TlsCredsPskProperties', diff --git a/util/meson.build b/util/meson.build index 5e282130df..e97cd2d779 100644 --- a/util/meson.build +++ b/util/meson.build @@ -1,4 +1,5 @@ util_ss.add(files('osdep.c', 'cutils.c', 'unicode.c', 'qemu-timer-common.c')) +util_ss.add(files('thread-context.c')) if not config_host_data.get('CONFIG_ATOMIC64') util_ss.add(files('atomic64.c')) endif diff --git a/util/oslib-posix.c b/util/oslib-posix.c index 905cbc27cc..28305cdea3 100644 --- a/util/oslib-posix.c +++ b/util/oslib-posix.c @@ -42,6 +42,7 @@ #include "qemu/cutils.h" #include "qemu/compiler.h" #include "qemu/units.h" +#include "qemu/thread-context.h" #ifdef CONFIG_LINUX #include diff --git a/util/thread-context.c b/util/thread-context.c new file mode 100644 index 0000000000..c921905396 --- /dev/null +++ b/util/thread-context.c @@ -0,0 +1,278 @@ +/* + * QEMU Thread Context + * + * Copyright Red Hat Inc., 2022 + * + * Authors: + * David Hildenbrand + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qemu/thread-context.h" +#include "qapi/error.h" +#include "qapi/qapi-builtin-visit.h" +#include "qapi/visitor.h" +#include "qemu/config-file.h" +#include "qapi/qapi-builtin-visit.h" +#include "qom/object_interfaces.h" +#include "qemu/module.h" +#include "qemu/bitmap.h" + +enum { + TC_CMD_NONE = 0, + TC_CMD_STOP, + TC_CMD_NEW, +}; + +typedef struct ThreadContextCmdNew { + QemuThread *thread; + const char *name; + void *(*start_routine)(void *); + void *arg; + int mode; +} ThreadContextCmdNew; + +static void *thread_context_run(void *opaque) +{ + ThreadContext *tc = opaque; + + tc->thread_id = qemu_get_thread_id(); + qemu_sem_post(&tc->sem); + + while (true) { + /* + * Threads inherit the CPU affinity of the creating thread. For this + * reason, we create new (especially short-lived) threads from our + * persistent context thread. + * + * Especially when QEMU is not allowed to set the affinity itself, + * management tools can simply set the affinity of the context thread + * after creating the context, to have new threads created via + * the context inherit the CPU affinity automatically. + */ + switch (tc->thread_cmd) { + case TC_CMD_NONE: + break; + case TC_CMD_STOP: + tc->thread_cmd = TC_CMD_NONE; + qemu_sem_post(&tc->sem); + return NULL; + case TC_CMD_NEW: { + ThreadContextCmdNew *cmd_new = tc->thread_cmd_data; + + qemu_thread_create(cmd_new->thread, cmd_new->name, + cmd_new->start_routine, cmd_new->arg, + cmd_new->mode); + tc->thread_cmd = TC_CMD_NONE; + tc->thread_cmd_data = NULL; + qemu_sem_post(&tc->sem); + break; + } + default: + g_assert_not_reached(); + } + qemu_sem_wait(&tc->sem_thread); + } +} + +static void thread_context_set_cpu_affinity(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + ThreadContext *tc = THREAD_CONTEXT(obj); + uint16List *l, *host_cpus = NULL; + unsigned long *bitmap = NULL; + int nbits = 0, ret; + Error *err = NULL; + + visit_type_uint16List(v, name, &host_cpus, &err); + if (err) { + error_propagate(errp, err); + return; + } + + if (!host_cpus) { + error_setg(errp, "CPU list is empty"); + goto out; + } + + for (l = host_cpus; l; l = l->next) { + nbits = MAX(nbits, l->value + 1); + } + bitmap = bitmap_new(nbits); + for (l = host_cpus; l; l = l->next) { + set_bit(l->value, bitmap); + } + + if (tc->thread_id != -1) { + /* + * Note: we won't be adjusting the affinity of any thread that is still + * around, but only the affinity of the context thread. + */ + ret = qemu_thread_set_affinity(&tc->thread, bitmap, nbits); + if (ret) { + error_setg(errp, "Setting CPU affinity failed: %s", strerror(ret)); + } + } else { + tc->init_cpu_bitmap = bitmap; + bitmap = NULL; + tc->init_cpu_nbits = nbits; + } +out: + g_free(bitmap); + qapi_free_uint16List(host_cpus); +} + +static void thread_context_get_cpu_affinity(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + unsigned long *bitmap, nbits, value; + ThreadContext *tc = THREAD_CONTEXT(obj); + uint16List *host_cpus = NULL; + uint16List **tail = &host_cpus; + int ret; + + if (tc->thread_id == -1) { + error_setg(errp, "Object not initialized yet"); + return; + } + + ret = qemu_thread_get_affinity(&tc->thread, &bitmap, &nbits); + if (ret) { + error_setg(errp, "Getting CPU affinity failed: %s", strerror(ret)); + return; + } + + value = find_first_bit(bitmap, nbits); + while (value < nbits) { + QAPI_LIST_APPEND(tail, value); + + value = find_next_bit(bitmap, nbits, value + 1); + } + g_free(bitmap); + + visit_type_uint16List(v, name, &host_cpus, errp); + qapi_free_uint16List(host_cpus); +} + +static void thread_context_get_thread_id(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + ThreadContext *tc = THREAD_CONTEXT(obj); + uint64_t value = tc->thread_id; + + visit_type_uint64(v, name, &value, errp); +} + +static void thread_context_instance_complete(UserCreatable *uc, Error **errp) +{ + ThreadContext *tc = THREAD_CONTEXT(uc); + char *thread_name; + int ret; + + thread_name = g_strdup_printf("TC %s", + object_get_canonical_path_component(OBJECT(uc))); + qemu_thread_create(&tc->thread, thread_name, thread_context_run, tc, + QEMU_THREAD_JOINABLE); + g_free(thread_name); + + /* Wait until initialization of the thread is done. */ + while (tc->thread_id == -1) { + qemu_sem_wait(&tc->sem); + } + + if (tc->init_cpu_bitmap) { + ret = qemu_thread_set_affinity(&tc->thread, tc->init_cpu_bitmap, + tc->init_cpu_nbits); + if (ret) { + error_setg(errp, "Setting CPU affinity failed: %s", strerror(ret)); + } + g_free(tc->init_cpu_bitmap); + tc->init_cpu_bitmap = NULL; + } +} + +static void thread_context_class_init(ObjectClass *oc, void *data) +{ + UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc); + + ucc->complete = thread_context_instance_complete; + object_class_property_add(oc, "thread-id", "int", + thread_context_get_thread_id, NULL, NULL, + NULL); + object_class_property_add(oc, "cpu-affinity", "int", + thread_context_get_cpu_affinity, + thread_context_set_cpu_affinity, NULL, NULL); +} + +static void thread_context_instance_init(Object *obj) +{ + ThreadContext *tc = THREAD_CONTEXT(obj); + + tc->thread_id = -1; + qemu_sem_init(&tc->sem, 0); + qemu_sem_init(&tc->sem_thread, 0); + qemu_mutex_init(&tc->mutex); +} + +static void thread_context_instance_finalize(Object *obj) +{ + ThreadContext *tc = THREAD_CONTEXT(obj); + + if (tc->thread_id != -1) { + tc->thread_cmd = TC_CMD_STOP; + qemu_sem_post(&tc->sem_thread); + qemu_thread_join(&tc->thread); + } + qemu_sem_destroy(&tc->sem); + qemu_sem_destroy(&tc->sem_thread); + qemu_mutex_destroy(&tc->mutex); +} + +static const TypeInfo thread_context_info = { + .name = TYPE_THREAD_CONTEXT, + .parent = TYPE_OBJECT, + .class_init = thread_context_class_init, + .instance_size = sizeof(ThreadContext), + .instance_init = thread_context_instance_init, + .instance_finalize = thread_context_instance_finalize, + .interfaces = (InterfaceInfo[]) { + { TYPE_USER_CREATABLE }, + { } + } +}; + +static void thread_context_register_types(void) +{ + type_register_static(&thread_context_info); +} +type_init(thread_context_register_types) + +void thread_context_create_thread(ThreadContext *tc, QemuThread *thread, + const char *name, + void *(*start_routine)(void *), void *arg, + int mode) +{ + ThreadContextCmdNew data = { + .thread = thread, + .name = name, + .start_routine = start_routine, + .arg = arg, + .mode = mode, + }; + + qemu_mutex_lock(&tc->mutex); + tc->thread_cmd = TC_CMD_NEW; + tc->thread_cmd_data = &data; + qemu_sem_post(&tc->sem_thread); + + while (tc->thread_cmd != TC_CMD_NONE) { + qemu_sem_wait(&tc->sem); + } + qemu_mutex_unlock(&tc->mutex); +} From 10218ae6d006f76410804cc4dc690085b3d008b5 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Fri, 14 Oct 2022 15:47:17 +0200 Subject: [PATCH 188/705] util: Add write-only "node-affinity" property for ThreadContext Let's make it easier to pin threads created via a ThreadContext to all host CPUs currently belonging to a given set of host NUMA nodes -- which is the common case. "node-affinity" is simply a shortcut for setting "cpu-affinity" manually to the list of host CPUs belonging to the set of host nodes. This property can only be written. A simple QEMU example to set the CPU affinity to host node 1 on a system with two nodes, 24 CPUs each, whereby odd-numbered host CPUs belong to host node 1: qemu-system-x86_64 -S \ -object thread-context,id=tc1,node-affinity=1 And we can query the cpu-affinity via HMP/QMP: (qemu) qom-get tc1 cpu-affinity [ 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47 ] We cannot query the node-affinity: (qemu) qom-get tc1 node-affinity Error: Insufficient permission to perform this operation But note that due to dynamic library loading this example will not work before we actually make use of thread_context_create_thread() in QEMU code, because the type will otherwise not get registered. We'll wire this up next to make it work. Note that if the host CPUs for a host node change due do CPU hot(un)plug CPU onlining/offlining (i.e., lscpu output changes) after the ThreadContext was started, the CPU affinity will not get updated. Reviewed-by: Michal Privoznik Acked-by: Markus Armbruster Message-Id: <20221014134720.168738-5-david@redhat.com> Signed-off-by: David Hildenbrand --- qapi/qom.json | 9 ++++- util/meson.build | 2 +- util/thread-context.c | 84 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 2 deletions(-) diff --git a/qapi/qom.json b/qapi/qom.json index 8013ba4b82..20b5735d78 100644 --- a/qapi/qom.json +++ b/qapi/qom.json @@ -839,10 +839,17 @@ # threads created in the thread context (default: QEMU main # thread CPU affinity) # +# @node-affinity: the list of host node numbers that will be resolved to a +# list of host CPU numbers used as CPU affinity. This is a +# shortcut for specifying the list of host CPU numbers +# belonging to the host nodes manually by setting +# @cpu-affinity. (default: QEMU main thread affinity) +# # Since: 7.2 ## { 'struct': 'ThreadContextProperties', - 'data': { '*cpu-affinity': ['uint16'] } } + 'data': { '*cpu-affinity': ['uint16'], + '*node-affinity': ['uint16'] } } ## diff --git a/util/meson.build b/util/meson.build index e97cd2d779..c0a7bc54d4 100644 --- a/util/meson.build +++ b/util/meson.build @@ -1,5 +1,5 @@ util_ss.add(files('osdep.c', 'cutils.c', 'unicode.c', 'qemu-timer-common.c')) -util_ss.add(files('thread-context.c')) +util_ss.add(files('thread-context.c'), numa) if not config_host_data.get('CONFIG_ATOMIC64') util_ss.add(files('atomic64.c')) endif diff --git a/util/thread-context.c b/util/thread-context.c index c921905396..4138245332 100644 --- a/util/thread-context.c +++ b/util/thread-context.c @@ -21,6 +21,10 @@ #include "qemu/module.h" #include "qemu/bitmap.h" +#ifdef CONFIG_NUMA +#include +#endif + enum { TC_CMD_NONE = 0, TC_CMD_STOP, @@ -88,6 +92,11 @@ static void thread_context_set_cpu_affinity(Object *obj, Visitor *v, int nbits = 0, ret; Error *err = NULL; + if (tc->init_cpu_bitmap) { + error_setg(errp, "Mixing CPU and node affinity not supported"); + return; + } + visit_type_uint16List(v, name, &host_cpus, &err); if (err) { error_propagate(errp, err); @@ -159,6 +168,79 @@ static void thread_context_get_cpu_affinity(Object *obj, Visitor *v, qapi_free_uint16List(host_cpus); } +static void thread_context_set_node_affinity(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ +#ifdef CONFIG_NUMA + const int nbits = numa_num_possible_cpus(); + ThreadContext *tc = THREAD_CONTEXT(obj); + uint16List *l, *host_nodes = NULL; + unsigned long *bitmap = NULL; + struct bitmask *tmp_cpus; + Error *err = NULL; + int ret, i; + + if (tc->init_cpu_bitmap) { + error_setg(errp, "Mixing CPU and node affinity not supported"); + return; + } + + visit_type_uint16List(v, name, &host_nodes, &err); + if (err) { + error_propagate(errp, err); + return; + } + + if (!host_nodes) { + error_setg(errp, "Node list is empty"); + goto out; + } + + bitmap = bitmap_new(nbits); + tmp_cpus = numa_allocate_cpumask(); + for (l = host_nodes; l; l = l->next) { + numa_bitmask_clearall(tmp_cpus); + ret = numa_node_to_cpus(l->value, tmp_cpus); + if (ret) { + /* We ignore any errors, such as impossible nodes. */ + continue; + } + for (i = 0; i < nbits; i++) { + if (numa_bitmask_isbitset(tmp_cpus, i)) { + set_bit(i, bitmap); + } + } + } + numa_free_cpumask(tmp_cpus); + + if (bitmap_empty(bitmap, nbits)) { + error_setg(errp, "The nodes select no CPUs"); + goto out; + } + + if (tc->thread_id != -1) { + /* + * Note: we won't be adjusting the affinity of any thread that is still + * around for now, but only the affinity of the context thread. + */ + ret = qemu_thread_set_affinity(&tc->thread, bitmap, nbits); + if (ret) { + error_setg(errp, "Setting CPU affinity failed: %s", strerror(ret)); + } + } else { + tc->init_cpu_bitmap = bitmap; + bitmap = NULL; + tc->init_cpu_nbits = nbits; + } +out: + g_free(bitmap); + qapi_free_uint16List(host_nodes); +#else + error_setg(errp, "NUMA node affinity is not supported by this QEMU"); +#endif +} + static void thread_context_get_thread_id(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) @@ -208,6 +290,8 @@ static void thread_context_class_init(ObjectClass *oc, void *data) object_class_property_add(oc, "cpu-affinity", "int", thread_context_get_cpu_affinity, thread_context_set_cpu_affinity, NULL, NULL); + object_class_property_add(oc, "node-affinity", "int", NULL, + thread_context_set_node_affinity, NULL, NULL); } static void thread_context_instance_init(Object *obj) From e04a34e55cf1911099e2d8a680f9bee4f6d90e4a Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Fri, 14 Oct 2022 15:47:18 +0200 Subject: [PATCH 189/705] util: Make qemu_prealloc_mem() optionally consume a ThreadContext ... and implement it under POSIX. When a ThreadContext is provided, create new threads via the context such that these new threads obtain a properly configured CPU affinity. Reviewed-by: Michal Privoznik Message-Id: <20221014134720.168738-6-david@redhat.com> Signed-off-by: David Hildenbrand --- backends/hostmem.c | 5 +++-- hw/virtio/virtio-mem.c | 2 +- include/qemu/osdep.h | 4 +++- util/oslib-posix.c | 20 ++++++++++++++------ util/oslib-win32.c | 2 +- 5 files changed, 22 insertions(+), 11 deletions(-) diff --git a/backends/hostmem.c b/backends/hostmem.c index 491cb10b97..76f0394490 100644 --- a/backends/hostmem.c +++ b/backends/hostmem.c @@ -232,7 +232,8 @@ static void host_memory_backend_set_prealloc(Object *obj, bool value, void *ptr = memory_region_get_ram_ptr(&backend->mr); uint64_t sz = memory_region_size(&backend->mr); - qemu_prealloc_mem(fd, ptr, sz, backend->prealloc_threads, &local_err); + qemu_prealloc_mem(fd, ptr, sz, backend->prealloc_threads, NULL, + &local_err); if (local_err) { error_propagate(errp, local_err); return; @@ -384,7 +385,7 @@ host_memory_backend_memory_complete(UserCreatable *uc, Error **errp) */ if (backend->prealloc) { qemu_prealloc_mem(memory_region_get_fd(&backend->mr), ptr, sz, - backend->prealloc_threads, &local_err); + backend->prealloc_threads, NULL, &local_err); if (local_err) { goto out; } diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c index 0e9ef4ff19..ed170def48 100644 --- a/hw/virtio/virtio-mem.c +++ b/hw/virtio/virtio-mem.c @@ -467,7 +467,7 @@ static int virtio_mem_set_block_state(VirtIOMEM *vmem, uint64_t start_gpa, int fd = memory_region_get_fd(&vmem->memdev->mr); Error *local_err = NULL; - qemu_prealloc_mem(fd, area, size, 1, &local_err); + qemu_prealloc_mem(fd, area, size, 1, NULL, &local_err); if (local_err) { static bool warned; diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index e556e45143..625298c8bc 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -568,6 +568,8 @@ unsigned long qemu_getauxval(unsigned long type); void qemu_set_tty_echo(int fd, bool echo); +typedef struct ThreadContext ThreadContext; + /** * qemu_prealloc_mem: * @fd: the fd mapped into the area, -1 for anonymous memory @@ -582,7 +584,7 @@ void qemu_set_tty_echo(int fd, bool echo); * after allocating file blocks for mapped files. */ void qemu_prealloc_mem(int fd, char *area, size_t sz, int max_threads, - Error **errp); + ThreadContext *tc, Error **errp); /** * qemu_get_pid_name: diff --git a/util/oslib-posix.c b/util/oslib-posix.c index 28305cdea3..59a891b6a8 100644 --- a/util/oslib-posix.c +++ b/util/oslib-posix.c @@ -419,7 +419,8 @@ static inline int get_memset_num_threads(size_t hpagesize, size_t numpages, } static int touch_all_pages(char *area, size_t hpagesize, size_t numpages, - int max_threads, bool use_madv_populate_write) + int max_threads, ThreadContext *tc, + bool use_madv_populate_write) { static gsize initialized = 0; MemsetContext context = { @@ -458,9 +459,16 @@ static int touch_all_pages(char *area, size_t hpagesize, size_t numpages, context.threads[i].numpages = numpages_per_thread + (i < leftover); context.threads[i].hpagesize = hpagesize; context.threads[i].context = &context; - qemu_thread_create(&context.threads[i].pgthread, "touch_pages", - touch_fn, &context.threads[i], - QEMU_THREAD_JOINABLE); + if (tc) { + thread_context_create_thread(tc, &context.threads[i].pgthread, + "touch_pages", + touch_fn, &context.threads[i], + QEMU_THREAD_JOINABLE); + } else { + qemu_thread_create(&context.threads[i].pgthread, "touch_pages", + touch_fn, &context.threads[i], + QEMU_THREAD_JOINABLE); + } addr += context.threads[i].numpages * hpagesize; } @@ -496,7 +504,7 @@ static bool madv_populate_write_possible(char *area, size_t pagesize) } void qemu_prealloc_mem(int fd, char *area, size_t sz, int max_threads, - Error **errp) + ThreadContext *tc, Error **errp) { static gsize initialized; int ret; @@ -537,7 +545,7 @@ void qemu_prealloc_mem(int fd, char *area, size_t sz, int max_threads, } /* touch pages simultaneously */ - ret = touch_all_pages(area, hpagesize, numpages, max_threads, + ret = touch_all_pages(area, hpagesize, numpages, max_threads, tc, use_madv_populate_write); if (ret) { error_setg_errno(errp, -ret, diff --git a/util/oslib-win32.c b/util/oslib-win32.c index e1cb725ecc..a67cb3822e 100644 --- a/util/oslib-win32.c +++ b/util/oslib-win32.c @@ -269,7 +269,7 @@ int getpagesize(void) } void qemu_prealloc_mem(int fd, char *area, size_t sz, int max_threads, - Error **errp) + ThreadContext *tc, Error **errp) { int i; size_t pagesize = qemu_real_host_page_size(); From e6816458624813de4a31f89096a620b410e1c2b8 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Fri, 14 Oct 2022 15:47:19 +0200 Subject: [PATCH 190/705] hostmem: Allow for specifying a ThreadContext for preallocation Let's allow for specifying a thread context via the "prealloc-context" property. When set, preallcoation threads will be crated via the thread context -- inheriting the same CPU affinity as the thread context. Pinning preallcoation threads to CPUs can heavily increase performance in NUMA setups, because, preallocation from a CPU close to the target NUMA node(s) is faster then preallocation from a CPU further remote, simply because of memory bandwidth for initializing memory with zeroes. This is especially relevant for very large VMs backed by huge/gigantic pages, whereby preallocation is mandatory. Reviewed-by: Michal Privoznik Message-Id: <20221014134720.168738-7-david@redhat.com> Signed-off-by: David Hildenbrand --- backends/hostmem.c | 12 +++++++++--- include/sysemu/hostmem.h | 2 ++ qapi/qom.json | 4 ++++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/backends/hostmem.c b/backends/hostmem.c index 76f0394490..8640294c10 100644 --- a/backends/hostmem.c +++ b/backends/hostmem.c @@ -232,8 +232,8 @@ static void host_memory_backend_set_prealloc(Object *obj, bool value, void *ptr = memory_region_get_ram_ptr(&backend->mr); uint64_t sz = memory_region_size(&backend->mr); - qemu_prealloc_mem(fd, ptr, sz, backend->prealloc_threads, NULL, - &local_err); + qemu_prealloc_mem(fd, ptr, sz, backend->prealloc_threads, + backend->prealloc_context, &local_err); if (local_err) { error_propagate(errp, local_err); return; @@ -385,7 +385,8 @@ host_memory_backend_memory_complete(UserCreatable *uc, Error **errp) */ if (backend->prealloc) { qemu_prealloc_mem(memory_region_get_fd(&backend->mr), ptr, sz, - backend->prealloc_threads, NULL, &local_err); + backend->prealloc_threads, + backend->prealloc_context, &local_err); if (local_err) { goto out; } @@ -493,6 +494,11 @@ host_memory_backend_class_init(ObjectClass *oc, void *data) NULL, NULL); object_class_property_set_description(oc, "prealloc-threads", "Number of CPU threads to use for prealloc"); + object_class_property_add_link(oc, "prealloc-context", + TYPE_THREAD_CONTEXT, offsetof(HostMemoryBackend, prealloc_context), + object_property_allow_set_link, OBJ_PROP_LINK_STRONG); + object_class_property_set_description(oc, "prealloc-context", + "Context to use for creating CPU threads for preallocation"); object_class_property_add(oc, "size", "int", host_memory_backend_get_size, host_memory_backend_set_size, diff --git a/include/sysemu/hostmem.h b/include/sysemu/hostmem.h index 9ff5c16963..39326f1d4f 100644 --- a/include/sysemu/hostmem.h +++ b/include/sysemu/hostmem.h @@ -18,6 +18,7 @@ #include "qom/object.h" #include "exec/memory.h" #include "qemu/bitmap.h" +#include "qemu/thread-context.h" #define TYPE_MEMORY_BACKEND "memory-backend" OBJECT_DECLARE_TYPE(HostMemoryBackend, HostMemoryBackendClass, @@ -66,6 +67,7 @@ struct HostMemoryBackend { bool merge, dump, use_canonical_path; bool prealloc, is_mapped, share, reserve; uint32_t prealloc_threads; + ThreadContext *prealloc_context; DECLARE_BITMAP(host_nodes, MAX_NODES + 1); HostMemPolicy policy; diff --git a/qapi/qom.json b/qapi/qom.json index 20b5735d78..87fcad2423 100644 --- a/qapi/qom.json +++ b/qapi/qom.json @@ -578,6 +578,9 @@ # # @prealloc-threads: number of CPU threads to use for prealloc (default: 1) # +# @prealloc-context: thread context to use for creation of preallocation threads +# (default: none) (since 7.2) +# # @share: if false, the memory is private to QEMU; if true, it is shared # (default: false) # @@ -608,6 +611,7 @@ '*policy': 'HostMemPolicy', '*prealloc': 'bool', '*prealloc-threads': 'uint32', + '*prealloc-context': 'str', '*share': 'bool', '*reserve': 'bool', 'size': 'size', From bd77c30df984faefa85e6a402939b485d6e05f05 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Fri, 14 Oct 2022 15:47:20 +0200 Subject: [PATCH 191/705] vl: Allow ThreadContext objects to be created before the sandbox option Currently, there is no way to configure a CPU affinity inside QEMU when the sandbox option disables it for QEMU as a whole, for example, via: -sandbox enable=on,resourcecontrol=deny While ThreadContext objects can be created on the QEMU commandline and the CPU affinity can be configured externally via the thread-id, this is insufficient if a ThreadContext with a certain CPU affinity is already required during QEMU startup, before we can intercept QEMU and configure the CPU affinity. Blocking sched_setaffinity() was introduced in 24f8cdc57224 ("seccomp: add resourcecontrol argument to command line"), "to avoid any bigger of the process". However, we only care about once QEMU is running, not when the instance starting QEMU explicitly requests a certain CPU affinity on the QEMU comandline. Right now, for NUMA-aware preallocation of memory backends used for initial machine RAM, one has to: 1) Start QEMU with the memory-backend with "prealloc=off" 2) Pause QEMU before it starts the guest (-S) 3) Create ThreadContext, configure the CPU affinity using the thread-id 4) Configure the ThreadContext as "prealloc-context" of the memory backend 5) Trigger preallocation by setting "prealloc=on" To simplify this handling especially for initial machine RAM, allow creation of ThreadContext objects before parsing sandbox options, such that the CPU affinity requested on the QEMU commandline alongside the sandbox option can be set. As ThreadContext objects essentially only create a persistent context thread and set the CPU affinity, this is easily possible. With this change, we can create a ThreadContext with a CPU affinity on the QEMU commandline and use it for preallocation of memory backends glued to the machine (simplified example): To make "-name debug-threads=on" keep working as expected for the context threads, perform earlier parsing of "-name". qemu-system-x86_64 -m 1G \ -object thread-context,id=tc1,cpu-affinity=3-4 \ -object memory-backend-ram,id=pc.ram,size=1G,prealloc=on,prealloc-threads=2,prealloc-context=tc1 \ -machine memory-backend=pc.ram \ -S -monitor stdio -sandbox enable=on,resourcecontrol=deny And while we can query the current CPU affinity: (qemu) qom-get tc1 cpu-affinity [ 3, 4 ] We can no longer change it from QEMU directly: (qemu) qom-set tc1 cpu-affinity 1-2 Error: Setting CPU affinity failed: Operation not permitted Reviewed-by: Michal Privoznik Message-Id: <20221014134720.168738-8-david@redhat.com> Signed-off-by: David Hildenbrand --- softmmu/vl.c | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/softmmu/vl.c b/softmmu/vl.c index b464da25bc..b5a23420ac 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -1759,6 +1759,27 @@ static void object_option_parse(const char *optarg) visit_free(v); } +/* + * Very early object creation, before the sandbox options have been activated. + */ +static bool object_create_pre_sandbox(const char *type) +{ + /* + * Objects should in general not get initialized "too early" without + * a reason. If you add one, state the reason in a comment! + */ + + /* + * Reason: -sandbox on,resourcecontrol=deny disallows setting CPU + * affinity of threads. + */ + if (g_str_equal(type, "thread-context")) { + return true; + } + + return false; +} + /* * Initial object creation happens before all other * QEMU data types are created. The majority of objects @@ -1773,6 +1794,11 @@ static bool object_create_early(const char *type) * add one, state the reason in a comment! */ + /* Reason: already created. */ + if (object_create_pre_sandbox(type)) { + return false; + } + /* Reason: property "chardev" */ if (g_str_equal(type, "rng-egd") || g_str_equal(type, "qtest")) { @@ -1895,7 +1921,7 @@ static void qemu_create_early_backends(void) */ static bool object_create_late(const char *type) { - return !object_create_early(type); + return !object_create_early(type) && !object_create_pre_sandbox(type); } static void qemu_create_late_backends(void) @@ -2351,6 +2377,11 @@ static int process_runstate_actions(void *opaque, QemuOpts *opts, Error **errp) static void qemu_process_early_options(void) { + qemu_opts_foreach(qemu_find_opts("name"), + parse_name, NULL, &error_fatal); + + object_option_foreach_add(object_create_pre_sandbox); + #ifdef CONFIG_SECCOMP QemuOptsList *olist = qemu_find_opts_err("sandbox", NULL); if (olist) { @@ -2358,9 +2389,6 @@ static void qemu_process_early_options(void) } #endif - qemu_opts_foreach(qemu_find_opts("name"), - parse_name, NULL, &error_fatal); - if (qemu_opts_foreach(qemu_find_opts("action"), process_runstate_actions, NULL, &error_fatal)) { exit(1); From e4c93e44ab103f6c67abd85d620343f61aafa004 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 21 Oct 2022 17:01:31 +0100 Subject: [PATCH 192/705] target/arm: Implement FEAT_E0PD FEAT_E0PD adds new bits E0PD0 and E0PD1 to TCR_EL1, which allow the OS to forbid EL0 access to half of the address space. Since this is an EL0-specific variation on the existing TCR_ELx.{EPD0,EPD1}, we can implement it entirely in aa64_va_parameters(). This requires moving the existing regime_is_user() to internals.h so that the code in helper.c can get at it. Reviewed-by: Richard Henderson Signed-off-by: Peter Maydell Message-id: 20221021160131.3531787-1-peter.maydell@linaro.org --- docs/system/arm/emulation.rst | 1 + target/arm/cpu.h | 5 +++++ target/arm/cpu64.c | 1 + target/arm/helper.c | 9 +++++++++ target/arm/internals.h | 19 +++++++++++++++++++ target/arm/ptw.c | 19 ------------------- 6 files changed, 35 insertions(+), 19 deletions(-) diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst index cfb4b0768b..fd61360a08 100644 --- a/docs/system/arm/emulation.rst +++ b/docs/system/arm/emulation.rst @@ -24,6 +24,7 @@ the following architecture extensions: - FEAT_Debugv8p4 (Debug changes for v8.4) - FEAT_DotProd (Advanced SIMD dot product instructions) - FEAT_DoubleFault (Double Fault Extension) +- FEAT_E0PD (Preventing EL0 access to halves of address maps) - FEAT_ETS (Enhanced Translation Synchronization) - FEAT_FCMA (Floating-point complex number instructions) - FEAT_FHM (Floating-point half-precision multiplication instructions) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index db9ec6a038..09564d0393 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -4147,6 +4147,11 @@ static inline bool isar_feature_aa64_lva(const ARMISARegisters *id) return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, VARANGE) != 0; } +static inline bool isar_feature_aa64_e0pd(const ARMISARegisters *id) +{ + return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, E0PD) != 0; +} + static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id) { return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0; diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 85e0d1daf1..da95eabab5 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -1185,6 +1185,7 @@ static void aarch64_max_initfn(Object *obj) t = FIELD_DP64(t, ID_AA64MMFR2, FWB, 1); /* FEAT_S2FWB */ t = FIELD_DP64(t, ID_AA64MMFR2, TTL, 1); /* FEAT_TTL */ t = FIELD_DP64(t, ID_AA64MMFR2, BBM, 2); /* FEAT_BBM at level 2 */ + t = FIELD_DP64(t, ID_AA64MMFR2, E0PD, 1); /* FEAT_E0PD */ cpu->isar.id_aa64mmfr2 = t; t = cpu->isar.id_aa64zfr0; diff --git a/target/arm/helper.c b/target/arm/helper.c index c672903f43..252651a8d1 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -10491,6 +10491,8 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va, ps = extract32(tcr, 16, 3); ds = extract64(tcr, 32, 1); } else { + bool e0pd; + /* * Bit 55 is always between the two regions, and is canonical for * determining if address tagging is enabled. @@ -10502,15 +10504,22 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va, epd = extract32(tcr, 7, 1); sh = extract32(tcr, 12, 2); hpd = extract64(tcr, 41, 1); + e0pd = extract64(tcr, 55, 1); } else { tsz = extract32(tcr, 16, 6); gran = tg1_to_gran_size(extract32(tcr, 30, 2)); epd = extract32(tcr, 23, 1); sh = extract32(tcr, 28, 2); hpd = extract64(tcr, 42, 1); + e0pd = extract64(tcr, 56, 1); } ps = extract64(tcr, 32, 3); ds = extract64(tcr, 59, 1); + + if (e0pd && cpu_isar_feature(aa64_e0pd, cpu) && + regime_is_user(env, mmu_idx)) { + epd = true; + } } gran = sanitize_gran_size(cpu, gran, stage2); diff --git a/target/arm/internals.h b/target/arm/internals.h index b26c9ca17b..1926f3679c 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -707,6 +707,25 @@ static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx) } } +static inline bool regime_is_user(CPUARMState *env, ARMMMUIdx mmu_idx) +{ + switch (mmu_idx) { + case ARMMMUIdx_E20_0: + case ARMMMUIdx_Stage1_E0: + case ARMMMUIdx_MUser: + case ARMMMUIdx_MSUser: + case ARMMMUIdx_MUserNegPri: + case ARMMMUIdx_MSUserNegPri: + return true; + default: + return false; + case ARMMMUIdx_E10_0: + case ARMMMUIdx_E10_1: + case ARMMMUIdx_E10_1_PAN: + g_assert_not_reached(); + } +} + /* Return the SCTLR value which controls this address translation regime */ static inline uint64_t regime_sctlr(CPUARMState *env, ARMMMUIdx mmu_idx) { diff --git a/target/arm/ptw.c b/target/arm/ptw.c index 6c5ed56a10..aed6f92d6f 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -104,25 +104,6 @@ static bool regime_translation_big_endian(CPUARMState *env, ARMMMUIdx mmu_idx) return (regime_sctlr(env, mmu_idx) & SCTLR_EE) != 0; } -static bool regime_is_user(CPUARMState *env, ARMMMUIdx mmu_idx) -{ - switch (mmu_idx) { - case ARMMMUIdx_E20_0: - case ARMMMUIdx_Stage1_E0: - case ARMMMUIdx_MUser: - case ARMMMUIdx_MSUser: - case ARMMMUIdx_MUserNegPri: - case ARMMMUIdx_MSUserNegPri: - return true; - default: - return false; - case ARMMMUIdx_E10_0: - case ARMMMUIdx_E10_1: - case ARMMMUIdx_E10_1_PAN: - g_assert_not_reached(); - } -} - /* Return the TTBR associated with this translation regime */ static uint64_t regime_ttbr(CPUARMState *env, ARMMMUIdx mmu_idx, int ttbrn) { From 7cd5d384bb298ce3c595a3774213b5b478881ac8 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Brucker Date: Tue, 27 Sep 2022 11:03:48 +0100 Subject: [PATCH 193/705] hw/arm/virt: Fix devicetree warnings about the virtio-iommu node The "PCI Bus Binding to: IEEE Std 1275-1994" defines the compatible string for a PCIe bus or endpoint as "pci," or similar. Since the initial binding for PCI virtio-iommu didn't follow this rule, it was modified to accept both strings and ensure backward compatibility. Also, the unit-name for the node should be "device,function". Fix corresponding dt-validate and dtc warnings: pcie@10000000: virtio_iommu@16:compatible: ['virtio,pci-iommu'] does not contain items matching the given schema pcie@10000000: Unevaluated properties are not allowed (... 'virtio_iommu@16' were unexpected) From schema: linux/Documentation/devicetree/bindings/pci/host-generic-pci.yaml virtio_iommu@16: compatible: 'oneOf' conditional failed, one must be fixed: ['virtio,pci-iommu'] is too short 'pci1af4,1057' was expected From schema: dtschema/schemas/pci/pci-bus.yaml Warning (pci_device_reg): /pcie@10000000/virtio_iommu@16: PCI unit address format error, expected "2,0" Signed-off-by: Jean-Philippe Brucker Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/arm/virt.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index cda9defe8f..b871350856 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -1371,14 +1371,15 @@ static void create_smmu(const VirtMachineState *vms, static void create_virtio_iommu_dt_bindings(VirtMachineState *vms) { - const char compat[] = "virtio,pci-iommu"; + const char compat[] = "virtio,pci-iommu\0pci1af4,1057"; uint16_t bdf = vms->virtio_iommu_bdf; MachineState *ms = MACHINE(vms); char *node; vms->iommu_phandle = qemu_fdt_alloc_phandle(ms->fdt); - node = g_strdup_printf("%s/virtio_iommu@%d", vms->pciehb_nodename, bdf); + node = g_strdup_printf("%s/virtio_iommu@%x,%x", vms->pciehb_nodename, + PCI_SLOT(bdf), PCI_FUNC(bdf)); qemu_fdt_add_subnode(ms->fdt, node); qemu_fdt_setprop(ms->fdt, node, "compatible", compat, sizeof(compat)); qemu_fdt_setprop_sized_cells(ms->fdt, node, "reg", From c939a7c7b93ee44a4963fabe81454e1f956ecd4b Mon Sep 17 00:00:00 2001 From: Ake Koomsin Date: Mon, 17 Oct 2022 18:24:32 +0900 Subject: [PATCH 194/705] target/arm: honor HCR_E2H and HCR_TGE in arm_excp_unmasked() An exception targeting EL2 from lower EL is actually maskable when HCR_E2H and HCR_TGE are both set. This applies to both secure and non-secure Security state. We can remove the conditions that try to suppress masking of interrupts when we are Secure and the exception targets EL2 and Secure EL2 is disabled. This is OK because in that situation arm_phys_excp_target_el() will never return 2 as the target EL. The 'not if secure' check in this function was originally written before arm_hcr_el2_eff(), and back then the target EL returned by arm_phys_excp_target_el() could be 2 even if we were in Secure EL0/EL1; but it is no longer needed. Signed-off-by: Ake Koomsin Message-id: 20221017092432.546881-1-ake@igel.co.jp [PMM: Add commit message paragraph explaining why it's OK to remove the checks on secure and SCR_EEL2] Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- target/arm/cpu.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 0a7bfbf999..a021df9e9e 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -587,14 +587,24 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx, if ((target_el > cur_el) && (target_el != 1)) { /* Exceptions targeting a higher EL may not be maskable */ if (arm_feature(env, ARM_FEATURE_AARCH64)) { - /* - * 64-bit masking rules are simple: exceptions to EL3 - * can't be masked, and exceptions to EL2 can only be - * masked from Secure state. The HCR and SCR settings - * don't affect the masking logic, only the interrupt routing. - */ - if (target_el == 3 || !secure || (env->cp15.scr_el3 & SCR_EEL2)) { + switch (target_el) { + case 2: + /* + * According to ARM DDI 0487H.a, an interrupt can be masked + * when HCR_E2H and HCR_TGE are both set regardless of the + * current Security state. Note that we need to revisit this + * part again once we need to support NMI. + */ + if ((hcr_el2 & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) { + unmasked = true; + } + break; + case 3: + /* Interrupt cannot be masked when the target EL is 3 */ unmasked = true; + break; + default: + g_assert_not_reached(); } } else { /* From 310616d3677aad709d3eaf8f5f08683f2853f227 Mon Sep 17 00:00:00 2001 From: Damien Hedde Date: Thu, 20 Oct 2022 15:27:49 +0100 Subject: [PATCH 195/705] hw/core/resettable: fix reset level counting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The code for handling the reset level count in the Resettable code has two issues: The reset count is only decremented for the 1->0 case. This means that if there's ever a nested reset that takes the count to 2 then it will never again be decremented. Eventually the count will exceed the '50' limit in resettable_phase_enter() and QEMU will trip over the assertion failure. The repro case in issue 1266 is an example of this that happens now the SCSI subsystem uses three-phase reset. Secondly, the count is decremented only after the exit phase handler is called. Moving the reset count decrement from "just after" to "just before" calling the exit phase handler allows resettable_is_in_reset() to return false during the handler execution. This simplifies reset handling in resettable devices. Typically, a function that updates the device state will just need to read the current reset state and not anymore treat the "in a reset-exit transition" as a special case. Note that the semantics change to the *_is_in_reset() functions will have no effect on the current codebase, because only two devices (hw/char/cadence_uart.c and hw/misc/zynq_sclr.c) currently call those functions, and in neither case do they do it from the device's exit phase methed. Fixes: 4a5fc890 ("scsi: Use device_cold_reset() and bus_cold_reset()") Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1266 Signed-off-by: Damien Hedde Signed-off-by: Peter Maydell Reported-by: Michael Peter Reviewed-by: Philippe Mathieu-Daudé Message-id: 20221020142749.3357951-1-peter.maydell@linaro.org Buglink: https://bugs.launchpad.net/qemu/+bug/1905297 Reported-by: Michael Peter [PMM: adjust the docs paragraph changed to get the name of the 'enter' phase right and to clarify exactly when the count is adjusted; rewrite the commit message] Signed-off-by: Peter Maydell --- docs/devel/reset.rst | 8 +++++--- hw/core/resettable.c | 3 +-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/devel/reset.rst b/docs/devel/reset.rst index abea1102dc..7cc6a6b314 100644 --- a/docs/devel/reset.rst +++ b/docs/devel/reset.rst @@ -210,9 +210,11 @@ Polling the reset state Resettable interface provides the ``resettable_is_in_reset()`` function. This function returns true if the object parameter is currently under reset. -An object is under reset from the beginning of the *init* phase to the end of -the *exit* phase. During all three phases, the function will return that the -object is in reset. +An object is under reset from the beginning of the *enter* phase (before +either its children or its own enter method is called) to the *exit* +phase. During *enter* and *hold* phase only, the function will return that the +object is in reset. The state is changed after the *exit* is propagated to +its children and just before calling the object's own *exit* method. This function may be used if the object behavior has to be adapted while in reset state. For example if a device has an irq input, diff --git a/hw/core/resettable.c b/hw/core/resettable.c index 96a99ce39e..c3df75c6ba 100644 --- a/hw/core/resettable.c +++ b/hw/core/resettable.c @@ -201,12 +201,11 @@ static void resettable_phase_exit(Object *obj, void *opaque, ResetType type) resettable_child_foreach(rc, obj, resettable_phase_exit, NULL, type); assert(s->count > 0); - if (s->count == 1) { + if (--s->count == 0) { trace_resettable_phase_exit_exec(obj, obj_typename, !!rc->phases.exit); if (rc->phases.exit && !resettable_get_tr_func(rc, obj)) { rc->phases.exit(obj); } - s->count = 0; } s->exit_phase_in_progress = false; trace_resettable_phase_exit_end(obj, obj_typename, s->count); From 7764963b9239dc966122617cc8b61d4530d6ce2a Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 13 Oct 2022 18:18:17 +0100 Subject: [PATCH 196/705] hw/hyperv/hyperv.c: Use device_cold_reset() instead of device_legacy_reset() The semantic difference between the deprecated device_legacy_reset() function and the newer device_cold_reset() function is that the new function resets both the device itself and any qbuses it owns, whereas the legacy function resets just the device itself and nothing else. In hyperv_synic_reset() we reset a SynICState, which has no qbuses, so for this purpose the two functions behave identically and we can stop using the deprecated one. Signed-off-by: Peter Maydell Reviewed-by: Maciej S. Szmigiero Message-id: 20221013171817.1447562-1-peter.maydell@linaro.org --- hw/hyperv/hyperv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/hyperv/hyperv.c b/hw/hyperv/hyperv.c index 4a1b59cb9d..57b402b956 100644 --- a/hw/hyperv/hyperv.c +++ b/hw/hyperv/hyperv.c @@ -157,7 +157,7 @@ void hyperv_synic_reset(CPUState *cs) SynICState *synic = get_synic(cs); if (synic) { - device_legacy_reset(DEVICE(synic)); + device_cold_reset(DEVICE(synic)); } } From 7719419deb07a431455dfb0178480ef4be2d3e2c Mon Sep 17 00:00:00 2001 From: Axel Heider Date: Wed, 19 Oct 2022 15:09:50 +0200 Subject: [PATCH 197/705] target/imx: reload cmp timer outside of the reload ptimer transaction When running seL4 tests (https://docs.sel4.systems/projects/sel4test) on the sabrelight platform, the timer tests fail. The arm/imx6 EPIT timer interrupt does not fire properly, instead of a e.g. second in can take up to a minute to finally see the interrupt. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1263 Signed-off-by: Axel Heider Message-id: 166663118138.13362.1229967229046092876-0@git.sr.ht Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/timer/imx_epit.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c index 2bf8c754b2..ec0fa440d7 100644 --- a/hw/timer/imx_epit.c +++ b/hw/timer/imx_epit.c @@ -275,10 +275,15 @@ static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value, /* If IOVW bit is set then set the timer value */ ptimer_set_count(s->timer_reload, s->lr); } - + /* + * Commit the change to s->timer_reload, so it can propagate. Otherwise + * the timer interrupt may not fire properly. The commit must happen + * before calling imx_epit_reload_compare_timer(), which reads + * s->timer_reload internally again. + */ + ptimer_transaction_commit(s->timer_reload); imx_epit_reload_compare_timer(s); ptimer_transaction_commit(s->timer_cmp); - ptimer_transaction_commit(s->timer_reload); break; case 3: /* CMP */ From edc05dd43ade287e735f1d8c972562dbdd12a378 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 15:18:38 +1000 Subject: [PATCH 198/705] target/arm: Introduce regime_is_stage2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reduce the amount of typing required for this check. Reviewed-by: Alex Bennée Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson Message-id: 20221024051851.3074715-2-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/helper.c | 14 +++++--------- target/arm/internals.h | 5 +++++ target/arm/ptw.c | 14 ++++++-------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index 252651a8d1..47afaec6b4 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -10352,7 +10352,7 @@ int aa64_va_parameter_tbi(uint64_t tcr, ARMMMUIdx mmu_idx) { if (regime_has_2_ranges(mmu_idx)) { return extract64(tcr, 37, 2); - } else if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) { + } else if (regime_is_stage2(mmu_idx)) { return 0; /* VTCR_EL2 */ } else { /* Replicate the single TBI bit so we always have 2 bits. */ @@ -10364,7 +10364,7 @@ int aa64_va_parameter_tbid(uint64_t tcr, ARMMMUIdx mmu_idx) { if (regime_has_2_ranges(mmu_idx)) { return extract64(tcr, 51, 2); - } else if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) { + } else if (regime_is_stage2(mmu_idx)) { return 0; /* VTCR_EL2 */ } else { /* Replicate the single TBID bit so we always have 2 bits. */ @@ -10474,7 +10474,7 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va, int select, tsz, tbi, max_tsz, min_tsz, ps, sh; ARMGranuleSize gran; ARMCPU *cpu = env_archcpu(env); - bool stage2 = mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S; + bool stage2 = regime_is_stage2(mmu_idx); if (!regime_has_2_ranges(mmu_idx)) { select = 0; @@ -10541,22 +10541,18 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va, } ds = false; } else if (ds) { - switch (mmu_idx) { - case ARMMMUIdx_Stage2: - case ARMMMUIdx_Stage2_S: + if (regime_is_stage2(mmu_idx)) { if (gran == Gran16K) { ds = cpu_isar_feature(aa64_tgran16_2_lpa2, cpu); } else { ds = cpu_isar_feature(aa64_tgran4_2_lpa2, cpu); } - break; - default: + } else { if (gran == Gran16K) { ds = cpu_isar_feature(aa64_tgran16_lpa2, cpu); } else { ds = cpu_isar_feature(aa64_tgran4_lpa2, cpu); } - break; } if (ds) { min_tsz = 12; diff --git a/target/arm/internals.h b/target/arm/internals.h index 1926f3679c..2c4768dd05 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -673,6 +673,11 @@ static inline bool regime_is_pan(CPUARMState *env, ARMMMUIdx mmu_idx) } } +static inline bool regime_is_stage2(ARMMMUIdx mmu_idx) +{ + return mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S; +} + /* Return the exception level which controls this address translation regime */ static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx) { diff --git a/target/arm/ptw.c b/target/arm/ptw.c index aed6f92d6f..32d6412586 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -823,8 +823,7 @@ static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64, bool have_wxn; int wxn = 0; - assert(mmu_idx != ARMMMUIdx_Stage2); - assert(mmu_idx != ARMMMUIdx_Stage2_S); + assert(!regime_is_stage2(mmu_idx)); user_rw = simple_ap_to_rw_prot_is_user(ap, true); if (is_user) { @@ -1152,7 +1151,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, goto do_fault; } - if (mmu_idx != ARMMMUIdx_Stage2 && mmu_idx != ARMMMUIdx_Stage2_S) { + if (!regime_is_stage2(mmu_idx)) { /* * The starting level depends on the virtual address size (which can * be up to 48 bits) and the translation granule size. It indicates @@ -1323,7 +1322,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, attrs = extract64(descriptor, 2, 10) | (extract64(descriptor, 52, 12) << 10); - if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) { + if (regime_is_stage2(mmu_idx)) { /* Stage 2 table descriptors do not include any attribute fields */ break; } @@ -1355,7 +1354,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, ap = extract32(attrs, 4, 2); - if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) { + if (regime_is_stage2(mmu_idx)) { ns = mmu_idx == ARMMMUIdx_Stage2; xn = extract32(attrs, 11, 2); result->f.prot = get_S2prot(env, ap, xn, s1_is_el0); @@ -1385,7 +1384,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, result->f.guarded = guarded; } - if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) { + if (regime_is_stage2(mmu_idx)) { result->cacheattrs.is_s2_format = true; result->cacheattrs.attrs = extract32(attrs, 0, 4); } else { @@ -1416,8 +1415,7 @@ do_fault: fi->type = fault_type; fi->level = level; /* Tag the error as S2 for failed S1 PTW at S2 or ordinary S2. */ - fi->stage2 = fi->s1ptw || (mmu_idx == ARMMMUIdx_Stage2 || - mmu_idx == ARMMMUIdx_Stage2_S); + fi->stage2 = fi->s1ptw || regime_is_stage2(mmu_idx); fi->s1ns = mmu_idx == ARMMMUIdx_Stage2; return true; } From 48da29e485af5c92e284fbb6ef279b2a98eea7c4 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 15:18:39 +1000 Subject: [PATCH 199/705] target/arm: Add ptw_idx to S1Translate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hoist the computation of the mmu_idx for the ptw up to get_phys_addr_with_struct and get_phys_addr_twostage. This removes the duplicate check for stage2 disabled from the middle of the walk, performing it only once. Signed-off-by: Richard Henderson Reviewed-by: Alex Bennée Tested-by: Alex Bennée Message-id: 20221024051851.3074715-3-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/ptw.c | 71 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 17 deletions(-) diff --git a/target/arm/ptw.c b/target/arm/ptw.c index 32d6412586..3c153f6831 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -17,6 +17,7 @@ typedef struct S1Translate { ARMMMUIdx in_mmu_idx; + ARMMMUIdx in_ptw_idx; bool in_secure; bool in_debug; bool out_secure; @@ -214,33 +215,24 @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw, { bool is_secure = ptw->in_secure; ARMMMUIdx mmu_idx = ptw->in_mmu_idx; - ARMMMUIdx s2_mmu_idx = is_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2; - bool s2_phys = false; + ARMMMUIdx s2_mmu_idx = ptw->in_ptw_idx; uint8_t pte_attrs; bool pte_secure; - if (!arm_mmu_idx_is_stage1_of_2(mmu_idx) - || regime_translation_disabled(env, s2_mmu_idx, is_secure)) { - s2_mmu_idx = is_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS; - s2_phys = true; - } - if (unlikely(ptw->in_debug)) { /* * From gdbstub, do not use softmmu so that we don't modify the * state of the cpu at all, including softmmu tlb contents. */ - if (s2_phys) { - ptw->out_phys = addr; - pte_attrs = 0; - pte_secure = is_secure; - } else { + if (regime_is_stage2(s2_mmu_idx)) { S1Translate s2ptw = { .in_mmu_idx = s2_mmu_idx, + .in_ptw_idx = is_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS, .in_secure = is_secure, .in_debug = true, }; GetPhysAddrResult s2 = { }; + if (!get_phys_addr_lpae(env, &s2ptw, addr, MMU_DATA_LOAD, false, &s2, fi)) { goto fail; @@ -248,6 +240,11 @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw, ptw->out_phys = s2.f.phys_addr; pte_attrs = s2.cacheattrs.attrs; pte_secure = s2.f.attrs.secure; + } else { + /* Regime is physical. */ + ptw->out_phys = addr; + pte_attrs = 0; + pte_secure = is_secure; } ptw->out_host = NULL; } else { @@ -268,7 +265,7 @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw, pte_secure = full->attrs.secure; } - if (!s2_phys) { + if (regime_is_stage2(s2_mmu_idx)) { uint64_t hcr = arm_hcr_el2_eff_secstate(env, is_secure); if ((hcr & HCR_PTW) && S2_attrs_are_device(hcr, pte_attrs)) { @@ -1263,7 +1260,18 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, descaddr |= (address >> (stride * (4 - level))) & indexmask; descaddr &= ~7ULL; nstable = extract32(tableattrs, 4, 1); - ptw->in_secure = !nstable; + if (!nstable) { + /* + * Stage2_S -> Stage2 or Phys_S -> Phys_NS + * Assert that the non-secure idx are even, and relative order. + */ + QEMU_BUILD_BUG_ON((ARMMMUIdx_Phys_NS & 1) != 0); + QEMU_BUILD_BUG_ON((ARMMMUIdx_Stage2 & 1) != 0); + QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_NS + 1 != ARMMMUIdx_Phys_S); + QEMU_BUILD_BUG_ON(ARMMMUIdx_Stage2 + 1 != ARMMMUIdx_Stage2_S); + ptw->in_ptw_idx &= ~1; + ptw->in_secure = false; + } descriptor = arm_ldq_ptw(env, ptw, descaddr, fi); if (fi->type != ARMFault_None) { goto do_fault; @@ -2449,6 +2457,7 @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw, is_el0 = ptw->in_mmu_idx == ARMMMUIdx_Stage1_E0; ptw->in_mmu_idx = s2walk_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2; + ptw->in_ptw_idx = s2walk_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS; ptw->in_secure = s2walk_secure; /* @@ -2508,10 +2517,32 @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw, ARMMMUFaultInfo *fi) { ARMMMUIdx mmu_idx = ptw->in_mmu_idx; - ARMMMUIdx s1_mmu_idx = stage_1_mmu_idx(mmu_idx); bool is_secure = ptw->in_secure; + ARMMMUIdx s1_mmu_idx; - if (mmu_idx != s1_mmu_idx) { + switch (mmu_idx) { + case ARMMMUIdx_Phys_S: + case ARMMMUIdx_Phys_NS: + /* Checking Phys early avoids special casing later vs regime_el. */ + return get_phys_addr_disabled(env, address, access_type, mmu_idx, + is_secure, result, fi); + + case ARMMMUIdx_Stage1_E0: + case ARMMMUIdx_Stage1_E1: + case ARMMMUIdx_Stage1_E1_PAN: + /* First stage lookup uses second stage for ptw. */ + ptw->in_ptw_idx = is_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2; + break; + + case ARMMMUIdx_E10_0: + s1_mmu_idx = ARMMMUIdx_Stage1_E0; + goto do_twostage; + case ARMMMUIdx_E10_1: + s1_mmu_idx = ARMMMUIdx_Stage1_E1; + goto do_twostage; + case ARMMMUIdx_E10_1_PAN: + s1_mmu_idx = ARMMMUIdx_Stage1_E1_PAN; + do_twostage: /* * Call ourselves recursively to do the stage 1 and then stage 2 * translations if mmu_idx is a two-stage regime, and EL2 present. @@ -2522,6 +2553,12 @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw, return get_phys_addr_twostage(env, ptw, address, access_type, result, fi); } + /* fall through */ + + default: + /* Single stage and second stage uses physical for ptw. */ + ptw->in_ptw_idx = is_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS; + break; } /* From 980a68925c8f19ae181c226af0776c0e3ddd0264 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 15:18:40 +1000 Subject: [PATCH 200/705] target/arm: Add isar predicates for FEAT_HAFDBS The MMFR1 field may indicate support for hardware update of access flag alone, or access flag and dirty bit. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20221024051851.3074715-4-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/cpu.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 09564d0393..9aeed3c848 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -4152,6 +4152,16 @@ static inline bool isar_feature_aa64_e0pd(const ARMISARegisters *id) return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, E0PD) != 0; } +static inline bool isar_feature_aa64_hafs(const ARMISARegisters *id) +{ + return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HAFDBS) != 0; +} + +static inline bool isar_feature_aa64_hdbs(const ARMISARegisters *id) +{ + return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HAFDBS) >= 2; +} + static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id) { return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0; From 8973922783483dee02aaf254a9d6a8fdd3e200f4 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 15:18:41 +1000 Subject: [PATCH 201/705] target/arm: Extract HA and HD in aa64_va_parameters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Reviewed-by: Alex Bennée Message-id: 20221024051851.3074715-5-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/helper.c | 8 +++++++- target/arm/internals.h | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index 47afaec6b4..b070a20f1a 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -10470,7 +10470,7 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va, ARMMMUIdx mmu_idx, bool data) { uint64_t tcr = regime_tcr(env, mmu_idx); - bool epd, hpd, tsz_oob, ds; + bool epd, hpd, tsz_oob, ds, ha, hd; int select, tsz, tbi, max_tsz, min_tsz, ps, sh; ARMGranuleSize gran; ARMCPU *cpu = env_archcpu(env); @@ -10489,6 +10489,8 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va, epd = false; sh = extract32(tcr, 12, 2); ps = extract32(tcr, 16, 3); + ha = extract32(tcr, 21, 1) && cpu_isar_feature(aa64_hafs, cpu); + hd = extract32(tcr, 22, 1) && cpu_isar_feature(aa64_hdbs, cpu); ds = extract64(tcr, 32, 1); } else { bool e0pd; @@ -10514,6 +10516,8 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va, e0pd = extract64(tcr, 56, 1); } ps = extract64(tcr, 32, 3); + ha = extract64(tcr, 39, 1) && cpu_isar_feature(aa64_hafs, cpu); + hd = extract64(tcr, 40, 1) && cpu_isar_feature(aa64_hdbs, cpu); ds = extract64(tcr, 59, 1); if (e0pd && cpu_isar_feature(aa64_e0pd, cpu) && @@ -10586,6 +10590,8 @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va, .hpd = hpd, .tsz_oob = tsz_oob, .ds = ds, + .ha = ha, + .hd = ha && hd, .gran = gran, }; } diff --git a/target/arm/internals.h b/target/arm/internals.h index 2c4768dd05..201ae370d5 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -1065,6 +1065,8 @@ typedef struct ARMVAParameters { bool hpd : 1; bool tsz_oob : 1; /* tsz has been clamped to legal range */ bool ds : 1; + bool ha : 1; + bool hd : 1; ARMGranuleSize gran : 2; } ARMVAParameters; From 93e5b3a6f9c7e481e781bde69a5f87cd93cc1a34 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 15:18:42 +1000 Subject: [PATCH 202/705] target/arm: Move S1_ptw_translate outside arm_ld[lq]_ptw Separate S1 translation from the actual lookup. Will enable lpae hardware updates. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20221024051851.3074715-6-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/ptw.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/target/arm/ptw.c b/target/arm/ptw.c index 3c153f6831..44341a9dbc 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -300,18 +300,12 @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw, } /* All loads done in the course of a page table walk go through here. */ -static uint32_t arm_ldl_ptw(CPUARMState *env, S1Translate *ptw, hwaddr addr, +static uint32_t arm_ldl_ptw(CPUARMState *env, S1Translate *ptw, ARMMMUFaultInfo *fi) { CPUState *cs = env_cpu(env); uint32_t data; - if (!S1_ptw_translate(env, ptw, addr, fi)) { - /* Failure. */ - assert(fi->s1ptw); - return 0; - } - if (likely(ptw->out_host)) { /* Page tables are in RAM, and we have the host address. */ if (ptw->out_be) { @@ -339,18 +333,12 @@ static uint32_t arm_ldl_ptw(CPUARMState *env, S1Translate *ptw, hwaddr addr, return data; } -static uint64_t arm_ldq_ptw(CPUARMState *env, S1Translate *ptw, hwaddr addr, +static uint64_t arm_ldq_ptw(CPUARMState *env, S1Translate *ptw, ARMMMUFaultInfo *fi) { CPUState *cs = env_cpu(env); uint64_t data; - if (!S1_ptw_translate(env, ptw, addr, fi)) { - /* Failure. */ - assert(fi->s1ptw); - return 0; - } - if (likely(ptw->out_host)) { /* Page tables are in RAM, and we have the host address. */ if (ptw->out_be) { @@ -507,7 +495,10 @@ static bool get_phys_addr_v5(CPUARMState *env, S1Translate *ptw, fi->type = ARMFault_Translation; goto do_fault; } - desc = arm_ldl_ptw(env, ptw, table, fi); + if (!S1_ptw_translate(env, ptw, table, fi)) { + goto do_fault; + } + desc = arm_ldl_ptw(env, ptw, fi); if (fi->type != ARMFault_None) { goto do_fault; } @@ -545,7 +536,10 @@ static bool get_phys_addr_v5(CPUARMState *env, S1Translate *ptw, /* Fine pagetable. */ table = (desc & 0xfffff000) | ((address >> 8) & 0xffc); } - desc = arm_ldl_ptw(env, ptw, table, fi); + if (!S1_ptw_translate(env, ptw, table, fi)) { + goto do_fault; + } + desc = arm_ldl_ptw(env, ptw, fi); if (fi->type != ARMFault_None) { goto do_fault; } @@ -630,7 +624,10 @@ static bool get_phys_addr_v6(CPUARMState *env, S1Translate *ptw, fi->type = ARMFault_Translation; goto do_fault; } - desc = arm_ldl_ptw(env, ptw, table, fi); + if (!S1_ptw_translate(env, ptw, table, fi)) { + goto do_fault; + } + desc = arm_ldl_ptw(env, ptw, fi); if (fi->type != ARMFault_None) { goto do_fault; } @@ -683,7 +680,10 @@ static bool get_phys_addr_v6(CPUARMState *env, S1Translate *ptw, ns = extract32(desc, 3, 1); /* Lookup l2 entry. */ table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc); - desc = arm_ldl_ptw(env, ptw, table, fi); + if (!S1_ptw_translate(env, ptw, table, fi)) { + goto do_fault; + } + desc = arm_ldl_ptw(env, ptw, fi); if (fi->type != ARMFault_None) { goto do_fault; } @@ -1272,7 +1272,10 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, ptw->in_ptw_idx &= ~1; ptw->in_secure = false; } - descriptor = arm_ldq_ptw(env, ptw, descaddr, fi); + if (!S1_ptw_translate(env, ptw, descaddr, fi)) { + goto do_fault; + } + descriptor = arm_ldq_ptw(env, ptw, fi); if (fi->type != ARMFault_None) { goto do_fault; } From f0a398a2490656fac87b7ee4ba1fb01a42840875 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 15:18:43 +1000 Subject: [PATCH 203/705] target/arm: Add ARMFault_UnsuppAtomicUpdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fault type is to be used with FEAT_HAFDBS when the guest enables hw updates, but places the tables in memory where atomic updates are unsupported. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Reviewed-by: Alex Bennée Message-id: 20221024051851.3074715-7-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/internals.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/target/arm/internals.h b/target/arm/internals.h index 201ae370d5..d9121d9ff8 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -338,6 +338,7 @@ typedef enum ARMFaultType { ARMFault_AsyncExternal, ARMFault_Debug, ARMFault_TLBConflict, + ARMFault_UnsuppAtomicUpdate, ARMFault_Lockdown, ARMFault_Exclusive, ARMFault_ICacheMaint, @@ -524,6 +525,9 @@ static inline uint32_t arm_fi_to_lfsc(ARMMMUFaultInfo *fi) case ARMFault_TLBConflict: fsc = 0x30; break; + case ARMFault_UnsuppAtomicUpdate: + fsc = 0x31; + break; case ARMFault_Lockdown: fsc = 0x34; break; From fe4ddc151b72a06eaeaa2359c51b66e698dd9c44 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 15:18:44 +1000 Subject: [PATCH 204/705] target/arm: Remove loop from get_phys_addr_lpae The unconditional loop was used both to iterate over levels and to control parsing of attributes. Use an explicit goto in both cases. While this appears less clean for iterating over levels, we will need to jump back into the middle of this loop for atomic updates, which is even uglier. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20221024051851.3074715-8-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/ptw.c | 192 +++++++++++++++++++++++------------------------ 1 file changed, 96 insertions(+), 96 deletions(-) diff --git a/target/arm/ptw.c b/target/arm/ptw.c index 44341a9dbc..2a5f018835 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -1061,6 +1061,8 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, uint64_t descaddrmask; bool aarch64 = arm_el_is_aa64(env, el); bool guarded = false; + uint64_t descriptor; + bool nstable; /* TODO: This code does not support shareability levels. */ if (aarch64) { @@ -1253,106 +1255,104 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, * bits at each step. */ tableattrs = is_secure ? 0 : (1 << 4); - for (;;) { - uint64_t descriptor; - bool nstable; - - descaddr |= (address >> (stride * (4 - level))) & indexmask; - descaddr &= ~7ULL; - nstable = extract32(tableattrs, 4, 1); - if (!nstable) { - /* - * Stage2_S -> Stage2 or Phys_S -> Phys_NS - * Assert that the non-secure idx are even, and relative order. - */ - QEMU_BUILD_BUG_ON((ARMMMUIdx_Phys_NS & 1) != 0); - QEMU_BUILD_BUG_ON((ARMMMUIdx_Stage2 & 1) != 0); - QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_NS + 1 != ARMMMUIdx_Phys_S); - QEMU_BUILD_BUG_ON(ARMMMUIdx_Stage2 + 1 != ARMMMUIdx_Stage2_S); - ptw->in_ptw_idx &= ~1; - ptw->in_secure = false; - } - if (!S1_ptw_translate(env, ptw, descaddr, fi)) { - goto do_fault; - } - descriptor = arm_ldq_ptw(env, ptw, fi); - if (fi->type != ARMFault_None) { - goto do_fault; - } - - if (!(descriptor & 1) || - (!(descriptor & 2) && (level == 3))) { - /* Invalid, or the Reserved level 3 encoding */ - goto do_fault; - } - - descaddr = descriptor & descaddrmask; + next_level: + descaddr |= (address >> (stride * (4 - level))) & indexmask; + descaddr &= ~7ULL; + nstable = extract32(tableattrs, 4, 1); + if (!nstable) { /* - * For FEAT_LPA and PS=6, bits [51:48] of descaddr are in [15:12] - * of descriptor. For FEAT_LPA2 and effective DS, bits [51:50] of - * descaddr are in [9:8]. Otherwise, if descaddr is out of range, - * raise AddressSizeFault. + * Stage2_S -> Stage2 or Phys_S -> Phys_NS + * Assert that the non-secure idx are even, and relative order. */ - if (outputsize > 48) { - if (param.ds) { - descaddr |= extract64(descriptor, 8, 2) << 50; - } else { - descaddr |= extract64(descriptor, 12, 4) << 48; - } - } else if (descaddr >> outputsize) { - fault_type = ARMFault_AddressSize; - goto do_fault; - } - - if ((descriptor & 2) && (level < 3)) { - /* - * Table entry. The top five bits are attributes which may - * propagate down through lower levels of the table (and - * which are all arranged so that 0 means "no effect", so - * we can gather them up by ORing in the bits at each level). - */ - tableattrs |= extract64(descriptor, 59, 5); - level++; - indexmask = indexmask_grainsize; - continue; - } - /* - * Block entry at level 1 or 2, or page entry at level 3. - * These are basically the same thing, although the number - * of bits we pull in from the vaddr varies. Note that although - * descaddrmask masks enough of the low bits of the descriptor - * to give a correct page or table address, the address field - * in a block descriptor is smaller; so we need to explicitly - * clear the lower bits here before ORing in the low vaddr bits. - */ - page_size = (1ULL << ((stride * (4 - level)) + 3)); - descaddr &= ~(hwaddr)(page_size - 1); - descaddr |= (address & (page_size - 1)); - /* Extract attributes from the descriptor */ - attrs = extract64(descriptor, 2, 10) - | (extract64(descriptor, 52, 12) << 10); - - if (regime_is_stage2(mmu_idx)) { - /* Stage 2 table descriptors do not include any attribute fields */ - break; - } - /* Merge in attributes from table descriptors */ - attrs |= nstable << 3; /* NS */ - guarded = extract64(descriptor, 50, 1); /* GP */ - if (param.hpd) { - /* HPD disables all the table attributes except NSTable. */ - break; - } - attrs |= extract32(tableattrs, 0, 2) << 11; /* XN, PXN */ - /* - * The sense of AP[1] vs APTable[0] is reversed, as APTable[0] == 1 - * means "force PL1 access only", which means forcing AP[1] to 0. - */ - attrs &= ~(extract32(tableattrs, 2, 1) << 4); /* !APT[0] => AP[1] */ - attrs |= extract32(tableattrs, 3, 1) << 5; /* APT[1] => AP[2] */ - break; + QEMU_BUILD_BUG_ON((ARMMMUIdx_Phys_NS & 1) != 0); + QEMU_BUILD_BUG_ON((ARMMMUIdx_Stage2 & 1) != 0); + QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_NS + 1 != ARMMMUIdx_Phys_S); + QEMU_BUILD_BUG_ON(ARMMMUIdx_Stage2 + 1 != ARMMMUIdx_Stage2_S); + ptw->in_ptw_idx &= ~1; + ptw->in_secure = false; } + if (!S1_ptw_translate(env, ptw, descaddr, fi)) { + goto do_fault; + } + descriptor = arm_ldq_ptw(env, ptw, fi); + if (fi->type != ARMFault_None) { + goto do_fault; + } + + if (!(descriptor & 1) || (!(descriptor & 2) && (level == 3))) { + /* Invalid, or the Reserved level 3 encoding */ + goto do_fault; + } + + descaddr = descriptor & descaddrmask; + + /* + * For FEAT_LPA and PS=6, bits [51:48] of descaddr are in [15:12] + * of descriptor. For FEAT_LPA2 and effective DS, bits [51:50] of + * descaddr are in [9:8]. Otherwise, if descaddr is out of range, + * raise AddressSizeFault. + */ + if (outputsize > 48) { + if (param.ds) { + descaddr |= extract64(descriptor, 8, 2) << 50; + } else { + descaddr |= extract64(descriptor, 12, 4) << 48; + } + } else if (descaddr >> outputsize) { + fault_type = ARMFault_AddressSize; + goto do_fault; + } + + if ((descriptor & 2) && (level < 3)) { + /* + * Table entry. The top five bits are attributes which may + * propagate down through lower levels of the table (and + * which are all arranged so that 0 means "no effect", so + * we can gather them up by ORing in the bits at each level). + */ + tableattrs |= extract64(descriptor, 59, 5); + level++; + indexmask = indexmask_grainsize; + goto next_level; + } + + /* + * Block entry at level 1 or 2, or page entry at level 3. + * These are basically the same thing, although the number + * of bits we pull in from the vaddr varies. Note that although + * descaddrmask masks enough of the low bits of the descriptor + * to give a correct page or table address, the address field + * in a block descriptor is smaller; so we need to explicitly + * clear the lower bits here before ORing in the low vaddr bits. + */ + page_size = (1ULL << ((stride * (4 - level)) + 3)); + descaddr &= ~(hwaddr)(page_size - 1); + descaddr |= (address & (page_size - 1)); + /* Extract attributes from the descriptor */ + attrs = extract64(descriptor, 2, 10) + | (extract64(descriptor, 52, 12) << 10); + + if (regime_is_stage2(mmu_idx)) { + /* Stage 2 table descriptors do not include any attribute fields */ + goto skip_attrs; + } + /* Merge in attributes from table descriptors */ + attrs |= nstable << 3; /* NS */ + guarded = extract64(descriptor, 50, 1); /* GP */ + if (param.hpd) { + /* HPD disables all the table attributes except NSTable. */ + goto skip_attrs; + } + attrs |= extract32(tableattrs, 0, 2) << 11; /* XN, PXN */ + /* + * The sense of AP[1] vs APTable[0] is reversed, as APTable[0] == 1 + * means "force PL1 access only", which means forcing AP[1] to 0. + */ + attrs &= ~(extract32(tableattrs, 2, 1) << 4); /* !APT[0] => AP[1] */ + attrs |= extract32(tableattrs, 3, 1) << 5; /* APT[1] => AP[2] */ + skip_attrs: + /* * Here descaddr is the final physical address, and attributes * are all in attrs. From 27c1b81d6195ca5f39d656c5cca497ed78943339 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 15:18:45 +1000 Subject: [PATCH 205/705] target/arm: Fix fault reporting in get_phys_addr_lpae MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Always overriding fi->type was incorrect, as we would not properly propagate the fault type from S1_ptw_translate, or arm_ldq_ptw. Simplify things by providing a new label for a translation fault. For other faults, store into fi directly. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Reviewed-by: Alex Bennée Message-id: 20221024051851.3074715-9-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/ptw.c | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/target/arm/ptw.c b/target/arm/ptw.c index 2a5f018835..3302376e42 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -1044,8 +1044,6 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, ARMCPU *cpu = env_archcpu(env); ARMMMUIdx mmu_idx = ptw->in_mmu_idx; bool is_secure = ptw->in_secure; - /* Read an LPAE long-descriptor translation table. */ - ARMFaultType fault_type = ARMFault_Translation; uint32_t level; ARMVAParameters param; uint64_t ttbr; @@ -1082,8 +1080,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, * so our choice is to always raise the fault. */ if (param.tsz_oob) { - fault_type = ARMFault_Translation; - goto do_fault; + goto do_translation_fault; } addrsize = 64 - 8 * param.tbi; @@ -1120,8 +1117,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, addrsize - inputsize); if (-top_bits != param.select) { /* The gap between the two regions is a Translation fault */ - fault_type = ARMFault_Translation; - goto do_fault; + goto do_translation_fault; } } @@ -1147,7 +1143,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, * Translation table walk disabled => Translation fault on TLB miss * Note: This is always 0 on 64-bit EL2 and EL3. */ - goto do_fault; + goto do_translation_fault; } if (!regime_is_stage2(mmu_idx)) { @@ -1178,8 +1174,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, if (param.ds && stride == 9 && sl2) { if (sl0 != 0) { level = 0; - fault_type = ARMFault_Translation; - goto do_fault; + goto do_translation_fault; } startlevel = -1; } else if (!aarch64 || stride == 9) { @@ -1198,8 +1193,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, ok = check_s2_mmu_setup(cpu, aarch64, startlevel, inputsize, stride, outputsize); if (!ok) { - fault_type = ARMFault_Translation; - goto do_fault; + goto do_translation_fault; } level = startlevel; } @@ -1221,7 +1215,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, descaddr |= extract64(ttbr, 2, 4) << 48; } else if (descaddr >> outputsize) { level = 0; - fault_type = ARMFault_AddressSize; + fi->type = ARMFault_AddressSize; goto do_fault; } @@ -1282,7 +1276,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, if (!(descriptor & 1) || (!(descriptor & 2) && (level == 3))) { /* Invalid, or the Reserved level 3 encoding */ - goto do_fault; + goto do_translation_fault; } descaddr = descriptor & descaddrmask; @@ -1300,7 +1294,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, descaddr |= extract64(descriptor, 12, 4) << 48; } } else if (descaddr >> outputsize) { - fault_type = ARMFault_AddressSize; + fi->type = ARMFault_AddressSize; goto do_fault; } @@ -1357,9 +1351,9 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, * Here descaddr is the final physical address, and attributes * are all in attrs. */ - fault_type = ARMFault_AccessFlag; if ((attrs & (1 << 8)) == 0) { /* Access flag */ + fi->type = ARMFault_AccessFlag; goto do_fault; } @@ -1376,8 +1370,8 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, result->f.prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn); } - fault_type = ARMFault_Permission; if (!(result->f.prot & (1 << access_type))) { + fi->type = ARMFault_Permission; goto do_fault; } @@ -1422,8 +1416,9 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, result->f.lg_page_size = ctz64(page_size); return false; -do_fault: - fi->type = fault_type; + do_translation_fault: + fi->type = ARMFault_Translation; + do_fault: fi->level = level; /* Tag the error as S2 for failed S1 PTW at S2 or ordinary S2. */ fi->stage2 = fi->s1ptw || regime_is_stage2(mmu_idx); From 4566609176f82a8033d422bc6c04fc9c354bed24 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 15:18:46 +1000 Subject: [PATCH 206/705] target/arm: Don't shift attrs in get_phys_addr_lpae MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Leave the upper and lower attributes in the place they originate from in the descriptor. Shifting them around is confusing, since one cannot read the bit numbers out of the manual. Also, new attributes have been added which would alter the shifts. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Message-id: 20221024051851.3074715-10-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/ptw.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/target/arm/ptw.c b/target/arm/ptw.c index 3302376e42..691110f70c 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -1050,7 +1050,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, hwaddr descaddr, indexmask, indexmask_grainsize; uint32_t tableattrs; target_ulong page_size; - uint32_t attrs; + uint64_t attrs; int32_t stride; int addrsize, inputsize, outputsize; uint64_t tcr = regime_tcr(env, mmu_idx); @@ -1324,49 +1324,48 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, descaddr &= ~(hwaddr)(page_size - 1); descaddr |= (address & (page_size - 1)); /* Extract attributes from the descriptor */ - attrs = extract64(descriptor, 2, 10) - | (extract64(descriptor, 52, 12) << 10); + attrs = descriptor & (MAKE_64BIT_MASK(2, 10) | MAKE_64BIT_MASK(52, 12)); if (regime_is_stage2(mmu_idx)) { /* Stage 2 table descriptors do not include any attribute fields */ goto skip_attrs; } /* Merge in attributes from table descriptors */ - attrs |= nstable << 3; /* NS */ + attrs |= nstable << 5; /* NS */ guarded = extract64(descriptor, 50, 1); /* GP */ if (param.hpd) { /* HPD disables all the table attributes except NSTable. */ goto skip_attrs; } - attrs |= extract32(tableattrs, 0, 2) << 11; /* XN, PXN */ + attrs |= extract64(tableattrs, 0, 2) << 53; /* XN, PXN */ /* * The sense of AP[1] vs APTable[0] is reversed, as APTable[0] == 1 * means "force PL1 access only", which means forcing AP[1] to 0. */ - attrs &= ~(extract32(tableattrs, 2, 1) << 4); /* !APT[0] => AP[1] */ - attrs |= extract32(tableattrs, 3, 1) << 5; /* APT[1] => AP[2] */ + attrs &= ~(extract64(tableattrs, 2, 1) << 6); /* !APT[0] => AP[1] */ + attrs |= extract32(tableattrs, 3, 1) << 7; /* APT[1] => AP[2] */ skip_attrs: /* * Here descaddr is the final physical address, and attributes * are all in attrs. */ - if ((attrs & (1 << 8)) == 0) { + if ((attrs & (1 << 10)) == 0) { /* Access flag */ fi->type = ARMFault_AccessFlag; goto do_fault; } - ap = extract32(attrs, 4, 2); + ap = extract32(attrs, 6, 2); if (regime_is_stage2(mmu_idx)) { ns = mmu_idx == ARMMMUIdx_Stage2; - xn = extract32(attrs, 11, 2); + xn = extract64(attrs, 53, 2); result->f.prot = get_S2prot(env, ap, xn, s1_is_el0); } else { - ns = extract32(attrs, 3, 1); - xn = extract32(attrs, 12, 1); - pxn = extract32(attrs, 11, 1); + ns = extract32(attrs, 5, 1); + xn = extract64(attrs, 54, 1); + pxn = extract64(attrs, 53, 1); result->f.prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn); } @@ -1391,10 +1390,10 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, if (regime_is_stage2(mmu_idx)) { result->cacheattrs.is_s2_format = true; - result->cacheattrs.attrs = extract32(attrs, 0, 4); + result->cacheattrs.attrs = extract32(attrs, 2, 4); } else { /* Index into MAIR registers for cache attributes */ - uint8_t attrindx = extract32(attrs, 0, 3); + uint8_t attrindx = extract32(attrs, 2, 3); uint64_t mair = env->cp15.mair_el[regime_el(env, mmu_idx)]; assert(attrindx <= 7); result->cacheattrs.is_s2_format = false; @@ -1409,7 +1408,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, if (param.ds) { result->cacheattrs.shareability = param.sh; } else { - result->cacheattrs.shareability = extract32(attrs, 6, 2); + result->cacheattrs.shareability = extract32(attrs, 8, 2); } result->f.phys_addr = descaddr; From 0e8df0fe2425eae7baaf18da869da9aa3c44dc03 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 15:18:47 +1000 Subject: [PATCH 207/705] target/arm: Consider GP an attribute in get_phys_addr_lpae MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both GP and DBM are in the upper attribute block. Extend the computation of attrs to include them, then simplify the setting of guarded. Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Reviewed-by: Alex Bennée Message-id: 20221024051851.3074715-11-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/ptw.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/target/arm/ptw.c b/target/arm/ptw.c index 691110f70c..79a0ef45c7 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -1058,7 +1058,6 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, uint32_t el = regime_el(env, mmu_idx); uint64_t descaddrmask; bool aarch64 = arm_el_is_aa64(env, el); - bool guarded = false; uint64_t descriptor; bool nstable; @@ -1324,7 +1323,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, descaddr &= ~(hwaddr)(page_size - 1); descaddr |= (address & (page_size - 1)); /* Extract attributes from the descriptor */ - attrs = descriptor & (MAKE_64BIT_MASK(2, 10) | MAKE_64BIT_MASK(52, 12)); + attrs = descriptor & (MAKE_64BIT_MASK(2, 10) | MAKE_64BIT_MASK(50, 14)); if (regime_is_stage2(mmu_idx)) { /* Stage 2 table descriptors do not include any attribute fields */ @@ -1332,7 +1331,6 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, } /* Merge in attributes from table descriptors */ attrs |= nstable << 5; /* NS */ - guarded = extract64(descriptor, 50, 1); /* GP */ if (param.hpd) { /* HPD disables all the table attributes except NSTable. */ goto skip_attrs; @@ -1385,7 +1383,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, /* When in aarch64 mode, and BTI is enabled, remember GP in the TLB. */ if (aarch64 && cpu_isar_feature(aa64_bti, cpu)) { - result->f.guarded = guarded; + result->f.guarded = extract64(attrs, 50, 1); /* GP */ } if (regime_is_stage2(mmu_idx)) { From 34a57faeab62b27c01f008ef08654ca225e46673 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 15:18:48 +1000 Subject: [PATCH 208/705] target/arm: Tidy merging of attributes from descriptor and table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace some gotos with some nested if statements. Signed-off-by: Richard Henderson Reviewed-by: Alex Bennée Message-id: 20221024051851.3074715-12-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/ptw.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/target/arm/ptw.c b/target/arm/ptw.c index 79a0ef45c7..73b3c37b23 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -1322,27 +1322,25 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, page_size = (1ULL << ((stride * (4 - level)) + 3)); descaddr &= ~(hwaddr)(page_size - 1); descaddr |= (address & (page_size - 1)); - /* Extract attributes from the descriptor */ - attrs = descriptor & (MAKE_64BIT_MASK(2, 10) | MAKE_64BIT_MASK(50, 14)); - if (regime_is_stage2(mmu_idx)) { - /* Stage 2 table descriptors do not include any attribute fields */ - goto skip_attrs; - } - /* Merge in attributes from table descriptors */ - attrs |= nstable << 5; /* NS */ - if (param.hpd) { - /* HPD disables all the table attributes except NSTable. */ - goto skip_attrs; - } - attrs |= extract64(tableattrs, 0, 2) << 53; /* XN, PXN */ /* - * The sense of AP[1] vs APTable[0] is reversed, as APTable[0] == 1 - * means "force PL1 access only", which means forcing AP[1] to 0. + * Extract attributes from the descriptor, and apply table descriptors. + * Stage 2 table descriptors do not include any attribute fields. + * HPD disables all the table attributes except NSTable. */ - attrs &= ~(extract64(tableattrs, 2, 1) << 6); /* !APT[0] => AP[1] */ - attrs |= extract32(tableattrs, 3, 1) << 7; /* APT[1] => AP[2] */ - skip_attrs: + attrs = descriptor & (MAKE_64BIT_MASK(2, 10) | MAKE_64BIT_MASK(50, 14)); + if (!regime_is_stage2(mmu_idx)) { + attrs |= nstable << 5; /* NS */ + if (!param.hpd) { + attrs |= extract64(tableattrs, 0, 2) << 53; /* XN, PXN */ + /* + * The sense of AP[1] vs APTable[0] is reversed, as APTable[0] == 1 + * means "force PL1 access only", which means forcing AP[1] to 0. + */ + attrs &= ~(extract64(tableattrs, 2, 1) << 6); /* !APT[0] => AP[1] */ + attrs |= extract32(tableattrs, 3, 1) << 7; /* APT[1] => AP[2] */ + } + } /* * Here descaddr is the final physical address, and attributes From 71943a1e9084dde71cabba5895920f3a0c54de9b Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 15:18:49 +1000 Subject: [PATCH 209/705] target/arm: Implement FEAT_HAFDBS, access flag portion Perform the atomic update for hardware management of the access flag. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20221024051851.3074715-13-richard.henderson@linaro.org [PMM: Fix accidental PROT_WRITE to PAGE_WRITE; add missing main-loop.h include] Signed-off-by: Peter Maydell --- docs/system/arm/emulation.rst | 1 + target/arm/cpu64.c | 1 + target/arm/ptw.c | 177 +++++++++++++++++++++++++++++----- 3 files changed, 157 insertions(+), 22 deletions(-) diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst index fd61360a08..e3af79bb8c 100644 --- a/docs/system/arm/emulation.rst +++ b/docs/system/arm/emulation.rst @@ -33,6 +33,7 @@ the following architecture extensions: - FEAT_FlagM (Flag manipulation instructions v2) - FEAT_FlagM2 (Enhancements to flag manipulation instructions) - FEAT_GTG (Guest translation granule size) +- FEAT_HAFDBS (Hardware management of the access flag and dirty bit state) - FEAT_HCX (Support for the HCRX_EL2 register) - FEAT_HPDS (Hierarchical permission disables) - FEAT_I8MM (AArch64 Int8 matrix multiplication instructions) diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index da95eabab5..f2c3e41f5a 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -1165,6 +1165,7 @@ static void aarch64_max_initfn(Object *obj) cpu->isar.id_aa64mmfr0 = t; t = cpu->isar.id_aa64mmfr1; + t = FIELD_DP64(t, ID_AA64MMFR1, HAFDBS, 1); /* FEAT_HAFDBS, AF only */ t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* FEAT_VMID16 */ t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1); /* FEAT_VHE */ t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* FEAT_HPDS */ diff --git a/target/arm/ptw.c b/target/arm/ptw.c index 73b3c37b23..9941fa0ef9 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -9,6 +9,7 @@ #include "qemu/osdep.h" #include "qemu/log.h" #include "qemu/range.h" +#include "qemu/main-loop.h" #include "exec/exec-all.h" #include "cpu.h" #include "internals.h" @@ -21,7 +22,9 @@ typedef struct S1Translate { bool in_secure; bool in_debug; bool out_secure; + bool out_rw; bool out_be; + hwaddr out_virt; hwaddr out_phys; void *out_host; } S1Translate; @@ -219,6 +222,8 @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw, uint8_t pte_attrs; bool pte_secure; + ptw->out_virt = addr; + if (unlikely(ptw->in_debug)) { /* * From gdbstub, do not use softmmu so that we don't modify the @@ -247,6 +252,7 @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw, pte_secure = is_secure; } ptw->out_host = NULL; + ptw->out_rw = false; } else { CPUTLBEntryFull *full; int flags; @@ -261,6 +267,7 @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw, goto fail; } ptw->out_phys = full->phys_addr; + ptw->out_rw = full->prot & PAGE_WRITE; pte_attrs = full->pte_attrs; pte_secure = full->attrs.secure; } @@ -304,14 +311,16 @@ static uint32_t arm_ldl_ptw(CPUARMState *env, S1Translate *ptw, ARMMMUFaultInfo *fi) { CPUState *cs = env_cpu(env); + void *host = ptw->out_host; uint32_t data; - if (likely(ptw->out_host)) { + if (likely(host)) { /* Page tables are in RAM, and we have the host address. */ + data = qatomic_read((uint32_t *)host); if (ptw->out_be) { - data = ldl_be_p(ptw->out_host); + data = be32_to_cpu(data); } else { - data = ldl_le_p(ptw->out_host); + data = le32_to_cpu(data); } } else { /* Page tables are in MMIO. */ @@ -337,15 +346,25 @@ static uint64_t arm_ldq_ptw(CPUARMState *env, S1Translate *ptw, ARMMMUFaultInfo *fi) { CPUState *cs = env_cpu(env); + void *host = ptw->out_host; uint64_t data; - if (likely(ptw->out_host)) { + if (likely(host)) { /* Page tables are in RAM, and we have the host address. */ +#ifdef CONFIG_ATOMIC64 + data = qatomic_read__nocheck((uint64_t *)host); if (ptw->out_be) { - data = ldq_be_p(ptw->out_host); + data = be64_to_cpu(data); } else { - data = ldq_le_p(ptw->out_host); + data = le64_to_cpu(data); } +#else + if (ptw->out_be) { + data = ldq_be_p(host); + } else { + data = ldq_le_p(host); + } +#endif } else { /* Page tables are in MMIO. */ MemTxAttrs attrs = { .secure = ptw->out_secure }; @@ -366,6 +385,91 @@ static uint64_t arm_ldq_ptw(CPUARMState *env, S1Translate *ptw, return data; } +static uint64_t arm_casq_ptw(CPUARMState *env, uint64_t old_val, + uint64_t new_val, S1Translate *ptw, + ARMMMUFaultInfo *fi) +{ + uint64_t cur_val; + void *host = ptw->out_host; + + if (unlikely(!host)) { + fi->type = ARMFault_UnsuppAtomicUpdate; + fi->s1ptw = true; + return 0; + } + + /* + * Raising a stage2 Protection fault for an atomic update to a read-only + * page is delayed until it is certain that there is a change to make. + */ + if (unlikely(!ptw->out_rw)) { + int flags; + void *discard; + + env->tlb_fi = fi; + flags = probe_access_flags(env, ptw->out_virt, MMU_DATA_STORE, + arm_to_core_mmu_idx(ptw->in_ptw_idx), + true, &discard, 0); + env->tlb_fi = NULL; + + if (unlikely(flags & TLB_INVALID_MASK)) { + assert(fi->type != ARMFault_None); + fi->s2addr = ptw->out_virt; + fi->stage2 = true; + fi->s1ptw = true; + fi->s1ns = !ptw->in_secure; + return 0; + } + + /* In case CAS mismatches and we loop, remember writability. */ + ptw->out_rw = true; + } + +#ifdef CONFIG_ATOMIC64 + if (ptw->out_be) { + old_val = cpu_to_be64(old_val); + new_val = cpu_to_be64(new_val); + cur_val = qatomic_cmpxchg__nocheck((uint64_t *)host, old_val, new_val); + cur_val = be64_to_cpu(cur_val); + } else { + old_val = cpu_to_le64(old_val); + new_val = cpu_to_le64(new_val); + cur_val = qatomic_cmpxchg__nocheck((uint64_t *)host, old_val, new_val); + cur_val = le64_to_cpu(cur_val); + } +#else + /* + * We can't support the full 64-bit atomic cmpxchg on the host. + * Because this is only used for FEAT_HAFDBS, which is only for AA64, + * we know that TCG_OVERSIZED_GUEST is set, which means that we are + * running in round-robin mode and could only race with dma i/o. + */ +#ifndef TCG_OVERSIZED_GUEST +# error "Unexpected configuration" +#endif + bool locked = qemu_mutex_iothread_locked(); + if (!locked) { + qemu_mutex_lock_iothread(); + } + if (ptw->out_be) { + cur_val = ldq_be_p(host); + if (cur_val == old_val) { + stq_be_p(host, new_val); + } + } else { + cur_val = ldq_le_p(host); + if (cur_val == old_val) { + stq_le_p(host, new_val); + } + } + if (!locked) { + qemu_mutex_unlock_iothread(); + } +#endif + + return cur_val; +} + static bool get_level1_table_address(CPUARMState *env, ARMMMUIdx mmu_idx, uint32_t *table, uint32_t address) { @@ -1058,7 +1162,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, uint32_t el = regime_el(env, mmu_idx); uint64_t descaddrmask; bool aarch64 = arm_el_is_aa64(env, el); - uint64_t descriptor; + uint64_t descriptor, new_descriptor; bool nstable; /* TODO: This code does not support shareability levels. */ @@ -1272,7 +1376,9 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, if (fi->type != ARMFault_None) { goto do_fault; } + new_descriptor = descriptor; + restart_atomic_update: if (!(descriptor & 1) || (!(descriptor & 2) && (level == 3))) { /* Invalid, or the Reserved level 3 encoding */ goto do_translation_fault; @@ -1318,17 +1424,36 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, * to give a correct page or table address, the address field * in a block descriptor is smaller; so we need to explicitly * clear the lower bits here before ORing in the low vaddr bits. + * + * Afterward, descaddr is the final physical address. */ page_size = (1ULL << ((stride * (4 - level)) + 3)); descaddr &= ~(hwaddr)(page_size - 1); descaddr |= (address & (page_size - 1)); + if (likely(!ptw->in_debug)) { + /* + * Access flag. + * If HA is enabled, prepare to update the descriptor below. + * Otherwise, pass the access fault on to software. + */ + if (!(descriptor & (1 << 10))) { + if (param.ha) { + new_descriptor |= 1 << 10; /* AF */ + } else { + fi->type = ARMFault_AccessFlag; + goto do_fault; + } + } + } + /* - * Extract attributes from the descriptor, and apply table descriptors. - * Stage 2 table descriptors do not include any attribute fields. - * HPD disables all the table attributes except NSTable. + * Extract attributes from the (modified) descriptor, and apply + * table descriptors. Stage 2 table descriptors do not include + * any attribute fields. HPD disables all the table attributes + * except NSTable. */ - attrs = descriptor & (MAKE_64BIT_MASK(2, 10) | MAKE_64BIT_MASK(50, 14)); + attrs = new_descriptor & (MAKE_64BIT_MASK(2, 10) | MAKE_64BIT_MASK(50, 14)); if (!regime_is_stage2(mmu_idx)) { attrs |= nstable << 5; /* NS */ if (!param.hpd) { @@ -1342,18 +1467,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, } } - /* - * Here descaddr is the final physical address, and attributes - * are all in attrs. - */ - if ((attrs & (1 << 10)) == 0) { - /* Access flag */ - fi->type = ARMFault_AccessFlag; - goto do_fault; - } - ap = extract32(attrs, 6, 2); - if (regime_is_stage2(mmu_idx)) { ns = mmu_idx == ARMMMUIdx_Stage2; xn = extract64(attrs, 53, 2); @@ -1370,6 +1484,25 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, goto do_fault; } + /* If FEAT_HAFDBS has made changes, update the PTE. */ + if (new_descriptor != descriptor) { + new_descriptor = arm_casq_ptw(env, descriptor, new_descriptor, ptw, fi); + if (fi->type != ARMFault_None) { + goto do_fault; + } + /* + * I_YZSVV says that if the in-memory descriptor has changed, + * then we must use the information in that new value + * (which might include a different output address, different + * attributes, or generate a fault). + * Restart the handling of the descriptor value from scratch. + */ + if (new_descriptor != descriptor) { + descriptor = new_descriptor; + goto restart_atomic_update; + } + } + if (ns) { /* * The NS bit will (as required by the architecture) have no effect if From 65c123fdf577413a7d910e6b07c10e79d118041f Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 15:18:50 +1000 Subject: [PATCH 210/705] target/arm: Implement FEAT_HAFDBS, dirty bit portion Perform the atomic update for hardware management of the dirty bit. Signed-off-by: Richard Henderson Message-id: 20221024051851.3074715-14-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/cpu64.c | 2 +- target/arm/ptw.c | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index f2c3e41f5a..3d74f134f5 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -1165,7 +1165,7 @@ static void aarch64_max_initfn(Object *obj) cpu->isar.id_aa64mmfr0 = t; t = cpu->isar.id_aa64mmfr1; - t = FIELD_DP64(t, ID_AA64MMFR1, HAFDBS, 1); /* FEAT_HAFDBS, AF only */ + t = FIELD_DP64(t, ID_AA64MMFR1, HAFDBS, 2); /* FEAT_HAFDBS */ t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* FEAT_VMID16 */ t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1); /* FEAT_VHE */ t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* FEAT_HPDS */ diff --git a/target/arm/ptw.c b/target/arm/ptw.c index 9941fa0ef9..a1f4ae654f 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -1445,6 +1445,22 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, goto do_fault; } } + + /* + * Dirty Bit. + * If HD is enabled, pre-emptively set/clear the appropriate AP/S2AP + * bit for writeback. The actual write protection test may still be + * overridden by tableattrs, to be merged below. + */ + if (param.hd + && extract64(descriptor, 51, 1) /* DBM */ + && access_type == MMU_DATA_STORE) { + if (regime_is_stage2(mmu_idx)) { + new_descriptor |= 1ull << 7; /* set S2AP[1] */ + } else { + new_descriptor &= ~(1ull << 7); /* clear AP[2] */ + } + } } /* From c8d6c286ab4bff1c5ff511f3e834fb2a713d65d2 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 15:18:51 +1000 Subject: [PATCH 211/705] target/arm: Use the max page size in a 2-stage ptw We had only been reporting the stage2 page size. This causes problems if stage1 is using a larger page size (16k, 2M, etc), but stage2 is using a smaller page size, because cputlb does not set large_page_{addr,mask} properly. Fix by using the max of the two page sizes. Reported-by: Marc Zyngier Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20221024051851.3074715-15-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/ptw.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/target/arm/ptw.c b/target/arm/ptw.c index a1f4ae654f..58a7bbda50 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -2571,7 +2571,7 @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw, ARMMMUFaultInfo *fi) { hwaddr ipa; - int s1_prot; + int s1_prot, s1_lgpgsz; bool is_secure = ptw->in_secure; bool ret, ipa_secure, s2walk_secure; ARMCacheAttrs cacheattrs1; @@ -2607,6 +2607,7 @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw, * Save the stage1 results so that we may merge prot and cacheattrs later. */ s1_prot = result->f.prot; + s1_lgpgsz = result->f.lg_page_size; cacheattrs1 = result->cacheattrs; memset(result, 0, sizeof(*result)); @@ -2621,6 +2622,14 @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw, return ret; } + /* + * Use the maximum of the S1 & S2 page size, so that invalidation + * of pages > TARGET_PAGE_SIZE works correctly. + */ + if (result->f.lg_page_size < s1_lgpgsz) { + result->f.lg_page_size = s1_lgpgsz; + } + /* Combine the S1 and S2 cache attributes. */ hcr = arm_hcr_el2_eff_secstate(env, is_secure); if (hcr & HCR_DC) { From 7966d70f6f6b188475e67c2c363f19eec3d28c96 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Tue, 25 Oct 2022 02:43:17 +0200 Subject: [PATCH 212/705] reset: allow registering handlers that aren't called by snapshot loading Snapshot loading only expects to call deterministic handlers, not non-deterministic ones. So introduce a way of registering handlers that won't be called when reseting for snapshots. Signed-off-by: Jason A. Donenfeld Message-id: 20221025004327.568476-2-Jason@zx2c4.com [PMM: updated json doc comment with Markus' text; fixed checkpatch style nit] Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/arm/aspeed.c | 4 ++-- hw/arm/mps2-tz.c | 4 ++-- hw/core/reset.c | 17 ++++++++++++++++- hw/hppa/machine.c | 4 ++-- hw/i386/microvm.c | 4 ++-- hw/i386/pc.c | 6 +++--- hw/ppc/pegasos2.c | 4 ++-- hw/ppc/pnv.c | 4 ++-- hw/ppc/spapr.c | 4 ++-- hw/s390x/s390-virtio-ccw.c | 4 ++-- include/hw/boards.h | 2 +- include/sysemu/reset.h | 5 ++++- migration/savevm.c | 2 +- qapi/run-state.json | 6 +++++- softmmu/runstate.c | 11 ++++++++--- 15 files changed, 54 insertions(+), 27 deletions(-) diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c index f8bc6d4a14..55f114ef72 100644 --- a/hw/arm/aspeed.c +++ b/hw/arm/aspeed.c @@ -1356,12 +1356,12 @@ static void aspeed_machine_bletchley_class_init(ObjectClass *oc, void *data) aspeed_soc_num_cpus(amc->soc_name); } -static void fby35_reset(MachineState *state) +static void fby35_reset(MachineState *state, ShutdownCause reason) { AspeedMachineState *bmc = ASPEED_MACHINE(state); AspeedGPIOState *gpio = &bmc->soc.gpio; - qemu_devices_reset(); + qemu_devices_reset(reason); /* Board ID: 7 (Class-1, 4 slots) */ object_property_set_bool(OBJECT(gpio), "gpioV4", true, &error_fatal); diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c index 394192b9b2..284c09c91d 100644 --- a/hw/arm/mps2-tz.c +++ b/hw/arm/mps2-tz.c @@ -1239,7 +1239,7 @@ static void mps2_set_remap(Object *obj, const char *value, Error **errp) } } -static void mps2_machine_reset(MachineState *machine) +static void mps2_machine_reset(MachineState *machine, ShutdownCause reason) { MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine); @@ -1249,7 +1249,7 @@ static void mps2_machine_reset(MachineState *machine) * reset see the correct mapping. */ remap_memory(mms, mms->remap); - qemu_devices_reset(); + qemu_devices_reset(reason); } static void mps2tz_class_init(ObjectClass *oc, void *data) diff --git a/hw/core/reset.c b/hw/core/reset.c index 36be82c491..d3263b613e 100644 --- a/hw/core/reset.c +++ b/hw/core/reset.c @@ -33,6 +33,7 @@ typedef struct QEMUResetEntry { QTAILQ_ENTRY(QEMUResetEntry) entry; QEMUResetHandler *func; void *opaque; + bool skip_on_snapshot_load; } QEMUResetEntry; static QTAILQ_HEAD(, QEMUResetEntry) reset_handlers = @@ -47,6 +48,16 @@ void qemu_register_reset(QEMUResetHandler *func, void *opaque) QTAILQ_INSERT_TAIL(&reset_handlers, re, entry); } +void qemu_register_reset_nosnapshotload(QEMUResetHandler *func, void *opaque) +{ + QEMUResetEntry *re = g_new0(QEMUResetEntry, 1); + + re->func = func; + re->opaque = opaque; + re->skip_on_snapshot_load = true; + QTAILQ_INSERT_TAIL(&reset_handlers, re, entry); +} + void qemu_unregister_reset(QEMUResetHandler *func, void *opaque) { QEMUResetEntry *re; @@ -60,12 +71,16 @@ void qemu_unregister_reset(QEMUResetHandler *func, void *opaque) } } -void qemu_devices_reset(void) +void qemu_devices_reset(ShutdownCause reason) { QEMUResetEntry *re, *nre; /* reset all devices */ QTAILQ_FOREACH_SAFE(re, &reset_handlers, entry, nre) { + if (reason == SHUTDOWN_CAUSE_SNAPSHOT_LOAD && + re->skip_on_snapshot_load) { + continue; + } re->func(re->opaque); } } diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c index e53d5f0fa7..19ea7c2c66 100644 --- a/hw/hppa/machine.c +++ b/hw/hppa/machine.c @@ -411,12 +411,12 @@ static void machine_hppa_init(MachineState *machine) cpu[0]->env.gr[19] = FW_CFG_IO_BASE; } -static void hppa_machine_reset(MachineState *ms) +static void hppa_machine_reset(MachineState *ms, ShutdownCause reason) { unsigned int smp_cpus = ms->smp.cpus; int i; - qemu_devices_reset(); + qemu_devices_reset(reason); /* Start all CPUs at the firmware entry point. * Monarch CPU will initialize firmware, secondary CPUs diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c index 52f9aa9d8c..ffd1884100 100644 --- a/hw/i386/microvm.c +++ b/hw/i386/microvm.c @@ -467,7 +467,7 @@ static void microvm_machine_state_init(MachineState *machine) microvm_devices_init(mms); } -static void microvm_machine_reset(MachineState *machine) +static void microvm_machine_reset(MachineState *machine, ShutdownCause reason) { MicrovmMachineState *mms = MICROVM_MACHINE(machine); CPUState *cs; @@ -480,7 +480,7 @@ static void microvm_machine_reset(MachineState *machine) mms->kernel_cmdline_fixed = true; } - qemu_devices_reset(); + qemu_devices_reset(reason); CPU_FOREACH(cs) { cpu = X86_CPU(cs); diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 768982ae9a..3e86083db3 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1847,12 +1847,12 @@ static void pc_machine_initfn(Object *obj) cxl_machine_init(obj, &pcms->cxl_devices_state); } -static void pc_machine_reset(MachineState *machine) +static void pc_machine_reset(MachineState *machine, ShutdownCause reason) { CPUState *cs; X86CPU *cpu; - qemu_devices_reset(); + qemu_devices_reset(reason); /* Reset APIC after devices have been reset to cancel * any changes that qemu_devices_reset() might have done. @@ -1867,7 +1867,7 @@ static void pc_machine_reset(MachineState *machine) static void pc_machine_wakeup(MachineState *machine) { cpu_synchronize_all_states(); - pc_machine_reset(machine); + pc_machine_reset(machine, SHUTDOWN_CAUSE_NONE); cpu_synchronize_all_post_reset(); } diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c index ecf682b148..bb4d008ba9 100644 --- a/hw/ppc/pegasos2.c +++ b/hw/ppc/pegasos2.c @@ -248,14 +248,14 @@ static void pegasos2_pci_config_write(Pegasos2MachineState *pm, int bus, pegasos2_mv_reg_write(pm, pcicfg + 4, len, val); } -static void pegasos2_machine_reset(MachineState *machine) +static void pegasos2_machine_reset(MachineState *machine, ShutdownCause reason) { Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine); void *fdt; uint64_t d[2]; int sz; - qemu_devices_reset(); + qemu_devices_reset(reason); if (!pm->vof) { return; /* Firmware should set up machine so nothing to do */ } diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index 40bb573d1a..3d01e26f84 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -643,13 +643,13 @@ static void pnv_powerdown_notify(Notifier *n, void *opaque) } } -static void pnv_reset(MachineState *machine) +static void pnv_reset(MachineState *machine, ShutdownCause reason) { PnvMachineState *pnv = PNV_MACHINE(machine); IPMIBmc *bmc; void *fdt; - qemu_devices_reset(); + qemu_devices_reset(reason); /* * The machine should provide by default an internal BMC simulator. diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index f79ac85ca1..66b414d2e9 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1623,7 +1623,7 @@ void spapr_check_mmu_mode(bool guest_radix) } } -static void spapr_machine_reset(MachineState *machine) +static void spapr_machine_reset(MachineState *machine, ShutdownCause reason) { SpaprMachineState *spapr = SPAPR_MACHINE(machine); PowerPCCPU *first_ppc_cpu; @@ -1649,7 +1649,7 @@ static void spapr_machine_reset(MachineState *machine) spapr_setup_hpt(spapr); } - qemu_devices_reset(); + qemu_devices_reset(reason); spapr_ovec_cleanup(spapr->ov5_cas); spapr->ov5_cas = spapr_ovec_new(); diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index 1cc20d8717..806de32034 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -411,7 +411,7 @@ static void s390_pv_prepare_reset(S390CcwMachineState *ms) s390_pv_prep_reset(); } -static void s390_machine_reset(MachineState *machine) +static void s390_machine_reset(MachineState *machine, ShutdownCause reason) { S390CcwMachineState *ms = S390_CCW_MACHINE(machine); enum s390_reset reset_type; @@ -433,7 +433,7 @@ static void s390_machine_reset(MachineState *machine) s390_machine_unprotect(ms); } - qemu_devices_reset(); + qemu_devices_reset(reason); s390_crypto_reset(); /* configure and start the ipl CPU only */ diff --git a/include/hw/boards.h b/include/hw/boards.h index 311ed17e18..90f1dd3aeb 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -231,7 +231,7 @@ struct MachineClass { const char *deprecation_reason; void (*init)(MachineState *state); - void (*reset)(MachineState *state); + void (*reset)(MachineState *state, ShutdownCause reason); void (*wakeup)(MachineState *state); int (*kvm_type)(MachineState *machine, const char *arg); diff --git a/include/sysemu/reset.h b/include/sysemu/reset.h index 0b0d6d7598..609e4d50c2 100644 --- a/include/sysemu/reset.h +++ b/include/sysemu/reset.h @@ -1,10 +1,13 @@ #ifndef QEMU_SYSEMU_RESET_H #define QEMU_SYSEMU_RESET_H +#include "qapi/qapi-events-run-state.h" + typedef void QEMUResetHandler(void *opaque); void qemu_register_reset(QEMUResetHandler *func, void *opaque); +void qemu_register_reset_nosnapshotload(QEMUResetHandler *func, void *opaque); void qemu_unregister_reset(QEMUResetHandler *func, void *opaque); -void qemu_devices_reset(void); +void qemu_devices_reset(ShutdownCause reason); #endif diff --git a/migration/savevm.c b/migration/savevm.c index 48e85c052c..a0cdb714f7 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -3058,7 +3058,7 @@ bool load_snapshot(const char *name, const char *vmstate, goto err_drain; } - qemu_system_reset(SHUTDOWN_CAUSE_NONE); + qemu_system_reset(SHUTDOWN_CAUSE_SNAPSHOT_LOAD); mis->from_src_file = f; if (!yank_register_instance(MIGRATION_YANK_INSTANCE, errp)) { diff --git a/qapi/run-state.json b/qapi/run-state.json index 49989d30e6..419c188dd1 100644 --- a/qapi/run-state.json +++ b/qapi/run-state.json @@ -86,12 +86,16 @@ # ignores --no-reboot. This is useful for sanitizing # hypercalls on s390 that are used during kexec/kdump/boot # +# @snapshot-load: A snapshot is being loaded by the record & replay +# subsystem. This value is used only within QEMU. It +# doesn't occur in QMP. (since 7.2) +# ## { 'enum': 'ShutdownCause', # Beware, shutdown_caused_by_guest() depends on enumeration order 'data': [ 'none', 'host-error', 'host-qmp-quit', 'host-qmp-system-reset', 'host-signal', 'host-ui', 'guest-shutdown', 'guest-reset', - 'guest-panic', 'subsystem-reset'] } + 'guest-panic', 'subsystem-reset', 'snapshot-load'] } ## # @StatusInfo: diff --git a/softmmu/runstate.c b/softmmu/runstate.c index 1e68680b9d..3dd83d5e5d 100644 --- a/softmmu/runstate.c +++ b/softmmu/runstate.c @@ -441,11 +441,16 @@ void qemu_system_reset(ShutdownCause reason) cpu_synchronize_all_states(); if (mc && mc->reset) { - mc->reset(current_machine); + mc->reset(current_machine, reason); } else { - qemu_devices_reset(); + qemu_devices_reset(reason); } - if (reason && reason != SHUTDOWN_CAUSE_SUBSYSTEM_RESET) { + switch (reason) { + case SHUTDOWN_CAUSE_NONE: + case SHUTDOWN_CAUSE_SUBSYSTEM_RESET: + case SHUTDOWN_CAUSE_SNAPSHOT_LOAD: + break; + default: qapi_event_send_reset(shutdown_caused_by_guest(reason), reason); } cpu_synchronize_all_post_reset(); From e1e618b9a0f9c23e9caa5933fa30ee3d33e00bfe Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Tue, 25 Oct 2022 02:43:18 +0200 Subject: [PATCH 213/705] device-tree: add re-randomization helper function When the system reboots, the rng-seed that the FDT has should be re-randomized, so that the new boot gets a new seed. Several architectures require this functionality, so export a function for injecting a new seed into the given FDT. Cc: Alistair Francis Cc: David Gibson Signed-off-by: Jason A. Donenfeld Reviewed-by: Alistair Francis Message-id: 20221025004327.568476-3-Jason@zx2c4.com Signed-off-by: Peter Maydell --- include/sysemu/device_tree.h | 9 +++++++++ softmmu/device_tree.c | 21 +++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/include/sysemu/device_tree.h b/include/sysemu/device_tree.h index e7c5441f56..ca5339beae 100644 --- a/include/sysemu/device_tree.h +++ b/include/sysemu/device_tree.h @@ -197,6 +197,15 @@ int qemu_fdt_setprop_sized_cells_from_array(void *fdt, qdt_tmp); \ }) + +/** + * qemu_fdt_randomize_seeds: + * @fdt: device tree blob + * + * Re-randomize all "rng-seed" properties with new seeds. + */ +void qemu_fdt_randomize_seeds(void *fdt); + #define FDT_PCI_RANGE_RELOCATABLE 0x80000000 #define FDT_PCI_RANGE_PREFETCHABLE 0x40000000 #define FDT_PCI_RANGE_ALIASED 0x20000000 diff --git a/softmmu/device_tree.c b/softmmu/device_tree.c index ce74f3d48d..30aa3aea9f 100644 --- a/softmmu/device_tree.c +++ b/softmmu/device_tree.c @@ -22,6 +22,7 @@ #include "qemu/option.h" #include "qemu/bswap.h" #include "qemu/cutils.h" +#include "qemu/guest-random.h" #include "sysemu/device_tree.h" #include "hw/loader.h" #include "hw/boards.h" @@ -680,3 +681,23 @@ void hmp_dumpdtb(Monitor *mon, const QDict *qdict) info_report("dtb dumped to %s", filename); } + +void qemu_fdt_randomize_seeds(void *fdt) +{ + int noffset, poffset, len; + const char *name; + uint8_t *data; + + for (noffset = fdt_next_node(fdt, 0, NULL); + noffset >= 0; + noffset = fdt_next_node(fdt, noffset, NULL)) { + for (poffset = fdt_first_property_offset(fdt, noffset); + poffset >= 0; + poffset = fdt_next_property_offset(fdt, poffset)) { + data = (uint8_t *)fdt_getprop_by_offset(fdt, poffset, &name, &len); + if (!data || strcmp(name, "rng-seed")) + continue; + qemu_guest_getrandom_nofail(data, len); + } + } +} From 14b29fea742034186403914b4d013d0e83f19e78 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Tue, 25 Oct 2022 02:43:19 +0200 Subject: [PATCH 214/705] x86: do not re-randomize RNG seed on snapshot load Snapshot loading is supposed to be deterministic, so we shouldn't re-randomize the various seeds used. Signed-off-by: Jason A. Donenfeld Message-id: 20221025004327.568476-4-Jason@zx2c4.com Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/i386/x86.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/i386/x86.c b/hw/i386/x86.c index 1148f70c03..bd50a064a3 100644 --- a/hw/i386/x86.c +++ b/hw/i386/x86.c @@ -1111,7 +1111,7 @@ void x86_load_linux(X86MachineState *x86ms, setup_data->type = cpu_to_le32(SETUP_RNG_SEED); setup_data->len = cpu_to_le32(RNG_SEED_LENGTH); qemu_guest_getrandom_nofail(setup_data->data, RNG_SEED_LENGTH); - qemu_register_reset(reset_rng_seed, setup_data); + qemu_register_reset_nosnapshotload(reset_rng_seed, setup_data); fw_cfg_add_bytes_callback(fw_cfg, FW_CFG_KERNEL_DATA, reset_rng_seed, NULL, setup_data, kernel, kernel_size, true); } else { From 98aa4c839d2cd24a2f6d3bbaa68fcb5d4aa502cd Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Tue, 25 Oct 2022 02:43:20 +0200 Subject: [PATCH 215/705] arm: re-randomize rng-seed on reboot When the system reboots, the rng-seed that the FDT has should be re-randomized, so that the new boot gets a new seed. Since the FDT is in the ROM region at this point, we add a hook right after the ROM has been added, so that we have a pointer to that copy of the FDT. Cc: Peter Maydell Cc: qemu-arm@nongnu.org Signed-off-by: Jason A. Donenfeld Message-id: 20221025004327.568476-5-Jason@zx2c4.com Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/arm/boot.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/arm/boot.c b/hw/arm/boot.c index b0b92af188..b106f31468 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -683,6 +683,8 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo, * the DTB is copied again upon reset, even if addr points into RAM. */ rom_add_blob_fixed_as("dtb", fdt, size, addr, as); + qemu_register_reset_nosnapshotload(qemu_fdt_randomize_seeds, + rom_ptr_for_as(as, addr, size)); g_free(fdt); From 64c75db3c5ab6f8c75c8132b200cf1c64186f04b Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Tue, 25 Oct 2022 02:43:21 +0200 Subject: [PATCH 216/705] riscv: re-randomize rng-seed on reboot When the system reboots, the rng-seed that the FDT has should be re-randomized, so that the new boot gets a new seed. Since the FDT is in the ROM region at this point, we add a hook right after the ROM has been added, so that we have a pointer to that copy of the FDT. Cc: Palmer Dabbelt Cc: Alistair Francis Cc: Bin Meng Cc: qemu-riscv@nongnu.org Signed-off-by: Jason A. Donenfeld Reviewed-by: Alistair Francis Message-id: 20221025004327.568476-6-Jason@zx2c4.com Signed-off-by: Peter Maydell --- hw/riscv/boot.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c index e82bf27338..ebd351c840 100644 --- a/hw/riscv/boot.c +++ b/hw/riscv/boot.c @@ -30,6 +30,7 @@ #include "sysemu/device_tree.h" #include "sysemu/qtest.h" #include "sysemu/kvm.h" +#include "sysemu/reset.h" #include @@ -241,6 +242,8 @@ uint64_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt) rom_add_blob_fixed_as("fdt", fdt, fdtsize, fdt_addr, &address_space_memory); + qemu_register_reset_nosnapshotload(qemu_fdt_randomize_seeds, + rom_ptr_for_as(&address_space_memory, fdt_addr, fdtsize)); return fdt_addr; } From 1ffd007c9c5862d50235cfb507a1722fe1c213b5 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Tue, 25 Oct 2022 02:43:22 +0200 Subject: [PATCH 217/705] m68k/virt: do not re-randomize RNG seed on snapshot load Snapshot loading is supposed to be deterministic, so we shouldn't re-randomize the various seeds used. Signed-off-by: Jason A. Donenfeld Message-id: 20221025004327.568476-7-Jason@zx2c4.com Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/m68k/virt.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c index 89c4108eb5..da5eafd275 100644 --- a/hw/m68k/virt.c +++ b/hw/m68k/virt.c @@ -89,7 +89,6 @@ typedef struct { M68kCPU *cpu; hwaddr initial_pc; hwaddr initial_stack; - struct bi_record *rng_seed; } ResetInfo; static void main_cpu_reset(void *opaque) @@ -98,16 +97,18 @@ static void main_cpu_reset(void *opaque) M68kCPU *cpu = reset_info->cpu; CPUState *cs = CPU(cpu); - if (reset_info->rng_seed) { - qemu_guest_getrandom_nofail((void *)reset_info->rng_seed->data + 2, - be16_to_cpu(*(uint16_t *)reset_info->rng_seed->data)); - } - cpu_reset(cs); cpu->env.aregs[7] = reset_info->initial_stack; cpu->env.pc = reset_info->initial_pc; } +static void rerandomize_rng_seed(void *opaque) +{ + struct bi_record *rng_seed = opaque; + qemu_guest_getrandom_nofail((void *)rng_seed->data + 2, + be16_to_cpu(*(uint16_t *)rng_seed->data)); +} + static void virt_init(MachineState *machine) { M68kCPU *cpu = NULL; @@ -289,9 +290,10 @@ static void virt_init(MachineState *machine) BOOTINFO0(param_ptr, BI_LAST); rom_add_blob_fixed_as("bootinfo", param_blob, param_ptr - param_blob, parameters_base, cs->as); - reset_info->rng_seed = rom_ptr_for_as(cs->as, parameters_base, - param_ptr - param_blob) + - (param_rng_seed - param_blob); + qemu_register_reset_nosnapshotload(rerandomize_rng_seed, + rom_ptr_for_as(cs->as, parameters_base, + param_ptr - param_blob) + + (param_rng_seed - param_blob)); g_free(param_blob); } } From fbbbe7eb23e4120a64238d41367a3fabccb59781 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Tue, 25 Oct 2022 02:43:23 +0200 Subject: [PATCH 218/705] m68k/q800: do not re-randomize RNG seed on snapshot load Snapshot loading is supposed to be deterministic, so we shouldn't re-randomize the various seeds used. Signed-off-by: Jason A. Donenfeld Message-id: 20221025004327.568476-8-Jason@zx2c4.com Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/m68k/q800.c | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c index e09e244ddc..9d52ca6613 100644 --- a/hw/m68k/q800.c +++ b/hw/m68k/q800.c @@ -321,27 +321,23 @@ static const TypeInfo glue_info = { }, }; -typedef struct { - M68kCPU *cpu; - struct bi_record *rng_seed; -} ResetInfo; - static void main_cpu_reset(void *opaque) { - ResetInfo *reset_info = opaque; - M68kCPU *cpu = reset_info->cpu; + M68kCPU *cpu = opaque; CPUState *cs = CPU(cpu); - if (reset_info->rng_seed) { - qemu_guest_getrandom_nofail((void *)reset_info->rng_seed->data + 2, - be16_to_cpu(*(uint16_t *)reset_info->rng_seed->data)); - } - cpu_reset(cs); cpu->env.aregs[7] = ldl_phys(cs->as, 0); cpu->env.pc = ldl_phys(cs->as, 4); } +static void rerandomize_rng_seed(void *opaque) +{ + struct bi_record *rng_seed = opaque; + qemu_guest_getrandom_nofail((void *)rng_seed->data + 2, + be16_to_cpu(*(uint16_t *)rng_seed->data)); +} + static uint8_t fake_mac_rom[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -397,7 +393,6 @@ static void q800_init(MachineState *machine) NubusBus *nubus; DeviceState *glue; DriveInfo *dinfo; - ResetInfo *reset_info; uint8_t rng_seed[32]; linux_boot = (kernel_filename != NULL); @@ -408,12 +403,9 @@ static void q800_init(MachineState *machine) exit(1); } - reset_info = g_new0(ResetInfo, 1); - /* init CPUs */ cpu = M68K_CPU(cpu_create(machine->cpu_type)); - reset_info->cpu = cpu; - qemu_register_reset(main_cpu_reset, reset_info); + qemu_register_reset(main_cpu_reset, cpu); /* RAM */ memory_region_add_subregion(get_system_memory(), 0, machine->ram); @@ -687,9 +679,10 @@ static void q800_init(MachineState *machine) BOOTINFO0(param_ptr, BI_LAST); rom_add_blob_fixed_as("bootinfo", param_blob, param_ptr - param_blob, parameters_base, cs->as); - reset_info->rng_seed = rom_ptr_for_as(cs->as, parameters_base, - param_ptr - param_blob) + - (param_rng_seed - param_blob); + qemu_register_reset_nosnapshotload(rerandomize_rng_seed, + rom_ptr_for_as(cs->as, parameters_base, + param_ptr - param_blob) + + (param_rng_seed - param_blob)); g_free(param_blob); } else { uint8_t *ptr; From 4fbae24450a67c3dfea6d2617e6d1f7a4dd206dc Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Tue, 25 Oct 2022 02:43:24 +0200 Subject: [PATCH 219/705] mips/boston: re-randomize rng-seed on reboot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the system reboots, the rng-seed that the FDT has should be re-randomized, so that the new boot gets a new seed. Since the FDT is in the ROM region at this point, we add a hook right after the ROM has been added, so that we have a pointer to that copy of the FDT. Cc: Aleksandar Rikalo Cc: Paul Burton Cc: Philippe Mathieu-Daudé Signed-off-by: Jason A. Donenfeld Message-id: 20221025004327.568476-9-Jason@zx2c4.com Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/mips/boston.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hw/mips/boston.c b/hw/mips/boston.c index d2ab9da1a0..cab63f43bf 100644 --- a/hw/mips/boston.c +++ b/hw/mips/boston.c @@ -41,6 +41,7 @@ #include "sysemu/sysemu.h" #include "sysemu/qtest.h" #include "sysemu/runstate.h" +#include "sysemu/reset.h" #include #include "qom/object.h" @@ -810,6 +811,8 @@ static void boston_mach_init(MachineState *machine) /* Calculate real fdt size after filter */ dt_size = fdt_totalsize(dtb_load_data); rom_add_blob_fixed("dtb", dtb_load_data, dt_size, dtb_paddr); + qemu_register_reset_nosnapshotload(qemu_fdt_randomize_seeds, + rom_ptr(dtb_paddr, dt_size)); } else { /* Try to load file as FIT */ fit_err = load_fit(&boston_fit_loader, machine->kernel_filename, s); From 2db07d0506d365884b140fd5640fd71db15eacbc Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Tue, 25 Oct 2022 02:43:26 +0200 Subject: [PATCH 220/705] openrisc: re-randomize rng-seed on reboot When the system reboots, the rng-seed that the FDT has should be re-randomized, so that the new boot gets a new seed. Since the FDT is in the ROM region at this point, we add a hook right after the ROM has been added, so that we have a pointer to that copy of the FDT. Cc: Stafford Horne Signed-off-by: Jason A. Donenfeld Message-id: 20221025004327.568476-11-Jason@zx2c4.com Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/openrisc/boot.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hw/openrisc/boot.c b/hw/openrisc/boot.c index 128ccbcba2..007e80cd5a 100644 --- a/hw/openrisc/boot.c +++ b/hw/openrisc/boot.c @@ -14,6 +14,7 @@ #include "hw/openrisc/boot.h" #include "sysemu/device_tree.h" #include "sysemu/qtest.h" +#include "sysemu/reset.h" #include @@ -111,6 +112,8 @@ uint32_t openrisc_load_fdt(void *fdt, hwaddr load_start, rom_add_blob_fixed_as("fdt", fdt, fdtsize, fdt_addr, &address_space_memory); + qemu_register_reset_nosnapshotload(qemu_fdt_randomize_seeds, + rom_ptr_for_as(&address_space_memory, fdt_addr, fdtsize)); return fdt_addr; } From a76b911c0de3d72e245060a57d02f816fb1334e2 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Tue, 25 Oct 2022 02:43:27 +0200 Subject: [PATCH 221/705] rx: re-randomize rng-seed on reboot When the system reboots, the rng-seed that the FDT has should be re-randomized, so that the new boot gets a new seed. Since the FDT is in the ROM region at this point, we add a hook right after the ROM has been added, so that we have a pointer to that copy of the FDT. Cc: Yoshinori Sato Signed-off-by: Jason A. Donenfeld Message-id: 20221025004327.568476-12-Jason@zx2c4.com Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/rx/rx-gdbsim.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hw/rx/rx-gdbsim.c b/hw/rx/rx-gdbsim.c index 8ffe1b8035..47c17026c7 100644 --- a/hw/rx/rx-gdbsim.c +++ b/hw/rx/rx-gdbsim.c @@ -25,6 +25,7 @@ #include "hw/rx/rx62n.h" #include "sysemu/qtest.h" #include "sysemu/device_tree.h" +#include "sysemu/reset.h" #include "hw/boards.h" #include "qom/object.h" @@ -148,6 +149,8 @@ static void rx_gdbsim_init(MachineState *machine) dtb_offset = ROUND_DOWN(machine->ram_size - dtb_size, 16); rom_add_blob_fixed("dtb", dtb, dtb_size, SDRAM_BASE + dtb_offset); + qemu_register_reset_nosnapshotload(qemu_fdt_randomize_seeds, + rom_ptr(SDRAM_BASE + dtb_offset, dtb_size)); /* Set dtb address to R1 */ RX_CPU(first_cpu)->env.regs[1] = SDRAM_BASE + dtb_offset; } From 6233a138599bea89ad683b883dca38388f12fd2d Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Tue, 25 Oct 2022 19:28:43 +0200 Subject: [PATCH 222/705] mips/malta: pass RNG seed via env var and re-randomize on reboot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As of the kernel commit linked below, Linux ingests an RNG seed passed as part of the environment block by the bootloader or firmware. This mechanism works across all different environment block types, generically, which pass some block via the second firmware argument. On malta, this has been tested to work when passed as an argument from U-Boot's linux_env_set. As is the case on most other architectures (such as boston), when booting with `-kernel`, QEMU, acting as the bootloader, should pass the RNG seed, so that the machine has good entropy for Linux to consume. So this commit implements that quite simply by using the guest random API, which is what is used on nearly all other archs too. It also reinitializes the seed on reboot, so that it is always fresh. Link: https://git.kernel.org/torvalds/c/056a68cea01 Cc: Aleksandar Rikalo Cc: Paul Burton Cc: Philippe Mathieu-Daudé Signed-off-by: Jason A. Donenfeld Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/mips/malta.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/hw/mips/malta.c b/hw/mips/malta.c index 0e932988e0..7c3ad0974b 100644 --- a/hw/mips/malta.c +++ b/hw/mips/malta.c @@ -26,6 +26,7 @@ #include "qemu/units.h" #include "qemu/bitops.h" #include "qemu/datadir.h" +#include "qemu/guest-random.h" #include "hw/clock.h" #include "hw/southbridge/piix.h" #include "hw/isa/superio.h" @@ -1017,6 +1018,17 @@ static void G_GNUC_PRINTF(3, 4) prom_set(uint32_t *prom_buf, int index, va_end(ap); } +static void reinitialize_rng_seed(void *opaque) +{ + char *rng_seed_hex = opaque; + uint8_t rng_seed[32]; + + qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed)); + for (size_t i = 0; i < sizeof(rng_seed); ++i) { + sprintf(rng_seed_hex + i * 2, "%02x", rng_seed[i]); + } +} + /* Kernel */ static uint64_t load_kernel(void) { @@ -1028,6 +1040,9 @@ static uint64_t load_kernel(void) long prom_size; int prom_index = 0; uint64_t (*xlate_to_kseg0) (void *opaque, uint64_t addr); + uint8_t rng_seed[32]; + char rng_seed_hex[sizeof(rng_seed) * 2 + 1]; + size_t rng_seed_prom_offset; #if TARGET_BIG_ENDIAN big_endian = 1; @@ -1115,9 +1130,21 @@ static uint64_t load_kernel(void) prom_set(prom_buf, prom_index++, "modetty0"); prom_set(prom_buf, prom_index++, "38400n8r"); + + qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed)); + for (size_t i = 0; i < sizeof(rng_seed); ++i) { + sprintf(rng_seed_hex + i * 2, "%02x", rng_seed[i]); + } + prom_set(prom_buf, prom_index++, "rngseed"); + rng_seed_prom_offset = prom_index * ENVP_ENTRY_SIZE + + sizeof(uint32_t) * ENVP_NB_ENTRIES; + prom_set(prom_buf, prom_index++, "%s", rng_seed_hex); + prom_set(prom_buf, prom_index++, NULL); rom_add_blob_fixed("prom", prom_buf, prom_size, ENVP_PADDR); + qemu_register_reset_nosnapshotload(reinitialize_rng_seed, + rom_ptr(ENVP_PADDR, prom_size) + rng_seed_prom_offset); g_free(prom_buf); return kernel_entry; From dd84a906e061550daaedea6ce88762f1839253ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Tue, 26 Apr 2022 14:06:49 +0100 Subject: [PATCH 223/705] scripts: check if .git exists before checking submodule status MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently we check status of each submodule, before actually checking if we're in a git repo. These status commands will all fail, but we are hiding their output so we don't see it currently. Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé --- scripts/git-submodule.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/git-submodule.sh b/scripts/git-submodule.sh index e225d3a963..7be41f5948 100755 --- a/scripts/git-submodule.sh +++ b/scripts/git-submodule.sh @@ -51,6 +51,12 @@ validate_error() { exit 1 } +if test -n "$maybe_modules" && ! test -e ".git" +then + echo "$0: unexpectedly called with submodules but no git checkout exists" + exit 1 +fi + modules="" for m in $maybe_modules do @@ -63,12 +69,6 @@ do fi done -if test -n "$maybe_modules" && ! test -e ".git" -then - echo "$0: unexpectedly called with submodules but no git checkout exists" - exit 1 -fi - case "$command" in status|validate) if test -z "$maybe_modules" From 3983bf1b41cefcf553a2c6316f767367d6977b51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Wed, 28 Sep 2022 15:56:42 +0100 Subject: [PATCH 224/705] crypto: check for and report errors setting PSK credentials MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If setting credentials fails, the handshake will later fail to complete with an obscure error message which is hard to diagnose. Reviewed-by: Bin Meng Tested-by: Bin Meng Signed-off-by: Daniel P. Berrangé --- crypto/tlscredspsk.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/crypto/tlscredspsk.c b/crypto/tlscredspsk.c index a4f9891274..546cad1c5a 100644 --- a/crypto/tlscredspsk.c +++ b/crypto/tlscredspsk.c @@ -109,7 +109,12 @@ qcrypto_tls_creds_psk_load(QCryptoTLSCredsPSK *creds, goto cleanup; } - gnutls_psk_set_server_credentials_file(creds->data.server, pskfile); + ret = gnutls_psk_set_server_credentials_file(creds->data.server, pskfile); + if (ret < 0) { + error_setg(errp, "Cannot set PSK server credentials: %s", + gnutls_strerror(ret)); + goto cleanup; + } gnutls_psk_set_server_dh_params(creds->data.server, creds->parent_obj.dh_params); } else { @@ -135,8 +140,13 @@ qcrypto_tls_creds_psk_load(QCryptoTLSCredsPSK *creds, goto cleanup; } - gnutls_psk_set_client_credentials(creds->data.client, - username, &key, GNUTLS_PSK_KEY_HEX); + ret = gnutls_psk_set_client_credentials(creds->data.client, + username, &key, GNUTLS_PSK_KEY_HEX); + if (ret < 0) { + error_setg(errp, "Cannot set PSK client credentials: %s", + gnutls_strerror(ret)); + goto cleanup; + } } rv = 0; From f1018ea0a30f577d1e3515d0a6362e362a0cb86f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Wed, 28 Sep 2022 15:57:24 +0100 Subject: [PATCH 225/705] tests: avoid DOS line endings in PSK file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using FILE * APIs for writing the PSK file results in translation from UNIX to DOS line endings on Windows. When the crypto PSK code later loads the credentials the stray \r will result in failure to load the PSK credentials into GNUTLS. Rather than switching the FILE* APIs to open in binary format, just switch to the more concise g_file_set_contents API. Reviewed-by: Bin Meng Tested-by: Bin Meng Signed-off-by: Daniel P. Berrangé --- tests/unit/crypto-tls-psk-helpers.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/unit/crypto-tls-psk-helpers.c b/tests/unit/crypto-tls-psk-helpers.c index 511e08cc9c..c6cc740772 100644 --- a/tests/unit/crypto-tls-psk-helpers.c +++ b/tests/unit/crypto-tls-psk-helpers.c @@ -27,15 +27,14 @@ static void test_tls_psk_init_common(const char *pskfile, const char *user, const char *key) { - FILE *fp; + g_autoptr(GError) gerr = NULL; + g_autofree char *line = g_strdup_printf("%s:%s\n", user, key); - fp = fopen(pskfile, "w"); - if (fp == NULL) { - g_critical("Failed to create pskfile %s: %s", pskfile, strerror(errno)); + g_file_set_contents(pskfile, line, strlen(line), &gerr); + if (gerr != NULL) { + g_critical("Failed to create pskfile %s: %s", pskfile, gerr->message); abort(); } - fprintf(fp, "%s:%s\n", user, key); - fclose(fp); } void test_tls_psk_init(const char *pskfile) From c1d8634c207defb547a57515729233e47f65718f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Tue, 10 May 2022 14:17:43 +0100 Subject: [PATCH 226/705] crypto: sanity check that LUKS header strings are NUL-terminated MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The LUKS spec requires that header strings are NUL-terminated, and our code relies on that. Protect against maliciously crafted headers by adding validation. Reviewed-by: Richard W.M. Jones Signed-off-by: Daniel P. Berrangé --- crypto/block-luks.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/crypto/block-luks.c b/crypto/block-luks.c index f62be6836b..27d1b34c1d 100644 --- a/crypto/block-luks.c +++ b/crypto/block-luks.c @@ -554,6 +554,24 @@ qcrypto_block_luks_check_header(const QCryptoBlockLUKS *luks, Error **errp) return -1; } + if (!memchr(luks->header.cipher_name, '\0', + sizeof(luks->header.cipher_name))) { + error_setg(errp, "LUKS header cipher name is not NUL terminated"); + return -1; + } + + if (!memchr(luks->header.cipher_mode, '\0', + sizeof(luks->header.cipher_mode))) { + error_setg(errp, "LUKS header cipher mode is not NUL terminated"); + return -1; + } + + if (!memchr(luks->header.hash_spec, '\0', + sizeof(luks->header.hash_spec))) { + error_setg(errp, "LUKS header hash spec is not NUL terminated"); + return -1; + } + /* Check all keyslots for corruption */ for (i = 0 ; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS ; i++) { From f1195961f36b19ce9008dabf11ee8362803bcd92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Tue, 10 May 2022 14:27:33 +0100 Subject: [PATCH 227/705] crypto: enforce that LUKS stripes is always a fixed value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Although the LUKS stripes are encoded in the keyslot header and so potentially configurable, in pratice the cryptsetup impl mandates this has the fixed value 4000. To avoid incompatibility apply the same enforcement in QEMU too. This also caps the memory usage for key material when QEMU tries to open a LUKS volume. Reviewed-by: Richard W.M. Jones Signed-off-by: Daniel P. Berrangé --- crypto/block-luks.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/crypto/block-luks.c b/crypto/block-luks.c index 27d1b34c1d..81744e2a8e 100644 --- a/crypto/block-luks.c +++ b/crypto/block-luks.c @@ -582,8 +582,9 @@ qcrypto_block_luks_check_header(const QCryptoBlockLUKS *luks, Error **errp) header_sectors, slot1->stripes); - if (slot1->stripes == 0) { - error_setg(errp, "Keyslot %zu is corrupted (stripes == 0)", i); + if (slot1->stripes != QCRYPTO_BLOCK_LUKS_STRIPES) { + error_setg(errp, "Keyslot %zu is corrupted (stripes %d != %d)", + i, slot1->stripes, QCRYPTO_BLOCK_LUKS_STRIPES); return -1; } From 93569c373027c5c46e518e01c0c3e2d07fbb6890 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Tue, 10 May 2022 14:35:57 +0100 Subject: [PATCH 228/705] crypto: enforce that key material doesn't overlap with LUKS header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We already check that key material doesn't overlap between key slots, and that it doesn't overlap with the payload. We didn't check for overlap with the LUKS header. Reviewed-by: Richard W.M. Jones Signed-off-by: Daniel P. Berrangé --- crypto/block-luks.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/crypto/block-luks.c b/crypto/block-luks.c index 81744e2a8e..6ef9a89ffa 100644 --- a/crypto/block-luks.c +++ b/crypto/block-luks.c @@ -595,6 +595,14 @@ qcrypto_block_luks_check_header(const QCryptoBlockLUKS *luks, Error **errp) return -1; } + if (start1 < DIV_ROUND_UP(sizeof(QCryptoBlockLUKSHeader), + QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)) { + error_setg(errp, + "Keyslot %zu is overlapping with the LUKS header", + i); + return -1; + } + if (start1 + len1 > luks->header.payload_offset_sector) { error_setg(errp, "Keyslot %zu is overlapping with the encrypted payload", From d233fbc327d3f1f03bc30e0486b9ade3aa23f9ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Mon, 5 Sep 2022 13:50:03 +0100 Subject: [PATCH 229/705] crypto: validate that LUKS payload doesn't overlap with header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We already validate that LUKS keyslots don't overlap with the header, or with each other. This closes the remaining hole in validation of LUKS file regions. Reviewed-by: Richard W.M. Jones Signed-off-by: Daniel P. Berrangé --- crypto/block-luks.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/crypto/block-luks.c b/crypto/block-luks.c index 6ef9a89ffa..f22bc63e54 100644 --- a/crypto/block-luks.c +++ b/crypto/block-luks.c @@ -572,6 +572,13 @@ qcrypto_block_luks_check_header(const QCryptoBlockLUKS *luks, Error **errp) return -1; } + if (luks->header.payload_offset_sector < + DIV_ROUND_UP(QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET, + QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)) { + error_setg(errp, "LUKS payload is overlapping with the header"); + return -1; + } + /* Check all keyslots for corruption */ for (i = 0 ; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS ; i++) { From c5f6962801b868b02fbaf01861f64783470d3d2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Mon, 5 Sep 2022 13:57:01 +0100 Subject: [PATCH 230/705] crypto: strengthen the check for key slots overlapping with LUKS header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The LUKS header data on disk is a fixed size, however, there's expected to be a gap between the end of the header and the first key slot to get alignment with the 2nd sector on 4k drives. This wasn't originally part of the LUKS spec, but was always part of the reference implementation, so it is worth validating this. Reviewed-by: Richard W.M. Jones Signed-off-by: Daniel P. Berrangé --- crypto/block-luks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/block-luks.c b/crypto/block-luks.c index f22bc63e54..e6ee8506b2 100644 --- a/crypto/block-luks.c +++ b/crypto/block-luks.c @@ -602,7 +602,7 @@ qcrypto_block_luks_check_header(const QCryptoBlockLUKS *luks, Error **errp) return -1; } - if (start1 < DIV_ROUND_UP(sizeof(QCryptoBlockLUKSHeader), + if (start1 < DIV_ROUND_UP(QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)) { error_setg(errp, "Keyslot %zu is overlapping with the LUKS header", From b57151ac0366d3fb14318a55b0fc943134f7f80b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Mon, 5 Sep 2022 13:52:29 +0100 Subject: [PATCH 231/705] crypto: check that LUKS PBKDF2 iterations count is non-zero MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both the master key and key slot passphrases are run through the PBKDF2 algorithm. The iterations count is expected to be generally very large (many 10's or 100's of 1000s). It is hard to define a low level cutoff, but we can certainly say that iterations count should be non-zero. A zero count likely indicates an initialization mistake so reject it. Reviewed-by: Richard W.M. Jones Signed-off-by: Daniel P. Berrangé --- crypto/block-luks.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/crypto/block-luks.c b/crypto/block-luks.c index e6ee8506b2..254490c256 100644 --- a/crypto/block-luks.c +++ b/crypto/block-luks.c @@ -579,6 +579,11 @@ qcrypto_block_luks_check_header(const QCryptoBlockLUKS *luks, Error **errp) return -1; } + if (luks->header.master_key_iterations == 0) { + error_setg(errp, "LUKS key iteration count is zero"); + return -1; + } + /* Check all keyslots for corruption */ for (i = 0 ; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS ; i++) { @@ -602,6 +607,12 @@ qcrypto_block_luks_check_header(const QCryptoBlockLUKS *luks, Error **errp) return -1; } + if (slot1->active == QCRYPTO_BLOCK_LUKS_KEY_SLOT_ENABLED && + slot1->iterations == 0) { + error_setg(errp, "Keyslot %zu iteration count is zero", i); + return -1; + } + if (start1 < DIV_ROUND_UP(QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)) { error_setg(errp, From 36445acebdd100237551b47b4fd77f0c5403a10f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Tue, 10 May 2022 15:19:58 +0100 Subject: [PATCH 232/705] crypto: split LUKS header definitions off into file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will allow unit testing code to use the structs. Reviewed-by: Richard W.M. Jones Signed-off-by: Daniel P. Berrangé --- crypto/block-luks-priv.h | 137 +++++++++++++++++++++++++++++++++++++++ crypto/block-luks.c | 94 +-------------------------- 2 files changed, 138 insertions(+), 93 deletions(-) create mode 100644 crypto/block-luks-priv.h diff --git a/crypto/block-luks-priv.h b/crypto/block-luks-priv.h new file mode 100644 index 0000000000..1516571dcb --- /dev/null +++ b/crypto/block-luks-priv.h @@ -0,0 +1,137 @@ +/* + * QEMU Crypto block device encryption LUKS format + * + * Copyright (c) 2015-2016 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu/bswap.h" + +#include "block-luks.h" + +#include "crypto/hash.h" +#include "crypto/afsplit.h" +#include "crypto/pbkdf.h" +#include "crypto/secret.h" +#include "crypto/random.h" +#include "qemu/uuid.h" + +#include "qemu/coroutine.h" +#include "qemu/bitmap.h" + +/* + * Reference for the LUKS format implemented here is + * + * docs/on-disk-format.pdf + * + * in 'cryptsetup' package source code + * + * This file implements the 1.2.1 specification, dated + * Oct 16, 2011. + */ + +typedef struct QCryptoBlockLUKSHeader QCryptoBlockLUKSHeader; +typedef struct QCryptoBlockLUKSKeySlot QCryptoBlockLUKSKeySlot; + + +/* The following constants are all defined by the LUKS spec */ +#define QCRYPTO_BLOCK_LUKS_VERSION 1 + +#define QCRYPTO_BLOCK_LUKS_MAGIC_LEN 6 +#define QCRYPTO_BLOCK_LUKS_CIPHER_NAME_LEN 32 +#define QCRYPTO_BLOCK_LUKS_CIPHER_MODE_LEN 32 +#define QCRYPTO_BLOCK_LUKS_HASH_SPEC_LEN 32 +#define QCRYPTO_BLOCK_LUKS_DIGEST_LEN 20 +#define QCRYPTO_BLOCK_LUKS_SALT_LEN 32 +#define QCRYPTO_BLOCK_LUKS_UUID_LEN 40 +#define QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS 8 +#define QCRYPTO_BLOCK_LUKS_STRIPES 4000 +#define QCRYPTO_BLOCK_LUKS_MIN_SLOT_KEY_ITERS 1000 +#define QCRYPTO_BLOCK_LUKS_MIN_MASTER_KEY_ITERS 1000 +#define QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET 4096 + +#define QCRYPTO_BLOCK_LUKS_KEY_SLOT_DISABLED 0x0000DEAD +#define QCRYPTO_BLOCK_LUKS_KEY_SLOT_ENABLED 0x00AC71F3 + +#define QCRYPTO_BLOCK_LUKS_SECTOR_SIZE 512LL + +#define QCRYPTO_BLOCK_LUKS_DEFAULT_ITER_TIME_MS 2000 +#define QCRYPTO_BLOCK_LUKS_ERASE_ITERATIONS 40 + +static const char qcrypto_block_luks_magic[QCRYPTO_BLOCK_LUKS_MAGIC_LEN] = { + 'L', 'U', 'K', 'S', 0xBA, 0xBE +}; + +/* + * This struct is written to disk in big-endian format, + * but operated upon in native-endian format. + */ +struct QCryptoBlockLUKSKeySlot { + /* state of keyslot, enabled/disable */ + uint32_t active; + /* iterations for PBKDF2 */ + uint32_t iterations; + /* salt for PBKDF2 */ + uint8_t salt[QCRYPTO_BLOCK_LUKS_SALT_LEN]; + /* start sector of key material */ + uint32_t key_offset_sector; + /* number of anti-forensic stripes */ + uint32_t stripes; +}; + +/* + * This struct is written to disk in big-endian format, + * but operated upon in native-endian format. + */ +struct QCryptoBlockLUKSHeader { + /* 'L', 'U', 'K', 'S', '0xBA', '0xBE' */ + char magic[QCRYPTO_BLOCK_LUKS_MAGIC_LEN]; + + /* LUKS version, currently 1 */ + uint16_t version; + + /* cipher name specification (aes, etc) */ + char cipher_name[QCRYPTO_BLOCK_LUKS_CIPHER_NAME_LEN]; + + /* cipher mode specification (cbc-plain, xts-essiv:sha256, etc) */ + char cipher_mode[QCRYPTO_BLOCK_LUKS_CIPHER_MODE_LEN]; + + /* hash specification (sha256, etc) */ + char hash_spec[QCRYPTO_BLOCK_LUKS_HASH_SPEC_LEN]; + + /* start offset of the volume data (in 512 byte sectors) */ + uint32_t payload_offset_sector; + + /* Number of key bytes */ + uint32_t master_key_len; + + /* master key checksum after PBKDF2 */ + uint8_t master_key_digest[QCRYPTO_BLOCK_LUKS_DIGEST_LEN]; + + /* salt for master key PBKDF2 */ + uint8_t master_key_salt[QCRYPTO_BLOCK_LUKS_SALT_LEN]; + + /* iterations for master key PBKDF2 */ + uint32_t master_key_iterations; + + /* UUID of the partition in standard ASCII representation */ + uint8_t uuid[QCRYPTO_BLOCK_LUKS_UUID_LEN]; + + /* key slots */ + QCryptoBlockLUKSKeySlot key_slots[QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS]; +}; diff --git a/crypto/block-luks.c b/crypto/block-luks.c index 254490c256..375cce44cd 100644 --- a/crypto/block-luks.c +++ b/crypto/block-luks.c @@ -23,6 +23,7 @@ #include "qemu/bswap.h" #include "block-luks.h" +#include "block-luks-priv.h" #include "crypto/hash.h" #include "crypto/afsplit.h" @@ -46,37 +47,6 @@ */ typedef struct QCryptoBlockLUKS QCryptoBlockLUKS; -typedef struct QCryptoBlockLUKSHeader QCryptoBlockLUKSHeader; -typedef struct QCryptoBlockLUKSKeySlot QCryptoBlockLUKSKeySlot; - - -/* The following constants are all defined by the LUKS spec */ -#define QCRYPTO_BLOCK_LUKS_VERSION 1 - -#define QCRYPTO_BLOCK_LUKS_MAGIC_LEN 6 -#define QCRYPTO_BLOCK_LUKS_CIPHER_NAME_LEN 32 -#define QCRYPTO_BLOCK_LUKS_CIPHER_MODE_LEN 32 -#define QCRYPTO_BLOCK_LUKS_HASH_SPEC_LEN 32 -#define QCRYPTO_BLOCK_LUKS_DIGEST_LEN 20 -#define QCRYPTO_BLOCK_LUKS_SALT_LEN 32 -#define QCRYPTO_BLOCK_LUKS_UUID_LEN 40 -#define QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS 8 -#define QCRYPTO_BLOCK_LUKS_STRIPES 4000 -#define QCRYPTO_BLOCK_LUKS_MIN_SLOT_KEY_ITERS 1000 -#define QCRYPTO_BLOCK_LUKS_MIN_MASTER_KEY_ITERS 1000 -#define QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET 4096 - -#define QCRYPTO_BLOCK_LUKS_KEY_SLOT_DISABLED 0x0000DEAD -#define QCRYPTO_BLOCK_LUKS_KEY_SLOT_ENABLED 0x00AC71F3 - -#define QCRYPTO_BLOCK_LUKS_SECTOR_SIZE 512LL - -#define QCRYPTO_BLOCK_LUKS_DEFAULT_ITER_TIME_MS 2000 -#define QCRYPTO_BLOCK_LUKS_ERASE_ITERATIONS 40 - -static const char qcrypto_block_luks_magic[QCRYPTO_BLOCK_LUKS_MAGIC_LEN] = { - 'L', 'U', 'K', 'S', 0xBA, 0xBE -}; typedef struct QCryptoBlockLUKSNameMap QCryptoBlockLUKSNameMap; struct QCryptoBlockLUKSNameMap { @@ -134,69 +104,7 @@ qcrypto_block_luks_cipher_name_map[] = { { "twofish", qcrypto_block_luks_cipher_size_map_twofish }, }; - -/* - * This struct is written to disk in big-endian format, - * but operated upon in native-endian format. - */ -struct QCryptoBlockLUKSKeySlot { - /* state of keyslot, enabled/disable */ - uint32_t active; - /* iterations for PBKDF2 */ - uint32_t iterations; - /* salt for PBKDF2 */ - uint8_t salt[QCRYPTO_BLOCK_LUKS_SALT_LEN]; - /* start sector of key material */ - uint32_t key_offset_sector; - /* number of anti-forensic stripes */ - uint32_t stripes; -}; - QEMU_BUILD_BUG_ON(sizeof(struct QCryptoBlockLUKSKeySlot) != 48); - - -/* - * This struct is written to disk in big-endian format, - * but operated upon in native-endian format. - */ -struct QCryptoBlockLUKSHeader { - /* 'L', 'U', 'K', 'S', '0xBA', '0xBE' */ - char magic[QCRYPTO_BLOCK_LUKS_MAGIC_LEN]; - - /* LUKS version, currently 1 */ - uint16_t version; - - /* cipher name specification (aes, etc) */ - char cipher_name[QCRYPTO_BLOCK_LUKS_CIPHER_NAME_LEN]; - - /* cipher mode specification (cbc-plain, xts-essiv:sha256, etc) */ - char cipher_mode[QCRYPTO_BLOCK_LUKS_CIPHER_MODE_LEN]; - - /* hash specification (sha256, etc) */ - char hash_spec[QCRYPTO_BLOCK_LUKS_HASH_SPEC_LEN]; - - /* start offset of the volume data (in 512 byte sectors) */ - uint32_t payload_offset_sector; - - /* Number of key bytes */ - uint32_t master_key_len; - - /* master key checksum after PBKDF2 */ - uint8_t master_key_digest[QCRYPTO_BLOCK_LUKS_DIGEST_LEN]; - - /* salt for master key PBKDF2 */ - uint8_t master_key_salt[QCRYPTO_BLOCK_LUKS_SALT_LEN]; - - /* iterations for master key PBKDF2 */ - uint32_t master_key_iterations; - - /* UUID of the partition in standard ASCII representation */ - uint8_t uuid[QCRYPTO_BLOCK_LUKS_UUID_LEN]; - - /* key slots */ - QCryptoBlockLUKSKeySlot key_slots[QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS]; -}; - QEMU_BUILD_BUG_ON(sizeof(struct QCryptoBlockLUKSHeader) != 592); From 98c72dfb714385b03da03abb45f931a14af6138e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Tue, 10 May 2022 15:40:55 +0100 Subject: [PATCH 233/705] crypto: split off helpers for converting LUKS header endianess MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The unit test suite is shortly going to want to convert header endianness separately from the main I/O functions. Reviewed-by: Richard W.M. Jones Signed-off-by: Daniel P. Berrangé --- crypto/block-luks-priv.h | 6 +++ crypto/block-luks.c | 79 ++++++++++++++++++++++++---------------- 2 files changed, 53 insertions(+), 32 deletions(-) diff --git a/crypto/block-luks-priv.h b/crypto/block-luks-priv.h index 1516571dcb..90a20d432b 100644 --- a/crypto/block-luks-priv.h +++ b/crypto/block-luks-priv.h @@ -135,3 +135,9 @@ struct QCryptoBlockLUKSHeader { /* key slots */ QCryptoBlockLUKSKeySlot key_slots[QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS]; }; + + +void +qcrypto_block_luks_to_disk_endian(QCryptoBlockLUKSHeader *hdr); +void +qcrypto_block_luks_from_disk_endian(QCryptoBlockLUKSHeader *hdr); diff --git a/crypto/block-luks.c b/crypto/block-luks.c index 375cce44cd..bb89c10225 100644 --- a/crypto/block-luks.c +++ b/crypto/block-luks.c @@ -348,6 +348,51 @@ qcrypto_block_luks_splitkeylen_sectors(const QCryptoBlockLUKS *luks, return ROUND_UP(splitkeylen_sectors, header_sectors); } + +void +qcrypto_block_luks_to_disk_endian(QCryptoBlockLUKSHeader *hdr) +{ + size_t i; + + /* + * Everything on disk uses Big Endian (tm), so flip header fields + * before writing them + */ + cpu_to_be16s(&hdr->version); + cpu_to_be32s(&hdr->payload_offset_sector); + cpu_to_be32s(&hdr->master_key_len); + cpu_to_be32s(&hdr->master_key_iterations); + + for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) { + cpu_to_be32s(&hdr->key_slots[i].active); + cpu_to_be32s(&hdr->key_slots[i].iterations); + cpu_to_be32s(&hdr->key_slots[i].key_offset_sector); + cpu_to_be32s(&hdr->key_slots[i].stripes); + } +} + +void +qcrypto_block_luks_from_disk_endian(QCryptoBlockLUKSHeader *hdr) +{ + size_t i; + + /* + * The header is always stored in big-endian format, so + * convert everything to native + */ + be16_to_cpus(&hdr->version); + be32_to_cpus(&hdr->payload_offset_sector); + be32_to_cpus(&hdr->master_key_len); + be32_to_cpus(&hdr->master_key_iterations); + + for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) { + be32_to_cpus(&hdr->key_slots[i].active); + be32_to_cpus(&hdr->key_slots[i].iterations); + be32_to_cpus(&hdr->key_slots[i].key_offset_sector); + be32_to_cpus(&hdr->key_slots[i].stripes); + } +} + /* * Stores the main LUKS header, taking care of endianess */ @@ -359,28 +404,13 @@ qcrypto_block_luks_store_header(QCryptoBlock *block, { const QCryptoBlockLUKS *luks = block->opaque; Error *local_err = NULL; - size_t i; g_autofree QCryptoBlockLUKSHeader *hdr_copy = NULL; /* Create a copy of the header */ hdr_copy = g_new0(QCryptoBlockLUKSHeader, 1); memcpy(hdr_copy, &luks->header, sizeof(QCryptoBlockLUKSHeader)); - /* - * Everything on disk uses Big Endian (tm), so flip header fields - * before writing them - */ - cpu_to_be16s(&hdr_copy->version); - cpu_to_be32s(&hdr_copy->payload_offset_sector); - cpu_to_be32s(&hdr_copy->master_key_len); - cpu_to_be32s(&hdr_copy->master_key_iterations); - - for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) { - cpu_to_be32s(&hdr_copy->key_slots[i].active); - cpu_to_be32s(&hdr_copy->key_slots[i].iterations); - cpu_to_be32s(&hdr_copy->key_slots[i].key_offset_sector); - cpu_to_be32s(&hdr_copy->key_slots[i].stripes); - } + qcrypto_block_luks_to_disk_endian(hdr_copy); /* Write out the partition header and key slot headers */ writefunc(block, 0, (const uint8_t *)hdr_copy, sizeof(*hdr_copy), @@ -404,7 +434,6 @@ qcrypto_block_luks_load_header(QCryptoBlock *block, Error **errp) { int rv; - size_t i; QCryptoBlockLUKS *luks = block->opaque; /* @@ -420,21 +449,7 @@ qcrypto_block_luks_load_header(QCryptoBlock *block, return rv; } - /* - * The header is always stored in big-endian format, so - * convert everything to native - */ - be16_to_cpus(&luks->header.version); - be32_to_cpus(&luks->header.payload_offset_sector); - be32_to_cpus(&luks->header.master_key_len); - be32_to_cpus(&luks->header.master_key_iterations); - - for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) { - be32_to_cpus(&luks->header.key_slots[i].active); - be32_to_cpus(&luks->header.key_slots[i].iterations); - be32_to_cpus(&luks->header.key_slots[i].key_offset_sector); - be32_to_cpus(&luks->header.key_slots[i].stripes); - } + qcrypto_block_luks_from_disk_endian(&luks->header); return 0; } From 6c1989321eb95d5d2e29d3537484836bf0f21744 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Mon, 5 Sep 2022 12:08:21 +0100 Subject: [PATCH 234/705] crypto: quote algorithm names in error messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If given a malformed LUKS header, it is possible that the algorithm names end up being an empty string. This leads to confusing error messages unless quoting is used to highlight where the empty string is subsituted in the error message. Reviewed-by: Richard W.M. Jones Signed-off-by: Daniel P. Berrangé --- crypto/block-luks.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crypto/block-luks.c b/crypto/block-luks.c index bb89c10225..df2b4105d6 100644 --- a/crypto/block-luks.c +++ b/crypto/block-luks.c @@ -162,7 +162,7 @@ static int qcrypto_block_luks_cipher_name_lookup(const char *name, } } - error_setg(errp, "Algorithm %s with key size %d bytes not supported", + error_setg(errp, "Algorithm '%s' with key size %d bytes not supported", name, key_bytes); return 0; } @@ -198,7 +198,7 @@ static int qcrypto_block_luks_name_lookup(const char *name, int ret = qapi_enum_parse(map, name, -1, NULL); if (ret < 0) { - error_setg(errp, "%s %s not supported", type, name); + error_setg(errp, "%s '%s' not supported", type, name); return 0; } return ret; @@ -592,7 +592,7 @@ qcrypto_block_luks_parse_header(QCryptoBlockLUKS *luks, Error **errp) */ ivgen_name = strchr(cipher_mode, '-'); if (!ivgen_name) { - error_setg(errp, "Unexpected cipher mode string format %s", + error_setg(errp, "Unexpected cipher mode string format '%s'", luks->header.cipher_mode); return -1; } From 741c314a337ff4c79b8a86fbd5891054b0191d44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Mon, 5 Sep 2022 14:37:05 +0100 Subject: [PATCH 235/705] crypto: ensure LUKS tests run with GNUTLS crypto provider MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GNUTLS is supported as a crypto provider since commit cc4c7c738297958b3d1d16269f57d71d22f5a9ff Author: Daniel P. Berrangé Date: Wed Jun 30 17:20:02 2021 +0100 crypto: introduce build system for gnutls crypto backend So enable the LUKS tests in this config. Reviewed-by: Richard W.M. Jones Signed-off-by: Daniel P. Berrangé --- tests/unit/test-crypto-block.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/unit/test-crypto-block.c b/tests/unit/test-crypto-block.c index 3417b67be5..3d50eb4b6e 100644 --- a/tests/unit/test-crypto-block.c +++ b/tests/unit/test-crypto-block.c @@ -30,7 +30,8 @@ #endif #if (defined(_WIN32) || defined RUSAGE_THREAD) && \ - (defined(CONFIG_NETTLE) || defined(CONFIG_GCRYPT)) + (defined(CONFIG_NETTLE) || defined(CONFIG_GCRYPT) || \ + defined(CONFIG_GNUTLS_CRYPTO)) #define TEST_LUKS #else #undef TEST_LUKS From da0ab2c4c4d22dece12acd9ddaed901a10a5edee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Mon, 5 Sep 2022 14:57:17 +0100 Subject: [PATCH 236/705] crypto: add test cases for many malformed LUKS header scenarios MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Validate that we diagnose each malformed LUKS header scenario with a distinct error report. Reviewed-by: Richard W.M. Jones Signed-off-by: Daniel P. Berrangé --- tests/unit/test-crypto-block.c | 299 +++++++++++++++++++++++++++++++++ 1 file changed, 299 insertions(+) diff --git a/tests/unit/test-crypto-block.c b/tests/unit/test-crypto-block.c index 3d50eb4b6e..b629e240a9 100644 --- a/tests/unit/test-crypto-block.c +++ b/tests/unit/test-crypto-block.c @@ -22,6 +22,7 @@ #include "qapi/error.h" #include "crypto/init.h" #include "crypto/block.h" +#include "crypto/block-luks-priv.h" #include "qemu/buffer.h" #include "qemu/module.h" #include "crypto/secret.h" @@ -345,6 +346,230 @@ static void test_block(gconstpointer opaque) } +#ifdef TEST_LUKS +typedef const char *(*LuksHeaderDoBadStuff)(QCryptoBlockLUKSHeader *hdr); + +static void +test_luks_bad_header(gconstpointer data) +{ + LuksHeaderDoBadStuff badstuff = data; + QCryptoBlock *blk; + Buffer buf; + Object *sec = test_block_secret(); + QCryptoBlockLUKSHeader hdr; + Error *err = NULL; + const char *msg; + + memset(&buf, 0, sizeof(buf)); + buffer_init(&buf, "header"); + + /* Correctly create the volume initially */ + blk = qcrypto_block_create(&luks_create_opts_default, NULL, + test_block_init_func, + test_block_write_func, + &buf, + &error_abort); + g_assert(blk); + + qcrypto_block_free(blk); + + /* Mangle it in some unpleasant way */ + g_assert(buf.offset >= sizeof(hdr)); + memcpy(&hdr, buf.buffer, sizeof(hdr)); + qcrypto_block_luks_to_disk_endian(&hdr); + + msg = badstuff(&hdr); + + qcrypto_block_luks_from_disk_endian(&hdr); + memcpy(buf.buffer, &hdr, sizeof(hdr)); + + /* Check that we fail to open it again */ + blk = qcrypto_block_open(&luks_open_opts, NULL, + test_block_read_func, + &buf, + 0, + 1, + &err); + g_assert(!blk); + g_assert(err); + + g_assert_cmpstr(error_get_pretty(err), ==, msg); + error_free(err); + + object_unparent(sec); + + buffer_free(&buf); +} + +static const char *luks_bad_null_term_cipher_name(QCryptoBlockLUKSHeader *hdr) +{ + /* Replace NUL termination with spaces */ + char *offset = hdr->cipher_name + strlen(hdr->cipher_name); + memset(offset, ' ', sizeof(hdr->cipher_name) - (offset - hdr->cipher_name)); + + return "LUKS header cipher name is not NUL terminated"; +} + +static const char *luks_bad_null_term_cipher_mode(QCryptoBlockLUKSHeader *hdr) +{ + /* Replace NUL termination with spaces */ + char *offset = hdr->cipher_mode + strlen(hdr->cipher_mode); + memset(offset, ' ', sizeof(hdr->cipher_mode) - (offset - hdr->cipher_mode)); + + return "LUKS header cipher mode is not NUL terminated"; +} + +static const char *luks_bad_null_term_hash_spec(QCryptoBlockLUKSHeader *hdr) +{ + /* Replace NUL termination with spaces */ + char *offset = hdr->hash_spec + strlen(hdr->hash_spec); + memset(offset, ' ', sizeof(hdr->hash_spec) - (offset - hdr->hash_spec)); + + return "LUKS header hash spec is not NUL terminated"; +} + +static const char *luks_bad_cipher_name_empty(QCryptoBlockLUKSHeader *hdr) +{ + memcpy(hdr->cipher_name, "", 1); + + return "Algorithm '' with key size 32 bytes not supported"; +} + +static const char *luks_bad_cipher_name_unknown(QCryptoBlockLUKSHeader *hdr) +{ + memcpy(hdr->cipher_name, "aess", 5); + + return "Algorithm 'aess' with key size 32 bytes not supported"; +} + +static const char *luks_bad_cipher_xts_size(QCryptoBlockLUKSHeader *hdr) +{ + hdr->master_key_len = 33; + + return "XTS cipher key length should be a multiple of 2"; +} + +static const char *luks_bad_cipher_cbc_size(QCryptoBlockLUKSHeader *hdr) +{ + hdr->master_key_len = 33; + memcpy(hdr->cipher_mode, "cbc-essiv", 10); + + return "Algorithm 'aes' with key size 33 bytes not supported"; +} + +static const char *luks_bad_cipher_mode_empty(QCryptoBlockLUKSHeader *hdr) +{ + memcpy(hdr->cipher_mode, "", 1); + + return "Unexpected cipher mode string format ''"; +} + +static const char *luks_bad_cipher_mode_unknown(QCryptoBlockLUKSHeader *hdr) +{ + memcpy(hdr->cipher_mode, "xfs", 4); + + return "Unexpected cipher mode string format 'xfs'"; +} + +static const char *luks_bad_ivgen_separator(QCryptoBlockLUKSHeader *hdr) +{ + memcpy(hdr->cipher_mode, "xts:plain64", 12); + + return "Unexpected cipher mode string format 'xts:plain64'"; +} + +static const char *luks_bad_ivgen_name_empty(QCryptoBlockLUKSHeader *hdr) +{ + memcpy(hdr->cipher_mode, "xts-", 5); + + return "IV generator '' not supported"; +} + +static const char *luks_bad_ivgen_name_unknown(QCryptoBlockLUKSHeader *hdr) +{ + memcpy(hdr->cipher_mode, "xts-plain65", 12); + + return "IV generator 'plain65' not supported"; +} + +static const char *luks_bad_ivgen_hash_empty(QCryptoBlockLUKSHeader *hdr) +{ + memcpy(hdr->cipher_mode, "xts-plain65:", 13); + + return "Hash algorithm '' not supported"; +} + +static const char *luks_bad_ivgen_hash_unknown(QCryptoBlockLUKSHeader *hdr) +{ + memcpy(hdr->cipher_mode, "xts-plain65:sha257", 19); + + return "Hash algorithm 'sha257' not supported"; +} + +static const char *luks_bad_hash_spec_empty(QCryptoBlockLUKSHeader *hdr) +{ + memcpy(hdr->hash_spec, "", 1); + + return "Hash algorithm '' not supported"; +} + +static const char *luks_bad_hash_spec_unknown(QCryptoBlockLUKSHeader *hdr) +{ + memcpy(hdr->hash_spec, "sha2566", 8); + + return "Hash algorithm 'sha2566' not supported"; +} + +static const char *luks_bad_stripes(QCryptoBlockLUKSHeader *hdr) +{ + hdr->key_slots[0].stripes = 3999; + + return "Keyslot 0 is corrupted (stripes 3999 != 4000)"; +} + +static const char *luks_bad_key_overlap_header(QCryptoBlockLUKSHeader *hdr) +{ + hdr->key_slots[0].key_offset_sector = 2; + + return "Keyslot 0 is overlapping with the LUKS header"; +} + +static const char *luks_bad_key_overlap_key(QCryptoBlockLUKSHeader *hdr) +{ + hdr->key_slots[0].key_offset_sector = hdr->key_slots[1].key_offset_sector; + + return "Keyslots 0 and 1 are overlapping in the header"; +} + +static const char *luks_bad_key_overlap_payload(QCryptoBlockLUKSHeader *hdr) +{ + hdr->key_slots[0].key_offset_sector = hdr->payload_offset_sector + 42; + + return "Keyslot 0 is overlapping with the encrypted payload"; +} + +static const char *luks_bad_payload_overlap_header(QCryptoBlockLUKSHeader *hdr) +{ + hdr->payload_offset_sector = 2; + + return "LUKS payload is overlapping with the header"; +} + +static const char *luks_bad_key_iterations(QCryptoBlockLUKSHeader *hdr) +{ + hdr->key_slots[0].iterations = 0; + + return "Keyslot 0 iteration count is zero"; +} + +static const char *luks_bad_iterations(QCryptoBlockLUKSHeader *hdr) +{ + hdr->master_key_iterations = 0; + + return "LUKS key iteration count is zero"; +} +#endif + int main(int argc, char **argv) { gsize i; @@ -365,5 +590,79 @@ int main(int argc, char **argv) } } +#ifdef TEST_LUKS + if (g_test_slow()) { + g_test_add_data_func("/crypto/block/luks/bad/cipher-name-nul-term", + luks_bad_null_term_cipher_name, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/cipher-mode-nul-term", + luks_bad_null_term_cipher_mode, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/hash-spec-nul-term", + luks_bad_null_term_hash_spec, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/cipher-name-empty", + luks_bad_cipher_name_empty, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/cipher-name-unknown", + luks_bad_cipher_name_unknown, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/cipher-xts-size", + luks_bad_cipher_xts_size, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/cipher-cbc-size", + luks_bad_cipher_cbc_size, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/cipher-mode-empty", + luks_bad_cipher_mode_empty, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/cipher-mode-unknown", + luks_bad_cipher_mode_unknown, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/ivgen-separator", + luks_bad_ivgen_separator, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/ivgen-name-empty", + luks_bad_ivgen_name_empty, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/ivgen-name-unknown", + luks_bad_ivgen_name_unknown, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/ivgen-hash-empty", + luks_bad_ivgen_hash_empty, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/ivgen-hash-unknown", + luks_bad_ivgen_hash_unknown, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/hash-spec-empty", + luks_bad_hash_spec_empty, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/hash-spec-unknown", + luks_bad_hash_spec_unknown, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/stripes", + luks_bad_stripes, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/key-overlap-header", + luks_bad_key_overlap_header, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/key-overlap-key", + luks_bad_key_overlap_key, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/key-overlap-payload", + luks_bad_key_overlap_payload, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/payload-overlap-header", + luks_bad_payload_overlap_header, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/iterations", + luks_bad_iterations, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/key-iterations", + luks_bad_key_iterations, + test_luks_bad_header); + } +#endif + return g_test_run(); } From b885cdda79045791e1f33600639b7614ea114f16 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 20 Oct 2022 14:05:41 +0200 Subject: [PATCH 237/705] MAINTAINERS: Fold "Block QAPI, monitor, ..." into "Block layer core" Section "Block QAPI, monitor, command line" is about the external interfaces we provide for block devices. It covers the relevant QAPI schema parts, monitor and command line code, more or less. The section's files are also covered by section "Block layer core", except for the QAPI schema files. I haven't acted as maintainer in this area for a long time. Make it official: add the QAPI schema files to section "Block layer core", and delete section "Block QAPI, monitor, command line". Cc: Kevin Wolf Cc: Hanna Reitz Signed-off-by: Markus Armbruster Message-Id: <20221020120541.80757-1-armbru@redhat.com> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- MAINTAINERS | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 32e495e165..07a022b0d0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2509,6 +2509,8 @@ S: Supported F: block* F: block/ F: hw/block/ +F: qapi/block*.json +F: qapi/transaction.json F: include/block/ F: qemu-img* F: docs/tools/qemu-img.rst @@ -2582,16 +2584,6 @@ F: include/qemu/co-shared-resource.h T: git https://gitlab.com/jsnow/qemu.git jobs T: git https://gitlab.com/vsementsov/qemu.git block -Block QAPI, monitor, command line -M: Markus Armbruster -S: Supported -F: blockdev.c -F: blockdev-hmp-cmds.c -F: block/qapi.c -F: qapi/block*.json -F: qapi/transaction.json -T: git https://repo.or.cz/qemu/armbru.git block-next - Compute Express Link M: Ben Widawsky M: Jonathan Cameron From 6b6471eee11dce4c995419b68441c6637be3d90a Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Mon, 10 Oct 2022 12:04:30 +0800 Subject: [PATCH 238/705] block: Ignore close() failure in get_tmp_filename() The temporary file has been created and is ready for use. Checking return value of close() does not seem useful. The file descriptor is almost certainly closed; see close(2) under "Dealing with error returns from close()". Let's simply ignore close() failure here. Suggested-by: Markus Armbruster Signed-off-by: Bin Meng Reviewed-by: Markus Armbruster Message-Id: <20221010040432.3380478-1-bin.meng@windriver.com> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- block.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/block.c b/block.c index 1fbf6b9e69..66a35b3982 100644 --- a/block.c +++ b/block.c @@ -887,10 +887,7 @@ int get_tmp_filename(char *filename, int size) if (fd < 0) { return -errno; } - if (close(fd) != 0) { - unlink(filename); - return -errno; - } + close(fd); return 0; #endif } From 69fbfff95e849156985cf95e2010ffc8762e34e6 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Mon, 10 Oct 2022 12:04:31 +0800 Subject: [PATCH 239/705] block: Refactor get_tmp_filename() At present there are two callers of get_tmp_filename() and they are inconsistent. One does: /* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */ char *tmp_filename = g_malloc0(PATH_MAX + 1); ... ret = get_tmp_filename(tmp_filename, PATH_MAX + 1); while the other does: s->qcow_filename = g_malloc(PATH_MAX); ret = get_tmp_filename(s->qcow_filename, PATH_MAX); As we can see different 'size' arguments are passed. There are also platform specific implementations inside the function, and the use of snprintf is really undesirable. The function name is also misleading. It creates a temporary file, not just a filename. Refactor this routine by changing its name and signature to: char *create_tmp_file(Error **errp) and use g_get_tmp_dir() / g_mkstemp() for a consistent implementation. While we are here, add some comments to mention that /var/tmp is preferred over /tmp on non-win32 hosts. Signed-off-by: Bin Meng Message-Id: <20221010040432.3380478-2-bin.meng@windriver.com> [kwolf: Fixed incorrect errno negation and iotest 051] Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- block.c | 56 +++++++++++++++++--------------- block/vvfat.c | 7 ++-- include/block/block_int-common.h | 2 +- tests/qemu-iotests/051 | 3 +- tests/qemu-iotests/051.out | 2 +- tests/qemu-iotests/051.pc.out | 2 +- 6 files changed, 38 insertions(+), 34 deletions(-) diff --git a/block.c b/block.c index 66a35b3982..c8374dac4f 100644 --- a/block.c +++ b/block.c @@ -861,35 +861,42 @@ int bdrv_probe_geometry(BlockDriverState *bs, HDGeometry *geo) /* * Create a uniquely-named empty temporary file. - * Return 0 upon success, otherwise a negative errno value. + * Return the actual file name used upon success, otherwise NULL. + * This string should be freed with g_free() when not needed any longer. + * + * Note: creating a temporary file for the caller to (re)open is + * inherently racy. Use g_file_open_tmp() instead whenever practical. */ -int get_tmp_filename(char *filename, int size) +char *create_tmp_file(Error **errp) { -#ifdef _WIN32 - char temp_dir[MAX_PATH]; - /* GetTempFileName requires that its output buffer (4th param) - have length MAX_PATH or greater. */ - assert(size >= MAX_PATH); - return (GetTempPath(MAX_PATH, temp_dir) - && GetTempFileName(temp_dir, "qem", 0, filename) - ? 0 : -GetLastError()); -#else int fd; const char *tmpdir; - tmpdir = getenv("TMPDIR"); - if (!tmpdir) { + g_autofree char *filename = NULL; + + tmpdir = g_get_tmp_dir(); +#ifndef _WIN32 + /* + * See commit 69bef79 ("block: use /var/tmp instead of /tmp for -snapshot") + * + * This function is used to create temporary disk images (like -snapshot), + * so the files can become very large. /tmp is often a tmpfs where as + * /var/tmp is usually on a disk, so more appropriate for disk images. + */ + if (!g_strcmp0(tmpdir, "/tmp")) { tmpdir = "/var/tmp"; } - if (snprintf(filename, size, "%s/vl.XXXXXX", tmpdir) >= size) { - return -EOVERFLOW; - } - fd = mkstemp(filename); +#endif + + filename = g_strdup_printf("%s/vl.XXXXXX", tmpdir); + fd = g_mkstemp(filename); if (fd < 0) { - return -errno; + error_setg_errno(errp, errno, "Could not open temporary file '%s'", + filename); + return NULL; } close(fd); - return 0; -#endif + + return g_steal_pointer(&filename); } /* @@ -3715,8 +3722,7 @@ static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs, QDict *snapshot_options, Error **errp) { - /* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */ - char *tmp_filename = g_malloc0(PATH_MAX + 1); + g_autofree char *tmp_filename = NULL; int64_t total_size; QemuOpts *opts = NULL; BlockDriverState *bs_snapshot = NULL; @@ -3735,9 +3741,8 @@ static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs, } /* Create the temporary image */ - ret = get_tmp_filename(tmp_filename, PATH_MAX + 1); - if (ret < 0) { - error_setg_errno(errp, -ret, "Could not get temporary filename"); + tmp_filename = create_tmp_file(errp); + if (!tmp_filename) { goto out; } @@ -3771,7 +3776,6 @@ static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs, out: qobject_unref(snapshot_options); - g_free(tmp_filename); return bs_snapshot; } diff --git a/block/vvfat.c b/block/vvfat.c index d6dd919683..f9bf8406d3 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -3146,10 +3146,9 @@ static int enable_write_target(BlockDriverState *bs, Error **errp) array_init(&(s->commits), sizeof(commit_t)); - s->qcow_filename = g_malloc(PATH_MAX); - ret = get_tmp_filename(s->qcow_filename, PATH_MAX); - if (ret < 0) { - error_setg_errno(errp, -ret, "can't create temporary file"); + s->qcow_filename = create_tmp_file(errp); + if (!s->qcow_filename) { + ret = -ENOENT; goto err; } diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h index 8947abab76..d7c0a7e96f 100644 --- a/include/block/block_int-common.h +++ b/include/block/block_int-common.h @@ -1230,7 +1230,7 @@ static inline BlockDriverState *child_bs(BdrvChild *child) } int bdrv_check_request(int64_t offset, int64_t bytes, Error **errp); -int get_tmp_filename(char *filename, int size); +char *create_tmp_file(Error **errp); void bdrv_parse_filename_strip_prefix(const char *filename, const char *prefix, QDict *options); diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051 index f1a506518b..4c079b11e3 100755 --- a/tests/qemu-iotests/051 +++ b/tests/qemu-iotests/051 @@ -375,7 +375,8 @@ if [ "${VALGRIND_QEMU_VM}" == "y" ]; then _casenotrun "Valgrind needs a valid TMPDIR for itself" fi VALGRIND_QEMU_VM= \ -TMPDIR=/nonexistent run_qemu -drive driver=null-co,snapshot=on +TMPDIR=/nonexistent run_qemu -drive driver=null-co,snapshot=on | + sed -e "s#'[^']*/vl\.[A-Za-z0-9]\{6\}'#SNAPSHOT_PATH#g" # Using snapshot=on together with read-only=on echo "info block" | diff --git a/tests/qemu-iotests/051.out b/tests/qemu-iotests/051.out index 441f83e41a..e5ddb03bda 100644 --- a/tests/qemu-iotests/051.out +++ b/tests/qemu-iotests/051.out @@ -459,7 +459,7 @@ wrote 4096/4096 bytes at offset 0 read 4096/4096 bytes at offset 0 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) Testing: -drive driver=null-co,snapshot=on -QEMU_PROG: -drive driver=null-co,snapshot=on: Could not get temporary filename: No such file or directory +QEMU_PROG: -drive driver=null-co,snapshot=on: Could not open temporary file SNAPSHOT_PATH: No such file or directory Testing: -drive file=TEST_DIR/t.qcow2,snapshot=on,read-only=on,if=none,id=drive0 QEMU X.Y.Z monitor - type 'help' for more information diff --git a/tests/qemu-iotests/051.pc.out b/tests/qemu-iotests/051.pc.out index 063e4fc584..bade1ff3b9 100644 --- a/tests/qemu-iotests/051.pc.out +++ b/tests/qemu-iotests/051.pc.out @@ -539,7 +539,7 @@ wrote 4096/4096 bytes at offset 0 read 4096/4096 bytes at offset 0 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) Testing: -drive driver=null-co,snapshot=on -QEMU_PROG: -drive driver=null-co,snapshot=on: Could not get temporary filename: No such file or directory +QEMU_PROG: -drive driver=null-co,snapshot=on: Could not open temporary file SNAPSHOT_PATH: No such file or directory Testing: -drive file=TEST_DIR/t.qcow2,snapshot=on,read-only=on,if=none,id=drive0 QEMU X.Y.Z monitor - type 'help' for more information From d0f95b6ca0241b14d6cc0f366d162684909370a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Mon, 10 Oct 2022 19:55:10 +0200 Subject: [PATCH 240/705] vvfat: allow some writes to bootsector MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 'reserved1' field in bootsector is used to mark volume dirty, or need to verify. Allow writes to bootsector which only changes the 'reserved1' field. This fixes I/O errors on Windows guests. Resolves: https://bugs.launchpad.net/qemu/+bug/1889421 Signed-off-by: Hervé Poussineau Message-Id: <20221010175511.3414357-2-hpoussin@reactos.org> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- block/vvfat.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/block/vvfat.c b/block/vvfat.c index f9bf8406d3..e76b42dbaf 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -2993,11 +2993,35 @@ DLOG(checkpoint()); vvfat_close_current_file(s); + if (sector_num == s->offset_to_bootsector && nb_sectors == 1) { + /* + * Write on bootsector. Allow only changing the reserved1 field, + * used to mark volume dirtiness + */ + unsigned char *bootsector = s->first_sectors + + s->offset_to_bootsector * 0x200; + /* + * LATER TODO: if FAT32, this is wrong (see init_directories(), + * which always creates a FAT16 bootsector) + */ + const int reserved1_offset = offsetof(bootsector_t, u.fat16.reserved1); + + for (i = 0; i < 0x200; i++) { + if (i != reserved1_offset && bootsector[i] != buf[i]) { + fprintf(stderr, "Tried to write to protected bootsector\n"); + return -1; + } + } + + /* Update bootsector with the only updatable byte, and return success */ + bootsector[reserved1_offset] = buf[reserved1_offset]; + return 0; + } + /* * Some sanity checks: * - do not allow writing to the boot sector */ - if (sector_num < s->offset_to_fat) return -1; From 1e85c7259b7f5b5b7f9a360e2327b1baff723c79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Mon, 10 Oct 2022 19:55:11 +0200 Subject: [PATCH 241/705] vvfat: allow spaces in file names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In R/W mode, files with spaces were never created on host side. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1176 Fixes: c79e243ed67683d6d06692bd7040f7394da178b0 Signed-off-by: Hervé Poussineau Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Kevin Wolf Message-Id: <20221010175511.3414357-3-hpoussin@reactos.org> Signed-off-by: Kevin Wolf --- block/vvfat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/vvfat.c b/block/vvfat.c index e76b42dbaf..c5b1442145 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -499,7 +499,7 @@ static bool valid_filename(const unsigned char *name) (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c > 127 || - strchr("$%'-_@~`!(){}^#&.+,;=[]", c) != NULL)) + strchr(" $%'-_@~`!(){}^#&.+,;=[]", c) != NULL)) { return false; } From 7845e731471365663dea8e34338f93791d31ea44 Mon Sep 17 00:00:00 2001 From: Sam Li Date: Sat, 24 Sep 2022 22:48:15 +0800 Subject: [PATCH 242/705] block/io_uring: revert "Use io_uring_register_ring_fd() to skip fd operations" Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1193 The commit "Use io_uring_register_ring_fd() to skip fd operations" broke when booting a guest with iothread and io_uring. That is because the io_uring_register_ring_fd() call is made from the main thread instead of IOThread where io_uring_submit() is called. It can not be guaranteed to register the ring fd in the correct thread or unregister the same ring fd if the IOThread is disabled. This optimization is not critical so we will revert previous commit. This reverts commit e2848bc574fe2715c694bf8fe9a1ba7f78a1125a and 77e3f038af1764983087e3551a0fde9951952c4d. Cc: qemu-stable@nongnu.org Signed-off-by: Sam Li Message-Id: <20220924144815.5591-1-faithilikerun@gmail.com> Reviewed-by: Stefano Garzarella Tested-by: Dario Faggioli Signed-off-by: Kevin Wolf --- block/io_uring.c | 13 +------------ meson.build | 1 - 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/block/io_uring.c b/block/io_uring.c index a1760152e0..973e15d876 100644 --- a/block/io_uring.c +++ b/block/io_uring.c @@ -11,7 +11,6 @@ #include "qemu/osdep.h" #include #include "block/aio.h" -#include "qemu/error-report.h" #include "qemu/queue.h" #include "block/block.h" #include "block/raw-aio.h" @@ -19,7 +18,6 @@ #include "qapi/error.h" #include "trace.h" - /* io_uring ring size */ #define MAX_ENTRIES 128 @@ -432,17 +430,8 @@ LuringState *luring_init(Error **errp) } ioq_init(&s->io_q); -#ifdef CONFIG_LIBURING_REGISTER_RING_FD - if (io_uring_register_ring_fd(&s->ring) < 0) { - /* - * Only warn about this error: we will fallback to the non-optimized - * io_uring operations. - */ - warn_report("failed to register linux io_uring ring file descriptor"); - } -#endif - return s; + } void luring_cleanup(LuringState *s) diff --git a/meson.build b/meson.build index b686dfef75..44c1f92697 100644 --- a/meson.build +++ b/meson.build @@ -1839,7 +1839,6 @@ config_host_data.set('CONFIG_LIBNFS', libnfs.found()) config_host_data.set('CONFIG_LIBSSH', libssh.found()) config_host_data.set('CONFIG_LINUX_AIO', libaio.found()) config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found()) -config_host_data.set('CONFIG_LIBURING_REGISTER_RING_FD', cc.has_function('io_uring_register_ring_fd', prefix: '#include ', dependencies:linux_io_uring)) config_host_data.set('CONFIG_LIBPMEM', libpmem.found()) config_host_data.set('CONFIG_NUMA', numa.found()) config_host_data.set('CONFIG_OPENGL', opengl.found()) From ab6075d849f4285fc730d3ae6e17418d65d09998 Mon Sep 17 00:00:00 2001 From: Li Feng Date: Mon, 19 Sep 2022 20:18:16 +0800 Subject: [PATCH 243/705] vhost-user-blk: fix the resize crash If the os is not installed and doesn't have the virtio guest driver, the vhost dev isn't started, so the dev->vdev is NULL. Reproduce: mount a Win 2019 iso, go into the install ui, then resize the virtio-blk device, qemu crash. Signed-off-by: Li Feng Message-Id: <20220919121816.3252223-1-fengli@smartx.com> Reviewed-by: Raphael Norwitz Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- hw/block/vhost-user-blk.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c index 84902dde17..13bf5cc47a 100644 --- a/hw/block/vhost-user-blk.c +++ b/hw/block/vhost-user-blk.c @@ -97,6 +97,10 @@ static int vhost_user_blk_handle_config_change(struct vhost_dev *dev) VHostUserBlk *s = VHOST_USER_BLK(dev->vdev); Error *local_err = NULL; + if (!dev->started) { + return 0; + } + ret = vhost_dev_get_config(dev, (uint8_t *)&blkcfg, vdev->config_len, &local_err); if (ret < 0) { From 046fd84facfc4d326070bf5306dd9cedb7bd9854 Mon Sep 17 00:00:00 2001 From: Vladimir Sementsov-Ogievskiy Date: Tue, 26 Jul 2022 23:11:20 +0300 Subject: [PATCH 244/705] block: BlockDriver: add .filtered_child_is_backing field Unfortunately not all filters use .file child as filtered child. Two exclusions are mirror_top and commit_top. Happily they both are private filters. Bad thing is that this inconsistency is observable through qmp commands query-block / query-named-block-nodes. So, could we just change mirror_top and commit_top to use file child as all other filter driver is an open question. Probably, we could do that with some kind of deprecation period, but how to warn users during it? For now, let's just add a field so we can distinguish them in generic code, it will be used in further commits. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Hanna Reitz Message-Id: <20220726201134.924743-2-vsementsov@yandex-team.ru> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- block/commit.c | 1 + block/mirror.c | 1 + include/block/block_int-common.h | 13 +++++++++++++ 3 files changed, 15 insertions(+) diff --git a/block/commit.c b/block/commit.c index 38571510cb..e210e86bac 100644 --- a/block/commit.c +++ b/block/commit.c @@ -238,6 +238,7 @@ static BlockDriver bdrv_commit_top = { .bdrv_child_perm = bdrv_commit_top_child_perm, .is_filter = true, + .filtered_child_is_backing = true, }; void commit_start(const char *job_id, BlockDriverState *bs, diff --git a/block/mirror.c b/block/mirror.c index 80c0109d39..f9432af3df 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -1587,6 +1587,7 @@ static BlockDriver bdrv_mirror_top = { .bdrv_child_perm = bdrv_mirror_top_child_perm, .is_filter = true, + .filtered_child_is_backing = true, }; static BlockJob *mirror_start_job( diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h index d7c0a7e96f..95392052c9 100644 --- a/include/block/block_int-common.h +++ b/include/block/block_int-common.h @@ -119,6 +119,19 @@ struct BlockDriver { * (And this filtered child must then be bs->file or bs->backing.) */ bool is_filter; + /* + * Only make sense for filter drivers, for others must be false. + * If true, filtered child is bs->backing. Otherwise it's bs->file. + * Only two internal filters use bs->backing as filtered child and has this + * field set to true: mirror_top and commit_top. + * + * Never create any more such filters! + * + * TODO: imagine how to deprecate this behavior and make all filters work + * similarly using bs->file as filtered child. + */ + bool filtered_child_is_backing; + /* * Set to true if the BlockDriver is a format driver. Format nodes * generally do not expect their children to be other format nodes From 83930780325b144a5908c45b3957b9b6457b3831 Mon Sep 17 00:00:00 2001 From: Vladimir Sementsov-Ogievskiy Date: Tue, 26 Jul 2022 23:11:21 +0300 Subject: [PATCH 245/705] block: introduce bdrv_open_file_child() helper Almost all drivers call bdrv_open_child() similarly. Let's create a helper for this. The only not updated drivers that call bdrv_open_child() to set bs->file are raw-format and snapshot-access: raw-format sometimes want to have filtered child but don't set drv->is_filter to true. snapshot-access wants only DATA | PRIMARY Possibly we should implement drv->is_filter_func() handler, to consider raw-format as filter when it works as filter.. But it's another story. Note also, that we decrease assignments to bs->file in code: it helps us restrict modifying this field in further commit. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Hanna Reitz Message-Id: <20220726201134.924743-3-vsementsov@yandex-team.ru> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- block.c | 21 +++++++++++++++++++++ block/blkdebug.c | 9 +++------ block/blklogwrites.c | 7 ++----- block/blkreplay.c | 7 ++----- block/blkverify.c | 9 +++------ block/bochs.c | 7 +++---- block/cloop.c | 7 +++---- block/copy-before-write.c | 9 ++++----- block/copy-on-read.c | 9 ++++----- block/crypto.c | 11 ++++++----- block/dmg.c | 7 +++---- block/filter-compress.c | 8 +++----- block/parallels.c | 7 +++---- block/preallocate.c | 9 ++++----- block/qcow.c | 6 ++---- block/qcow2.c | 8 ++++---- block/qed.c | 8 ++++---- block/replication.c | 8 +++----- block/throttle.c | 8 +++----- block/vdi.c | 7 +++---- block/vhdx.c | 7 +++---- block/vmdk.c | 7 +++---- block/vpc.c | 7 +++---- include/block/block-global-state.h | 3 +++ 24 files changed, 95 insertions(+), 101 deletions(-) diff --git a/block.c b/block.c index c8374dac4f..25a596a612 100644 --- a/block.c +++ b/block.c @@ -3673,6 +3673,27 @@ BdrvChild *bdrv_open_child(const char *filename, errp); } +/* + * Wrapper on bdrv_open_child() for most popular case: open primary child of bs. + */ +int bdrv_open_file_child(const char *filename, + QDict *options, const char *bdref_key, + BlockDriverState *parent, Error **errp) +{ + BdrvChildRole role; + + /* commit_top and mirror_top don't use this function */ + assert(!parent->drv->filtered_child_is_backing); + + role = parent->drv->is_filter ? + (BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY) : BDRV_CHILD_IMAGE; + + parent->file = bdrv_open_child(filename, options, bdref_key, parent, + &child_of_bds, role, false, errp); + + return parent->file ? 0 : -EINVAL; +} + /* * TODO Future callers may need to specify parent/child_class in order for * option inheritance to work. Existing callers use it for the root node. diff --git a/block/blkdebug.c b/block/blkdebug.c index bbf2948703..5fcfc8ac6f 100644 --- a/block/blkdebug.c +++ b/block/blkdebug.c @@ -503,12 +503,9 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags, } /* Open the image file */ - bs->file = bdrv_open_child(qemu_opt_get(opts, "x-image"), options, "image", - bs, &child_of_bds, - BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, - false, errp); - if (!bs->file) { - ret = -EINVAL; + ret = bdrv_open_file_child(qemu_opt_get(opts, "x-image"), options, "image", + bs, errp); + if (ret < 0) { goto out; } diff --git a/block/blklogwrites.c b/block/blklogwrites.c index e3c6c4039c..12b4c3c8cf 100644 --- a/block/blklogwrites.c +++ b/block/blklogwrites.c @@ -155,11 +155,8 @@ static int blk_log_writes_open(BlockDriverState *bs, QDict *options, int flags, } /* Open the file */ - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, false, - errp); - if (!bs->file) { - ret = -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { goto fail; } diff --git a/block/blkreplay.c b/block/blkreplay.c index dcbe780ddb..76a0b8d12a 100644 --- a/block/blkreplay.c +++ b/block/blkreplay.c @@ -26,11 +26,8 @@ static int blkreplay_open(BlockDriverState *bs, QDict *options, int flags, int ret; /* Open the image file */ - bs->file = bdrv_open_child(NULL, options, "image", bs, &child_of_bds, - BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, - false, errp); - if (!bs->file) { - ret = -EINVAL; + ret = bdrv_open_file_child(NULL, options, "image", bs, errp); + if (ret < 0) { goto fail; } diff --git a/block/blkverify.c b/block/blkverify.c index 020b1ae7b6..43a2d94f7b 100644 --- a/block/blkverify.c +++ b/block/blkverify.c @@ -122,12 +122,9 @@ static int blkverify_open(BlockDriverState *bs, QDict *options, int flags, } /* Open the raw file */ - bs->file = bdrv_open_child(qemu_opt_get(opts, "x-raw"), options, "raw", - bs, &child_of_bds, - BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, - false, errp); - if (!bs->file) { - ret = -EINVAL; + ret = bdrv_open_file_child(qemu_opt_get(opts, "x-raw"), options, "raw", + bs, errp); + if (ret < 0) { goto fail; } diff --git a/block/bochs.c b/block/bochs.c index b76f34fe03..e30e3908d9 100644 --- a/block/bochs.c +++ b/block/bochs.c @@ -110,10 +110,9 @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags, return ret; } - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_IMAGE, false, errp); - if (!bs->file) { - return -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } ret = bdrv_pread(bs->file, 0, sizeof(bochs), &bochs, 0); diff --git a/block/cloop.c b/block/cloop.c index 40b146e714..3ff975a94d 100644 --- a/block/cloop.c +++ b/block/cloop.c @@ -71,10 +71,9 @@ static int cloop_open(BlockDriverState *bs, QDict *options, int flags, return ret; } - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_IMAGE, false, errp); - if (!bs->file) { - return -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } /* read header */ diff --git a/block/copy-before-write.c b/block/copy-before-write.c index afbdd04489..4abaa7339e 100644 --- a/block/copy-before-write.c +++ b/block/copy-before-write.c @@ -412,6 +412,7 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags, int64_t cluster_size; g_autoptr(BlockdevOptions) full_opts = NULL; BlockdevOptionsCbw *opts; + int ret; full_opts = cbw_parse_options(options, errp); if (!full_opts) { @@ -420,11 +421,9 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags, assert(full_opts->driver == BLOCKDEV_DRIVER_COPY_BEFORE_WRITE); opts = &full_opts->u.copy_before_write; - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, - false, errp); - if (!bs->file) { - return -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } s->target = bdrv_open_child(NULL, options, "target", bs, &child_of_bds, diff --git a/block/copy-on-read.c b/block/copy-on-read.c index 1fc7fb3333..815ac1d835 100644 --- a/block/copy-on-read.c +++ b/block/copy-on-read.c @@ -41,12 +41,11 @@ static int cor_open(BlockDriverState *bs, QDict *options, int flags, BDRVStateCOR *state = bs->opaque; /* Find a bottom node name, if any */ const char *bottom_node = qdict_get_try_str(options, "bottom"); + int ret; - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, - false, errp); - if (!bs->file) { - return -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } bs->supported_read_flags = BDRV_REQ_PREFETCH; diff --git a/block/crypto.c b/block/crypto.c index 7a57774b76..396e529bb2 100644 --- a/block/crypto.c +++ b/block/crypto.c @@ -261,15 +261,14 @@ static int block_crypto_open_generic(QCryptoBlockFormat format, { BlockCrypto *crypto = bs->opaque; QemuOpts *opts = NULL; - int ret = -EINVAL; + int ret; QCryptoBlockOpenOptions *open_opts = NULL; unsigned int cflags = 0; QDict *cryptoopts = NULL; - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_IMAGE, false, errp); - if (!bs->file) { - return -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } bs->supported_write_flags = BDRV_REQ_FUA & @@ -277,6 +276,7 @@ static int block_crypto_open_generic(QCryptoBlockFormat format, opts = qemu_opts_create(opts_spec, NULL, 0, &error_abort); if (!qemu_opts_absorb_qdict(opts, options, errp)) { + ret = -EINVAL; goto cleanup; } @@ -285,6 +285,7 @@ static int block_crypto_open_generic(QCryptoBlockFormat format, open_opts = block_crypto_open_opts_init(cryptoopts, errp); if (!open_opts) { + ret = -EINVAL; goto cleanup; } diff --git a/block/dmg.c b/block/dmg.c index 98db18d82a..422136276a 100644 --- a/block/dmg.c +++ b/block/dmg.c @@ -440,10 +440,9 @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags, return ret; } - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_IMAGE, false, errp); - if (!bs->file) { - return -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } block_module_load_one("dmg-bz2"); diff --git a/block/filter-compress.c b/block/filter-compress.c index d5be538619..305716c86c 100644 --- a/block/filter-compress.c +++ b/block/filter-compress.c @@ -30,11 +30,9 @@ static int compress_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) { - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, - false, errp); - if (!bs->file) { - return -EINVAL; + int ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } if (!bs->file->bs->drv || !block_driver_can_compress(bs->file->bs->drv)) { diff --git a/block/parallels.c b/block/parallels.c index c1523e7dab..27c81cee40 100644 --- a/block/parallels.c +++ b/block/parallels.c @@ -737,10 +737,9 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags, Error *local_err = NULL; char *buf; - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_IMAGE, false, errp); - if (!bs->file) { - return -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } ret = bdrv_pread(bs->file, 0, sizeof(ph), &ph, 0); diff --git a/block/preallocate.c b/block/preallocate.c index e15cb8c74a..d50ee7f49b 100644 --- a/block/preallocate.c +++ b/block/preallocate.c @@ -134,6 +134,7 @@ static int preallocate_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) { BDRVPreallocateState *s = bs->opaque; + int ret; /* * s->data_end and friends should be initialized on permission update. @@ -141,11 +142,9 @@ static int preallocate_open(BlockDriverState *bs, QDict *options, int flags, */ s->file_end = s->zero_start = s->data_end = -EINVAL; - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, - false, errp); - if (!bs->file) { - return -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } if (!preallocate_absorb_opts(&s->opts, options, bs->file->bs, errp)) { diff --git a/block/qcow.c b/block/qcow.c index 311aaa8705..72ed4c3321 100644 --- a/block/qcow.c +++ b/block/qcow.c @@ -121,10 +121,8 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags, qdict_extract_subqdict(options, &encryptopts, "encrypt."); encryptfmt = qdict_get_try_str(encryptopts, "format"); - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_IMAGE, false, errp); - if (!bs->file) { - ret = -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { goto fail; } diff --git a/block/qcow2.c b/block/qcow2.c index b57f7cc8ee..b47016cf61 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1905,11 +1905,11 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags, .errp = errp, .ret = -EINPROGRESS }; + int ret; - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_IMAGE, false, errp); - if (!bs->file) { - return -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } /* Initialise locks */ diff --git a/block/qed.c b/block/qed.c index bda00e6257..4627169348 100644 --- a/block/qed.c +++ b/block/qed.c @@ -561,11 +561,11 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags, .errp = errp, .ret = -EINPROGRESS }; + int ret; - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_IMAGE, false, errp); - if (!bs->file) { - return -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } bdrv_qed_init_state(bs); diff --git a/block/replication.c b/block/replication.c index c67f931f37..ee33dc4598 100644 --- a/block/replication.c +++ b/block/replication.c @@ -88,11 +88,9 @@ static int replication_open(BlockDriverState *bs, QDict *options, const char *mode; const char *top_id; - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, - false, errp); - if (!bs->file) { - return -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } ret = -EINVAL; diff --git a/block/throttle.c b/block/throttle.c index ddd450593a..131eba3ab4 100644 --- a/block/throttle.c +++ b/block/throttle.c @@ -78,11 +78,9 @@ static int throttle_open(BlockDriverState *bs, QDict *options, char *group; int ret; - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, - false, errp); - if (!bs->file) { - return -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } bs->supported_write_flags = bs->file->bs->supported_write_flags | BDRV_REQ_WRITE_UNCHANGED; diff --git a/block/vdi.c b/block/vdi.c index e942325455..a9bafb5a9e 100644 --- a/block/vdi.c +++ b/block/vdi.c @@ -377,10 +377,9 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags, int ret; QemuUUID uuid_link, uuid_parent; - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_IMAGE, false, errp); - if (!bs->file) { - return -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } logout("\n"); diff --git a/block/vhdx.c b/block/vhdx.c index e10e78ebfd..ce1e75f5ec 100644 --- a/block/vhdx.c +++ b/block/vhdx.c @@ -1001,10 +1001,9 @@ static int vhdx_open(BlockDriverState *bs, QDict *options, int flags, uint64_t signature; Error *local_err = NULL; - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_IMAGE, false, errp); - if (!bs->file) { - return -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } s->bat = NULL; diff --git a/block/vmdk.c b/block/vmdk.c index f7d8856dfb..d75a87cb85 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -1308,10 +1308,9 @@ static int vmdk_open(BlockDriverState *bs, QDict *options, int flags, BDRVVmdkState *s = bs->opaque; uint32_t magic; - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_IMAGE, false, errp); - if (!bs->file) { - return -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } buf = vmdk_read_desc(bs->file, 0, errp); diff --git a/block/vpc.c b/block/vpc.c index 4f49ef207f..95841f259a 100644 --- a/block/vpc.c +++ b/block/vpc.c @@ -233,10 +233,9 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags, int ret; int64_t bs_size; - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_IMAGE, false, errp); - if (!bs->file) { - return -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } opts = qemu_opts_create(&vpc_runtime_opts, NULL, 0, &error_abort); diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h index 21265e3966..29a38d7e18 100644 --- a/include/block/block-global-state.h +++ b/include/block/block-global-state.h @@ -76,6 +76,9 @@ BdrvChild *bdrv_open_child(const char *filename, const BdrvChildClass *child_class, BdrvChildRole child_role, bool allow_none, Error **errp); +int bdrv_open_file_child(const char *filename, + QDict *options, const char *bdref_key, + BlockDriverState *parent, Error **errp); BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp); int bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd, Error **errp); From a987aa7d3c70a2f7d2e052c1e8e449fcd35c3f78 Mon Sep 17 00:00:00 2001 From: Vladimir Sementsov-Ogievskiy Date: Tue, 26 Jul 2022 23:11:22 +0300 Subject: [PATCH 246/705] block/blklogwrites: don't care to remove bs->file child on failure We don't need to remove bs->file, generic layer takes care of it. No other driver cares to remove bs->file on failure by hand. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Hanna Reitz Message-Id: <20220726201134.924743-4-vsementsov@yandex-team.ru> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- block/blklogwrites.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/block/blklogwrites.c b/block/blklogwrites.c index 12b4c3c8cf..cef9efe55d 100644 --- a/block/blklogwrites.c +++ b/block/blklogwrites.c @@ -254,10 +254,6 @@ fail_log: s->log_file = NULL; } fail: - if (ret < 0) { - bdrv_unref_child(bs, bs->file); - bs->file = NULL; - } qemu_opts_del(opts); return ret; } From 1dcea719794b38752fdd4f8f47c743ecb03be1cc Mon Sep 17 00:00:00 2001 From: Vladimir Sementsov-Ogievskiy Date: Tue, 26 Jul 2022 23:11:23 +0300 Subject: [PATCH 247/705] test-bdrv-graph-mod: update test_parallel_perm_update test case test_parallel_perm_update() does two things that we are going to restrict in the near future: 1. It updates bs->file field by hand. bs->file will be managed automatically by generic code (together with bs->children list). Let's better refactor our "tricky" bds to have own state where one of children is linked as "selected". This also looks less "tricky", so avoid using this word. 2. It create FILTERED children that are not PRIMARY. Except for tests all FILTERED children in the Qemu block layer are always PRIMARY as well. We are going to formalize this rule, so let's better use DATA children here. 3. It creates more than one FILTERED child, which is already abandoned in BDRV_CHILD_FILTERED's description. While being here, update the picture to better correspond to the test code. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Hanna Reitz Message-Id: <20220726201134.924743-5-vsementsov@yandex-team.ru> Signed-off-by: Kevin Wolf --- tests/unit/test-bdrv-graph-mod.c | 80 +++++++++++++++++++------------- 1 file changed, 49 insertions(+), 31 deletions(-) diff --git a/tests/unit/test-bdrv-graph-mod.c b/tests/unit/test-bdrv-graph-mod.c index a6e3bb79be..e2f1355af1 100644 --- a/tests/unit/test-bdrv-graph-mod.c +++ b/tests/unit/test-bdrv-graph-mod.c @@ -241,13 +241,26 @@ static void test_parallel_exclusive_write(void) bdrv_unref(top); } -static void write_to_file_perms(BlockDriverState *bs, BdrvChild *c, - BdrvChildRole role, - BlockReopenQueue *reopen_queue, - uint64_t perm, uint64_t shared, - uint64_t *nperm, uint64_t *nshared) +/* + * write-to-selected node may have several DATA children, one of them may be + * "selected". Exclusive write permission is taken on selected child. + * + * We don't realize write handler itself, as we need only to test how permission + * update works. + */ +typedef struct BDRVWriteToSelectedState { + BdrvChild *selected; +} BDRVWriteToSelectedState; + +static void write_to_selected_perms(BlockDriverState *bs, BdrvChild *c, + BdrvChildRole role, + BlockReopenQueue *reopen_queue, + uint64_t perm, uint64_t shared, + uint64_t *nperm, uint64_t *nshared) { - if (bs->file && c == bs->file) { + BDRVWriteToSelectedState *s = bs->opaque; + + if (s->selected && c == s->selected) { *nperm = BLK_PERM_WRITE; *nshared = BLK_PERM_ALL & ~BLK_PERM_WRITE; } else { @@ -256,9 +269,10 @@ static void write_to_file_perms(BlockDriverState *bs, BdrvChild *c, } } -static BlockDriver bdrv_write_to_file = { - .format_name = "tricky-perm", - .bdrv_child_perm = write_to_file_perms, +static BlockDriver bdrv_write_to_selected = { + .format_name = "write-to-selected", + .instance_size = sizeof(BDRVWriteToSelectedState), + .bdrv_child_perm = write_to_selected_perms, }; @@ -266,15 +280,18 @@ static BlockDriver bdrv_write_to_file = { * The following test shows that topological-sort order is required for * permission update, simple DFS is not enough. * - * Consider the block driver which has two filter children: one active - * with exclusive write access and one inactive with no specific - * permissions. + * Consider the block driver (write-to-selected) which has two children: one is + * selected so we have exclusive write access to it and for the other one we + * don't need any specific permissions. * * And, these two children has a common base child, like this: + * (additional "top" on top is used in test just because the only public + * function to update permission should get a specific child to update. + * Making bdrv_refresh_perms() public just for this test isn't worth it) * - * ┌─────┐ ┌──────┐ - * │ fl2 │ ◀── │ top │ - * └─────┘ └──────┘ + * ┌─────┐ ┌───────────────────┐ ┌─────┐ + * │ fl2 │ ◀── │ write-to-selected │ ◀── │ top │ + * └─────┘ └───────────────────┘ └─────┘ * │ │ * │ │ w * │ ▼ @@ -290,14 +307,14 @@ static BlockDriver bdrv_write_to_file = { * * So, exclusive write is propagated. * - * Assume, we want to make fl2 active instead of fl1. - * So, we set some option for top driver and do permission update. + * Assume, we want to select fl2 instead of fl1. + * So, we set some option for write-to-selected driver and do permission update. * * With simple DFS, if permission update goes first through - * top->fl1->base branch it will succeed: it firstly drop exclusive write - * permissions and than apply them for another BdrvChildren. - * But if permission update goes first through top->fl2->base branch it - * will fail, as when we try to update fl2->base child, old not yet + * write-to-selected -> fl1 -> base branch it will succeed: it firstly drop + * exclusive write permissions and than apply them for another BdrvChildren. + * But if permission update goes first through write-to-selected -> fl2 -> base + * branch it will fail, as when we try to update fl2->base child, old not yet * updated fl1->base child will be in conflict. * * With topological-sort order we always update parents before children, so fl1 @@ -306,9 +323,10 @@ static BlockDriver bdrv_write_to_file = { static void test_parallel_perm_update(void) { BlockDriverState *top = no_perm_node("top"); - BlockDriverState *tricky = - bdrv_new_open_driver(&bdrv_write_to_file, "tricky", BDRV_O_RDWR, + BlockDriverState *ws = + bdrv_new_open_driver(&bdrv_write_to_selected, "ws", BDRV_O_RDWR, &error_abort); + BDRVWriteToSelectedState *s = ws->opaque; BlockDriverState *base = no_perm_node("base"); BlockDriverState *fl1 = pass_through_node("fl1"); BlockDriverState *fl2 = pass_through_node("fl2"); @@ -320,33 +338,33 @@ static void test_parallel_perm_update(void) */ bdrv_ref(base); - bdrv_attach_child(top, tricky, "file", &child_of_bds, BDRV_CHILD_DATA, + bdrv_attach_child(top, ws, "file", &child_of_bds, BDRV_CHILD_DATA, &error_abort); - c_fl1 = bdrv_attach_child(tricky, fl1, "first", &child_of_bds, - BDRV_CHILD_FILTERED, &error_abort); - c_fl2 = bdrv_attach_child(tricky, fl2, "second", &child_of_bds, - BDRV_CHILD_FILTERED, &error_abort); + c_fl1 = bdrv_attach_child(ws, fl1, "first", &child_of_bds, + BDRV_CHILD_DATA, &error_abort); + c_fl2 = bdrv_attach_child(ws, fl2, "second", &child_of_bds, + BDRV_CHILD_DATA, &error_abort); bdrv_attach_child(fl1, base, "backing", &child_of_bds, BDRV_CHILD_FILTERED, &error_abort); bdrv_attach_child(fl2, base, "backing", &child_of_bds, BDRV_CHILD_FILTERED, &error_abort); /* Select fl1 as first child to be active */ - tricky->file = c_fl1; + s->selected = c_fl1; bdrv_child_refresh_perms(top, top->children.lh_first, &error_abort); assert(c_fl1->perm & BLK_PERM_WRITE); assert(!(c_fl2->perm & BLK_PERM_WRITE)); /* Now, try to switch active child and update permissions */ - tricky->file = c_fl2; + s->selected = c_fl2; bdrv_child_refresh_perms(top, top->children.lh_first, &error_abort); assert(c_fl2->perm & BLK_PERM_WRITE); assert(!(c_fl1->perm & BLK_PERM_WRITE)); /* Switch once more, to not care about real child order in the list */ - tricky->file = c_fl1; + s->selected = c_fl1; bdrv_child_refresh_perms(top, top->children.lh_first, &error_abort); assert(c_fl1->perm & BLK_PERM_WRITE); From 9ebfc111a1e34fcec5285095954c360acc2be01a Mon Sep 17 00:00:00 2001 From: Vladimir Sementsov-Ogievskiy Date: Tue, 26 Jul 2022 23:11:24 +0300 Subject: [PATCH 248/705] tests-bdrv-drain: bdrv_replace_test driver: declare supports_backing We do add COW child to the node. In future we are going to forbid adding COW child to the node that doesn't support backing. So, fix it here now. Don't worry about setting bs->backing itself: in further commit we'll update the block-layer to automatically set/unset this field in generic code. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Hanna Reitz Message-Id: <20220726201134.924743-6-vsementsov@yandex-team.ru> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- tests/unit/test-bdrv-drain.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/unit/test-bdrv-drain.c b/tests/unit/test-bdrv-drain.c index 4924ceb562..84e09d7070 100644 --- a/tests/unit/test-bdrv-drain.c +++ b/tests/unit/test-bdrv-drain.c @@ -1970,6 +1970,7 @@ static void coroutine_fn bdrv_replace_test_co_drain_end(BlockDriverState *bs) static BlockDriver bdrv_replace_test = { .format_name = "replace_test", .instance_size = sizeof(BDRVReplaceTestState), + .supports_backing = true, .bdrv_close = bdrv_replace_test_close, .bdrv_co_preadv = bdrv_replace_test_co_preadv, From 1921b4f7868cb398a8939b48e2cdac4d6ff79e41 Mon Sep 17 00:00:00 2001 From: Vladimir Sementsov-Ogievskiy Date: Tue, 26 Jul 2022 23:11:25 +0300 Subject: [PATCH 249/705] test-bdrv-graph-mod: fix filters to be filters bdrv_pass_through is used as filter, even all node variables has corresponding names. We want to append it, so it should be backing-child-based filter like mirror_top. So, in test_update_perm_tree, first child should be DATA, as we don't want filters with two filtered children. bdrv_exclusive_writer is used as a filter once. So it should be filter anyway. We want to append it, so it should be backing-child-based fitler too. Make all FILTERED children to be PRIMARY as well. We are going to force this rule by assertion soon. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Hanna Reitz Message-Id: <20220726201134.924743-7-vsementsov@yandex-team.ru> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- include/block/block_int-common.h | 5 +++-- tests/unit/test-bdrv-graph-mod.c | 24 +++++++++++++++++------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h index 95392052c9..10feef9f0c 100644 --- a/include/block/block_int-common.h +++ b/include/block/block_int-common.h @@ -122,8 +122,9 @@ struct BlockDriver { /* * Only make sense for filter drivers, for others must be false. * If true, filtered child is bs->backing. Otherwise it's bs->file. - * Only two internal filters use bs->backing as filtered child and has this - * field set to true: mirror_top and commit_top. + * Two internal filters use bs->backing as filtered child and has this + * field set to true: mirror_top and commit_top. There also two such test + * filters in tests/unit/test-bdrv-graph-mod.c. * * Never create any more such filters! * diff --git a/tests/unit/test-bdrv-graph-mod.c b/tests/unit/test-bdrv-graph-mod.c index e2f1355af1..c522591531 100644 --- a/tests/unit/test-bdrv-graph-mod.c +++ b/tests/unit/test-bdrv-graph-mod.c @@ -26,6 +26,8 @@ static BlockDriver bdrv_pass_through = { .format_name = "pass-through", + .is_filter = true, + .filtered_child_is_backing = true, .bdrv_child_perm = bdrv_default_perms, }; @@ -57,6 +59,8 @@ static void exclusive_write_perms(BlockDriverState *bs, BdrvChild *c, static BlockDriver bdrv_exclusive_writer = { .format_name = "exclusive-writer", + .is_filter = true, + .filtered_child_is_backing = true, .bdrv_child_perm = exclusive_write_perms, }; @@ -134,7 +138,7 @@ static void test_update_perm_tree(void) blk_insert_bs(root, bs, &error_abort); bdrv_attach_child(filter, bs, "child", &child_of_bds, - BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, &error_abort); + BDRV_CHILD_DATA, &error_abort); ret = bdrv_append(filter, bs, NULL); g_assert_cmpint(ret, <, 0); @@ -228,11 +232,14 @@ static void test_parallel_exclusive_write(void) */ bdrv_ref(base); - bdrv_attach_child(top, fl1, "backing", &child_of_bds, BDRV_CHILD_DATA, + bdrv_attach_child(top, fl1, "backing", &child_of_bds, + BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, &error_abort); - bdrv_attach_child(fl1, base, "backing", &child_of_bds, BDRV_CHILD_FILTERED, + bdrv_attach_child(fl1, base, "backing", &child_of_bds, + BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, &error_abort); - bdrv_attach_child(fl2, base, "backing", &child_of_bds, BDRV_CHILD_FILTERED, + bdrv_attach_child(fl2, base, "backing", &child_of_bds, + BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, &error_abort); bdrv_replace_node(fl1, fl2, &error_abort); @@ -344,9 +351,11 @@ static void test_parallel_perm_update(void) BDRV_CHILD_DATA, &error_abort); c_fl2 = bdrv_attach_child(ws, fl2, "second", &child_of_bds, BDRV_CHILD_DATA, &error_abort); - bdrv_attach_child(fl1, base, "backing", &child_of_bds, BDRV_CHILD_FILTERED, + bdrv_attach_child(fl1, base, "backing", &child_of_bds, + BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, &error_abort); - bdrv_attach_child(fl2, base, "backing", &child_of_bds, BDRV_CHILD_FILTERED, + bdrv_attach_child(fl2, base, "backing", &child_of_bds, + BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, &error_abort); /* Select fl1 as first child to be active */ @@ -397,7 +406,8 @@ static void test_append_greedy_filter(void) BlockDriverState *base = no_perm_node("base"); BlockDriverState *fl = exclusive_writer_node("fl1"); - bdrv_attach_child(top, base, "backing", &child_of_bds, BDRV_CHILD_COW, + bdrv_attach_child(top, base, "backing", &child_of_bds, + BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, &error_abort); bdrv_append(fl, base, &error_abort); From 71ca43852aeb59d69d39ca12f93063aa171a9dbf Mon Sep 17 00:00:00 2001 From: Vladimir Sementsov-Ogievskiy Date: Tue, 26 Jul 2022 23:11:26 +0300 Subject: [PATCH 250/705] block: document connection between child roles and bs->backing/bs->file Make the informal rules formal. In further commit we'll add corresponding assertions. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Hanna Reitz Message-Id: <20220726201134.924743-8-vsementsov@yandex-team.ru> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- include/block/block-common.h | 39 ++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/include/block/block-common.h b/include/block/block-common.h index fdb7306e78..fda67a7c38 100644 --- a/include/block/block-common.h +++ b/include/block/block-common.h @@ -313,6 +313,45 @@ enum { * * At least one of DATA, METADATA, FILTERED, or COW must be set for * every child. + * + * + * = Connection with bs->children, bs->file and bs->backing fields = + * + * 1. Filters + * + * Filter drivers have drv->is_filter = true. + * + * Filter node has exactly one FILTERED|PRIMARY child, and may have other + * children which must not have these bits (one example is the + * copy-before-write filter, which also has its target DATA child). + * + * Filter nodes never have COW children. + * + * For most filters, the filtered child is linked in bs->file, bs->backing is + * NULL. For some filters (as an exception), it is the other way around; those + * drivers will have drv->filtered_child_is_backing set to true (see that + * field’s documentation for what drivers this concerns) + * + * 2. "raw" driver (block/raw-format.c) + * + * Formally it's not a filter (drv->is_filter = false) + * + * bs->backing is always NULL + * + * Only has one child, linked in bs->file. Its role is either FILTERED|PRIMARY + * (like filter) or DATA|PRIMARY depending on options. + * + * 3. Other drivers + * + * Don't have any FILTERED children. + * + * May have at most one COW child. In this case it's linked in bs->backing. + * Otherwise bs->backing is NULL. COW child is never PRIMARY. + * + * May have at most one PRIMARY child. In this case it's linked in bs->file. + * Otherwise bs->file is NULL. + * + * May also have some other children that don't have the PRIMARY or COW bit set. */ enum BdrvChildRoleBits { /* From 0c6100a7ff4733773e32b4b9bd00eb81955bd788 Mon Sep 17 00:00:00 2001 From: Vladimir Sementsov-Ogievskiy Date: Tue, 26 Jul 2022 23:11:27 +0300 Subject: [PATCH 251/705] block/snapshot: stress that we fallback to primary child Actually what we chose is a primary child. Let's stress it in the code. We are going to drop indirect pointer logic here in future. Actually this commit simplifies the future work: we drop use of indirection in the assertion now. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Hanna Reitz Message-Id: <20220726201134.924743-9-vsementsov@yandex-team.ru> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- block/snapshot.c | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/block/snapshot.c b/block/snapshot.c index d6f53c3065..75e8d3a937 100644 --- a/block/snapshot.c +++ b/block/snapshot.c @@ -161,21 +161,14 @@ bool bdrv_snapshot_find_by_id_and_name(BlockDriverState *bs, static BdrvChild **bdrv_snapshot_fallback_ptr(BlockDriverState *bs) { BdrvChild **fallback; - BdrvChild *child; + BdrvChild *child = bdrv_primary_child(bs); - /* - * The only BdrvChild pointers that are safe to modify (and which - * we can thus return a reference to) are bs->file and - * bs->backing. - */ - fallback = &bs->file; - if (!*fallback && bs->drv && bs->drv->is_filter) { - fallback = &bs->backing; - } - - if (!*fallback) { + /* We allow fallback only to primary child */ + if (!child) { return NULL; } + fallback = (child == bs->file ? &bs->file : &bs->backing); + assert(*fallback == child); /* * Check that there are no other children that would need to be @@ -309,15 +302,12 @@ int bdrv_snapshot_goto(BlockDriverState *bs, } /* - * fallback_ptr is &bs->file or &bs->backing. *fallback_ptr - * was closed above and set to NULL, but the .bdrv_open() call - * has opened it again, because we set the respective option - * (with the qdict_put_str() call above). - * Assert that .bdrv_open() has attached some child on - * *fallback_ptr, and that it has attached the one we wanted - * it to (i.e., fallback_bs). + * fallback was a primary child. It was closed above and set to NULL, + * but the .bdrv_open() call has opened it again, because we set the + * respective option (with the qdict_put_str() call above). + * Assert that .bdrv_open() has attached the right BDS as primary child. */ - assert(*fallback_ptr && fallback_bs == (*fallback_ptr)->bs); + assert(bdrv_primary_bs(bs) == fallback_bs); bdrv_unref(fallback_bs); return ret; } From 4eba825a8237985dc1c53a42bc810dcfa1a3d5e3 Mon Sep 17 00:00:00 2001 From: Vladimir Sementsov-Ogievskiy Date: Tue, 26 Jul 2022 23:11:28 +0300 Subject: [PATCH 252/705] Revert "block: Let replace_child_noperm free children" We are going to reimplement this behavior (clear bs->file / bs->backing pointers automatically when child->bs is cleared) in a nicer way, see further commit "block: Manipulate bs->file / bs->backing pointers in .attach/.detach". With this revert we bring back a problem that was fixed by b0a9f6fed3d8. Still the problem was mostly theoretical, we don't have concrete bugs fixed by b0a9f6fed3d8, we don't have a specific test. Probably some accidental failures of iotests are related. Alternatively, we may merge this and following three reverts into final "block: Manipulate ..." to avoid any kind of regression. But seems that in this case having separate clear revert commits is better. This reverts commit b0a9f6fed3d80de610dcd04a7e66f9f30a04174f. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Hanna Reitz Message-Id: <20220726201134.924743-10-vsementsov@yandex-team.ru> Signed-off-by: Kevin Wolf --- block.c | 102 +++++++++++++------------------------------------------- 1 file changed, 23 insertions(+), 79 deletions(-) diff --git a/block.c b/block.c index 25a596a612..7a9a6efca8 100644 --- a/block.c +++ b/block.c @@ -90,10 +90,8 @@ static BlockDriverState *bdrv_open_inherit(const char *filename, static bool bdrv_recurse_has_child(BlockDriverState *bs, BlockDriverState *child); -static void bdrv_child_free(BdrvChild *child); static void bdrv_replace_child_noperm(BdrvChild **child, - BlockDriverState *new_bs, - bool free_empty_child); + BlockDriverState *new_bs); static void bdrv_remove_file_or_backing_child(BlockDriverState *bs, BdrvChild *child, Transaction *tran); @@ -2345,7 +2343,6 @@ typedef struct BdrvReplaceChildState { BdrvChild *child; BdrvChild **childp; BlockDriverState *old_bs; - bool free_empty_child; } BdrvReplaceChildState; static void bdrv_replace_child_commit(void *opaque) @@ -2353,9 +2350,6 @@ static void bdrv_replace_child_commit(void *opaque) BdrvReplaceChildState *s = opaque; GLOBAL_STATE_CODE(); - if (s->free_empty_child && !s->child->bs) { - bdrv_child_free(s->child); - } bdrv_unref(s->old_bs); } @@ -2373,26 +2367,22 @@ static void bdrv_replace_child_abort(void *opaque) * modify the BdrvChild * pointer we indirectly pass to it, i.e. it * will not modify s->child. From that perspective, it does not matter * whether we pass s->childp or &s->child. + * (TODO: Right now, bdrv_replace_child_noperm() never modifies that + * pointer anyway (though it will in the future), so at this point it + * absolutely does not matter whether we pass s->childp or &s->child.) * (2) If new_bs is not NULL, s->childp will be NULL. We then cannot use * it here. * (3) If new_bs is NULL, *s->childp will have been NULLed by * bdrv_replace_child_tran()'s bdrv_replace_child_noperm() call, and we * must not pass a NULL *s->childp here. + * (TODO: In its current state, bdrv_replace_child_noperm() will not + * have NULLed *s->childp, so this does not apply yet. It will in the + * future.) * * So whether new_bs was NULL or not, we cannot pass s->childp here; and in * any case, there is no reason to pass it anyway. */ - bdrv_replace_child_noperm(&s->child, s->old_bs, true); - /* - * The child was pre-existing, so s->old_bs must be non-NULL, and - * s->child thus must not have been freed - */ - assert(s->child != NULL); - if (!new_bs) { - /* As described above, *s->childp was cleared, so restore it */ - assert(s->childp != NULL); - *s->childp = s->child; - } + bdrv_replace_child_noperm(&s->child, s->old_bs); bdrv_unref(new_bs); } @@ -2409,44 +2399,30 @@ static TransactionActionDrv bdrv_replace_child_drv = { * * The function doesn't update permissions, caller is responsible for this. * - * (*childp)->bs must not be NULL. - * * Note that if new_bs == NULL, @childp is stored in a state object attached * to @tran, so that the old child can be reinstated in the abort handler. * Therefore, if @new_bs can be NULL, @childp must stay valid until the * transaction is committed or aborted. * - * If @free_empty_child is true and @new_bs is NULL, the BdrvChild is - * freed (on commit). @free_empty_child should only be false if the - * caller will free the BDrvChild themselves (which may be important - * if this is in turn called in another transactional context). + * (TODO: The reinstating does not happen yet, but it will once + * bdrv_replace_child_noperm() NULLs *childp when new_bs is NULL.) */ static void bdrv_replace_child_tran(BdrvChild **childp, BlockDriverState *new_bs, - Transaction *tran, - bool free_empty_child) + Transaction *tran) { BdrvReplaceChildState *s = g_new(BdrvReplaceChildState, 1); *s = (BdrvReplaceChildState) { .child = *childp, .childp = new_bs == NULL ? childp : NULL, .old_bs = (*childp)->bs, - .free_empty_child = free_empty_child, }; tran_add(tran, &bdrv_replace_child_drv, s); - /* The abort handler relies on this */ - assert(s->old_bs != NULL); - if (new_bs) { bdrv_ref(new_bs); } - /* - * Pass free_empty_child=false, we will free the child (if - * necessary) in bdrv_replace_child_commit() (if our - * @free_empty_child parameter was true). - */ - bdrv_replace_child_noperm(childp, new_bs, false); + bdrv_replace_child_noperm(childp, new_bs); /* old_bs reference is transparently moved from *childp to @s */ } @@ -2828,22 +2804,8 @@ uint64_t bdrv_qapi_perm_to_blk_perm(BlockPermission qapi_perm) return permissions[qapi_perm]; } -/** - * Replace (*childp)->bs by @new_bs. - * - * If @new_bs is NULL, *childp will be set to NULL, too: BDS parents - * generally cannot handle a BdrvChild with .bs == NULL, so clearing - * BdrvChild.bs should generally immediately be followed by the - * BdrvChild pointer being cleared as well. - * - * If @free_empty_child is true and @new_bs is NULL, the BdrvChild is - * freed. @free_empty_child should only be false if the caller will - * free the BdrvChild themselves (this may be important in a - * transactional context, where it may only be freed on commit). - */ static void bdrv_replace_child_noperm(BdrvChild **childp, - BlockDriverState *new_bs, - bool free_empty_child) + BlockDriverState *new_bs) { BdrvChild *child = *childp; BlockDriverState *old_bs = child->bs; @@ -2882,9 +2844,6 @@ static void bdrv_replace_child_noperm(BdrvChild **childp, } child->bs = new_bs; - if (!new_bs) { - *childp = NULL; - } if (new_bs) { assert_bdrv_graph_writable(new_bs); @@ -2915,10 +2874,6 @@ static void bdrv_replace_child_noperm(BdrvChild **childp, bdrv_parent_drained_end_single(child); drain_saldo++; } - - if (free_empty_child && !child->bs) { - bdrv_child_free(child); - } } /** @@ -2950,14 +2905,7 @@ static void bdrv_attach_child_common_abort(void *opaque) BlockDriverState *bs = child->bs; GLOBAL_STATE_CODE(); - /* - * Pass free_empty_child=false, because we still need the child - * for the AioContext operations on the parent below; those - * BdrvChildClass methods all work on a BdrvChild object, so we - * need to keep it as an empty shell (after this function, it will - * not be attached to any parent, and it will not have a .bs). - */ - bdrv_replace_child_noperm(s->child, NULL, false); + bdrv_replace_child_noperm(s->child, NULL); if (bdrv_get_aio_context(bs) != s->old_child_ctx) { bdrv_try_set_aio_context(bs, s->old_child_ctx, &error_abort); @@ -2979,6 +2927,7 @@ static void bdrv_attach_child_common_abort(void *opaque) bdrv_unref(bs); bdrv_child_free(child); + *s->child = NULL; } static TransactionActionDrv bdrv_attach_child_common_drv = { @@ -3057,9 +3006,7 @@ static int bdrv_attach_child_common(BlockDriverState *child_bs, } bdrv_ref(child_bs); - bdrv_replace_child_noperm(&new_child, child_bs, true); - /* child_bs was non-NULL, so new_child must not have been freed */ - assert(new_child != NULL); + bdrv_replace_child_noperm(&new_child, child_bs); *child = new_child; @@ -3120,7 +3067,8 @@ static void bdrv_detach_child(BdrvChild **childp) BlockDriverState *old_bs = (*childp)->bs; GLOBAL_STATE_CODE(); - bdrv_replace_child_noperm(childp, NULL, true); + bdrv_replace_child_noperm(childp, NULL); + bdrv_child_free(*childp); if (old_bs) { /* @@ -5171,11 +5119,7 @@ static void bdrv_remove_file_or_backing_child(BlockDriverState *bs, } if (child->bs) { - /* - * Pass free_empty_child=false, we will free the child in - * bdrv_remove_filter_or_cow_child_commit() - */ - bdrv_replace_child_tran(childp, NULL, tran, false); + bdrv_replace_child_tran(childp, NULL, tran); } s = g_new(BdrvRemoveFilterOrCowChild, 1); @@ -5185,6 +5129,8 @@ static void bdrv_remove_file_or_backing_child(BlockDriverState *bs, .is_backing = (childp == &bs->backing), }; tran_add(tran, &bdrv_remove_filter_or_cow_child_drv, s); + + *childp = NULL; } /* @@ -5228,7 +5174,7 @@ static int bdrv_replace_node_noperm(BlockDriverState *from, * Passing a pointer to the local variable @c is fine here, because * @to is not NULL, and so &c will not be attached to the transaction. */ - bdrv_replace_child_tran(&c, to, tran, true); + bdrv_replace_child_tran(&c, to, tran); } return 0; @@ -5393,9 +5339,7 @@ int bdrv_replace_child_bs(BdrvChild *child, BlockDriverState *new_bs, bdrv_drained_begin(old_bs); bdrv_drained_begin(new_bs); - bdrv_replace_child_tran(&child, new_bs, tran, true); - /* @new_bs must have been non-NULL, so @child must not have been freed */ - assert(child != NULL); + bdrv_replace_child_tran(&child, new_bs, tran); found = g_hash_table_new(NULL, NULL); refresh_list = bdrv_topological_dfs(refresh_list, found, old_bs); From 0f0b1e29d35e0a7da6271b3fa0fefa63380204e7 Mon Sep 17 00:00:00 2001 From: Vladimir Sementsov-Ogievskiy Date: Tue, 26 Jul 2022 23:11:29 +0300 Subject: [PATCH 253/705] Revert "block: Let replace_child_tran keep indirect pointer" That's a preparation to previously reverted "block: Let replace_child_noperm free children". Drop it too, we don't need it for a new approach. This reverts commit 82b54cf51656bf3cd5ed1ac549e8a1085a0e3290. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Hanna Reitz Message-Id: <20220726201134.924743-11-vsementsov@yandex-team.ru> Signed-off-by: Kevin Wolf --- block.c | 81 +++++++-------------------------------------------------- 1 file changed, 10 insertions(+), 71 deletions(-) diff --git a/block.c b/block.c index 7a9a6efca8..196d1cf665 100644 --- a/block.c +++ b/block.c @@ -2341,7 +2341,6 @@ static int bdrv_drv_set_perm(BlockDriverState *bs, uint64_t perm, typedef struct BdrvReplaceChildState { BdrvChild *child; - BdrvChild **childp; BlockDriverState *old_bs; } BdrvReplaceChildState; @@ -2359,29 +2358,7 @@ static void bdrv_replace_child_abort(void *opaque) BlockDriverState *new_bs = s->child->bs; GLOBAL_STATE_CODE(); - /* - * old_bs reference is transparently moved from @s to s->child. - * - * Pass &s->child here instead of s->childp, because: - * (1) s->old_bs must be non-NULL, so bdrv_replace_child_noperm() will not - * modify the BdrvChild * pointer we indirectly pass to it, i.e. it - * will not modify s->child. From that perspective, it does not matter - * whether we pass s->childp or &s->child. - * (TODO: Right now, bdrv_replace_child_noperm() never modifies that - * pointer anyway (though it will in the future), so at this point it - * absolutely does not matter whether we pass s->childp or &s->child.) - * (2) If new_bs is not NULL, s->childp will be NULL. We then cannot use - * it here. - * (3) If new_bs is NULL, *s->childp will have been NULLed by - * bdrv_replace_child_tran()'s bdrv_replace_child_noperm() call, and we - * must not pass a NULL *s->childp here. - * (TODO: In its current state, bdrv_replace_child_noperm() will not - * have NULLed *s->childp, so this does not apply yet. It will in the - * future.) - * - * So whether new_bs was NULL or not, we cannot pass s->childp here; and in - * any case, there is no reason to pass it anyway. - */ + /* old_bs reference is transparently moved from @s to @s->child */ bdrv_replace_child_noperm(&s->child, s->old_bs); bdrv_unref(new_bs); } @@ -2398,32 +2375,22 @@ static TransactionActionDrv bdrv_replace_child_drv = { * Note: real unref of old_bs is done only on commit. * * The function doesn't update permissions, caller is responsible for this. - * - * Note that if new_bs == NULL, @childp is stored in a state object attached - * to @tran, so that the old child can be reinstated in the abort handler. - * Therefore, if @new_bs can be NULL, @childp must stay valid until the - * transaction is committed or aborted. - * - * (TODO: The reinstating does not happen yet, but it will once - * bdrv_replace_child_noperm() NULLs *childp when new_bs is NULL.) */ -static void bdrv_replace_child_tran(BdrvChild **childp, - BlockDriverState *new_bs, +static void bdrv_replace_child_tran(BdrvChild *child, BlockDriverState *new_bs, Transaction *tran) { BdrvReplaceChildState *s = g_new(BdrvReplaceChildState, 1); *s = (BdrvReplaceChildState) { - .child = *childp, - .childp = new_bs == NULL ? childp : NULL, - .old_bs = (*childp)->bs, + .child = child, + .old_bs = child->bs, }; tran_add(tran, &bdrv_replace_child_drv, s); if (new_bs) { bdrv_ref(new_bs); } - bdrv_replace_child_noperm(childp, new_bs); - /* old_bs reference is transparently moved from *childp to @s */ + bdrv_replace_child_noperm(&child, new_bs); + /* old_bs reference is transparently moved from @child to @s */ } /* @@ -5045,7 +5012,6 @@ static bool should_update_child(BdrvChild *c, BlockDriverState *to) typedef struct BdrvRemoveFilterOrCowChild { BdrvChild *child; - BlockDriverState *bs; bool is_backing; } BdrvRemoveFilterOrCowChild; @@ -5075,19 +5041,10 @@ static void bdrv_remove_filter_or_cow_child_commit(void *opaque) bdrv_child_free(s->child); } -static void bdrv_remove_filter_or_cow_child_clean(void *opaque) -{ - BdrvRemoveFilterOrCowChild *s = opaque; - - /* Drop the bs reference after the transaction is done */ - bdrv_unref(s->bs); - g_free(s); -} - static TransactionActionDrv bdrv_remove_filter_or_cow_child_drv = { .abort = bdrv_remove_filter_or_cow_child_abort, .commit = bdrv_remove_filter_or_cow_child_commit, - .clean = bdrv_remove_filter_or_cow_child_clean, + .clean = g_free, }; /* @@ -5105,11 +5062,6 @@ static void bdrv_remove_file_or_backing_child(BlockDriverState *bs, return; } - /* - * Keep a reference to @bs so @childp will stay valid throughout the - * transaction (required by bdrv_replace_child_tran()) - */ - bdrv_ref(bs); if (child == bs->backing) { childp = &bs->backing; } else if (child == bs->file) { @@ -5119,13 +5071,12 @@ static void bdrv_remove_file_or_backing_child(BlockDriverState *bs, } if (child->bs) { - bdrv_replace_child_tran(childp, NULL, tran); + bdrv_replace_child_tran(*childp, NULL, tran); } s = g_new(BdrvRemoveFilterOrCowChild, 1); *s = (BdrvRemoveFilterOrCowChild) { .child = child, - .bs = bs, .is_backing = (childp == &bs->backing), }; tran_add(tran, &bdrv_remove_filter_or_cow_child_drv, s); @@ -5151,7 +5102,6 @@ static int bdrv_replace_node_noperm(BlockDriverState *from, { BdrvChild *c, *next; - assert(to != NULL); GLOBAL_STATE_CODE(); QLIST_FOREACH_SAFE(c, &from->parents, next_parent, next) { @@ -5169,12 +5119,7 @@ static int bdrv_replace_node_noperm(BlockDriverState *from, c->name, from->node_name); return -EPERM; } - - /* - * Passing a pointer to the local variable @c is fine here, because - * @to is not NULL, and so &c will not be attached to the transaction. - */ - bdrv_replace_child_tran(&c, to, tran); + bdrv_replace_child_tran(c, to, tran); } return 0; @@ -5189,8 +5134,6 @@ static int bdrv_replace_node_noperm(BlockDriverState *from, * * With @detach_subchain=true @to must be in a backing chain of @from. In this * case backing link of the cow-parent of @to is removed. - * - * @to must not be NULL. */ static int bdrv_replace_node_common(BlockDriverState *from, BlockDriverState *to, @@ -5204,7 +5147,6 @@ static int bdrv_replace_node_common(BlockDriverState *from, int ret; GLOBAL_STATE_CODE(); - assert(to != NULL); if (detach_subchain) { assert(bdrv_chain_contains(from, to)); @@ -5261,9 +5203,6 @@ out: return ret; } -/** - * Replace node @from by @to (where neither may be NULL). - */ int bdrv_replace_node(BlockDriverState *from, BlockDriverState *to, Error **errp) { @@ -5339,7 +5278,7 @@ int bdrv_replace_child_bs(BdrvChild *child, BlockDriverState *new_bs, bdrv_drained_begin(old_bs); bdrv_drained_begin(new_bs); - bdrv_replace_child_tran(&child, new_bs, tran); + bdrv_replace_child_tran(child, new_bs, tran); found = g_hash_table_new(NULL, NULL); refresh_list = bdrv_topological_dfs(refresh_list, found, old_bs); From a2c37a30422328fe2391bd1ff342f8941c7681bc Mon Sep 17 00:00:00 2001 From: Vladimir Sementsov-Ogievskiy Date: Tue, 26 Jul 2022 23:11:30 +0300 Subject: [PATCH 254/705] Revert "block: Restructure remove_file_or_backing_child()" That's a preparation to previously reverted "block: Let replace_child_noperm free children". Drop it too, we don't need it for a new approach. This reverts commit 562bda8bb41879eeda0bd484dd3d55134579b28e. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Hanna Reitz Message-Id: <20220726201134.924743-12-vsementsov@yandex-team.ru> Signed-off-by: Kevin Wolf --- block.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/block.c b/block.c index 196d1cf665..2f80b7e094 100644 --- a/block.c +++ b/block.c @@ -5055,33 +5055,30 @@ static void bdrv_remove_file_or_backing_child(BlockDriverState *bs, BdrvChild *child, Transaction *tran) { - BdrvChild **childp; BdrvRemoveFilterOrCowChild *s; + assert(child == bs->backing || child == bs->file); + if (!child) { return; } - if (child == bs->backing) { - childp = &bs->backing; - } else if (child == bs->file) { - childp = &bs->file; - } else { - g_assert_not_reached(); - } - if (child->bs) { - bdrv_replace_child_tran(*childp, NULL, tran); + bdrv_replace_child_tran(child, NULL, tran); } s = g_new(BdrvRemoveFilterOrCowChild, 1); *s = (BdrvRemoveFilterOrCowChild) { .child = child, - .is_backing = (childp == &bs->backing), + .is_backing = (child == bs->backing), }; tran_add(tran, &bdrv_remove_filter_or_cow_child_drv, s); - *childp = NULL; + if (s->is_backing) { + bs->backing = NULL; + } else { + bs->file = NULL; + } } /* From 544acc7d1e1eebce76c9a8bc76a660433df2c3cd Mon Sep 17 00:00:00 2001 From: Vladimir Sementsov-Ogievskiy Date: Tue, 26 Jul 2022 23:11:31 +0300 Subject: [PATCH 255/705] Revert "block: Pass BdrvChild ** to replace_child_noperm" That's a preparation to previously reverted "block: Let replace_child_noperm free children". Drop it too, we don't need it for a new approach. This reverts commit be64bbb0149748f3999c49b13976aafb8330ea86. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Hanna Reitz Message-Id: <20220726201134.924743-13-vsementsov@yandex-team.ru> Signed-off-by: Kevin Wolf --- block.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/block.c b/block.c index 2f80b7e094..683a9e0eff 100644 --- a/block.c +++ b/block.c @@ -90,7 +90,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename, static bool bdrv_recurse_has_child(BlockDriverState *bs, BlockDriverState *child); -static void bdrv_replace_child_noperm(BdrvChild **child, +static void bdrv_replace_child_noperm(BdrvChild *child, BlockDriverState *new_bs); static void bdrv_remove_file_or_backing_child(BlockDriverState *bs, BdrvChild *child, @@ -2359,7 +2359,7 @@ static void bdrv_replace_child_abort(void *opaque) GLOBAL_STATE_CODE(); /* old_bs reference is transparently moved from @s to @s->child */ - bdrv_replace_child_noperm(&s->child, s->old_bs); + bdrv_replace_child_noperm(s->child, s->old_bs); bdrv_unref(new_bs); } @@ -2389,7 +2389,7 @@ static void bdrv_replace_child_tran(BdrvChild *child, BlockDriverState *new_bs, if (new_bs) { bdrv_ref(new_bs); } - bdrv_replace_child_noperm(&child, new_bs); + bdrv_replace_child_noperm(child, new_bs); /* old_bs reference is transparently moved from @child to @s */ } @@ -2771,10 +2771,9 @@ uint64_t bdrv_qapi_perm_to_blk_perm(BlockPermission qapi_perm) return permissions[qapi_perm]; } -static void bdrv_replace_child_noperm(BdrvChild **childp, +static void bdrv_replace_child_noperm(BdrvChild *child, BlockDriverState *new_bs) { - BdrvChild *child = *childp; BlockDriverState *old_bs = child->bs; int new_bs_quiesce_counter; int drain_saldo; @@ -2872,7 +2871,7 @@ static void bdrv_attach_child_common_abort(void *opaque) BlockDriverState *bs = child->bs; GLOBAL_STATE_CODE(); - bdrv_replace_child_noperm(s->child, NULL); + bdrv_replace_child_noperm(child, NULL); if (bdrv_get_aio_context(bs) != s->old_child_ctx) { bdrv_try_set_aio_context(bs, s->old_child_ctx, &error_abort); @@ -2973,7 +2972,7 @@ static int bdrv_attach_child_common(BlockDriverState *child_bs, } bdrv_ref(child_bs); - bdrv_replace_child_noperm(&new_child, child_bs); + bdrv_replace_child_noperm(new_child, child_bs); *child = new_child; @@ -3029,13 +3028,13 @@ static int bdrv_attach_child_noperm(BlockDriverState *parent_bs, return 0; } -static void bdrv_detach_child(BdrvChild **childp) +static void bdrv_detach_child(BdrvChild *child) { - BlockDriverState *old_bs = (*childp)->bs; + BlockDriverState *old_bs = child->bs; GLOBAL_STATE_CODE(); - bdrv_replace_child_noperm(childp, NULL); - bdrv_child_free(*childp); + bdrv_replace_child_noperm(child, NULL); + bdrv_child_free(child); if (old_bs) { /* @@ -3147,7 +3146,7 @@ void bdrv_root_unref_child(BdrvChild *child) GLOBAL_STATE_CODE(); child_bs = child->bs; - bdrv_detach_child(&child); + bdrv_detach_child(child); bdrv_unref(child_bs); } From 5bb047477807375e2d5e2494b1d1302d5cea4b73 Mon Sep 17 00:00:00 2001 From: Vladimir Sementsov-Ogievskiy Date: Tue, 26 Jul 2022 23:11:32 +0300 Subject: [PATCH 256/705] block: Manipulate bs->file / bs->backing pointers in .attach/.detach bs->file and bs->backing are a kind of duplication of part of bs->children. But very useful diplication, so let's not drop them at all:) We should manage bs->file and bs->backing in same place, where we manage bs->children, to keep them in sync. Moreover, generic io paths are unprepared to BdrvChild without a bs, so it's double good to clear bs->file / bs->backing when we detach the child. Detach is simple: if we detach bs->file or bs->backing child, just set corresponding field to NULL. Attach is a bit more complicated. But we still can precisely detect should we set one of bs->file / bs->backing or not: - if role is BDRV_CHILD_COW, we definitely deal with bs->backing - else, if role is BDRV_CHILD_FILTERED (it must be also BDRV_CHILD_PRIMARY), it's a filtered child. Use bs->drv->filtered_child_is_backing to chose the pointer field to modify. - else, if role is BDRV_CHILD_PRIMARY, we deal with bs->file - in all other cases, it's neither bs->backing nor bs->file. It's some other child and we shouldn't care OK. This change brings one more good thing: we can (and should) get rid of all indirect pointers in the block-graph-change transactions: bdrv_attach_child_common() stores BdrvChild** into transaction to clear it on abort. bdrv_attach_child_common() has two callers: bdrv_attach_child_noperm() just pass-through this feature, bdrv_root_attach_child() doesn't need the feature. Look at bdrv_attach_child_noperm() callers: - bdrv_attach_child() doesn't need the feature - bdrv_set_file_or_backing_noperm() uses the feature to manage bs->file and bs->backing, we don't want it anymore - bdrv_append() uses the feature to manage bs->backing, again we don't want it anymore So, we should drop this stuff! Great! We could probably keep BdrvChild** argument to keep the int return value, but it seems not worth the complexity. Finally, we now set .file / .backing automatically in generic code and want to restring setting them by hand outside of .attach/.detach. So, this patch cleanups all remaining places where they were set. To find such places I use: git grep '\->file =' git grep '\->backing =' git grep '&.*\' git grep '&.*\' Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Hanna Reitz Message-Id: <20220726201134.924743-14-vsementsov@yandex-team.ru> Signed-off-by: Kevin Wolf --- block.c | 232 ++++++++++++++----------------- block/raw-format.c | 4 +- block/snapshot-access.c | 6 +- block/snapshot.c | 1 - include/block/block_int-common.h | 15 +- tests/unit/test-bdrv-drain.c | 10 +- 6 files changed, 125 insertions(+), 143 deletions(-) diff --git a/block.c b/block.c index 683a9e0eff..ed11a421b0 100644 --- a/block.c +++ b/block.c @@ -1445,9 +1445,39 @@ static void bdrv_child_cb_attach(BdrvChild *child) assert_bdrv_graph_writable(bs); QLIST_INSERT_HEAD(&bs->children, child, next); + if (bs->drv->is_filter || (child->role & BDRV_CHILD_FILTERED)) { + /* + * Here we handle filters and block/raw-format.c when it behave like + * filter. They generally have a single PRIMARY child, which is also the + * FILTERED child, and that they may have multiple more children, which + * are neither PRIMARY nor FILTERED. And never we have a COW child here. + * So bs->file will be the PRIMARY child, unless the PRIMARY child goes + * into bs->backing on exceptional cases; and bs->backing will be + * nothing else. + */ + assert(!(child->role & BDRV_CHILD_COW)); + if (child->role & BDRV_CHILD_PRIMARY) { + assert(child->role & BDRV_CHILD_FILTERED); + assert(!bs->backing); + assert(!bs->file); - if (child->role & BDRV_CHILD_COW) { + if (bs->drv->filtered_child_is_backing) { + bs->backing = child; + } else { + bs->file = child; + } + } else { + assert(!(child->role & BDRV_CHILD_FILTERED)); + } + } else if (child->role & BDRV_CHILD_COW) { + assert(bs->drv->supports_backing); + assert(!(child->role & BDRV_CHILD_PRIMARY)); + assert(!bs->backing); + bs->backing = child; bdrv_backing_attach(child); + } else if (child->role & BDRV_CHILD_PRIMARY) { + assert(!bs->file); + bs->file = child; } bdrv_apply_subtree_drain(child, bs); @@ -1465,6 +1495,12 @@ static void bdrv_child_cb_detach(BdrvChild *child) assert_bdrv_graph_writable(bs); QLIST_REMOVE(child, next); + if (child == bs->backing) { + assert(child != bs->file); + bs->backing = NULL; + } else if (child == bs->file) { + bs->file = NULL; + } } static int bdrv_child_cb_update_filename(BdrvChild *c, BlockDriverState *base, @@ -1670,7 +1706,7 @@ open_failed: bs->drv = NULL; if (bs->file != NULL) { bdrv_unref_child(bs, bs->file); - bs->file = NULL; + assert(!bs->file); } g_free(bs->opaque); bs->opaque = NULL; @@ -2859,7 +2895,7 @@ static void bdrv_child_free(BdrvChild *child) } typedef struct BdrvAttachChildCommonState { - BdrvChild **child; + BdrvChild *child; AioContext *old_parent_ctx; AioContext *old_child_ctx; } BdrvAttachChildCommonState; @@ -2867,33 +2903,31 @@ typedef struct BdrvAttachChildCommonState { static void bdrv_attach_child_common_abort(void *opaque) { BdrvAttachChildCommonState *s = opaque; - BdrvChild *child = *s->child; - BlockDriverState *bs = child->bs; + BlockDriverState *bs = s->child->bs; GLOBAL_STATE_CODE(); - bdrv_replace_child_noperm(child, NULL); + bdrv_replace_child_noperm(s->child, NULL); if (bdrv_get_aio_context(bs) != s->old_child_ctx) { bdrv_try_set_aio_context(bs, s->old_child_ctx, &error_abort); } - if (bdrv_child_get_parent_aio_context(child) != s->old_parent_ctx) { + if (bdrv_child_get_parent_aio_context(s->child) != s->old_parent_ctx) { GSList *ignore; /* No need to ignore `child`, because it has been detached already */ ignore = NULL; - child->klass->can_set_aio_ctx(child, s->old_parent_ctx, &ignore, - &error_abort); + s->child->klass->can_set_aio_ctx(s->child, s->old_parent_ctx, &ignore, + &error_abort); g_slist_free(ignore); ignore = NULL; - child->klass->set_aio_ctx(child, s->old_parent_ctx, &ignore); + s->child->klass->set_aio_ctx(s->child, s->old_parent_ctx, &ignore); g_slist_free(ignore); } bdrv_unref(bs); - bdrv_child_free(child); - *s->child = NULL; + bdrv_child_free(s->child); } static TransactionActionDrv bdrv_attach_child_common_drv = { @@ -2904,28 +2938,22 @@ static TransactionActionDrv bdrv_attach_child_common_drv = { /* * Common part of attaching bdrv child to bs or to blk or to job * - * Resulting new child is returned through @child. - * At start *@child must be NULL. - * @child is saved to a new entry of @tran, so that *@child could be reverted to - * NULL on abort(). So referenced variable must live at least until transaction - * end. - * * Function doesn't update permissions, caller is responsible for this. + * + * Returns new created child. */ -static int bdrv_attach_child_common(BlockDriverState *child_bs, - const char *child_name, - const BdrvChildClass *child_class, - BdrvChildRole child_role, - uint64_t perm, uint64_t shared_perm, - void *opaque, BdrvChild **child, - Transaction *tran, Error **errp) +static BdrvChild *bdrv_attach_child_common(BlockDriverState *child_bs, + const char *child_name, + const BdrvChildClass *child_class, + BdrvChildRole child_role, + uint64_t perm, uint64_t shared_perm, + void *opaque, + Transaction *tran, Error **errp) { BdrvChild *new_child; AioContext *parent_ctx; AioContext *child_ctx = bdrv_get_aio_context(child_bs); - assert(child); - assert(*child == NULL); assert(child_class->get_parent_desc); GLOBAL_STATE_CODE(); @@ -2967,42 +2995,35 @@ static int bdrv_attach_child_common(BlockDriverState *child_bs, if (ret < 0) { error_propagate(errp, local_err); bdrv_child_free(new_child); - return ret; + return NULL; } } bdrv_ref(child_bs); bdrv_replace_child_noperm(new_child, child_bs); - *child = new_child; - BdrvAttachChildCommonState *s = g_new(BdrvAttachChildCommonState, 1); *s = (BdrvAttachChildCommonState) { - .child = child, + .child = new_child, .old_parent_ctx = parent_ctx, .old_child_ctx = child_ctx, }; tran_add(tran, &bdrv_attach_child_common_drv, s); - return 0; + return new_child; } /* - * Variable referenced by @child must live at least until transaction end. - * (see bdrv_attach_child_common() doc for details) - * * Function doesn't update permissions, caller is responsible for this. */ -static int bdrv_attach_child_noperm(BlockDriverState *parent_bs, - BlockDriverState *child_bs, - const char *child_name, - const BdrvChildClass *child_class, - BdrvChildRole child_role, - BdrvChild **child, - Transaction *tran, - Error **errp) +static BdrvChild *bdrv_attach_child_noperm(BlockDriverState *parent_bs, + BlockDriverState *child_bs, + const char *child_name, + const BdrvChildClass *child_class, + BdrvChildRole child_role, + Transaction *tran, + Error **errp) { - int ret; uint64_t perm, shared_perm; assert(parent_bs->drv); @@ -3011,21 +3032,16 @@ static int bdrv_attach_child_noperm(BlockDriverState *parent_bs, if (bdrv_recurse_has_child(child_bs, parent_bs)) { error_setg(errp, "Making '%s' a %s child of '%s' would create a cycle", child_bs->node_name, child_name, parent_bs->node_name); - return -EINVAL; + return NULL; } bdrv_get_cumulative_perm(parent_bs, &perm, &shared_perm); bdrv_child_perm(parent_bs, child_bs, NULL, child_role, NULL, perm, shared_perm, &perm, &shared_perm); - ret = bdrv_attach_child_common(child_bs, child_name, child_class, - child_role, perm, shared_perm, parent_bs, - child, tran, errp); - if (ret < 0) { - return ret; - } - - return 0; + return bdrv_attach_child_common(child_bs, child_name, child_class, + child_role, perm, shared_perm, parent_bs, + tran, errp); } static void bdrv_detach_child(BdrvChild *child) @@ -3070,15 +3086,16 @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs, void *opaque, Error **errp) { int ret; - BdrvChild *child = NULL; + BdrvChild *child; Transaction *tran = tran_new(); GLOBAL_STATE_CODE(); - ret = bdrv_attach_child_common(child_bs, child_name, child_class, + child = bdrv_attach_child_common(child_bs, child_name, child_class, child_role, perm, shared_perm, opaque, - &child, tran, errp); - if (ret < 0) { + tran, errp); + if (!child) { + ret = -EINVAL; goto out; } @@ -3086,11 +3103,10 @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs, out: tran_finalize(tran, ret); - /* child is unset on failure by bdrv_attach_child_common_abort() */ - assert((ret < 0) == !child); bdrv_unref(child_bs); - return child; + + return ret < 0 ? NULL : child; } /* @@ -3112,14 +3128,15 @@ BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs, Error **errp) { int ret; - BdrvChild *child = NULL; + BdrvChild *child; Transaction *tran = tran_new(); GLOBAL_STATE_CODE(); - ret = bdrv_attach_child_noperm(parent_bs, child_bs, child_name, child_class, - child_role, &child, tran, errp); - if (ret < 0) { + child = bdrv_attach_child_noperm(parent_bs, child_bs, child_name, + child_class, child_role, tran, errp); + if (!child) { + ret = -EINVAL; goto out; } @@ -3130,12 +3147,10 @@ BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs, out: tran_finalize(tran, ret); - /* child is unset on failure by bdrv_attach_child_common_abort() */ - assert((ret < 0) == !child); bdrv_unref(child_bs); - return child; + return ret < 0 ? NULL : child; } /* Callers must ensure that child->frozen is false. */ @@ -3277,7 +3292,6 @@ static int bdrv_set_file_or_backing_noperm(BlockDriverState *parent_bs, bool is_backing, Transaction *tran, Error **errp) { - int ret = 0; bool update_inherits_from = bdrv_inherits_from_recursive(child_bs, parent_bs); BdrvChild *child = is_backing ? parent_bs->backing : parent_bs->file; @@ -3335,14 +3349,12 @@ static int bdrv_set_file_or_backing_noperm(BlockDriverState *parent_bs, goto out; } - ret = bdrv_attach_child_noperm(parent_bs, child_bs, - is_backing ? "backing" : "file", - &child_of_bds, role, - is_backing ? &parent_bs->backing : - &parent_bs->file, - tran, errp); - if (ret < 0) { - return ret; + child = bdrv_attach_child_noperm(parent_bs, child_bs, + is_backing ? "backing" : "file", + &child_of_bds, role, + tran, errp); + if (!child) { + return -EINVAL; } @@ -3598,14 +3610,16 @@ int bdrv_open_file_child(const char *filename, /* commit_top and mirror_top don't use this function */ assert(!parent->drv->filtered_child_is_backing); - role = parent->drv->is_filter ? (BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY) : BDRV_CHILD_IMAGE; - parent->file = bdrv_open_child(filename, options, bdref_key, parent, - &child_of_bds, role, false, errp); + if (!bdrv_open_child(filename, options, bdref_key, parent, + &child_of_bds, role, false, errp)) + { + return -EINVAL; + } - return parent->file ? 0 : -EINVAL; + return 0; } /* @@ -4877,8 +4891,8 @@ static void bdrv_close(BlockDriverState *bs) bdrv_unref_child(bs, child); } - bs->backing = NULL; - bs->file = NULL; + assert(!bs->backing); + assert(!bs->file); g_free(bs->opaque); bs->opaque = NULL; qatomic_set(&bs->copy_on_read, 0); @@ -5009,41 +5023,14 @@ static bool should_update_child(BdrvChild *c, BlockDriverState *to) return ret; } -typedef struct BdrvRemoveFilterOrCowChild { - BdrvChild *child; - bool is_backing; -} BdrvRemoveFilterOrCowChild; - -static void bdrv_remove_filter_or_cow_child_abort(void *opaque) -{ - BdrvRemoveFilterOrCowChild *s = opaque; - BlockDriverState *parent_bs = s->child->opaque; - - if (s->is_backing) { - parent_bs->backing = s->child; - } else { - parent_bs->file = s->child; - } - - /* - * We don't have to restore child->bs here to undo bdrv_replace_child_tran() - * because that function is transactionable and it registered own completion - * entries in @tran, so .abort() for bdrv_replace_child_safe() will be - * called automatically. - */ -} - static void bdrv_remove_filter_or_cow_child_commit(void *opaque) { - BdrvRemoveFilterOrCowChild *s = opaque; GLOBAL_STATE_CODE(); - bdrv_child_free(s->child); + bdrv_child_free(opaque); } static TransactionActionDrv bdrv_remove_filter_or_cow_child_drv = { - .abort = bdrv_remove_filter_or_cow_child_abort, .commit = bdrv_remove_filter_or_cow_child_commit, - .clean = g_free, }; /* @@ -5054,8 +5041,6 @@ static void bdrv_remove_file_or_backing_child(BlockDriverState *bs, BdrvChild *child, Transaction *tran) { - BdrvRemoveFilterOrCowChild *s; - assert(child == bs->backing || child == bs->file); if (!child) { @@ -5066,18 +5051,7 @@ static void bdrv_remove_file_or_backing_child(BlockDriverState *bs, bdrv_replace_child_tran(child, NULL, tran); } - s = g_new(BdrvRemoveFilterOrCowChild, 1); - *s = (BdrvRemoveFilterOrCowChild) { - .child = child, - .is_backing = (child == bs->backing), - }; - tran_add(tran, &bdrv_remove_filter_or_cow_child_drv, s); - - if (s->is_backing) { - bs->backing = NULL; - } else { - bs->file = NULL; - } + tran_add(tran, &bdrv_remove_filter_or_cow_child_drv, child); } /* @@ -5231,16 +5205,18 @@ int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top, Error **errp) { int ret; + BdrvChild *child; Transaction *tran = tran_new(); GLOBAL_STATE_CODE(); assert(!bs_new->backing); - ret = bdrv_attach_child_noperm(bs_new, bs_top, "backing", - &child_of_bds, bdrv_backing_role(bs_new), - &bs_new->backing, tran, errp); - if (ret < 0) { + child = bdrv_attach_child_noperm(bs_new, bs_top, "backing", + &child_of_bds, bdrv_backing_role(bs_new), + tran, errp); + if (!child) { + ret = -EINVAL; goto out; } diff --git a/block/raw-format.c b/block/raw-format.c index f337ac7569..408b20e22d 100644 --- a/block/raw-format.c +++ b/block/raw-format.c @@ -458,8 +458,8 @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags, file_role = BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY; } - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - file_role, false, errp); + bdrv_open_child(NULL, options, "file", bs, &child_of_bds, + file_role, false, errp); if (!bs->file) { return -EINVAL; } diff --git a/block/snapshot-access.c b/block/snapshot-access.c index 77b87c1946..0a30ec6cd9 100644 --- a/block/snapshot-access.c +++ b/block/snapshot-access.c @@ -82,9 +82,9 @@ static void snapshot_access_refresh_filename(BlockDriverState *bs) static int snapshot_access_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) { - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_DATA | BDRV_CHILD_PRIMARY, - false, errp); + bdrv_open_child(NULL, options, "file", bs, &child_of_bds, + BDRV_CHILD_DATA | BDRV_CHILD_PRIMARY, + false, errp); if (!bs->file) { return -EINVAL; } diff --git a/block/snapshot.c b/block/snapshot.c index 75e8d3a937..f3971ac2bd 100644 --- a/block/snapshot.c +++ b/block/snapshot.c @@ -288,7 +288,6 @@ int bdrv_snapshot_goto(BlockDriverState *bs, /* .bdrv_open() will re-attach it */ bdrv_unref_child(bs, *fallback_ptr); - *fallback_ptr = NULL; ret = bdrv_snapshot_goto(fallback_bs, snapshot_id, errp); open_ret = drv->bdrv_open(bs, options, bs->open_flags, &local_err); diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h index 10feef9f0c..1f300ee7f6 100644 --- a/include/block/block_int-common.h +++ b/include/block/block_int-common.h @@ -1056,9 +1056,6 @@ struct BlockDriverState { QDict *full_open_options; char exact_filename[PATH_MAX]; - BdrvChild *backing; - BdrvChild *file; - /* I/O Limits */ BlockLimits bl; @@ -1117,7 +1114,19 @@ struct BlockDriverState { * parent node of this node. */ BlockDriverState *inherits_from; + + /* + * @backing and @file are some of @children or NULL. All these three fields + * (@file, @backing and @children) are modified only in + * bdrv_child_cb_attach() and bdrv_child_cb_detach(). + * + * See also comment in include/block/block.h, to learn how backing and file + * are connected with BdrvChildRole. + */ QLIST_HEAD(, BdrvChild) children; + BdrvChild *backing; + BdrvChild *file; + QLIST_HEAD(, BdrvChild) parents; QDict *options; diff --git a/tests/unit/test-bdrv-drain.c b/tests/unit/test-bdrv-drain.c index 84e09d7070..0eecf14310 100644 --- a/tests/unit/test-bdrv-drain.c +++ b/tests/unit/test-bdrv-drain.c @@ -1830,9 +1830,8 @@ static void test_drop_intermediate_poll(void) for (i = 0; i < 3; i++) { if (i) { /* Takes the reference to chain[i - 1] */ - chain[i]->backing = bdrv_attach_child(chain[i], chain[i - 1], - "chain", &chain_child_class, - BDRV_CHILD_COW, &error_abort); + bdrv_attach_child(chain[i], chain[i - 1], "chain", + &chain_child_class, BDRV_CHILD_COW, &error_abort); } } @@ -2050,9 +2049,8 @@ static void do_test_replace_child_mid_drain(int old_drain_count, new_child_bs->total_sectors = 1; bdrv_ref(old_child_bs); - parent_bs->backing = bdrv_attach_child(parent_bs, old_child_bs, "child", - &child_of_bds, BDRV_CHILD_COW, - &error_abort); + bdrv_attach_child(parent_bs, old_child_bs, "child", &child_of_bds, + BDRV_CHILD_COW, &error_abort); for (i = 0; i < old_drain_count; i++) { bdrv_drained_begin(old_child_bs); From c5c2174146a30423103f25a76e079b3c9c4e59b1 Mon Sep 17 00:00:00 2001 From: Vladimir Sementsov-Ogievskiy Date: Tue, 26 Jul 2022 23:11:33 +0300 Subject: [PATCH 257/705] block/snapshot: drop indirection around bdrv_snapshot_fallback_ptr Now the indirection is not actually used, we can safely reduce it to simple pointer. For consistency do a bit of refactoring to get rid of _ptr suffixes that become meaningless. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Hanna Reitz Message-Id: <20220726201134.924743-15-vsementsov@yandex-team.ru> Signed-off-by: Kevin Wolf --- block/snapshot.c | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/block/snapshot.c b/block/snapshot.c index f3971ac2bd..e22ac3eac6 100644 --- a/block/snapshot.c +++ b/block/snapshot.c @@ -151,34 +151,29 @@ bool bdrv_snapshot_find_by_id_and_name(BlockDriverState *bs, } /** - * Return a pointer to the child BDS pointer to which we can fall + * Return a pointer to child of given BDS to which we can fall * back if the given BDS does not support snapshots. * Return NULL if there is no BDS to (safely) fall back to. - * - * We need to return an indirect pointer because bdrv_snapshot_goto() - * has to modify the BdrvChild pointer. */ -static BdrvChild **bdrv_snapshot_fallback_ptr(BlockDriverState *bs) +static BdrvChild *bdrv_snapshot_fallback_child(BlockDriverState *bs) { - BdrvChild **fallback; - BdrvChild *child = bdrv_primary_child(bs); + BdrvChild *fallback = bdrv_primary_child(bs); + BdrvChild *child; /* We allow fallback only to primary child */ - if (!child) { + if (!fallback) { return NULL; } - fallback = (child == bs->file ? &bs->file : &bs->backing); - assert(*fallback == child); /* * Check that there are no other children that would need to be * snapshotted. If there are, it is not safe to fall back to - * *fallback. + * fallback. */ QLIST_FOREACH(child, &bs->children, next) { if (child->role & (BDRV_CHILD_DATA | BDRV_CHILD_METADATA | BDRV_CHILD_FILTERED) && - child != *fallback) + child != fallback) { return NULL; } @@ -189,8 +184,7 @@ static BdrvChild **bdrv_snapshot_fallback_ptr(BlockDriverState *bs) static BlockDriverState *bdrv_snapshot_fallback(BlockDriverState *bs) { - BdrvChild **child_ptr = bdrv_snapshot_fallback_ptr(bs); - return child_ptr ? (*child_ptr)->bs : NULL; + return child_bs(bdrv_snapshot_fallback_child(bs)); } int bdrv_can_snapshot(BlockDriverState *bs) @@ -237,7 +231,7 @@ int bdrv_snapshot_goto(BlockDriverState *bs, Error **errp) { BlockDriver *drv = bs->drv; - BdrvChild **fallback_ptr; + BdrvChild *fallback; int ret, open_ret; GLOBAL_STATE_CODE(); @@ -260,13 +254,13 @@ int bdrv_snapshot_goto(BlockDriverState *bs, return ret; } - fallback_ptr = bdrv_snapshot_fallback_ptr(bs); - if (fallback_ptr) { + fallback = bdrv_snapshot_fallback_child(bs); + if (fallback) { QDict *options; QDict *file_options; Error *local_err = NULL; - BlockDriverState *fallback_bs = (*fallback_ptr)->bs; - char *subqdict_prefix = g_strdup_printf("%s.", (*fallback_ptr)->name); + BlockDriverState *fallback_bs = fallback->bs; + char *subqdict_prefix = g_strdup_printf("%s.", fallback->name); options = qdict_clone_shallow(bs->options); @@ -277,8 +271,8 @@ int bdrv_snapshot_goto(BlockDriverState *bs, qobject_unref(file_options); g_free(subqdict_prefix); - /* Force .bdrv_open() below to re-attach fallback_bs on *fallback_ptr */ - qdict_put_str(options, (*fallback_ptr)->name, + /* Force .bdrv_open() below to re-attach fallback_bs on fallback */ + qdict_put_str(options, fallback->name, bdrv_get_node_name(fallback_bs)); /* Now close bs, apply the snapshot on fallback_bs, and re-open bs */ @@ -287,7 +281,7 @@ int bdrv_snapshot_goto(BlockDriverState *bs, } /* .bdrv_open() will re-attach it */ - bdrv_unref_child(bs, *fallback_ptr); + bdrv_unref_child(bs, fallback); ret = bdrv_snapshot_goto(fallback_bs, snapshot_id, errp); open_ret = drv->bdrv_open(bs, options, bs->open_flags, &local_err); From 57f08941d32a81e687d222294d33bdbfd75b5f44 Mon Sep 17 00:00:00 2001 From: Vladimir Sementsov-Ogievskiy Date: Tue, 26 Jul 2022 23:11:34 +0300 Subject: [PATCH 258/705] block: refactor bdrv_remove_file_or_backing_child to bdrv_remove_child Now the function can remove any child, so give it more common name. Drop assertions and drop bs argument which becomes unused. Function would be reused in a further commit. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Hanna Reitz Message-Id: <20220726201134.924743-16-vsementsov@yandex-team.ru> Signed-off-by: Kevin Wolf --- block.c | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/block.c b/block.c index ed11a421b0..2d74bfe665 100644 --- a/block.c +++ b/block.c @@ -92,9 +92,7 @@ static bool bdrv_recurse_has_child(BlockDriverState *bs, static void bdrv_replace_child_noperm(BdrvChild *child, BlockDriverState *new_bs); -static void bdrv_remove_file_or_backing_child(BlockDriverState *bs, - BdrvChild *child, - Transaction *tran); +static void bdrv_remove_child(BdrvChild *child, Transaction *tran); static void bdrv_remove_filter_or_cow_child(BlockDriverState *bs, Transaction *tran); @@ -3342,7 +3340,7 @@ static int bdrv_set_file_or_backing_noperm(BlockDriverState *parent_bs, if (child) { bdrv_unset_inherits_from(parent_bs, child, tran); - bdrv_remove_file_or_backing_child(parent_bs, child, tran); + bdrv_remove_child(child, tran); } if (!child_bs) { @@ -5023,26 +5021,19 @@ static bool should_update_child(BdrvChild *c, BlockDriverState *to) return ret; } -static void bdrv_remove_filter_or_cow_child_commit(void *opaque) +static void bdrv_remove_child_commit(void *opaque) { GLOBAL_STATE_CODE(); bdrv_child_free(opaque); } -static TransactionActionDrv bdrv_remove_filter_or_cow_child_drv = { - .commit = bdrv_remove_filter_or_cow_child_commit, +static TransactionActionDrv bdrv_remove_child_drv = { + .commit = bdrv_remove_child_commit, }; -/* - * A function to remove backing or file child of @bs. - * Function doesn't update permissions, caller is responsible for this. - */ -static void bdrv_remove_file_or_backing_child(BlockDriverState *bs, - BdrvChild *child, - Transaction *tran) +/* Function doesn't update permissions, caller is responsible for this. */ +static void bdrv_remove_child(BdrvChild *child, Transaction *tran) { - assert(child == bs->backing || child == bs->file); - if (!child) { return; } @@ -5051,7 +5042,7 @@ static void bdrv_remove_file_or_backing_child(BlockDriverState *bs, bdrv_replace_child_tran(child, NULL, tran); } - tran_add(tran, &bdrv_remove_filter_or_cow_child_drv, child); + tran_add(tran, &bdrv_remove_child_drv, child); } /* @@ -5062,7 +5053,7 @@ static void bdrv_remove_file_or_backing_child(BlockDriverState *bs, static void bdrv_remove_filter_or_cow_child(BlockDriverState *bs, Transaction *tran) { - bdrv_remove_file_or_backing_child(bs, bdrv_filter_or_cow_child(bs), tran); + bdrv_remove_child(bdrv_filter_or_cow_child(bs), tran); } static int bdrv_replace_node_noperm(BlockDriverState *from, From 7f898610f6782d6303c14c3c180b88ce1b303754 Mon Sep 17 00:00:00 2001 From: Emanuele Giuseppe Esposito Date: Tue, 25 Oct 2022 04:49:43 -0400 Subject: [PATCH 259/705] block.c: assert bs->aio_context is written under BQL and drains Also here ->aio_context is read by I/O threads and written under BQL. Signed-off-by: Emanuele Giuseppe Esposito Reviewed-by: Kevin Wolf Reviewed-by: Hanna Reitz Message-Id: <20221025084952.2139888-2-eesposit@redhat.com> Signed-off-by: Kevin Wolf --- block.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/block.c b/block.c index 2d74bfe665..4d727aa38c 100644 --- a/block.c +++ b/block.c @@ -7153,6 +7153,7 @@ static void bdrv_detach_aio_context(BlockDriverState *bs) if (bs->quiesce_counter) { aio_enable_external(bs->aio_context); } + assert_bdrv_graph_writable(bs); bs->aio_context = NULL; } @@ -7166,6 +7167,7 @@ static void bdrv_attach_aio_context(BlockDriverState *bs, aio_disable_external(new_context); } + assert_bdrv_graph_writable(bs); bs->aio_context = new_context; if (bs->drv && bs->drv->bdrv_attach_aio_context) { From 7e8c182fb5e5950a52623b0d463c2f1fcd15a80a Mon Sep 17 00:00:00 2001 From: Emanuele Giuseppe Esposito Date: Tue, 25 Oct 2022 04:49:44 -0400 Subject: [PATCH 260/705] block: use transactions as a replacement of ->{can_}set_aio_context() Simplify the way the aiocontext can be changed in a BDS graph. There are currently two problems in bdrv_try_set_aio_context: - There is a confusion of AioContext locks taken and released, because we assume that old aiocontext is always taken and new one is taken inside. - It doesn't look very safe to call bdrv_drained_begin while some nodes have already switched to the new aiocontext and others haven't. This could be especially dangerous because bdrv_drained_begin polls, so something else could be executed while graph is in an inconsistent state. Additional minor nitpick: can_set and set_ callbacks both traverse the graph, both using the ignored list of visited nodes in a different way. Therefore, get rid of all of this and introduce a new callback, change_aio_context, that uses transactions to efficiently, cleanly and most importantly safely change the aiocontext of a graph. This new callback is a "merge" of the two previous ones: - Just like can_set_aio_context, recursively traverses the graph. Marks all nodes that are visited using a GList, and checks if they *could* change the aio_context. - For each node that passes the above check, drain it and add a new transaction that implements a callback that effectively changes the aiocontext. - Once done, the recursive function returns if *all* nodes can change the AioContext. If so, commit the above transactions. Regardless of the outcome, call transaction.clean() to undo all drains done in the recursion. - The transaction list is scanned only after all nodes are being drained, so we are sure that they all are in the same context, and then we switch their AioContext, concluding the drain only after all nodes switched to the new AioContext. In this way we make sure that bdrv_drained_begin() is always called under the old AioContext, and bdrv_drained_end() under the new one. - Because of the above, we don't need to release and re-acquire the old AioContext every time, as everything is done once (and not per-node drain and aiocontext change). Note that the "change" API is not yet invoked anywhere. Signed-off-by: Emanuele Giuseppe Esposito Message-Id: <20221025084952.2139888-3-eesposit@redhat.com> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- block.c | 220 ++++++++++++++++++++++++++++- include/block/block-global-state.h | 6 + include/block/block_int-common.h | 3 + 3 files changed, 228 insertions(+), 1 deletion(-) diff --git a/block.c b/block.c index 4d727aa38c..38e5d831ca 100644 --- a/block.c +++ b/block.c @@ -104,6 +104,10 @@ static void bdrv_reopen_abort(BDRVReopenState *reopen_state); static bool bdrv_backing_overridden(BlockDriverState *bs); +static bool bdrv_change_aio_context(BlockDriverState *bs, AioContext *ctx, + GSList **visited, Transaction *tran, + Error **errp); + /* If non-zero, use only whitelisted block drivers */ static int use_bdrv_whitelist; @@ -7196,7 +7200,7 @@ static void bdrv_attach_aio_context(BlockDriverState *bs, * must not own the AioContext lock for new_context (unless new_context is the * same as the current context of bs). * - * @ignore will accumulate all visited BdrvChild object. The caller is + * @ignore will accumulate all visited BdrvChild objects. The caller is * responsible for freeing the list afterwards. */ void bdrv_set_aio_context_ignore(BlockDriverState *bs, @@ -7305,6 +7309,38 @@ static bool bdrv_parent_can_set_aio_context(BdrvChild *c, AioContext *ctx, return true; } +typedef struct BdrvStateSetAioContext { + AioContext *new_ctx; + BlockDriverState *bs; +} BdrvStateSetAioContext; + +static bool bdrv_parent_change_aio_context(BdrvChild *c, AioContext *ctx, + GSList **visited, Transaction *tran, + Error **errp) +{ + GLOBAL_STATE_CODE(); + if (g_slist_find(*visited, c)) { + return true; + } + *visited = g_slist_prepend(*visited, c); + + /* + * A BdrvChildClass that doesn't handle AioContext changes cannot + * tolerate any AioContext changes + */ + if (!c->klass->change_aio_ctx) { + char *user = bdrv_child_user_desc(c); + error_setg(errp, "Changing iothreads is not supported by %s", user); + g_free(user); + return false; + } + if (!c->klass->change_aio_ctx(c, ctx, visited, tran, errp)) { + assert(!errp || *errp); + return false; + } + return true; +} + bool bdrv_child_can_set_aio_context(BdrvChild *c, AioContext *ctx, GSList **ignore, Error **errp) { @@ -7316,6 +7352,18 @@ bool bdrv_child_can_set_aio_context(BdrvChild *c, AioContext *ctx, return bdrv_can_set_aio_context(c->bs, ctx, ignore, errp); } +bool bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx, + GSList **visited, Transaction *tran, + Error **errp) +{ + GLOBAL_STATE_CODE(); + if (g_slist_find(*visited, c)) { + return true; + } + *visited = g_slist_prepend(*visited, c); + return bdrv_change_aio_context(c->bs, ctx, visited, tran, errp); +} + /* @ignore will accumulate all visited BdrvChild object. The caller is * responsible for freeing the list afterwards. */ bool bdrv_can_set_aio_context(BlockDriverState *bs, AioContext *ctx, @@ -7343,6 +7391,98 @@ bool bdrv_can_set_aio_context(BlockDriverState *bs, AioContext *ctx, return true; } +static void bdrv_set_aio_context_clean(void *opaque) +{ + BdrvStateSetAioContext *state = (BdrvStateSetAioContext *) opaque; + BlockDriverState *bs = (BlockDriverState *) state->bs; + + /* Paired with bdrv_drained_begin in bdrv_change_aio_context() */ + bdrv_drained_end(bs); + + g_free(state); +} + +static void bdrv_set_aio_context_commit(void *opaque) +{ + BdrvStateSetAioContext *state = (BdrvStateSetAioContext *) opaque; + BlockDriverState *bs = (BlockDriverState *) state->bs; + AioContext *new_context = state->new_ctx; + AioContext *old_context = bdrv_get_aio_context(bs); + assert_bdrv_graph_writable(bs); + + /* + * Take the old AioContex when detaching it from bs. + * At this point, new_context lock is already acquired, and we are now + * also taking old_context. This is safe as long as bdrv_detach_aio_context + * does not call AIO_POLL_WHILE(). + */ + if (old_context != qemu_get_aio_context()) { + aio_context_acquire(old_context); + } + bdrv_detach_aio_context(bs); + if (old_context != qemu_get_aio_context()) { + aio_context_release(old_context); + } + bdrv_attach_aio_context(bs, new_context); +} + +static TransactionActionDrv set_aio_context = { + .commit = bdrv_set_aio_context_commit, + .clean = bdrv_set_aio_context_clean, +}; + +/* + * Changes the AioContext used for fd handlers, timers, and BHs by this + * BlockDriverState and all its children and parents. + * + * Must be called from the main AioContext. + * + * The caller must own the AioContext lock for the old AioContext of bs, but it + * must not own the AioContext lock for new_context (unless new_context is the + * same as the current context of bs). + * + * @visited will accumulate all visited BdrvChild objects. The caller is + * responsible for freeing the list afterwards. + */ +static bool bdrv_change_aio_context(BlockDriverState *bs, AioContext *ctx, + GSList **visited, Transaction *tran, + Error **errp) +{ + BdrvChild *c; + BdrvStateSetAioContext *state; + + GLOBAL_STATE_CODE(); + + if (bdrv_get_aio_context(bs) == ctx) { + return true; + } + + QLIST_FOREACH(c, &bs->parents, next_parent) { + if (!bdrv_parent_change_aio_context(c, ctx, visited, tran, errp)) { + return false; + } + } + + QLIST_FOREACH(c, &bs->children, next) { + if (!bdrv_child_change_aio_context(c, ctx, visited, tran, errp)) { + return false; + } + } + + state = g_new(BdrvStateSetAioContext, 1); + *state = (BdrvStateSetAioContext) { + .new_ctx = ctx, + .bs = bs, + }; + + /* Paired with bdrv_drained_end in bdrv_set_aio_context_clean() */ + bdrv_drained_begin(bs); + + tran_add(tran, &set_aio_context, state); + + return true; +} + int bdrv_child_try_set_aio_context(BlockDriverState *bs, AioContext *ctx, BdrvChild *ignore_child, Error **errp) { @@ -7366,6 +7506,84 @@ int bdrv_child_try_set_aio_context(BlockDriverState *bs, AioContext *ctx, return 0; } +/* + * Change bs's and recursively all of its parents' and children's AioContext + * to the given new context, returning an error if that isn't possible. + * + * If ignore_child is not NULL, that child (and its subgraph) will not + * be touched. + * + * This function still requires the caller to take the bs current + * AioContext lock, otherwise draining will fail since AIO_WAIT_WHILE + * assumes the lock is always held if bs is in another AioContext. + * For the same reason, it temporarily also holds the new AioContext, since + * bdrv_drained_end calls BDRV_POLL_WHILE that assumes the lock is taken too. + * Therefore the new AioContext lock must not be taken by the caller. + */ +int bdrv_child_try_change_aio_context(BlockDriverState *bs, AioContext *ctx, + BdrvChild *ignore_child, Error **errp) +{ + Transaction *tran; + GSList *visited; + int ret; + AioContext *old_context = bdrv_get_aio_context(bs); + GLOBAL_STATE_CODE(); + + /* + * Recursion phase: go through all nodes of the graph. + * Take care of checking that all nodes support changing AioContext + * and drain them, builing a linear list of callbacks to run if everything + * is successful (the transaction itself). + */ + tran = tran_new(); + visited = ignore_child ? g_slist_prepend(NULL, ignore_child) : NULL; + ret = bdrv_change_aio_context(bs, ctx, &visited, tran, errp); + g_slist_free(visited); + + /* + * Linear phase: go through all callbacks collected in the transaction. + * Run all callbacks collected in the recursion to switch all nodes + * AioContext lock (transaction commit), or undo all changes done in the + * recursion (transaction abort). + */ + + if (!ret) { + /* Just run clean() callbacks. No AioContext changed. */ + tran_abort(tran); + return -EPERM; + } + + /* + * Release old AioContext, it won't be needed anymore, as all + * bdrv_drained_begin() have been called already. + */ + if (qemu_get_aio_context() != old_context) { + aio_context_release(old_context); + } + + /* + * Acquire new AioContext since bdrv_drained_end() is going to be called + * after we switched all nodes in the new AioContext, and the function + * assumes that the lock of the bs is always taken. + */ + if (qemu_get_aio_context() != ctx) { + aio_context_acquire(ctx); + } + + tran_commit(tran); + + if (qemu_get_aio_context() != ctx) { + aio_context_release(ctx); + } + + /* Re-acquire the old AioContext, since the caller takes and releases it. */ + if (qemu_get_aio_context() != old_context) { + aio_context_acquire(old_context); + } + + return 0; +} + int bdrv_try_set_aio_context(BlockDriverState *bs, AioContext *ctx, Error **errp) { diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h index 29a38d7e18..7b0095b419 100644 --- a/include/block/block-global-state.h +++ b/include/block/block-global-state.h @@ -232,6 +232,12 @@ bool bdrv_can_set_aio_context(BlockDriverState *bs, AioContext *ctx, GSList **ignore, Error **errp); AioContext *bdrv_child_get_parent_aio_context(BdrvChild *c); +bool bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx, + GSList **visited, Transaction *tran, + Error **errp); +int bdrv_child_try_change_aio_context(BlockDriverState *bs, AioContext *ctx, + BdrvChild *ignore_child, Error **errp); + int bdrv_probe_blocksizes(BlockDriverState *bs, BlockSizes *bsz); int bdrv_probe_geometry(BlockDriverState *bs, HDGeometry *geo); diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h index 1f300ee7f6..9067a99249 100644 --- a/include/block/block_int-common.h +++ b/include/block/block_int-common.h @@ -910,6 +910,9 @@ struct BdrvChildClass { GSList **ignore, Error **errp); void (*set_aio_ctx)(BdrvChild *child, AioContext *ctx, GSList **ignore); + bool (*change_aio_ctx)(BdrvChild *child, AioContext *ctx, + GSList **visited, Transaction *tran, Error **errp); + AioContext *(*get_parent_aio_context)(BdrvChild *child); /* From e08cc001d502958040565636e19a42c06e1ae8b7 Mon Sep 17 00:00:00 2001 From: Emanuele Giuseppe Esposito Date: Tue, 25 Oct 2022 04:49:45 -0400 Subject: [PATCH 261/705] bdrv_change_aio_context: use hash table instead of list of visited nodes Minor performance improvement, but given that we have hash tables available, avoid iterating in the visited nodes list every time just to check if a node has been already visited. The data structure is not actually a proper hash map, but an hash set, as we are just adding nodes and not key,value pairs. Suggested-by: Hanna Reitz Signed-off-by: Emanuele Giuseppe Esposito Reviewed-by: Kevin Wolf Message-Id: <20221025084952.2139888-4-eesposit@redhat.com> Signed-off-by: Kevin Wolf --- block.c | 28 ++++++++++++++++------------ include/block/block-global-state.h | 2 +- include/block/block_int-common.h | 3 ++- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/block.c b/block.c index 38e5d831ca..59319d9b0f 100644 --- a/block.c +++ b/block.c @@ -105,7 +105,7 @@ static void bdrv_reopen_abort(BDRVReopenState *reopen_state); static bool bdrv_backing_overridden(BlockDriverState *bs); static bool bdrv_change_aio_context(BlockDriverState *bs, AioContext *ctx, - GSList **visited, Transaction *tran, + GHashTable *visited, Transaction *tran, Error **errp); /* If non-zero, use only whitelisted block drivers */ @@ -7315,14 +7315,15 @@ typedef struct BdrvStateSetAioContext { } BdrvStateSetAioContext; static bool bdrv_parent_change_aio_context(BdrvChild *c, AioContext *ctx, - GSList **visited, Transaction *tran, + GHashTable *visited, + Transaction *tran, Error **errp) { GLOBAL_STATE_CODE(); - if (g_slist_find(*visited, c)) { + if (g_hash_table_contains(visited, c)) { return true; } - *visited = g_slist_prepend(*visited, c); + g_hash_table_add(visited, c); /* * A BdrvChildClass that doesn't handle AioContext changes cannot @@ -7353,14 +7354,14 @@ bool bdrv_child_can_set_aio_context(BdrvChild *c, AioContext *ctx, } bool bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx, - GSList **visited, Transaction *tran, + GHashTable *visited, Transaction *tran, Error **errp) { GLOBAL_STATE_CODE(); - if (g_slist_find(*visited, c)) { + if (g_hash_table_contains(visited, c)) { return true; } - *visited = g_slist_prepend(*visited, c); + g_hash_table_add(visited, c); return bdrv_change_aio_context(c->bs, ctx, visited, tran, errp); } @@ -7445,7 +7446,7 @@ static TransactionActionDrv set_aio_context = { * responsible for freeing the list afterwards. */ static bool bdrv_change_aio_context(BlockDriverState *bs, AioContext *ctx, - GSList **visited, Transaction *tran, + GHashTable *visited, Transaction *tran, Error **errp) { BdrvChild *c; @@ -7524,7 +7525,7 @@ int bdrv_child_try_change_aio_context(BlockDriverState *bs, AioContext *ctx, BdrvChild *ignore_child, Error **errp) { Transaction *tran; - GSList *visited; + GHashTable *visited; int ret; AioContext *old_context = bdrv_get_aio_context(bs); GLOBAL_STATE_CODE(); @@ -7536,9 +7537,12 @@ int bdrv_child_try_change_aio_context(BlockDriverState *bs, AioContext *ctx, * is successful (the transaction itself). */ tran = tran_new(); - visited = ignore_child ? g_slist_prepend(NULL, ignore_child) : NULL; - ret = bdrv_change_aio_context(bs, ctx, &visited, tran, errp); - g_slist_free(visited); + visited = g_hash_table_new(NULL, NULL); + if (ignore_child) { + g_hash_table_add(visited, ignore_child); + } + ret = bdrv_change_aio_context(bs, ctx, visited, tran, errp); + g_hash_table_destroy(visited); /* * Linear phase: go through all callbacks collected in the transaction. diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h index 7b0095b419..e7372ec541 100644 --- a/include/block/block-global-state.h +++ b/include/block/block-global-state.h @@ -233,7 +233,7 @@ bool bdrv_can_set_aio_context(BlockDriverState *bs, AioContext *ctx, AioContext *bdrv_child_get_parent_aio_context(BdrvChild *c); bool bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx, - GSList **visited, Transaction *tran, + GHashTable *visited, Transaction *tran, Error **errp); int bdrv_child_try_change_aio_context(BlockDriverState *bs, AioContext *ctx, BdrvChild *ignore_child, Error **errp); diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h index 9067a99249..7ccbbdae05 100644 --- a/include/block/block_int-common.h +++ b/include/block/block_int-common.h @@ -911,7 +911,8 @@ struct BdrvChildClass { void (*set_aio_ctx)(BdrvChild *child, AioContext *ctx, GSList **ignore); bool (*change_aio_ctx)(BdrvChild *child, AioContext *ctx, - GSList **visited, Transaction *tran, Error **errp); + GHashTable *visited, Transaction *tran, + Error **errp); AioContext *(*get_parent_aio_context)(BdrvChild *child); From 3428b100dc65dbce3e3b646df471a8fb2a5df556 Mon Sep 17 00:00:00 2001 From: Emanuele Giuseppe Esposito Date: Tue, 25 Oct 2022 04:49:46 -0400 Subject: [PATCH 262/705] blockjob: implement .change_aio_ctx in child_job child_job_change_aio_ctx() is very similar to child_job_can_set_aio_ctx(), but it implements a new transaction so that if all check pass, the new transaction's .commit() will take care of changin the BlockJob AioContext. child_job_set_aio_ctx_commit() is similar to child_job_set_aio_ctx(), but it doesn't need to invoke the recursion, as this is already taken care by child_job_change_aio_ctx(). Note: bdrv_child_try_change_aio_context() is not called by anyone at this point. Signed-off-by: Emanuele Giuseppe Esposito Reviewed-by: Hanna Reitz Reviewed-by: Kevin Wolf Message-Id: <20221025084952.2139888-5-eesposit@redhat.com> Signed-off-by: Kevin Wolf --- blockjob.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/blockjob.c b/blockjob.c index bdf20a0e35..5a783b75c6 100644 --- a/blockjob.c +++ b/blockjob.c @@ -126,6 +126,50 @@ static void child_job_drained_end(BdrvChild *c, int *drained_end_counter) job_resume(&job->job); } +typedef struct BdrvStateChildJobContext { + AioContext *new_ctx; + BlockJob *job; +} BdrvStateChildJobContext; + +static void child_job_set_aio_ctx_commit(void *opaque) +{ + BdrvStateChildJobContext *s = opaque; + BlockJob *job = s->job; + + job_set_aio_context(&job->job, s->new_ctx); +} + +static TransactionActionDrv change_child_job_context = { + .commit = child_job_set_aio_ctx_commit, + .clean = g_free, +}; + +static bool child_job_change_aio_ctx(BdrvChild *c, AioContext *ctx, + GHashTable *visited, Transaction *tran, + Error **errp) +{ + BlockJob *job = c->opaque; + BdrvStateChildJobContext *s; + GSList *l; + + for (l = job->nodes; l; l = l->next) { + BdrvChild *sibling = l->data; + if (!bdrv_child_change_aio_context(sibling, ctx, visited, + tran, errp)) { + return false; + } + } + + s = g_new(BdrvStateChildJobContext, 1); + *s = (BdrvStateChildJobContext) { + .new_ctx = ctx, + .job = job, + }; + + tran_add(tran, &change_child_job_context, s); + return true; +} + static bool child_job_can_set_aio_ctx(BdrvChild *c, AioContext *ctx, GSList **ignore, Error **errp) { @@ -174,6 +218,7 @@ static const BdrvChildClass child_job = { .drained_end = child_job_drained_end, .can_set_aio_ctx = child_job_can_set_aio_ctx, .set_aio_ctx = child_job_set_aio_ctx, + .change_aio_ctx = child_job_change_aio_ctx, .stay_at_node = true, .get_parent_aio_context = child_job_get_parent_aio_context, }; From 27633e740e784709f256f6ee70f2dd0b5a87279f Mon Sep 17 00:00:00 2001 From: Emanuele Giuseppe Esposito Date: Tue, 25 Oct 2022 04:49:47 -0400 Subject: [PATCH 263/705] block: implement .change_aio_ctx in child_of_bds bdrv_child_cb_change_aio_ctx() is identical to bdrv_child_cb_can_set_aio_ctx(), as we only need to recursively go on the parent bs. Note: bdrv_child_try_change_aio_context() is not called by anyone at this point. Signed-off-by: Emanuele Giuseppe Esposito Reviewed-by: Hanna Reitz Reviewed-by: Kevin Wolf Message-Id: <20221025084952.2139888-6-eesposit@redhat.com> Signed-off-by: Kevin Wolf --- block.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/block.c b/block.c index 59319d9b0f..3386457083 100644 --- a/block.c +++ b/block.c @@ -1242,6 +1242,14 @@ static int bdrv_child_cb_inactivate(BdrvChild *child) return 0; } +static bool bdrv_child_cb_change_aio_ctx(BdrvChild *child, AioContext *ctx, + GHashTable *visited, Transaction *tran, + Error **errp) +{ + BlockDriverState *bs = child->opaque; + return bdrv_change_aio_context(bs, ctx, visited, tran, errp); +} + static bool bdrv_child_cb_can_set_aio_ctx(BdrvChild *child, AioContext *ctx, GSList **ignore, Error **errp) { @@ -1534,6 +1542,7 @@ const BdrvChildClass child_of_bds = { .inactivate = bdrv_child_cb_inactivate, .can_set_aio_ctx = bdrv_child_cb_can_set_aio_ctx, .set_aio_ctx = bdrv_child_cb_set_aio_ctx, + .change_aio_ctx = bdrv_child_cb_change_aio_ctx, .update_filename = bdrv_child_cb_update_filename, .get_parent_aio_context = child_of_bds_get_parent_aio_context, }; From 33949396216fa16a97f5b33877b50d5830f21aad Mon Sep 17 00:00:00 2001 From: Emanuele Giuseppe Esposito Date: Tue, 25 Oct 2022 04:49:48 -0400 Subject: [PATCH 264/705] block-backend: implement .change_aio_ctx in child_root blk_root_change_aio_ctx() is very similar to blk_root_can_set_aio_ctx(), but implements a new transaction so that if all check pass, the new transaction's .commit will take care of changing the BlockBackend AioContext. blk_root_set_aio_ctx_commit() is the same as blk_root_set_aio_ctx(). Note: bdrv_child_try_change_aio_context() is not called by anyone at this point. Signed-off-by: Emanuele Giuseppe Esposito Reviewed-by: Kevin Wolf Message-Id: <20221025084952.2139888-7-eesposit@redhat.com> Signed-off-by: Kevin Wolf --- block/block-backend.c | 52 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/block/block-backend.c b/block/block-backend.c index aa4adf06ae..d87ae435a7 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -138,6 +138,9 @@ static bool blk_root_can_set_aio_ctx(BdrvChild *child, AioContext *ctx, GSList **ignore, Error **errp); static void blk_root_set_aio_ctx(BdrvChild *child, AioContext *ctx, GSList **ignore); +static bool blk_root_change_aio_ctx(BdrvChild *child, AioContext *ctx, + GHashTable *visited, Transaction *tran, + Error **errp); static char *blk_root_get_parent_desc(BdrvChild *child) { @@ -336,6 +339,7 @@ static const BdrvChildClass child_root = { .can_set_aio_ctx = blk_root_can_set_aio_ctx, .set_aio_ctx = blk_root_set_aio_ctx, + .change_aio_ctx = blk_root_change_aio_ctx, .get_parent_aio_context = blk_root_get_parent_aio_context, }; @@ -2177,6 +2181,54 @@ int blk_set_aio_context(BlockBackend *blk, AioContext *new_context, return blk_do_set_aio_context(blk, new_context, true, errp); } +typedef struct BdrvStateBlkRootContext { + AioContext *new_ctx; + BlockBackend *blk; +} BdrvStateBlkRootContext; + +static void blk_root_set_aio_ctx_commit(void *opaque) +{ + BdrvStateBlkRootContext *s = opaque; + BlockBackend *blk = s->blk; + + blk_do_set_aio_context(blk, s->new_ctx, false, &error_abort); +} + +static TransactionActionDrv set_blk_root_context = { + .commit = blk_root_set_aio_ctx_commit, + .clean = g_free, +}; + +static bool blk_root_change_aio_ctx(BdrvChild *child, AioContext *ctx, + GHashTable *visited, Transaction *tran, + Error **errp) +{ + BlockBackend *blk = child->opaque; + BdrvStateBlkRootContext *s; + + if (!blk->allow_aio_context_change) { + /* + * Manually created BlockBackends (those with a name) that are not + * attached to anything can change their AioContext without updating + * their user; return an error for others. + */ + if (!blk->name || blk->dev) { + /* TODO Add BB name/QOM path */ + error_setg(errp, "Cannot change iothread of active block backend"); + return false; + } + } + + s = g_new(BdrvStateBlkRootContext, 1); + *s = (BdrvStateBlkRootContext) { + .new_ctx = ctx, + .blk = blk, + }; + + tran_add(tran, &set_blk_root_context, s); + return true; +} + static bool blk_root_can_set_aio_ctx(BdrvChild *child, AioContext *ctx, GSList **ignore, Error **errp) { From f8be48adf08641f43dfb34b6abf50f9bc21fc250 Mon Sep 17 00:00:00 2001 From: Emanuele Giuseppe Esposito Date: Tue, 25 Oct 2022 04:49:49 -0400 Subject: [PATCH 265/705] block: use the new _change_ API instead of _can_set_ and _set_ Replace all direct usage of ->can_set_aio_ctx and ->set_aio_ctx, and call bdrv_child_try_change_aio_context() in bdrv_try_set_aio_context(), the main function called through the whole block layer. From this point onwards, ->can_set_aio_ctx and ->set_aio_ctx won't be used anymore. Signed-off-by: Emanuele Giuseppe Esposito Reviewed-by: Kevin Wolf Message-Id: <20221025084952.2139888-8-eesposit@redhat.com> Signed-off-by: Kevin Wolf --- block.c | 44 ++++++++++++++++++++++++------------------- block/block-backend.c | 8 ++++++-- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/block.c b/block.c index 3386457083..c35249e8c3 100644 --- a/block.c +++ b/block.c @@ -2924,17 +2924,21 @@ static void bdrv_attach_child_common_abort(void *opaque) } if (bdrv_child_get_parent_aio_context(s->child) != s->old_parent_ctx) { - GSList *ignore; + Transaction *tran; + GHashTable *visited; + bool ret; - /* No need to ignore `child`, because it has been detached already */ - ignore = NULL; - s->child->klass->can_set_aio_ctx(s->child, s->old_parent_ctx, &ignore, - &error_abort); - g_slist_free(ignore); + tran = tran_new(); - ignore = NULL; - s->child->klass->set_aio_ctx(s->child, s->old_parent_ctx, &ignore); - g_slist_free(ignore); + /* No need to visit `child`, because it has been detached already */ + visited = g_hash_table_new(NULL, NULL); + ret = s->child->klass->change_aio_ctx(s->child, s->old_parent_ctx, + visited, tran, &error_abort); + g_hash_table_destroy(visited); + + /* transaction is supposed to always succeed */ + assert(ret == true); + tran_commit(tran); } bdrv_unref(bs); @@ -2989,18 +2993,20 @@ static BdrvChild *bdrv_attach_child_common(BlockDriverState *child_bs, Error *local_err = NULL; int ret = bdrv_try_set_aio_context(child_bs, parent_ctx, &local_err); - if (ret < 0 && child_class->can_set_aio_ctx) { - GSList *ignore = g_slist_prepend(NULL, new_child); - if (child_class->can_set_aio_ctx(new_child, child_ctx, &ignore, - NULL)) - { + if (ret < 0 && child_class->change_aio_ctx) { + Transaction *tran = tran_new(); + GHashTable *visited = g_hash_table_new(NULL, NULL); + bool ret_child; + + g_hash_table_add(visited, new_child); + ret_child = child_class->change_aio_ctx(new_child, child_ctx, + visited, tran, NULL); + if (ret_child == true) { error_free(local_err); ret = 0; - g_slist_free(ignore); - ignore = g_slist_prepend(NULL, new_child); - child_class->set_aio_ctx(new_child, child_ctx, &ignore); } - g_slist_free(ignore); + tran_finalize(tran, ret_child == true ? 0 : -1); + g_hash_table_destroy(visited); } if (ret < 0) { @@ -7601,7 +7607,7 @@ int bdrv_try_set_aio_context(BlockDriverState *bs, AioContext *ctx, Error **errp) { GLOBAL_STATE_CODE(); - return bdrv_child_try_set_aio_context(bs, ctx, NULL, errp); + return bdrv_child_try_change_aio_context(bs, ctx, NULL, errp); } void bdrv_add_aio_context_notifier(BlockDriverState *bs, diff --git a/block/block-backend.c b/block/block-backend.c index d87ae435a7..ff417dbff9 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -2153,8 +2153,12 @@ static int blk_do_set_aio_context(BlockBackend *blk, AioContext *new_context, bdrv_ref(bs); if (update_root_node) { - ret = bdrv_child_try_set_aio_context(bs, new_context, blk->root, - errp); + /* + * update_root_node MUST be false for blk_root_set_aio_ctx_commit(), + * as we are already in the commit function of a transaction. + */ + ret = bdrv_child_try_change_aio_context(bs, new_context, blk->root, + errp); if (ret < 0) { bdrv_unref(bs); return ret; From d2aafbb68a0390b8166fbf62c572b306f7bf02ce Mon Sep 17 00:00:00 2001 From: Emanuele Giuseppe Esposito Date: Tue, 25 Oct 2022 04:49:50 -0400 Subject: [PATCH 266/705] block: remove all unused ->can_set_aio_ctx and ->set_aio_ctx callbacks Together with all _can_set_ and _set_ APIs, as they are not needed anymore. Signed-off-by: Emanuele Giuseppe Esposito Reviewed-by: Kevin Wolf Message-Id: <20221025084952.2139888-9-eesposit@redhat.com> Signed-off-by: Kevin Wolf --- block.c | 196 ----------------------------- block/block-backend.c | 33 ----- blockjob.c | 35 ------ include/block/block-global-state.h | 9 -- include/block/block_int-common.h | 4 - 5 files changed, 277 deletions(-) diff --git a/block.c b/block.c index c35249e8c3..353240eecd 100644 --- a/block.c +++ b/block.c @@ -1250,20 +1250,6 @@ static bool bdrv_child_cb_change_aio_ctx(BdrvChild *child, AioContext *ctx, return bdrv_change_aio_context(bs, ctx, visited, tran, errp); } -static bool bdrv_child_cb_can_set_aio_ctx(BdrvChild *child, AioContext *ctx, - GSList **ignore, Error **errp) -{ - BlockDriverState *bs = child->opaque; - return bdrv_can_set_aio_context(bs, ctx, ignore, errp); -} - -static void bdrv_child_cb_set_aio_ctx(BdrvChild *child, AioContext *ctx, - GSList **ignore) -{ - BlockDriverState *bs = child->opaque; - return bdrv_set_aio_context_ignore(bs, ctx, ignore); -} - /* * Returns the options and flags that a temporary snapshot should get, based on * the originally requested flags (the originally requested image will have @@ -1540,8 +1526,6 @@ const BdrvChildClass child_of_bds = { .attach = bdrv_child_cb_attach, .detach = bdrv_child_cb_detach, .inactivate = bdrv_child_cb_inactivate, - .can_set_aio_ctx = bdrv_child_cb_can_set_aio_ctx, - .set_aio_ctx = bdrv_child_cb_set_aio_ctx, .change_aio_ctx = bdrv_child_cb_change_aio_ctx, .update_filename = bdrv_child_cb_update_filename, .get_parent_aio_context = child_of_bds_get_parent_aio_context, @@ -7205,125 +7189,6 @@ static void bdrv_attach_aio_context(BlockDriverState *bs, bs->walking_aio_notifiers = false; } -/* - * Changes the AioContext used for fd handlers, timers, and BHs by this - * BlockDriverState and all its children and parents. - * - * Must be called from the main AioContext. - * - * The caller must own the AioContext lock for the old AioContext of bs, but it - * must not own the AioContext lock for new_context (unless new_context is the - * same as the current context of bs). - * - * @ignore will accumulate all visited BdrvChild objects. The caller is - * responsible for freeing the list afterwards. - */ -void bdrv_set_aio_context_ignore(BlockDriverState *bs, - AioContext *new_context, GSList **ignore) -{ - AioContext *old_context = bdrv_get_aio_context(bs); - GSList *children_to_process = NULL; - GSList *parents_to_process = NULL; - GSList *entry; - BdrvChild *child, *parent; - - g_assert(qemu_get_current_aio_context() == qemu_get_aio_context()); - GLOBAL_STATE_CODE(); - - if (old_context == new_context) { - return; - } - - bdrv_drained_begin(bs); - - QLIST_FOREACH(child, &bs->children, next) { - if (g_slist_find(*ignore, child)) { - continue; - } - *ignore = g_slist_prepend(*ignore, child); - children_to_process = g_slist_prepend(children_to_process, child); - } - - QLIST_FOREACH(parent, &bs->parents, next_parent) { - if (g_slist_find(*ignore, parent)) { - continue; - } - *ignore = g_slist_prepend(*ignore, parent); - parents_to_process = g_slist_prepend(parents_to_process, parent); - } - - for (entry = children_to_process; - entry != NULL; - entry = g_slist_next(entry)) { - child = entry->data; - bdrv_set_aio_context_ignore(child->bs, new_context, ignore); - } - g_slist_free(children_to_process); - - for (entry = parents_to_process; - entry != NULL; - entry = g_slist_next(entry)) { - parent = entry->data; - assert(parent->klass->set_aio_ctx); - parent->klass->set_aio_ctx(parent, new_context, ignore); - } - g_slist_free(parents_to_process); - - bdrv_detach_aio_context(bs); - - /* Acquire the new context, if necessary */ - if (qemu_get_aio_context() != new_context) { - aio_context_acquire(new_context); - } - - bdrv_attach_aio_context(bs, new_context); - - /* - * If this function was recursively called from - * bdrv_set_aio_context_ignore(), there may be nodes in the - * subtree that have not yet been moved to the new AioContext. - * Release the old one so bdrv_drained_end() can poll them. - */ - if (qemu_get_aio_context() != old_context) { - aio_context_release(old_context); - } - - bdrv_drained_end(bs); - - if (qemu_get_aio_context() != old_context) { - aio_context_acquire(old_context); - } - if (qemu_get_aio_context() != new_context) { - aio_context_release(new_context); - } -} - -static bool bdrv_parent_can_set_aio_context(BdrvChild *c, AioContext *ctx, - GSList **ignore, Error **errp) -{ - GLOBAL_STATE_CODE(); - if (g_slist_find(*ignore, c)) { - return true; - } - *ignore = g_slist_prepend(*ignore, c); - - /* - * A BdrvChildClass that doesn't handle AioContext changes cannot - * tolerate any AioContext changes - */ - if (!c->klass->can_set_aio_ctx) { - char *user = bdrv_child_user_desc(c); - error_setg(errp, "Changing iothreads is not supported by %s", user); - g_free(user); - return false; - } - if (!c->klass->can_set_aio_ctx(c, ctx, ignore, errp)) { - assert(!errp || *errp); - return false; - } - return true; -} - typedef struct BdrvStateSetAioContext { AioContext *new_ctx; BlockDriverState *bs; @@ -7357,17 +7222,6 @@ static bool bdrv_parent_change_aio_context(BdrvChild *c, AioContext *ctx, return true; } -bool bdrv_child_can_set_aio_context(BdrvChild *c, AioContext *ctx, - GSList **ignore, Error **errp) -{ - GLOBAL_STATE_CODE(); - if (g_slist_find(*ignore, c)) { - return true; - } - *ignore = g_slist_prepend(*ignore, c); - return bdrv_can_set_aio_context(c->bs, ctx, ignore, errp); -} - bool bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx, GHashTable *visited, Transaction *tran, Error **errp) @@ -7380,33 +7234,6 @@ bool bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx, return bdrv_change_aio_context(c->bs, ctx, visited, tran, errp); } -/* @ignore will accumulate all visited BdrvChild object. The caller is - * responsible for freeing the list afterwards. */ -bool bdrv_can_set_aio_context(BlockDriverState *bs, AioContext *ctx, - GSList **ignore, Error **errp) -{ - BdrvChild *c; - - if (bdrv_get_aio_context(bs) == ctx) { - return true; - } - - GLOBAL_STATE_CODE(); - - QLIST_FOREACH(c, &bs->parents, next_parent) { - if (!bdrv_parent_can_set_aio_context(c, ctx, ignore, errp)) { - return false; - } - } - QLIST_FOREACH(c, &bs->children, next) { - if (!bdrv_child_can_set_aio_context(c, ctx, ignore, errp)) { - return false; - } - } - - return true; -} - static void bdrv_set_aio_context_clean(void *opaque) { BdrvStateSetAioContext *state = (BdrvStateSetAioContext *) opaque; @@ -7499,29 +7326,6 @@ static bool bdrv_change_aio_context(BlockDriverState *bs, AioContext *ctx, return true; } -int bdrv_child_try_set_aio_context(BlockDriverState *bs, AioContext *ctx, - BdrvChild *ignore_child, Error **errp) -{ - GSList *ignore; - bool ret; - - GLOBAL_STATE_CODE(); - - ignore = ignore_child ? g_slist_prepend(NULL, ignore_child) : NULL; - ret = bdrv_can_set_aio_context(bs, ctx, &ignore, errp); - g_slist_free(ignore); - - if (!ret) { - return -EPERM; - } - - ignore = ignore_child ? g_slist_prepend(NULL, ignore_child) : NULL; - bdrv_set_aio_context_ignore(bs, ctx, &ignore); - g_slist_free(ignore); - - return 0; -} - /* * Change bs's and recursively all of its parents' and children's AioContext * to the given new context, returning an error if that isn't possible. diff --git a/block/block-backend.c b/block/block-backend.c index ff417dbff9..a91c8d3916 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -134,10 +134,6 @@ static void blk_root_drained_end(BdrvChild *child, int *drained_end_counter); static void blk_root_change_media(BdrvChild *child, bool load); static void blk_root_resize(BdrvChild *child); -static bool blk_root_can_set_aio_ctx(BdrvChild *child, AioContext *ctx, - GSList **ignore, Error **errp); -static void blk_root_set_aio_ctx(BdrvChild *child, AioContext *ctx, - GSList **ignore); static bool blk_root_change_aio_ctx(BdrvChild *child, AioContext *ctx, GHashTable *visited, Transaction *tran, Error **errp); @@ -337,8 +333,6 @@ static const BdrvChildClass child_root = { .attach = blk_root_attach, .detach = blk_root_detach, - .can_set_aio_ctx = blk_root_can_set_aio_ctx, - .set_aio_ctx = blk_root_set_aio_ctx, .change_aio_ctx = blk_root_change_aio_ctx, .get_parent_aio_context = blk_root_get_parent_aio_context, @@ -2233,33 +2227,6 @@ static bool blk_root_change_aio_ctx(BdrvChild *child, AioContext *ctx, return true; } -static bool blk_root_can_set_aio_ctx(BdrvChild *child, AioContext *ctx, - GSList **ignore, Error **errp) -{ - BlockBackend *blk = child->opaque; - - if (blk->allow_aio_context_change) { - return true; - } - - /* Only manually created BlockBackends that are not attached to anything - * can change their AioContext without updating their user. */ - if (!blk->name || blk->dev) { - /* TODO Add BB name/QOM path */ - error_setg(errp, "Cannot change iothread of active block backend"); - return false; - } - - return true; -} - -static void blk_root_set_aio_ctx(BdrvChild *child, AioContext *ctx, - GSList **ignore) -{ - BlockBackend *blk = child->opaque; - blk_do_set_aio_context(blk, ctx, false, &error_abort); -} - void blk_add_aio_context_notifier(BlockBackend *blk, void (*attached_aio_context)(AioContext *new_context, void *opaque), void (*detach_aio_context)(void *opaque), void *opaque) diff --git a/blockjob.c b/blockjob.c index 5a783b75c6..2d86014fa5 100644 --- a/blockjob.c +++ b/blockjob.c @@ -170,39 +170,6 @@ static bool child_job_change_aio_ctx(BdrvChild *c, AioContext *ctx, return true; } -static bool child_job_can_set_aio_ctx(BdrvChild *c, AioContext *ctx, - GSList **ignore, Error **errp) -{ - BlockJob *job = c->opaque; - GSList *l; - - for (l = job->nodes; l; l = l->next) { - BdrvChild *sibling = l->data; - if (!bdrv_child_can_set_aio_context(sibling, ctx, ignore, errp)) { - return false; - } - } - return true; -} - -static void child_job_set_aio_ctx(BdrvChild *c, AioContext *ctx, - GSList **ignore) -{ - BlockJob *job = c->opaque; - GSList *l; - - for (l = job->nodes; l; l = l->next) { - BdrvChild *sibling = l->data; - if (g_slist_find(*ignore, sibling)) { - continue; - } - *ignore = g_slist_prepend(*ignore, sibling); - bdrv_set_aio_context_ignore(sibling->bs, ctx, ignore); - } - - job_set_aio_context(&job->job, ctx); -} - static AioContext *child_job_get_parent_aio_context(BdrvChild *c) { BlockJob *job = c->opaque; @@ -216,8 +183,6 @@ static const BdrvChildClass child_job = { .drained_begin = child_job_drained_begin, .drained_poll = child_job_drained_poll, .drained_end = child_job_drained_end, - .can_set_aio_ctx = child_job_can_set_aio_ctx, - .set_aio_ctx = child_job_set_aio_ctx, .change_aio_ctx = child_job_change_aio_ctx, .stay_at_node = true, .get_parent_aio_context = child_job_get_parent_aio_context, diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h index e7372ec541..03d4ade7c2 100644 --- a/include/block/block-global-state.h +++ b/include/block/block-global-state.h @@ -220,18 +220,9 @@ void coroutine_fn bdrv_co_lock(BlockDriverState *bs); */ void coroutine_fn bdrv_co_unlock(BlockDriverState *bs); -void bdrv_set_aio_context_ignore(BlockDriverState *bs, - AioContext *new_context, GSList **ignore); int bdrv_try_set_aio_context(BlockDriverState *bs, AioContext *ctx, Error **errp); -int bdrv_child_try_set_aio_context(BlockDriverState *bs, AioContext *ctx, - BdrvChild *ignore_child, Error **errp); -bool bdrv_child_can_set_aio_context(BdrvChild *c, AioContext *ctx, - GSList **ignore, Error **errp); -bool bdrv_can_set_aio_context(BlockDriverState *bs, AioContext *ctx, - GSList **ignore, Error **errp); AioContext *bdrv_child_get_parent_aio_context(BdrvChild *c); - bool bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx, GHashTable *visited, Transaction *tran, Error **errp); diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h index 7ccbbdae05..c756b838e8 100644 --- a/include/block/block_int-common.h +++ b/include/block/block_int-common.h @@ -906,10 +906,6 @@ struct BdrvChildClass { int (*update_filename)(BdrvChild *child, BlockDriverState *new_base, const char *filename, Error **errp); - bool (*can_set_aio_ctx)(BdrvChild *child, AioContext *ctx, - GSList **ignore, Error **errp); - void (*set_aio_ctx)(BdrvChild *child, AioContext *ctx, GSList **ignore); - bool (*change_aio_ctx)(BdrvChild *child, AioContext *ctx, GHashTable *visited, Transaction *tran, Error **errp); From a41cfda12674a296579bc5459646ded9547b1220 Mon Sep 17 00:00:00 2001 From: Emanuele Giuseppe Esposito Date: Tue, 25 Oct 2022 04:49:51 -0400 Subject: [PATCH 267/705] block: rename bdrv_child_try_change_aio_context in bdrv_try_change_aio_context No functional changes intended. Signed-off-by: Emanuele Giuseppe Esposito Reviewed-by: Kevin Wolf Message-Id: <20221025084952.2139888-10-eesposit@redhat.com> Signed-off-by: Kevin Wolf --- block.c | 6 +++--- block/block-backend.c | 3 +-- include/block/block-global-state.h | 4 ++-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/block.c b/block.c index 353240eecd..cf97a35f82 100644 --- a/block.c +++ b/block.c @@ -7340,8 +7340,8 @@ static bool bdrv_change_aio_context(BlockDriverState *bs, AioContext *ctx, * bdrv_drained_end calls BDRV_POLL_WHILE that assumes the lock is taken too. * Therefore the new AioContext lock must not be taken by the caller. */ -int bdrv_child_try_change_aio_context(BlockDriverState *bs, AioContext *ctx, - BdrvChild *ignore_child, Error **errp) +int bdrv_try_change_aio_context(BlockDriverState *bs, AioContext *ctx, + BdrvChild *ignore_child, Error **errp) { Transaction *tran; GHashTable *visited; @@ -7411,7 +7411,7 @@ int bdrv_try_set_aio_context(BlockDriverState *bs, AioContext *ctx, Error **errp) { GLOBAL_STATE_CODE(); - return bdrv_child_try_change_aio_context(bs, ctx, NULL, errp); + return bdrv_try_change_aio_context(bs, ctx, NULL, errp); } void bdrv_add_aio_context_notifier(BlockDriverState *bs, diff --git a/block/block-backend.c b/block/block-backend.c index a91c8d3916..705afef9b3 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -2151,8 +2151,7 @@ static int blk_do_set_aio_context(BlockBackend *blk, AioContext *new_context, * update_root_node MUST be false for blk_root_set_aio_ctx_commit(), * as we are already in the commit function of a transaction. */ - ret = bdrv_child_try_change_aio_context(bs, new_context, blk->root, - errp); + ret = bdrv_try_change_aio_context(bs, new_context, blk->root, errp); if (ret < 0) { bdrv_unref(bs); return ret; diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h index 03d4ade7c2..8db3132e8f 100644 --- a/include/block/block-global-state.h +++ b/include/block/block-global-state.h @@ -226,8 +226,8 @@ AioContext *bdrv_child_get_parent_aio_context(BdrvChild *c); bool bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx, GHashTable *visited, Transaction *tran, Error **errp); -int bdrv_child_try_change_aio_context(BlockDriverState *bs, AioContext *ctx, - BdrvChild *ignore_child, Error **errp); +int bdrv_try_change_aio_context(BlockDriverState *bs, AioContext *ctx, + BdrvChild *ignore_child, Error **errp); int bdrv_probe_blocksizes(BlockDriverState *bs, BlockSizes *bsz); int bdrv_probe_geometry(BlockDriverState *bs, HDGeometry *geo); From 142e6907120d12de1e7ac402e556597ebbab86e8 Mon Sep 17 00:00:00 2001 From: Emanuele Giuseppe Esposito Date: Tue, 25 Oct 2022 04:49:52 -0400 Subject: [PATCH 268/705] block: remove bdrv_try_set_aio_context and replace it with bdrv_try_change_aio_context No functional change intended. Signed-off-by: Emanuele Giuseppe Esposito Reviewed-by: Kevin Wolf Message-Id: <20221025084952.2139888-11-eesposit@redhat.com> Signed-off-by: Kevin Wolf --- block.c | 14 ++++---------- block/export/export.c | 2 +- blockdev.c | 22 +++++++++++----------- docs/devel/multiple-iothreads.txt | 4 ++-- include/block/block-global-state.h | 2 -- job.c | 2 +- tests/unit/test-bdrv-drain.c | 6 +++--- tests/unit/test-block-iothread.c | 10 +++++----- 8 files changed, 27 insertions(+), 35 deletions(-) diff --git a/block.c b/block.c index cf97a35f82..5da15d0f4e 100644 --- a/block.c +++ b/block.c @@ -2904,7 +2904,7 @@ static void bdrv_attach_child_common_abort(void *opaque) bdrv_replace_child_noperm(s->child, NULL); if (bdrv_get_aio_context(bs) != s->old_child_ctx) { - bdrv_try_set_aio_context(bs, s->old_child_ctx, &error_abort); + bdrv_try_change_aio_context(bs, s->old_child_ctx, NULL, &error_abort); } if (bdrv_child_get_parent_aio_context(s->child) != s->old_parent_ctx) { @@ -2975,7 +2975,8 @@ static BdrvChild *bdrv_attach_child_common(BlockDriverState *child_bs, parent_ctx = bdrv_child_get_parent_aio_context(new_child); if (child_ctx != parent_ctx) { Error *local_err = NULL; - int ret = bdrv_try_set_aio_context(child_bs, parent_ctx, &local_err); + int ret = bdrv_try_change_aio_context(child_bs, parent_ctx, NULL, + &local_err); if (ret < 0 && child_class->change_aio_ctx) { Transaction *tran = tran_new(); @@ -3065,7 +3066,7 @@ static void bdrv_detach_child(BdrvChild *child) * When the parent requiring a non-default AioContext is removed, the * node moves back to the main AioContext */ - bdrv_try_set_aio_context(old_bs, qemu_get_aio_context(), NULL); + bdrv_try_change_aio_context(old_bs, qemu_get_aio_context(), NULL, NULL); } } @@ -7407,13 +7408,6 @@ int bdrv_try_change_aio_context(BlockDriverState *bs, AioContext *ctx, return 0; } -int bdrv_try_set_aio_context(BlockDriverState *bs, AioContext *ctx, - Error **errp) -{ - GLOBAL_STATE_CODE(); - return bdrv_try_change_aio_context(bs, ctx, NULL, errp); -} - void bdrv_add_aio_context_notifier(BlockDriverState *bs, void (*attached_aio_context)(AioContext *new_context, void *opaque), void (*detach_aio_context)(void *opaque), void *opaque) diff --git a/block/export/export.c b/block/export/export.c index 4744862915..7cc0c25c1c 100644 --- a/block/export/export.c +++ b/block/export/export.c @@ -129,7 +129,7 @@ BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp) /* Ignore errors with fixed-iothread=false */ set_context_errp = fixed_iothread ? errp : NULL; - ret = bdrv_try_set_aio_context(bs, new_ctx, set_context_errp); + ret = bdrv_try_change_aio_context(bs, new_ctx, NULL, set_context_errp); if (ret == 0) { aio_context_release(ctx); aio_context_acquire(new_ctx); diff --git a/blockdev.c b/blockdev.c index a32bafc07a..9dd88d14d0 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1630,8 +1630,8 @@ static void external_snapshot_abort(BlkActionState *common) aio_context_release(aio_context); aio_context_acquire(tmp_context); - ret = bdrv_try_set_aio_context(state->old_bs, - aio_context, NULL); + ret = bdrv_try_change_aio_context(state->old_bs, + aio_context, NULL, NULL); assert(ret == 0); aio_context_release(tmp_context); @@ -1792,12 +1792,12 @@ static void drive_backup_prepare(BlkActionState *common, Error **errp) goto out; } - /* Honor bdrv_try_set_aio_context() context acquisition requirements. */ + /* Honor bdrv_try_change_aio_context() context acquisition requirements. */ old_context = bdrv_get_aio_context(target_bs); aio_context_release(aio_context); aio_context_acquire(old_context); - ret = bdrv_try_set_aio_context(target_bs, aio_context, errp); + ret = bdrv_try_change_aio_context(target_bs, aio_context, NULL, errp); if (ret < 0) { bdrv_unref(target_bs); aio_context_release(old_context); @@ -1892,12 +1892,12 @@ static void blockdev_backup_prepare(BlkActionState *common, Error **errp) return; } - /* Honor bdrv_try_set_aio_context() context acquisition requirements. */ + /* Honor bdrv_try_change_aio_context() context acquisition requirements. */ aio_context = bdrv_get_aio_context(bs); old_context = bdrv_get_aio_context(target_bs); aio_context_acquire(old_context); - ret = bdrv_try_set_aio_context(target_bs, aio_context, errp); + ret = bdrv_try_change_aio_context(target_bs, aio_context, NULL, errp); if (ret < 0) { aio_context_release(old_context); return; @@ -3194,12 +3194,12 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp) !bdrv_has_zero_init(target_bs))); - /* Honor bdrv_try_set_aio_context() context acquisition requirements. */ + /* Honor bdrv_try_change_aio_context() context acquisition requirements. */ old_context = bdrv_get_aio_context(target_bs); aio_context_release(aio_context); aio_context_acquire(old_context); - ret = bdrv_try_set_aio_context(target_bs, aio_context, errp); + ret = bdrv_try_change_aio_context(target_bs, aio_context, NULL, errp); if (ret < 0) { bdrv_unref(target_bs); aio_context_release(old_context); @@ -3266,12 +3266,12 @@ void qmp_blockdev_mirror(bool has_job_id, const char *job_id, zero_target = (sync == MIRROR_SYNC_MODE_FULL); - /* Honor bdrv_try_set_aio_context() context acquisition requirements. */ + /* Honor bdrv_try_change_aio_context() context acquisition requirements. */ old_context = bdrv_get_aio_context(target_bs); aio_context = bdrv_get_aio_context(bs); aio_context_acquire(old_context); - ret = bdrv_try_set_aio_context(target_bs, aio_context, errp); + ret = bdrv_try_change_aio_context(target_bs, aio_context, NULL, errp); aio_context_release(old_context); aio_context_acquire(aio_context); @@ -3767,7 +3767,7 @@ void qmp_x_blockdev_set_iothread(const char *node_name, StrOrNull *iothread, old_context = bdrv_get_aio_context(bs); aio_context_acquire(old_context); - bdrv_try_set_aio_context(bs, new_context, errp); + bdrv_try_change_aio_context(bs, new_context, NULL, errp); aio_context_release(old_context); } diff --git a/docs/devel/multiple-iothreads.txt b/docs/devel/multiple-iothreads.txt index aeb997bed5..343120f2ef 100644 --- a/docs/devel/multiple-iothreads.txt +++ b/docs/devel/multiple-iothreads.txt @@ -109,7 +109,7 @@ The AioContext originates from the QEMU block layer, even though nowadays AioContext is a generic event loop that can be used by any QEMU subsystem. The block layer has support for AioContext integrated. Each BlockDriverState -is associated with an AioContext using bdrv_try_set_aio_context() and +is associated with an AioContext using bdrv_try_change_aio_context() and bdrv_get_aio_context(). This allows block layer code to process I/O inside the right AioContext. Other subsystems may wish to follow a similar approach. @@ -134,5 +134,5 @@ Long-running jobs (usually in the form of coroutines) are best scheduled in the BlockDriverState's AioContext to avoid the need to acquire/release around each bdrv_*() call. The functions bdrv_add/remove_aio_context_notifier, or alternatively blk_add/remove_aio_context_notifier if you use BlockBackends, -can be used to get a notification whenever bdrv_try_set_aio_context() moves a +can be used to get a notification whenever bdrv_try_change_aio_context() moves a BlockDriverState to a different AioContext. diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h index 8db3132e8f..73795a0095 100644 --- a/include/block/block-global-state.h +++ b/include/block/block-global-state.h @@ -220,8 +220,6 @@ void coroutine_fn bdrv_co_lock(BlockDriverState *bs); */ void coroutine_fn bdrv_co_unlock(BlockDriverState *bs); -int bdrv_try_set_aio_context(BlockDriverState *bs, AioContext *ctx, - Error **errp); AioContext *bdrv_child_get_parent_aio_context(BdrvChild *c); bool bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx, GHashTable *visited, Transaction *tran, diff --git a/job.c b/job.c index 78feae05fb..72d57f0934 100644 --- a/job.c +++ b/job.c @@ -588,7 +588,7 @@ static void coroutine_fn job_do_yield_locked(Job *job, uint64_t ns) next_aio_context = job->aio_context; /* * Coroutine has resumed, but in the meanwhile the job AioContext - * might have changed via bdrv_try_set_aio_context(), so we need to move + * might have changed via bdrv_try_change_aio_context(), so we need to move * the coroutine too in the new aiocontext. */ while (qemu_get_current_aio_context() != next_aio_context) { diff --git a/tests/unit/test-bdrv-drain.c b/tests/unit/test-bdrv-drain.c index 0eecf14310..09dc4a4891 100644 --- a/tests/unit/test-bdrv-drain.c +++ b/tests/unit/test-bdrv-drain.c @@ -1538,16 +1538,16 @@ static void test_set_aio_context(void) &error_abort); bdrv_drained_begin(bs); - bdrv_try_set_aio_context(bs, ctx_a, &error_abort); + bdrv_try_change_aio_context(bs, ctx_a, NULL, &error_abort); aio_context_acquire(ctx_a); bdrv_drained_end(bs); bdrv_drained_begin(bs); - bdrv_try_set_aio_context(bs, ctx_b, &error_abort); + bdrv_try_change_aio_context(bs, ctx_b, NULL, &error_abort); aio_context_release(ctx_a); aio_context_acquire(ctx_b); - bdrv_try_set_aio_context(bs, qemu_get_aio_context(), &error_abort); + bdrv_try_change_aio_context(bs, qemu_get_aio_context(), NULL, &error_abort); aio_context_release(ctx_b); bdrv_drained_end(bs); diff --git a/tests/unit/test-block-iothread.c b/tests/unit/test-block-iothread.c index def0709b2b..8ca5adec5e 100644 --- a/tests/unit/test-block-iothread.c +++ b/tests/unit/test-block-iothread.c @@ -765,7 +765,7 @@ static void test_propagate_mirror(void) filter = bdrv_find_node("filter_node"); /* Change the AioContext of src */ - bdrv_try_set_aio_context(src, ctx, &error_abort); + bdrv_try_change_aio_context(src, ctx, NULL, &error_abort); g_assert(bdrv_get_aio_context(src) == ctx); g_assert(bdrv_get_aio_context(target) == ctx); g_assert(bdrv_get_aio_context(filter) == ctx); @@ -773,7 +773,7 @@ static void test_propagate_mirror(void) /* Change the AioContext of target */ aio_context_acquire(ctx); - bdrv_try_set_aio_context(target, main_ctx, &error_abort); + bdrv_try_change_aio_context(target, main_ctx, NULL, &error_abort); aio_context_release(ctx); g_assert(bdrv_get_aio_context(src) == main_ctx); g_assert(bdrv_get_aio_context(target) == main_ctx); @@ -783,7 +783,7 @@ static void test_propagate_mirror(void) blk = blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL); blk_insert_bs(blk, src, &error_abort); - bdrv_try_set_aio_context(target, ctx, &local_err); + bdrv_try_change_aio_context(target, ctx, NULL, &local_err); error_free_or_abort(&local_err); g_assert(blk_get_aio_context(blk) == main_ctx); @@ -794,7 +794,7 @@ static void test_propagate_mirror(void) /* ...unless we explicitly allow it */ aio_context_acquire(ctx); blk_set_allow_aio_context_change(blk, true); - bdrv_try_set_aio_context(target, ctx, &error_abort); + bdrv_try_change_aio_context(target, ctx, NULL, &error_abort); aio_context_release(ctx); g_assert(blk_get_aio_context(blk) == ctx); @@ -806,7 +806,7 @@ static void test_propagate_mirror(void) aio_context_acquire(ctx); blk_set_aio_context(blk, main_ctx, &error_abort); - bdrv_try_set_aio_context(target, main_ctx, &error_abort); + bdrv_try_change_aio_context(target, main_ctx, NULL, &error_abort); aio_context_release(ctx); blk_unref(blk); From ebdebe47283dd7d20d88834f03f741758419c254 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 8 Sep 2022 21:28:15 +0800 Subject: [PATCH 269/705] block/nfs: Fix 32-bit Windows build libnfs.h declares nfs_fstat() as the following for win32: int nfs_fstat(struct nfs_context *nfs, struct nfsfh *nfsfh, struct __stat64 *st); The 'st' parameter should be of type 'struct __stat64'. The codes happen to build successfully for 64-bit Windows, but it does not build for 32-bit Windows. Fixes: 6542aa9c75bc ("block: add native support for NFS") Fixes: 18a8056e0bc7 ("block/nfs: cache allocated filesize for read-only files") Signed-off-by: Bin Meng Message-Id: <20220908132817.1831008-6-bmeng.cn@gmail.com> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- block/nfs.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/block/nfs.c b/block/nfs.c index 596ebe98cb..ece22353ac 100644 --- a/block/nfs.c +++ b/block/nfs.c @@ -418,7 +418,11 @@ static int64_t nfs_client_open(NFSClient *client, BlockdevOptionsNfs *opts, int flags, int open_flags, Error **errp) { int64_t ret = -EINVAL; +#ifdef _WIN32 + struct __stat64 st; +#else struct stat st; +#endif char *file = NULL, *strp = NULL; qemu_mutex_init(&client->mutex); @@ -781,7 +785,11 @@ static int nfs_reopen_prepare(BDRVReopenState *state, BlockReopenQueue *queue, Error **errp) { NFSClient *client = state->bs->opaque; +#ifdef _WIN32 + struct __stat64 st; +#else struct stat st; +#endif int ret = 0; if (state->flags & BDRV_O_RDWR && bdrv_is_read_only(state->bs)) { From 1a2152568ad5d9afafff96d47d2bf340ac3dc2ea Mon Sep 17 00:00:00 2001 From: Alberto Faria Date: Thu, 13 Oct 2022 14:36:48 +0200 Subject: [PATCH 270/705] backup: remove incorrect coroutine_fn annotation The .set_speed callback is not called from coroutine. Signed-off-by: Alberto Faria Signed-off-by: Paolo Bonzini Message-Id: <20221013123711.620631-2-pbonzini@redhat.com> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- block/backup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/backup.c b/block/backup.c index b2b649e305..6a9ad97a53 100644 --- a/block/backup.c +++ b/block/backup.c @@ -309,7 +309,7 @@ static void coroutine_fn backup_pause(Job *job) } } -static void coroutine_fn backup_set_speed(BlockJob *job, int64_t speed) +static void backup_set_speed(BlockJob *job, int64_t speed) { BackupBlockJob *s = container_of(job, BackupBlockJob, common); From 7c85803c496744c30d070a37be2faf2070d417d3 Mon Sep 17 00:00:00 2001 From: Alberto Faria Date: Thu, 13 Oct 2022 14:36:49 +0200 Subject: [PATCH 271/705] block: remove incorrect coroutine_fn annotation Signed-off-by: Alberto Faria Signed-off-by: Paolo Bonzini Message-Id: <20221013123711.620631-3-pbonzini@redhat.com> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- block/io.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/block/io.c b/block/io.c index d30073036e..236b12da2a 100644 --- a/block/io.c +++ b/block/io.c @@ -2739,8 +2739,8 @@ int coroutine_fn bdrv_co_is_zero_fast(BlockDriverState *bs, int64_t offset, return (pnum == bytes) && (ret & BDRV_BLOCK_ZERO); } -int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, int64_t offset, - int64_t bytes, int64_t *pnum) +int bdrv_is_allocated(BlockDriverState *bs, int64_t offset, int64_t bytes, + int64_t *pnum) { int ret; int64_t dummy; From 6894ee2bee20fd22055f8a7337ef465efab0c823 Mon Sep 17 00:00:00 2001 From: Alberto Faria Date: Thu, 13 Oct 2022 14:36:50 +0200 Subject: [PATCH 272/705] monitor: add missing coroutine_fn annotation hmp_block_resize and hmp_screendump are defined as a ".coroutine = true" command, so they must be coroutine_fn. Signed-off-by: Alberto Faria Signed-off-by: Paolo Bonzini Message-Id: <20221013123711.620631-4-pbonzini@redhat.com> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- block/monitor/block-hmp-cmds.c | 2 +- include/block/block-hmp-cmds.h | 2 +- include/monitor/hmp.h | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c index 939a520d17..b6135e9bfe 100644 --- a/block/monitor/block-hmp-cmds.c +++ b/block/monitor/block-hmp-cmds.c @@ -489,7 +489,7 @@ void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict) hmp_handle_error(mon, err); } -void hmp_block_resize(Monitor *mon, const QDict *qdict) +void coroutine_fn hmp_block_resize(Monitor *mon, const QDict *qdict) { const char *device = qdict_get_str(qdict, "device"); int64_t size = qdict_get_int(qdict, "size"); diff --git a/include/block/block-hmp-cmds.h b/include/block/block-hmp-cmds.h index 50ce0247c3..ba0593c440 100644 --- a/include/block/block-hmp-cmds.h +++ b/include/block/block-hmp-cmds.h @@ -38,7 +38,7 @@ void hmp_nbd_server_add(Monitor *mon, const QDict *qdict); void hmp_nbd_server_remove(Monitor *mon, const QDict *qdict); void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict); -void hmp_block_resize(Monitor *mon, const QDict *qdict); +void coroutine_fn hmp_block_resize(Monitor *mon, const QDict *qdict); void hmp_block_stream(Monitor *mon, const QDict *qdict); void hmp_block_passwd(Monitor *mon, const QDict *qdict); void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict); diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h index a9cf064ee8..dfbc0c9a2f 100644 --- a/include/monitor/hmp.h +++ b/include/monitor/hmp.h @@ -15,6 +15,7 @@ #define HMP_H #include "qemu/readline.h" +#include "qemu/coroutine.h" #include "qapi/qapi-types-common.h" bool hmp_handle_error(Monitor *mon, Error *err); @@ -81,7 +82,7 @@ void hmp_netdev_del(Monitor *mon, const QDict *qdict); void hmp_getfd(Monitor *mon, const QDict *qdict); void hmp_closefd(Monitor *mon, const QDict *qdict); void hmp_sendkey(Monitor *mon, const QDict *qdict); -void hmp_screendump(Monitor *mon, const QDict *qdict); +void coroutine_fn hmp_screendump(Monitor *mon, const QDict *qdict); void hmp_chardev_add(Monitor *mon, const QDict *qdict); void hmp_chardev_change(Monitor *mon, const QDict *qdict); void hmp_chardev_remove(Monitor *mon, const QDict *qdict); From 42f6ad79e38b0a64d154c2131c5adb09fd181eb1 Mon Sep 17 00:00:00 2001 From: Alberto Faria Date: Thu, 13 Oct 2022 14:36:51 +0200 Subject: [PATCH 273/705] ssh: add missing coroutine_fn annotation ssh_write is only called from ssh_co_writev. Signed-off-by: Alberto Faria Signed-off-by: Paolo Bonzini Message-Id: <20221013123711.620631-5-pbonzini@redhat.com> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- block/ssh.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/block/ssh.c b/block/ssh.c index a2dc646536..ceb4f4c5bc 100644 --- a/block/ssh.c +++ b/block/ssh.c @@ -1129,9 +1129,9 @@ static coroutine_fn int ssh_co_readv(BlockDriverState *bs, return ret; } -static int ssh_write(BDRVSSHState *s, BlockDriverState *bs, - int64_t offset, size_t size, - QEMUIOVector *qiov) +static coroutine_fn int ssh_write(BDRVSSHState *s, BlockDriverState *bs, + int64_t offset, size_t size, + QEMUIOVector *qiov) { ssize_t r; size_t written; From 16bb776f5b48e045f5eb5d105ee74135bfc781dd Mon Sep 17 00:00:00 2001 From: Alberto Faria Date: Thu, 13 Oct 2022 14:36:52 +0200 Subject: [PATCH 274/705] block: add missing coroutine_fn annotation to prototypes The functions are marked coroutine_fn in the definition. Signed-off-by: Alberto Faria Signed-off-by: Paolo Bonzini Message-Id: <20221013123711.620631-6-pbonzini@redhat.com> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- include/block/block-io.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/block/block-io.h b/include/block/block-io.h index 492f95fc05..770ddeb7c8 100644 --- a/include/block/block-io.h +++ b/include/block/block-io.h @@ -83,12 +83,13 @@ void bdrv_aio_cancel(BlockAIOCB *acb); void bdrv_aio_cancel_async(BlockAIOCB *acb); /* sg packet commands */ -int bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf); +int coroutine_fn bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf); /* Ensure contents are flushed to disk. */ int coroutine_fn bdrv_co_flush(BlockDriverState *bs); -int bdrv_co_pdiscard(BdrvChild *child, int64_t offset, int64_t bytes); +int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset, + int64_t bytes); bool bdrv_can_write_zeroes_with_unmap(BlockDriverState *bs); int bdrv_block_status(BlockDriverState *bs, int64_t offset, int64_t bytes, int64_t *pnum, int64_t *map, From d63f006a58b32f6df51ca12ac9d9e87b648eb617 Mon Sep 17 00:00:00 2001 From: Alberto Faria Date: Thu, 13 Oct 2022 14:36:53 +0200 Subject: [PATCH 275/705] coroutine-lock: add missing coroutine_fn annotation to prototypes The functions are marked coroutine_fn in the definition. Signed-off-by: Alberto Faria Signed-off-by: Paolo Bonzini Message-Id: <20221013123711.620631-7-pbonzini@redhat.com> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- include/qemu/coroutine.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h index aae33cce17..d848489b65 100644 --- a/include/qemu/coroutine.h +++ b/include/qemu/coroutine.h @@ -276,7 +276,7 @@ void qemu_co_rwlock_init(CoRwlock *lock); * of a parallel writer, control is transferred to the caller of the current * coroutine. */ -void qemu_co_rwlock_rdlock(CoRwlock *lock); +void coroutine_fn qemu_co_rwlock_rdlock(CoRwlock *lock); /** * Write Locks the CoRwlock from a reader. This is a bit more efficient than @@ -285,7 +285,7 @@ void qemu_co_rwlock_rdlock(CoRwlock *lock); * to the caller of the current coroutine; another writer might run while * @qemu_co_rwlock_upgrade blocks. */ -void qemu_co_rwlock_upgrade(CoRwlock *lock); +void coroutine_fn qemu_co_rwlock_upgrade(CoRwlock *lock); /** * Downgrades a write-side critical section to a reader. Downgrading with @@ -293,20 +293,20 @@ void qemu_co_rwlock_upgrade(CoRwlock *lock); * followed by @qemu_co_rwlock_rdlock. This makes it more efficient, but * may also sometimes be necessary for correctness. */ -void qemu_co_rwlock_downgrade(CoRwlock *lock); +void coroutine_fn qemu_co_rwlock_downgrade(CoRwlock *lock); /** * Write Locks the mutex. If the lock cannot be taken immediately because * of a parallel reader, control is transferred to the caller of the current * coroutine. */ -void qemu_co_rwlock_wrlock(CoRwlock *lock); +void coroutine_fn qemu_co_rwlock_wrlock(CoRwlock *lock); /** * Unlocks the read/write lock and schedules the next coroutine that was * waiting for this lock to be run. */ -void qemu_co_rwlock_unlock(CoRwlock *lock); +void coroutine_fn qemu_co_rwlock_unlock(CoRwlock *lock); typedef struct QemuCoSleep { Coroutine *to_wake; From 512ef174fb531a00e6762b007e42095631d2b48d Mon Sep 17 00:00:00 2001 From: Alberto Faria Date: Thu, 13 Oct 2022 14:36:54 +0200 Subject: [PATCH 276/705] coroutine-io: add missing coroutine_fn annotation to prototypes Signed-off-by: Alberto Faria Signed-off-by: Paolo Bonzini Message-Id: <20221013123711.620631-8-pbonzini@redhat.com> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- include/qemu/coroutine.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h index d848489b65..06d323143c 100644 --- a/include/qemu/coroutine.h +++ b/include/qemu/coroutine.h @@ -378,8 +378,9 @@ void qemu_coroutine_dec_pool_size(unsigned int additional_pool_size); * The same interface as qemu_sendv_recvv(), with added yielding. * XXX should mark these as coroutine_fn */ -ssize_t qemu_co_sendv_recvv(int sockfd, struct iovec *iov, unsigned iov_cnt, - size_t offset, size_t bytes, bool do_send); +ssize_t coroutine_fn qemu_co_sendv_recvv(int sockfd, struct iovec *iov, + unsigned iov_cnt, size_t offset, + size_t bytes, bool do_send); #define qemu_co_recvv(sockfd, iov, iov_cnt, offset, bytes) \ qemu_co_sendv_recvv(sockfd, iov, iov_cnt, offset, bytes, false) #define qemu_co_sendv(sockfd, iov, iov_cnt, offset, bytes) \ @@ -388,7 +389,8 @@ ssize_t qemu_co_sendv_recvv(int sockfd, struct iovec *iov, unsigned iov_cnt, /** * The same as above, but with just a single buffer */ -ssize_t qemu_co_send_recv(int sockfd, void *buf, size_t bytes, bool do_send); +ssize_t coroutine_fn qemu_co_send_recv(int sockfd, void *buf, size_t bytes, + bool do_send); #define qemu_co_recv(sockfd, buf, bytes) \ qemu_co_send_recv(sockfd, buf, bytes, false) #define qemu_co_send(sockfd, buf, bytes) \ From c2d7680893a53c3d1443dd729fa60814dd1b2bad Mon Sep 17 00:00:00 2001 From: Alberto Faria Date: Thu, 13 Oct 2022 14:36:55 +0200 Subject: [PATCH 277/705] block: add missing coroutine_fn annotation to BlockDriverState callbacks Signed-off-by: Alberto Faria Signed-off-by: Paolo Bonzini Message-Id: <20221013123711.620631-9-pbonzini@redhat.com> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- block/qcow2.h | 14 +++++++------- include/block/block_int-common.h | 12 +++++------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/block/qcow2.h b/block/qcow2.h index 3e7c5e80b6..ad6e7f65bd 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -991,13 +991,13 @@ int qcow2_truncate_bitmaps_check(BlockDriverState *bs, Error **errp); bool qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, bool release_stored, Error **errp); int qcow2_reopen_bitmaps_ro(BlockDriverState *bs, Error **errp); -bool qcow2_co_can_store_new_dirty_bitmap(BlockDriverState *bs, - const char *name, - uint32_t granularity, - Error **errp); -int qcow2_co_remove_persistent_dirty_bitmap(BlockDriverState *bs, - const char *name, - Error **errp); +bool coroutine_fn qcow2_co_can_store_new_dirty_bitmap(BlockDriverState *bs, + const char *name, + uint32_t granularity, + Error **errp); +int coroutine_fn qcow2_co_remove_persistent_dirty_bitmap(BlockDriverState *bs, + const char *name, + Error **errp); bool qcow2_supports_persistent_dirty_bitmap(BlockDriverState *bs); uint64_t qcow2_get_persistent_dirty_bitmap_size(BlockDriverState *bs, uint32_t cluster_size); diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h index c756b838e8..afce4f8c0a 100644 --- a/include/block/block_int-common.h +++ b/include/block/block_int-common.h @@ -745,13 +745,11 @@ struct BlockDriver { void coroutine_fn (*bdrv_co_drain_end)(BlockDriverState *bs); bool (*bdrv_supports_persistent_dirty_bitmap)(BlockDriverState *bs); - bool (*bdrv_co_can_store_new_dirty_bitmap)(BlockDriverState *bs, - const char *name, - uint32_t granularity, - Error **errp); - int (*bdrv_co_remove_persistent_dirty_bitmap)(BlockDriverState *bs, - const char *name, - Error **errp); + bool coroutine_fn (*bdrv_co_can_store_new_dirty_bitmap)( + BlockDriverState *bs, const char *name, uint32_t granularity, + Error **errp); + int coroutine_fn (*bdrv_co_remove_persistent_dirty_bitmap)( + BlockDriverState *bs, const char *name, Error **errp); }; static inline bool block_driver_can_compress(BlockDriver *drv) From 014688a1b56bab8f3e15810971667ac15acbaa88 Mon Sep 17 00:00:00 2001 From: Alberto Faria Date: Thu, 13 Oct 2022 14:36:56 +0200 Subject: [PATCH 278/705] qcow2: add coroutine_fn annotation for indirect-called functions Signed-off-by: Alberto Faria Signed-off-by: Paolo Bonzini Message-Id: <20221013123711.620631-10-pbonzini@redhat.com> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- block/qcow2.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index b47016cf61..a8bb7135a5 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -5287,8 +5287,8 @@ static int64_t qcow2_check_vmstate_request(BlockDriverState *bs, return pos; } -static int qcow2_save_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, - int64_t pos) +static coroutine_fn int qcow2_save_vmstate(BlockDriverState *bs, + QEMUIOVector *qiov, int64_t pos) { int64_t offset = qcow2_check_vmstate_request(bs, qiov, pos); if (offset < 0) { @@ -5299,8 +5299,8 @@ static int qcow2_save_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, return bs->drv->bdrv_co_pwritev_part(bs, offset, qiov->size, qiov, 0, 0); } -static int qcow2_load_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, - int64_t pos) +static coroutine_fn int qcow2_load_vmstate(BlockDriverState *bs, + QEMUIOVector *qiov, int64_t pos) { int64_t offset = qcow2_check_vmstate_request(bs, qiov, pos); if (offset < 0) { From f72b38b67e49e1460c6a2dffd4ee97c0155347eb Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 13 Oct 2022 14:36:57 +0200 Subject: [PATCH 279/705] blkdebug: add missing coroutine_fn annotation for indirect-called functions Signed-off-by: Paolo Bonzini Message-Id: <20221013123711.620631-11-pbonzini@redhat.com> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- block/blkdebug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/blkdebug.c b/block/blkdebug.c index 5fcfc8ac6f..4265ca125e 100644 --- a/block/blkdebug.c +++ b/block/blkdebug.c @@ -669,7 +669,7 @@ blkdebug_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags); } -static int blkdebug_co_flush(BlockDriverState *bs) +static int coroutine_fn blkdebug_co_flush(BlockDriverState *bs) { int err = rule_check(bs, 0, 0, BLKDEBUG_IO_TYPE_FLUSH); From ea4b80146e4a000b7e9452390f71dca030a8a1b0 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 13 Oct 2022 14:36:58 +0200 Subject: [PATCH 280/705] qcow: manually add more coroutine_fn annotations get_cluster_offset() and decompress_cluster() are only called from the read and write paths. The validity of these was double-checked with Alberto Faria's static analyzer. Signed-off-by: Paolo Bonzini Message-Id: <20221013123711.620631-12-pbonzini@redhat.com> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- block/qcow.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/block/qcow.c b/block/qcow.c index 72ed4c3321..46bbabd2e3 100644 --- a/block/qcow.c +++ b/block/qcow.c @@ -92,7 +92,8 @@ typedef struct BDRVQcowState { static QemuOptsList qcow_create_opts; -static int decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset); +static int coroutine_fn decompress_cluster(BlockDriverState *bs, + uint64_t cluster_offset); static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename) { @@ -349,10 +350,11 @@ static int qcow_reopen_prepare(BDRVReopenState *state, * return 0 if not allocated, 1 if *result is assigned, and negative * errno on failure. */ -static int get_cluster_offset(BlockDriverState *bs, - uint64_t offset, int allocate, - int compressed_size, - int n_start, int n_end, uint64_t *result) +static int coroutine_fn get_cluster_offset(BlockDriverState *bs, + uint64_t offset, int allocate, + int compressed_size, + int n_start, int n_end, + uint64_t *result) { BDRVQcowState *s = bs->opaque; int min_index, i, j, l1_index, l2_index, ret; @@ -583,7 +585,8 @@ static int decompress_buffer(uint8_t *out_buf, int out_buf_size, return 0; } -static int decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset) +static int coroutine_fn decompress_cluster(BlockDriverState *bs, + uint64_t cluster_offset) { BDRVQcowState *s = bs->opaque; int ret, csize; From a1b4ecfd6f4e7d8bfba3a3990150cb92577d92d4 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 13 Oct 2022 14:36:59 +0200 Subject: [PATCH 281/705] qcow2: manually add more coroutine_fn annotations The validity of these was double-checked with Alberto Faria's static analyzer. Signed-off-by: Paolo Bonzini Message-Id: <20221013123711.620631-13-pbonzini@redhat.com> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- block/qcow2-bitmap.c | 4 ++-- block/qcow2-cluster.c | 21 ++++++++++++--------- block/qcow2-refcount.c | 8 ++++---- block/qcow2.h | 18 +++++++++--------- 4 files changed, 27 insertions(+), 24 deletions(-) diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c index 7197754843..bcad567c0c 100644 --- a/block/qcow2-bitmap.c +++ b/block/qcow2-bitmap.c @@ -955,8 +955,8 @@ static void set_readonly_helper(gpointer bitmap, gpointer value) * If header_updated is not NULL then it is set appropriately regardless of * the return value. */ -bool qcow2_load_dirty_bitmaps(BlockDriverState *bs, bool *header_updated, - Error **errp) +bool coroutine_fn qcow2_load_dirty_bitmaps(BlockDriverState *bs, + bool *header_updated, Error **errp) { BDRVQcow2State *s = bs->opaque; Qcow2BitmapList *bm_list; diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index 0f293950a1..097f6484ed 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -31,7 +31,8 @@ #include "qemu/memalign.h" #include "trace.h" -int qcow2_shrink_l1_table(BlockDriverState *bs, uint64_t exact_size) +int coroutine_fn qcow2_shrink_l1_table(BlockDriverState *bs, + uint64_t exact_size) { BDRVQcow2State *s = bs->opaque; int new_l1_size, i, ret; @@ -823,10 +824,10 @@ static int get_cluster_table(BlockDriverState *bs, uint64_t offset, * * Return 0 on success and -errno in error cases */ -int qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs, - uint64_t offset, - int compressed_size, - uint64_t *host_offset) +int coroutine_fn qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs, + uint64_t offset, + int compressed_size, + uint64_t *host_offset) { BDRVQcow2State *s = bs->opaque; int l2_index, ret; @@ -1488,8 +1489,9 @@ static int coroutine_fn handle_dependencies(BlockDriverState *bs, * * -errno: in error cases */ -static int handle_copied(BlockDriverState *bs, uint64_t guest_offset, - uint64_t *host_offset, uint64_t *bytes, QCowL2Meta **m) +static int coroutine_fn handle_copied(BlockDriverState *bs, + uint64_t guest_offset, uint64_t *host_offset, uint64_t *bytes, + QCowL2Meta **m) { BDRVQcow2State *s = bs->opaque; int l2_index; @@ -1653,8 +1655,9 @@ static int do_alloc_cluster_offset(BlockDriverState *bs, uint64_t guest_offset, * * -errno: in error cases */ -static int handle_alloc(BlockDriverState *bs, uint64_t guest_offset, - uint64_t *host_offset, uint64_t *bytes, QCowL2Meta **m) +static int coroutine_fn handle_alloc(BlockDriverState *bs, + uint64_t guest_offset, uint64_t *host_offset, uint64_t *bytes, + QCowL2Meta **m) { BDRVQcow2State *s = bs->opaque; int l2_index; diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index 1fbb07ca77..40e3870887 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -97,7 +97,7 @@ static void update_max_refcount_table_index(BDRVQcow2State *s) s->max_refcount_table_index = i; } -int qcow2_refcount_init(BlockDriverState *bs) +int coroutine_fn qcow2_refcount_init(BlockDriverState *bs) { BDRVQcow2State *s = bs->opaque; unsigned int refcount_table_size2, i; @@ -3559,8 +3559,8 @@ static int64_t get_refblock_offset(BlockDriverState *bs, uint64_t offset) return covering_refblock_offset; } -static int qcow2_discard_refcount_block(BlockDriverState *bs, - uint64_t discard_block_offs) +static int coroutine_fn +qcow2_discard_refcount_block(BlockDriverState *bs, uint64_t discard_block_offs) { BDRVQcow2State *s = bs->opaque; int64_t refblock_offs; @@ -3616,7 +3616,7 @@ static int qcow2_discard_refcount_block(BlockDriverState *bs, return 0; } -int qcow2_shrink_reftable(BlockDriverState *bs) +int coroutine_fn qcow2_shrink_reftable(BlockDriverState *bs) { BDRVQcow2State *s = bs->opaque; uint64_t *reftable_tmp = diff --git a/block/qcow2.h b/block/qcow2.h index ad6e7f65bd..2285f18a73 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -846,7 +846,7 @@ int qcow2_validate_table(BlockDriverState *bs, uint64_t offset, Error **errp); /* qcow2-refcount.c functions */ -int qcow2_refcount_init(BlockDriverState *bs); +int coroutine_fn qcow2_refcount_init(BlockDriverState *bs); void qcow2_refcount_close(BlockDriverState *bs); int qcow2_get_refcount(BlockDriverState *bs, int64_t cluster_index, @@ -893,14 +893,14 @@ int qcow2_inc_refcounts_imrt(BlockDriverState *bs, BdrvCheckResult *res, int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order, BlockDriverAmendStatusCB *status_cb, void *cb_opaque, Error **errp); -int qcow2_shrink_reftable(BlockDriverState *bs); +int coroutine_fn qcow2_shrink_reftable(BlockDriverState *bs); int64_t qcow2_get_last_cluster(BlockDriverState *bs, int64_t size); int coroutine_fn qcow2_detect_metadata_preallocation(BlockDriverState *bs); /* qcow2-cluster.c functions */ int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size, bool exact_size); -int qcow2_shrink_l1_table(BlockDriverState *bs, uint64_t max_size); +int coroutine_fn qcow2_shrink_l1_table(BlockDriverState *bs, uint64_t max_size); int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index); int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num, uint8_t *buf, int nb_sectors, bool enc, Error **errp); @@ -911,10 +911,10 @@ int qcow2_get_host_offset(BlockDriverState *bs, uint64_t offset, int coroutine_fn qcow2_alloc_host_offset(BlockDriverState *bs, uint64_t offset, unsigned int *bytes, uint64_t *host_offset, QCowL2Meta **m); -int qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs, - uint64_t offset, - int compressed_size, - uint64_t *host_offset); +int coroutine_fn qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs, + uint64_t offset, + int compressed_size, + uint64_t *host_offset); void qcow2_parse_compressed_l2_entry(BlockDriverState *bs, uint64_t l2_entry, uint64_t *coffset, int *csize); @@ -982,8 +982,8 @@ void qcow2_cache_discard(Qcow2Cache *c, void *table); int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res, void **refcount_table, int64_t *refcount_table_size); -bool qcow2_load_dirty_bitmaps(BlockDriverState *bs, bool *header_updated, - Error **errp); +bool coroutine_fn qcow2_load_dirty_bitmaps(BlockDriverState *bs, + bool *header_updated, Error **errp); bool qcow2_get_bitmap_info_list(BlockDriverState *bs, Qcow2BitmapInfoList **info_list, Error **errp); int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp); From c9d43d0deb367d35bb911a5b2cf8233a426699cd Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 13 Oct 2022 14:37:00 +0200 Subject: [PATCH 282/705] vmdk: manually add more coroutine_fn annotations The validity of these was double-checked with Alberto Faria's static analyzer. Signed-off-by: Paolo Bonzini Message-Id: <20221013123711.620631-14-pbonzini@redhat.com> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- block/vmdk.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/block/vmdk.c b/block/vmdk.c index d75a87cb85..e5004945b0 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -1403,13 +1403,13 @@ static void vmdk_refresh_limits(BlockDriverState *bs, Error **errp) * [@skip_start_sector, @skip_end_sector) is not copied or written, and leave * it for call to write user data in the request. */ -static int get_whole_cluster(BlockDriverState *bs, - VmdkExtent *extent, - uint64_t cluster_offset, - uint64_t offset, - uint64_t skip_start_bytes, - uint64_t skip_end_bytes, - bool zeroed) +static int coroutine_fn get_whole_cluster(BlockDriverState *bs, + VmdkExtent *extent, + uint64_t cluster_offset, + uint64_t offset, + uint64_t skip_start_bytes, + uint64_t skip_end_bytes, + bool zeroed) { int ret = VMDK_OK; int64_t cluster_bytes; @@ -1484,8 +1484,8 @@ exit: return ret; } -static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data, - uint32_t offset) +static int coroutine_fn vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data, + uint32_t offset) { offset = cpu_to_le32(offset); /* update L2 table */ @@ -1536,14 +1536,14 @@ static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data, * VMDK_UNALLOC if cluster is not mapped and @allocate is false. * VMDK_ERROR if failed. */ -static int get_cluster_offset(BlockDriverState *bs, - VmdkExtent *extent, - VmdkMetaData *m_data, - uint64_t offset, - bool allocate, - uint64_t *cluster_offset, - uint64_t skip_start_bytes, - uint64_t skip_end_bytes) +static int coroutine_fn get_cluster_offset(BlockDriverState *bs, + VmdkExtent *extent, + VmdkMetaData *m_data, + uint64_t offset, + bool allocate, + uint64_t *cluster_offset, + uint64_t skip_start_bytes, + uint64_t skip_end_bytes) { unsigned int l1_index, l2_offset, l2_index; int min_index, i, j; From a06678874bf6ed4f437b384749c704e21a4e61b9 Mon Sep 17 00:00:00 2001 From: Alberto Faria Date: Thu, 13 Oct 2022 14:37:01 +0200 Subject: [PATCH 283/705] commit: switch to *_co_* functions Signed-off-by: Alberto Faria Signed-off-by: Paolo Bonzini Message-Id: <20221013123711.620631-15-pbonzini@redhat.com> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- block/commit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/commit.c b/block/commit.c index e210e86bac..0029b31944 100644 --- a/block/commit.c +++ b/block/commit.c @@ -135,7 +135,7 @@ static int coroutine_fn commit_run(Job *job, Error **errp) } if (base_len < len) { - ret = blk_truncate(s->base, len, false, PREALLOC_MODE_OFF, 0, NULL); + ret = blk_co_truncate(s->base, len, false, PREALLOC_MODE_OFF, 0, NULL); if (ret) { return ret; } From ce47ff20b9f3c05b2b371539bedc437c531c0beb Mon Sep 17 00:00:00 2001 From: Alberto Faria Date: Thu, 13 Oct 2022 14:37:02 +0200 Subject: [PATCH 284/705] block: switch to *_co_* functions Signed-off-by: Alberto Faria Signed-off-by: Paolo Bonzini Message-Id: <20221013123711.620631-16-pbonzini@redhat.com> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- block.c | 2 +- block/io.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/block.c b/block.c index 5da15d0f4e..5311b21f8e 100644 --- a/block.c +++ b/block.c @@ -643,7 +643,7 @@ create_file_fallback_zero_first_sector(BlockBackend *blk, bytes_to_clear = MIN(current_size, BDRV_SECTOR_SIZE); if (bytes_to_clear) { - ret = blk_pwrite_zeroes(blk, 0, bytes_to_clear, BDRV_REQ_MAY_UNMAP); + ret = blk_co_pwrite_zeroes(blk, 0, bytes_to_clear, BDRV_REQ_MAY_UNMAP); if (ret < 0) { error_setg_errno(errp, -ret, "Failed to clear the new image's first sector"); diff --git a/block/io.c b/block/io.c index 236b12da2a..5518a9d1e6 100644 --- a/block/io.c +++ b/block/io.c @@ -2729,8 +2729,8 @@ int coroutine_fn bdrv_co_is_zero_fast(BlockDriverState *bs, int64_t offset, return 1; } - ret = bdrv_common_block_status_above(bs, NULL, false, false, offset, - bytes, &pnum, NULL, NULL, NULL); + ret = bdrv_co_common_block_status_above(bs, NULL, false, false, offset, + bytes, &pnum, NULL, NULL, NULL); if (ret < 0) { return ret; From 882762165a3be58cf6752330878a5c2b181183ce Mon Sep 17 00:00:00 2001 From: Alberto Faria Date: Thu, 13 Oct 2022 14:37:03 +0200 Subject: [PATCH 285/705] mirror: switch to *_co_* functions Signed-off-by: Alberto Faria Signed-off-by: Paolo Bonzini Message-Id: <20221013123711.620631-17-pbonzini@redhat.com> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- block/mirror.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/block/mirror.c b/block/mirror.c index f9432af3df..18bf2d4212 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -922,8 +922,8 @@ static int coroutine_fn mirror_run(Job *job, Error **errp) * active layer. */ if (s->base == blk_bs(s->target)) { if (s->bdev_length > target_length) { - ret = blk_truncate(s->target, s->bdev_length, false, - PREALLOC_MODE_OFF, 0, NULL); + ret = blk_co_truncate(s->target, s->bdev_length, false, + PREALLOC_MODE_OFF, 0, NULL); if (ret < 0) { goto immediate_exit; } From 50688be02a679b7e385a051da6ae18c09de77098 Mon Sep 17 00:00:00 2001 From: Alberto Faria Date: Thu, 13 Oct 2022 14:37:04 +0200 Subject: [PATCH 286/705] parallels: switch to *_co_* functions Signed-off-by: Alberto Faria Signed-off-by: Paolo Bonzini Message-Id: <20221013123711.620631-18-pbonzini@redhat.com> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- block/parallels.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/block/parallels.c b/block/parallels.c index 27c81cee40..892e9ec8d9 100644 --- a/block/parallels.c +++ b/block/parallels.c @@ -205,18 +205,18 @@ static coroutine_fn int64_t allocate_clusters(BlockDriverState *bs, * force the safer-but-slower fallocate. */ if (s->prealloc_mode == PRL_PREALLOC_MODE_TRUNCATE) { - ret = bdrv_truncate(bs->file, - (s->data_end + space) << BDRV_SECTOR_BITS, - false, PREALLOC_MODE_OFF, BDRV_REQ_ZERO_WRITE, - NULL); + ret = bdrv_co_truncate(bs->file, + (s->data_end + space) << BDRV_SECTOR_BITS, + false, PREALLOC_MODE_OFF, + BDRV_REQ_ZERO_WRITE, NULL); if (ret == -ENOTSUP) { s->prealloc_mode = PRL_PREALLOC_MODE_FALLOCATE; } } if (s->prealloc_mode == PRL_PREALLOC_MODE_FALLOCATE) { - ret = bdrv_pwrite_zeroes(bs->file, - s->data_end << BDRV_SECTOR_BITS, - space << BDRV_SECTOR_BITS, 0); + ret = bdrv_co_pwrite_zeroes(bs->file, + s->data_end << BDRV_SECTOR_BITS, + space << BDRV_SECTOR_BITS, 0); } if (ret < 0) { return ret; @@ -278,8 +278,8 @@ static coroutine_fn int parallels_co_flush_to_os(BlockDriverState *bs) if (off + to_write > s->header_size) { to_write = s->header_size - off; } - ret = bdrv_pwrite(bs->file, off, to_write, (uint8_t *)s->header + off, - 0); + ret = bdrv_co_pwrite(bs->file, off, to_write, + (uint8_t *)s->header + off, 0); if (ret < 0) { qemu_co_mutex_unlock(&s->lock); return ret; @@ -504,8 +504,8 @@ static int coroutine_fn parallels_co_check(BlockDriverState *bs, * In order to really repair the image, we must shrink it. * That means we have to pass exact=true. */ - ret = bdrv_truncate(bs->file, res->image_end_offset, true, - PREALLOC_MODE_OFF, 0, &local_err); + ret = bdrv_co_truncate(bs->file, res->image_end_offset, true, + PREALLOC_MODE_OFF, 0, &local_err); if (ret < 0) { error_report_err(local_err); res->check_errors++; @@ -600,12 +600,12 @@ static int coroutine_fn parallels_co_create(BlockdevCreateOptions* opts, memset(tmp, 0, sizeof(tmp)); memcpy(tmp, &header, sizeof(header)); - ret = blk_pwrite(blk, 0, BDRV_SECTOR_SIZE, tmp, 0); + ret = blk_co_pwrite(blk, 0, BDRV_SECTOR_SIZE, tmp, 0); if (ret < 0) { goto exit; } - ret = blk_pwrite_zeroes(blk, BDRV_SECTOR_SIZE, - (bat_sectors - 1) << BDRV_SECTOR_BITS, 0); + ret = blk_co_pwrite_zeroes(blk, BDRV_SECTOR_SIZE, + (bat_sectors - 1) << BDRV_SECTOR_BITS, 0); if (ret < 0) { goto exit; } From 58684155e42fe16a21d8c1fcc7927c5b96706ff4 Mon Sep 17 00:00:00 2001 From: Alberto Faria Date: Thu, 13 Oct 2022 14:37:05 +0200 Subject: [PATCH 287/705] qcow: switch to *_co_* functions Signed-off-by: Alberto Faria Signed-off-by: Paolo Bonzini Message-Id: <20221013123711.620631-19-pbonzini@redhat.com> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- block/qcow.c | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/block/qcow.c b/block/qcow.c index 46bbabd2e3..bb25125b22 100644 --- a/block/qcow.c +++ b/block/qcow.c @@ -381,9 +381,9 @@ static int coroutine_fn get_cluster_offset(BlockDriverState *bs, s->l1_table[l1_index] = l2_offset; tmp = cpu_to_be64(l2_offset); BLKDBG_EVENT(bs->file, BLKDBG_L1_UPDATE); - ret = bdrv_pwrite_sync(bs->file, - s->l1_table_offset + l1_index * sizeof(tmp), - sizeof(tmp), &tmp, 0); + ret = bdrv_co_pwrite_sync(bs->file, + s->l1_table_offset + l1_index * sizeof(tmp), + sizeof(tmp), &tmp, 0); if (ret < 0) { return ret; } @@ -414,14 +414,14 @@ static int coroutine_fn get_cluster_offset(BlockDriverState *bs, BLKDBG_EVENT(bs->file, BLKDBG_L2_LOAD); if (new_l2_table) { memset(l2_table, 0, s->l2_size * sizeof(uint64_t)); - ret = bdrv_pwrite_sync(bs->file, l2_offset, - s->l2_size * sizeof(uint64_t), l2_table, 0); + ret = bdrv_co_pwrite_sync(bs->file, l2_offset, + s->l2_size * sizeof(uint64_t), l2_table, 0); if (ret < 0) { return ret; } } else { - ret = bdrv_pread(bs->file, l2_offset, s->l2_size * sizeof(uint64_t), - l2_table, 0); + ret = bdrv_co_pread(bs->file, l2_offset, + s->l2_size * sizeof(uint64_t), l2_table, 0); if (ret < 0) { return ret; } @@ -453,8 +453,8 @@ static int coroutine_fn get_cluster_offset(BlockDriverState *bs, cluster_offset = QEMU_ALIGN_UP(cluster_offset, s->cluster_size); /* write the cluster content */ BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO); - ret = bdrv_pwrite(bs->file, cluster_offset, s->cluster_size, - s->cluster_cache, 0); + ret = bdrv_co_pwrite(bs->file, cluster_offset, s->cluster_size, + s->cluster_cache, 0); if (ret < 0) { return ret; } @@ -469,8 +469,9 @@ static int coroutine_fn get_cluster_offset(BlockDriverState *bs, if (cluster_offset + s->cluster_size > INT64_MAX) { return -E2BIG; } - ret = bdrv_truncate(bs->file, cluster_offset + s->cluster_size, - false, PREALLOC_MODE_OFF, 0, NULL); + ret = bdrv_co_truncate(bs->file, + cluster_offset + s->cluster_size, + false, PREALLOC_MODE_OFF, 0, NULL); if (ret < 0) { return ret; } @@ -492,9 +493,9 @@ static int coroutine_fn get_cluster_offset(BlockDriverState *bs, return -EIO; } BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO); - ret = bdrv_pwrite(bs->file, cluster_offset + i, - BDRV_SECTOR_SIZE, - s->cluster_data, 0); + ret = bdrv_co_pwrite(bs->file, cluster_offset + i, + BDRV_SECTOR_SIZE, + s->cluster_data, 0); if (ret < 0) { return ret; } @@ -514,8 +515,8 @@ static int coroutine_fn get_cluster_offset(BlockDriverState *bs, } else { BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE); } - ret = bdrv_pwrite_sync(bs->file, l2_offset + l2_index * sizeof(tmp), - sizeof(tmp), &tmp, 0); + ret = bdrv_co_pwrite_sync(bs->file, l2_offset + l2_index * sizeof(tmp), + sizeof(tmp), &tmp, 0); if (ret < 0) { return ret; } @@ -597,7 +598,7 @@ static int coroutine_fn decompress_cluster(BlockDriverState *bs, csize = cluster_offset >> (63 - s->cluster_bits); csize &= (s->cluster_size - 1); BLKDBG_EVENT(bs->file, BLKDBG_READ_COMPRESSED); - ret = bdrv_pread(bs->file, coffset, csize, s->cluster_data, 0); + ret = bdrv_co_pread(bs->file, coffset, csize, s->cluster_data, 0); if (ret < 0) return -1; if (decompress_buffer(s->cluster_cache, s->cluster_size, @@ -891,14 +892,14 @@ static int coroutine_fn qcow_co_create(BlockdevCreateOptions *opts, } /* write all the data */ - ret = blk_pwrite(qcow_blk, 0, sizeof(header), &header, 0); + ret = blk_co_pwrite(qcow_blk, 0, sizeof(header), &header, 0); if (ret < 0) { goto exit; } if (qcow_opts->has_backing_file) { - ret = blk_pwrite(qcow_blk, sizeof(header), backing_filename_len, - qcow_opts->backing_file, 0); + ret = blk_co_pwrite(qcow_blk, sizeof(header), backing_filename_len, + qcow_opts->backing_file, 0); if (ret < 0) { goto exit; } @@ -907,8 +908,8 @@ static int coroutine_fn qcow_co_create(BlockdevCreateOptions *opts, tmp = g_malloc0(BDRV_SECTOR_SIZE); for (i = 0; i < DIV_ROUND_UP(sizeof(uint64_t) * l1_size, BDRV_SECTOR_SIZE); i++) { - ret = blk_pwrite(qcow_blk, header_size + BDRV_SECTOR_SIZE * i, - BDRV_SECTOR_SIZE, tmp, 0); + ret = blk_co_pwrite(qcow_blk, header_size + BDRV_SECTOR_SIZE * i, + BDRV_SECTOR_SIZE, tmp, 0); if (ret < 0) { g_free(tmp); goto exit; From 38505e2a147c4f9fade382ede4a40e287c7bd846 Mon Sep 17 00:00:00 2001 From: Alberto Faria Date: Thu, 13 Oct 2022 14:37:06 +0200 Subject: [PATCH 288/705] qcow2: switch to *_co_* functions Signed-off-by: Alberto Faria Signed-off-by: Paolo Bonzini Message-Id: <20221013123711.620631-20-pbonzini@redhat.com> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- block/qcow2-cluster.c | 8 ++++---- block/qcow2-refcount.c | 10 +++++----- block/qcow2-snapshot.c | 6 +++--- block/qcow2.c | 24 ++++++++++++------------ 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index 097f6484ed..40ed847f97 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -48,14 +48,14 @@ int coroutine_fn qcow2_shrink_l1_table(BlockDriverState *bs, #endif BLKDBG_EVENT(bs->file, BLKDBG_L1_SHRINK_WRITE_TABLE); - ret = bdrv_pwrite_zeroes(bs->file, s->l1_table_offset + - new_l1_size * L1E_SIZE, - (s->l1_size - new_l1_size) * L1E_SIZE, 0); + ret = bdrv_co_pwrite_zeroes(bs->file, + s->l1_table_offset + new_l1_size * L1E_SIZE, + (s->l1_size - new_l1_size) * L1E_SIZE, 0); if (ret < 0) { goto fail; } - ret = bdrv_flush(bs->file->bs); + ret = bdrv_co_flush(bs->file->bs); if (ret < 0) { goto fail; } diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index 40e3870887..81264740f0 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -118,8 +118,8 @@ int coroutine_fn qcow2_refcount_init(BlockDriverState *bs) goto fail; } BLKDBG_EVENT(bs->file, BLKDBG_REFTABLE_LOAD); - ret = bdrv_pread(bs->file, s->refcount_table_offset, - refcount_table_size2, s->refcount_table, 0); + ret = bdrv_co_pread(bs->file, s->refcount_table_offset, + refcount_table_size2, s->refcount_table, 0); if (ret < 0) { goto fail; } @@ -3657,9 +3657,9 @@ int coroutine_fn qcow2_shrink_reftable(BlockDriverState *bs) reftable_tmp[i] = unused_block ? 0 : cpu_to_be64(s->refcount_table[i]); } - ret = bdrv_pwrite_sync(bs->file, s->refcount_table_offset, - s->refcount_table_size * REFTABLE_ENTRY_SIZE, - reftable_tmp, 0); + ret = bdrv_co_pwrite_sync(bs->file, s->refcount_table_offset, + s->refcount_table_size * REFTABLE_ENTRY_SIZE, + reftable_tmp, 0); /* * If the write in the reftable failed the image may contain a partially * overwritten reftable. In this case it would be better to clear the diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c index d1d46facbf..62e8a0335d 100644 --- a/block/qcow2-snapshot.c +++ b/block/qcow2-snapshot.c @@ -441,9 +441,9 @@ int coroutine_fn qcow2_check_read_snapshot_table(BlockDriverState *bs, } QEMU_PACKED snapshot_table_pointer; /* qcow2_do_open() discards this information in check mode */ - ret = bdrv_pread(bs->file, offsetof(QCowHeader, nb_snapshots), - sizeof(snapshot_table_pointer), &snapshot_table_pointer, - 0); + ret = bdrv_co_pread(bs->file, offsetof(QCowHeader, nb_snapshots), + sizeof(snapshot_table_pointer), &snapshot_table_pointer, + 0); if (ret < 0) { result->check_errors++; fprintf(stderr, "ERROR failed to read the snapshot table pointer from " diff --git a/block/qcow2.c b/block/qcow2.c index a8bb7135a5..4d6666d3ff 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1306,7 +1306,7 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options, uint64_t l1_vm_state_index; bool update_header = false; - ret = bdrv_pread(bs->file, 0, sizeof(header), &header, 0); + ret = bdrv_co_pread(bs->file, 0, sizeof(header), &header, 0); if (ret < 0) { error_setg_errno(errp, -ret, "Could not read qcow2 header"); goto fail; @@ -1382,9 +1382,9 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options, if (header.header_length > sizeof(header)) { s->unknown_header_fields_size = header.header_length - sizeof(header); s->unknown_header_fields = g_malloc(s->unknown_header_fields_size); - ret = bdrv_pread(bs->file, sizeof(header), - s->unknown_header_fields_size, - s->unknown_header_fields, 0); + ret = bdrv_co_pread(bs->file, sizeof(header), + s->unknown_header_fields_size, + s->unknown_header_fields, 0); if (ret < 0) { error_setg_errno(errp, -ret, "Could not read unknown qcow2 header " "fields"); @@ -1579,8 +1579,8 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options, ret = -ENOMEM; goto fail; } - ret = bdrv_pread(bs->file, s->l1_table_offset, s->l1_size * L1E_SIZE, - s->l1_table, 0); + ret = bdrv_co_pread(bs->file, s->l1_table_offset, s->l1_size * L1E_SIZE, + s->l1_table, 0); if (ret < 0) { error_setg_errno(errp, -ret, "Could not read L1 table"); goto fail; @@ -1699,8 +1699,8 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options, } s->image_backing_file = g_malloc(len + 1); - ret = bdrv_pread(bs->file, header.backing_file_offset, len, - s->image_backing_file, 0); + ret = bdrv_co_pread(bs->file, header.backing_file_offset, len, + s->image_backing_file, 0); if (ret < 0) { error_setg_errno(errp, -ret, "Could not read backing file name"); goto fail; @@ -3679,7 +3679,7 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp) cpu_to_be64(QCOW2_INCOMPAT_EXTL2); } - ret = blk_pwrite(blk, 0, cluster_size, header, 0); + ret = blk_co_pwrite(blk, 0, cluster_size, header, 0); g_free(header); if (ret < 0) { error_setg_errno(errp, -ret, "Could not write qcow2 header"); @@ -3689,7 +3689,7 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp) /* Write a refcount table with one refcount block */ refcount_table = g_malloc0(2 * cluster_size); refcount_table[0] = cpu_to_be64(2 * cluster_size); - ret = blk_pwrite(blk, cluster_size, 2 * cluster_size, refcount_table, 0); + ret = blk_co_pwrite(blk, cluster_size, 2 * cluster_size, refcount_table, 0); g_free(refcount_table); if (ret < 0) { @@ -3744,8 +3744,8 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp) } /* Okay, now that we have a valid image, let's give it the right size */ - ret = blk_truncate(blk, qcow2_opts->size, false, qcow2_opts->preallocation, - 0, errp); + ret = blk_co_truncate(blk, qcow2_opts->size, false, + qcow2_opts->preallocation, 0, errp); if (ret < 0) { error_prepend(errp, "Could not resize image: "); goto out; From 3aba34adb19131ebfb996f700c518a0352a489ac Mon Sep 17 00:00:00 2001 From: Alberto Faria Date: Thu, 13 Oct 2022 14:37:07 +0200 Subject: [PATCH 289/705] qed: switch to *_co_* functions Signed-off-by: Alberto Faria Signed-off-by: Paolo Bonzini Message-Id: <20221013123711.620631-21-pbonzini@redhat.com> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- block/qed-table.c | 2 +- block/qed.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/block/qed-table.c b/block/qed-table.c index 1cc844b1a5..aa203f2627 100644 --- a/block/qed-table.c +++ b/block/qed-table.c @@ -100,7 +100,7 @@ static int coroutine_fn qed_write_table(BDRVQEDState *s, uint64_t offset, } if (flush) { - ret = bdrv_flush(s->bs); + ret = bdrv_co_flush(s->bs); if (ret < 0) { goto out; } diff --git a/block/qed.c b/block/qed.c index 4627169348..d7f2c6fc7c 100644 --- a/block/qed.c +++ b/block/qed.c @@ -387,7 +387,7 @@ static int coroutine_fn bdrv_qed_do_open(BlockDriverState *bs, QDict *options, int64_t file_size; int ret; - ret = bdrv_pread(bs->file, 0, sizeof(le_header), &le_header, 0); + ret = bdrv_co_pread(bs->file, 0, sizeof(le_header), &le_header, 0); if (ret < 0) { error_setg(errp, "Failed to read QED header"); return ret; @@ -492,7 +492,7 @@ static int coroutine_fn bdrv_qed_do_open(BlockDriverState *bs, QDict *options, } /* From here on only known autoclear feature bits are valid */ - bdrv_flush(bs->file->bs); + bdrv_co_flush(bs->file->bs); } s->l1_table = qed_alloc_table(s); @@ -693,7 +693,7 @@ static int coroutine_fn bdrv_qed_co_create(BlockdevCreateOptions *opts, * The QED format associates file length with allocation status, * so a new file (which is empty) must have a length of 0. */ - ret = blk_truncate(blk, 0, true, PREALLOC_MODE_OFF, 0, errp); + ret = blk_co_truncate(blk, 0, true, PREALLOC_MODE_OFF, 0, errp); if (ret < 0) { goto out; } @@ -712,18 +712,18 @@ static int coroutine_fn bdrv_qed_co_create(BlockdevCreateOptions *opts, } qed_header_cpu_to_le(&header, &le_header); - ret = blk_pwrite(blk, 0, sizeof(le_header), &le_header, 0); + ret = blk_co_pwrite(blk, 0, sizeof(le_header), &le_header, 0); if (ret < 0) { goto out; } - ret = blk_pwrite(blk, sizeof(le_header), header.backing_filename_size, + ret = blk_co_pwrite(blk, sizeof(le_header), header.backing_filename_size, qed_opts->backing_file, 0); if (ret < 0) { goto out; } l1_table = g_malloc0(l1_size); - ret = blk_pwrite(blk, header.l1_table_offset, l1_size, l1_table, 0); + ret = blk_co_pwrite(blk, header.l1_table_offset, l1_size, l1_table, 0); if (ret < 0) { goto out; } From 3f6530282226587e9253e4129e2297e955cc90b2 Mon Sep 17 00:00:00 2001 From: Alberto Faria Date: Thu, 13 Oct 2022 14:37:08 +0200 Subject: [PATCH 290/705] vdi: switch to *_co_* functions Signed-off-by: Alberto Faria Signed-off-by: Paolo Bonzini Message-Id: <20221013123711.620631-22-pbonzini@redhat.com> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- block/vdi.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/block/vdi.c b/block/vdi.c index a9bafb5a9e..c0c111c4b9 100644 --- a/block/vdi.c +++ b/block/vdi.c @@ -663,7 +663,8 @@ vdi_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, * so this full-cluster write does not overlap a partial write * of the same cluster, issued from the "else" branch. */ - ret = bdrv_pwrite(bs->file, data_offset, s->block_size, block, 0); + ret = bdrv_co_pwrite(bs->file, data_offset, s->block_size, block, + 0); qemu_co_rwlock_unlock(&s->bmap_lock); } else { nonallocating_write: @@ -708,7 +709,7 @@ nonallocating_write: assert(VDI_IS_ALLOCATED(bmap_first)); *header = s->header; vdi_header_to_le(header); - ret = bdrv_pwrite(bs->file, 0, sizeof(*header), header, 0); + ret = bdrv_co_pwrite(bs->file, 0, sizeof(*header), header, 0); g_free(header); if (ret < 0) { @@ -725,8 +726,8 @@ nonallocating_write: base = ((uint8_t *)&s->bmap[0]) + bmap_first * SECTOR_SIZE; logout("will write %u block map sectors starting from entry %u\n", n_sectors, bmap_first); - ret = bdrv_pwrite(bs->file, offset * SECTOR_SIZE, - n_sectors * SECTOR_SIZE, base, 0); + ret = bdrv_co_pwrite(bs->file, offset * SECTOR_SIZE, + n_sectors * SECTOR_SIZE, base, 0); } return ret; @@ -844,7 +845,7 @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options, vdi_header_print(&header); } vdi_header_to_le(&header); - ret = blk_pwrite(blk, offset, sizeof(header), &header, 0); + ret = blk_co_pwrite(blk, offset, sizeof(header), &header, 0); if (ret < 0) { error_setg(errp, "Error writing header"); goto exit; @@ -865,7 +866,7 @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options, bmap[i] = VDI_UNALLOCATED; } } - ret = blk_pwrite(blk, offset, bmap_size, bmap, 0); + ret = blk_co_pwrite(blk, offset, bmap_size, bmap, 0); if (ret < 0) { error_setg(errp, "Error writing bmap"); goto exit; @@ -874,8 +875,8 @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options, } if (image_type == VDI_TYPE_STATIC) { - ret = blk_truncate(blk, offset + blocks * block_size, false, - PREALLOC_MODE_OFF, 0, errp); + ret = blk_co_truncate(blk, offset + blocks * block_size, false, + PREALLOC_MODE_OFF, 0, errp); if (ret < 0) { error_prepend(errp, "Failed to statically allocate file"); goto exit; From eb342749c0cc8002fc19a5589fb5c3d836118185 Mon Sep 17 00:00:00 2001 From: Alberto Faria Date: Thu, 13 Oct 2022 14:37:09 +0200 Subject: [PATCH 291/705] vhdx: switch to *_co_* functions Signed-off-by: Alberto Faria Signed-off-by: Paolo Bonzini Message-Id: <20221013123711.620631-23-pbonzini@redhat.com> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- block/vhdx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/block/vhdx.c b/block/vhdx.c index ce1e75f5ec..a41db46294 100644 --- a/block/vhdx.c +++ b/block/vhdx.c @@ -2011,15 +2011,15 @@ static int coroutine_fn vhdx_co_create(BlockdevCreateOptions *opts, creator = g_utf8_to_utf16("QEMU v" QEMU_VERSION, -1, NULL, &creator_items, NULL); signature = cpu_to_le64(VHDX_FILE_SIGNATURE); - ret = blk_pwrite(blk, VHDX_FILE_ID_OFFSET, sizeof(signature), &signature, - 0); + ret = blk_co_pwrite(blk, VHDX_FILE_ID_OFFSET, sizeof(signature), &signature, + 0); if (ret < 0) { error_setg_errno(errp, -ret, "Failed to write file signature"); goto delete_and_exit; } if (creator) { - ret = blk_pwrite(blk, VHDX_FILE_ID_OFFSET + sizeof(signature), - creator_items * sizeof(gunichar2), creator, 0); + ret = blk_co_pwrite(blk, VHDX_FILE_ID_OFFSET + sizeof(signature), + creator_items * sizeof(gunichar2), creator, 0); if (ret < 0) { error_setg_errno(errp, -ret, "Failed to write creator field"); goto delete_and_exit; From a5c4e5be7e09d46bd57693c139e74f9cbab042a3 Mon Sep 17 00:00:00 2001 From: Alberto Faria Date: Thu, 13 Oct 2022 14:37:10 +0200 Subject: [PATCH 292/705] vmdk: switch to *_co_* functions Signed-off-by: Alberto Faria Signed-off-by: Paolo Bonzini Message-Id: <20221013123711.620631-24-pbonzini@redhat.com> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- block/vmdk.c | 54 ++++++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/block/vmdk.c b/block/vmdk.c index e5004945b0..26376352b9 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -1440,16 +1440,16 @@ static int coroutine_fn get_whole_cluster(BlockDriverState *bs, if (copy_from_backing) { /* qcow2 emits this on bs->file instead of bs->backing */ BLKDBG_EVENT(extent->file, BLKDBG_COW_READ); - ret = bdrv_pread(bs->backing, offset, skip_start_bytes, - whole_grain, 0); + ret = bdrv_co_pread(bs->backing, offset, skip_start_bytes, + whole_grain, 0); if (ret < 0) { ret = VMDK_ERROR; goto exit; } } BLKDBG_EVENT(extent->file, BLKDBG_COW_WRITE); - ret = bdrv_pwrite(extent->file, cluster_offset, skip_start_bytes, - whole_grain, 0); + ret = bdrv_co_pwrite(extent->file, cluster_offset, skip_start_bytes, + whole_grain, 0); if (ret < 0) { ret = VMDK_ERROR; goto exit; @@ -1460,18 +1460,18 @@ static int coroutine_fn get_whole_cluster(BlockDriverState *bs, if (copy_from_backing) { /* qcow2 emits this on bs->file instead of bs->backing */ BLKDBG_EVENT(extent->file, BLKDBG_COW_READ); - ret = bdrv_pread(bs->backing, offset + skip_end_bytes, - cluster_bytes - skip_end_bytes, - whole_grain + skip_end_bytes, 0); + ret = bdrv_co_pread(bs->backing, offset + skip_end_bytes, + cluster_bytes - skip_end_bytes, + whole_grain + skip_end_bytes, 0); if (ret < 0) { ret = VMDK_ERROR; goto exit; } } BLKDBG_EVENT(extent->file, BLKDBG_COW_WRITE); - ret = bdrv_pwrite(extent->file, cluster_offset + skip_end_bytes, - cluster_bytes - skip_end_bytes, - whole_grain + skip_end_bytes, 0); + ret = bdrv_co_pwrite(extent->file, cluster_offset + skip_end_bytes, + cluster_bytes - skip_end_bytes, + whole_grain + skip_end_bytes, 0); if (ret < 0) { ret = VMDK_ERROR; goto exit; @@ -1490,23 +1490,23 @@ static int coroutine_fn vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data, offset = cpu_to_le32(offset); /* update L2 table */ BLKDBG_EVENT(extent->file, BLKDBG_L2_UPDATE); - if (bdrv_pwrite(extent->file, - ((int64_t)m_data->l2_offset * 512) - + (m_data->l2_index * sizeof(offset)), - sizeof(offset), &offset, 0) < 0) { + if (bdrv_co_pwrite(extent->file, + ((int64_t)m_data->l2_offset * 512) + + (m_data->l2_index * sizeof(offset)), + sizeof(offset), &offset, 0) < 0) { return VMDK_ERROR; } /* update backup L2 table */ if (extent->l1_backup_table_offset != 0) { m_data->l2_offset = extent->l1_backup_table[m_data->l1_index]; - if (bdrv_pwrite(extent->file, - ((int64_t)m_data->l2_offset * 512) - + (m_data->l2_index * sizeof(offset)), - sizeof(offset), &offset, 0) < 0) { + if (bdrv_co_pwrite(extent->file, + ((int64_t)m_data->l2_offset * 512) + + (m_data->l2_index * sizeof(offset)), + sizeof(offset), &offset, 0) < 0) { return VMDK_ERROR; } } - if (bdrv_flush(extent->file->bs) < 0) { + if (bdrv_co_flush(extent->file->bs) < 0) { return VMDK_ERROR; } if (m_data->l2_cache_entry) { @@ -1623,11 +1623,10 @@ static int coroutine_fn get_cluster_offset(BlockDriverState *bs, } l2_table = (char *)extent->l2_cache + (min_index * l2_size_bytes); BLKDBG_EVENT(extent->file, BLKDBG_L2_LOAD); - if (bdrv_pread(extent->file, + if (bdrv_co_pread(extent->file, (int64_t)l2_offset * 512, l2_size_bytes, - l2_table, - 0 + l2_table, 0 ) < 0) { return VMDK_ERROR; } @@ -1898,7 +1897,8 @@ vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset, cluster_buf = g_malloc(buf_bytes); uncomp_buf = g_malloc(cluster_bytes); BLKDBG_EVENT(extent->file, BLKDBG_READ_COMPRESSED); - ret = bdrv_pread(extent->file, cluster_offset, buf_bytes, cluster_buf, 0); + ret = bdrv_co_pread(extent->file, cluster_offset, buf_bytes, cluster_buf, + 0); if (ret < 0) { goto out; } @@ -2143,8 +2143,8 @@ vmdk_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes, return length; } length = QEMU_ALIGN_UP(length, BDRV_SECTOR_SIZE); - ret = bdrv_truncate(s->extents[i].file, length, false, - PREALLOC_MODE_OFF, 0, NULL); + ret = bdrv_co_truncate(s->extents[i].file, length, false, + PREALLOC_MODE_OFF, 0, NULL); if (ret < 0) { return ret; } @@ -2585,7 +2585,7 @@ static int coroutine_fn vmdk_co_do_create(int64_t size, desc_offset = 0x200; } - ret = blk_pwrite(blk, desc_offset, desc_len, desc, 0); + ret = blk_co_pwrite(blk, desc_offset, desc_len, desc, 0); if (ret < 0) { error_setg_errno(errp, -ret, "Could not write description"); goto exit; @@ -2593,7 +2593,7 @@ static int coroutine_fn vmdk_co_do_create(int64_t size, /* bdrv_pwrite write padding zeros to align to sector, we don't need that * for description file */ if (desc_offset == 0) { - ret = blk_truncate(blk, desc_len, false, PREALLOC_MODE_OFF, 0, errp); + ret = blk_co_truncate(blk, desc_len, false, PREALLOC_MODE_OFF, 0, errp); if (ret < 0) { goto exit; } From 247cf5c035ee598a58386230ab9db551ca3c1b1d Mon Sep 17 00:00:00 2001 From: Alberto Faria Date: Thu, 13 Oct 2022 14:37:11 +0200 Subject: [PATCH 293/705] monitor: switch to *_co_* functions Signed-off-by: Alberto Faria Signed-off-by: Paolo Bonzini Message-Id: <20221013123711.620631-25-pbonzini@redhat.com> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- blockdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blockdev.c b/blockdev.c index 9dd88d14d0..3f1dec6242 100644 --- a/blockdev.c +++ b/blockdev.c @@ -2448,7 +2448,7 @@ void coroutine_fn qmp_block_resize(bool has_device, const char *device, bdrv_co_unlock(bs); old_ctx = bdrv_co_enter(bs); - blk_truncate(blk, size, false, PREALLOC_MODE_OFF, 0, errp); + blk_co_truncate(blk, size, false, PREALLOC_MODE_OFF, 0, errp); bdrv_co_leave(bs, old_ctx); bdrv_co_lock(bs); From be8da05b5ed8fb546731b9edb997f303f272bad8 Mon Sep 17 00:00:00 2001 From: Emanuele Giuseppe Esposito Date: Thu, 27 Oct 2022 03:27:26 -0400 Subject: [PATCH 294/705] block/block-backend: blk_set_enable_write_cache is IO_CODE blk_set_enable_write_cache() is defined as GLOBAL_STATE_CODE but can be invoked from iothreads when handling scsi requests. This triggers an assertion failure: 0x00007fd6c3515ce1 in raise () from /lib/x86_64-linux-gnu/libc.so.6 0x00007fd6c34ff537 in abort () from /lib/x86_64-linux-gnu/libc.so.6 0x00007fd6c34ff40f in ?? () from /lib/x86_64-linux-gnu/libc.so.6 0x00007fd6c350e662 in __assert_fail () from /lib/x86_64-linux-gnu/libc.so.6 0x000056149e2cea03 in blk_set_enable_write_cache (wce=true, blk=0x5614a01c27f0) at ../src/block/block-backend.c:1949 0x000056149e2d0a67 in blk_set_enable_write_cache (blk=0x5614a01c27f0, wce=) at ../src/block/block-backend.c:1951 0x000056149dfe9c59 in scsi_disk_apply_mode_select (p=0x7fd6b400c00e "\004", page=, s=) at ../src/hw/scsi/scsi-disk.c:1520 mode_select_pages (change=true, len=18, p=0x7fd6b400c00e "\004", r=0x7fd6b4001ff0) at ../src/hw/scsi/scsi-disk.c:1570 scsi_disk_emulate_mode_select (inbuf=, r=0x7fd6b4001ff0) at ../src/hw/scsi/scsi-disk.c:1640 scsi_disk_emulate_write_data (req=0x7fd6b4001ff0) at ../src/hw/scsi/scsi-disk.c:1934 0x000056149e18ff16 in virtio_scsi_handle_cmd_req_submit (req=, req=, s=0x5614a12f16b0) at ../src/hw/scsi/virtio-scsi.c:719 virtio_scsi_handle_cmd_vq (vq=0x7fd6bab92140, s=0x5614a12f16b0) at ../src/hw/scsi/virtio-scsi.c:761 virtio_scsi_handle_cmd (vq=, vdev=) at ../src/hw/scsi/virtio-scsi.c:775 virtio_scsi_handle_cmd (vdev=0x5614a12f16b0, vq=0x7fd6bab92140) at ../src/hw/scsi/virtio-scsi.c:765 0x000056149e1a8aa6 in virtio_queue_notify_vq (vq=0x7fd6bab92140) at ../src/hw/virtio/virtio.c:2365 0x000056149e3ccea5 in aio_dispatch_handler (ctx=ctx@entry=0x5614a01babe0, node=) at ../src/util/aio-posix.c:369 0x000056149e3cd868 in aio_dispatch_ready_handlers (ready_list=0x7fd6c09b2680, ctx=0x5614a01babe0) at ../src/util/aio-posix.c:399 aio_poll (ctx=0x5614a01babe0, blocking=blocking@entry=true) at ../src/util/aio-posix.c:713 0x000056149e2a7796 in iothread_run (opaque=opaque@entry=0x56149ffde500) at ../src/iothread.c:67 0x000056149e3d0859 in qemu_thread_start (args=0x7fd6c09b26f0) at ../src/util/qemu-thread-posix.c:504 0x00007fd6c36b9ea7 in start_thread () from /lib/x86_64-linux-gnu/libpthread.so.0 0x00007fd6c35d9aef in clone () from /lib/x86_64-linux-gnu/libc.so.6 Changing GLOBAL_STATE_CODE in IO_CODE is allowed, since GSC callers are allowed to call IO_CODE. Resolves: #1272 Signed-off-by: Emanuele Giuseppe Esposito Message-Id: <20221027072726.2681500-1-eesposit@redhat.com> Reviewed-by: Kevin Wolf Reviewed-by: Hanna Reitz Tested-by: Antoine Damhet Signed-off-by: Kevin Wolf --- block/block-backend.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/block-backend.c b/block/block-backend.c index 705afef9b3..ec17dc49a9 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -1944,7 +1944,7 @@ bool blk_enable_write_cache(BlockBackend *blk) void blk_set_enable_write_cache(BlockBackend *blk, bool wce) { - GLOBAL_STATE_CODE(); + IO_CODE(); blk->enable_write_cache = wce; } From df8d07081718c29d04d106583d9c300128686cda Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Thu, 20 Oct 2022 11:58:45 +0200 Subject: [PATCH 295/705] virtio-net: fix bottom-half packet TX on asynchronous completion When virtio-net is used with the socket netdev backend, the backend can be busy and not able to collect new packets. In this case, net_socket_receive() returns 0 and registers a poll function to detect when the socket is ready again. In virtio_net_tx_bh(), virtio_net_flush_tx() forwards the 0, the virtio notifications are disabled and the function is not re-scheduled, waiting for the backend to be ready. When the socket netdev backend is again able to send packets, the poll function re-starts to flush remaining packets. This is done by calling virtio_net_tx_complete(). It re-enables notifications and calls again virtio_net_flush_tx(). But it seems if virtio_net_flush_tx() reaches the tx_burst value all the queue is not flushed and no new notification is sent to re-schedule virtio_net_tx_bh(). Nothing re-start to flush the queue and remaining packets are stuck in the queue. To fix that, detect in virtio_net_tx_complete() if virtio_net_flush_tx() has been stopped by tx_burst and if yes re-schedule the bottom half function virtio_net_tx_bh() to flush the remaining packets. This is what is done in virtio_net_tx_bh() when the virtio_net_flush_tx() is synchronous, and completly by-passed when the operation needs to be asynchronous. Fixes: a697a334b3c4 ("virtio-net: Introduce a new bottom half packet TX") Cc: alex.williamson@redhat.com Signed-off-by: Laurent Vivier Reviewed-by: Michael S. Tsirkin Acked-by: Michael S. Tsirkin Signed-off-by: Jason Wang --- hw/net/virtio-net.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index e9f696b4cf..1fbf2f3e19 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -2526,6 +2526,7 @@ static void virtio_net_tx_complete(NetClientState *nc, ssize_t len) VirtIONet *n = qemu_get_nic_opaque(nc); VirtIONetQueue *q = virtio_net_get_subqueue(nc); VirtIODevice *vdev = VIRTIO_DEVICE(n); + int ret; virtqueue_push(q->tx_vq, q->async_tx.elem, 0); virtio_notify(vdev, q->tx_vq); @@ -2534,7 +2535,17 @@ static void virtio_net_tx_complete(NetClientState *nc, ssize_t len) q->async_tx.elem = NULL; virtio_queue_set_notification(q->tx_vq, 1); - virtio_net_flush_tx(q); + ret = virtio_net_flush_tx(q); + if (q->tx_bh && ret >= n->tx_burst) { + /* + * the flush has been stopped by tx_burst + * we will not receive notification for the + * remainining part, so re-schedule + */ + virtio_queue_set_notification(q->tx_vq, 0); + qemu_bh_schedule(q->tx_bh); + q->tx_waiting = 1; + } } /* TX */ From 7550a82259fcf9ce5f1f6443ced779d0eb8afdca Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Thu, 20 Oct 2022 11:58:46 +0200 Subject: [PATCH 296/705] virtio-net: fix TX timer with tx_burst When virtio_net_flush_tx() reaches the tx_burst value all the queue is not flushed and nothing restart the timer. Fix that by doing for TX timer as we do for bottom half TX: rearming the timer if we find any packet to send during the virtio_net_flush_tx() call. Fixes: e3f30488e5f8 ("virtio-net: Limit number of packets sent per TX flush") Cc: alex.williamson@redhat.com Signed-off-by: Laurent Vivier Reviewed-by: Michael S. Tsirkin Signed-off-by: Jason Wang --- hw/net/virtio-net.c | 50 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 1fbf2f3e19..b6903aea54 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -2536,14 +2536,19 @@ static void virtio_net_tx_complete(NetClientState *nc, ssize_t len) virtio_queue_set_notification(q->tx_vq, 1); ret = virtio_net_flush_tx(q); - if (q->tx_bh && ret >= n->tx_burst) { + if (ret >= n->tx_burst) { /* * the flush has been stopped by tx_burst * we will not receive notification for the * remainining part, so re-schedule */ virtio_queue_set_notification(q->tx_vq, 0); - qemu_bh_schedule(q->tx_bh); + if (q->tx_bh) { + qemu_bh_schedule(q->tx_bh); + } else { + timer_mod(q->tx_timer, + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + n->tx_timeout); + } q->tx_waiting = 1; } } @@ -2644,6 +2649,8 @@ drop: return num_packets; } +static void virtio_net_tx_timer(void *opaque); + static void virtio_net_handle_tx_timer(VirtIODevice *vdev, VirtQueue *vq) { VirtIONet *n = VIRTIO_NET(vdev); @@ -2661,15 +2668,13 @@ static void virtio_net_handle_tx_timer(VirtIODevice *vdev, VirtQueue *vq) } if (q->tx_waiting) { - virtio_queue_set_notification(vq, 1); + /* We already have queued packets, immediately flush */ timer_del(q->tx_timer); - q->tx_waiting = 0; - if (virtio_net_flush_tx(q) == -EINVAL) { - return; - } + virtio_net_tx_timer(q); } else { + /* re-arm timer to flush it (and more) on next tick */ timer_mod(q->tx_timer, - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + n->tx_timeout); + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + n->tx_timeout); q->tx_waiting = 1; virtio_queue_set_notification(vq, 0); } @@ -2702,6 +2707,8 @@ static void virtio_net_tx_timer(void *opaque) VirtIONetQueue *q = opaque; VirtIONet *n = q->n; VirtIODevice *vdev = VIRTIO_DEVICE(n); + int ret; + /* This happens when device was stopped but BH wasn't. */ if (!vdev->vm_running) { /* Make sure tx waiting is set, so we'll run when restarted. */ @@ -2716,8 +2723,33 @@ static void virtio_net_tx_timer(void *opaque) return; } + ret = virtio_net_flush_tx(q); + if (ret == -EBUSY || ret == -EINVAL) { + return; + } + /* + * If we flush a full burst of packets, assume there are + * more coming and immediately rearm + */ + if (ret >= n->tx_burst) { + q->tx_waiting = 1; + timer_mod(q->tx_timer, + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + n->tx_timeout); + return; + } + /* + * If less than a full burst, re-enable notification and flush + * anything that may have come in while we weren't looking. If + * we find something, assume the guest is still active and rearm + */ virtio_queue_set_notification(q->tx_vq, 1); - virtio_net_flush_tx(q); + ret = virtio_net_flush_tx(q); + if (ret > 0) { + virtio_queue_set_notification(q->tx_vq, 0); + q->tx_waiting = 1; + timer_mod(q->tx_timer, + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + n->tx_timeout); + } } static void virtio_net_tx_bh(void *opaque) From faa825ddb3f116c2aa4db0ab5ed72bd093f39337 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= Date: Thu, 20 Oct 2022 10:00:58 +0200 Subject: [PATCH 297/705] vdpa: Delete duplicated vdpa_feature_bits entry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This entry was duplicated on referenced commit. Removing it. Fixes: 402378407dbd ("vhost-vdpa: multiqueue support") Signed-off-by: Eugenio Pérez Acked-by: Jason Wang Signed-off-by: Jason Wang --- net/vhost-vdpa.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c index 4bc3fd01a8..eebf29f5c1 100644 --- a/net/vhost-vdpa.c +++ b/net/vhost-vdpa.c @@ -63,7 +63,6 @@ const int vdpa_feature_bits[] = { VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_RX_EXTRA, VIRTIO_NET_F_CTRL_VLAN, - VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_CTRL_MAC_ADDR, VIRTIO_NET_F_RSS, VIRTIO_NET_F_MQ, From 6ce262fbe7744a3d82d872e232fd0d39cfba0363 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= Date: Thu, 20 Oct 2022 10:02:30 +0200 Subject: [PATCH 298/705] vdpa: Remove shadow CVQ command check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The guest will see undefined behavior if it issue not negotiate commands, bit it is expected somehow. Simplify code deleting this check. Signed-off-by: Eugenio Pérez Acked-by: Jason Wang Signed-off-by: Jason Wang --- net/vhost-vdpa.c | 48 ------------------------------------------------ 1 file changed, 48 deletions(-) diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c index eebf29f5c1..6d64000202 100644 --- a/net/vhost-vdpa.c +++ b/net/vhost-vdpa.c @@ -461,48 +461,6 @@ static NetClientInfo net_vhost_vdpa_cvq_info = { .check_peer_type = vhost_vdpa_check_peer_type, }; -/** - * Do not forward commands not supported by SVQ. Otherwise, the device could - * accept it and qemu would not know how to update the device model. - */ -static bool vhost_vdpa_net_cvq_validate_cmd(const void *out_buf, size_t len) -{ - struct virtio_net_ctrl_hdr ctrl; - - if (unlikely(len < sizeof(ctrl))) { - qemu_log_mask(LOG_GUEST_ERROR, - "%s: invalid legnth of out buffer %zu\n", __func__, len); - return false; - } - - memcpy(&ctrl, out_buf, sizeof(ctrl)); - switch (ctrl.class) { - case VIRTIO_NET_CTRL_MAC: - switch (ctrl.cmd) { - case VIRTIO_NET_CTRL_MAC_ADDR_SET: - return true; - default: - qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid mac cmd %u\n", - __func__, ctrl.cmd); - }; - break; - case VIRTIO_NET_CTRL_MQ: - switch (ctrl.cmd) { - case VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET: - return true; - default: - qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid mq cmd %u\n", - __func__, ctrl.cmd); - }; - break; - default: - qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid control class %u\n", - __func__, ctrl.class); - }; - - return false; -} - /** * Validate and copy control virtqueue commands. * @@ -526,16 +484,10 @@ static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq, .iov_len = sizeof(status), }; ssize_t dev_written = -EINVAL; - bool ok; out.iov_len = iov_to_buf(elem->out_sg, elem->out_num, 0, s->cvq_cmd_out_buffer, vhost_vdpa_net_cvq_cmd_len()); - ok = vhost_vdpa_net_cvq_validate_cmd(s->cvq_cmd_out_buffer, out.iov_len); - if (unlikely(!ok)) { - goto out; - } - dev_written = vhost_vdpa_net_cvq_add(s, out.iov_len, sizeof(status)); if (unlikely(dev_written < 0)) { goto out; From 8801ccd0500437a86e3d15a806f37ebb84605dce Mon Sep 17 00:00:00 2001 From: Si-Wei Liu Date: Sat, 8 Oct 2022 00:58:58 -0700 Subject: [PATCH 299/705] vhost-vdpa: allow passing opened vhostfd to vhost-vdpa MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Similar to other vhost backends, vhostfd can be passed to vhost-vdpa backend as another parameter to instantiate vhost-vdpa net client. This would benefit the use case where only open file descriptors, as opposed to raw vhost-vdpa device paths, are accessible from the QEMU process. (qemu) netdev_add type=vhost-vdpa,vhostfd=61,id=vhost-vdpa1 Signed-off-by: Si-Wei Liu Acked-by: Eugenio Pérez Signed-off-by: Jason Wang --- net/vhost-vdpa.c | 25 ++++++++++++++++++++----- qapi/net.json | 3 +++ qemu-options.hx | 6 ++++-- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c index 6d64000202..9c1b25d782 100644 --- a/net/vhost-vdpa.c +++ b/net/vhost-vdpa.c @@ -634,14 +634,29 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name, assert(netdev->type == NET_CLIENT_DRIVER_VHOST_VDPA); opts = &netdev->u.vhost_vdpa; - if (!opts->vhostdev) { - error_setg(errp, "vdpa character device not specified with vhostdev"); + if (!opts->has_vhostdev && !opts->has_vhostfd) { + error_setg(errp, + "vhost-vdpa: neither vhostdev= nor vhostfd= was specified"); return -1; } - vdpa_device_fd = qemu_open(opts->vhostdev, O_RDWR, errp); - if (vdpa_device_fd == -1) { - return -errno; + if (opts->has_vhostdev && opts->has_vhostfd) { + error_setg(errp, + "vhost-vdpa: vhostdev= and vhostfd= are mutually exclusive"); + return -1; + } + + if (opts->has_vhostdev) { + vdpa_device_fd = qemu_open(opts->vhostdev, O_RDWR, errp); + if (vdpa_device_fd == -1) { + return -errno; + } + } else if (opts->has_vhostfd) { + vdpa_device_fd = monitor_fd_param(monitor_cur(), opts->vhostfd, errp); + if (vdpa_device_fd == -1) { + error_prepend(errp, "vhost-vdpa: unable to parse vhostfd: "); + return -1; + } } r = vhost_vdpa_get_features(vdpa_device_fd, &features, errp); diff --git a/qapi/net.json b/qapi/net.json index dd088c09c5..926ecc8cca 100644 --- a/qapi/net.json +++ b/qapi/net.json @@ -442,6 +442,8 @@ # @vhostdev: path of vhost-vdpa device # (default:'/dev/vhost-vdpa-0') # +# @vhostfd: file descriptor of an already opened vhost vdpa device +# # @queues: number of queues to be created for multiqueue vhost-vdpa # (default: 1) # @@ -456,6 +458,7 @@ { 'struct': 'NetdevVhostVDPAOptions', 'data': { '*vhostdev': 'str', + '*vhostfd': 'str', '*queues': 'int', '*x-svq': {'type': 'bool', 'features' : [ 'unstable'] } } } diff --git a/qemu-options.hx b/qemu-options.hx index eb38e5dc40..876a70aa63 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -2790,8 +2790,10 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev, " configure a vhost-user network, backed by a chardev 'dev'\n" #endif #ifdef __linux__ - "-netdev vhost-vdpa,id=str,vhostdev=/path/to/dev\n" + "-netdev vhost-vdpa,id=str[,vhostdev=/path/to/dev][,vhostfd=h]\n" " configure a vhost-vdpa network,Establish a vhost-vdpa netdev\n" + " use 'vhostdev=/path/to/dev' to open a vhost vdpa device\n" + " use 'vhostfd=h' to connect to an already opened vhost vdpa device\n" #endif #ifdef CONFIG_VMNET "-netdev vmnet-host,id=str[,isolated=on|off][,net-uuid=uuid]\n" @@ -3296,7 +3298,7 @@ SRST -netdev type=vhost-user,id=net0,chardev=chr0 \ -device virtio-net-pci,netdev=net0 -``-netdev vhost-vdpa,vhostdev=/path/to/dev`` +``-netdev vhost-vdpa[,vhostdev=/path/to/dev][,vhostfd=h]`` Establish a vhost-vdpa netdev. vDPA device is a device that uses a datapath which complies with From 7d0e12af59286f3784c3ab7502325fc6a051d117 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Mon, 3 Oct 2022 11:06:12 +0100 Subject: [PATCH 300/705] net: improve error message for missing netdev backend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current message when using '-net user...' with SLIRP disabled at compile time is: qemu-system-x86_64: -net user: Parameter 'type' expects a net backend type (maybe it is not compiled into this binary) An observation is that we're using the 'netdev->type' field here which is an enum value, produced after QAPI has converted from its string form. IOW, at this point in the code, we know that the user's specified type name was a valid network backend. The only possible scenario that can make the backend init function be NULL, is if support for that backend was disabled at build time. Given this, we don't need to caveat our error message with a 'maybe' hint, we can be totally explicit. The use of QERR_INVALID_PARAMETER_VALUE doesn't really lend itself to user friendly error message text. Since this is not used to set a specific QAPI error class, we can simply stop using this pre-formatted error text and provide something better. Thus the new message is: qemu-system-x86_64: -net user: network backend 'user' is not compiled into this binary The case of passing 'hubport' for -net is also given a message reminding people they should have used -netdev/-nic instead, as this backend type is only valid for the modern syntax. Reviewed-by: Marc-André Lureau Reviewed-by: Thomas Huth Signed-off-by: Daniel P. Berrangé Signed-off-by: Jason Wang --- net/net.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/net/net.c b/net/net.c index 2db160e063..8ddafacf13 100644 --- a/net/net.c +++ b/net/net.c @@ -1036,19 +1036,23 @@ static int net_client_init1(const Netdev *netdev, bool is_netdev, Error **errp) if (is_netdev) { if (netdev->type == NET_CLIENT_DRIVER_NIC || !net_client_init_fun[netdev->type]) { - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "type", - "a netdev backend type"); + error_setg(errp, "network backend '%s' is not compiled into this binary", + NetClientDriver_str(netdev->type)); return -1; } } else { if (netdev->type == NET_CLIENT_DRIVER_NONE) { return 0; /* nothing to do */ } - if (netdev->type == NET_CLIENT_DRIVER_HUBPORT || - !net_client_init_fun[netdev->type]) { - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "type", - "a net backend type (maybe it is not compiled " - "into this binary)"); + if (netdev->type == NET_CLIENT_DRIVER_HUBPORT) { + error_setg(errp, "network backend '%s' is only supported with -netdev/-nic", + NetClientDriver_str(netdev->type)); + return -1; + } + + if (!net_client_init_fun[netdev->type]) { + error_setg(errp, "network backend '%s' is not compiled into this binary", + NetClientDriver_str(netdev->type)); return -1; } From f0c48e05bd7c535aa0614d284d165d998936c79b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= Date: Thu, 20 Oct 2022 17:52:48 +0200 Subject: [PATCH 301/705] vhost: allocate event_idx fields on vring MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There was not enough room to accomodate them. Reviewed-by: Michael S. Tsirkin Signed-off-by: Eugenio Pérez Signed-off-by: Jason Wang --- hw/virtio/vhost-shadow-virtqueue.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c index 596d4434d2..a518f84772 100644 --- a/hw/virtio/vhost-shadow-virtqueue.c +++ b/hw/virtio/vhost-shadow-virtqueue.c @@ -570,16 +570,16 @@ void vhost_svq_get_vring_addr(const VhostShadowVirtqueue *svq, size_t vhost_svq_driver_area_size(const VhostShadowVirtqueue *svq) { size_t desc_size = sizeof(vring_desc_t) * svq->vring.num; - size_t avail_size = offsetof(vring_avail_t, ring) + - sizeof(uint16_t) * svq->vring.num; + size_t avail_size = offsetof(vring_avail_t, ring[svq->vring.num]) + + sizeof(uint16_t); return ROUND_UP(desc_size + avail_size, qemu_real_host_page_size()); } size_t vhost_svq_device_area_size(const VhostShadowVirtqueue *svq) { - size_t used_size = offsetof(vring_used_t, ring) + - sizeof(vring_used_elem_t) * svq->vring.num; + size_t used_size = offsetof(vring_used_t, ring[svq->vring.num]) + + sizeof(uint16_t); return ROUND_UP(used_size, qemu_real_host_page_size()); } From 01f8beacea2a31edb6c270653052bea2778ae65d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= Date: Thu, 20 Oct 2022 17:52:49 +0200 Subject: [PATCH 302/705] vhost: toggle device callbacks using used event idx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Actually use the new field of the used ring and tell the device if SVQ wants to be notified. The code is not reachable at the moment. Reviewed-by: Michael S. Tsirkin Signed-off-by: Eugenio Pérez Signed-off-by: Jason Wang --- hw/virtio/vhost-shadow-virtqueue.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c index a518f84772..f5c0fad3fc 100644 --- a/hw/virtio/vhost-shadow-virtqueue.c +++ b/hw/virtio/vhost-shadow-virtqueue.c @@ -369,15 +369,27 @@ static bool vhost_svq_more_used(VhostShadowVirtqueue *svq) */ static bool vhost_svq_enable_notification(VhostShadowVirtqueue *svq) { - svq->vring.avail->flags &= ~cpu_to_le16(VRING_AVAIL_F_NO_INTERRUPT); - /* Make sure the flag is written before the read of used_idx */ + if (virtio_vdev_has_feature(svq->vdev, VIRTIO_RING_F_EVENT_IDX)) { + uint16_t *used_event = (uint16_t *)&svq->vring.avail->ring[svq->vring.num]; + *used_event = svq->shadow_used_idx; + } else { + svq->vring.avail->flags &= ~cpu_to_le16(VRING_AVAIL_F_NO_INTERRUPT); + } + + /* Make sure the event is enabled before the read of used_idx */ smp_mb(); return !vhost_svq_more_used(svq); } static void vhost_svq_disable_notification(VhostShadowVirtqueue *svq) { - svq->vring.avail->flags |= cpu_to_le16(VRING_AVAIL_F_NO_INTERRUPT); + /* + * No need to disable notification in the event idx case, since used event + * index is already an index too far away. + */ + if (!virtio_vdev_has_feature(svq->vdev, VIRTIO_RING_F_EVENT_IDX)) { + svq->vring.avail->flags |= cpu_to_le16(VRING_AVAIL_F_NO_INTERRUPT); + } } static uint16_t vhost_svq_last_desc_of_chain(const VhostShadowVirtqueue *svq, From 22a6840ff282727df3e3c745d92d764c7081f49b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= Date: Thu, 20 Oct 2022 17:52:50 +0200 Subject: [PATCH 303/705] vhost: use avail event idx on vhost_svq_kick MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So SVQ code knows if an event is needed. The code is not reachable at the moment. Reviewed-by: Michael S. Tsirkin Signed-off-by: Eugenio Pérez Signed-off-by: Jason Wang --- hw/virtio/vhost-shadow-virtqueue.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c index f5c0fad3fc..f306ebef72 100644 --- a/hw/virtio/vhost-shadow-virtqueue.c +++ b/hw/virtio/vhost-shadow-virtqueue.c @@ -218,12 +218,22 @@ static bool vhost_svq_add_split(VhostShadowVirtqueue *svq, static void vhost_svq_kick(VhostShadowVirtqueue *svq) { + bool needs_kick; + /* * We need to expose the available array entries before checking the used * flags */ smp_mb(); - if (svq->vring.used->flags & VRING_USED_F_NO_NOTIFY) { + + if (virtio_vdev_has_feature(svq->vdev, VIRTIO_RING_F_EVENT_IDX)) { + uint16_t avail_event = *(uint16_t *)(&svq->vring.used->ring[svq->vring.num]); + needs_kick = vring_need_event(avail_event, svq->shadow_avail_idx, svq->shadow_avail_idx - 1); + } else { + needs_kick = !(svq->vring.used->flags & VRING_USED_F_NO_NOTIFY); + } + + if (!needs_kick) { return; } From 396d512669dccea2bb982685870356ab71e956ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= Date: Thu, 20 Oct 2022 17:52:51 +0200 Subject: [PATCH 304/705] vhost: Accept event idx flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enabling all the code path created before. Reviewed-by: Michael S. Tsirkin Signed-off-by: Eugenio Pérez Signed-off-by: Jason Wang --- hw/virtio/vhost-shadow-virtqueue.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c index f306ebef72..5bd14cad96 100644 --- a/hw/virtio/vhost-shadow-virtqueue.c +++ b/hw/virtio/vhost-shadow-virtqueue.c @@ -33,6 +33,7 @@ bool vhost_svq_valid_features(uint64_t features, Error **errp) ++b) { switch (b) { case VIRTIO_F_ANY_LAYOUT: + case VIRTIO_RING_F_EVENT_IDX: continue; case VIRTIO_F_ACCESS_PLATFORM: From 30e4226b78f888a75dade5a2cf1488f94da3a8db Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Fri, 21 Oct 2022 11:09:06 +0200 Subject: [PATCH 305/705] net: introduce convert_host_port() Signed-off-by: Laurent Vivier Reviewed-by: Stefano Brivio Reviewed-by: David Gibson Acked-by: Michael S. Tsirkin Signed-off-by: Jason Wang --- include/qemu/sockets.h | 2 ++ net/net.c | 74 ++++++++++++++++++++++-------------------- 2 files changed, 40 insertions(+), 36 deletions(-) diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h index 036745e586..db4bedb6fa 100644 --- a/include/qemu/sockets.h +++ b/include/qemu/sockets.h @@ -65,6 +65,8 @@ void socket_listen_cleanup(int fd, Error **errp); int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp); /* Old, ipv4 only bits. Don't use for new code. */ +int convert_host_port(struct sockaddr_in *saddr, const char *host, + const char *port, Error **errp); int parse_host_port(struct sockaddr_in *saddr, const char *str, Error **errp); int socket_init(void); diff --git a/net/net.c b/net/net.c index 8ddafacf13..407bdd1f07 100644 --- a/net/net.c +++ b/net/net.c @@ -66,15 +66,47 @@ static QTAILQ_HEAD(, NetClientState) net_clients; /***********************************************************/ /* network device redirectors */ +int convert_host_port(struct sockaddr_in *saddr, const char *host, + const char *port, Error **errp) +{ + struct hostent *he; + const char *r; + long p; + + memset(saddr, 0, sizeof(*saddr)); + + saddr->sin_family = AF_INET; + if (host[0] == '\0') { + saddr->sin_addr.s_addr = 0; + } else { + if (qemu_isdigit(host[0])) { + if (!inet_aton(host, &saddr->sin_addr)) { + error_setg(errp, "host address '%s' is not a valid " + "IPv4 address", host); + return -1; + } + } else { + he = gethostbyname(host); + if (he == NULL) { + error_setg(errp, "can't resolve host address '%s'", host); + return -1; + } + saddr->sin_addr = *(struct in_addr *)he->h_addr; + } + } + if (qemu_strtol(port, &r, 0, &p) != 0) { + error_setg(errp, "port number '%s' is invalid", port); + return -1; + } + saddr->sin_port = htons(p); + return 0; +} + int parse_host_port(struct sockaddr_in *saddr, const char *str, Error **errp) { gchar **substrings; - struct hostent *he; - const char *addr, *p, *r; - int port, ret = 0; - - memset(saddr, 0, sizeof(*saddr)); + int ret; substrings = g_strsplit(str, ":", 2); if (!substrings || !substrings[0] || !substrings[1]) { @@ -84,37 +116,7 @@ int parse_host_port(struct sockaddr_in *saddr, const char *str, goto out; } - addr = substrings[0]; - p = substrings[1]; - - saddr->sin_family = AF_INET; - if (addr[0] == '\0') { - saddr->sin_addr.s_addr = 0; - } else { - if (qemu_isdigit(addr[0])) { - if (!inet_aton(addr, &saddr->sin_addr)) { - error_setg(errp, "host address '%s' is not a valid " - "IPv4 address", addr); - ret = -1; - goto out; - } - } else { - he = gethostbyname(addr); - if (he == NULL) { - error_setg(errp, "can't resolve host address '%s'", addr); - ret = -1; - goto out; - } - saddr->sin_addr = *(struct in_addr *)he->h_addr; - } - } - port = strtol(p, (char **)&r, 0); - if (r == p) { - error_setg(errp, "port number '%s' is invalid", p); - ret = -1; - goto out; - } - saddr->sin_port = htons(port); + ret = convert_host_port(saddr, substrings[0], substrings[1], errp); out: g_strfreev(substrings); From d63ef17bfcba1126df6bfcb7bca64c96ac4a8d99 Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Fri, 21 Oct 2022 11:09:07 +0200 Subject: [PATCH 306/705] net: remove the @errp argument of net_client_inits() The only caller passes &error_fatal, so use this directly in the function. It's what we do for -blockdev, -device, and -object. Suggested-by: Markus Armbruster Signed-off-by: Laurent Vivier Reviewed-by: Markus Armbruster Reviewed-by: David Gibson Acked-by: Michael S. Tsirkin Signed-off-by: Jason Wang --- include/net/net.h | 2 +- net/net.c | 20 +++++++------------- softmmu/vl.c | 2 +- 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/include/net/net.h b/include/net/net.h index 81d0b21def..c1c34a58f8 100644 --- a/include/net/net.h +++ b/include/net/net.h @@ -222,7 +222,7 @@ extern const char *host_net_devices[]; /* from net.c */ int net_client_parse(QemuOptsList *opts_list, const char *str); void show_netdevs(void); -int net_init_clients(Error **errp); +void net_init_clients(void); void net_check_clients(void); void net_cleanup(void); void hmp_host_net_add(Monitor *mon, const QDict *qdict); diff --git a/net/net.c b/net/net.c index 407bdd1f07..5e788802b1 100644 --- a/net/net.c +++ b/net/net.c @@ -1566,27 +1566,21 @@ out: return ret; } -int net_init_clients(Error **errp) +void net_init_clients(void) { net_change_state_entry = qemu_add_vm_change_state_handler(net_vm_change_state_handler, NULL); QTAILQ_INIT(&net_clients); - if (qemu_opts_foreach(qemu_find_opts("netdev"), - net_init_netdev, NULL, errp)) { - return -1; - } + qemu_opts_foreach(qemu_find_opts("netdev"), net_init_netdev, NULL, + &error_fatal); - if (qemu_opts_foreach(qemu_find_opts("nic"), net_param_nic, NULL, errp)) { - return -1; - } + qemu_opts_foreach(qemu_find_opts("nic"), net_param_nic, NULL, + &error_fatal); - if (qemu_opts_foreach(qemu_find_opts("net"), net_init_client, NULL, errp)) { - return -1; - } - - return 0; + qemu_opts_foreach(qemu_find_opts("net"), net_init_client, NULL, + &error_fatal); } int net_client_parse(QemuOptsList *opts_list, const char *optarg) diff --git a/softmmu/vl.c b/softmmu/vl.c index b464da25bc..a4ae131e4d 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -1904,7 +1904,7 @@ static void qemu_create_late_backends(void) qtest_server_init(qtest_chrdev, qtest_log, &error_fatal); } - net_init_clients(&error_fatal); + net_init_clients(); object_option_foreach_add(object_create_late); From 21fccb2cbbacdc045f19605915e847de31ca9862 Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Fri, 21 Oct 2022 11:09:08 +0200 Subject: [PATCH 307/705] net: simplify net_client_parse() error management All net_client_parse() callers exit in case of error. Move exit(1) to net_client_parse() and remove error checking from the callers. Suggested-by: Markus Armbruster Signed-off-by: Laurent Vivier Reviewed-by: Markus Armbruster Reviewed-by: David Gibson Acked-by: Michael S. Tsirkin Signed-off-by: Jason Wang --- include/net/net.h | 2 +- net/net.c | 6 ++---- softmmu/vl.c | 12 +++--------- 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/include/net/net.h b/include/net/net.h index c1c34a58f8..55023e7e9f 100644 --- a/include/net/net.h +++ b/include/net/net.h @@ -220,7 +220,7 @@ extern NICInfo nd_table[MAX_NICS]; extern const char *host_net_devices[]; /* from net.c */ -int net_client_parse(QemuOptsList *opts_list, const char *str); +void net_client_parse(QemuOptsList *opts_list, const char *str); void show_netdevs(void); void net_init_clients(void); void net_check_clients(void); diff --git a/net/net.c b/net/net.c index 5e788802b1..178257abfd 100644 --- a/net/net.c +++ b/net/net.c @@ -1583,13 +1583,11 @@ void net_init_clients(void) &error_fatal); } -int net_client_parse(QemuOptsList *opts_list, const char *optarg) +void net_client_parse(QemuOptsList *opts_list, const char *optarg) { if (!qemu_opts_parse_noisily(opts_list, optarg, true)) { - return -1; + exit(1); } - - return 0; } /* From FreeBSD */ diff --git a/softmmu/vl.c b/softmmu/vl.c index a4ae131e4d..e69aa43de4 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -2801,21 +2801,15 @@ void qemu_init(int argc, char **argv) break; case QEMU_OPTION_netdev: default_net = 0; - if (net_client_parse(qemu_find_opts("netdev"), optarg) == -1) { - exit(1); - } + net_client_parse(qemu_find_opts("netdev"), optarg); break; case QEMU_OPTION_nic: default_net = 0; - if (net_client_parse(qemu_find_opts("nic"), optarg) == -1) { - exit(1); - } + net_client_parse(qemu_find_opts("nic"), optarg); break; case QEMU_OPTION_net: default_net = 0; - if (net_client_parse(qemu_find_opts("net"), optarg) == -1) { - exit(1); - } + net_client_parse(qemu_find_opts("net"), optarg); break; #ifdef CONFIG_LIBISCSI case QEMU_OPTION_iscsi: From f3eedcddba36dddfb7769a8c96a0f710e894ffc0 Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Fri, 21 Oct 2022 11:09:09 +0200 Subject: [PATCH 308/705] qapi: net: introduce a way to bypass qemu_opts_parse_noisily() As qemu_opts_parse_noisily() flattens the QAPI structures ("type" field of Netdev structure can collides with "type" field of SocketAddress), we introduce a way to bypass qemu_opts_parse_noisily() and use directly visit_type_Netdev() to parse the backend parameters. More details from Markus: qemu_init() passes the argument of -netdev, -nic, and -net to net_client_parse(). net_client_parse() parses with qemu_opts_parse_noisily(), passing QemuOptsList qemu_netdev_opts for -netdev, qemu_nic_opts for -nic, and qemu_net_opts for -net. Their desc[] are all empty, which means any keys are accepted. The result of the parse (a QemuOpts) is stored in the QemuOptsList. Note that QemuOpts is flat by design. In some places, we layer non-flat on top using dotted keys convention, but not here. net_init_clients() iterates over the stored QemuOpts, and passes them to net_init_netdev(), net_param_nic(), or net_init_client(), respectively. These functions pass the QemuOpts to net_client_init(). They also do other things with the QemuOpts, which we can ignore here. net_client_init() uses the opts visitor to convert the (flat) QemOpts to a (non-flat) QAPI object Netdev. Netdev is also the argument of QMP command netdev_add. The opts visitor was an early attempt to support QAPI in (QemuOpts-based) CLI. It restricts QAPI types to a certain shape; see commit eb7ee2cbeb "qapi: introduce OptsVisitor". A more modern way to support QAPI is qobject_input_visitor_new_str(). It uses keyval_parse() instead of QemuOpts for KEY=VALUE,... syntax, and it also supports JSON syntax. The former isn't quite as expressive as JSON, but it's a lot closer than QemuOpts + opts visitor. This commit paves the way to use of the modern way instead. Signed-off-by: Laurent Vivier Reviewed-by: Markus Armbruster Acked-by: Michael S. Tsirkin Signed-off-by: Jason Wang --- include/net/net.h | 2 ++ net/net.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++ softmmu/vl.c | 6 ++++- 3 files changed, 64 insertions(+), 1 deletion(-) diff --git a/include/net/net.h b/include/net/net.h index 55023e7e9f..025dbf1e14 100644 --- a/include/net/net.h +++ b/include/net/net.h @@ -220,6 +220,8 @@ extern NICInfo nd_table[MAX_NICS]; extern const char *host_net_devices[]; /* from net.c */ +bool netdev_is_modern(const char *optarg); +void netdev_parse_modern(const char *optarg); void net_client_parse(QemuOptsList *opts_list, const char *str); void show_netdevs(void); void net_init_clients(void); diff --git a/net/net.c b/net/net.c index 178257abfd..128a90f1fd 100644 --- a/net/net.c +++ b/net/net.c @@ -54,6 +54,7 @@ #include "net/colo-compare.h" #include "net/filter.h" #include "qapi/string-output-visitor.h" +#include "qapi/qobject-input-visitor.h" /* Net bridge is currently not supported for W32. */ #if !defined(_WIN32) @@ -63,6 +64,16 @@ static VMChangeStateEntry *net_change_state_entry; static QTAILQ_HEAD(, NetClientState) net_clients; +typedef struct NetdevQueueEntry { + Netdev *nd; + Location loc; + QSIMPLEQ_ENTRY(NetdevQueueEntry) entry; +} NetdevQueueEntry; + +typedef QSIMPLEQ_HEAD(, NetdevQueueEntry) NetdevQueue; + +static NetdevQueue nd_queue = QSIMPLEQ_HEAD_INITIALIZER(nd_queue); + /***********************************************************/ /* network device redirectors */ @@ -1566,6 +1577,20 @@ out: return ret; } +static void netdev_init_modern(void) +{ + while (!QSIMPLEQ_EMPTY(&nd_queue)) { + NetdevQueueEntry *nd = QSIMPLEQ_FIRST(&nd_queue); + + QSIMPLEQ_REMOVE_HEAD(&nd_queue, entry); + loc_push_restore(&nd->loc); + net_client_init1(nd->nd, true, &error_fatal); + loc_pop(&nd->loc); + qapi_free_Netdev(nd->nd); + g_free(nd); + } +} + void net_init_clients(void) { net_change_state_entry = @@ -1573,6 +1598,8 @@ void net_init_clients(void) QTAILQ_INIT(&net_clients); + netdev_init_modern(); + qemu_opts_foreach(qemu_find_opts("netdev"), net_init_netdev, NULL, &error_fatal); @@ -1583,6 +1610,36 @@ void net_init_clients(void) &error_fatal); } +/* + * Does this -netdev argument use modern rather than traditional syntax? + * Modern syntax is to be parsed with netdev_parse_modern(). + * Traditional syntax is to be parsed with net_client_parse(). + */ +bool netdev_is_modern(const char *optarg) +{ + return false; +} + +/* + * netdev_parse_modern() uses modern, more expressive syntax than + * net_client_parse(), but supports only the -netdev option. + * netdev_parse_modern() appends to @nd_queue, whereas net_client_parse() + * appends to @qemu_netdev_opts. + */ +void netdev_parse_modern(const char *optarg) +{ + Visitor *v; + NetdevQueueEntry *nd; + + v = qobject_input_visitor_new_str(optarg, "type", &error_fatal); + nd = g_new(NetdevQueueEntry, 1); + visit_type_Netdev(v, NULL, &nd->nd, &error_fatal); + visit_free(v); + loc_save(&nd->loc); + + QSIMPLEQ_INSERT_TAIL(&nd_queue, nd, entry); +} + void net_client_parse(QemuOptsList *opts_list, const char *optarg) { if (!qemu_opts_parse_noisily(opts_list, optarg, true)) { diff --git a/softmmu/vl.c b/softmmu/vl.c index e69aa43de4..99fb49c7b0 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -2801,7 +2801,11 @@ void qemu_init(int argc, char **argv) break; case QEMU_OPTION_netdev: default_net = 0; - net_client_parse(qemu_find_opts("netdev"), optarg); + if (netdev_is_modern(optarg)) { + netdev_parse_modern(optarg); + } else { + net_client_parse(qemu_find_opts("netdev"), optarg); + } break; case QEMU_OPTION_nic: default_net = 0; From 53b85d9574f3c162c0aadbd988f95e207d4c6e31 Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Fri, 21 Oct 2022 11:09:10 +0200 Subject: [PATCH 309/705] net: introduce qemu_set_info_str() function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Embed the setting of info_str in a function. Signed-off-by: Laurent Vivier Reviewed-by: David Gibson Acked-by: Michael S. Tsirkin Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Jason Wang --- hw/net/xen_nic.c | 5 ++--- include/net/net.h | 1 + net/l2tpv3.c | 3 +-- net/net.c | 17 ++++++++++++----- net/slirp.c | 5 ++--- net/socket.c | 33 ++++++++++++++------------------- net/tap-win32.c | 3 +-- net/tap.c | 13 +++++-------- net/vde.c | 3 +-- net/vhost-user.c | 3 +-- net/vhost-vdpa.c | 2 +- 11 files changed, 41 insertions(+), 47 deletions(-) diff --git a/hw/net/xen_nic.c b/hw/net/xen_nic.c index 5c815b4f0c..7d92c2d022 100644 --- a/hw/net/xen_nic.c +++ b/hw/net/xen_nic.c @@ -296,9 +296,8 @@ static int net_init(struct XenLegacyDevice *xendev) netdev->nic = qemu_new_nic(&net_xen_info, &netdev->conf, "xen", NULL, netdev); - snprintf(qemu_get_queue(netdev->nic)->info_str, - sizeof(qemu_get_queue(netdev->nic)->info_str), - "nic: xenbus vif macaddr=%s", netdev->mac); + qemu_set_info_str(qemu_get_queue(netdev->nic), + "nic: xenbus vif macaddr=%s", netdev->mac); /* fill info */ xenstore_write_be_int(&netdev->xendev, "feature-rx-copy", 1); diff --git a/include/net/net.h b/include/net/net.h index 025dbf1e14..3db75ff841 100644 --- a/include/net/net.h +++ b/include/net/net.h @@ -177,6 +177,7 @@ ssize_t qemu_send_packet_async(NetClientState *nc, const uint8_t *buf, void qemu_purge_queued_packets(NetClientState *nc); void qemu_flush_queued_packets(NetClientState *nc); void qemu_flush_or_purge_queued_packets(NetClientState *nc, bool purge); +void qemu_set_info_str(NetClientState *nc, const char *fmt, ...); void qemu_format_nic_info_str(NetClientState *nc, uint8_t macaddr[6]); bool qemu_has_ufo(NetClientState *nc); bool qemu_has_vnet_hdr(NetClientState *nc); diff --git a/net/l2tpv3.c b/net/l2tpv3.c index af373e5c30..350041a0d6 100644 --- a/net/l2tpv3.c +++ b/net/l2tpv3.c @@ -723,8 +723,7 @@ int net_init_l2tpv3(const Netdev *netdev, l2tpv3_read_poll(s, true); - snprintf(s->nc.info_str, sizeof(s->nc.info_str), - "l2tpv3: connected"); + qemu_set_info_str(&s->nc, "l2tpv3: connected"); return 0; outerr: qemu_del_net_client(nc); diff --git a/net/net.c b/net/net.c index 128a90f1fd..f29a59cd7f 100644 --- a/net/net.c +++ b/net/net.c @@ -141,13 +141,20 @@ char *qemu_mac_strdup_printf(const uint8_t *macaddr) macaddr[3], macaddr[4], macaddr[5]); } +void qemu_set_info_str(NetClientState *nc, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vsnprintf(nc->info_str, sizeof(nc->info_str), fmt, ap); + va_end(ap); +} + void qemu_format_nic_info_str(NetClientState *nc, uint8_t macaddr[6]) { - snprintf(nc->info_str, sizeof(nc->info_str), - "model=%s,macaddr=%02x:%02x:%02x:%02x:%02x:%02x", - nc->model, - macaddr[0], macaddr[1], macaddr[2], - macaddr[3], macaddr[4], macaddr[5]); + qemu_set_info_str(nc, "model=%s,macaddr=%02x:%02x:%02x:%02x:%02x:%02x", + nc->model, macaddr[0], macaddr[1], macaddr[2], + macaddr[3], macaddr[4], macaddr[5]); } static int mac_table[256] = {0}; diff --git a/net/slirp.c b/net/slirp.c index 8679be6444..14a8d59277 100644 --- a/net/slirp.c +++ b/net/slirp.c @@ -611,9 +611,8 @@ static int net_slirp_init(NetClientState *peer, const char *model, nc = qemu_new_net_client(&net_slirp_info, peer, model, name); - snprintf(nc->info_str, sizeof(nc->info_str), - "net=%s,restrict=%s", inet_ntoa(net), - restricted ? "on" : "off"); + qemu_set_info_str(nc, "net=%s,restrict=%s", inet_ntoa(net), + restricted ? "on" : "off"); s = DO_UPCAST(SlirpState, nc, nc); diff --git a/net/socket.c b/net/socket.c index bfd8596250..ade1ecf38b 100644 --- a/net/socket.c +++ b/net/socket.c @@ -179,7 +179,7 @@ static void net_socket_send(void *opaque) s->fd = -1; net_socket_rs_init(&s->rs, net_socket_rs_finalize, false); s->nc.link_down = true; - memset(s->nc.info_str, 0, sizeof(s->nc.info_str)); + qemu_set_info_str(&s->nc, ""); return; } @@ -387,16 +387,15 @@ static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer, /* mcast: save bound address as dst */ if (is_connected && mcast != NULL) { s->dgram_dst = saddr; - snprintf(nc->info_str, sizeof(nc->info_str), - "socket: fd=%d (cloned mcast=%s:%d)", - fd, inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port)); + qemu_set_info_str(nc, "socket: fd=%d (cloned mcast=%s:%d)", fd, + inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port)); } else { if (sa_type == SOCKET_ADDRESS_TYPE_UNIX) { s->dgram_dst.sin_family = AF_UNIX; } - snprintf(nc->info_str, sizeof(nc->info_str), - "socket: fd=%d %s", fd, SocketAddressType_str(sa_type)); + qemu_set_info_str(nc, "socket: fd=%d %s", fd, + SocketAddressType_str(sa_type)); } return s; @@ -430,7 +429,7 @@ static NetSocketState *net_socket_fd_init_stream(NetClientState *peer, nc = qemu_new_net_client(&net_socket_info, peer, model, name); - snprintf(nc->info_str, sizeof(nc->info_str), "socket: fd=%d", fd); + qemu_set_info_str(nc, "socket: fd=%d", fd); s = DO_UPCAST(NetSocketState, nc, nc); @@ -497,9 +496,8 @@ static void net_socket_accept(void *opaque) s->fd = fd; s->nc.link_down = false; net_socket_connect(s); - snprintf(s->nc.info_str, sizeof(s->nc.info_str), - "socket: connection from %s:%d", - inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port)); + qemu_set_info_str(&s->nc, "socket: connection from %s:%d", + inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port)); } static int net_socket_listen_init(NetClientState *peer, @@ -597,9 +595,8 @@ static int net_socket_connect_init(NetClientState *peer, return -1; } - snprintf(s->nc.info_str, sizeof(s->nc.info_str), - "socket: connect to %s:%d", - inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port)); + qemu_set_info_str(&s->nc, "socket: connect to %s:%d", + inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port)); return 0; } @@ -642,9 +639,8 @@ static int net_socket_mcast_init(NetClientState *peer, s->dgram_dst = saddr; - snprintf(s->nc.info_str, sizeof(s->nc.info_str), - "socket: mcast=%s:%d", - inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port)); + qemu_set_info_str(&s->nc, "socket: mcast=%s:%d", + inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port)); return 0; } @@ -697,9 +693,8 @@ static int net_socket_udp_init(NetClientState *peer, s->dgram_dst = raddr; - snprintf(s->nc.info_str, sizeof(s->nc.info_str), - "socket: udp=%s:%d", - inet_ntoa(raddr.sin_addr), ntohs(raddr.sin_port)); + qemu_set_info_str(&s->nc, "socket: udp=%s:%d", inet_ntoa(raddr.sin_addr), + ntohs(raddr.sin_port)); return 0; } diff --git a/net/tap-win32.c b/net/tap-win32.c index 7466f22e77..a49c28ba5d 100644 --- a/net/tap-win32.c +++ b/net/tap-win32.c @@ -789,8 +789,7 @@ static int tap_win32_init(NetClientState *peer, const char *model, s = DO_UPCAST(TAPState, nc, nc); - snprintf(s->nc.info_str, sizeof(s->nc.info_str), - "tap: ifname=%s", ifname); + qemu_set_info_str(&s->nc, "tap: ifname=%s", ifname); s->handle = handle; diff --git a/net/tap.c b/net/tap.c index e203d07a12..1210a0436d 100644 --- a/net/tap.c +++ b/net/tap.c @@ -630,8 +630,7 @@ int net_init_bridge(const Netdev *netdev, const char *name, } s = net_tap_fd_init(peer, "bridge", name, fd, vnet_hdr); - snprintf(s->nc.info_str, sizeof(s->nc.info_str), "helper=%s,br=%s", helper, - br); + qemu_set_info_str(&s->nc, "helper=%s,br=%s", helper, br); return 0; } @@ -690,14 +689,12 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer, } if (tap->has_fd || tap->has_fds) { - snprintf(s->nc.info_str, sizeof(s->nc.info_str), "fd=%d", fd); + qemu_set_info_str(&s->nc, "fd=%d", fd); } else if (tap->has_helper) { - snprintf(s->nc.info_str, sizeof(s->nc.info_str), "helper=%s", - tap->helper); + qemu_set_info_str(&s->nc, "helper=%s", tap->helper); } else { - snprintf(s->nc.info_str, sizeof(s->nc.info_str), - "ifname=%s,script=%s,downscript=%s", ifname, script, - downscript); + qemu_set_info_str(&s->nc, "ifname=%s,script=%s,downscript=%s", ifname, + script, downscript); if (strcmp(downscript, "no") != 0) { snprintf(s->down_script, sizeof(s->down_script), "%s", downscript); diff --git a/net/vde.c b/net/vde.c index 1083916bcf..c0a08662cc 100644 --- a/net/vde.c +++ b/net/vde.c @@ -98,8 +98,7 @@ static int net_vde_init(NetClientState *peer, const char *model, nc = qemu_new_net_client(&net_vde_info, peer, model, name); - snprintf(nc->info_str, sizeof(nc->info_str), "sock=%s,fd=%d", - sock, vde_datafd(vde)); + qemu_set_info_str(nc, "sock=%s,fd=%d", sock, vde_datafd(vde)); s = DO_UPCAST(VDEState, nc, nc); diff --git a/net/vhost-user.c b/net/vhost-user.c index b1a0247b59..3a6b90da86 100644 --- a/net/vhost-user.c +++ b/net/vhost-user.c @@ -341,8 +341,7 @@ static int net_vhost_user_init(NetClientState *peer, const char *device, user = g_new0(struct VhostUserState, 1); for (i = 0; i < queues; i++) { nc = qemu_new_net_client(&net_vhost_user_info, peer, device, name); - snprintf(nc->info_str, sizeof(nc->info_str), "vhost-user%d to %s", - i, chr->label); + qemu_set_info_str(nc, "vhost-user%d to %s", i, chr->label); nc->queue_index = i; if (!nc0) { nc0 = nc; diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c index 9c1b25d782..854ebd61ae 100644 --- a/net/vhost-vdpa.c +++ b/net/vhost-vdpa.c @@ -544,7 +544,7 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer, nc = qemu_new_net_control_client(&net_vhost_vdpa_cvq_info, peer, device, name); } - snprintf(nc->info_str, sizeof(nc->info_str), TYPE_VHOST_VDPA); + qemu_set_info_str(nc, TYPE_VHOST_VDPA); s = DO_UPCAST(VhostVDPAState, nc, nc); s->vhost_vdpa.device_fd = vdpa_device_fd; From 5166fe0ae46dbfed8cd7e7c3743c591caef81336 Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Fri, 21 Oct 2022 11:09:11 +0200 Subject: [PATCH 310/705] qapi: net: add stream and dgram netdevs Copied from socket netdev file and modified to use SocketAddress to be able to introduce new features like unix socket. "udp" and "mcast" are squashed into dgram netdev, multicast is detected according to the IP address type. "listen" and "connect" modes are managed by stream netdev. An optional parameter "server" defines the mode (off by default) The two new types need to be parsed the modern way with -netdev, because with the traditional way, the "type" field of netdev structure collides with the "type" field of SocketAddress and prevents the correct evaluation of the command line option. Moreover the traditional way doesn't allow to use the same type (SocketAddress) several times with the -netdev option (needed to specify "local" and "remote" addresses). The previous commit paved the way for parsing the modern way, but omitted one detail: how to pick modern vs. traditional, in netdev_is_modern(). We want to pick based on the value of parameter "type". But how to extract it from the option argument? Parsing the option argument, either the modern or the traditional way, extracts it for us, but only if parsing succeeds. If parsing fails, there is no good option. No matter which parser we pick, it'll be the wrong one for some arguments, and the error reporting will be confusing. Fortunately, the traditional parser accepts *anything* when called in a certain way. This maximizes our chance to extract the value of "type", and in turn minimizes the risk of confusing error reporting. Signed-off-by: Laurent Vivier Reviewed-by: Stefano Brivio Acked-by: Markus Armbruster Acked-by: Michael S. Tsirkin Signed-off-by: Jason Wang --- hmp-commands.hx | 2 +- net/clients.h | 6 + net/dgram.c | 537 ++++++++++++++++++++++++++++++++++++++++++++++++ net/hub.c | 2 + net/meson.build | 2 + net/net.c | 30 ++- net/stream.c | 425 ++++++++++++++++++++++++++++++++++++++ qapi/net.json | 66 +++++- qemu-options.hx | 12 ++ 9 files changed, 1078 insertions(+), 4 deletions(-) create mode 100644 net/dgram.c create mode 100644 net/stream.c diff --git a/hmp-commands.hx b/hmp-commands.hx index 12b6d4e2dc..673e39a697 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1276,7 +1276,7 @@ ERST { .name = "netdev_add", .args_type = "netdev:O", - .params = "[user|tap|socket|vde|bridge|hubport|netmap|vhost-user" + .params = "[user|tap|socket|stream|dgram|vde|bridge|hubport|netmap|vhost-user" #ifdef CONFIG_VMNET "|vmnet-host|vmnet-shared|vmnet-bridged" #endif diff --git a/net/clients.h b/net/clients.h index c9157789f2..ed8bdfff1e 100644 --- a/net/clients.h +++ b/net/clients.h @@ -40,6 +40,12 @@ int net_init_hubport(const Netdev *netdev, const char *name, int net_init_socket(const Netdev *netdev, const char *name, NetClientState *peer, Error **errp); +int net_init_stream(const Netdev *netdev, const char *name, + NetClientState *peer, Error **errp); + +int net_init_dgram(const Netdev *netdev, const char *name, + NetClientState *peer, Error **errp); + int net_init_tap(const Netdev *netdev, const char *name, NetClientState *peer, Error **errp); diff --git a/net/dgram.c b/net/dgram.c new file mode 100644 index 0000000000..5339585b82 --- /dev/null +++ b/net/dgram.c @@ -0,0 +1,537 @@ +/* + * QEMU System Emulator + * + * Copyright (c) 2003-2008 Fabrice Bellard + * Copyright (c) 2022 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "qemu/osdep.h" + +#include "net/net.h" +#include "clients.h" +#include "monitor/monitor.h" +#include "qapi/error.h" +#include "qemu/error-report.h" +#include "qemu/option.h" +#include "qemu/sockets.h" +#include "qemu/iov.h" +#include "qemu/main-loop.h" +#include "qemu/cutils.h" + +typedef struct NetDgramState { + NetClientState nc; + int fd; + SocketReadState rs; + struct sockaddr_in dgram_dst; /* contains destination iff connectionless */ + bool read_poll; /* waiting to receive data? */ + bool write_poll; /* waiting to transmit data? */ +} NetDgramState; + +static void net_dgram_send(void *opaque); +static void net_dgram_writable(void *opaque); + +static void net_dgram_update_fd_handler(NetDgramState *s) +{ + qemu_set_fd_handler(s->fd, + s->read_poll ? net_dgram_send : NULL, + s->write_poll ? net_dgram_writable : NULL, + s); +} + +static void net_dgram_read_poll(NetDgramState *s, bool enable) +{ + s->read_poll = enable; + net_dgram_update_fd_handler(s); +} + +static void net_dgram_write_poll(NetDgramState *s, bool enable) +{ + s->write_poll = enable; + net_dgram_update_fd_handler(s); +} + +static void net_dgram_writable(void *opaque) +{ + NetDgramState *s = opaque; + + net_dgram_write_poll(s, false); + + qemu_flush_queued_packets(&s->nc); +} + +static ssize_t net_dgram_receive(NetClientState *nc, + const uint8_t *buf, size_t size) +{ + NetDgramState *s = DO_UPCAST(NetDgramState, nc, nc); + ssize_t ret; + + do { + if (s->dgram_dst.sin_family != AF_UNIX) { + ret = sendto(s->fd, buf, size, 0, + (struct sockaddr *)&s->dgram_dst, + sizeof(s->dgram_dst)); + } else { + ret = send(s->fd, buf, size, 0); + } + } while (ret == -1 && errno == EINTR); + + if (ret == -1 && errno == EAGAIN) { + net_dgram_write_poll(s, true); + return 0; + } + return ret; +} + +static void net_dgram_send_completed(NetClientState *nc, ssize_t len) +{ + NetDgramState *s = DO_UPCAST(NetDgramState, nc, nc); + + if (!s->read_poll) { + net_dgram_read_poll(s, true); + } +} + +static void net_dgram_rs_finalize(SocketReadState *rs) +{ + NetDgramState *s = container_of(rs, NetDgramState, rs); + + if (qemu_send_packet_async(&s->nc, rs->buf, + rs->packet_len, + net_dgram_send_completed) == 0) { + net_dgram_read_poll(s, false); + } +} + +static void net_dgram_send(void *opaque) +{ + NetDgramState *s = opaque; + int size; + + size = recv(s->fd, s->rs.buf, sizeof(s->rs.buf), 0); + if (size < 0) { + return; + } + if (size == 0) { + /* end of connection */ + net_dgram_read_poll(s, false); + net_dgram_write_poll(s, false); + return; + } + if (qemu_send_packet_async(&s->nc, s->rs.buf, size, + net_dgram_send_completed) == 0) { + net_dgram_read_poll(s, false); + } +} + +static int net_dgram_mcast_create(struct sockaddr_in *mcastaddr, + struct in_addr *localaddr, + Error **errp) +{ + struct ip_mreq imr; + int fd; + int val, ret; +#ifdef __OpenBSD__ + unsigned char loop; +#else + int loop; +#endif + + if (!IN_MULTICAST(ntohl(mcastaddr->sin_addr.s_addr))) { + error_setg(errp, "specified mcastaddr %s (0x%08x) " + "does not contain a multicast address", + inet_ntoa(mcastaddr->sin_addr), + (int)ntohl(mcastaddr->sin_addr.s_addr)); + return -1; + } + + fd = qemu_socket(PF_INET, SOCK_DGRAM, 0); + if (fd < 0) { + error_setg_errno(errp, errno, "can't create datagram socket"); + return -1; + } + + /* + * Allow multiple sockets to bind the same multicast ip and port by setting + * SO_REUSEADDR. This is the only situation where SO_REUSEADDR should be set + * on windows. Use socket_set_fast_reuse otherwise as it sets SO_REUSEADDR + * only on posix systems. + */ + val = 1; + ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); + if (ret < 0) { + error_setg_errno(errp, errno, "can't set socket option SO_REUSEADDR"); + goto fail; + } + + ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr)); + if (ret < 0) { + error_setg_errno(errp, errno, "can't bind ip=%s to socket", + inet_ntoa(mcastaddr->sin_addr)); + goto fail; + } + + /* Add host to multicast group */ + imr.imr_multiaddr = mcastaddr->sin_addr; + if (localaddr) { + imr.imr_interface = *localaddr; + } else { + imr.imr_interface.s_addr = htonl(INADDR_ANY); + } + + ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, + &imr, sizeof(struct ip_mreq)); + if (ret < 0) { + error_setg_errno(errp, errno, + "can't add socket to multicast group %s", + inet_ntoa(imr.imr_multiaddr)); + goto fail; + } + + /* Force mcast msgs to loopback (eg. several QEMUs in same host */ + loop = 1; + ret = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, + &loop, sizeof(loop)); + if (ret < 0) { + error_setg_errno(errp, errno, + "can't force multicast message to loopback"); + goto fail; + } + + /* If a bind address is given, only send packets from that address */ + if (localaddr != NULL) { + ret = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, + localaddr, sizeof(*localaddr)); + if (ret < 0) { + error_setg_errno(errp, errno, + "can't set the default network send interface"); + goto fail; + } + } + + qemu_socket_set_nonblock(fd); + return fd; +fail: + if (fd >= 0) { + closesocket(fd); + } + return -1; +} + +static void net_dgram_cleanup(NetClientState *nc) +{ + NetDgramState *s = DO_UPCAST(NetDgramState, nc, nc); + if (s->fd != -1) { + net_dgram_read_poll(s, false); + net_dgram_write_poll(s, false); + close(s->fd); + s->fd = -1; + } +} + +static NetClientInfo net_dgram_socket_info = { + .type = NET_CLIENT_DRIVER_DGRAM, + .size = sizeof(NetDgramState), + .receive = net_dgram_receive, + .cleanup = net_dgram_cleanup, +}; + +static NetDgramState *net_dgram_fd_init(NetClientState *peer, + const char *model, + const char *name, + int fd, int is_fd, + SocketAddress *mcast, + Error **errp) +{ + struct sockaddr_in saddr; + int newfd; + NetClientState *nc; + NetDgramState *s; + SocketAddress *sa; + SocketAddressType sa_type; + + sa = socket_local_address(fd, errp); + if (!sa) { + return NULL; + } + sa_type = sa->type; + qapi_free_SocketAddress(sa); + + /* + * fd passed: multicast: "learn" dgram_dst address from bound address and + * save it. Because this may be "shared" socket from a "master" process, + * datagrams would be recv() by ONLY ONE process: we must "clone" this + * dgram socket --jjo + */ + + if (is_fd && mcast != NULL) { + if (convert_host_port(&saddr, mcast->u.inet.host, + mcast->u.inet.port, errp) < 0) { + goto err; + } + /* must be bound */ + if (saddr.sin_addr.s_addr == 0) { + error_setg(errp, "can't setup multicast destination address"); + goto err; + } + /* clone dgram socket */ + newfd = net_dgram_mcast_create(&saddr, NULL, errp); + if (newfd < 0) { + goto err; + } + /* clone newfd to fd, close newfd */ + dup2(newfd, fd); + close(newfd); + + } + + nc = qemu_new_net_client(&net_dgram_socket_info, peer, model, name); + + s = DO_UPCAST(NetDgramState, nc, nc); + + s->fd = fd; + net_socket_rs_init(&s->rs, net_dgram_rs_finalize, false); + net_dgram_read_poll(s, true); + + /* mcast: save bound address as dst */ + if (is_fd && mcast != NULL) { + s->dgram_dst = saddr; + qemu_set_info_str(nc, "fd=%d (cloned mcast=%s:%d)", fd, + inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port)); + } else { + if (sa_type == SOCKET_ADDRESS_TYPE_UNIX) { + s->dgram_dst.sin_family = AF_UNIX; + } + + qemu_set_info_str(nc, "fd=%d %s", fd, SocketAddressType_str(sa_type)); + } + + return s; + +err: + closesocket(fd); + return NULL; +} + +static int net_dgram_mcast_init(NetClientState *peer, + const char *model, + const char *name, + SocketAddress *remote, + SocketAddress *local, + Error **errp) +{ + NetDgramState *s; + int fd, ret; + struct sockaddr_in saddr; + + if (remote->type != SOCKET_ADDRESS_TYPE_INET) { + error_setg(errp, "multicast only support inet type"); + return -1; + } + + if (convert_host_port(&saddr, remote->u.inet.host, remote->u.inet.port, + errp) < 0) { + return -1; + } + + if (!local) { + fd = net_dgram_mcast_create(&saddr, NULL, errp); + if (fd < 0) { + return -1; + } + } else { + switch (local->type) { + case SOCKET_ADDRESS_TYPE_INET: { + struct in_addr localaddr; + + if (inet_aton(local->u.inet.host, &localaddr) == 0) { + error_setg(errp, "localaddr '%s' is not a valid IPv4 address", + local->u.inet.host); + return -1; + } + + fd = net_dgram_mcast_create(&saddr, &localaddr, errp); + if (fd < 0) { + return -1; + } + break; + } + case SOCKET_ADDRESS_TYPE_FD: + fd = monitor_fd_param(monitor_cur(), local->u.fd.str, errp); + if (fd == -1) { + return -1; + } + ret = qemu_socket_try_set_nonblock(fd); + if (ret < 0) { + error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d", + name, fd); + return -1; + } + break; + default: + error_setg(errp, "only support inet or fd type for local"); + return -1; + } + } + + s = net_dgram_fd_init(peer, model, name, fd, + local->type == SOCKET_ADDRESS_TYPE_FD, + remote, errp); + if (!s) { + return -1; + } + + s->dgram_dst = saddr; + + qemu_set_info_str(&s->nc, "mcast=%s:%d", inet_ntoa(saddr.sin_addr), + ntohs(saddr.sin_port)); + return 0; + +} + + +int net_init_dgram(const Netdev *netdev, const char *name, + NetClientState *peer, Error **errp) +{ + NetDgramState *s; + int fd, ret; + struct sockaddr_in raddr_in; + struct sockaddr_in laddr_in; + SocketAddress *remote, *local; + + assert(netdev->type == NET_CLIENT_DRIVER_DGRAM); + + remote = netdev->u.dgram.remote; + local = netdev->u.dgram.local; + + /* detect multicast address */ + if (remote && remote->type == SOCKET_ADDRESS_TYPE_INET) { + struct sockaddr_in mcastaddr; + + if (convert_host_port(&mcastaddr, remote->u.inet.host, + remote->u.inet.port, errp) < 0) { + return -1; + } + + if (IN_MULTICAST(ntohl(mcastaddr.sin_addr.s_addr))) { + return net_dgram_mcast_init(peer, "dram", name, remote, local, + errp); + } + } + + /* unicast address */ + if (!local) { + error_setg(errp, "dgram requires local= parameter"); + return -1; + } + + if (remote) { + if (local->type == SOCKET_ADDRESS_TYPE_FD) { + error_setg(errp, "don't set remote with local.fd"); + return -1; + } + if (remote->type != local->type) { + error_setg(errp, "remote and local types must be the same"); + return -1; + } + } else { + if (local->type != SOCKET_ADDRESS_TYPE_FD) { + error_setg(errp, "type=inet requires remote parameter"); + return -1; + } + } + + switch (local->type) { + case SOCKET_ADDRESS_TYPE_INET: + if (convert_host_port(&laddr_in, local->u.inet.host, local->u.inet.port, + errp) < 0) { + return -1; + } + + if (convert_host_port(&raddr_in, remote->u.inet.host, + remote->u.inet.port, errp) < 0) { + return -1; + } + + fd = qemu_socket(PF_INET, SOCK_DGRAM, 0); + if (fd < 0) { + error_setg_errno(errp, errno, "can't create datagram socket"); + return -1; + } + + ret = socket_set_fast_reuse(fd); + if (ret < 0) { + error_setg_errno(errp, errno, + "can't set socket option SO_REUSEADDR"); + closesocket(fd); + return -1; + } + ret = bind(fd, (struct sockaddr *)&laddr_in, sizeof(laddr_in)); + if (ret < 0) { + error_setg_errno(errp, errno, "can't bind ip=%s to socket", + inet_ntoa(laddr_in.sin_addr)); + closesocket(fd); + return -1; + } + qemu_socket_set_nonblock(fd); + break; + case SOCKET_ADDRESS_TYPE_FD: + fd = monitor_fd_param(monitor_cur(), local->u.fd.str, errp); + if (fd == -1) { + return -1; + } + ret = qemu_socket_try_set_nonblock(fd); + if (ret < 0) { + error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d", + name, fd); + return -1; + } + break; + default: + error_setg(errp, "only support inet or fd type for local"); + return -1; + } + + s = net_dgram_fd_init(peer, "dgram", name, fd, 0, NULL, errp); + if (!s) { + return -1; + } + + if (remote) { + s->dgram_dst = raddr_in; + } + + switch (local->type) { + case SOCKET_ADDRESS_TYPE_INET: + qemu_set_info_str(&s->nc, "udp=%s:%d/%s:%d", + inet_ntoa(laddr_in.sin_addr), + ntohs(laddr_in.sin_port), + inet_ntoa(raddr_in.sin_addr), + ntohs(raddr_in.sin_port)); + break; + case SOCKET_ADDRESS_TYPE_FD: + qemu_set_info_str(&s->nc, "fd=%d", fd); + break; + default: + g_assert_not_reached(); + } + + return 0; +} diff --git a/net/hub.c b/net/hub.c index 1375738bf1..67ca534856 100644 --- a/net/hub.c +++ b/net/hub.c @@ -313,6 +313,8 @@ void net_hub_check_clients(void) case NET_CLIENT_DRIVER_USER: case NET_CLIENT_DRIVER_TAP: case NET_CLIENT_DRIVER_SOCKET: + case NET_CLIENT_DRIVER_STREAM: + case NET_CLIENT_DRIVER_DGRAM: case NET_CLIENT_DRIVER_VDE: case NET_CLIENT_DRIVER_VHOST_USER: has_host_dev = 1; diff --git a/net/meson.build b/net/meson.build index d1be76daf3..6cd1e3dab3 100644 --- a/net/meson.build +++ b/net/meson.build @@ -13,6 +13,8 @@ softmmu_ss.add(files( 'net.c', 'queue.c', 'socket.c', + 'stream.c', + 'dgram.c', 'util.c', )) diff --git a/net/net.c b/net/net.c index f29a59cd7f..840ad9dca5 100644 --- a/net/net.c +++ b/net/net.c @@ -48,6 +48,7 @@ #include "qemu/qemu-print.h" #include "qemu/main-loop.h" #include "qemu/option.h" +#include "qemu/keyval.h" #include "qapi/error.h" #include "qapi/opts-visitor.h" #include "sysemu/runstate.h" @@ -1021,6 +1022,8 @@ static int (* const net_client_init_fun[NET_CLIENT_DRIVER__MAX])( #endif [NET_CLIENT_DRIVER_TAP] = net_init_tap, [NET_CLIENT_DRIVER_SOCKET] = net_init_socket, + [NET_CLIENT_DRIVER_STREAM] = net_init_stream, + [NET_CLIENT_DRIVER_DGRAM] = net_init_dgram, #ifdef CONFIG_VDE [NET_CLIENT_DRIVER_VDE] = net_init_vde, #endif @@ -1112,6 +1115,8 @@ void show_netdevs(void) int idx; const char *available_netdevs[] = { "socket", + "stream", + "dgram", "hubport", "tap", #ifdef CONFIG_SLIRP @@ -1624,7 +1629,30 @@ void net_init_clients(void) */ bool netdev_is_modern(const char *optarg) { - return false; + QemuOpts *opts; + bool is_modern; + const char *type; + static QemuOptsList dummy_opts = { + .name = "netdev", + .implied_opt_name = "type", + .head = QTAILQ_HEAD_INITIALIZER(dummy_opts.head), + .desc = { { } }, + }; + + if (optarg[0] == '{') { + /* This is JSON, which means it's modern syntax */ + return true; + } + + opts = qemu_opts_create(&dummy_opts, NULL, false, &error_abort); + qemu_opts_do_parse(opts, optarg, dummy_opts.implied_opt_name, + &error_abort); + type = qemu_opt_get(opts, "type"); + is_modern = !g_strcmp0(type, "stream") || !g_strcmp0(type, "dgram"); + + qemu_opts_reset(&dummy_opts); + + return is_modern; } /* diff --git a/net/stream.c b/net/stream.c new file mode 100644 index 0000000000..0a7e84749a --- /dev/null +++ b/net/stream.c @@ -0,0 +1,425 @@ +/* + * QEMU System Emulator + * + * Copyright (c) 2003-2008 Fabrice Bellard + * Copyright (c) 2022 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "qemu/osdep.h" + +#include "net/net.h" +#include "clients.h" +#include "monitor/monitor.h" +#include "qapi/error.h" +#include "qemu/error-report.h" +#include "qemu/option.h" +#include "qemu/sockets.h" +#include "qemu/iov.h" +#include "qemu/main-loop.h" +#include "qemu/cutils.h" + +typedef struct NetStreamState { + NetClientState nc; + int listen_fd; + int fd; + SocketReadState rs; + unsigned int send_index; /* number of bytes sent*/ + bool read_poll; /* waiting to receive data? */ + bool write_poll; /* waiting to transmit data? */ +} NetStreamState; + +static void net_stream_send(void *opaque); +static void net_stream_accept(void *opaque); +static void net_stream_writable(void *opaque); + +static void net_stream_update_fd_handler(NetStreamState *s) +{ + qemu_set_fd_handler(s->fd, + s->read_poll ? net_stream_send : NULL, + s->write_poll ? net_stream_writable : NULL, + s); +} + +static void net_stream_read_poll(NetStreamState *s, bool enable) +{ + s->read_poll = enable; + net_stream_update_fd_handler(s); +} + +static void net_stream_write_poll(NetStreamState *s, bool enable) +{ + s->write_poll = enable; + net_stream_update_fd_handler(s); +} + +static void net_stream_writable(void *opaque) +{ + NetStreamState *s = opaque; + + net_stream_write_poll(s, false); + + qemu_flush_queued_packets(&s->nc); +} + +static ssize_t net_stream_receive(NetClientState *nc, const uint8_t *buf, + size_t size) +{ + NetStreamState *s = DO_UPCAST(NetStreamState, nc, nc); + uint32_t len = htonl(size); + struct iovec iov[] = { + { + .iov_base = &len, + .iov_len = sizeof(len), + }, { + .iov_base = (void *)buf, + .iov_len = size, + }, + }; + size_t remaining; + ssize_t ret; + + remaining = iov_size(iov, 2) - s->send_index; + ret = iov_send(s->fd, iov, 2, s->send_index, remaining); + + if (ret == -1 && errno == EAGAIN) { + ret = 0; /* handled further down */ + } + if (ret == -1) { + s->send_index = 0; + return -errno; + } + if (ret < (ssize_t)remaining) { + s->send_index += ret; + net_stream_write_poll(s, true); + return 0; + } + s->send_index = 0; + return size; +} + +static void net_stream_send_completed(NetClientState *nc, ssize_t len) +{ + NetStreamState *s = DO_UPCAST(NetStreamState, nc, nc); + + if (!s->read_poll) { + net_stream_read_poll(s, true); + } +} + +static void net_stream_rs_finalize(SocketReadState *rs) +{ + NetStreamState *s = container_of(rs, NetStreamState, rs); + + if (qemu_send_packet_async(&s->nc, rs->buf, + rs->packet_len, + net_stream_send_completed) == 0) { + net_stream_read_poll(s, false); + } +} + +static void net_stream_send(void *opaque) +{ + NetStreamState *s = opaque; + int size; + int ret; + uint8_t buf1[NET_BUFSIZE]; + const uint8_t *buf; + + size = recv(s->fd, buf1, sizeof(buf1), 0); + if (size < 0) { + if (errno != EWOULDBLOCK) { + goto eoc; + } + } else if (size == 0) { + /* end of connection */ + eoc: + net_stream_read_poll(s, false); + net_stream_write_poll(s, false); + if (s->listen_fd != -1) { + qemu_set_fd_handler(s->listen_fd, net_stream_accept, NULL, s); + } + closesocket(s->fd); + + s->fd = -1; + net_socket_rs_init(&s->rs, net_stream_rs_finalize, false); + s->nc.link_down = true; + qemu_set_info_str(&s->nc, ""); + + return; + } + buf = buf1; + + ret = net_fill_rstate(&s->rs, buf, size); + + if (ret == -1) { + goto eoc; + } +} + +static void net_stream_cleanup(NetClientState *nc) +{ + NetStreamState *s = DO_UPCAST(NetStreamState, nc, nc); + if (s->fd != -1) { + net_stream_read_poll(s, false); + net_stream_write_poll(s, false); + close(s->fd); + s->fd = -1; + } + if (s->listen_fd != -1) { + qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL); + closesocket(s->listen_fd); + s->listen_fd = -1; + } +} + +static void net_stream_connect(void *opaque) +{ + NetStreamState *s = opaque; + net_stream_read_poll(s, true); +} + +static NetClientInfo net_stream_info = { + .type = NET_CLIENT_DRIVER_STREAM, + .size = sizeof(NetStreamState), + .receive = net_stream_receive, + .cleanup = net_stream_cleanup, +}; + +static NetStreamState *net_stream_fd_init(NetClientState *peer, + const char *model, + const char *name, + int fd, int is_connected) +{ + NetClientState *nc; + NetStreamState *s; + + nc = qemu_new_net_client(&net_stream_info, peer, model, name); + + qemu_set_info_str(nc, "fd=%d", fd); + + s = DO_UPCAST(NetStreamState, nc, nc); + + s->fd = fd; + s->listen_fd = -1; + net_socket_rs_init(&s->rs, net_stream_rs_finalize, false); + + /* Disable Nagle algorithm on TCP sockets to reduce latency */ + socket_set_nodelay(fd); + + if (is_connected) { + net_stream_connect(s); + } else { + qemu_set_fd_handler(s->fd, NULL, net_stream_connect, s); + } + return s; +} + +static void net_stream_accept(void *opaque) +{ + NetStreamState *s = opaque; + struct sockaddr_in saddr; + socklen_t len; + int fd; + + for (;;) { + len = sizeof(saddr); + fd = qemu_accept(s->listen_fd, (struct sockaddr *)&saddr, &len); + if (fd < 0 && errno != EINTR) { + return; + } else if (fd >= 0) { + qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL); + break; + } + } + + s->fd = fd; + s->nc.link_down = false; + net_stream_connect(s); + qemu_set_info_str(&s->nc, "connection from %s:%d", + inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port)); +} + +static int net_stream_server_init(NetClientState *peer, + const char *model, + const char *name, + SocketAddress *addr, + Error **errp) +{ + NetClientState *nc; + NetStreamState *s; + int fd, ret; + + switch (addr->type) { + case SOCKET_ADDRESS_TYPE_INET: { + struct sockaddr_in saddr_in; + + if (convert_host_port(&saddr_in, addr->u.inet.host, addr->u.inet.port, + errp) < 0) { + return -1; + } + + fd = qemu_socket(PF_INET, SOCK_STREAM, 0); + if (fd < 0) { + error_setg_errno(errp, errno, "can't create stream socket"); + return -1; + } + qemu_socket_set_nonblock(fd); + + socket_set_fast_reuse(fd); + + ret = bind(fd, (struct sockaddr *)&saddr_in, sizeof(saddr_in)); + if (ret < 0) { + error_setg_errno(errp, errno, "can't bind ip=%s to socket", + inet_ntoa(saddr_in.sin_addr)); + closesocket(fd); + return -1; + } + break; + } + case SOCKET_ADDRESS_TYPE_FD: + fd = monitor_fd_param(monitor_cur(), addr->u.fd.str, errp); + if (fd == -1) { + return -1; + } + ret = qemu_socket_try_set_nonblock(fd); + if (ret < 0) { + error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d", + name, fd); + return -1; + } + break; + default: + error_setg(errp, "only support inet or fd type"); + return -1; + } + + ret = listen(fd, 0); + if (ret < 0) { + error_setg_errno(errp, errno, "can't listen on socket"); + closesocket(fd); + return -1; + } + + nc = qemu_new_net_client(&net_stream_info, peer, model, name); + s = DO_UPCAST(NetStreamState, nc, nc); + s->fd = -1; + s->listen_fd = fd; + s->nc.link_down = true; + net_socket_rs_init(&s->rs, net_stream_rs_finalize, false); + + qemu_set_fd_handler(s->listen_fd, net_stream_accept, NULL, s); + return 0; +} + +static int net_stream_client_init(NetClientState *peer, + const char *model, + const char *name, + SocketAddress *addr, + Error **errp) +{ + NetStreamState *s; + struct sockaddr_in saddr_in; + int fd, connected, ret; + + switch (addr->type) { + case SOCKET_ADDRESS_TYPE_INET: + if (convert_host_port(&saddr_in, addr->u.inet.host, addr->u.inet.port, + errp) < 0) { + return -1; + } + + fd = qemu_socket(PF_INET, SOCK_STREAM, 0); + if (fd < 0) { + error_setg_errno(errp, errno, "can't create stream socket"); + return -1; + } + qemu_socket_set_nonblock(fd); + + connected = 0; + for (;;) { + ret = connect(fd, (struct sockaddr *)&saddr_in, sizeof(saddr_in)); + if (ret < 0) { + if (errno == EINTR || errno == EWOULDBLOCK) { + /* continue */ + } else if (errno == EINPROGRESS || + errno == EALREADY || + errno == EINVAL) { + break; + } else { + error_setg_errno(errp, errno, "can't connect socket"); + closesocket(fd); + return -1; + } + } else { + connected = 1; + break; + } + } + break; + case SOCKET_ADDRESS_TYPE_FD: + fd = monitor_fd_param(monitor_cur(), addr->u.fd.str, errp); + if (fd == -1) { + return -1; + } + ret = qemu_socket_try_set_nonblock(fd); + if (ret < 0) { + error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d", + name, fd); + return -1; + } + connected = 1; + break; + default: + error_setg(errp, "only support inet or fd type"); + return -1; + } + + s = net_stream_fd_init(peer, model, name, fd, connected); + + switch (addr->type) { + case SOCKET_ADDRESS_TYPE_INET: + qemu_set_info_str(&s->nc, "connect to %s:%d", + inet_ntoa(saddr_in.sin_addr), + ntohs(saddr_in.sin_port)); + break; + case SOCKET_ADDRESS_TYPE_FD: + qemu_set_info_str(&s->nc, "connect to fd %d", fd); + break; + default: + g_assert_not_reached(); + } + + return 0; +} + +int net_init_stream(const Netdev *netdev, const char *name, + NetClientState *peer, Error **errp) +{ + const NetdevStreamOptions *sock; + + assert(netdev->type == NET_CLIENT_DRIVER_STREAM); + sock = &netdev->u.stream; + + if (!sock->has_server || !sock->server) { + return net_stream_client_init(peer, "stream", name, sock->addr, errp); + } + return net_stream_server_init(peer, "stream", name, sock->addr, errp); +} diff --git a/qapi/net.json b/qapi/net.json index 926ecc8cca..d476d33c72 100644 --- a/qapi/net.json +++ b/qapi/net.json @@ -7,6 +7,7 @@ ## { 'include': 'common.json' } +{ 'include': 'sockets.json' } ## # @set_link: @@ -576,6 +577,60 @@ '*isolated': 'bool' }, 'if': 'CONFIG_VMNET' } +## +# @NetdevStreamOptions: +# +# Configuration info for stream socket netdev +# +# @addr: socket address to listen on (server=true) +# or connect to (server=false) +# @server: create server socket (default: false) +# +# Only SocketAddress types 'inet' and 'fd' are supported. +# +# Since: 7.2 +## +{ 'struct': 'NetdevStreamOptions', + 'data': { + 'addr': 'SocketAddress', + '*server': 'bool' } } + +## +# @NetdevDgramOptions: +# +# Configuration info for datagram socket netdev. +# +# @remote: remote address +# @local: local address +# +# Only SocketAddress types 'inet' and 'fd' are supported. +# +# If remote address is present and it's a multicast address, local address +# is optional. Otherwise local address is required and remote address is +# optional. +# +# .. table:: Valid parameters combination table +# :widths: auto +# +# ============= ======== ===== +# remote local okay? +# ============= ======== ===== +# absent absent no +# absent not fd no +# absent fd yes +# multicast absent yes +# multicast present yes +# not multicast absent no +# not multicast present yes +# ============= ======== ===== +# +# Since: 7.2 +## +{ 'struct': 'NetdevDgramOptions', + 'data': { + '*local': 'SocketAddress', + '*remote': 'SocketAddress' } } + ## # @NetClientDriver: # @@ -587,10 +642,13 @@ # @vmnet-host since 7.1 # @vmnet-shared since 7.1 # @vmnet-bridged since 7.1 +# @stream since 7.2 +# @dgram since 7.2 ## { 'enum': 'NetClientDriver', - 'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde', - 'bridge', 'hubport', 'netmap', 'vhost-user', 'vhost-vdpa', + 'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'stream', + 'dgram', 'vde', 'bridge', 'hubport', 'netmap', 'vhost-user', + 'vhost-vdpa', { 'name': 'vmnet-host', 'if': 'CONFIG_VMNET' }, { 'name': 'vmnet-shared', 'if': 'CONFIG_VMNET' }, { 'name': 'vmnet-bridged', 'if': 'CONFIG_VMNET' }] } @@ -610,6 +668,8 @@ # 'vmnet-host' - since 7.1 # 'vmnet-shared' - since 7.1 # 'vmnet-bridged' - since 7.1 +# 'stream' since 7.2 +# 'dgram' since 7.2 ## { 'union': 'Netdev', 'base': { 'id': 'str', 'type': 'NetClientDriver' }, @@ -620,6 +680,8 @@ 'tap': 'NetdevTapOptions', 'l2tpv3': 'NetdevL2TPv3Options', 'socket': 'NetdevSocketOptions', + 'stream': 'NetdevStreamOptions', + 'dgram': 'NetdevDgramOptions', 'vde': 'NetdevVdeOptions', 'bridge': 'NetdevBridgeOptions', 'hubport': 'NetdevHubPortOptions', diff --git a/qemu-options.hx b/qemu-options.hx index 876a70aa63..01f2b92d6f 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -2772,6 +2772,18 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev, "-netdev socket,id=str[,fd=h][,udp=host:port][,localaddr=host:port]\n" " configure a network backend to connect to another network\n" " using an UDP tunnel\n" + "-netdev stream,id=str[,server=on|off],addr.type=inet,addr.host=host,addr.port=port\n" + "-netdev stream,id=str[,server=on|off],addr.type=fd,addr.str=file-descriptor\n" + " configure a network backend to connect to another network\n" + " using a socket connection in stream mode.\n" + "-netdev dgram,id=str,remote.type=inet,remote.host=maddr,remote.port=port[,local.type=inet,local.host=addr]\n" + "-netdev dgram,id=str,remote.type=inet,remote.host=maddr,remote.port=port[,local.type=fd,local.str=file-descriptor]\n" + " configure a network backend to connect to a multicast maddr and port\n" + " use ``local.host=addr`` to specify the host address to send packets from\n" + "-netdev dgram,id=str,local.type=inet,local.host=addr,local.port=port[,remote.type=inet,remote.host=addr,remote.port=port]\n" + "-netdev dgram,id=str,local.type=fd,local.str=file-descriptor\n" + " configure a network backend to connect to another network\n" + " using an UDP tunnel\n" #ifdef CONFIG_VDE "-netdev vde,id=str[,sock=socketpath][,port=n][,group=groupname][,mode=octalmode]\n" " configure a network backend to connect to port 'n' of a vde switch\n" From daf188ff04ea86fedf447ce366af3d1025020909 Mon Sep 17 00:00:00 2001 From: Stefano Brivio Date: Fri, 21 Oct 2022 11:09:12 +0200 Subject: [PATCH 311/705] net: socket: Don't ignore EINVAL on netdev socket connection Other errors are treated as failure by net_socket_connect_init(), but if connect() returns EINVAL, we'll fail silently. Remove the related exception. Signed-off-by: Stefano Brivio Signed-off-by: Laurent Vivier Reviewed-by: David Gibson Acked-by: Michael S. Tsirkin Signed-off-by: Jason Wang --- net/socket.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/socket.c b/net/socket.c index ade1ecf38b..4944bb70d5 100644 --- a/net/socket.c +++ b/net/socket.c @@ -577,8 +577,7 @@ static int net_socket_connect_init(NetClientState *peer, if (errno == EINTR || errno == EWOULDBLOCK) { /* continue */ } else if (errno == EINPROGRESS || - errno == EALREADY || - errno == EINVAL) { + errno == EALREADY) { break; } else { error_setg_errno(errp, errno, "can't connect socket"); From 80d3e4779d6c5fee0402b0b48de15c3c812845a4 Mon Sep 17 00:00:00 2001 From: Stefano Brivio Date: Fri, 21 Oct 2022 11:09:13 +0200 Subject: [PATCH 312/705] net: stream: Don't ignore EINVAL on netdev socket connection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Other errors are treated as failure by net_stream_client_init(), but if connect() returns EINVAL, we'll fail silently. Remove the related exception. Signed-off-by: Stefano Brivio [lvivier: applied to net/stream.c] Signed-off-by: Laurent Vivier Reviewed-by: Daniel P. Berrangé Reviewed-by: David Gibson Acked-by: Michael S. Tsirkin Signed-off-by: Jason Wang --- net/stream.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/stream.c b/net/stream.c index 0a7e84749a..e4388fe7e4 100644 --- a/net/stream.c +++ b/net/stream.c @@ -360,8 +360,7 @@ static int net_stream_client_init(NetClientState *peer, if (errno == EINTR || errno == EWOULDBLOCK) { /* continue */ } else if (errno == EINPROGRESS || - errno == EALREADY || - errno == EINVAL) { + errno == EALREADY) { break; } else { error_setg_errno(errp, errno, "can't connect socket"); From 13c6be96618c4435ba412c098bfe35a76355bc45 Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Fri, 21 Oct 2022 11:09:14 +0200 Subject: [PATCH 313/705] net: stream: add unix socket MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Laurent Vivier Reviewed-by: Stefano Brivio Acked-by: Michael S. Tsirkin Acked-by: Markus Armbruster (QAPI schema) Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Jason Wang --- net/stream.c | 107 +++++++++++++++++++++++++++++++++++++++++++++--- qapi/net.json | 2 +- qemu-options.hx | 1 + 3 files changed, 104 insertions(+), 6 deletions(-) diff --git a/net/stream.c b/net/stream.c index e4388fe7e4..884f473018 100644 --- a/net/stream.c +++ b/net/stream.c @@ -235,7 +235,7 @@ static NetStreamState *net_stream_fd_init(NetClientState *peer, static void net_stream_accept(void *opaque) { NetStreamState *s = opaque; - struct sockaddr_in saddr; + struct sockaddr_storage saddr; socklen_t len; int fd; @@ -253,8 +253,26 @@ static void net_stream_accept(void *opaque) s->fd = fd; s->nc.link_down = false; net_stream_connect(s); - qemu_set_info_str(&s->nc, "connection from %s:%d", - inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port)); + switch (saddr.ss_family) { + case AF_INET: { + struct sockaddr_in *saddr_in = (struct sockaddr_in *)&saddr; + + qemu_set_info_str(&s->nc, "connection from %s:%d", + inet_ntoa(saddr_in->sin_addr), + ntohs(saddr_in->sin_port)); + break; + } + case AF_UNIX: { + struct sockaddr_un saddr_un; + + len = sizeof(saddr_un); + getsockname(s->listen_fd, (struct sockaddr *)&saddr_un, &len); + qemu_set_info_str(&s->nc, "connect from %s", saddr_un.sun_path); + break; + } + default: + g_assert_not_reached(); + } } static int net_stream_server_init(NetClientState *peer, @@ -294,6 +312,43 @@ static int net_stream_server_init(NetClientState *peer, } break; } + case SOCKET_ADDRESS_TYPE_UNIX: { + struct sockaddr_un saddr_un; + + ret = unlink(addr->u.q_unix.path); + if (ret < 0 && errno != ENOENT) { + error_setg_errno(errp, errno, "failed to unlink socket %s", + addr->u.q_unix.path); + return -1; + } + + saddr_un.sun_family = PF_UNIX; + ret = snprintf(saddr_un.sun_path, sizeof(saddr_un.sun_path), "%s", + addr->u.q_unix.path); + if (ret < 0 || ret >= sizeof(saddr_un.sun_path)) { + error_setg(errp, "UNIX socket path '%s' is too long", + addr->u.q_unix.path); + error_append_hint(errp, "Path must be less than %zu bytes\n", + sizeof(saddr_un.sun_path)); + return -1; + } + + fd = qemu_socket(PF_UNIX, SOCK_STREAM, 0); + if (fd < 0) { + error_setg_errno(errp, errno, "can't create stream socket"); + return -1; + } + qemu_socket_set_nonblock(fd); + + ret = bind(fd, (struct sockaddr *)&saddr_un, sizeof(saddr_un)); + if (ret < 0) { + error_setg_errno(errp, errno, "can't create socket with path: %s", + saddr_un.sun_path); + closesocket(fd); + return -1; + } + break; + } case SOCKET_ADDRESS_TYPE_FD: fd = monitor_fd_param(monitor_cur(), addr->u.fd.str, errp); if (fd == -1) { @@ -337,6 +392,7 @@ static int net_stream_client_init(NetClientState *peer, { NetStreamState *s; struct sockaddr_in saddr_in; + struct sockaddr_un saddr_un; int fd, connected, ret; switch (addr->type) { @@ -373,6 +429,45 @@ static int net_stream_client_init(NetClientState *peer, } } break; + case SOCKET_ADDRESS_TYPE_UNIX: + saddr_un.sun_family = PF_UNIX; + ret = snprintf(saddr_un.sun_path, sizeof(saddr_un.sun_path), "%s", + addr->u.q_unix.path); + if (ret < 0 || ret >= sizeof(saddr_un.sun_path)) { + error_setg(errp, "UNIX socket path '%s' is too long", + addr->u.q_unix.path); + error_append_hint(errp, "Path must be less than %zu bytes\n", + sizeof(saddr_un.sun_path)); + return -1; + } + + fd = qemu_socket(PF_UNIX, SOCK_STREAM, 0); + if (fd < 0) { + error_setg_errno(errp, errno, "can't create stream socket"); + return -1; + } + qemu_socket_set_nonblock(fd); + + connected = 0; + for (;;) { + ret = connect(fd, (struct sockaddr *)&saddr_un, sizeof(saddr_un)); + if (ret < 0) { + if (errno == EINTR || errno == EWOULDBLOCK) { + /* continue */ + } else if (errno == EAGAIN || + errno == EALREADY) { + break; + } else { + error_setg_errno(errp, errno, "can't connect socket"); + closesocket(fd); + return -1; + } + } else { + connected = 1; + break; + } + } + break; case SOCKET_ADDRESS_TYPE_FD: fd = monitor_fd_param(monitor_cur(), addr->u.fd.str, errp); if (fd == -1) { @@ -387,7 +482,7 @@ static int net_stream_client_init(NetClientState *peer, connected = 1; break; default: - error_setg(errp, "only support inet or fd type"); + error_setg(errp, "only support inet, unix or fd type"); return -1; } @@ -399,13 +494,15 @@ static int net_stream_client_init(NetClientState *peer, inet_ntoa(saddr_in.sin_addr), ntohs(saddr_in.sin_port)); break; + case SOCKET_ADDRESS_TYPE_UNIX: + qemu_set_info_str(&s->nc, " connect to %s", saddr_un.sun_path); + break; case SOCKET_ADDRESS_TYPE_FD: qemu_set_info_str(&s->nc, "connect to fd %d", fd); break; default: g_assert_not_reached(); } - return 0; } diff --git a/qapi/net.json b/qapi/net.json index d476d33c72..b4768ce62b 100644 --- a/qapi/net.json +++ b/qapi/net.json @@ -586,7 +586,7 @@ # or connect to (server=false) # @server: create server socket (default: false) # -# Only SocketAddress types 'inet' and 'fd' are supported. +# Only SocketAddress types 'unix', 'inet' and 'fd' are supported. # # Since: 7.2 ## diff --git a/qemu-options.hx b/qemu-options.hx index 01f2b92d6f..858f3dc738 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -2773,6 +2773,7 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev, " configure a network backend to connect to another network\n" " using an UDP tunnel\n" "-netdev stream,id=str[,server=on|off],addr.type=inet,addr.host=host,addr.port=port\n" + "-netdev stream,id=str[,server=on|off],addr.type=unix,addr.path=path\n" "-netdev stream,id=str[,server=on|off],addr.type=fd,addr.str=file-descriptor\n" " configure a network backend to connect to another network\n" " using a socket connection in stream mode.\n" From 7c1f0c33cc9d7436172da0882f088b3cfc8a0733 Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Fri, 21 Oct 2022 11:09:15 +0200 Subject: [PATCH 314/705] net: dgram: make dgram_dst generic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dgram_dst is a sockaddr_in structure. To be able to use it with unix socket, use a pointer to a generic sockaddr structure. Rename it dest_addr, and store socket length in dest_len. Signed-off-by: Laurent Vivier Reviewed-by: Stefano Brivio Acked-by: Michael S. Tsirkin Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Jason Wang --- net/dgram.c | 82 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 53 insertions(+), 29 deletions(-) diff --git a/net/dgram.c b/net/dgram.c index 5339585b82..e20be9ca79 100644 --- a/net/dgram.c +++ b/net/dgram.c @@ -40,9 +40,11 @@ typedef struct NetDgramState { NetClientState nc; int fd; SocketReadState rs; - struct sockaddr_in dgram_dst; /* contains destination iff connectionless */ bool read_poll; /* waiting to receive data? */ bool write_poll; /* waiting to transmit data? */ + /* contains destination iff connectionless */ + struct sockaddr *dest_addr; + socklen_t dest_len; } NetDgramState; static void net_dgram_send(void *opaque); @@ -84,10 +86,8 @@ static ssize_t net_dgram_receive(NetClientState *nc, ssize_t ret; do { - if (s->dgram_dst.sin_family != AF_UNIX) { - ret = sendto(s->fd, buf, size, 0, - (struct sockaddr *)&s->dgram_dst, - sizeof(s->dgram_dst)); + if (s->dest_addr) { + ret = sendto(s->fd, buf, size, 0, s->dest_addr, s->dest_len); } else { ret = send(s->fd, buf, size, 0); } @@ -244,6 +244,9 @@ static void net_dgram_cleanup(NetClientState *nc) close(s->fd); s->fd = -1; } + g_free(s->dest_addr); + s->dest_addr = NULL; + s->dest_len = 0; } static NetClientInfo net_dgram_socket_info = { @@ -260,7 +263,7 @@ static NetDgramState *net_dgram_fd_init(NetClientState *peer, SocketAddress *mcast, Error **errp) { - struct sockaddr_in saddr; + struct sockaddr_in *saddr = NULL; int newfd; NetClientState *nc; NetDgramState *s; @@ -275,31 +278,32 @@ static NetDgramState *net_dgram_fd_init(NetClientState *peer, qapi_free_SocketAddress(sa); /* - * fd passed: multicast: "learn" dgram_dst address from bound address and + * fd passed: multicast: "learn" dest_addr address from bound address and * save it. Because this may be "shared" socket from a "master" process, * datagrams would be recv() by ONLY ONE process: we must "clone" this * dgram socket --jjo */ if (is_fd && mcast != NULL) { - if (convert_host_port(&saddr, mcast->u.inet.host, - mcast->u.inet.port, errp) < 0) { + saddr = g_new(struct sockaddr_in, 1); + + if (convert_host_port(saddr, mcast->u.inet.host, mcast->u.inet.port, + errp) < 0) { goto err; } /* must be bound */ - if (saddr.sin_addr.s_addr == 0) { + if (saddr->sin_addr.s_addr == 0) { error_setg(errp, "can't setup multicast destination address"); goto err; } /* clone dgram socket */ - newfd = net_dgram_mcast_create(&saddr, NULL, errp); + newfd = net_dgram_mcast_create(saddr, NULL, errp); if (newfd < 0) { goto err; } /* clone newfd to fd, close newfd */ dup2(newfd, fd); close(newfd); - } nc = qemu_new_net_client(&net_dgram_socket_info, peer, model, name); @@ -311,21 +315,20 @@ static NetDgramState *net_dgram_fd_init(NetClientState *peer, net_dgram_read_poll(s, true); /* mcast: save bound address as dst */ - if (is_fd && mcast != NULL) { - s->dgram_dst = saddr; + if (saddr) { + g_assert(s->dest_addr == NULL); + s->dest_addr = (struct sockaddr *)saddr; + s->dest_len = sizeof(*saddr); qemu_set_info_str(nc, "fd=%d (cloned mcast=%s:%d)", fd, - inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port)); + inet_ntoa(saddr->sin_addr), ntohs(saddr->sin_port)); } else { - if (sa_type == SOCKET_ADDRESS_TYPE_UNIX) { - s->dgram_dst.sin_family = AF_UNIX; - } - qemu_set_info_str(nc, "fd=%d %s", fd, SocketAddressType_str(sa_type)); } return s; err: + g_free(saddr); closesocket(fd); return NULL; } @@ -339,21 +342,24 @@ static int net_dgram_mcast_init(NetClientState *peer, { NetDgramState *s; int fd, ret; - struct sockaddr_in saddr; + struct sockaddr_in *saddr; if (remote->type != SOCKET_ADDRESS_TYPE_INET) { error_setg(errp, "multicast only support inet type"); return -1; } - if (convert_host_port(&saddr, remote->u.inet.host, remote->u.inet.port, + saddr = g_new(struct sockaddr_in, 1); + if (convert_host_port(saddr, remote->u.inet.host, remote->u.inet.port, errp) < 0) { + g_free(saddr); return -1; } if (!local) { - fd = net_dgram_mcast_create(&saddr, NULL, errp); + fd = net_dgram_mcast_create(saddr, NULL, errp); if (fd < 0) { + g_free(saddr); return -1; } } else { @@ -362,13 +368,15 @@ static int net_dgram_mcast_init(NetClientState *peer, struct in_addr localaddr; if (inet_aton(local->u.inet.host, &localaddr) == 0) { + g_free(saddr); error_setg(errp, "localaddr '%s' is not a valid IPv4 address", local->u.inet.host); return -1; } - fd = net_dgram_mcast_create(&saddr, &localaddr, errp); + fd = net_dgram_mcast_create(saddr, &localaddr, errp); if (fd < 0) { + g_free(saddr); return -1; } break; @@ -376,16 +384,19 @@ static int net_dgram_mcast_init(NetClientState *peer, case SOCKET_ADDRESS_TYPE_FD: fd = monitor_fd_param(monitor_cur(), local->u.fd.str, errp); if (fd == -1) { + g_free(saddr); return -1; } ret = qemu_socket_try_set_nonblock(fd); if (ret < 0) { + g_free(saddr); error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d", name, fd); return -1; } break; default: + g_free(saddr); error_setg(errp, "only support inet or fd type for local"); return -1; } @@ -395,13 +406,17 @@ static int net_dgram_mcast_init(NetClientState *peer, local->type == SOCKET_ADDRESS_TYPE_FD, remote, errp); if (!s) { + g_free(saddr); return -1; } - s->dgram_dst = saddr; + g_assert(s->dest_addr == NULL); + s->dest_addr = (struct sockaddr *)saddr; + s->dest_len = sizeof(*saddr); + + qemu_set_info_str(&s->nc, "mcast=%s:%d", inet_ntoa(saddr->sin_addr), + ntohs(saddr->sin_port)); - qemu_set_info_str(&s->nc, "mcast=%s:%d", inet_ntoa(saddr.sin_addr), - ntohs(saddr.sin_port)); return 0; } @@ -412,9 +427,10 @@ int net_init_dgram(const Netdev *netdev, const char *name, { NetDgramState *s; int fd, ret; - struct sockaddr_in raddr_in; - struct sockaddr_in laddr_in; SocketAddress *remote, *local; + struct sockaddr *dest_addr; + struct sockaddr_in laddr_in, raddr_in; + socklen_t dest_len; assert(netdev->type == NET_CLIENT_DRIVER_DGRAM); @@ -491,6 +507,10 @@ int net_init_dgram(const Netdev *netdev, const char *name, return -1; } qemu_socket_set_nonblock(fd); + + dest_len = sizeof(raddr_in); + dest_addr = g_malloc(dest_len); + memcpy(dest_addr, &raddr_in, dest_len); break; case SOCKET_ADDRESS_TYPE_FD: fd = monitor_fd_param(monitor_cur(), local->u.fd.str, errp); @@ -503,6 +523,8 @@ int net_init_dgram(const Netdev *netdev, const char *name, name, fd); return -1; } + dest_addr = NULL; + dest_len = 0; break; default: error_setg(errp, "only support inet or fd type for local"); @@ -515,7 +537,9 @@ int net_init_dgram(const Netdev *netdev, const char *name, } if (remote) { - s->dgram_dst = raddr_in; + g_assert(s->dest_addr == NULL); + s->dest_addr = dest_addr; + s->dest_len = dest_len; } switch (local->type) { From 8ecc7f40bc76f2a565a74d1e5b2d7462cf050f1d Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Fri, 21 Oct 2022 11:09:16 +0200 Subject: [PATCH 315/705] net: dgram: move mcast specific code from net_socket_fd_init_dgram() It is less complex to manage special cases directly in net_dgram_mcast_init() and net_dgram_udp_init(). Signed-off-by: Laurent Vivier Reviewed-by: Stefano Brivio Acked-by: Michael S. Tsirkin Signed-off-by: Jason Wang --- net/dgram.c | 143 ++++++++++++++++++++++++++++------------------------ 1 file changed, 76 insertions(+), 67 deletions(-) diff --git a/net/dgram.c b/net/dgram.c index e20be9ca79..e581cc62f3 100644 --- a/net/dgram.c +++ b/net/dgram.c @@ -259,52 +259,11 @@ static NetClientInfo net_dgram_socket_info = { static NetDgramState *net_dgram_fd_init(NetClientState *peer, const char *model, const char *name, - int fd, int is_fd, - SocketAddress *mcast, + int fd, Error **errp) { - struct sockaddr_in *saddr = NULL; - int newfd; NetClientState *nc; NetDgramState *s; - SocketAddress *sa; - SocketAddressType sa_type; - - sa = socket_local_address(fd, errp); - if (!sa) { - return NULL; - } - sa_type = sa->type; - qapi_free_SocketAddress(sa); - - /* - * fd passed: multicast: "learn" dest_addr address from bound address and - * save it. Because this may be "shared" socket from a "master" process, - * datagrams would be recv() by ONLY ONE process: we must "clone" this - * dgram socket --jjo - */ - - if (is_fd && mcast != NULL) { - saddr = g_new(struct sockaddr_in, 1); - - if (convert_host_port(saddr, mcast->u.inet.host, mcast->u.inet.port, - errp) < 0) { - goto err; - } - /* must be bound */ - if (saddr->sin_addr.s_addr == 0) { - error_setg(errp, "can't setup multicast destination address"); - goto err; - } - /* clone dgram socket */ - newfd = net_dgram_mcast_create(saddr, NULL, errp); - if (newfd < 0) { - goto err; - } - /* clone newfd to fd, close newfd */ - dup2(newfd, fd); - close(newfd); - } nc = qemu_new_net_client(&net_dgram_socket_info, peer, model, name); @@ -314,23 +273,7 @@ static NetDgramState *net_dgram_fd_init(NetClientState *peer, net_socket_rs_init(&s->rs, net_dgram_rs_finalize, false); net_dgram_read_poll(s, true); - /* mcast: save bound address as dst */ - if (saddr) { - g_assert(s->dest_addr == NULL); - s->dest_addr = (struct sockaddr *)saddr; - s->dest_len = sizeof(*saddr); - qemu_set_info_str(nc, "fd=%d (cloned mcast=%s:%d)", fd, - inet_ntoa(saddr->sin_addr), ntohs(saddr->sin_port)); - } else { - qemu_set_info_str(nc, "fd=%d %s", fd, SocketAddressType_str(sa_type)); - } - return s; - -err: - g_free(saddr); - closesocket(fd); - return NULL; } static int net_dgram_mcast_init(NetClientState *peer, @@ -381,7 +324,9 @@ static int net_dgram_mcast_init(NetClientState *peer, } break; } - case SOCKET_ADDRESS_TYPE_FD: + case SOCKET_ADDRESS_TYPE_FD: { + int newfd; + fd = monitor_fd_param(monitor_cur(), local->u.fd.str, errp); if (fd == -1) { g_free(saddr); @@ -394,7 +339,42 @@ static int net_dgram_mcast_init(NetClientState *peer, name, fd); return -1; } + + /* + * fd passed: multicast: "learn" dest_addr address from bound + * address and save it. Because this may be "shared" socket from a + * "master" process, datagrams would be recv() by ONLY ONE process: + * we must "clone" this dgram socket --jjo + */ + + saddr = g_new(struct sockaddr_in, 1); + + if (convert_host_port(saddr, local->u.inet.host, local->u.inet.port, + errp) < 0) { + g_free(saddr); + closesocket(fd); + return -1; + } + + /* must be bound */ + if (saddr->sin_addr.s_addr == 0) { + error_setg(errp, "can't setup multicast destination address"); + g_free(saddr); + closesocket(fd); + return -1; + } + /* clone dgram socket */ + newfd = net_dgram_mcast_create(saddr, NULL, errp); + if (newfd < 0) { + g_free(saddr); + closesocket(fd); + return -1; + } + /* clone newfd to fd, close newfd */ + dup2(newfd, fd); + close(newfd); break; + } default: g_free(saddr); error_setg(errp, "only support inet or fd type for local"); @@ -402,9 +382,7 @@ static int net_dgram_mcast_init(NetClientState *peer, } } - s = net_dgram_fd_init(peer, model, name, fd, - local->type == SOCKET_ADDRESS_TYPE_FD, - remote, errp); + s = net_dgram_fd_init(peer, model, name, fd, errp); if (!s) { g_free(saddr); return -1; @@ -414,8 +392,26 @@ static int net_dgram_mcast_init(NetClientState *peer, s->dest_addr = (struct sockaddr *)saddr; s->dest_len = sizeof(*saddr); - qemu_set_info_str(&s->nc, "mcast=%s:%d", inet_ntoa(saddr->sin_addr), - ntohs(saddr->sin_port)); + if (!local) { + qemu_set_info_str(&s->nc, "mcast=%s:%d", + inet_ntoa(saddr->sin_addr), + ntohs(saddr->sin_port)); + } else { + switch (local->type) { + case SOCKET_ADDRESS_TYPE_INET: + qemu_set_info_str(&s->nc, "mcast=%s:%d", + inet_ntoa(saddr->sin_addr), + ntohs(saddr->sin_port)); + break; + case SOCKET_ADDRESS_TYPE_FD: + qemu_set_info_str(&s->nc, "fd=%d (cloned mcast=%s:%d)", + fd, inet_ntoa(saddr->sin_addr), + ntohs(saddr->sin_port)); + break; + default: + g_assert_not_reached(); + } + } return 0; @@ -531,7 +527,7 @@ int net_init_dgram(const Netdev *netdev, const char *name, return -1; } - s = net_dgram_fd_init(peer, "dgram", name, fd, 0, NULL, errp); + s = net_dgram_fd_init(peer, "dgram", name, fd, errp); if (!s) { return -1; } @@ -550,9 +546,22 @@ int net_init_dgram(const Netdev *netdev, const char *name, inet_ntoa(raddr_in.sin_addr), ntohs(raddr_in.sin_port)); break; - case SOCKET_ADDRESS_TYPE_FD: - qemu_set_info_str(&s->nc, "fd=%d", fd); + case SOCKET_ADDRESS_TYPE_FD: { + SocketAddress *sa; + SocketAddressType sa_type; + + sa = socket_local_address(fd, errp); + if (sa) { + sa_type = sa->type; + qapi_free_SocketAddress(sa); + + qemu_set_info_str(&s->nc, "fd=%d %s", fd, + SocketAddressType_str(sa_type)); + } else { + qemu_set_info_str(&s->nc, "fd=%d", fd); + } break; + } default: g_assert_not_reached(); } From 784e7a2531040824f88f33494be256a9e331e219 Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Fri, 21 Oct 2022 11:09:17 +0200 Subject: [PATCH 316/705] net: dgram: add unix socket Signed-off-by: Laurent Vivier Reviewed-by: Stefano Brivio Reviewed-by: David Gibson Acked-by: Michael S. Tsirkin Acked-by: Markus Armbruster (QAPI schema) Signed-off-by: Jason Wang --- net/dgram.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++- qapi/net.json | 2 +- qemu-options.hx | 1 + 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/net/dgram.c b/net/dgram.c index e581cc62f3..9f7bf38376 100644 --- a/net/dgram.c +++ b/net/dgram.c @@ -426,6 +426,7 @@ int net_init_dgram(const Netdev *netdev, const char *name, SocketAddress *remote, *local; struct sockaddr *dest_addr; struct sockaddr_in laddr_in, raddr_in; + struct sockaddr_un laddr_un, raddr_un; socklen_t dest_len; assert(netdev->type == NET_CLIENT_DRIVER_DGRAM); @@ -465,7 +466,8 @@ int net_init_dgram(const Netdev *netdev, const char *name, } } else { if (local->type != SOCKET_ADDRESS_TYPE_FD) { - error_setg(errp, "type=inet requires remote parameter"); + error_setg(errp, + "type=inet or type=unix requires remote parameter"); return -1; } } @@ -508,6 +510,53 @@ int net_init_dgram(const Netdev *netdev, const char *name, dest_addr = g_malloc(dest_len); memcpy(dest_addr, &raddr_in, dest_len); break; + case SOCKET_ADDRESS_TYPE_UNIX: + ret = unlink(local->u.q_unix.path); + if (ret < 0 && errno != ENOENT) { + error_setg_errno(errp, errno, "failed to unlink socket %s", + local->u.q_unix.path); + return -1; + } + + laddr_un.sun_family = PF_UNIX; + ret = snprintf(laddr_un.sun_path, sizeof(laddr_un.sun_path), "%s", + local->u.q_unix.path); + if (ret < 0 || ret >= sizeof(laddr_un.sun_path)) { + error_setg(errp, "UNIX socket path '%s' is too long", + local->u.q_unix.path); + error_append_hint(errp, "Path must be less than %zu bytes\n", + sizeof(laddr_un.sun_path)); + } + + raddr_un.sun_family = PF_UNIX; + ret = snprintf(raddr_un.sun_path, sizeof(raddr_un.sun_path), "%s", + remote->u.q_unix.path); + if (ret < 0 || ret >= sizeof(raddr_un.sun_path)) { + error_setg(errp, "UNIX socket path '%s' is too long", + remote->u.q_unix.path); + error_append_hint(errp, "Path must be less than %zu bytes\n", + sizeof(raddr_un.sun_path)); + } + + fd = qemu_socket(PF_UNIX, SOCK_DGRAM, 0); + if (fd < 0) { + error_setg_errno(errp, errno, "can't create datagram socket"); + return -1; + } + + ret = bind(fd, (struct sockaddr *)&laddr_un, sizeof(laddr_un)); + if (ret < 0) { + error_setg_errno(errp, errno, "can't bind unix=%s to socket", + laddr_un.sun_path); + closesocket(fd); + return -1; + } + qemu_socket_set_nonblock(fd); + + dest_len = sizeof(raddr_un); + dest_addr = g_malloc(dest_len); + memcpy(dest_addr, &raddr_un, dest_len); + break; case SOCKET_ADDRESS_TYPE_FD: fd = monitor_fd_param(monitor_cur(), local->u.fd.str, errp); if (fd == -1) { @@ -546,6 +595,10 @@ int net_init_dgram(const Netdev *netdev, const char *name, inet_ntoa(raddr_in.sin_addr), ntohs(raddr_in.sin_port)); break; + case SOCKET_ADDRESS_TYPE_UNIX: + qemu_set_info_str(&s->nc, "udp=%s:%s", + laddr_un.sun_path, raddr_un.sun_path); + break; case SOCKET_ADDRESS_TYPE_FD: { SocketAddress *sa; SocketAddressType sa_type; diff --git a/qapi/net.json b/qapi/net.json index b4768ce62b..cbc8d77c97 100644 --- a/qapi/net.json +++ b/qapi/net.json @@ -603,7 +603,7 @@ # @remote: remote address # @local: local address # -# Only SocketAddress types 'inet' and 'fd' are supported. +# Only SocketAddress types 'unix', 'inet' and 'fd' are supported. # # If remote address is present and it's a multicast address, local address # is optional. Otherwise local address is required and remote address is diff --git a/qemu-options.hx b/qemu-options.hx index 858f3dc738..e76142bfb6 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -2782,6 +2782,7 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev, " configure a network backend to connect to a multicast maddr and port\n" " use ``local.host=addr`` to specify the host address to send packets from\n" "-netdev dgram,id=str,local.type=inet,local.host=addr,local.port=port[,remote.type=inet,remote.host=addr,remote.port=port]\n" + "-netdev dgram,id=str,local.type=unix,local.path=path[,remote.type=unix,remote.path=path]\n" "-netdev dgram,id=str,local.type=fd,local.str=file-descriptor\n" " configure a network backend to connect to another network\n" " using an UDP tunnel\n" From 18bf1c94565b1b594873aaea9dfd47c83abd8543 Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Fri, 21 Oct 2022 11:09:18 +0200 Subject: [PATCH 317/705] qemu-sockets: move and rename SocketAddress_to_str() Rename SocketAddress_to_str() to socket_uri() and move it to util/qemu-sockets.c close to socket_parse(). socket_uri() generates a string from a SocketAddress while socket_parse() generates a SocketAddress from a string. Signed-off-by: Laurent Vivier Reviewed-by: David Gibson Reviewed-by: Dr. David Alan Gilbert Acked-by: Michael S. Tsirkin Signed-off-by: Jason Wang --- include/qemu/sockets.h | 2 +- monitor/hmp-cmds.c | 23 +---------------------- util/qemu-sockets.c | 20 ++++++++++++++++++++ 3 files changed, 22 insertions(+), 23 deletions(-) diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h index db4bedb6fa..214058d8e3 100644 --- a/include/qemu/sockets.h +++ b/include/qemu/sockets.h @@ -58,6 +58,7 @@ NetworkAddressFamily inet_netfamily(int family); int unix_listen(const char *path, Error **errp); int unix_connect(const char *path, Error **errp); +char *socket_uri(SocketAddress *addr); SocketAddress *socket_parse(const char *str, Error **errp); int socket_connect(SocketAddress *addr, Error **errp); int socket_listen(SocketAddress *addr, int num, Error **errp); @@ -141,5 +142,4 @@ SocketAddress *socket_address_flatten(SocketAddressLegacy *addr); * Return 0 on success. */ int socket_address_parse_named_fd(SocketAddress *addr, Error **errp); - #endif /* QEMU_SOCKETS_H */ diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index bab86c5537..01b789a79e 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -199,27 +199,6 @@ void hmp_info_mice(Monitor *mon, const QDict *qdict) qapi_free_MouseInfoList(mice_list); } -static char *SocketAddress_to_str(SocketAddress *addr) -{ - switch (addr->type) { - case SOCKET_ADDRESS_TYPE_INET: - return g_strdup_printf("tcp:%s:%s", - addr->u.inet.host, - addr->u.inet.port); - case SOCKET_ADDRESS_TYPE_UNIX: - return g_strdup_printf("unix:%s", - addr->u.q_unix.path); - case SOCKET_ADDRESS_TYPE_FD: - return g_strdup_printf("fd:%s", addr->u.fd.str); - case SOCKET_ADDRESS_TYPE_VSOCK: - return g_strdup_printf("tcp:%s:%s", - addr->u.vsock.cid, - addr->u.vsock.port); - default: - return g_strdup("unknown address type"); - } -} - void hmp_info_migrate(Monitor *mon, const QDict *qdict) { MigrationInfo *info; @@ -382,7 +361,7 @@ void hmp_info_migrate(Monitor *mon, const QDict *qdict) monitor_printf(mon, "socket address: [\n"); for (addr = info->socket_address; addr; addr = addr->next) { - char *s = SocketAddress_to_str(addr->value); + char *s = socket_uri(addr->value); monitor_printf(mon, "\t%s\n", s); g_free(s); } diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c index 83f4bd6fd2..9f6f655fd5 100644 --- a/util/qemu-sockets.c +++ b/util/qemu-sockets.c @@ -1077,6 +1077,26 @@ int unix_connect(const char *path, Error **errp) return sock; } +char *socket_uri(SocketAddress *addr) +{ + switch (addr->type) { + case SOCKET_ADDRESS_TYPE_INET: + return g_strdup_printf("tcp:%s:%s", + addr->u.inet.host, + addr->u.inet.port); + case SOCKET_ADDRESS_TYPE_UNIX: + return g_strdup_printf("unix:%s", + addr->u.q_unix.path); + case SOCKET_ADDRESS_TYPE_FD: + return g_strdup_printf("fd:%s", addr->u.fd.str); + case SOCKET_ADDRESS_TYPE_VSOCK: + return g_strdup_printf("tcp:%s:%s", + addr->u.vsock.cid, + addr->u.vsock.port); + default: + return g_strdup("unknown address type"); + } +} SocketAddress *socket_parse(const char *str, Error **errp) { From 7651b3211904eda3207d50f31c7f9acc8c375cec Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Fri, 21 Oct 2022 11:09:19 +0200 Subject: [PATCH 318/705] qemu-sockets: update socket_uri() and socket_parse() to be consistent To be consistent with socket_uri(), add 'tcp:' prefix for inet type in socket_parse(), by default socket_parse() use tcp when no prefix is provided (format is host:port). In socket_uri(), use 'vsock:' prefix for vsock type rather than 'tcp:' because it makes a vsock address look like an inet address with CID misinterpreted as host. Goes back to commit 9aca82ba31 "migration: Create socket-address parameter" Signed-off-by: Laurent Vivier Reviewed-by: Dr. David Alan Gilbert Reviewed-by: Markus Armbruster Reviewed-by: David Gibson Acked-by: Michael S. Tsirkin Signed-off-by: Jason Wang --- util/qemu-sockets.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c index 9f6f655fd5..a9926af714 100644 --- a/util/qemu-sockets.c +++ b/util/qemu-sockets.c @@ -1090,7 +1090,7 @@ char *socket_uri(SocketAddress *addr) case SOCKET_ADDRESS_TYPE_FD: return g_strdup_printf("fd:%s", addr->u.fd.str); case SOCKET_ADDRESS_TYPE_VSOCK: - return g_strdup_printf("tcp:%s:%s", + return g_strdup_printf("vsock:%s:%s", addr->u.vsock.cid, addr->u.vsock.port); default: @@ -1124,6 +1124,11 @@ SocketAddress *socket_parse(const char *str, Error **errp) if (vsock_parse(&addr->u.vsock, str + strlen("vsock:"), errp)) { goto fail; } + } else if (strstart(str, "tcp:", NULL)) { + addr->type = SOCKET_ADDRESS_TYPE_INET; + if (inet_parse(&addr->u.inet, str + strlen("tcp:"), errp)) { + goto fail; + } } else { addr->type = SOCKET_ADDRESS_TYPE_INET; if (inet_parse(&addr->u.inet, str, errp)) { From 1f9c890fa3b6a09b34aea915500f9f002b5d9d60 Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Fri, 21 Oct 2022 11:09:20 +0200 Subject: [PATCH 319/705] net: stream: move to QIO to enable additional parameters Use QIOChannel, QIOChannelSocket and QIONetListener. This allows net/stream to use all the available parameters provided by SocketAddress. Signed-off-by: Laurent Vivier Acked-by: Michael S. Tsirkin Signed-off-by: Jason Wang --- net/stream.c | 516 ++++++++++++++++++------------------------------ qemu-options.hx | 4 +- 2 files changed, 190 insertions(+), 330 deletions(-) diff --git a/net/stream.c b/net/stream.c index 884f473018..54c67e14d2 100644 --- a/net/stream.c +++ b/net/stream.c @@ -35,48 +35,36 @@ #include "qemu/iov.h" #include "qemu/main-loop.h" #include "qemu/cutils.h" +#include "io/channel.h" +#include "io/channel-socket.h" +#include "io/net-listener.h" typedef struct NetStreamState { NetClientState nc; - int listen_fd; - int fd; + QIOChannel *listen_ioc; + QIONetListener *listener; + QIOChannel *ioc; + guint ioc_read_tag; + guint ioc_write_tag; SocketReadState rs; unsigned int send_index; /* number of bytes sent*/ - bool read_poll; /* waiting to receive data? */ - bool write_poll; /* waiting to transmit data? */ } NetStreamState; -static void net_stream_send(void *opaque); -static void net_stream_accept(void *opaque); -static void net_stream_writable(void *opaque); +static void net_stream_listen(QIONetListener *listener, + QIOChannelSocket *cioc, + void *opaque); -static void net_stream_update_fd_handler(NetStreamState *s) +static gboolean net_stream_writable(QIOChannel *ioc, + GIOCondition condition, + gpointer data) { - qemu_set_fd_handler(s->fd, - s->read_poll ? net_stream_send : NULL, - s->write_poll ? net_stream_writable : NULL, - s); -} + NetStreamState *s = data; -static void net_stream_read_poll(NetStreamState *s, bool enable) -{ - s->read_poll = enable; - net_stream_update_fd_handler(s); -} - -static void net_stream_write_poll(NetStreamState *s, bool enable) -{ - s->write_poll = enable; - net_stream_update_fd_handler(s); -} - -static void net_stream_writable(void *opaque) -{ - NetStreamState *s = opaque; - - net_stream_write_poll(s, false); + s->ioc_write_tag = 0; qemu_flush_queued_packets(&s->nc); + + return G_SOURCE_REMOVE; } static ssize_t net_stream_receive(NetClientState *nc, const uint8_t *buf, @@ -93,13 +81,15 @@ static ssize_t net_stream_receive(NetClientState *nc, const uint8_t *buf, .iov_len = size, }, }; + struct iovec local_iov[2]; + unsigned int nlocal_iov; size_t remaining; ssize_t ret; remaining = iov_size(iov, 2) - s->send_index; - ret = iov_send(s->fd, iov, 2, s->send_index, remaining); - - if (ret == -1 && errno == EAGAIN) { + nlocal_iov = iov_copy(local_iov, 2, iov, 2, s->send_index, remaining); + ret = qio_channel_writev(s->ioc, local_iov, nlocal_iov, NULL); + if (ret == QIO_CHANNEL_ERR_BLOCK) { ret = 0; /* handled further down */ } if (ret == -1) { @@ -108,19 +98,25 @@ static ssize_t net_stream_receive(NetClientState *nc, const uint8_t *buf, } if (ret < (ssize_t)remaining) { s->send_index += ret; - net_stream_write_poll(s, true); + s->ioc_write_tag = qio_channel_add_watch(s->ioc, G_IO_OUT, + net_stream_writable, s, NULL); return 0; } s->send_index = 0; return size; } +static gboolean net_stream_send(QIOChannel *ioc, + GIOCondition condition, + gpointer data); + static void net_stream_send_completed(NetClientState *nc, ssize_t len) { NetStreamState *s = DO_UPCAST(NetStreamState, nc, nc); - if (!s->read_poll) { - net_stream_read_poll(s, true); + if (!s->ioc_read_tag) { + s->ioc_read_tag = qio_channel_add_watch(s->ioc, G_IO_IN, + net_stream_send, s, NULL); } } @@ -131,19 +127,24 @@ static void net_stream_rs_finalize(SocketReadState *rs) if (qemu_send_packet_async(&s->nc, rs->buf, rs->packet_len, net_stream_send_completed) == 0) { - net_stream_read_poll(s, false); + if (s->ioc_read_tag) { + g_source_remove(s->ioc_read_tag); + s->ioc_read_tag = 0; + } } } -static void net_stream_send(void *opaque) +static gboolean net_stream_send(QIOChannel *ioc, + GIOCondition condition, + gpointer data) { - NetStreamState *s = opaque; + NetStreamState *s = data; int size; int ret; - uint8_t buf1[NET_BUFSIZE]; - const uint8_t *buf; + char buf1[NET_BUFSIZE]; + const char *buf; - size = recv(s->fd, buf1, sizeof(buf1), 0); + size = qio_channel_read(s->ioc, buf1, sizeof(buf1), NULL); if (size < 0) { if (errno != EWOULDBLOCK) { goto eoc; @@ -151,51 +152,63 @@ static void net_stream_send(void *opaque) } else if (size == 0) { /* end of connection */ eoc: - net_stream_read_poll(s, false); - net_stream_write_poll(s, false); - if (s->listen_fd != -1) { - qemu_set_fd_handler(s->listen_fd, net_stream_accept, NULL, s); + s->ioc_read_tag = 0; + if (s->ioc_write_tag) { + g_source_remove(s->ioc_write_tag); + s->ioc_write_tag = 0; } - closesocket(s->fd); + if (s->listener) { + qio_net_listener_set_client_func(s->listener, net_stream_listen, + s, NULL); + } + object_unref(OBJECT(s->ioc)); + s->ioc = NULL; - s->fd = -1; net_socket_rs_init(&s->rs, net_stream_rs_finalize, false); s->nc.link_down = true; qemu_set_info_str(&s->nc, ""); - return; + return G_SOURCE_REMOVE; } buf = buf1; - ret = net_fill_rstate(&s->rs, buf, size); + ret = net_fill_rstate(&s->rs, (const uint8_t *)buf, size); if (ret == -1) { goto eoc; } + + return G_SOURCE_CONTINUE; } static void net_stream_cleanup(NetClientState *nc) { NetStreamState *s = DO_UPCAST(NetStreamState, nc, nc); - if (s->fd != -1) { - net_stream_read_poll(s, false); - net_stream_write_poll(s, false); - close(s->fd); - s->fd = -1; + if (s->ioc) { + if (QIO_CHANNEL_SOCKET(s->ioc)->fd != -1) { + if (s->ioc_read_tag) { + g_source_remove(s->ioc_read_tag); + s->ioc_read_tag = 0; + } + if (s->ioc_write_tag) { + g_source_remove(s->ioc_write_tag); + s->ioc_write_tag = 0; + } + } + object_unref(OBJECT(s->ioc)); + s->ioc = NULL; } - if (s->listen_fd != -1) { - qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL); - closesocket(s->listen_fd); - s->listen_fd = -1; + if (s->listen_ioc) { + if (s->listener) { + qio_net_listener_disconnect(s->listener); + object_unref(OBJECT(s->listener)); + s->listener = NULL; + } + object_unref(OBJECT(s->listen_ioc)); + s->listen_ioc = NULL; } } -static void net_stream_connect(void *opaque) -{ - NetStreamState *s = opaque; - net_stream_read_poll(s, true); -} - static NetClientInfo net_stream_info = { .type = NET_CLIENT_DRIVER_STREAM, .size = sizeof(NetStreamState), @@ -203,76 +216,66 @@ static NetClientInfo net_stream_info = { .cleanup = net_stream_cleanup, }; -static NetStreamState *net_stream_fd_init(NetClientState *peer, - const char *model, - const char *name, - int fd, int is_connected) -{ - NetClientState *nc; - NetStreamState *s; - - nc = qemu_new_net_client(&net_stream_info, peer, model, name); - - qemu_set_info_str(nc, "fd=%d", fd); - - s = DO_UPCAST(NetStreamState, nc, nc); - - s->fd = fd; - s->listen_fd = -1; - net_socket_rs_init(&s->rs, net_stream_rs_finalize, false); - - /* Disable Nagle algorithm on TCP sockets to reduce latency */ - socket_set_nodelay(fd); - - if (is_connected) { - net_stream_connect(s); - } else { - qemu_set_fd_handler(s->fd, NULL, net_stream_connect, s); - } - return s; -} - -static void net_stream_accept(void *opaque) +static void net_stream_listen(QIONetListener *listener, + QIOChannelSocket *cioc, + void *opaque) { NetStreamState *s = opaque; - struct sockaddr_storage saddr; - socklen_t len; - int fd; + SocketAddress *addr; + char *uri; - for (;;) { - len = sizeof(saddr); - fd = qemu_accept(s->listen_fd, (struct sockaddr *)&saddr, &len); - if (fd < 0 && errno != EINTR) { - return; - } else if (fd >= 0) { - qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL); - break; - } - } + object_ref(OBJECT(cioc)); - s->fd = fd; + qio_net_listener_set_client_func(s->listener, NULL, s, NULL); + + s->ioc = QIO_CHANNEL(cioc); + qio_channel_set_name(s->ioc, "stream-server"); s->nc.link_down = false; - net_stream_connect(s); - switch (saddr.ss_family) { - case AF_INET: { - struct sockaddr_in *saddr_in = (struct sockaddr_in *)&saddr; - qemu_set_info_str(&s->nc, "connection from %s:%d", - inet_ntoa(saddr_in->sin_addr), - ntohs(saddr_in->sin_port)); - break; - } - case AF_UNIX: { - struct sockaddr_un saddr_un; + s->ioc_read_tag = qio_channel_add_watch(s->ioc, G_IO_IN, net_stream_send, + s, NULL); - len = sizeof(saddr_un); - getsockname(s->listen_fd, (struct sockaddr *)&saddr_un, &len); - qemu_set_info_str(&s->nc, "connect from %s", saddr_un.sun_path); - break; + if (cioc->localAddr.ss_family == AF_UNIX) { + addr = qio_channel_socket_get_local_address(cioc, NULL); + } else { + addr = qio_channel_socket_get_remote_address(cioc, NULL); } - default: - g_assert_not_reached(); + g_assert(addr != NULL); + uri = socket_uri(addr); + qemu_set_info_str(&s->nc, uri); + g_free(uri); + qapi_free_SocketAddress(addr); +} + +static void net_stream_server_listening(QIOTask *task, gpointer opaque) +{ + NetStreamState *s = opaque; + QIOChannelSocket *listen_sioc = QIO_CHANNEL_SOCKET(s->listen_ioc); + SocketAddress *addr; + int ret; + + if (listen_sioc->fd < 0) { + qemu_set_info_str(&s->nc, "connection error"); + return; } + + addr = qio_channel_socket_get_local_address(listen_sioc, NULL); + g_assert(addr != NULL); + ret = qemu_socket_try_set_nonblock(listen_sioc->fd); + if (addr->type == SOCKET_ADDRESS_TYPE_FD && ret < 0) { + qemu_set_info_str(&s->nc, "can't use file descriptor %s (errno %d)", + addr->u.fd.str, -ret); + return; + } + g_assert(ret == 0); + qapi_free_SocketAddress(addr); + + s->nc.link_down = true; + s->listener = qio_net_listener_new(); + + net_socket_rs_init(&s->rs, net_stream_rs_finalize, false); + qio_net_listener_set_client_func(s->listener, net_stream_listen, s, NULL); + qio_net_listener_add(s->listener, listen_sioc); } static int net_stream_server_init(NetClientState *peer, @@ -283,105 +286,61 @@ static int net_stream_server_init(NetClientState *peer, { NetClientState *nc; NetStreamState *s; - int fd, ret; - - switch (addr->type) { - case SOCKET_ADDRESS_TYPE_INET: { - struct sockaddr_in saddr_in; - - if (convert_host_port(&saddr_in, addr->u.inet.host, addr->u.inet.port, - errp) < 0) { - return -1; - } - - fd = qemu_socket(PF_INET, SOCK_STREAM, 0); - if (fd < 0) { - error_setg_errno(errp, errno, "can't create stream socket"); - return -1; - } - qemu_socket_set_nonblock(fd); - - socket_set_fast_reuse(fd); - - ret = bind(fd, (struct sockaddr *)&saddr_in, sizeof(saddr_in)); - if (ret < 0) { - error_setg_errno(errp, errno, "can't bind ip=%s to socket", - inet_ntoa(saddr_in.sin_addr)); - closesocket(fd); - return -1; - } - break; - } - case SOCKET_ADDRESS_TYPE_UNIX: { - struct sockaddr_un saddr_un; - - ret = unlink(addr->u.q_unix.path); - if (ret < 0 && errno != ENOENT) { - error_setg_errno(errp, errno, "failed to unlink socket %s", - addr->u.q_unix.path); - return -1; - } - - saddr_un.sun_family = PF_UNIX; - ret = snprintf(saddr_un.sun_path, sizeof(saddr_un.sun_path), "%s", - addr->u.q_unix.path); - if (ret < 0 || ret >= sizeof(saddr_un.sun_path)) { - error_setg(errp, "UNIX socket path '%s' is too long", - addr->u.q_unix.path); - error_append_hint(errp, "Path must be less than %zu bytes\n", - sizeof(saddr_un.sun_path)); - return -1; - } - - fd = qemu_socket(PF_UNIX, SOCK_STREAM, 0); - if (fd < 0) { - error_setg_errno(errp, errno, "can't create stream socket"); - return -1; - } - qemu_socket_set_nonblock(fd); - - ret = bind(fd, (struct sockaddr *)&saddr_un, sizeof(saddr_un)); - if (ret < 0) { - error_setg_errno(errp, errno, "can't create socket with path: %s", - saddr_un.sun_path); - closesocket(fd); - return -1; - } - break; - } - case SOCKET_ADDRESS_TYPE_FD: - fd = monitor_fd_param(monitor_cur(), addr->u.fd.str, errp); - if (fd == -1) { - return -1; - } - ret = qemu_socket_try_set_nonblock(fd); - if (ret < 0) { - error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d", - name, fd); - return -1; - } - break; - default: - error_setg(errp, "only support inet or fd type"); - return -1; - } - - ret = listen(fd, 0); - if (ret < 0) { - error_setg_errno(errp, errno, "can't listen on socket"); - closesocket(fd); - return -1; - } + QIOChannelSocket *listen_sioc = qio_channel_socket_new(); nc = qemu_new_net_client(&net_stream_info, peer, model, name); s = DO_UPCAST(NetStreamState, nc, nc); - s->fd = -1; - s->listen_fd = fd; - s->nc.link_down = true; + + s->listen_ioc = QIO_CHANNEL(listen_sioc); + qio_channel_socket_listen_async(listen_sioc, addr, 0, + net_stream_server_listening, s, + NULL, NULL); + + return 0; +} + +static void net_stream_client_connected(QIOTask *task, gpointer opaque) +{ + NetStreamState *s = opaque; + QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(s->ioc); + SocketAddress *addr; + gchar *uri; + int ret; + + if (sioc->fd < 0) { + qemu_set_info_str(&s->nc, "connection error"); + goto error; + } + + addr = qio_channel_socket_get_remote_address(sioc, NULL); + g_assert(addr != NULL); + uri = socket_uri(addr); + qemu_set_info_str(&s->nc, uri); + g_free(uri); + + ret = qemu_socket_try_set_nonblock(sioc->fd); + if (addr->type == SOCKET_ADDRESS_TYPE_FD && ret < 0) { + qemu_set_info_str(&s->nc, "can't use file descriptor %s (errno %d)", + addr->u.fd.str, -ret); + qapi_free_SocketAddress(addr); + goto error; + } + g_assert(ret == 0); + net_socket_rs_init(&s->rs, net_stream_rs_finalize, false); - qemu_set_fd_handler(s->listen_fd, net_stream_accept, NULL, s); - return 0; + /* Disable Nagle algorithm on TCP sockets to reduce latency */ + qio_channel_set_delay(s->ioc, false); + + s->ioc_read_tag = qio_channel_add_watch(s->ioc, G_IO_IN, net_stream_send, + s, NULL); + s->nc.link_down = false; + qapi_free_SocketAddress(addr); + + return; +error: + object_unref(OBJECT(s->ioc)); + s->ioc = NULL; } static int net_stream_client_init(NetClientState *peer, @@ -391,118 +350,19 @@ static int net_stream_client_init(NetClientState *peer, Error **errp) { NetStreamState *s; - struct sockaddr_in saddr_in; - struct sockaddr_un saddr_un; - int fd, connected, ret; + NetClientState *nc; + QIOChannelSocket *sioc = qio_channel_socket_new(); - switch (addr->type) { - case SOCKET_ADDRESS_TYPE_INET: - if (convert_host_port(&saddr_in, addr->u.inet.host, addr->u.inet.port, - errp) < 0) { - return -1; - } + nc = qemu_new_net_client(&net_stream_info, peer, model, name); + s = DO_UPCAST(NetStreamState, nc, nc); - fd = qemu_socket(PF_INET, SOCK_STREAM, 0); - if (fd < 0) { - error_setg_errno(errp, errno, "can't create stream socket"); - return -1; - } - qemu_socket_set_nonblock(fd); + s->ioc = QIO_CHANNEL(sioc); + s->nc.link_down = true; - connected = 0; - for (;;) { - ret = connect(fd, (struct sockaddr *)&saddr_in, sizeof(saddr_in)); - if (ret < 0) { - if (errno == EINTR || errno == EWOULDBLOCK) { - /* continue */ - } else if (errno == EINPROGRESS || - errno == EALREADY) { - break; - } else { - error_setg_errno(errp, errno, "can't connect socket"); - closesocket(fd); - return -1; - } - } else { - connected = 1; - break; - } - } - break; - case SOCKET_ADDRESS_TYPE_UNIX: - saddr_un.sun_family = PF_UNIX; - ret = snprintf(saddr_un.sun_path, sizeof(saddr_un.sun_path), "%s", - addr->u.q_unix.path); - if (ret < 0 || ret >= sizeof(saddr_un.sun_path)) { - error_setg(errp, "UNIX socket path '%s' is too long", - addr->u.q_unix.path); - error_append_hint(errp, "Path must be less than %zu bytes\n", - sizeof(saddr_un.sun_path)); - return -1; - } + qio_channel_socket_connect_async(sioc, addr, + net_stream_client_connected, s, + NULL, NULL); - fd = qemu_socket(PF_UNIX, SOCK_STREAM, 0); - if (fd < 0) { - error_setg_errno(errp, errno, "can't create stream socket"); - return -1; - } - qemu_socket_set_nonblock(fd); - - connected = 0; - for (;;) { - ret = connect(fd, (struct sockaddr *)&saddr_un, sizeof(saddr_un)); - if (ret < 0) { - if (errno == EINTR || errno == EWOULDBLOCK) { - /* continue */ - } else if (errno == EAGAIN || - errno == EALREADY) { - break; - } else { - error_setg_errno(errp, errno, "can't connect socket"); - closesocket(fd); - return -1; - } - } else { - connected = 1; - break; - } - } - break; - case SOCKET_ADDRESS_TYPE_FD: - fd = monitor_fd_param(monitor_cur(), addr->u.fd.str, errp); - if (fd == -1) { - return -1; - } - ret = qemu_socket_try_set_nonblock(fd); - if (ret < 0) { - error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d", - name, fd); - return -1; - } - connected = 1; - break; - default: - error_setg(errp, "only support inet, unix or fd type"); - return -1; - } - - s = net_stream_fd_init(peer, model, name, fd, connected); - - switch (addr->type) { - case SOCKET_ADDRESS_TYPE_INET: - qemu_set_info_str(&s->nc, "connect to %s:%d", - inet_ntoa(saddr_in.sin_addr), - ntohs(saddr_in.sin_port)); - break; - case SOCKET_ADDRESS_TYPE_UNIX: - qemu_set_info_str(&s->nc, " connect to %s", saddr_un.sun_path); - break; - case SOCKET_ADDRESS_TYPE_FD: - qemu_set_info_str(&s->nc, "connect to fd %d", fd); - break; - default: - g_assert_not_reached(); - } return 0; } diff --git a/qemu-options.hx b/qemu-options.hx index e76142bfb6..ceee0ddc25 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -2772,8 +2772,8 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev, "-netdev socket,id=str[,fd=h][,udp=host:port][,localaddr=host:port]\n" " configure a network backend to connect to another network\n" " using an UDP tunnel\n" - "-netdev stream,id=str[,server=on|off],addr.type=inet,addr.host=host,addr.port=port\n" - "-netdev stream,id=str[,server=on|off],addr.type=unix,addr.path=path\n" + "-netdev stream,id=str[,server=on|off],addr.type=inet,addr.host=host,addr.port=port[,to=maxport][,numeric=on|off][,keep-alive=on|off][,mptcp=on|off][,addr.ipv4=on|off][,addr.ipv6=on|off]\n" + "-netdev stream,id=str[,server=on|off],addr.type=unix,addr.path=path[,abstract=on|off][,tight=on|off]\n" "-netdev stream,id=str[,server=on|off],addr.type=fd,addr.str=file-descriptor\n" " configure a network backend to connect to another network\n" " using a socket connection in stream mode.\n" From e506fee8b1e092f6ac6f9459bf6a35b807644ad2 Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Fri, 21 Oct 2022 11:09:22 +0200 Subject: [PATCH 320/705] net: stream: add QAPI events to report connection state The netdev reports NETDEV_STREAM_CONNECTED event when the backend is connected, and NETDEV_STREAM_DISCONNECTED when it is disconnected. The NETDEV_STREAM_CONNECTED event includes the destination address. This allows a system manager like libvirt to detect when the server fails. For instance with passt: { 'execute': 'qmp_capabilities' } { "return": { } } { "timestamp": { "seconds": 1666341395, "microseconds": 505347 }, "event": "NETDEV_STREAM_CONNECTED", "data": { "netdev-id": "netdev0", "addr": { "path": "/tmp/passt_1.socket", "type": "unix" } } } [killing passt here] { "timestamp": { "seconds": 1666341430, "microseconds": 968694 }, "event": "NETDEV_STREAM_DISCONNECTED", "data": { "netdev-id": "netdev0" } } Signed-off-by: Laurent Vivier Acked-by: Michael S. Tsirkin Signed-off-by: Jason Wang --- net/stream.c | 5 +++++ qapi/net.json | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/net/stream.c b/net/stream.c index 54c67e14d2..53b7040cc4 100644 --- a/net/stream.c +++ b/net/stream.c @@ -38,6 +38,7 @@ #include "io/channel.h" #include "io/channel-socket.h" #include "io/net-listener.h" +#include "qapi/qapi-events-net.h" typedef struct NetStreamState { NetClientState nc; @@ -168,6 +169,8 @@ static gboolean net_stream_send(QIOChannel *ioc, s->nc.link_down = true; qemu_set_info_str(&s->nc, ""); + qapi_event_send_netdev_stream_disconnected(s->nc.name); + return G_SOURCE_REMOVE; } buf = buf1; @@ -244,6 +247,7 @@ static void net_stream_listen(QIONetListener *listener, uri = socket_uri(addr); qemu_set_info_str(&s->nc, uri); g_free(uri); + qapi_event_send_netdev_stream_connected(s->nc.name, addr); qapi_free_SocketAddress(addr); } @@ -335,6 +339,7 @@ static void net_stream_client_connected(QIOTask *task, gpointer opaque) s->ioc_read_tag = qio_channel_add_watch(s->ioc, G_IO_IN, net_stream_send, s, NULL); s->nc.link_down = false; + qapi_event_send_netdev_stream_connected(s->nc.name, addr); qapi_free_SocketAddress(addr); return; diff --git a/qapi/net.json b/qapi/net.json index cbc8d77c97..522ac582ed 100644 --- a/qapi/net.json +++ b/qapi/net.json @@ -898,3 +898,52 @@ ## { 'event': 'FAILOVER_NEGOTIATED', 'data': {'device-id': 'str'} } + +## +# @NETDEV_STREAM_CONNECTED: +# +# Emitted when the netdev stream backend is connected +# +# @netdev-id: QEMU netdev id that is connected +# @addr: The destination address +# +# Since: 7.2 +# +# Example: +# +# <- { "event": "NETDEV_STREAM_CONNECTED", +# "data": { "netdev-id": "netdev0", +# "addr": { "port": "47666", "ipv6": true, +# "host": "::1", "type": "inet" } }, +# "timestamp": { "seconds": 1666269863, "microseconds": 311222 } } +# +# or +# +# <- { "event": "NETDEV_STREAM_CONNECTED", +# "data": { "netdev-id": "netdev0", +# "addr": { "path": "/tmp/qemu0", "type": "unix" } }, +# "timestamp": { "seconds": 1666269706, "microseconds": 413651 } } +# +## +{ 'event': 'NETDEV_STREAM_CONNECTED', + 'data': { 'netdev-id': 'str', + 'addr': 'SocketAddress' } } + +## +# @NETDEV_STREAM_DISCONNECTED: +# +# Emitted when the netdev stream backend is disconnected +# +# @netdev-id: QEMU netdev id that is disconnected +# +# Since: 7.2 +# +# Example: +# +# <- { 'event': 'NETDEV_STREAM_DISCONNECTED', +# 'data': {'netdev-id': 'netdev0'}, +# 'timestamp': {'seconds': 1663330937, 'microseconds': 526695} } +# +## +{ 'event': 'NETDEV_STREAM_DISCONNECTED', + 'data': { 'netdev-id': 'str' } } From 9e3eb3b29a73c35adbbe60b0fd3c8feb6c680d55 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Wed, 12 Oct 2022 20:27:55 +0200 Subject: [PATCH 321/705] tests/tcg/s390x: Add a test for the vistr instruction This test can be used to verify that the change in the previous commit is indeed fixing the problem with the M3 vs. M4 field mixup. Message-Id: <20221012182755.1014853-4-thuth@redhat.com> Reviewed-by: Richard Henderson Reviewed-by: David Hildenbrand Signed-off-by: Thomas Huth --- tests/tcg/s390x/Makefile.target | 4 +++ tests/tcg/s390x/vistr.c | 45 +++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 tests/tcg/s390x/vistr.c diff --git a/tests/tcg/s390x/Makefile.target b/tests/tcg/s390x/Makefile.target index 29c8af8207..07fcc6d0ce 100644 --- a/tests/tcg/s390x/Makefile.target +++ b/tests/tcg/s390x/Makefile.target @@ -25,6 +25,10 @@ TESTS+=signals-s390x TESTS+=branch-relative-long TESTS+=noexec +Z13_TESTS=vistr +$(Z13_TESTS): CFLAGS+=-march=z13 -O2 +TESTS+=$(Z13_TESTS) + ifneq ($(CROSS_CC_HAS_Z14),) Z14_TESTS=vfminmax vfminmax: LDFLAGS+=-lm diff --git a/tests/tcg/s390x/vistr.c b/tests/tcg/s390x/vistr.c new file mode 100644 index 0000000000..8e3e987d71 --- /dev/null +++ b/tests/tcg/s390x/vistr.c @@ -0,0 +1,45 @@ +/* + * Test the VECTOR ISOLATE STRING (vistr) instruction + */ +#include +#include +#include "vx.h" + +static inline void vistr(S390Vector *v1, S390Vector *v2, + const uint8_t m3, const uint8_t m5) +{ + asm volatile("vistr %[v1], %[v2], %[m3], %[m5]\n" + : [v1] "=v" (v1->v) + : [v2] "v" (v2->v) + , [m3] "i" (m3) + , [m5] "i" (m5) + : "cc"); +} + +int main(int argc, char *argv[]) +{ + S390Vector vd = {}; + S390Vector vs16 = { + .h[0] = 0x1234, .h[1] = 0x0056, .h[2] = 0x7800, .h[3] = 0x0000, + .h[4] = 0x0078, .h[5] = 0x0000, .h[6] = 0x6543, .h[7] = 0x2100 + }; + S390Vector vs32 = { + .w[0] = 0x12340000, .w[1] = 0x78654300, + .w[2] = 0x0, .w[3] = 0x12, + }; + + vistr(&vd, &vs16, 1, 0); + if (vd.h[0] != 0x1234 || vd.h[1] != 0x0056 || vd.h[2] != 0x7800 || + vd.h[3] || vd.h[4] || vd.h[5] || vd.h[6] || vd.h[7]) { + puts("ERROR: vitrh failed!"); + return 1; + } + + vistr(&vd, &vs32, 2, 0); + if (vd.w[0] != 0x12340000 || vd.w[1] != 0x78654300 || vd.w[2] || vd.w[3]) { + puts("ERROR: vitrf failed!"); + return 1; + } + + return 0; +} From 9d711f19c5608910cdefdad24e23a2e695b312bb Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Wed, 19 Oct 2022 14:56:40 +0200 Subject: [PATCH 322/705] MAINTAINERS: target/s390x/: add Ilya as reviewer Ilya has volunteered to review TCG patches for s390x. Signed-off-by: Christian Borntraeger Acked-by: David Hildenbrand Acked-by: Richard Henderson Acked-by: Ilya Leoshkevich Message-Id: <20221019125640.3014143-1-borntraeger@linux.ibm.com> Signed-off-by: Thomas Huth --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 17ff0a0138..0a331eec7a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -303,6 +303,7 @@ F: target/rx/ S390 TCG CPUs M: Richard Henderson M: David Hildenbrand +R: Ilya Leoshkevich S: Maintained F: target/s390x/ F: target/s390x/tcg From daa8bb57dba5add4929dea6919858a2062101b26 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Wed, 12 Oct 2022 10:43:34 +0200 Subject: [PATCH 323/705] tests/qtest/tpm: Clean up remainders of swtpm After running "make check", there are remainders of the tpm tests left in the /tmp directory, slowly filling it up. Seems like "swtpm" leaves a ".lock" and a "tpm2-00.permall" file behind, so that the g_rmdir() calls on the temporary directories fail. Introduce a helper function to remove those leftovers before doing the g_rmdir(). Message-Id: <20221012084334.794253-1-thuth@redhat.com> Reviewed-by: Stefan Berger Signed-off-by: Thomas Huth --- tests/qtest/tpm-crb-swtpm-test.c | 5 ++--- tests/qtest/tpm-tis-device-swtpm-test.c | 5 ++--- tests/qtest/tpm-tis-swtpm-test.c | 5 ++--- tests/qtest/tpm-util.c | 19 +++++++++++++++++++ tests/qtest/tpm-util.h | 1 + 5 files changed, 26 insertions(+), 9 deletions(-) diff --git a/tests/qtest/tpm-crb-swtpm-test.c b/tests/qtest/tpm-crb-swtpm-test.c index 55fdb5657d..40254f762f 100644 --- a/tests/qtest/tpm-crb-swtpm-test.c +++ b/tests/qtest/tpm-crb-swtpm-test.c @@ -13,7 +13,6 @@ */ #include "qemu/osdep.h" -#include #include "libqtest.h" #include "qemu/module.h" @@ -62,9 +61,9 @@ int main(int argc, char **argv) tpm_crb_swtpm_migration_test); ret = g_test_run(); - g_rmdir(ts.dst_tpm_path); + tpm_util_rmdir(ts.dst_tpm_path); g_free(ts.dst_tpm_path); - g_rmdir(ts.src_tpm_path); + tpm_util_rmdir(ts.src_tpm_path); g_free(ts.src_tpm_path); g_free(ts.uri); diff --git a/tests/qtest/tpm-tis-device-swtpm-test.c b/tests/qtest/tpm-tis-device-swtpm-test.c index 7b20035142..8c067fddd4 100644 --- a/tests/qtest/tpm-tis-device-swtpm-test.c +++ b/tests/qtest/tpm-tis-device-swtpm-test.c @@ -14,7 +14,6 @@ */ #include "qemu/osdep.h" -#include #include "libqtest.h" #include "qemu/module.h" @@ -66,9 +65,9 @@ int main(int argc, char **argv) tpm_tis_swtpm_migration_test); ret = g_test_run(); - g_rmdir(ts.dst_tpm_path); + tpm_util_rmdir(ts.dst_tpm_path); g_free(ts.dst_tpm_path); - g_rmdir(ts.src_tpm_path); + tpm_util_rmdir(ts.src_tpm_path); g_free(ts.src_tpm_path); g_free(ts.uri); diff --git a/tests/qtest/tpm-tis-swtpm-test.c b/tests/qtest/tpm-tis-swtpm-test.c index 90131cb3c4..11539c0a52 100644 --- a/tests/qtest/tpm-tis-swtpm-test.c +++ b/tests/qtest/tpm-tis-swtpm-test.c @@ -13,7 +13,6 @@ */ #include "qemu/osdep.h" -#include #include "libqtest.h" #include "qemu/module.h" @@ -61,9 +60,9 @@ int main(int argc, char **argv) tpm_tis_swtpm_migration_test); ret = g_test_run(); - g_rmdir(ts.dst_tpm_path); + tpm_util_rmdir(ts.dst_tpm_path); g_free(ts.dst_tpm_path); - g_rmdir(ts.src_tpm_path); + tpm_util_rmdir(ts.src_tpm_path); g_free(ts.src_tpm_path); g_free(ts.uri); diff --git a/tests/qtest/tpm-util.c b/tests/qtest/tpm-util.c index e0dc5da0af..a7efe2d0d2 100644 --- a/tests/qtest/tpm-util.c +++ b/tests/qtest/tpm-util.c @@ -13,6 +13,7 @@ */ #include "qemu/osdep.h" +#include #include "hw/acpi/tpm.h" #include "libqtest.h" @@ -292,3 +293,21 @@ void tpm_util_migration_start_qemu(QTestState **src_qemu, g_free(src_qemu_args); g_free(dst_qemu_args); } + +/* Remove directory with remainders of swtpm */ +void tpm_util_rmdir(const char *path) +{ + char *filename; + int ret; + + filename = g_strdup_printf("%s/tpm2-00.permall", path); + g_unlink(filename); + g_free(filename); + + filename = g_strdup_printf("%s/.lock", path); + g_unlink(filename); + g_free(filename); + + ret = g_rmdir(path); + g_assert(!ret); +} diff --git a/tests/qtest/tpm-util.h b/tests/qtest/tpm-util.h index 3b97d69017..80720afac0 100644 --- a/tests/qtest/tpm-util.h +++ b/tests/qtest/tpm-util.h @@ -53,5 +53,6 @@ void tpm_util_migration_start_qemu(QTestState **src_qemu, const char *machine_options); void tpm_util_wait_for_migration_complete(QTestState *who); +void tpm_util_rmdir(const char *path); #endif /* TESTS_TPM_UTIL_H */ From 73df4f92273d80556777b9f2084898bd1889315e Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Wed, 12 Oct 2022 11:14:35 +0200 Subject: [PATCH 324/705] tests/qtest/cxl-test: Remove temporary directories after testing The cxl-test leaves some temporary directories behind. Let's clean them up now! Message-Id: <20221012091435.893570-1-thuth@redhat.com> Reviewed-by: Zhang Chen Acked-by: Jonathan Cameron Signed-off-by: Thomas Huth --- tests/qtest/cxl-test.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/qtest/cxl-test.c b/tests/qtest/cxl-test.c index cbe0fb549b..61f25a72b6 100644 --- a/tests/qtest/cxl-test.c +++ b/tests/qtest/cxl-test.c @@ -101,6 +101,7 @@ static void cxl_t3d(void) qtest_start(cmdline->str); qtest_end(); + rmdir(tmpfs); } static void cxl_1pxb_2rp_2t3d(void) @@ -115,6 +116,7 @@ static void cxl_1pxb_2rp_2t3d(void) qtest_start(cmdline->str); qtest_end(); + rmdir(tmpfs); } static void cxl_2pxb_4rp_4t3d(void) @@ -130,6 +132,7 @@ static void cxl_2pxb_4rp_4t3d(void) qtest_start(cmdline->str); qtest_end(); + rmdir(tmpfs); } #endif /* CONFIG_POSIX */ From 0e283d845e9040a4a20dfb2c7122c9e95afca46f Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Thu, 13 Oct 2022 14:52:45 +0900 Subject: [PATCH 325/705] tests/qtest/libqos/e1000e: Use e1000_regs.h The register definitions in tests/qtest/libqos/e1000e.c had names different from hw/net/e1000_regs.h, which made it hard to understand what test codes corresponds to the implementation. Use hw/net/e1000_regs.h from tests/qtest/libqos/e1000e.c to remove these duplications. E1000E_CTRL_EXT_TXLSFLOW is removed from E1000E_CTRL_EXT settings because hw/net/e1000_regs.h does not have the definition and it is for TCP segmentation offload, which does not matter for the implemented tests. Signed-off-by: Akihiko Odaki Message-Id: <20221013055245.28102-1-akihiko.odaki@daynix.com> Signed-off-by: Thomas Huth --- hw/net/e1000_regs.h | 1 + tests/qtest/libqos/e1000e.c | 119 +++++++++++++----------------------- 2 files changed, 45 insertions(+), 75 deletions(-) diff --git a/hw/net/e1000_regs.h b/hw/net/e1000_regs.h index ae99f58bab..9d423f6c09 100644 --- a/hw/net/e1000_regs.h +++ b/hw/net/e1000_regs.h @@ -793,6 +793,7 @@ #define E1000_CTRL_EXT_ASDCHK 0x00001000 /* auto speed detection check */ #define E1000_CTRL_EXT_EE_RST 0x00002000 /* EEPROM reset */ #define E1000_CTRL_EXT_LINK_EN 0x00010000 /* enable link status from external LINK_0 and LINK_1 pins */ +#define E1000_CTRL_EXT_DRV_LOAD 0x10000000 /* Driver loaded bit for FW */ #define E1000_CTRL_EXT_EIAME 0x01000000 #define E1000_CTRL_EXT_IAME 0x08000000 /* Int ACK Auto-mask */ #define E1000_CTRL_EXT_PBA_CLR 0x80000000 /* PBA Clear */ diff --git a/tests/qtest/libqos/e1000e.c b/tests/qtest/libqos/e1000e.c index fc14b07884..ed47e34044 100644 --- a/tests/qtest/libqos/e1000e.c +++ b/tests/qtest/libqos/e1000e.c @@ -17,6 +17,7 @@ */ #include "qemu/osdep.h" +#include "hw/net/e1000_regs.h" #include "../libqtest.h" #include "pci-pc.h" #include "qemu/sockets.h" @@ -27,49 +28,13 @@ #include "qgraph.h" #include "e1000e.h" -#define E1000E_IMS (0x00d0) +#define E1000E_IVAR_TEST_CFG \ + (E1000E_RX0_MSG_ID | E1000_IVAR_INT_ALLOC_VALID | \ + ((E1000E_TX0_MSG_ID | E1000_IVAR_INT_ALLOC_VALID) << 8) | \ + ((E1000E_OTHER_MSG_ID | E1000_IVAR_INT_ALLOC_VALID) << 16) | \ + E1000_IVAR_TX_INT_EVERY_WB) -#define E1000E_STATUS (0x0008) -#define E1000E_STATUS_LU BIT(1) -#define E1000E_STATUS_ASDV1000 BIT(9) - -#define E1000E_CTRL (0x0000) -#define E1000E_CTRL_RESET BIT(26) - -#define E1000E_RCTL (0x0100) -#define E1000E_RCTL_EN BIT(1) -#define E1000E_RCTL_UPE BIT(3) -#define E1000E_RCTL_MPE BIT(4) - -#define E1000E_RFCTL (0x5008) -#define E1000E_RFCTL_EXTEN BIT(15) - -#define E1000E_TCTL (0x0400) -#define E1000E_TCTL_EN BIT(1) - -#define E1000E_CTRL_EXT (0x0018) -#define E1000E_CTRL_EXT_DRV_LOAD BIT(28) -#define E1000E_CTRL_EXT_TXLSFLOW BIT(22) - -#define E1000E_IVAR (0x00E4) -#define E1000E_IVAR_TEST_CFG ((E1000E_RX0_MSG_ID << 0) | BIT(3) | \ - (E1000E_TX0_MSG_ID << 8) | BIT(11) | \ - (E1000E_OTHER_MSG_ID << 16) | BIT(19) | \ - BIT(31)) - -#define E1000E_RING_LEN (0x1000) - -#define E1000E_TDBAL (0x3800) - -#define E1000E_TDBAH (0x3804) -#define E1000E_TDH (0x3810) - -#define E1000E_RDBAL (0x2800) -#define E1000E_RDBAH (0x2804) -#define E1000E_RDH (0x2810) - -#define E1000E_TXD_LEN (16) -#define E1000E_RXD_LEN (16) +#define E1000E_RING_LEN (0x1000) static void e1000e_macreg_write(QE1000E *d, uint32_t reg, uint32_t val) { @@ -87,30 +52,34 @@ void e1000e_tx_ring_push(QE1000E *d, void *descr) { QE1000E_PCI *d_pci = container_of(d, QE1000E_PCI, e1000e); uint32_t tail = e1000e_macreg_read(d, E1000E_TDT); - uint32_t len = e1000e_macreg_read(d, E1000E_TDLEN) / E1000E_TXD_LEN; + uint32_t len = e1000e_macreg_read(d, E1000E_TDLEN) / E1000_RING_DESC_LEN; - qtest_memwrite(d_pci->pci_dev.bus->qts, d->tx_ring + tail * E1000E_TXD_LEN, - descr, E1000E_TXD_LEN); + qtest_memwrite(d_pci->pci_dev.bus->qts, + d->tx_ring + tail * E1000_RING_DESC_LEN, + descr, E1000_RING_DESC_LEN); e1000e_macreg_write(d, E1000E_TDT, (tail + 1) % len); /* Read WB data for the packet transmitted */ - qtest_memread(d_pci->pci_dev.bus->qts, d->tx_ring + tail * E1000E_TXD_LEN, - descr, E1000E_TXD_LEN); + qtest_memread(d_pci->pci_dev.bus->qts, + d->tx_ring + tail * E1000_RING_DESC_LEN, + descr, E1000_RING_DESC_LEN); } void e1000e_rx_ring_push(QE1000E *d, void *descr) { QE1000E_PCI *d_pci = container_of(d, QE1000E_PCI, e1000e); uint32_t tail = e1000e_macreg_read(d, E1000E_RDT); - uint32_t len = e1000e_macreg_read(d, E1000E_RDLEN) / E1000E_RXD_LEN; + uint32_t len = e1000e_macreg_read(d, E1000E_RDLEN) / E1000_RING_DESC_LEN; - qtest_memwrite(d_pci->pci_dev.bus->qts, d->rx_ring + tail * E1000E_RXD_LEN, - descr, E1000E_RXD_LEN); + qtest_memwrite(d_pci->pci_dev.bus->qts, + d->rx_ring + tail * E1000_RING_DESC_LEN, + descr, E1000_RING_DESC_LEN); e1000e_macreg_write(d, E1000E_RDT, (tail + 1) % len); /* Read WB data for the packet received */ - qtest_memread(d_pci->pci_dev.bus->qts, d->rx_ring + tail * E1000E_RXD_LEN, - descr, E1000E_RXD_LEN); + qtest_memread(d_pci->pci_dev.bus->qts, + d->rx_ring + tail * E1000_RING_DESC_LEN, + descr, E1000_RING_DESC_LEN); } static void e1000e_foreach_callback(QPCIDevice *dev, int devfn, void *data) @@ -151,53 +120,53 @@ static void e1000e_pci_start_hw(QOSGraphObject *obj) qpci_device_enable(&d->pci_dev); /* Reset the device */ - val = e1000e_macreg_read(&d->e1000e, E1000E_CTRL); - e1000e_macreg_write(&d->e1000e, E1000E_CTRL, val | E1000E_CTRL_RESET); + val = e1000e_macreg_read(&d->e1000e, E1000_CTRL); + e1000e_macreg_write(&d->e1000e, E1000_CTRL, val | E1000_CTRL_RST); /* Enable and configure MSI-X */ qpci_msix_enable(&d->pci_dev); - e1000e_macreg_write(&d->e1000e, E1000E_IVAR, E1000E_IVAR_TEST_CFG); + e1000e_macreg_write(&d->e1000e, E1000_IVAR, E1000E_IVAR_TEST_CFG); /* Check the device status - link and speed */ - val = e1000e_macreg_read(&d->e1000e, E1000E_STATUS); - g_assert_cmphex(val & (E1000E_STATUS_LU | E1000E_STATUS_ASDV1000), - ==, E1000E_STATUS_LU | E1000E_STATUS_ASDV1000); + val = e1000e_macreg_read(&d->e1000e, E1000_STATUS); + g_assert_cmphex(val & (E1000_STATUS_LU | E1000_STATUS_LAN_INIT_DONE), + ==, E1000_STATUS_LU | E1000_STATUS_LAN_INIT_DONE); /* Initialize TX/RX logic */ - e1000e_macreg_write(&d->e1000e, E1000E_RCTL, 0); - e1000e_macreg_write(&d->e1000e, E1000E_TCTL, 0); + e1000e_macreg_write(&d->e1000e, E1000_RCTL, 0); + e1000e_macreg_write(&d->e1000e, E1000_TCTL, 0); /* Notify the device that the driver is ready */ - val = e1000e_macreg_read(&d->e1000e, E1000E_CTRL_EXT); - e1000e_macreg_write(&d->e1000e, E1000E_CTRL_EXT, - val | E1000E_CTRL_EXT_DRV_LOAD | E1000E_CTRL_EXT_TXLSFLOW); + val = e1000e_macreg_read(&d->e1000e, E1000_CTRL_EXT); + e1000e_macreg_write(&d->e1000e, E1000_CTRL_EXT, + val | E1000_CTRL_EXT_DRV_LOAD); - e1000e_macreg_write(&d->e1000e, E1000E_TDBAL, + e1000e_macreg_write(&d->e1000e, E1000_TDBAL, (uint32_t) d->e1000e.tx_ring); - e1000e_macreg_write(&d->e1000e, E1000E_TDBAH, + e1000e_macreg_write(&d->e1000e, E1000_TDBAH, (uint32_t) (d->e1000e.tx_ring >> 32)); e1000e_macreg_write(&d->e1000e, E1000E_TDLEN, E1000E_RING_LEN); e1000e_macreg_write(&d->e1000e, E1000E_TDT, 0); - e1000e_macreg_write(&d->e1000e, E1000E_TDH, 0); + e1000e_macreg_write(&d->e1000e, E1000_TDH, 0); /* Enable transmit */ - e1000e_macreg_write(&d->e1000e, E1000E_TCTL, E1000E_TCTL_EN); - e1000e_macreg_write(&d->e1000e, E1000E_RDBAL, + e1000e_macreg_write(&d->e1000e, E1000_TCTL, E1000_TCTL_EN); + e1000e_macreg_write(&d->e1000e, E1000_RDBAL, (uint32_t)d->e1000e.rx_ring); - e1000e_macreg_write(&d->e1000e, E1000E_RDBAH, + e1000e_macreg_write(&d->e1000e, E1000_RDBAH, (uint32_t)(d->e1000e.rx_ring >> 32)); e1000e_macreg_write(&d->e1000e, E1000E_RDLEN, E1000E_RING_LEN); e1000e_macreg_write(&d->e1000e, E1000E_RDT, 0); - e1000e_macreg_write(&d->e1000e, E1000E_RDH, 0); + e1000e_macreg_write(&d->e1000e, E1000_RDH, 0); /* Enable receive */ - e1000e_macreg_write(&d->e1000e, E1000E_RFCTL, E1000E_RFCTL_EXTEN); - e1000e_macreg_write(&d->e1000e, E1000E_RCTL, E1000E_RCTL_EN | - E1000E_RCTL_UPE | - E1000E_RCTL_MPE); + e1000e_macreg_write(&d->e1000e, E1000_RFCTL, E1000_RFCTL_EXTEN); + e1000e_macreg_write(&d->e1000e, E1000_RCTL, E1000_RCTL_EN | + E1000_RCTL_UPE | + E1000_RCTL_MPE); /* Enable all interrupts */ - e1000e_macreg_write(&d->e1000e, E1000E_IMS, 0xFFFFFFFF); + e1000e_macreg_write(&d->e1000e, E1000_IMS, 0xFFFFFFFF); } From 690d43a8b1fa0d6fce6f68725e823e95115cf532 Mon Sep 17 00:00:00 2001 From: Brad Smith Date: Sun, 23 Oct 2022 01:00:07 -0400 Subject: [PATCH 326/705] tests/vm: update openbsd to release 7.2 tests/vm: update openbsd to release 7.2 Signed-off-by: Brad Smith Message-Id: Signed-off-by: Thomas Huth --- tests/vm/openbsd | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/vm/openbsd b/tests/vm/openbsd index 6f1b6f5b98..eaeb201e91 100755 --- a/tests/vm/openbsd +++ b/tests/vm/openbsd @@ -22,8 +22,8 @@ class OpenBSDVM(basevm.BaseVM): name = "openbsd" arch = "x86_64" - link = "https://cdn.openbsd.org/pub/OpenBSD/7.1/amd64/install71.iso" - csum = "d3a7c5b9bf890bc404304a1c96f9ee72e1d9bbcf9cc849c1133bdb0d67843396" + link = "https://cdn.openbsd.org/pub/OpenBSD/7.2/amd64/install72.iso" + csum = "0369ef40a3329efcb978c578c7fdc7bda71e502aecec930a74b44160928c91d3" size = "20G" pkgs = [ # tools @@ -56,6 +56,9 @@ class OpenBSDVM(basevm.BaseVM): # libs: migration "zstd", + + # libs: networking + "libslirp", ] BUILD_SCRIPT = """ From 8f4bcbcf110f27b3bf8b8c33b48ec321f3e136d3 Mon Sep 17 00:00:00 2001 From: Brad Smith Date: Tue, 25 Oct 2022 11:02:15 -0400 Subject: [PATCH 327/705] tests: Add sndio to the FreeBSD CI containers / VM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add sndio to the FreeBSD CI containers / VM Signed-off-by: Brad Smith Reviewed-by: Daniel P. Berrangé Reviewed-by: Warner Losh Message-Id: Signed-off-by: Thomas Huth --- .gitlab-ci.d/cirrus/freebsd-12.vars | 2 +- .gitlab-ci.d/cirrus/freebsd-13.vars | 2 +- tests/docker/dockerfiles/alpine.docker | 3 +- tests/docker/dockerfiles/centos8.docker | 2 +- .../dockerfiles/debian-amd64-cross.docker | 235 ++++++++--------- tests/docker/dockerfiles/debian-amd64.docker | 237 +++++++++--------- .../dockerfiles/debian-arm64-cross.docker | 233 ++++++++--------- .../dockerfiles/debian-armel-cross.docker | 231 ++++++++--------- .../dockerfiles/debian-armhf-cross.docker | 233 ++++++++--------- .../dockerfiles/debian-mips64el-cross.docker | 227 ++++++++--------- .../dockerfiles/debian-mipsel-cross.docker | 227 ++++++++--------- .../dockerfiles/debian-ppc64el-cross.docker | 231 ++++++++--------- .../dockerfiles/debian-s390x-cross.docker | 229 ++++++++--------- tests/docker/dockerfiles/fedora.docker | 230 ++++++++--------- tests/docker/dockerfiles/opensuse-leap.docker | 3 +- tests/docker/dockerfiles/ubuntu2004.docker | 235 ++++++++--------- tests/lcitool/libvirt-ci | 2 +- tests/lcitool/projects/qemu.yml | 1 + tests/vm/freebsd | 3 + 19 files changed, 1291 insertions(+), 1275 deletions(-) diff --git a/.gitlab-ci.d/cirrus/freebsd-12.vars b/.gitlab-ci.d/cirrus/freebsd-12.vars index c3db1d7d30..e3fc3235b9 100644 --- a/.gitlab-ci.d/cirrus/freebsd-12.vars +++ b/.gitlab-ci.d/cirrus/freebsd-12.vars @@ -11,6 +11,6 @@ MAKE='/usr/local/bin/gmake' NINJA='/usr/local/bin/ninja' PACKAGING_COMMAND='pkg' PIP3='/usr/local/bin/pip-3.8' -PKGS='alsa-lib bash bison bzip2 ca_root_nss capstone4 ccache cdrkit-genisoimage cmocka ctags curl cyrus-sasl dbus diffutils dtc flex fusefs-libs3 gettext git glib gmake gnutls gsed gtk3 json-c libepoxy libffi libgcrypt libjpeg-turbo libnfs libslirp libspice-server libssh libtasn1 llvm lzo2 meson ncurses nettle ninja opencv perl5 pixman pkgconf png py39-numpy py39-pillow py39-pip py39-sphinx py39-sphinx_rtd_theme py39-yaml python3 rpm2cpio sdl2 sdl2_image snappy spice-protocol tesseract texinfo usbredir virglrenderer vte3 zstd' +PKGS='alsa-lib bash bison bzip2 ca_root_nss capstone4 ccache cdrkit-genisoimage cmocka ctags curl cyrus-sasl dbus diffutils dtc flex fusefs-libs3 gettext git glib gmake gnutls gsed gtk3 json-c libepoxy libffi libgcrypt libjpeg-turbo libnfs libslirp libspice-server libssh libtasn1 llvm lzo2 meson ncurses nettle ninja opencv perl5 pixman pkgconf png py39-numpy py39-pillow py39-pip py39-sphinx py39-sphinx_rtd_theme py39-yaml python3 rpm2cpio sdl2 sdl2_image snappy sndio spice-protocol tesseract texinfo usbredir virglrenderer vte3 zstd' PYPI_PKGS='' PYTHON='/usr/local/bin/python3' diff --git a/.gitlab-ci.d/cirrus/freebsd-13.vars b/.gitlab-ci.d/cirrus/freebsd-13.vars index d31faa787f..9f56babd9c 100644 --- a/.gitlab-ci.d/cirrus/freebsd-13.vars +++ b/.gitlab-ci.d/cirrus/freebsd-13.vars @@ -11,6 +11,6 @@ MAKE='/usr/local/bin/gmake' NINJA='/usr/local/bin/ninja' PACKAGING_COMMAND='pkg' PIP3='/usr/local/bin/pip-3.8' -PKGS='alsa-lib bash bison bzip2 ca_root_nss capstone4 ccache cdrkit-genisoimage cmocka ctags curl cyrus-sasl dbus diffutils dtc flex fusefs-libs3 gettext git glib gmake gnutls gsed gtk3 json-c libepoxy libffi libgcrypt libjpeg-turbo libnfs libslirp libspice-server libssh libtasn1 llvm lzo2 meson ncurses nettle ninja opencv perl5 pixman pkgconf png py39-numpy py39-pillow py39-pip py39-sphinx py39-sphinx_rtd_theme py39-yaml python3 rpm2cpio sdl2 sdl2_image snappy spice-protocol tesseract texinfo usbredir virglrenderer vte3 zstd' +PKGS='alsa-lib bash bison bzip2 ca_root_nss capstone4 ccache cdrkit-genisoimage cmocka ctags curl cyrus-sasl dbus diffutils dtc flex fusefs-libs3 gettext git glib gmake gnutls gsed gtk3 json-c libepoxy libffi libgcrypt libjpeg-turbo libnfs libslirp libspice-server libssh libtasn1 llvm lzo2 meson ncurses nettle ninja opencv perl5 pixman pkgconf png py39-numpy py39-pillow py39-pip py39-sphinx py39-sphinx_rtd_theme py39-yaml python3 rpm2cpio sdl2 sdl2_image snappy sndio spice-protocol tesseract texinfo usbredir virglrenderer vte3 zstd' PYPI_PKGS='' PYTHON='/usr/local/bin/python3' diff --git a/tests/docker/dockerfiles/alpine.docker b/tests/docker/dockerfiles/alpine.docker index 9b7541261a..094f66f4eb 100644 --- a/tests/docker/dockerfiles/alpine.docker +++ b/tests/docker/dockerfiles/alpine.docker @@ -94,6 +94,7 @@ RUN apk update && \ sdl2_image-dev \ sed \ snappy-dev \ + sndio-dev \ sparse \ spice-dev \ spice-protocol \ @@ -119,8 +120,8 @@ RUN apk update && \ ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/g++ && \ ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc +ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" ENV LANG "en_US.UTF-8" ENV MAKE "/usr/bin/make" ENV NINJA "/usr/bin/ninja" ENV PYTHON "/usr/bin/python3" -ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" diff --git a/tests/docker/dockerfiles/centos8.docker b/tests/docker/dockerfiles/centos8.docker index d89113c0df..1f70d41aeb 100644 --- a/tests/docker/dockerfiles/centos8.docker +++ b/tests/docker/dockerfiles/centos8.docker @@ -130,8 +130,8 @@ RUN dnf distro-sync -y && \ ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/g++ && \ ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc +ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" ENV LANG "en_US.UTF-8" ENV MAKE "/usr/bin/make" ENV NINJA "/usr/bin/ninja" ENV PYTHON "/usr/bin/python3" -ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" diff --git a/tests/docker/dockerfiles/debian-amd64-cross.docker b/tests/docker/dockerfiles/debian-amd64-cross.docker index 9047759e76..5e57309361 100644 --- a/tests/docker/dockerfiles/debian-amd64-cross.docker +++ b/tests/docker/dockerfiles/debian-amd64-cross.docker @@ -11,62 +11,63 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get install -y eatmydata && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y \ - bash \ - bc \ - bison \ - bsdextrautils \ - bzip2 \ - ca-certificates \ - ccache \ - dbus \ - debianutils \ - diffutils \ - exuberant-ctags \ - findutils \ - flex \ - gcovr \ - genisoimage \ - gettext \ - git \ - hostname \ - libglib2.0-dev \ - libpcre2-dev \ - libspice-protocol-dev \ - llvm \ - locales \ - make \ - meson \ - ncat \ - ninja-build \ - openssh-client \ - perl-base \ - pkgconf \ - python3 \ - python3-numpy \ - python3-opencv \ - python3-pillow \ - python3-pip \ - python3-sphinx \ - python3-sphinx-rtd-theme \ - python3-venv \ - python3-yaml \ - rpm2cpio \ - sed \ - sparse \ - tar \ - tesseract-ocr \ - tesseract-ocr-eng \ - texinfo && \ + bash \ + bc \ + bison \ + bsdextrautils \ + bzip2 \ + ca-certificates \ + ccache \ + dbus \ + debianutils \ + diffutils \ + exuberant-ctags \ + findutils \ + flex \ + gcovr \ + genisoimage \ + gettext \ + git \ + hostname \ + libglib2.0-dev \ + libpcre2-dev \ + libsndio-dev \ + libspice-protocol-dev \ + llvm \ + locales \ + make \ + meson \ + ncat \ + ninja-build \ + openssh-client \ + perl-base \ + pkgconf \ + python3 \ + python3-numpy \ + python3-opencv \ + python3-pillow \ + python3-pip \ + python3-sphinx \ + python3-sphinx-rtd-theme \ + python3-venv \ + python3-yaml \ + rpm2cpio \ + sed \ + sparse \ + tar \ + tesseract-ocr \ + tesseract-ocr-eng \ + texinfo && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \ dpkg-reconfigure locales +ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" ENV LANG "en_US.UTF-8" ENV MAKE "/usr/bin/make" ENV NINJA "/usr/bin/ninja" ENV PYTHON "/usr/bin/python3" -ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" RUN export DEBIAN_FRONTEND=noninteractive && \ dpkg --add-architecture amd64 && \ @@ -74,76 +75,76 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y dpkg-dev && \ eatmydata apt-get install --no-install-recommends -y \ - g++-x86-64-linux-gnu \ - gcc-x86-64-linux-gnu \ - libaio-dev:amd64 \ - libasan5:amd64 \ - libasound2-dev:amd64 \ - libattr1-dev:amd64 \ - libbpf-dev:amd64 \ - libbrlapi-dev:amd64 \ - libbz2-dev:amd64 \ - libc6-dev:amd64 \ - libcacard-dev:amd64 \ - libcap-ng-dev:amd64 \ - libcapstone-dev:amd64 \ - libcmocka-dev:amd64 \ - libcurl4-gnutls-dev:amd64 \ - libdaxctl-dev:amd64 \ - libdrm-dev:amd64 \ - libepoxy-dev:amd64 \ - libfdt-dev:amd64 \ - libffi-dev:amd64 \ - libfuse3-dev:amd64 \ - libgbm-dev:amd64 \ - libgcrypt20-dev:amd64 \ - libglib2.0-dev:amd64 \ - libglusterfs-dev:amd64 \ - libgnutls28-dev:amd64 \ - libgtk-3-dev:amd64 \ - libibumad-dev:amd64 \ - libibverbs-dev:amd64 \ - libiscsi-dev:amd64 \ - libjemalloc-dev:amd64 \ - libjpeg62-turbo-dev:amd64 \ - libjson-c-dev:amd64 \ - liblttng-ust-dev:amd64 \ - liblzo2-dev:amd64 \ - libncursesw5-dev:amd64 \ - libnfs-dev:amd64 \ - libnuma-dev:amd64 \ - libpam0g-dev:amd64 \ - libpixman-1-dev:amd64 \ - libpmem-dev:amd64 \ - libpng-dev:amd64 \ - libpulse-dev:amd64 \ - librbd-dev:amd64 \ - librdmacm-dev:amd64 \ - libsasl2-dev:amd64 \ - libsdl2-dev:amd64 \ - libsdl2-image-dev:amd64 \ - libseccomp-dev:amd64 \ - libselinux1-dev:amd64 \ - libslirp-dev:amd64 \ - libsnappy-dev:amd64 \ - libspice-server-dev:amd64 \ - libssh-gcrypt-dev:amd64 \ - libsystemd-dev:amd64 \ - libtasn1-6-dev:amd64 \ - libubsan1:amd64 \ - libudev-dev:amd64 \ - liburing-dev:amd64 \ - libusb-1.0-0-dev:amd64 \ - libusbredirhost-dev:amd64 \ - libvdeplug-dev:amd64 \ - libvirglrenderer-dev:amd64 \ - libvte-2.91-dev:amd64 \ - libxen-dev:amd64 \ - libzstd-dev:amd64 \ - nettle-dev:amd64 \ - systemtap-sdt-dev:amd64 \ - xfslibs-dev:amd64 \ - zlib1g-dev:amd64 && \ + g++-x86-64-linux-gnu \ + gcc-x86-64-linux-gnu \ + libaio-dev:amd64 \ + libasan5:amd64 \ + libasound2-dev:amd64 \ + libattr1-dev:amd64 \ + libbpf-dev:amd64 \ + libbrlapi-dev:amd64 \ + libbz2-dev:amd64 \ + libc6-dev:amd64 \ + libcacard-dev:amd64 \ + libcap-ng-dev:amd64 \ + libcapstone-dev:amd64 \ + libcmocka-dev:amd64 \ + libcurl4-gnutls-dev:amd64 \ + libdaxctl-dev:amd64 \ + libdrm-dev:amd64 \ + libepoxy-dev:amd64 \ + libfdt-dev:amd64 \ + libffi-dev:amd64 \ + libfuse3-dev:amd64 \ + libgbm-dev:amd64 \ + libgcrypt20-dev:amd64 \ + libglib2.0-dev:amd64 \ + libglusterfs-dev:amd64 \ + libgnutls28-dev:amd64 \ + libgtk-3-dev:amd64 \ + libibumad-dev:amd64 \ + libibverbs-dev:amd64 \ + libiscsi-dev:amd64 \ + libjemalloc-dev:amd64 \ + libjpeg62-turbo-dev:amd64 \ + libjson-c-dev:amd64 \ + liblttng-ust-dev:amd64 \ + liblzo2-dev:amd64 \ + libncursesw5-dev:amd64 \ + libnfs-dev:amd64 \ + libnuma-dev:amd64 \ + libpam0g-dev:amd64 \ + libpixman-1-dev:amd64 \ + libpmem-dev:amd64 \ + libpng-dev:amd64 \ + libpulse-dev:amd64 \ + librbd-dev:amd64 \ + librdmacm-dev:amd64 \ + libsasl2-dev:amd64 \ + libsdl2-dev:amd64 \ + libsdl2-image-dev:amd64 \ + libseccomp-dev:amd64 \ + libselinux1-dev:amd64 \ + libslirp-dev:amd64 \ + libsnappy-dev:amd64 \ + libspice-server-dev:amd64 \ + libssh-gcrypt-dev:amd64 \ + libsystemd-dev:amd64 \ + libtasn1-6-dev:amd64 \ + libubsan1:amd64 \ + libudev-dev:amd64 \ + liburing-dev:amd64 \ + libusb-1.0-0-dev:amd64 \ + libusbredirhost-dev:amd64 \ + libvdeplug-dev:amd64 \ + libvirglrenderer-dev:amd64 \ + libvte-2.91-dev:amd64 \ + libxen-dev:amd64 \ + libzstd-dev:amd64 \ + nettle-dev:amd64 \ + systemtap-sdt-dev:amd64 \ + xfslibs-dev:amd64 \ + zlib1g-dev:amd64 && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ mkdir -p /usr/local/share/meson/cross && \ diff --git a/tests/docker/dockerfiles/debian-amd64.docker b/tests/docker/dockerfiles/debian-amd64.docker index a8b728ca64..bfeab01ee3 100644 --- a/tests/docker/dockerfiles/debian-amd64.docker +++ b/tests/docker/dockerfiles/debian-amd64.docker @@ -11,123 +11,124 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get install -y eatmydata && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y \ - bash \ - bc \ - bison \ - bsdextrautils \ - bzip2 \ - ca-certificates \ - ccache \ - clang \ - dbus \ - debianutils \ - diffutils \ - exuberant-ctags \ - findutils \ - flex \ - g++ \ - gcc \ - gcovr \ - genisoimage \ - gettext \ - git \ - hostname \ - libaio-dev \ - libasan5 \ - libasound2-dev \ - libattr1-dev \ - libbpf-dev \ - libbrlapi-dev \ - libbz2-dev \ - libc6-dev \ - libcacard-dev \ - libcap-ng-dev \ - libcapstone-dev \ - libcmocka-dev \ - libcurl4-gnutls-dev \ - libdaxctl-dev \ - libdrm-dev \ - libepoxy-dev \ - libfdt-dev \ - libffi-dev \ - libfuse3-dev \ - libgbm-dev \ - libgcrypt20-dev \ - libglib2.0-dev \ - libglusterfs-dev \ - libgnutls28-dev \ - libgtk-3-dev \ - libibumad-dev \ - libibverbs-dev \ - libiscsi-dev \ - libjemalloc-dev \ - libjpeg62-turbo-dev \ - libjson-c-dev \ - liblttng-ust-dev \ - liblzo2-dev \ - libncursesw5-dev \ - libnfs-dev \ - libnuma-dev \ - libpam0g-dev \ - libpcre2-dev \ - libpixman-1-dev \ - libpmem-dev \ - libpng-dev \ - libpulse-dev \ - librbd-dev \ - librdmacm-dev \ - libsasl2-dev \ - libsdl2-dev \ - libsdl2-image-dev \ - libseccomp-dev \ - libselinux1-dev \ - libslirp-dev \ - libsnappy-dev \ - libspice-protocol-dev \ - libspice-server-dev \ - libssh-gcrypt-dev \ - libsystemd-dev \ - libtasn1-6-dev \ - libubsan1 \ - libudev-dev \ - liburing-dev \ - libusb-1.0-0-dev \ - libusbredirhost-dev \ - libvdeplug-dev \ - libvirglrenderer-dev \ - libvte-2.91-dev \ - libxen-dev \ - libzstd-dev \ - llvm \ - locales \ - make \ - meson \ - multipath-tools \ - ncat \ - nettle-dev \ - ninja-build \ - openssh-client \ - perl-base \ - pkgconf \ - python3 \ - python3-numpy \ - python3-opencv \ - python3-pillow \ - python3-pip \ - python3-sphinx \ - python3-sphinx-rtd-theme \ - python3-venv \ - python3-yaml \ - rpm2cpio \ - sed \ - sparse \ - systemtap-sdt-dev \ - tar \ - tesseract-ocr \ - tesseract-ocr-eng \ - texinfo \ - xfslibs-dev \ - zlib1g-dev && \ + bash \ + bc \ + bison \ + bsdextrautils \ + bzip2 \ + ca-certificates \ + ccache \ + clang \ + dbus \ + debianutils \ + diffutils \ + exuberant-ctags \ + findutils \ + flex \ + g++ \ + gcc \ + gcovr \ + genisoimage \ + gettext \ + git \ + hostname \ + libaio-dev \ + libasan5 \ + libasound2-dev \ + libattr1-dev \ + libbpf-dev \ + libbrlapi-dev \ + libbz2-dev \ + libc6-dev \ + libcacard-dev \ + libcap-ng-dev \ + libcapstone-dev \ + libcmocka-dev \ + libcurl4-gnutls-dev \ + libdaxctl-dev \ + libdrm-dev \ + libepoxy-dev \ + libfdt-dev \ + libffi-dev \ + libfuse3-dev \ + libgbm-dev \ + libgcrypt20-dev \ + libglib2.0-dev \ + libglusterfs-dev \ + libgnutls28-dev \ + libgtk-3-dev \ + libibumad-dev \ + libibverbs-dev \ + libiscsi-dev \ + libjemalloc-dev \ + libjpeg62-turbo-dev \ + libjson-c-dev \ + liblttng-ust-dev \ + liblzo2-dev \ + libncursesw5-dev \ + libnfs-dev \ + libnuma-dev \ + libpam0g-dev \ + libpcre2-dev \ + libpixman-1-dev \ + libpmem-dev \ + libpng-dev \ + libpulse-dev \ + librbd-dev \ + librdmacm-dev \ + libsasl2-dev \ + libsdl2-dev \ + libsdl2-image-dev \ + libseccomp-dev \ + libselinux1-dev \ + libslirp-dev \ + libsnappy-dev \ + libsndio-dev \ + libspice-protocol-dev \ + libspice-server-dev \ + libssh-gcrypt-dev \ + libsystemd-dev \ + libtasn1-6-dev \ + libubsan1 \ + libudev-dev \ + liburing-dev \ + libusb-1.0-0-dev \ + libusbredirhost-dev \ + libvdeplug-dev \ + libvirglrenderer-dev \ + libvte-2.91-dev \ + libxen-dev \ + libzstd-dev \ + llvm \ + locales \ + make \ + meson \ + multipath-tools \ + ncat \ + nettle-dev \ + ninja-build \ + openssh-client \ + perl-base \ + pkgconf \ + python3 \ + python3-numpy \ + python3-opencv \ + python3-pillow \ + python3-pip \ + python3-sphinx \ + python3-sphinx-rtd-theme \ + python3-venv \ + python3-yaml \ + rpm2cpio \ + sed \ + sparse \ + systemtap-sdt-dev \ + tar \ + tesseract-ocr \ + tesseract-ocr-eng \ + texinfo \ + xfslibs-dev \ + zlib1g-dev && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \ @@ -140,11 +141,11 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/g++ && \ ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc +ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" ENV LANG "en_US.UTF-8" ENV MAKE "/usr/bin/make" ENV NINJA "/usr/bin/ninja" ENV PYTHON "/usr/bin/python3" -ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" # netmap/cscope/global RUN DEBIAN_FRONTEND=noninteractive eatmydata \ apt install -y --no-install-recommends \ diff --git a/tests/docker/dockerfiles/debian-arm64-cross.docker b/tests/docker/dockerfiles/debian-arm64-cross.docker index 17a5709245..98885bd0ee 100644 --- a/tests/docker/dockerfiles/debian-arm64-cross.docker +++ b/tests/docker/dockerfiles/debian-arm64-cross.docker @@ -11,62 +11,63 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get install -y eatmydata && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y \ - bash \ - bc \ - bison \ - bsdextrautils \ - bzip2 \ - ca-certificates \ - ccache \ - dbus \ - debianutils \ - diffutils \ - exuberant-ctags \ - findutils \ - flex \ - gcovr \ - genisoimage \ - gettext \ - git \ - hostname \ - libglib2.0-dev \ - libpcre2-dev \ - libspice-protocol-dev \ - llvm \ - locales \ - make \ - meson \ - ncat \ - ninja-build \ - openssh-client \ - perl-base \ - pkgconf \ - python3 \ - python3-numpy \ - python3-opencv \ - python3-pillow \ - python3-pip \ - python3-sphinx \ - python3-sphinx-rtd-theme \ - python3-venv \ - python3-yaml \ - rpm2cpio \ - sed \ - sparse \ - tar \ - tesseract-ocr \ - tesseract-ocr-eng \ - texinfo && \ + bash \ + bc \ + bison \ + bsdextrautils \ + bzip2 \ + ca-certificates \ + ccache \ + dbus \ + debianutils \ + diffutils \ + exuberant-ctags \ + findutils \ + flex \ + gcovr \ + genisoimage \ + gettext \ + git \ + hostname \ + libglib2.0-dev \ + libpcre2-dev \ + libsndio-dev \ + libspice-protocol-dev \ + llvm \ + locales \ + make \ + meson \ + ncat \ + ninja-build \ + openssh-client \ + perl-base \ + pkgconf \ + python3 \ + python3-numpy \ + python3-opencv \ + python3-pillow \ + python3-pip \ + python3-sphinx \ + python3-sphinx-rtd-theme \ + python3-venv \ + python3-yaml \ + rpm2cpio \ + sed \ + sparse \ + tar \ + tesseract-ocr \ + tesseract-ocr-eng \ + texinfo && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \ dpkg-reconfigure locales +ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" ENV LANG "en_US.UTF-8" ENV MAKE "/usr/bin/make" ENV NINJA "/usr/bin/ninja" ENV PYTHON "/usr/bin/python3" -ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" RUN export DEBIAN_FRONTEND=noninteractive && \ dpkg --add-architecture arm64 && \ @@ -74,75 +75,75 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y dpkg-dev && \ eatmydata apt-get install --no-install-recommends -y \ - g++-aarch64-linux-gnu \ - gcc-aarch64-linux-gnu \ - libaio-dev:arm64 \ - libasan5:arm64 \ - libasound2-dev:arm64 \ - libattr1-dev:arm64 \ - libbpf-dev:arm64 \ - libbrlapi-dev:arm64 \ - libbz2-dev:arm64 \ - libc6-dev:arm64 \ - libcacard-dev:arm64 \ - libcap-ng-dev:arm64 \ - libcapstone-dev:arm64 \ - libcmocka-dev:arm64 \ - libcurl4-gnutls-dev:arm64 \ - libdaxctl-dev:arm64 \ - libdrm-dev:arm64 \ - libepoxy-dev:arm64 \ - libfdt-dev:arm64 \ - libffi-dev:arm64 \ - libfuse3-dev:arm64 \ - libgbm-dev:arm64 \ - libgcrypt20-dev:arm64 \ - libglib2.0-dev:arm64 \ - libglusterfs-dev:arm64 \ - libgnutls28-dev:arm64 \ - libgtk-3-dev:arm64 \ - libibumad-dev:arm64 \ - libibverbs-dev:arm64 \ - libiscsi-dev:arm64 \ - libjemalloc-dev:arm64 \ - libjpeg62-turbo-dev:arm64 \ - libjson-c-dev:arm64 \ - liblttng-ust-dev:arm64 \ - liblzo2-dev:arm64 \ - libncursesw5-dev:arm64 \ - libnfs-dev:arm64 \ - libnuma-dev:arm64 \ - libpam0g-dev:arm64 \ - libpixman-1-dev:arm64 \ - libpng-dev:arm64 \ - libpulse-dev:arm64 \ - librbd-dev:arm64 \ - librdmacm-dev:arm64 \ - libsasl2-dev:arm64 \ - libsdl2-dev:arm64 \ - libsdl2-image-dev:arm64 \ - libseccomp-dev:arm64 \ - libselinux1-dev:arm64 \ - libslirp-dev:arm64 \ - libsnappy-dev:arm64 \ - libspice-server-dev:arm64 \ - libssh-gcrypt-dev:arm64 \ - libsystemd-dev:arm64 \ - libtasn1-6-dev:arm64 \ - libubsan1:arm64 \ - libudev-dev:arm64 \ - liburing-dev:arm64 \ - libusb-1.0-0-dev:arm64 \ - libusbredirhost-dev:arm64 \ - libvdeplug-dev:arm64 \ - libvirglrenderer-dev:arm64 \ - libvte-2.91-dev:arm64 \ - libxen-dev:arm64 \ - libzstd-dev:arm64 \ - nettle-dev:arm64 \ - systemtap-sdt-dev:arm64 \ - xfslibs-dev:arm64 \ - zlib1g-dev:arm64 && \ + g++-aarch64-linux-gnu \ + gcc-aarch64-linux-gnu \ + libaio-dev:arm64 \ + libasan5:arm64 \ + libasound2-dev:arm64 \ + libattr1-dev:arm64 \ + libbpf-dev:arm64 \ + libbrlapi-dev:arm64 \ + libbz2-dev:arm64 \ + libc6-dev:arm64 \ + libcacard-dev:arm64 \ + libcap-ng-dev:arm64 \ + libcapstone-dev:arm64 \ + libcmocka-dev:arm64 \ + libcurl4-gnutls-dev:arm64 \ + libdaxctl-dev:arm64 \ + libdrm-dev:arm64 \ + libepoxy-dev:arm64 \ + libfdt-dev:arm64 \ + libffi-dev:arm64 \ + libfuse3-dev:arm64 \ + libgbm-dev:arm64 \ + libgcrypt20-dev:arm64 \ + libglib2.0-dev:arm64 \ + libglusterfs-dev:arm64 \ + libgnutls28-dev:arm64 \ + libgtk-3-dev:arm64 \ + libibumad-dev:arm64 \ + libibverbs-dev:arm64 \ + libiscsi-dev:arm64 \ + libjemalloc-dev:arm64 \ + libjpeg62-turbo-dev:arm64 \ + libjson-c-dev:arm64 \ + liblttng-ust-dev:arm64 \ + liblzo2-dev:arm64 \ + libncursesw5-dev:arm64 \ + libnfs-dev:arm64 \ + libnuma-dev:arm64 \ + libpam0g-dev:arm64 \ + libpixman-1-dev:arm64 \ + libpng-dev:arm64 \ + libpulse-dev:arm64 \ + librbd-dev:arm64 \ + librdmacm-dev:arm64 \ + libsasl2-dev:arm64 \ + libsdl2-dev:arm64 \ + libsdl2-image-dev:arm64 \ + libseccomp-dev:arm64 \ + libselinux1-dev:arm64 \ + libslirp-dev:arm64 \ + libsnappy-dev:arm64 \ + libspice-server-dev:arm64 \ + libssh-gcrypt-dev:arm64 \ + libsystemd-dev:arm64 \ + libtasn1-6-dev:arm64 \ + libubsan1:arm64 \ + libudev-dev:arm64 \ + liburing-dev:arm64 \ + libusb-1.0-0-dev:arm64 \ + libusbredirhost-dev:arm64 \ + libvdeplug-dev:arm64 \ + libvirglrenderer-dev:arm64 \ + libvte-2.91-dev:arm64 \ + libxen-dev:arm64 \ + libzstd-dev:arm64 \ + nettle-dev:arm64 \ + systemtap-sdt-dev:arm64 \ + xfslibs-dev:arm64 \ + zlib1g-dev:arm64 && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ mkdir -p /usr/local/share/meson/cross && \ diff --git a/tests/docker/dockerfiles/debian-armel-cross.docker b/tests/docker/dockerfiles/debian-armel-cross.docker index 701fc70db0..d5c08714e4 100644 --- a/tests/docker/dockerfiles/debian-armel-cross.docker +++ b/tests/docker/dockerfiles/debian-armel-cross.docker @@ -11,62 +11,63 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get install -y eatmydata && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y \ - bash \ - bc \ - bison \ - bsdextrautils \ - bzip2 \ - ca-certificates \ - ccache \ - dbus \ - debianutils \ - diffutils \ - exuberant-ctags \ - findutils \ - flex \ - gcovr \ - genisoimage \ - gettext \ - git \ - hostname \ - libglib2.0-dev \ - libpcre2-dev \ - libspice-protocol-dev \ - llvm \ - locales \ - make \ - meson \ - ncat \ - ninja-build \ - openssh-client \ - perl-base \ - pkgconf \ - python3 \ - python3-numpy \ - python3-opencv \ - python3-pillow \ - python3-pip \ - python3-sphinx \ - python3-sphinx-rtd-theme \ - python3-venv \ - python3-yaml \ - rpm2cpio \ - sed \ - sparse \ - tar \ - tesseract-ocr \ - tesseract-ocr-eng \ - texinfo && \ + bash \ + bc \ + bison \ + bsdextrautils \ + bzip2 \ + ca-certificates \ + ccache \ + dbus \ + debianutils \ + diffutils \ + exuberant-ctags \ + findutils \ + flex \ + gcovr \ + genisoimage \ + gettext \ + git \ + hostname \ + libglib2.0-dev \ + libpcre2-dev \ + libsndio-dev \ + libspice-protocol-dev \ + llvm \ + locales \ + make \ + meson \ + ncat \ + ninja-build \ + openssh-client \ + perl-base \ + pkgconf \ + python3 \ + python3-numpy \ + python3-opencv \ + python3-pillow \ + python3-pip \ + python3-sphinx \ + python3-sphinx-rtd-theme \ + python3-venv \ + python3-yaml \ + rpm2cpio \ + sed \ + sparse \ + tar \ + tesseract-ocr \ + tesseract-ocr-eng \ + texinfo && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \ dpkg-reconfigure locales +ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" ENV LANG "en_US.UTF-8" ENV MAKE "/usr/bin/make" ENV NINJA "/usr/bin/ninja" ENV PYTHON "/usr/bin/python3" -ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" RUN export DEBIAN_FRONTEND=noninteractive && \ dpkg --add-architecture armel && \ @@ -74,74 +75,74 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y dpkg-dev && \ eatmydata apt-get install --no-install-recommends -y \ - g++-arm-linux-gnueabi \ - gcc-arm-linux-gnueabi \ - libaio-dev:armel \ - libasan5:armel \ - libasound2-dev:armel \ - libattr1-dev:armel \ - libbpf-dev:armel \ - libbrlapi-dev:armel \ - libbz2-dev:armel \ - libc6-dev:armel \ - libcacard-dev:armel \ - libcap-ng-dev:armel \ - libcapstone-dev:armel \ - libcmocka-dev:armel \ - libcurl4-gnutls-dev:armel \ - libdaxctl-dev:armel \ - libdrm-dev:armel \ - libepoxy-dev:armel \ - libfdt-dev:armel \ - libffi-dev:armel \ - libfuse3-dev:armel \ - libgbm-dev:armel \ - libgcrypt20-dev:armel \ - libglib2.0-dev:armel \ - libglusterfs-dev:armel \ - libgnutls28-dev:armel \ - libgtk-3-dev:armel \ - libibumad-dev:armel \ - libibverbs-dev:armel \ - libiscsi-dev:armel \ - libjemalloc-dev:armel \ - libjpeg62-turbo-dev:armel \ - libjson-c-dev:armel \ - liblttng-ust-dev:armel \ - liblzo2-dev:armel \ - libncursesw5-dev:armel \ - libnfs-dev:armel \ - libnuma-dev:armel \ - libpam0g-dev:armel \ - libpixman-1-dev:armel \ - libpng-dev:armel \ - libpulse-dev:armel \ - librbd-dev:armel \ - librdmacm-dev:armel \ - libsasl2-dev:armel \ - libsdl2-dev:armel \ - libsdl2-image-dev:armel \ - libseccomp-dev:armel \ - libselinux1-dev:armel \ - libslirp-dev:armel \ - libsnappy-dev:armel \ - libspice-server-dev:armel \ - libssh-gcrypt-dev:armel \ - libsystemd-dev:armel \ - libtasn1-6-dev:armel \ - libubsan1:armel \ - libudev-dev:armel \ - liburing-dev:armel \ - libusb-1.0-0-dev:armel \ - libusbredirhost-dev:armel \ - libvdeplug-dev:armel \ - libvirglrenderer-dev:armel \ - libvte-2.91-dev:armel \ - libzstd-dev:armel \ - nettle-dev:armel \ - systemtap-sdt-dev:armel \ - xfslibs-dev:armel \ - zlib1g-dev:armel && \ + g++-arm-linux-gnueabi \ + gcc-arm-linux-gnueabi \ + libaio-dev:armel \ + libasan5:armel \ + libasound2-dev:armel \ + libattr1-dev:armel \ + libbpf-dev:armel \ + libbrlapi-dev:armel \ + libbz2-dev:armel \ + libc6-dev:armel \ + libcacard-dev:armel \ + libcap-ng-dev:armel \ + libcapstone-dev:armel \ + libcmocka-dev:armel \ + libcurl4-gnutls-dev:armel \ + libdaxctl-dev:armel \ + libdrm-dev:armel \ + libepoxy-dev:armel \ + libfdt-dev:armel \ + libffi-dev:armel \ + libfuse3-dev:armel \ + libgbm-dev:armel \ + libgcrypt20-dev:armel \ + libglib2.0-dev:armel \ + libglusterfs-dev:armel \ + libgnutls28-dev:armel \ + libgtk-3-dev:armel \ + libibumad-dev:armel \ + libibverbs-dev:armel \ + libiscsi-dev:armel \ + libjemalloc-dev:armel \ + libjpeg62-turbo-dev:armel \ + libjson-c-dev:armel \ + liblttng-ust-dev:armel \ + liblzo2-dev:armel \ + libncursesw5-dev:armel \ + libnfs-dev:armel \ + libnuma-dev:armel \ + libpam0g-dev:armel \ + libpixman-1-dev:armel \ + libpng-dev:armel \ + libpulse-dev:armel \ + librbd-dev:armel \ + librdmacm-dev:armel \ + libsasl2-dev:armel \ + libsdl2-dev:armel \ + libsdl2-image-dev:armel \ + libseccomp-dev:armel \ + libselinux1-dev:armel \ + libslirp-dev:armel \ + libsnappy-dev:armel \ + libspice-server-dev:armel \ + libssh-gcrypt-dev:armel \ + libsystemd-dev:armel \ + libtasn1-6-dev:armel \ + libubsan1:armel \ + libudev-dev:armel \ + liburing-dev:armel \ + libusb-1.0-0-dev:armel \ + libusbredirhost-dev:armel \ + libvdeplug-dev:armel \ + libvirglrenderer-dev:armel \ + libvte-2.91-dev:armel \ + libzstd-dev:armel \ + nettle-dev:armel \ + systemtap-sdt-dev:armel \ + xfslibs-dev:armel \ + zlib1g-dev:armel && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ mkdir -p /usr/local/share/meson/cross && \ diff --git a/tests/docker/dockerfiles/debian-armhf-cross.docker b/tests/docker/dockerfiles/debian-armhf-cross.docker index 5a11fe3900..471444fcf4 100644 --- a/tests/docker/dockerfiles/debian-armhf-cross.docker +++ b/tests/docker/dockerfiles/debian-armhf-cross.docker @@ -11,62 +11,63 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get install -y eatmydata && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y \ - bash \ - bc \ - bison \ - bsdextrautils \ - bzip2 \ - ca-certificates \ - ccache \ - dbus \ - debianutils \ - diffutils \ - exuberant-ctags \ - findutils \ - flex \ - gcovr \ - genisoimage \ - gettext \ - git \ - hostname \ - libglib2.0-dev \ - libpcre2-dev \ - libspice-protocol-dev \ - llvm \ - locales \ - make \ - meson \ - ncat \ - ninja-build \ - openssh-client \ - perl-base \ - pkgconf \ - python3 \ - python3-numpy \ - python3-opencv \ - python3-pillow \ - python3-pip \ - python3-sphinx \ - python3-sphinx-rtd-theme \ - python3-venv \ - python3-yaml \ - rpm2cpio \ - sed \ - sparse \ - tar \ - tesseract-ocr \ - tesseract-ocr-eng \ - texinfo && \ + bash \ + bc \ + bison \ + bsdextrautils \ + bzip2 \ + ca-certificates \ + ccache \ + dbus \ + debianutils \ + diffutils \ + exuberant-ctags \ + findutils \ + flex \ + gcovr \ + genisoimage \ + gettext \ + git \ + hostname \ + libglib2.0-dev \ + libpcre2-dev \ + libsndio-dev \ + libspice-protocol-dev \ + llvm \ + locales \ + make \ + meson \ + ncat \ + ninja-build \ + openssh-client \ + perl-base \ + pkgconf \ + python3 \ + python3-numpy \ + python3-opencv \ + python3-pillow \ + python3-pip \ + python3-sphinx \ + python3-sphinx-rtd-theme \ + python3-venv \ + python3-yaml \ + rpm2cpio \ + sed \ + sparse \ + tar \ + tesseract-ocr \ + tesseract-ocr-eng \ + texinfo && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \ dpkg-reconfigure locales +ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" ENV LANG "en_US.UTF-8" ENV MAKE "/usr/bin/make" ENV NINJA "/usr/bin/ninja" ENV PYTHON "/usr/bin/python3" -ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" RUN export DEBIAN_FRONTEND=noninteractive && \ dpkg --add-architecture armhf && \ @@ -74,75 +75,75 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y dpkg-dev && \ eatmydata apt-get install --no-install-recommends -y \ - g++-arm-linux-gnueabihf \ - gcc-arm-linux-gnueabihf \ - libaio-dev:armhf \ - libasan5:armhf \ - libasound2-dev:armhf \ - libattr1-dev:armhf \ - libbpf-dev:armhf \ - libbrlapi-dev:armhf \ - libbz2-dev:armhf \ - libc6-dev:armhf \ - libcacard-dev:armhf \ - libcap-ng-dev:armhf \ - libcapstone-dev:armhf \ - libcmocka-dev:armhf \ - libcurl4-gnutls-dev:armhf \ - libdaxctl-dev:armhf \ - libdrm-dev:armhf \ - libepoxy-dev:armhf \ - libfdt-dev:armhf \ - libffi-dev:armhf \ - libfuse3-dev:armhf \ - libgbm-dev:armhf \ - libgcrypt20-dev:armhf \ - libglib2.0-dev:armhf \ - libglusterfs-dev:armhf \ - libgnutls28-dev:armhf \ - libgtk-3-dev:armhf \ - libibumad-dev:armhf \ - libibverbs-dev:armhf \ - libiscsi-dev:armhf \ - libjemalloc-dev:armhf \ - libjpeg62-turbo-dev:armhf \ - libjson-c-dev:armhf \ - liblttng-ust-dev:armhf \ - liblzo2-dev:armhf \ - libncursesw5-dev:armhf \ - libnfs-dev:armhf \ - libnuma-dev:armhf \ - libpam0g-dev:armhf \ - libpixman-1-dev:armhf \ - libpng-dev:armhf \ - libpulse-dev:armhf \ - librbd-dev:armhf \ - librdmacm-dev:armhf \ - libsasl2-dev:armhf \ - libsdl2-dev:armhf \ - libsdl2-image-dev:armhf \ - libseccomp-dev:armhf \ - libselinux1-dev:armhf \ - libslirp-dev:armhf \ - libsnappy-dev:armhf \ - libspice-server-dev:armhf \ - libssh-gcrypt-dev:armhf \ - libsystemd-dev:armhf \ - libtasn1-6-dev:armhf \ - libubsan1:armhf \ - libudev-dev:armhf \ - liburing-dev:armhf \ - libusb-1.0-0-dev:armhf \ - libusbredirhost-dev:armhf \ - libvdeplug-dev:armhf \ - libvirglrenderer-dev:armhf \ - libvte-2.91-dev:armhf \ - libxen-dev:armhf \ - libzstd-dev:armhf \ - nettle-dev:armhf \ - systemtap-sdt-dev:armhf \ - xfslibs-dev:armhf \ - zlib1g-dev:armhf && \ + g++-arm-linux-gnueabihf \ + gcc-arm-linux-gnueabihf \ + libaio-dev:armhf \ + libasan5:armhf \ + libasound2-dev:armhf \ + libattr1-dev:armhf \ + libbpf-dev:armhf \ + libbrlapi-dev:armhf \ + libbz2-dev:armhf \ + libc6-dev:armhf \ + libcacard-dev:armhf \ + libcap-ng-dev:armhf \ + libcapstone-dev:armhf \ + libcmocka-dev:armhf \ + libcurl4-gnutls-dev:armhf \ + libdaxctl-dev:armhf \ + libdrm-dev:armhf \ + libepoxy-dev:armhf \ + libfdt-dev:armhf \ + libffi-dev:armhf \ + libfuse3-dev:armhf \ + libgbm-dev:armhf \ + libgcrypt20-dev:armhf \ + libglib2.0-dev:armhf \ + libglusterfs-dev:armhf \ + libgnutls28-dev:armhf \ + libgtk-3-dev:armhf \ + libibumad-dev:armhf \ + libibverbs-dev:armhf \ + libiscsi-dev:armhf \ + libjemalloc-dev:armhf \ + libjpeg62-turbo-dev:armhf \ + libjson-c-dev:armhf \ + liblttng-ust-dev:armhf \ + liblzo2-dev:armhf \ + libncursesw5-dev:armhf \ + libnfs-dev:armhf \ + libnuma-dev:armhf \ + libpam0g-dev:armhf \ + libpixman-1-dev:armhf \ + libpng-dev:armhf \ + libpulse-dev:armhf \ + librbd-dev:armhf \ + librdmacm-dev:armhf \ + libsasl2-dev:armhf \ + libsdl2-dev:armhf \ + libsdl2-image-dev:armhf \ + libseccomp-dev:armhf \ + libselinux1-dev:armhf \ + libslirp-dev:armhf \ + libsnappy-dev:armhf \ + libspice-server-dev:armhf \ + libssh-gcrypt-dev:armhf \ + libsystemd-dev:armhf \ + libtasn1-6-dev:armhf \ + libubsan1:armhf \ + libudev-dev:armhf \ + liburing-dev:armhf \ + libusb-1.0-0-dev:armhf \ + libusbredirhost-dev:armhf \ + libvdeplug-dev:armhf \ + libvirglrenderer-dev:armhf \ + libvte-2.91-dev:armhf \ + libxen-dev:armhf \ + libzstd-dev:armhf \ + nettle-dev:armhf \ + systemtap-sdt-dev:armhf \ + xfslibs-dev:armhf \ + zlib1g-dev:armhf && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ mkdir -p /usr/local/share/meson/cross && \ diff --git a/tests/docker/dockerfiles/debian-mips64el-cross.docker b/tests/docker/dockerfiles/debian-mips64el-cross.docker index 9b90a4d6ff..15b0224b76 100644 --- a/tests/docker/dockerfiles/debian-mips64el-cross.docker +++ b/tests/docker/dockerfiles/debian-mips64el-cross.docker @@ -11,62 +11,63 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get install -y eatmydata && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y \ - bash \ - bc \ - bison \ - bsdextrautils \ - bzip2 \ - ca-certificates \ - ccache \ - dbus \ - debianutils \ - diffutils \ - exuberant-ctags \ - findutils \ - flex \ - gcovr \ - genisoimage \ - gettext \ - git \ - hostname \ - libglib2.0-dev \ - libpcre2-dev \ - libspice-protocol-dev \ - llvm \ - locales \ - make \ - meson \ - ncat \ - ninja-build \ - openssh-client \ - perl-base \ - pkgconf \ - python3 \ - python3-numpy \ - python3-opencv \ - python3-pillow \ - python3-pip \ - python3-sphinx \ - python3-sphinx-rtd-theme \ - python3-venv \ - python3-yaml \ - rpm2cpio \ - sed \ - sparse \ - tar \ - tesseract-ocr \ - tesseract-ocr-eng \ - texinfo && \ + bash \ + bc \ + bison \ + bsdextrautils \ + bzip2 \ + ca-certificates \ + ccache \ + dbus \ + debianutils \ + diffutils \ + exuberant-ctags \ + findutils \ + flex \ + gcovr \ + genisoimage \ + gettext \ + git \ + hostname \ + libglib2.0-dev \ + libpcre2-dev \ + libsndio-dev \ + libspice-protocol-dev \ + llvm \ + locales \ + make \ + meson \ + ncat \ + ninja-build \ + openssh-client \ + perl-base \ + pkgconf \ + python3 \ + python3-numpy \ + python3-opencv \ + python3-pillow \ + python3-pip \ + python3-sphinx \ + python3-sphinx-rtd-theme \ + python3-venv \ + python3-yaml \ + rpm2cpio \ + sed \ + sparse \ + tar \ + tesseract-ocr \ + tesseract-ocr-eng \ + texinfo && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \ dpkg-reconfigure locales +ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" ENV LANG "en_US.UTF-8" ENV MAKE "/usr/bin/make" ENV NINJA "/usr/bin/ninja" ENV PYTHON "/usr/bin/python3" -ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" RUN export DEBIAN_FRONTEND=noninteractive && \ dpkg --add-architecture mips64el && \ @@ -74,72 +75,72 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y dpkg-dev && \ eatmydata apt-get install --no-install-recommends -y \ - g++-mips64el-linux-gnuabi64 \ - gcc-mips64el-linux-gnuabi64 \ - libaio-dev:mips64el \ - libasound2-dev:mips64el \ - libattr1-dev:mips64el \ - libbpf-dev:mips64el \ - libbrlapi-dev:mips64el \ - libbz2-dev:mips64el \ - libc6-dev:mips64el \ - libcacard-dev:mips64el \ - libcap-ng-dev:mips64el \ - libcapstone-dev:mips64el \ - libcmocka-dev:mips64el \ - libcurl4-gnutls-dev:mips64el \ - libdaxctl-dev:mips64el \ - libdrm-dev:mips64el \ - libepoxy-dev:mips64el \ - libfdt-dev:mips64el \ - libffi-dev:mips64el \ - libfuse3-dev:mips64el \ - libgbm-dev:mips64el \ - libgcrypt20-dev:mips64el \ - libglib2.0-dev:mips64el \ - libglusterfs-dev:mips64el \ - libgnutls28-dev:mips64el \ - libgtk-3-dev:mips64el \ - libibumad-dev:mips64el \ - libibverbs-dev:mips64el \ - libiscsi-dev:mips64el \ - libjemalloc-dev:mips64el \ - libjpeg62-turbo-dev:mips64el \ - libjson-c-dev:mips64el \ - liblttng-ust-dev:mips64el \ - liblzo2-dev:mips64el \ - libncursesw5-dev:mips64el \ - libnfs-dev:mips64el \ - libnuma-dev:mips64el \ - libpam0g-dev:mips64el \ - libpixman-1-dev:mips64el \ - libpng-dev:mips64el \ - libpulse-dev:mips64el \ - librbd-dev:mips64el \ - librdmacm-dev:mips64el \ - libsasl2-dev:mips64el \ - libsdl2-dev:mips64el \ - libsdl2-image-dev:mips64el \ - libseccomp-dev:mips64el \ - libselinux1-dev:mips64el \ - libslirp-dev:mips64el \ - libsnappy-dev:mips64el \ - libspice-server-dev:mips64el \ - libssh-gcrypt-dev:mips64el \ - libsystemd-dev:mips64el \ - libtasn1-6-dev:mips64el \ - libudev-dev:mips64el \ - liburing-dev:mips64el \ - libusb-1.0-0-dev:mips64el \ - libusbredirhost-dev:mips64el \ - libvdeplug-dev:mips64el \ - libvirglrenderer-dev:mips64el \ - libvte-2.91-dev:mips64el \ - libzstd-dev:mips64el \ - nettle-dev:mips64el \ - systemtap-sdt-dev:mips64el \ - xfslibs-dev:mips64el \ - zlib1g-dev:mips64el && \ + g++-mips64el-linux-gnuabi64 \ + gcc-mips64el-linux-gnuabi64 \ + libaio-dev:mips64el \ + libasound2-dev:mips64el \ + libattr1-dev:mips64el \ + libbpf-dev:mips64el \ + libbrlapi-dev:mips64el \ + libbz2-dev:mips64el \ + libc6-dev:mips64el \ + libcacard-dev:mips64el \ + libcap-ng-dev:mips64el \ + libcapstone-dev:mips64el \ + libcmocka-dev:mips64el \ + libcurl4-gnutls-dev:mips64el \ + libdaxctl-dev:mips64el \ + libdrm-dev:mips64el \ + libepoxy-dev:mips64el \ + libfdt-dev:mips64el \ + libffi-dev:mips64el \ + libfuse3-dev:mips64el \ + libgbm-dev:mips64el \ + libgcrypt20-dev:mips64el \ + libglib2.0-dev:mips64el \ + libglusterfs-dev:mips64el \ + libgnutls28-dev:mips64el \ + libgtk-3-dev:mips64el \ + libibumad-dev:mips64el \ + libibverbs-dev:mips64el \ + libiscsi-dev:mips64el \ + libjemalloc-dev:mips64el \ + libjpeg62-turbo-dev:mips64el \ + libjson-c-dev:mips64el \ + liblttng-ust-dev:mips64el \ + liblzo2-dev:mips64el \ + libncursesw5-dev:mips64el \ + libnfs-dev:mips64el \ + libnuma-dev:mips64el \ + libpam0g-dev:mips64el \ + libpixman-1-dev:mips64el \ + libpng-dev:mips64el \ + libpulse-dev:mips64el \ + librbd-dev:mips64el \ + librdmacm-dev:mips64el \ + libsasl2-dev:mips64el \ + libsdl2-dev:mips64el \ + libsdl2-image-dev:mips64el \ + libseccomp-dev:mips64el \ + libselinux1-dev:mips64el \ + libslirp-dev:mips64el \ + libsnappy-dev:mips64el \ + libspice-server-dev:mips64el \ + libssh-gcrypt-dev:mips64el \ + libsystemd-dev:mips64el \ + libtasn1-6-dev:mips64el \ + libudev-dev:mips64el \ + liburing-dev:mips64el \ + libusb-1.0-0-dev:mips64el \ + libusbredirhost-dev:mips64el \ + libvdeplug-dev:mips64el \ + libvirglrenderer-dev:mips64el \ + libvte-2.91-dev:mips64el \ + libzstd-dev:mips64el \ + nettle-dev:mips64el \ + systemtap-sdt-dev:mips64el \ + xfslibs-dev:mips64el \ + zlib1g-dev:mips64el && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ mkdir -p /usr/local/share/meson/cross && \ diff --git a/tests/docker/dockerfiles/debian-mipsel-cross.docker b/tests/docker/dockerfiles/debian-mipsel-cross.docker index 02feaf26cb..a5d3ca6e2f 100644 --- a/tests/docker/dockerfiles/debian-mipsel-cross.docker +++ b/tests/docker/dockerfiles/debian-mipsel-cross.docker @@ -11,62 +11,63 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get install -y eatmydata && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y \ - bash \ - bc \ - bison \ - bsdextrautils \ - bzip2 \ - ca-certificates \ - ccache \ - dbus \ - debianutils \ - diffutils \ - exuberant-ctags \ - findutils \ - flex \ - gcovr \ - genisoimage \ - gettext \ - git \ - hostname \ - libglib2.0-dev \ - libpcre2-dev \ - libspice-protocol-dev \ - llvm \ - locales \ - make \ - meson \ - ncat \ - ninja-build \ - openssh-client \ - perl-base \ - pkgconf \ - python3 \ - python3-numpy \ - python3-opencv \ - python3-pillow \ - python3-pip \ - python3-sphinx \ - python3-sphinx-rtd-theme \ - python3-venv \ - python3-yaml \ - rpm2cpio \ - sed \ - sparse \ - tar \ - tesseract-ocr \ - tesseract-ocr-eng \ - texinfo && \ + bash \ + bc \ + bison \ + bsdextrautils \ + bzip2 \ + ca-certificates \ + ccache \ + dbus \ + debianutils \ + diffutils \ + exuberant-ctags \ + findutils \ + flex \ + gcovr \ + genisoimage \ + gettext \ + git \ + hostname \ + libglib2.0-dev \ + libpcre2-dev \ + libsndio-dev \ + libspice-protocol-dev \ + llvm \ + locales \ + make \ + meson \ + ncat \ + ninja-build \ + openssh-client \ + perl-base \ + pkgconf \ + python3 \ + python3-numpy \ + python3-opencv \ + python3-pillow \ + python3-pip \ + python3-sphinx \ + python3-sphinx-rtd-theme \ + python3-venv \ + python3-yaml \ + rpm2cpio \ + sed \ + sparse \ + tar \ + tesseract-ocr \ + tesseract-ocr-eng \ + texinfo && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \ dpkg-reconfigure locales +ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" ENV LANG "en_US.UTF-8" ENV MAKE "/usr/bin/make" ENV NINJA "/usr/bin/ninja" ENV PYTHON "/usr/bin/python3" -ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" RUN export DEBIAN_FRONTEND=noninteractive && \ dpkg --add-architecture mipsel && \ @@ -74,72 +75,72 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y dpkg-dev && \ eatmydata apt-get install --no-install-recommends -y \ - g++-mipsel-linux-gnu \ - gcc-mipsel-linux-gnu \ - libaio-dev:mipsel \ - libasound2-dev:mipsel \ - libattr1-dev:mipsel \ - libbpf-dev:mipsel \ - libbrlapi-dev:mipsel \ - libbz2-dev:mipsel \ - libc6-dev:mipsel \ - libcacard-dev:mipsel \ - libcap-ng-dev:mipsel \ - libcapstone-dev:mipsel \ - libcmocka-dev:mipsel \ - libcurl4-gnutls-dev:mipsel \ - libdaxctl-dev:mipsel \ - libdrm-dev:mipsel \ - libepoxy-dev:mipsel \ - libfdt-dev:mipsel \ - libffi-dev:mipsel \ - libfuse3-dev:mipsel \ - libgbm-dev:mipsel \ - libgcrypt20-dev:mipsel \ - libglib2.0-dev:mipsel \ - libglusterfs-dev:mipsel \ - libgnutls28-dev:mipsel \ - libgtk-3-dev:mipsel \ - libibumad-dev:mipsel \ - libibverbs-dev:mipsel \ - libiscsi-dev:mipsel \ - libjemalloc-dev:mipsel \ - libjpeg62-turbo-dev:mipsel \ - libjson-c-dev:mipsel \ - liblttng-ust-dev:mipsel \ - liblzo2-dev:mipsel \ - libncursesw5-dev:mipsel \ - libnfs-dev:mipsel \ - libnuma-dev:mipsel \ - libpam0g-dev:mipsel \ - libpixman-1-dev:mipsel \ - libpng-dev:mipsel \ - libpulse-dev:mipsel \ - librbd-dev:mipsel \ - librdmacm-dev:mipsel \ - libsasl2-dev:mipsel \ - libsdl2-dev:mipsel \ - libsdl2-image-dev:mipsel \ - libseccomp-dev:mipsel \ - libselinux1-dev:mipsel \ - libslirp-dev:mipsel \ - libsnappy-dev:mipsel \ - libspice-server-dev:mipsel \ - libssh-gcrypt-dev:mipsel \ - libsystemd-dev:mipsel \ - libtasn1-6-dev:mipsel \ - libudev-dev:mipsel \ - liburing-dev:mipsel \ - libusb-1.0-0-dev:mipsel \ - libusbredirhost-dev:mipsel \ - libvdeplug-dev:mipsel \ - libvirglrenderer-dev:mipsel \ - libvte-2.91-dev:mipsel \ - libzstd-dev:mipsel \ - nettle-dev:mipsel \ - systemtap-sdt-dev:mipsel \ - xfslibs-dev:mipsel \ - zlib1g-dev:mipsel && \ + g++-mipsel-linux-gnu \ + gcc-mipsel-linux-gnu \ + libaio-dev:mipsel \ + libasound2-dev:mipsel \ + libattr1-dev:mipsel \ + libbpf-dev:mipsel \ + libbrlapi-dev:mipsel \ + libbz2-dev:mipsel \ + libc6-dev:mipsel \ + libcacard-dev:mipsel \ + libcap-ng-dev:mipsel \ + libcapstone-dev:mipsel \ + libcmocka-dev:mipsel \ + libcurl4-gnutls-dev:mipsel \ + libdaxctl-dev:mipsel \ + libdrm-dev:mipsel \ + libepoxy-dev:mipsel \ + libfdt-dev:mipsel \ + libffi-dev:mipsel \ + libfuse3-dev:mipsel \ + libgbm-dev:mipsel \ + libgcrypt20-dev:mipsel \ + libglib2.0-dev:mipsel \ + libglusterfs-dev:mipsel \ + libgnutls28-dev:mipsel \ + libgtk-3-dev:mipsel \ + libibumad-dev:mipsel \ + libibverbs-dev:mipsel \ + libiscsi-dev:mipsel \ + libjemalloc-dev:mipsel \ + libjpeg62-turbo-dev:mipsel \ + libjson-c-dev:mipsel \ + liblttng-ust-dev:mipsel \ + liblzo2-dev:mipsel \ + libncursesw5-dev:mipsel \ + libnfs-dev:mipsel \ + libnuma-dev:mipsel \ + libpam0g-dev:mipsel \ + libpixman-1-dev:mipsel \ + libpng-dev:mipsel \ + libpulse-dev:mipsel \ + librbd-dev:mipsel \ + librdmacm-dev:mipsel \ + libsasl2-dev:mipsel \ + libsdl2-dev:mipsel \ + libsdl2-image-dev:mipsel \ + libseccomp-dev:mipsel \ + libselinux1-dev:mipsel \ + libslirp-dev:mipsel \ + libsnappy-dev:mipsel \ + libspice-server-dev:mipsel \ + libssh-gcrypt-dev:mipsel \ + libsystemd-dev:mipsel \ + libtasn1-6-dev:mipsel \ + libudev-dev:mipsel \ + liburing-dev:mipsel \ + libusb-1.0-0-dev:mipsel \ + libusbredirhost-dev:mipsel \ + libvdeplug-dev:mipsel \ + libvirglrenderer-dev:mipsel \ + libvte-2.91-dev:mipsel \ + libzstd-dev:mipsel \ + nettle-dev:mipsel \ + systemtap-sdt-dev:mipsel \ + xfslibs-dev:mipsel \ + zlib1g-dev:mipsel && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ mkdir -p /usr/local/share/meson/cross && \ diff --git a/tests/docker/dockerfiles/debian-ppc64el-cross.docker b/tests/docker/dockerfiles/debian-ppc64el-cross.docker index 97d3872ee2..d2954e61f6 100644 --- a/tests/docker/dockerfiles/debian-ppc64el-cross.docker +++ b/tests/docker/dockerfiles/debian-ppc64el-cross.docker @@ -11,62 +11,63 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get install -y eatmydata && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y \ - bash \ - bc \ - bison \ - bsdextrautils \ - bzip2 \ - ca-certificates \ - ccache \ - dbus \ - debianutils \ - diffutils \ - exuberant-ctags \ - findutils \ - flex \ - gcovr \ - genisoimage \ - gettext \ - git \ - hostname \ - libglib2.0-dev \ - libpcre2-dev \ - libspice-protocol-dev \ - llvm \ - locales \ - make \ - meson \ - ncat \ - ninja-build \ - openssh-client \ - perl-base \ - pkgconf \ - python3 \ - python3-numpy \ - python3-opencv \ - python3-pillow \ - python3-pip \ - python3-sphinx \ - python3-sphinx-rtd-theme \ - python3-venv \ - python3-yaml \ - rpm2cpio \ - sed \ - sparse \ - tar \ - tesseract-ocr \ - tesseract-ocr-eng \ - texinfo && \ + bash \ + bc \ + bison \ + bsdextrautils \ + bzip2 \ + ca-certificates \ + ccache \ + dbus \ + debianutils \ + diffutils \ + exuberant-ctags \ + findutils \ + flex \ + gcovr \ + genisoimage \ + gettext \ + git \ + hostname \ + libglib2.0-dev \ + libpcre2-dev \ + libsndio-dev \ + libspice-protocol-dev \ + llvm \ + locales \ + make \ + meson \ + ncat \ + ninja-build \ + openssh-client \ + perl-base \ + pkgconf \ + python3 \ + python3-numpy \ + python3-opencv \ + python3-pillow \ + python3-pip \ + python3-sphinx \ + python3-sphinx-rtd-theme \ + python3-venv \ + python3-yaml \ + rpm2cpio \ + sed \ + sparse \ + tar \ + tesseract-ocr \ + tesseract-ocr-eng \ + texinfo && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \ dpkg-reconfigure locales +ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" ENV LANG "en_US.UTF-8" ENV MAKE "/usr/bin/make" ENV NINJA "/usr/bin/ninja" ENV PYTHON "/usr/bin/python3" -ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" RUN export DEBIAN_FRONTEND=noninteractive && \ dpkg --add-architecture ppc64el && \ @@ -74,74 +75,74 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y dpkg-dev && \ eatmydata apt-get install --no-install-recommends -y \ - g++-powerpc64le-linux-gnu \ - gcc-powerpc64le-linux-gnu \ - libaio-dev:ppc64el \ - libasan5:ppc64el \ - libasound2-dev:ppc64el \ - libattr1-dev:ppc64el \ - libbpf-dev:ppc64el \ - libbrlapi-dev:ppc64el \ - libbz2-dev:ppc64el \ - libc6-dev:ppc64el \ - libcacard-dev:ppc64el \ - libcap-ng-dev:ppc64el \ - libcapstone-dev:ppc64el \ - libcmocka-dev:ppc64el \ - libcurl4-gnutls-dev:ppc64el \ - libdaxctl-dev:ppc64el \ - libdrm-dev:ppc64el \ - libepoxy-dev:ppc64el \ - libfdt-dev:ppc64el \ - libffi-dev:ppc64el \ - libfuse3-dev:ppc64el \ - libgbm-dev:ppc64el \ - libgcrypt20-dev:ppc64el \ - libglib2.0-dev:ppc64el \ - libglusterfs-dev:ppc64el \ - libgnutls28-dev:ppc64el \ - libgtk-3-dev:ppc64el \ - libibumad-dev:ppc64el \ - libibverbs-dev:ppc64el \ - libiscsi-dev:ppc64el \ - libjemalloc-dev:ppc64el \ - libjpeg62-turbo-dev:ppc64el \ - libjson-c-dev:ppc64el \ - liblttng-ust-dev:ppc64el \ - liblzo2-dev:ppc64el \ - libncursesw5-dev:ppc64el \ - libnfs-dev:ppc64el \ - libnuma-dev:ppc64el \ - libpam0g-dev:ppc64el \ - libpixman-1-dev:ppc64el \ - libpng-dev:ppc64el \ - libpulse-dev:ppc64el \ - librbd-dev:ppc64el \ - librdmacm-dev:ppc64el \ - libsasl2-dev:ppc64el \ - libsdl2-dev:ppc64el \ - libsdl2-image-dev:ppc64el \ - libseccomp-dev:ppc64el \ - libselinux1-dev:ppc64el \ - libslirp-dev:ppc64el \ - libsnappy-dev:ppc64el \ - libspice-server-dev:ppc64el \ - libssh-gcrypt-dev:ppc64el \ - libsystemd-dev:ppc64el \ - libtasn1-6-dev:ppc64el \ - libubsan1:ppc64el \ - libudev-dev:ppc64el \ - liburing-dev:ppc64el \ - libusb-1.0-0-dev:ppc64el \ - libusbredirhost-dev:ppc64el \ - libvdeplug-dev:ppc64el \ - libvirglrenderer-dev:ppc64el \ - libvte-2.91-dev:ppc64el \ - libzstd-dev:ppc64el \ - nettle-dev:ppc64el \ - systemtap-sdt-dev:ppc64el \ - xfslibs-dev:ppc64el \ - zlib1g-dev:ppc64el && \ + g++-powerpc64le-linux-gnu \ + gcc-powerpc64le-linux-gnu \ + libaio-dev:ppc64el \ + libasan5:ppc64el \ + libasound2-dev:ppc64el \ + libattr1-dev:ppc64el \ + libbpf-dev:ppc64el \ + libbrlapi-dev:ppc64el \ + libbz2-dev:ppc64el \ + libc6-dev:ppc64el \ + libcacard-dev:ppc64el \ + libcap-ng-dev:ppc64el \ + libcapstone-dev:ppc64el \ + libcmocka-dev:ppc64el \ + libcurl4-gnutls-dev:ppc64el \ + libdaxctl-dev:ppc64el \ + libdrm-dev:ppc64el \ + libepoxy-dev:ppc64el \ + libfdt-dev:ppc64el \ + libffi-dev:ppc64el \ + libfuse3-dev:ppc64el \ + libgbm-dev:ppc64el \ + libgcrypt20-dev:ppc64el \ + libglib2.0-dev:ppc64el \ + libglusterfs-dev:ppc64el \ + libgnutls28-dev:ppc64el \ + libgtk-3-dev:ppc64el \ + libibumad-dev:ppc64el \ + libibverbs-dev:ppc64el \ + libiscsi-dev:ppc64el \ + libjemalloc-dev:ppc64el \ + libjpeg62-turbo-dev:ppc64el \ + libjson-c-dev:ppc64el \ + liblttng-ust-dev:ppc64el \ + liblzo2-dev:ppc64el \ + libncursesw5-dev:ppc64el \ + libnfs-dev:ppc64el \ + libnuma-dev:ppc64el \ + libpam0g-dev:ppc64el \ + libpixman-1-dev:ppc64el \ + libpng-dev:ppc64el \ + libpulse-dev:ppc64el \ + librbd-dev:ppc64el \ + librdmacm-dev:ppc64el \ + libsasl2-dev:ppc64el \ + libsdl2-dev:ppc64el \ + libsdl2-image-dev:ppc64el \ + libseccomp-dev:ppc64el \ + libselinux1-dev:ppc64el \ + libslirp-dev:ppc64el \ + libsnappy-dev:ppc64el \ + libspice-server-dev:ppc64el \ + libssh-gcrypt-dev:ppc64el \ + libsystemd-dev:ppc64el \ + libtasn1-6-dev:ppc64el \ + libubsan1:ppc64el \ + libudev-dev:ppc64el \ + liburing-dev:ppc64el \ + libusb-1.0-0-dev:ppc64el \ + libusbredirhost-dev:ppc64el \ + libvdeplug-dev:ppc64el \ + libvirglrenderer-dev:ppc64el \ + libvte-2.91-dev:ppc64el \ + libzstd-dev:ppc64el \ + nettle-dev:ppc64el \ + systemtap-sdt-dev:ppc64el \ + xfslibs-dev:ppc64el \ + zlib1g-dev:ppc64el && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ mkdir -p /usr/local/share/meson/cross && \ diff --git a/tests/docker/dockerfiles/debian-s390x-cross.docker b/tests/docker/dockerfiles/debian-s390x-cross.docker index 95585e9e56..d43ce16317 100644 --- a/tests/docker/dockerfiles/debian-s390x-cross.docker +++ b/tests/docker/dockerfiles/debian-s390x-cross.docker @@ -11,62 +11,63 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get install -y eatmydata && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y \ - bash \ - bc \ - bison \ - bsdextrautils \ - bzip2 \ - ca-certificates \ - ccache \ - dbus \ - debianutils \ - diffutils \ - exuberant-ctags \ - findutils \ - flex \ - gcovr \ - genisoimage \ - gettext \ - git \ - hostname \ - libglib2.0-dev \ - libpcre2-dev \ - libspice-protocol-dev \ - llvm \ - locales \ - make \ - meson \ - ncat \ - ninja-build \ - openssh-client \ - perl-base \ - pkgconf \ - python3 \ - python3-numpy \ - python3-opencv \ - python3-pillow \ - python3-pip \ - python3-sphinx \ - python3-sphinx-rtd-theme \ - python3-venv \ - python3-yaml \ - rpm2cpio \ - sed \ - sparse \ - tar \ - tesseract-ocr \ - tesseract-ocr-eng \ - texinfo && \ + bash \ + bc \ + bison \ + bsdextrautils \ + bzip2 \ + ca-certificates \ + ccache \ + dbus \ + debianutils \ + diffutils \ + exuberant-ctags \ + findutils \ + flex \ + gcovr \ + genisoimage \ + gettext \ + git \ + hostname \ + libglib2.0-dev \ + libpcre2-dev \ + libsndio-dev \ + libspice-protocol-dev \ + llvm \ + locales \ + make \ + meson \ + ncat \ + ninja-build \ + openssh-client \ + perl-base \ + pkgconf \ + python3 \ + python3-numpy \ + python3-opencv \ + python3-pillow \ + python3-pip \ + python3-sphinx \ + python3-sphinx-rtd-theme \ + python3-venv \ + python3-yaml \ + rpm2cpio \ + sed \ + sparse \ + tar \ + tesseract-ocr \ + tesseract-ocr-eng \ + texinfo && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \ dpkg-reconfigure locales +ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" ENV LANG "en_US.UTF-8" ENV MAKE "/usr/bin/make" ENV NINJA "/usr/bin/ninja" ENV PYTHON "/usr/bin/python3" -ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" RUN export DEBIAN_FRONTEND=noninteractive && \ dpkg --add-architecture s390x && \ @@ -74,73 +75,73 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y dpkg-dev && \ eatmydata apt-get install --no-install-recommends -y \ - g++-s390x-linux-gnu \ - gcc-s390x-linux-gnu \ - libaio-dev:s390x \ - libasan5:s390x \ - libasound2-dev:s390x \ - libattr1-dev:s390x \ - libbpf-dev:s390x \ - libbrlapi-dev:s390x \ - libbz2-dev:s390x \ - libc6-dev:s390x \ - libcacard-dev:s390x \ - libcap-ng-dev:s390x \ - libcapstone-dev:s390x \ - libcmocka-dev:s390x \ - libcurl4-gnutls-dev:s390x \ - libdaxctl-dev:s390x \ - libdrm-dev:s390x \ - libepoxy-dev:s390x \ - libfdt-dev:s390x \ - libffi-dev:s390x \ - libfuse3-dev:s390x \ - libgbm-dev:s390x \ - libgcrypt20-dev:s390x \ - libglib2.0-dev:s390x \ - libglusterfs-dev:s390x \ - libgnutls28-dev:s390x \ - libgtk-3-dev:s390x \ - libibumad-dev:s390x \ - libibverbs-dev:s390x \ - libiscsi-dev:s390x \ - libjemalloc-dev:s390x \ - libjpeg62-turbo-dev:s390x \ - libjson-c-dev:s390x \ - liblttng-ust-dev:s390x \ - liblzo2-dev:s390x \ - libncursesw5-dev:s390x \ - libnfs-dev:s390x \ - libnuma-dev:s390x \ - libpam0g-dev:s390x \ - libpixman-1-dev:s390x \ - libpng-dev:s390x \ - libpulse-dev:s390x \ - librbd-dev:s390x \ - librdmacm-dev:s390x \ - libsasl2-dev:s390x \ - libsdl2-dev:s390x \ - libsdl2-image-dev:s390x \ - libseccomp-dev:s390x \ - libselinux1-dev:s390x \ - libslirp-dev:s390x \ - libsnappy-dev:s390x \ - libssh-gcrypt-dev:s390x \ - libsystemd-dev:s390x \ - libtasn1-6-dev:s390x \ - libubsan1:s390x \ - libudev-dev:s390x \ - liburing-dev:s390x \ - libusb-1.0-0-dev:s390x \ - libusbredirhost-dev:s390x \ - libvdeplug-dev:s390x \ - libvirglrenderer-dev:s390x \ - libvte-2.91-dev:s390x \ - libzstd-dev:s390x \ - nettle-dev:s390x \ - systemtap-sdt-dev:s390x \ - xfslibs-dev:s390x \ - zlib1g-dev:s390x && \ + g++-s390x-linux-gnu \ + gcc-s390x-linux-gnu \ + libaio-dev:s390x \ + libasan5:s390x \ + libasound2-dev:s390x \ + libattr1-dev:s390x \ + libbpf-dev:s390x \ + libbrlapi-dev:s390x \ + libbz2-dev:s390x \ + libc6-dev:s390x \ + libcacard-dev:s390x \ + libcap-ng-dev:s390x \ + libcapstone-dev:s390x \ + libcmocka-dev:s390x \ + libcurl4-gnutls-dev:s390x \ + libdaxctl-dev:s390x \ + libdrm-dev:s390x \ + libepoxy-dev:s390x \ + libfdt-dev:s390x \ + libffi-dev:s390x \ + libfuse3-dev:s390x \ + libgbm-dev:s390x \ + libgcrypt20-dev:s390x \ + libglib2.0-dev:s390x \ + libglusterfs-dev:s390x \ + libgnutls28-dev:s390x \ + libgtk-3-dev:s390x \ + libibumad-dev:s390x \ + libibverbs-dev:s390x \ + libiscsi-dev:s390x \ + libjemalloc-dev:s390x \ + libjpeg62-turbo-dev:s390x \ + libjson-c-dev:s390x \ + liblttng-ust-dev:s390x \ + liblzo2-dev:s390x \ + libncursesw5-dev:s390x \ + libnfs-dev:s390x \ + libnuma-dev:s390x \ + libpam0g-dev:s390x \ + libpixman-1-dev:s390x \ + libpng-dev:s390x \ + libpulse-dev:s390x \ + librbd-dev:s390x \ + librdmacm-dev:s390x \ + libsasl2-dev:s390x \ + libsdl2-dev:s390x \ + libsdl2-image-dev:s390x \ + libseccomp-dev:s390x \ + libselinux1-dev:s390x \ + libslirp-dev:s390x \ + libsnappy-dev:s390x \ + libssh-gcrypt-dev:s390x \ + libsystemd-dev:s390x \ + libtasn1-6-dev:s390x \ + libubsan1:s390x \ + libudev-dev:s390x \ + liburing-dev:s390x \ + libusb-1.0-0-dev:s390x \ + libusbredirhost-dev:s390x \ + libvdeplug-dev:s390x \ + libvirglrenderer-dev:s390x \ + libvte-2.91-dev:s390x \ + libzstd-dev:s390x \ + nettle-dev:s390x \ + systemtap-sdt-dev:s390x \ + xfslibs-dev:s390x \ + zlib1g-dev:s390x && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ mkdir -p /usr/local/share/meson/cross && \ diff --git a/tests/docker/dockerfiles/fedora.docker b/tests/docker/dockerfiles/fedora.docker index fe84166ca1..d200c7fc10 100644 --- a/tests/docker/dockerfiles/fedora.docker +++ b/tests/docker/dockerfiles/fedora.docker @@ -18,120 +18,120 @@ exec "$@"' > /usr/bin/nosync && \ chmod +x /usr/bin/nosync && \ nosync dnf update -y && \ nosync dnf install -y \ - SDL2-devel \ - SDL2_image-devel \ - alsa-lib-devel \ - bash \ - bc \ - bison \ - brlapi-devel \ - bzip2 \ - bzip2-devel \ - ca-certificates \ - capstone-devel \ - ccache \ - clang \ - ctags \ - cyrus-sasl-devel \ - daxctl-devel \ - dbus-daemon \ - device-mapper-multipath-devel \ - diffutils \ - findutils \ - flex \ - fuse3-devel \ - gcc \ - gcc-c++ \ - gcovr \ - genisoimage \ - gettext \ - git \ - glib2-devel \ - glib2-static \ - glibc-langpack-en \ - glibc-static \ - glusterfs-api-devel \ - gnutls-devel \ - gtk3-devel \ - hostname \ - jemalloc-devel \ - json-c-devel \ - libaio-devel \ - libasan \ - libattr-devel \ - libbpf-devel \ - libcacard-devel \ - libcap-ng-devel \ - libcmocka-devel \ - libcurl-devel \ - libdrm-devel \ - libepoxy-devel \ - libfdt-devel \ - libffi-devel \ - libgcrypt-devel \ - libiscsi-devel \ - libjpeg-devel \ - libnfs-devel \ - libpmem-devel \ - libpng-devel \ - librbd-devel \ - libseccomp-devel \ - libselinux-devel \ - libslirp-devel \ - libssh-devel \ - libtasn1-devel \ - libubsan \ - liburing-devel \ - libusbx-devel \ - libzstd-devel \ - llvm \ - lttng-ust-devel \ - lzo-devel \ - make \ - mesa-libgbm-devel \ - meson \ - ncurses-devel \ - nettle-devel \ - ninja-build \ - nmap-ncat \ - numactl-devel \ - openssh-clients \ - pam-devel \ - pcre-static \ - perl-base \ - pixman-devel \ - pkgconfig \ - pulseaudio-libs-devel \ - python3 \ - python3-PyYAML \ - python3-numpy \ - python3-opencv \ - python3-pillow \ - python3-pip \ - python3-sphinx \ - python3-sphinx_rtd_theme \ - rdma-core-devel \ - rpm \ - sed \ - snappy-devel \ - sparse \ - spice-protocol \ - spice-server-devel \ - systemd-devel \ - systemtap-sdt-devel \ - tar \ - tesseract \ - tesseract-langpack-eng \ - texinfo \ - usbredir-devel \ - util-linux \ - virglrenderer-devel \ - vte291-devel \ - which \ - xen-devel \ - xfsprogs-devel \ - zlib-devel \ - zlib-static && \ + SDL2-devel \ + SDL2_image-devel \ + alsa-lib-devel \ + bash \ + bc \ + bison \ + brlapi-devel \ + bzip2 \ + bzip2-devel \ + ca-certificates \ + capstone-devel \ + ccache \ + clang \ + ctags \ + cyrus-sasl-devel \ + daxctl-devel \ + dbus-daemon \ + device-mapper-multipath-devel \ + diffutils \ + findutils \ + flex \ + fuse3-devel \ + gcc \ + gcc-c++ \ + gcovr \ + genisoimage \ + gettext \ + git \ + glib2-devel \ + glib2-static \ + glibc-langpack-en \ + glibc-static \ + glusterfs-api-devel \ + gnutls-devel \ + gtk3-devel \ + hostname \ + jemalloc-devel \ + json-c-devel \ + libaio-devel \ + libasan \ + libattr-devel \ + libbpf-devel \ + libcacard-devel \ + libcap-ng-devel \ + libcmocka-devel \ + libcurl-devel \ + libdrm-devel \ + libepoxy-devel \ + libfdt-devel \ + libffi-devel \ + libgcrypt-devel \ + libiscsi-devel \ + libjpeg-devel \ + libnfs-devel \ + libpmem-devel \ + libpng-devel \ + librbd-devel \ + libseccomp-devel \ + libselinux-devel \ + libslirp-devel \ + libssh-devel \ + libtasn1-devel \ + libubsan \ + liburing-devel \ + libusbx-devel \ + libzstd-devel \ + llvm \ + lttng-ust-devel \ + lzo-devel \ + make \ + mesa-libgbm-devel \ + meson \ + ncurses-devel \ + nettle-devel \ + ninja-build \ + nmap-ncat \ + numactl-devel \ + openssh-clients \ + pam-devel \ + pcre-static \ + perl-base \ + pixman-devel \ + pkgconfig \ + pulseaudio-libs-devel \ + python3 \ + python3-PyYAML \ + python3-numpy \ + python3-opencv \ + python3-pillow \ + python3-pip \ + python3-sphinx \ + python3-sphinx_rtd_theme \ + rdma-core-devel \ + rpm \ + sed \ + snappy-devel \ + sparse \ + spice-protocol \ + spice-server-devel \ + systemd-devel \ + systemtap-sdt-devel \ + tar \ + tesseract \ + tesseract-langpack-eng \ + texinfo \ + usbredir-devel \ + util-linux \ + virglrenderer-devel \ + vte291-devel \ + which \ + xen-devel \ + xfsprogs-devel \ + zlib-devel \ + zlib-static && \ nosync dnf autoremove -y && \ nosync dnf clean all -y && \ rpm -qa | sort > /packages.txt && \ @@ -142,8 +142,8 @@ exec "$@"' > /usr/bin/nosync && \ ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/g++ && \ ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc +ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" ENV LANG "en_US.UTF-8" ENV MAKE "/usr/bin/make" ENV NINJA "/usr/bin/ninja" ENV PYTHON "/usr/bin/python3" -ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" diff --git a/tests/docker/dockerfiles/opensuse-leap.docker b/tests/docker/dockerfiles/opensuse-leap.docker index d80064756f..4361b01464 100644 --- a/tests/docker/dockerfiles/opensuse-leap.docker +++ b/tests/docker/dockerfiles/opensuse-leap.docker @@ -104,6 +104,7 @@ RUN zypper update -y && \ rpm \ sed \ snappy-devel \ + sndio-devel \ sparse \ spice-protocol-devel \ systemd-devel \ @@ -132,8 +133,8 @@ RUN zypper update -y && \ RUN /usr/bin/pip3 install meson==0.56.0 +ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" ENV LANG "en_US.UTF-8" ENV MAKE "/usr/bin/make" ENV NINJA "/usr/bin/ninja" ENV PYTHON "/usr/bin/python3" -ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" diff --git a/tests/docker/dockerfiles/ubuntu2004.docker b/tests/docker/dockerfiles/ubuntu2004.docker index 24594afc15..9417bca2fa 100644 --- a/tests/docker/dockerfiles/ubuntu2004.docker +++ b/tests/docker/dockerfiles/ubuntu2004.docker @@ -11,122 +11,123 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get install -y eatmydata && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y \ - bash \ - bc \ - bison \ - bsdmainutils \ - bzip2 \ - ca-certificates \ - ccache \ - clang \ - dbus \ - debianutils \ - diffutils \ - exuberant-ctags \ - findutils \ - flex \ - g++ \ - gcc \ - gcovr \ - genisoimage \ - gettext \ - git \ - hostname \ - libaio-dev \ - libasan5 \ - libasound2-dev \ - libattr1-dev \ - libbrlapi-dev \ - libbz2-dev \ - libc6-dev \ - libcacard-dev \ - libcap-ng-dev \ - libcapstone-dev \ - libcmocka-dev \ - libcurl4-gnutls-dev \ - libdaxctl-dev \ - libdrm-dev \ - libepoxy-dev \ - libfdt-dev \ - libffi-dev \ - libfuse3-dev \ - libgbm-dev \ - libgcrypt20-dev \ - libglib2.0-dev \ - libglusterfs-dev \ - libgnutls28-dev \ - libgtk-3-dev \ - libibumad-dev \ - libibverbs-dev \ - libiscsi-dev \ - libjemalloc-dev \ - libjpeg-turbo8-dev \ - libjson-c-dev \ - liblttng-ust-dev \ - liblzo2-dev \ - libncursesw5-dev \ - libnfs-dev \ - libnuma-dev \ - libpam0g-dev \ - libpcre2-dev \ - libpixman-1-dev \ - libpmem-dev \ - libpng-dev \ - libpulse-dev \ - librbd-dev \ - librdmacm-dev \ - libsasl2-dev \ - libsdl2-dev \ - libsdl2-image-dev \ - libseccomp-dev \ - libselinux1-dev \ - libslirp-dev \ - libsnappy-dev \ - libspice-protocol-dev \ - libspice-server-dev \ - libssh-dev \ - libsystemd-dev \ - libtasn1-6-dev \ - libubsan1 \ - libudev-dev \ - libusb-1.0-0-dev \ - libusbredirhost-dev \ - libvdeplug-dev \ - libvirglrenderer-dev \ - libvte-2.91-dev \ - libxen-dev \ - libzstd-dev \ - llvm \ - locales \ - make \ - multipath-tools \ - ncat \ - nettle-dev \ - ninja-build \ - openssh-client \ - perl-base \ - pkgconf \ - python3 \ - python3-numpy \ - python3-opencv \ - python3-pillow \ - python3-pip \ - python3-setuptools \ - python3-sphinx \ - python3-sphinx-rtd-theme \ - python3-venv \ - python3-wheel \ - python3-yaml \ - rpm2cpio \ - sed \ - sparse \ - systemtap-sdt-dev \ - tar \ - tesseract-ocr \ - tesseract-ocr-eng \ - texinfo \ - xfslibs-dev \ - zlib1g-dev && \ + bash \ + bc \ + bison \ + bsdmainutils \ + bzip2 \ + ca-certificates \ + ccache \ + clang \ + dbus \ + debianutils \ + diffutils \ + exuberant-ctags \ + findutils \ + flex \ + g++ \ + gcc \ + gcovr \ + genisoimage \ + gettext \ + git \ + hostname \ + libaio-dev \ + libasan5 \ + libasound2-dev \ + libattr1-dev \ + libbrlapi-dev \ + libbz2-dev \ + libc6-dev \ + libcacard-dev \ + libcap-ng-dev \ + libcapstone-dev \ + libcmocka-dev \ + libcurl4-gnutls-dev \ + libdaxctl-dev \ + libdrm-dev \ + libepoxy-dev \ + libfdt-dev \ + libffi-dev \ + libfuse3-dev \ + libgbm-dev \ + libgcrypt20-dev \ + libglib2.0-dev \ + libglusterfs-dev \ + libgnutls28-dev \ + libgtk-3-dev \ + libibumad-dev \ + libibverbs-dev \ + libiscsi-dev \ + libjemalloc-dev \ + libjpeg-turbo8-dev \ + libjson-c-dev \ + liblttng-ust-dev \ + liblzo2-dev \ + libncursesw5-dev \ + libnfs-dev \ + libnuma-dev \ + libpam0g-dev \ + libpcre2-dev \ + libpixman-1-dev \ + libpmem-dev \ + libpng-dev \ + libpulse-dev \ + librbd-dev \ + librdmacm-dev \ + libsasl2-dev \ + libsdl2-dev \ + libsdl2-image-dev \ + libseccomp-dev \ + libselinux1-dev \ + libslirp-dev \ + libsnappy-dev \ + libsndio-dev \ + libspice-protocol-dev \ + libspice-server-dev \ + libssh-dev \ + libsystemd-dev \ + libtasn1-6-dev \ + libubsan1 \ + libudev-dev \ + libusb-1.0-0-dev \ + libusbredirhost-dev \ + libvdeplug-dev \ + libvirglrenderer-dev \ + libvte-2.91-dev \ + libxen-dev \ + libzstd-dev \ + llvm \ + locales \ + make \ + multipath-tools \ + ncat \ + nettle-dev \ + ninja-build \ + openssh-client \ + perl-base \ + pkgconf \ + python3 \ + python3-numpy \ + python3-opencv \ + python3-pillow \ + python3-pip \ + python3-setuptools \ + python3-sphinx \ + python3-sphinx-rtd-theme \ + python3-venv \ + python3-wheel \ + python3-yaml \ + rpm2cpio \ + sed \ + sparse \ + systemtap-sdt-dev \ + tar \ + tesseract-ocr \ + tesseract-ocr-eng \ + texinfo \ + xfslibs-dev \ + zlib1g-dev && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \ @@ -141,11 +142,11 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ RUN /usr/bin/pip3 install meson==0.56.0 +ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" ENV LANG "en_US.UTF-8" ENV MAKE "/usr/bin/make" ENV NINJA "/usr/bin/ninja" ENV PYTHON "/usr/bin/python3" -ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" # Apply patch https://reviews.llvm.org/D75820 # This is required for TSan in clang-10 to compile with QEMU. RUN sed -i 's/^const/static const/g' /usr/lib/llvm-10/lib/clang/10.0.0/include/sanitizer/tsan_interface.h diff --git a/tests/lcitool/libvirt-ci b/tests/lcitool/libvirt-ci index e3712b7912..79691a50a5 160000 --- a/tests/lcitool/libvirt-ci +++ b/tests/lcitool/libvirt-ci @@ -1 +1 @@ -Subproject commit e3712b79122180fdb3b7a7ea8cbee47ece253f97 +Subproject commit 79691a50a5f99bd7adda236f66c3c09371b01afa diff --git a/tests/lcitool/projects/qemu.yml b/tests/lcitool/projects/qemu.yml index 0d92819249..c62dbc00f9 100644 --- a/tests/lcitool/projects/qemu.yml +++ b/tests/lcitool/projects/qemu.yml @@ -101,6 +101,7 @@ packages: - sdl2-image - sed - snappy + - sndio - sparse - spice-protocol - spice-server diff --git a/tests/vm/freebsd b/tests/vm/freebsd index 3643fe325d..d6ff4461ba 100755 --- a/tests/vm/freebsd +++ b/tests/vm/freebsd @@ -66,6 +66,9 @@ class FreeBSDVM(basevm.BaseVM): # libs: networking "libslirp", + + # libs: sndio + "sndio", ] BUILD_SCRIPT = """ From c9923550b446e54413024117c0ed978a08e3ab1a Mon Sep 17 00:00:00 2001 From: Xuzhou Cheng Date: Fri, 28 Oct 2022 12:57:26 +0800 Subject: [PATCH 328/705] accel/qtest: Support qtest accelerator for Windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently signal SIGIPI [=SIGUSR1] is used to kick the dummy CPU when qtest accelerator is used. However SIGUSR1 is unsupported on Windows. To support Windows, we add a QemuSemaphore CPUState::sem to kick the dummy CPU instead for Windows. Signed-off-by: Xuzhou Cheng Signed-off-by: Bin Meng Reviewed-by: Marc-André Lureau Message-Id: <20221028045736.679903-2-bin.meng@windriver.com> Signed-off-by: Thomas Huth --- accel/dummy-cpus.c | 14 ++++++++++++-- accel/meson.build | 2 +- accel/qtest/meson.build | 3 +-- include/hw/core/cpu.h | 1 + softmmu/cpus.c | 9 +++++---- 5 files changed, 20 insertions(+), 9 deletions(-) diff --git a/accel/dummy-cpus.c b/accel/dummy-cpus.c index 10429fdfb2..d6a1b8d0a2 100644 --- a/accel/dummy-cpus.c +++ b/accel/dummy-cpus.c @@ -21,8 +21,6 @@ static void *dummy_cpu_thread_fn(void *arg) { CPUState *cpu = arg; - sigset_t waitset; - int r; rcu_register_thread(); @@ -32,8 +30,13 @@ static void *dummy_cpu_thread_fn(void *arg) cpu->can_do_io = 1; current_cpu = cpu; +#ifndef _WIN32 + sigset_t waitset; + int r; + sigemptyset(&waitset); sigaddset(&waitset, SIG_IPI); +#endif /* signal CPU creation */ cpu_thread_signal_created(cpu); @@ -41,6 +44,7 @@ static void *dummy_cpu_thread_fn(void *arg) do { qemu_mutex_unlock_iothread(); +#ifndef _WIN32 do { int sig; r = sigwait(&waitset, &sig); @@ -49,6 +53,9 @@ static void *dummy_cpu_thread_fn(void *arg) perror("sigwait"); exit(1); } +#else + qemu_sem_wait(&cpu->sem); +#endif qemu_mutex_lock_iothread(); qemu_wait_io_event(cpu); } while (!cpu->unplug); @@ -69,4 +76,7 @@ void dummy_start_vcpu_thread(CPUState *cpu) cpu->cpu_index); qemu_thread_create(cpu->thread, thread_name, dummy_cpu_thread_fn, cpu, QEMU_THREAD_JOINABLE); +#ifdef _WIN32 + qemu_sem_init(&cpu->sem, 0); +#endif } diff --git a/accel/meson.build b/accel/meson.build index b9a963cf80..259c35c4c8 100644 --- a/accel/meson.build +++ b/accel/meson.build @@ -16,5 +16,5 @@ dummy_ss.add(files( 'dummy-cpus.c', )) -specific_ss.add_all(when: ['CONFIG_SOFTMMU', 'CONFIG_POSIX'], if_true: dummy_ss) +specific_ss.add_all(when: ['CONFIG_SOFTMMU'], if_true: dummy_ss) specific_ss.add_all(when: ['CONFIG_XEN'], if_true: dummy_ss) diff --git a/accel/qtest/meson.build b/accel/qtest/meson.build index 4c65600293..176d990ae1 100644 --- a/accel/qtest/meson.build +++ b/accel/qtest/meson.build @@ -1,2 +1 @@ -qtest_module_ss.add(when: ['CONFIG_SOFTMMU', 'CONFIG_POSIX'], - if_true: files('qtest.c')) +qtest_module_ss.add(when: ['CONFIG_SOFTMMU'], if_true: files('qtest.c')) diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h index f9b58773f7..8830546121 100644 --- a/include/hw/core/cpu.h +++ b/include/hw/core/cpu.h @@ -333,6 +333,7 @@ struct CPUState { struct QemuThread *thread; #ifdef _WIN32 HANDLE hThread; + QemuSemaphore sem; #endif int thread_id; bool running, has_waiter; diff --git a/softmmu/cpus.c b/softmmu/cpus.c index 61b27ff59d..9dd1a4dc17 100644 --- a/softmmu/cpus.c +++ b/softmmu/cpus.c @@ -437,18 +437,19 @@ void qemu_wait_io_event(CPUState *cpu) void cpus_kick_thread(CPUState *cpu) { -#ifndef _WIN32 - int err; - if (cpu->thread_kicked) { return; } cpu->thread_kicked = true; - err = pthread_kill(cpu->thread->thread, SIG_IPI); + +#ifndef _WIN32 + int err = pthread_kill(cpu->thread->thread, SIG_IPI); if (err && err != ESRCH) { fprintf(stderr, "qemu:%s: %s", __func__, strerror(err)); exit(1); } +#else + qemu_sem_post(&cpu->sem); #endif } From 84c662d2546feda2aeac21d09d4c71e8658062c0 Mon Sep 17 00:00:00 2001 From: Xuzhou Cheng Date: Fri, 28 Oct 2022 12:57:27 +0800 Subject: [PATCH 329/705] tests/qtest: Use send/recv for socket communication MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Socket communication in the libqtest and libqmp codes uses read() and write() which work on any file descriptor on *nix, and sockets in *nix are an example of a file descriptor. However sockets on Windows do not use *nix-style file descriptors, so read() and write() cannot be used on sockets on Windows. Switch over to use send() and recv() instead which work on both Windows and *nix. Signed-off-by: Xuzhou Cheng Signed-off-by: Bin Meng Reviewed-by: Marc-André Lureau Message-Id: <20221028045736.679903-3-bin.meng@windriver.com> Signed-off-by: Thomas Huth --- include/qemu/sockets.h | 13 +++++++++++++ tests/qtest/libqmp.c | 5 +++-- tests/qtest/libqtest.c | 5 +++-- util/osdep.c | 22 ++++++++++++++++++++++ 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h index 036745e586..61648f3f3c 100644 --- a/include/qemu/sockets.h +++ b/include/qemu/sockets.h @@ -33,6 +33,19 @@ int qemu_socketpair(int domain, int type, int protocol, int sv[2]); #endif int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen); +/* + * A variant of send(2) which handles partial send. + * + * Return the number of bytes transferred over the socket. + * Set errno if fewer than `count' bytes are sent. + * + * This function don't work with non-blocking socket's. + * Any of the possibilities with non-blocking socket's is bad: + * - return a short write (then name is wrong) + * - busy wait adding (errno == EAGAIN) to the loop + */ +ssize_t qemu_send_full(int s, const void *buf, size_t count) + G_GNUC_WARN_UNUSED_RESULT; int socket_set_cork(int fd, int v); int socket_set_nodelay(int fd); void qemu_socket_set_block(int fd); diff --git a/tests/qtest/libqmp.c b/tests/qtest/libqmp.c index ade26c15f0..2b08382e5d 100644 --- a/tests/qtest/libqmp.c +++ b/tests/qtest/libqmp.c @@ -23,6 +23,7 @@ #endif #include "qemu/cutils.h" +#include "qemu/sockets.h" #include "qapi/error.h" #include "qapi/qmp/json-parser.h" #include "qapi/qmp/qjson.h" @@ -36,7 +37,7 @@ typedef struct { static void socket_send(int fd, const char *buf, size_t size) { - size_t res = qemu_write_full(fd, buf, size); + ssize_t res = qemu_send_full(fd, buf, size); assert(res == size); } @@ -69,7 +70,7 @@ QDict *qmp_fd_receive(int fd) ssize_t len; char c; - len = read(fd, &c, 1); + len = recv(fd, &c, 1, 0); if (len == -1 && errno == EINTR) { continue; } diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c index b23eb3edc3..b01846fd98 100644 --- a/tests/qtest/libqtest.c +++ b/tests/qtest/libqtest.c @@ -27,6 +27,7 @@ #include "libqmp.h" #include "qemu/ctype.h" #include "qemu/cutils.h" +#include "qemu/sockets.h" #include "qapi/qmp/qdict.h" #include "qapi/qmp/qjson.h" #include "qapi/qmp/qlist.h" @@ -428,7 +429,7 @@ void qtest_quit(QTestState *s) static void socket_send(int fd, const char *buf, size_t size) { - size_t res = qemu_write_full(fd, buf, size); + ssize_t res = qemu_send_full(fd, buf, size); assert(res == size); } @@ -460,7 +461,7 @@ static GString *qtest_client_socket_recv_line(QTestState *s) ssize_t len; char buffer[1024]; - len = read(s->fd, buffer, sizeof(buffer)); + len = recv(s->fd, buffer, sizeof(buffer), 0); if (len == -1 && errno == EINTR) { continue; } diff --git a/util/osdep.c b/util/osdep.c index 746d5f7d71..77c1a6c562 100644 --- a/util/osdep.c +++ b/util/osdep.c @@ -502,6 +502,28 @@ int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen) return ret; } +ssize_t qemu_send_full(int s, const void *buf, size_t count) +{ + ssize_t ret = 0; + ssize_t total = 0; + + while (count) { + ret = send(s, buf, count, 0); + if (ret < 0) { + if (errno == EINTR) { + continue; + } + break; + } + + count -= ret; + buf += ret; + total += ret; + } + + return total; +} + void qemu_set_hw_version(const char *version) { hw_version = version; From b1d3095ccf61e4d1bd1d6273b9b7060fe7f20934 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Fri, 28 Oct 2022 12:57:28 +0800 Subject: [PATCH 330/705] tests/qtest: Support libqtest to build and run on Windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At present the libqtest codes were written to depend on several POSIX APIs, including fork(), kill() and waitpid(). Unfortunately these APIs are not available on Windows. This commit implements the corresponding functionalities using win32 native APIs. With this change, all qtest cases can build successfully on a Windows host, and we can start qtest testing on Windows now. Signed-off-by: Xuzhou Cheng Signed-off-by: Bin Meng Reviewed-by: Marc-André Lureau Message-Id: <20221028045736.679903-4-bin.meng@windriver.com> Signed-off-by: Thomas Huth --- tests/qtest/libqtest.c | 96 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 94 insertions(+), 2 deletions(-) diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c index b01846fd98..d12a604d78 100644 --- a/tests/qtest/libqtest.c +++ b/tests/qtest/libqtest.c @@ -16,9 +16,11 @@ #include "qemu/osdep.h" +#ifndef _WIN32 #include #include #include +#endif /* _WIN32 */ #ifdef __linux__ #include #endif /* __linux__ */ @@ -36,6 +38,16 @@ #define MAX_IRQ 256 #define SOCKET_TIMEOUT 50 +#ifndef _WIN32 +# define CMD_EXEC "exec " +# define DEV_STDERR "/dev/fd/2" +# define DEV_NULL "/dev/null" +#else +# define CMD_EXEC "" +# define DEV_STDERR "2" +# define DEV_NULL "nul" +#endif + typedef void (*QTestSendFn)(QTestState *s, const char *buf); typedef void (*ExternalSendFn)(void *s, const char *buf); typedef GString* (*QTestRecvFn)(QTestState *); @@ -58,6 +70,9 @@ struct QTestState int qmp_fd; pid_t qemu_pid; /* our child QEMU process */ int wstatus; +#ifdef _WIN32 + DWORD exit_code; +#endif int expected_status; bool big_endian; bool irq_level[MAX_IRQ]; @@ -119,10 +134,18 @@ bool qtest_probe_child(QTestState *s) pid_t pid = s->qemu_pid; if (pid != -1) { +#ifndef _WIN32 pid = waitpid(pid, &s->wstatus, WNOHANG); if (pid == 0) { return true; } +#else + GetExitCodeProcess((HANDLE)pid, &s->exit_code); + if (s->exit_code == STILL_ACTIVE) { + return true; + } + CloseHandle((HANDLE)pid); +#endif s->qemu_pid = -1; } return false; @@ -136,13 +159,25 @@ void qtest_set_expected_status(QTestState *s, int status) void qtest_kill_qemu(QTestState *s) { pid_t pid = s->qemu_pid; +#ifndef _WIN32 int wstatus; +#else + DWORD ret; +#endif /* Skip wait if qtest_probe_child already reaped. */ if (pid != -1) { +#ifndef _WIN32 kill(pid, SIGTERM); TFR(pid = waitpid(s->qemu_pid, &s->wstatus, 0)); assert(pid == s->qemu_pid); +#else + TerminateProcess((HANDLE)pid, s->expected_status); + ret = WaitForSingleObject((HANDLE)pid, INFINITE); + assert(ret == WAIT_OBJECT_0); + GetExitCodeProcess((HANDLE)pid, &s->exit_code); + CloseHandle((HANDLE)pid); +#endif s->qemu_pid = -1; } @@ -150,6 +185,7 @@ void qtest_kill_qemu(QTestState *s) * Check whether qemu exited with expected exit status; anything else is * fishy and should be logged with as much detail as possible. */ +#ifndef _WIN32 wstatus = s->wstatus; if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus) != s->expected_status) { fprintf(stderr, "%s:%d: kill_qemu() tried to terminate QEMU " @@ -166,6 +202,14 @@ void qtest_kill_qemu(QTestState *s) __FILE__, __LINE__, sig, signame, dump); abort(); } +#else + if (s->exit_code != s->expected_status) { + fprintf(stderr, "%s:%d: kill_qemu() tried to terminate QEMU " + "process but encountered exit status %ld (expected %d)\n", + __FILE__, __LINE__, s->exit_code, s->expected_status); + abort(); + } +#endif } static void kill_qemu_hook_func(void *s) @@ -244,6 +288,38 @@ static const char *qtest_qemu_binary(void) return qemu_bin; } +#ifdef _WIN32 +static pid_t qtest_create_process(char *cmd) +{ + STARTUPINFO si; + PROCESS_INFORMATION pi; + BOOL ret; + + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + ZeroMemory(&pi, sizeof(pi)); + + ret = CreateProcess(NULL, /* module name */ + cmd, /* command line */ + NULL, /* process handle not inheritable */ + NULL, /* thread handle not inheritable */ + FALSE, /* set handle inheritance to FALSE */ + 0, /* No creation flags */ + NULL, /* use parent's environment block */ + NULL, /* use parent's starting directory */ + &si, /* pointer to STARTUPINFO structure */ + &pi /* pointer to PROCESS_INFORMATION structure */ + ); + if (ret == 0) { + fprintf(stderr, "%s:%d: unable to create a new process (%s)\n", + __FILE__, __LINE__, strerror(GetLastError())); + abort(); + } + + return (pid_t)pi.hProcess; +} +#endif /* _WIN32 */ + QTestState *qtest_init_without_qmp_handshake(const char *extra_args) { QTestState *s; @@ -271,6 +347,7 @@ QTestState *qtest_init_without_qmp_handshake(const char *extra_args) unlink(socket_path); unlink(qmp_socket_path); + socket_init(); sock = init_socket(socket_path); qmpsock = init_socket(qmp_socket_path); @@ -279,7 +356,7 @@ QTestState *qtest_init_without_qmp_handshake(const char *extra_args) qtest_add_abrt_handler(kill_qemu_hook_func, s); - command = g_strdup_printf("exec %s %s" + command = g_strdup_printf(CMD_EXEC "%s %s" "-qtest unix:%s " "-qtest-log %s " "-chardev socket,path=%s,id=char0 " @@ -288,7 +365,7 @@ QTestState *qtest_init_without_qmp_handshake(const char *extra_args) "%s" " -accel qtest", qemu_binary, tracearg, socket_path, - getenv("QTEST_LOG") ? "/dev/fd/2" : "/dev/null", + getenv("QTEST_LOG") ? DEV_STDERR : DEV_NULL, qmp_socket_path, extra_args ?: ""); @@ -297,6 +374,7 @@ QTestState *qtest_init_without_qmp_handshake(const char *extra_args) s->pending_events = NULL; s->wstatus = 0; s->expected_status = 0; +#ifndef _WIN32 s->qemu_pid = fork(); if (s->qemu_pid == 0) { #ifdef __linux__ @@ -319,6 +397,9 @@ QTestState *qtest_init_without_qmp_handshake(const char *extra_args) execlp("/bin/sh", "sh", "-c", command, NULL); exit(1); } +#else + s->qemu_pid = qtest_create_process(command); +#endif /* _WIN32 */ g_free(command); s->fd = socket_accept(sock); @@ -337,9 +418,19 @@ QTestState *qtest_init_without_qmp_handshake(const char *extra_args) s->irq_level[i] = false; } + /* + * Stopping QEMU for debugging is not supported on Windows. + * + * Using DebugActiveProcess() API can suspend the QEMU process, + * but gdb cannot attach to the process. Using the undocumented + * NtSuspendProcess() can suspend the QEMU process and gdb can + * attach to the process, but gdb cannot resume it. + */ +#ifndef _WIN32 if (getenv("QTEST_STOP")) { kill(s->qemu_pid, SIGSTOP); } +#endif /* ask endianness of the target */ @@ -393,6 +484,7 @@ QTestState *qtest_init_with_serial(const char *extra_args, int *sock_fd) g_assert_true(sock_dir != NULL); sock_path = g_strdup_printf("%s/sock", sock_dir); + socket_init(); sock_fd_init = init_socket(sock_path); qts = qtest_initf("-chardev socket,id=s0,path=%s -serial chardev:s0 %s", From e4439e52806b797f38adf7a96b5ed74295f806b0 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Fri, 28 Oct 2022 12:57:29 +0800 Subject: [PATCH 331/705] tests/qtest: device-plug-test: Reverse the usage of double/single quotes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The usage of double/single quotes in test_q35_pci_unplug_json_request() should be reversed to work on both win32 and non-win32 platforms: - The value of -device parameter needs to be surrounded by "" as Windows does not drop '' when passing it to QEMU which causes QEMU command line option parser failure. - The JSON key/value pairs need to be surrounded by '' to make the JSON parser happy on Windows. Fixes: a12f1a7e56b7 ("tests/x86: Add subtest with 'q35' machine type to device-plug-test") Signed-off-by: Bin Meng Reviewed-by: Thomas Huth Reviewed-by: Marc-André Lureau Message-Id: <20221028045736.679903-5-bin.meng@windriver.com> Signed-off-by: Thomas Huth --- tests/qtest/device-plug-test.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/qtest/device-plug-test.c b/tests/qtest/device-plug-test.c index 3f44f731d1..5a6afa2b57 100644 --- a/tests/qtest/device-plug-test.c +++ b/tests/qtest/device-plug-test.c @@ -112,16 +112,16 @@ static void test_pci_unplug_json_request(void) static void test_q35_pci_unplug_json_request(void) { - const char *port = "-device '{\"driver\": \"pcie-root-port\", " - "\"id\": \"p1\"}'"; + const char *port = "-device \"{'driver': 'pcie-root-port', " + "'id': 'p1'}\""; - const char *bridge = "-device '{\"driver\": \"pcie-pci-bridge\", " - "\"id\": \"b1\", " - "\"bus\": \"p1\"}'"; + const char *bridge = "-device \"{'driver': 'pcie-pci-bridge', " + "'id': 'b1', " + "'bus': 'p1'}\""; - const char *device = "-device '{\"driver\": \"virtio-mouse-pci\", " - "\"bus\": \"b1\", " - "\"id\": \"dev0\"}'"; + const char *device = "-device \"{'driver': 'virtio-mouse-pci', " + "'bus': 'b1', " + "'id': 'dev0'}\""; QTestState *qtest = qtest_initf("-machine q35 %s %s %s", port, bridge, device); From 1b0f1b14fe26752d628dd71920f4bb63b79765a4 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Fri, 28 Oct 2022 12:57:30 +0800 Subject: [PATCH 332/705] tests/qtest: Use EXIT_FAILURE instead of magic number MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When migration fails, QEMU exits with a status code EXIT_FAILURE. Change qtests to use the well-defined macro instead of magic number. Signed-off-by: Bin Meng Message-Id: <20221028045736.679903-6-bin.meng@windriver.com> Reviewed-by: Thomas Huth Reviewed-by: Marc-André Lureau Reviewed-by: Juan Quintela Signed-off-by: Thomas Huth --- tests/qtest/dbus-vmstate-test.c | 2 +- tests/qtest/migration-test.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/qtest/dbus-vmstate-test.c b/tests/qtest/dbus-vmstate-test.c index 74ede651f6..6c990864e3 100644 --- a/tests/qtest/dbus-vmstate-test.c +++ b/tests/qtest/dbus-vmstate-test.c @@ -233,7 +233,7 @@ test_dbus_vmstate(Test *test) test->src_qemu = src_qemu; if (test->migrate_fail) { wait_for_migration_fail(src_qemu, true); - qtest_set_expected_status(dst_qemu, 1); + qtest_set_expected_status(dst_qemu, EXIT_FAILURE); } else { wait_for_migration_complete(src_qemu); } diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c index aa1ba179fa..28a06d8170 100644 --- a/tests/qtest/migration-test.c +++ b/tests/qtest/migration-test.c @@ -1342,7 +1342,7 @@ static void test_precopy_common(MigrateCommon *args) wait_for_migration_fail(from, allow_active); if (args->result == MIG_TEST_FAIL_DEST_QUIT_ERR) { - qtest_set_expected_status(to, 1); + qtest_set_expected_status(to, EXIT_FAILURE); } } else { if (args->iterations) { @@ -1738,7 +1738,7 @@ static void do_test_validate_uuid(MigrateStart *args, bool should_fail) migrate_qmp(from, uri, "{}"); if (should_fail) { - qtest_set_expected_status(to, 1); + qtest_set_expected_status(to, EXIT_FAILURE); wait_for_migration_fail(from, true); } else { wait_for_migration_complete(from); From 69c056fbc0cd57b4b2db7b3e823a9f6945756b38 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Fri, 28 Oct 2022 12:57:31 +0800 Subject: [PATCH 333/705] tests/qtest: libqtest: Introduce qtest_wait_qemu() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce an API for qtest to wait for the QEMU process to terminate. Suggested-by: Marc-André Lureau Signed-off-by: Bin Meng Reviewed-by: Marc-André Lureau Message-Id: <20221028045736.679903-7-bin.meng@windriver.com> Signed-off-by: Thomas Huth --- tests/qtest/libqtest.c | 63 +++++++++++++++++++++++++----------------- tests/qtest/libqtest.h | 9 ++++++ 2 files changed, 47 insertions(+), 25 deletions(-) diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c index d12a604d78..e1e2d39a6e 100644 --- a/tests/qtest/libqtest.c +++ b/tests/qtest/libqtest.c @@ -156,37 +156,14 @@ void qtest_set_expected_status(QTestState *s, int status) s->expected_status = status; } -void qtest_kill_qemu(QTestState *s) +static void qtest_check_status(QTestState *s) { - pid_t pid = s->qemu_pid; -#ifndef _WIN32 - int wstatus; -#else - DWORD ret; -#endif - - /* Skip wait if qtest_probe_child already reaped. */ - if (pid != -1) { -#ifndef _WIN32 - kill(pid, SIGTERM); - TFR(pid = waitpid(s->qemu_pid, &s->wstatus, 0)); - assert(pid == s->qemu_pid); -#else - TerminateProcess((HANDLE)pid, s->expected_status); - ret = WaitForSingleObject((HANDLE)pid, INFINITE); - assert(ret == WAIT_OBJECT_0); - GetExitCodeProcess((HANDLE)pid, &s->exit_code); - CloseHandle((HANDLE)pid); -#endif - s->qemu_pid = -1; - } - /* * Check whether qemu exited with expected exit status; anything else is * fishy and should be logged with as much detail as possible. */ #ifndef _WIN32 - wstatus = s->wstatus; + int wstatus = s->wstatus; if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus) != s->expected_status) { fprintf(stderr, "%s:%d: kill_qemu() tried to terminate QEMU " "process but encountered exit status %d (expected %d)\n", @@ -212,6 +189,42 @@ void qtest_kill_qemu(QTestState *s) #endif } +void qtest_wait_qemu(QTestState *s) +{ +#ifndef _WIN32 + pid_t pid; + + TFR(pid = waitpid(s->qemu_pid, &s->wstatus, 0)); + assert(pid == s->qemu_pid); +#else + DWORD ret; + + ret = WaitForSingleObject((HANDLE)s->qemu_pid, INFINITE); + assert(ret == WAIT_OBJECT_0); + GetExitCodeProcess((HANDLE)s->qemu_pid, &s->exit_code); + CloseHandle((HANDLE)s->qemu_pid); +#endif + + qtest_check_status(s); +} + +void qtest_kill_qemu(QTestState *s) +{ + /* Skip wait if qtest_probe_child() already reaped */ + if (s->qemu_pid != -1) { +#ifndef _WIN32 + kill(s->qemu_pid, SIGTERM); +#else + TerminateProcess((HANDLE)s->qemu_pid, s->expected_status); +#endif + qtest_wait_qemu(s); + s->qemu_pid = -1; + return; + } + + qtest_check_status(s); +} + static void kill_qemu_hook_func(void *s) { qtest_kill_qemu(s); diff --git a/tests/qtest/libqtest.h b/tests/qtest/libqtest.h index 65c040e504..91a5f7edd9 100644 --- a/tests/qtest/libqtest.h +++ b/tests/qtest/libqtest.h @@ -75,6 +75,15 @@ QTestState *qtest_init_without_qmp_handshake(const char *extra_args); */ QTestState *qtest_init_with_serial(const char *extra_args, int *sock_fd); +/** + * qtest_wait_qemu: + * @s: #QTestState instance to operate on. + * + * Wait for the QEMU process to terminate. It is safe to call this function + * multiple times. + */ +void qtest_wait_qemu(QTestState *s); + /** * qtest_kill_qemu: * @s: #QTestState instance to operate on. From f2d063e61ee2026700ab44bef967f663e976bec8 Mon Sep 17 00:00:00 2001 From: Xuzhou Cheng Date: Fri, 28 Oct 2022 12:57:32 +0800 Subject: [PATCH 334/705] tests/qtest: migration-test: Make sure QEMU process "to" exited after migration is canceled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure QEMU process "to" exited before launching another target for migration in the test_multifd_tcp_cancel case. Signed-off-by: Xuzhou Cheng Signed-off-by: Bin Meng Reviewed-by: Marc-André Lureau Message-Id: <20221028045736.679903-8-bin.meng@windriver.com> Signed-off-by: Thomas Huth --- tests/qtest/migration-test.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c index 28a06d8170..d2eb107f0c 100644 --- a/tests/qtest/migration-test.c +++ b/tests/qtest/migration-test.c @@ -2141,6 +2141,10 @@ static void test_multifd_tcp_cancel(void) migrate_cancel(from); + /* Make sure QEMU process "to" exited */ + qtest_set_expected_status(to, EXIT_FAILURE); + qtest_wait_qemu(to); + args = (MigrateStart){ .only_target = true, }; From 8aff9c3279087b8527fd2c3dd4cf0706892887ba Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Fri, 28 Oct 2022 12:57:33 +0800 Subject: [PATCH 335/705] tests/qtest: libqos: Do not build virtio-9p unconditionally MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At present the virtio-9p related codes are built into libqos unconditionally. Change to build them conditionally by testing the 'virtfs' config option. Signed-off-by: Bin Meng Reviewed-by: Thomas Huth Reviewed-by: Marc-André Lureau Message-Id: <20221028045736.679903-9-bin.meng@windriver.com> Signed-off-by: Thomas Huth --- tests/qtest/libqos/meson.build | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/qtest/libqos/meson.build b/tests/qtest/libqos/meson.build index 113c80b4e4..32f028872c 100644 --- a/tests/qtest/libqos/meson.build +++ b/tests/qtest/libqos/meson.build @@ -33,8 +33,6 @@ libqos_srcs = files( 'sdhci.c', 'tpci200.c', 'virtio.c', - 'virtio-9p.c', - 'virtio-9p-client.c', 'virtio-balloon.c', 'virtio-blk.c', 'vhost-user-blk.c', @@ -62,6 +60,10 @@ libqos_srcs = files( 'x86_64_pc-machine.c', ) +if have_virtfs + libqos_srcs += files('virtio-9p.c', 'virtio-9p-client.c') +endif + libqos = static_library('qos', libqos_srcs + genh, name_suffix: 'fa', build_by_default: false) From db8fca024fa98241ed40470f87b8ecfb82c57d32 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Fri, 28 Oct 2022 12:57:34 +0800 Subject: [PATCH 336/705] tests/qtest: libqtest: Correct the timeout unit of blocking receive calls for win32 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some qtest cases don't get response from the QEMU executable under test in time on Windows. It turns out that the socket receive call got timeout before it receive the complete response. The timeout value is supposed to be set to 50 seconds via the setsockopt() call, but there is a difference among platforms. The timeout unit of blocking receive calls is measured in seconds on non-Windows platforms but milliseconds on Windows. Signed-off-by: Bin Meng Reviewed-by: Marc-André Lureau Message-Id: <20221028045736.679903-10-bin.meng@windriver.com> Signed-off-by: Thomas Huth --- tests/qtest/libqtest.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c index e1e2d39a6e..2fbc3b88f3 100644 --- a/tests/qtest/libqtest.c +++ b/tests/qtest/libqtest.c @@ -36,13 +36,14 @@ #include "qapi/qmp/qstring.h" #define MAX_IRQ 256 -#define SOCKET_TIMEOUT 50 #ifndef _WIN32 +# define SOCKET_TIMEOUT 50 # define CMD_EXEC "exec " # define DEV_STDERR "/dev/fd/2" # define DEV_NULL "/dev/null" #else +# define SOCKET_TIMEOUT 50000 # define CMD_EXEC "" # define DEV_STDERR "2" # define DEV_NULL "nul" @@ -106,8 +107,16 @@ static int socket_accept(int sock) struct sockaddr_un addr; socklen_t addrlen; int ret; + /* + * timeout unit of blocking receive calls is different among platfoms. + * It's in seconds on non-Windows platforms but milliseconds on Windows. + */ +#ifndef _WIN32 struct timeval timeout = { .tv_sec = SOCKET_TIMEOUT, .tv_usec = 0 }; +#else + DWORD timeout = SOCKET_TIMEOUT; +#endif if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (void *)&timeout, sizeof(timeout))) { From 4f93f071ca9e7f85f976c805142d33f6cffd2745 Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Thu, 6 Oct 2022 17:06:49 -0300 Subject: [PATCH 337/705] target/ppc: fix msgclr/msgsnd insns flags On Power ISA v2.07, the category for these instructions became "Embedded.Processor Control" or "Book S". Signed-off-by: Matheus Ferst Reviewed-by: Fabiano Rosas Message-Id: <20221006200654.725390-2-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/translate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 7228857e23..b5d80fd13d 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -6902,9 +6902,9 @@ GEN_HANDLER2_E(tlbivax_booke206, "tlbivax", 0x1F, 0x12, 0x18, 0x00000001, GEN_HANDLER2_E(tlbilx_booke206, "tlbilx", 0x1F, 0x12, 0x00, 0x03800001, PPC_NONE, PPC2_BOOKE206), GEN_HANDLER2_E(msgsnd, "msgsnd", 0x1F, 0x0E, 0x06, 0x03ff0001, - PPC_NONE, PPC2_PRCNTL), + PPC_NONE, (PPC2_PRCNTL | PPC2_ISA207S)), GEN_HANDLER2_E(msgclr, "msgclr", 0x1F, 0x0E, 0x07, 0x03ff0001, - PPC_NONE, PPC2_PRCNTL), + PPC_NONE, (PPC2_PRCNTL | PPC2_ISA207S)), GEN_HANDLER2_E(msgsync, "msgsync", 0x1F, 0x16, 0x1B, 0x00000000, PPC_NONE, PPC2_PRCNTL), GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE), From 9d950c724144770d9d092f70716da0da022926de Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Thu, 6 Oct 2022 17:06:50 -0300 Subject: [PATCH 338/705] target/ppc: fix msgsync insns flags This instruction was added by Power ISA 3.0, using PPC2_PRCNTL makes it available for older processors, like de e5500 and e6500. Fixes: 7af1e7b02264 ("target/ppc: add support for hypervisor doorbells on book3s CPUs") Signed-off-by: Matheus Ferst Reviewed-by: Fabiano Rosas Message-Id: <20221006200654.725390-3-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/translate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/ppc/translate.c b/target/ppc/translate.c index b5d80fd13d..ccf2ffd567 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -6906,7 +6906,7 @@ GEN_HANDLER2_E(msgsnd, "msgsnd", 0x1F, 0x0E, 0x06, 0x03ff0001, GEN_HANDLER2_E(msgclr, "msgclr", 0x1F, 0x0E, 0x07, 0x03ff0001, PPC_NONE, (PPC2_PRCNTL | PPC2_ISA207S)), GEN_HANDLER2_E(msgsync, "msgsync", 0x1F, 0x16, 0x1B, 0x00000000, - PPC_NONE, PPC2_PRCNTL), + PPC_NONE, PPC2_ISA300), GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE), GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000E7C01, PPC_WRTEE), GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC), From e8db3cc76e9555c482ee92743bcf3560e25b1424 Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Thu, 6 Oct 2022 17:06:51 -0300 Subject: [PATCH 339/705] target/ppc: fix REQUIRE_HV macro definition The macro is missing a '{' after the if condition. Any use of REQUIRE_HV would cause a compilation error. Fixes: fc34e81acd51 ("target/ppc: add macros to check privilege level") Signed-off-by: Matheus Ferst Reviewed-by: Fabiano Rosas Message-Id: <20221006200654.725390-4-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/translate.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/target/ppc/translate.c b/target/ppc/translate.c index ccf2ffd567..f73ff2d2ee 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -6545,12 +6545,12 @@ static int64_t dw_compose_ea(DisasContext *ctx, int x) } \ } while (0) -#define REQUIRE_HV(CTX) \ - do { \ - if (unlikely((CTX)->pr || !(CTX)->hv)) \ - gen_priv_opc(CTX); \ - return true; \ - } \ +#define REQUIRE_HV(CTX) \ + do { \ + if (unlikely((CTX)->pr || !(CTX)->hv)) { \ + gen_priv_opc(CTX); \ + return true; \ + } \ } while (0) #else #define REQUIRE_SV(CTX) do { gen_priv_opc(CTX); return true; } while (0) From 98f43417b66457eb9c207a2a09e0eef984dadc41 Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Thu, 6 Oct 2022 17:06:52 -0300 Subject: [PATCH 340/705] target/ppc: move msgclr/msgsnd to decodetree Signed-off-by: Matheus Ferst Reviewed-by: Daniel Henrique Barboza Message-Id: <20221006200654.725390-5-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/insn32.decode | 5 ++ target/ppc/translate.c | 34 +-------- .../ppc/translate/processor-ctrl-impl.c.inc | 70 +++++++++++++++++++ 3 files changed, 77 insertions(+), 32 deletions(-) create mode 100644 target/ppc/translate/processor-ctrl-impl.c.inc diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index a5249ee32c..bba49ded1b 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -908,3 +908,8 @@ SLBSYNC 011111 ----- ----- ----- 0101010010 - TLBIE 011111 ..... - .. . . ..... 0100110010 - @X_tlbie TLBIEL 011111 ..... - .. . . ..... 0100010010 - @X_tlbie + +# Processor Control Instructions + +MSGCLR 011111 ----- ----- ..... 0011101110 - @X_rb +MSGSND 011111 ----- ----- ..... 0011001110 - @X_rb diff --git a/target/ppc/translate.c b/target/ppc/translate.c index f73ff2d2ee..231bc9551e 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -6241,34 +6241,6 @@ static void gen_icbt_440(DisasContext *ctx) /* Embedded.Processor Control */ -static void gen_msgclr(DisasContext *ctx) -{ -#if defined(CONFIG_USER_ONLY) - GEN_PRIV(ctx); -#else - CHK_HV(ctx); - if (is_book3s_arch2x(ctx)) { - gen_helper_book3s_msgclr(cpu_env, cpu_gpr[rB(ctx->opcode)]); - } else { - gen_helper_msgclr(cpu_env, cpu_gpr[rB(ctx->opcode)]); - } -#endif /* defined(CONFIG_USER_ONLY) */ -} - -static void gen_msgsnd(DisasContext *ctx) -{ -#if defined(CONFIG_USER_ONLY) - GEN_PRIV(ctx); -#else - CHK_HV(ctx); - if (is_book3s_arch2x(ctx)) { - gen_helper_book3s_msgsnd(cpu_gpr[rB(ctx->opcode)]); - } else { - gen_helper_msgsnd(cpu_gpr[rB(ctx->opcode)]); - } -#endif /* defined(CONFIG_USER_ONLY) */ -} - #if defined(TARGET_PPC64) static void gen_msgclrp(DisasContext *ctx) { @@ -6628,6 +6600,8 @@ static bool resolve_PLS_D(DisasContext *ctx, arg_D *d, arg_PLS_D *a) #include "translate/branch-impl.c.inc" +#include "translate/processor-ctrl-impl.c.inc" + #include "translate/storage-ctrl-impl.c.inc" /* Handles lfdp */ @@ -6901,10 +6875,6 @@ GEN_HANDLER2_E(tlbivax_booke206, "tlbivax", 0x1F, 0x12, 0x18, 0x00000001, PPC_NONE, PPC2_BOOKE206), GEN_HANDLER2_E(tlbilx_booke206, "tlbilx", 0x1F, 0x12, 0x00, 0x03800001, PPC_NONE, PPC2_BOOKE206), -GEN_HANDLER2_E(msgsnd, "msgsnd", 0x1F, 0x0E, 0x06, 0x03ff0001, - PPC_NONE, (PPC2_PRCNTL | PPC2_ISA207S)), -GEN_HANDLER2_E(msgclr, "msgclr", 0x1F, 0x0E, 0x07, 0x03ff0001, - PPC_NONE, (PPC2_PRCNTL | PPC2_ISA207S)), GEN_HANDLER2_E(msgsync, "msgsync", 0x1F, 0x16, 0x1B, 0x00000000, PPC_NONE, PPC2_ISA300), GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE), diff --git a/target/ppc/translate/processor-ctrl-impl.c.inc b/target/ppc/translate/processor-ctrl-impl.c.inc new file mode 100644 index 0000000000..208f2c2391 --- /dev/null +++ b/target/ppc/translate/processor-ctrl-impl.c.inc @@ -0,0 +1,70 @@ +/* + * Power ISA decode for Storage Control instructions + * + * Copyright (c) 2022 Instituto de Pesquisas Eldorado (eldorado.org.br) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Processor Control Instructions + */ + +static bool trans_MSGCLR(DisasContext *ctx, arg_X_rb *a) +{ + if (!(ctx->insns_flags2 & PPC2_ISA207S)) { + /* + * Before Power ISA 2.07, processor control instructions were only + * implemented in the "Embedded.Processor Control" category. + */ + REQUIRE_INSNS_FLAGS2(ctx, PRCNTL); + } + + REQUIRE_HV(ctx); + +#if !defined(CONFIG_USER_ONLY) + if (is_book3s_arch2x(ctx)) { + gen_helper_book3s_msgclr(cpu_env, cpu_gpr[a->rb]); + } else { + gen_helper_msgclr(cpu_env, cpu_gpr[a->rb]); + } +#else + qemu_build_not_reached(); +#endif + return true; +} + +static bool trans_MSGSND(DisasContext *ctx, arg_X_rb *a) +{ + if (!(ctx->insns_flags2 & PPC2_ISA207S)) { + /* + * Before Power ISA 2.07, processor control instructions were only + * implemented in the "Embedded.Processor Control" category. + */ + REQUIRE_INSNS_FLAGS2(ctx, PRCNTL); + } + + REQUIRE_HV(ctx); + +#if !defined(CONFIG_USER_ONLY) + if (is_book3s_arch2x(ctx)) { + gen_helper_book3s_msgsnd(cpu_gpr[a->rb]); + } else { + gen_helper_msgsnd(cpu_gpr[a->rb]); + } +#else + qemu_build_not_reached(); +#endif + return true; +} From e8e09d7da7dd572e6cf62b2f12b65fb9833cf7ba Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Thu, 6 Oct 2022 17:06:53 -0300 Subject: [PATCH 341/705] target/ppc: move msgclrp/msgsndp to decodetree Signed-off-by: Matheus Ferst Reviewed-by: Daniel Henrique Barboza Message-Id: <20221006200654.725390-6-matheus.ferst@eldorado.org.br> [danielhb: ppc32 build fix in trans_(MSGCLRP|MSGSNDP)] Signed-off-by: Daniel Henrique Barboza --- target/ppc/insn32.decode | 2 ++ target/ppc/translate.c | 26 ------------------- .../ppc/translate/processor-ctrl-impl.c.inc | 26 +++++++++++++++++++ 3 files changed, 28 insertions(+), 26 deletions(-) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index bba49ded1b..5ba4a6807d 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -913,3 +913,5 @@ TLBIEL 011111 ..... - .. . . ..... 0100010010 - @X_tlbie MSGCLR 011111 ----- ----- ..... 0011101110 - @X_rb MSGSND 011111 ----- ----- ..... 0011001110 - @X_rb +MSGCLRP 011111 ----- ----- ..... 0010101110 - @X_rb +MSGSNDP 011111 ----- ----- ..... 0010001110 - @X_rb diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 231bc9551e..9e200cec24 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -6241,28 +6241,6 @@ static void gen_icbt_440(DisasContext *ctx) /* Embedded.Processor Control */ -#if defined(TARGET_PPC64) -static void gen_msgclrp(DisasContext *ctx) -{ -#if defined(CONFIG_USER_ONLY) - GEN_PRIV(ctx); -#else - CHK_SV(ctx); - gen_helper_book3s_msgclrp(cpu_env, cpu_gpr[rB(ctx->opcode)]); -#endif /* defined(CONFIG_USER_ONLY) */ -} - -static void gen_msgsndp(DisasContext *ctx) -{ -#if defined(CONFIG_USER_ONLY) - GEN_PRIV(ctx); -#else - CHK_SV(ctx); - gen_helper_book3s_msgsndp(cpu_env, cpu_gpr[rB(ctx->opcode)]); -#endif /* defined(CONFIG_USER_ONLY) */ -} -#endif - static void gen_msgsync(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) @@ -6896,10 +6874,6 @@ GEN_HANDLER(vmladduhm, 0x04, 0x11, 0xFF, 0x00000000, PPC_ALTIVEC), GEN_HANDLER_E(maddhd_maddhdu, 0x04, 0x18, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA300), GEN_HANDLER_E(maddld, 0x04, 0x19, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA300), -GEN_HANDLER2_E(msgsndp, "msgsndp", 0x1F, 0x0E, 0x04, 0x03ff0001, - PPC_NONE, PPC2_ISA207S), -GEN_HANDLER2_E(msgclrp, "msgclrp", 0x1F, 0x0E, 0x05, 0x03ff0001, - PPC_NONE, PPC2_ISA207S), #endif #undef GEN_INT_ARITH_ADD diff --git a/target/ppc/translate/processor-ctrl-impl.c.inc b/target/ppc/translate/processor-ctrl-impl.c.inc index 208f2c2391..d704a322a8 100644 --- a/target/ppc/translate/processor-ctrl-impl.c.inc +++ b/target/ppc/translate/processor-ctrl-impl.c.inc @@ -68,3 +68,29 @@ static bool trans_MSGSND(DisasContext *ctx, arg_X_rb *a) #endif return true; } + +static bool trans_MSGCLRP(DisasContext *ctx, arg_X_rb *a) +{ + REQUIRE_64BIT(ctx); + REQUIRE_INSNS_FLAGS2(ctx, ISA207S); + REQUIRE_SV(ctx); +#if !defined(CONFIG_USER_ONLY) && defined(TARGET_PPC64) + gen_helper_book3s_msgclrp(cpu_env, cpu_gpr[a->rb]); +#else + qemu_build_not_reached(); +#endif + return true; +} + +static bool trans_MSGSNDP(DisasContext *ctx, arg_X_rb *a) +{ + REQUIRE_64BIT(ctx); + REQUIRE_INSNS_FLAGS2(ctx, ISA207S); + REQUIRE_SV(ctx); +#if !defined(CONFIG_USER_ONLY) && defined(TARGET_PPC64) + gen_helper_book3s_msgsndp(cpu_env, cpu_gpr[a->rb]); +#else + qemu_build_not_reached(); +#endif + return true; +} From b35bf5f2d759d97652b4acd96e62329a1657f3cb Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Thu, 6 Oct 2022 17:06:54 -0300 Subject: [PATCH 342/705] target/ppc: move msgsync to decodetree Signed-off-by: Matheus Ferst Reviewed-by: Daniel Henrique Barboza Message-Id: <20221006200654.725390-7-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/insn32.decode | 1 + target/ppc/translate.c | 14 -------------- target/ppc/translate/processor-ctrl-impl.c.inc | 9 +++++++++ 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 5ba4a6807d..70a3b4de5e 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -915,3 +915,4 @@ MSGCLR 011111 ----- ----- ..... 0011101110 - @X_rb MSGSND 011111 ----- ----- ..... 0011001110 - @X_rb MSGCLRP 011111 ----- ----- ..... 0010101110 - @X_rb MSGSNDP 011111 ----- ----- ..... 0010001110 - @X_rb +MSGSYNC 011111 ----- ----- ----- 1101110110 - diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 9e200cec24..959e7e3475 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -6239,18 +6239,6 @@ static void gen_icbt_440(DisasContext *ctx) */ } -/* Embedded.Processor Control */ - -static void gen_msgsync(DisasContext *ctx) -{ -#if defined(CONFIG_USER_ONLY) - GEN_PRIV(ctx); -#else - CHK_HV(ctx); -#endif /* defined(CONFIG_USER_ONLY) */ - /* interpreted as no-op */ -} - #if defined(TARGET_PPC64) static void gen_maddld(DisasContext *ctx) { @@ -6853,8 +6841,6 @@ GEN_HANDLER2_E(tlbivax_booke206, "tlbivax", 0x1F, 0x12, 0x18, 0x00000001, PPC_NONE, PPC2_BOOKE206), GEN_HANDLER2_E(tlbilx_booke206, "tlbilx", 0x1F, 0x12, 0x00, 0x03800001, PPC_NONE, PPC2_BOOKE206), -GEN_HANDLER2_E(msgsync, "msgsync", 0x1F, 0x16, 0x1B, 0x00000000, - PPC_NONE, PPC2_ISA300), GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE), GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000E7C01, PPC_WRTEE), GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC), diff --git a/target/ppc/translate/processor-ctrl-impl.c.inc b/target/ppc/translate/processor-ctrl-impl.c.inc index d704a322a8..cc7a50d579 100644 --- a/target/ppc/translate/processor-ctrl-impl.c.inc +++ b/target/ppc/translate/processor-ctrl-impl.c.inc @@ -94,3 +94,12 @@ static bool trans_MSGSNDP(DisasContext *ctx, arg_X_rb *a) #endif return true; } + +static bool trans_MSGSYNC(DisasContext *ctx, arg_MSGSYNC *a) +{ + REQUIRE_INSNS_FLAGS2(ctx, ISA300); + REQUIRE_HV(ctx); + + /* interpreted as no-op */ + return true; +} From dc46167a2225d3c0861cd4fcbc350e3e0e89bc61 Mon Sep 17 00:00:00 2001 From: "Lucas Mateus Castro (alqotel)" Date: Wed, 19 Oct 2022 09:50:29 -0300 Subject: [PATCH 343/705] target/ppc: Moved VMLADDUHM to decodetree and use gvec This patch moves VMLADDUHM to decodetree a creates a gvec implementation using mul_vec and add_vec. rept loop master patch 8 12500 0,01810500 0,00903100 (-50.1%) 25 4000 0,01739400 0,00747700 (-57.0%) 100 1000 0,01843600 0,00901400 (-51.1%) 500 200 0,02574600 0,01971000 (-23.4%) 2500 40 0,05921600 0,07121800 (+20.3%) 8000 12 0,15326700 0,21725200 (+41.7%) The significant difference in performance when REPT is low and LOOP is high I think is due to the fact that the new implementation has a higher translation time, as when using a helper only 5 TCGop are used but with the patch a total of 10 TCGop are needed (Power lacks a direct mul_vec equivalent so this instruction is implemented with the help of 5 others, vmuleu, vmulou, vmrgh, vmrgl and vpkum). Signed-off-by: Lucas Mateus Castro (alqotel) Reviewed-by: Richard Henderson Message-Id: <20221019125040.48028-2-lucas.araujo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/helper.h | 2 +- target/ppc/insn32.decode | 2 ++ target/ppc/int_helper.c | 3 +- target/ppc/translate.c | 1 - target/ppc/translate/vmx-impl.c.inc | 48 ++++++++++++++++++----------- 5 files changed, 35 insertions(+), 21 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 57eee07256..9c562ab00e 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -264,7 +264,7 @@ DEF_HELPER_FLAGS_4(VMSUMUHM, TCG_CALL_NO_RWG, void, avr, avr, avr, avr) DEF_HELPER_5(VMSUMUHS, void, env, avr, avr, avr, avr) DEF_HELPER_FLAGS_4(VMSUMSHM, TCG_CALL_NO_RWG, void, avr, avr, avr, avr) DEF_HELPER_5(VMSUMSHS, void, env, avr, avr, avr, avr) -DEF_HELPER_FLAGS_4(vmladduhm, TCG_CALL_NO_RWG, void, avr, avr, avr, avr) +DEF_HELPER_FLAGS_5(VMLADDUHM, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) DEF_HELPER_FLAGS_2(mtvscr, TCG_CALL_NO_RWG, void, env, i32) DEF_HELPER_FLAGS_1(mfvscr, TCG_CALL_NO_RWG, i32, env) DEF_HELPER_3(lvebx, void, env, avr, tl) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 70a3b4de5e..9ba1689230 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -693,6 +693,8 @@ VMSUMUHS 000100 ..... ..... ..... ..... 100111 @VA VMSUMCUD 000100 ..... ..... ..... ..... 010111 @VA VMSUMUDM 000100 ..... ..... ..... ..... 100011 @VA +VMLADDUHM 000100 ..... ..... ..... ..... 100010 @VA + ## Vector String Instructions VSTRIBL 000100 ..... 00000 ..... . 0000001101 @VX_tb_rc diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index 696096100b..0d25000b2a 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -974,7 +974,8 @@ void helper_vmhraddshs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, } } -void helper_vmladduhm(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) +void helper_VMLADDUHM(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c, + uint32_t v) { int i; diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 959e7e3475..58fbc15954 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -6855,7 +6855,6 @@ GEN_HANDLER(lvsl, 0x1f, 0x06, 0x00, 0x00000001, PPC_ALTIVEC), GEN_HANDLER(lvsr, 0x1f, 0x06, 0x01, 0x00000001, PPC_ALTIVEC), GEN_HANDLER(mfvscr, 0x04, 0x2, 0x18, 0x001ff800, PPC_ALTIVEC), GEN_HANDLER(mtvscr, 0x04, 0x2, 0x19, 0x03ff0000, PPC_ALTIVEC), -GEN_HANDLER(vmladduhm, 0x04, 0x11, 0xFF, 0x00000000, PPC_ALTIVEC), #if defined(TARGET_PPC64) GEN_HANDLER_E(maddhd_maddhdu, 0x04, 0x18, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA300), diff --git a/target/ppc/translate/vmx-impl.c.inc b/target/ppc/translate/vmx-impl.c.inc index e644ad3236..9f18c6d4f2 100644 --- a/target/ppc/translate/vmx-impl.c.inc +++ b/target/ppc/translate/vmx-impl.c.inc @@ -2523,24 +2523,6 @@ static void glue(gen_, name0##_##name1)(DisasContext *ctx) \ GEN_VAFORM_PAIRED(vmhaddshs, vmhraddshs, 16) -static void gen_vmladduhm(DisasContext *ctx) -{ - TCGv_ptr ra, rb, rc, rd; - if (unlikely(!ctx->altivec_enabled)) { - gen_exception(ctx, POWERPC_EXCP_VPU); - return; - } - ra = gen_avr_ptr(rA(ctx->opcode)); - rb = gen_avr_ptr(rB(ctx->opcode)); - rc = gen_avr_ptr(rC(ctx->opcode)); - rd = gen_avr_ptr(rD(ctx->opcode)); - gen_helper_vmladduhm(rd, ra, rb, rc); - tcg_temp_free_ptr(ra); - tcg_temp_free_ptr(rb); - tcg_temp_free_ptr(rc); - tcg_temp_free_ptr(rd); -} - static bool do_va_helper(DisasContext *ctx, arg_VA *a, void (*gen_helper)(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr)) { @@ -2569,6 +2551,36 @@ TRANS_FLAGS2(ALTIVEC_207, VSUBECUQ, do_va_helper, gen_helper_VSUBECUQ) TRANS_FLAGS(ALTIVEC, VPERM, do_va_helper, gen_helper_VPERM) TRANS_FLAGS2(ISA300, VPERMR, do_va_helper, gen_helper_VPERMR) +static void gen_vmladduhm_vec(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b, + TCGv_vec c) +{ + tcg_gen_mul_vec(vece, t, a, b); + tcg_gen_add_vec(vece, t, t, c); +} + +static bool trans_VMLADDUHM(DisasContext *ctx, arg_VA *a) +{ + static const TCGOpcode vecop_list[] = { + INDEX_op_add_vec, INDEX_op_mul_vec, 0 + }; + + static const GVecGen4 op = { + .fno = gen_helper_VMLADDUHM, + .fniv = gen_vmladduhm_vec, + .opt_opc = vecop_list, + .vece = MO_16 + }; + + REQUIRE_INSNS_FLAGS(ctx, ALTIVEC); + REQUIRE_VECTOR(ctx); + + tcg_gen_gvec_4(avr_full_offset(a->vrt), avr_full_offset(a->vra), + avr_full_offset(a->vrb), avr_full_offset(a->rc), + 16, 16, &op); + + return true; +} + static bool trans_VSEL(DisasContext *ctx, arg_VA *a) { REQUIRE_INSNS_FLAGS(ctx, ALTIVEC); From 306e4753354378213eddf6f4e6335ffc68186d1f Mon Sep 17 00:00:00 2001 From: "Lucas Mateus Castro (alqotel)" Date: Wed, 19 Oct 2022 09:50:30 -0300 Subject: [PATCH 344/705] target/ppc: Move VMH[R]ADDSHS instruction to decodetree This patch moves VMHADDSHS and VMHRADDSHS to decodetree I couldn't find a satisfactory implementation with TCG inline. vmhaddshs: rept loop master patch 8 12500 0,02983400 0,02648500 (-11.2%) 25 4000 0,02946000 0,02518000 (-14.5%) 100 1000 0,03104300 0,02638000 (-15.0%) 500 200 0,04002000 0,03502500 (-12.5%) 2500 40 0,08090100 0,07562200 (-6.5%) 8000 12 0,19242600 0,18626800 (-3.2%) vmhraddshs: rept loop master patch 8 12500 0,03078600 0,02851000 (-7.4%) 25 4000 0,02793200 0,02746900 (-1.7%) 100 1000 0,02886000 0,02839900 (-1.6%) 500 200 0,03714700 0,03799200 (+2.3%) 2500 40 0,07948000 0,07852200 (-1.2%) 8000 12 0,19049800 0,18813900 (-1.2%) Signed-off-by: Lucas Mateus Castro (alqotel) Reviewed-by: Richard Henderson Message-Id: <20221019125040.48028-3-lucas.araujo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/helper.h | 4 ++-- target/ppc/insn32.decode | 2 ++ target/ppc/int_helper.c | 4 ++-- target/ppc/translate/vmx-impl.c.inc | 5 +++-- target/ppc/translate/vmx-ops.c.inc | 1 - 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 9c562ab00e..f02a9497b7 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -258,8 +258,8 @@ DEF_HELPER_4(vpkuhum, void, env, avr, avr, avr) DEF_HELPER_4(vpkuwum, void, env, avr, avr, avr) DEF_HELPER_4(vpkudum, void, env, avr, avr, avr) DEF_HELPER_FLAGS_3(vpkpx, TCG_CALL_NO_RWG, void, avr, avr, avr) -DEF_HELPER_5(vmhaddshs, void, env, avr, avr, avr, avr) -DEF_HELPER_5(vmhraddshs, void, env, avr, avr, avr, avr) +DEF_HELPER_5(VMHADDSHS, void, env, avr, avr, avr, avr) +DEF_HELPER_5(VMHRADDSHS, void, env, avr, avr, avr, avr) DEF_HELPER_FLAGS_4(VMSUMUHM, TCG_CALL_NO_RWG, void, avr, avr, avr, avr) DEF_HELPER_5(VMSUMUHS, void, env, avr, avr, avr, avr) DEF_HELPER_FLAGS_4(VMSUMSHM, TCG_CALL_NO_RWG, void, avr, avr, avr, avr) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 9ba1689230..4e142d5e23 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -694,6 +694,8 @@ VMSUMCUD 000100 ..... ..... ..... ..... 010111 @VA VMSUMUDM 000100 ..... ..... ..... ..... 100011 @VA VMLADDUHM 000100 ..... ..... ..... ..... 100010 @VA +VMHADDSHS 000100 ..... ..... ..... ..... 100000 @VA +VMHRADDSHS 000100 ..... ..... ..... ..... 100001 @VA ## Vector String Instructions diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index 0d25000b2a..ae1ba8084d 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -939,7 +939,7 @@ target_ulong helper_vctzlsbb(ppc_avr_t *r) return count; } -void helper_vmhaddshs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, +void helper_VMHADDSHS(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) { int sat = 0; @@ -957,7 +957,7 @@ void helper_vmhaddshs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, } } -void helper_vmhraddshs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, +void helper_VMHRADDSHS(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) { int sat = 0; diff --git a/target/ppc/translate/vmx-impl.c.inc b/target/ppc/translate/vmx-impl.c.inc index 9f18c6d4f2..3acd585a2f 100644 --- a/target/ppc/translate/vmx-impl.c.inc +++ b/target/ppc/translate/vmx-impl.c.inc @@ -2521,7 +2521,7 @@ static void glue(gen_, name0##_##name1)(DisasContext *ctx) \ tcg_temp_free_ptr(rd); \ } -GEN_VAFORM_PAIRED(vmhaddshs, vmhraddshs, 16) +GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23) static bool do_va_helper(DisasContext *ctx, arg_VA *a, void (*gen_helper)(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr)) @@ -2620,7 +2620,8 @@ static bool do_va_env_helper(DisasContext *ctx, arg_VA *a, TRANS_FLAGS(ALTIVEC, VMSUMUHS, do_va_env_helper, gen_helper_VMSUMUHS) TRANS_FLAGS(ALTIVEC, VMSUMSHS, do_va_env_helper, gen_helper_VMSUMSHS) -GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23) +TRANS_FLAGS(ALTIVEC, VMHADDSHS, do_va_env_helper, gen_helper_VMHADDSHS) +TRANS_FLAGS(ALTIVEC, VMHRADDSHS, do_va_env_helper, gen_helper_VMHRADDSHS) GEN_VXFORM_NOA(vclzb, 1, 28) GEN_VXFORM_NOA(vclzh, 1, 29) diff --git a/target/ppc/translate/vmx-ops.c.inc b/target/ppc/translate/vmx-ops.c.inc index a3a0fd0650..7cd9d40e06 100644 --- a/target/ppc/translate/vmx-ops.c.inc +++ b/target/ppc/translate/vmx-ops.c.inc @@ -219,7 +219,6 @@ GEN_VXFORM_UIMM(vctsxs, 5, 15), #define GEN_VAFORM_PAIRED(name0, name1, opc2) \ GEN_HANDLER(name0##_##name1, 0x04, opc2, 0xFF, 0x00000000, PPC_ALTIVEC) -GEN_VAFORM_PAIRED(vmhaddshs, vmhraddshs, 16), GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23), GEN_VXFORM_DUAL(vclzb, vpopcntb, 1, 28, PPC_NONE, PPC2_ALTIVEC_207), From 611bc69bf6bc6b23e91e4798c036b941c9958b40 Mon Sep 17 00:00:00 2001 From: "Lucas Mateus Castro (alqotel)" Date: Wed, 19 Oct 2022 09:50:31 -0300 Subject: [PATCH 345/705] target/ppc: Move V(ADD|SUB)CUW to decodetree and use gvec This patch moves VADDCUW and VSUBCUW to decodtree with gvec using an implementation based on the helper, with the main difference being changing the -1 (aka all bits set to 1) result returned by cmp when true to +1. It also implemented a .fni4 version of those instructions and dropped the helper. vaddcuw: rept loop master patch 8 12500 0,01008200 0,00612400 (-39.3%) 25 4000 0,01091500 0,00471600 (-56.8%) 100 1000 0,01332500 0,00593700 (-55.4%) 500 200 0,01998500 0,01275700 (-36.2%) 2500 40 0,04704300 0,04364300 (-7.2%) 8000 12 0,10748200 0,11241000 (+4.6%) vsubcuw: rept loop master patch 8 12500 0,01226200 0,00571600 (-53.4%) 25 4000 0,01493500 0,00462100 (-69.1%) 100 1000 0,01522700 0,00455100 (-70.1%) 500 200 0,02384600 0,01133500 (-52.5%) 2500 40 0,04935200 0,03178100 (-35.6%) 8000 12 0,09039900 0,09440600 (+4.4%) Overall there was a gain in performance, but the TCGop code was still slightly bigger in the new version (it went from 4 to 5). Signed-off-by: Lucas Mateus Castro (alqotel) Reviewed-by: Richard Henderson Message-Id: <20221019125040.48028-4-lucas.araujo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/helper.h | 2 - target/ppc/insn32.decode | 2 + target/ppc/int_helper.c | 18 --------- target/ppc/translate/vmx-impl.c.inc | 61 +++++++++++++++++++++++++++-- target/ppc/translate/vmx-ops.c.inc | 3 +- 5 files changed, 60 insertions(+), 26 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index f02a9497b7..f7047ed2aa 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -193,11 +193,9 @@ DEF_HELPER_FLAGS_3(vslo, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_FLAGS_3(vsro, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_FLAGS_3(vsrv, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_FLAGS_3(vslv, TCG_CALL_NO_RWG, void, avr, avr, avr) -DEF_HELPER_FLAGS_3(vaddcuw, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_FLAGS_2(vprtybw, TCG_CALL_NO_RWG, void, avr, avr) DEF_HELPER_FLAGS_2(vprtybd, TCG_CALL_NO_RWG, void, avr, avr) DEF_HELPER_FLAGS_2(vprtybq, TCG_CALL_NO_RWG, void, avr, avr) -DEF_HELPER_FLAGS_3(vsubcuw, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_FLAGS_5(vaddsbs, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) DEF_HELPER_FLAGS_5(vaddshs, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) DEF_HELPER_FLAGS_5(vaddsws, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 4e142d5e23..c985f8f1bf 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -608,12 +608,14 @@ VRLQNM 000100 ..... ..... ..... 00101000101 @VX ## Vector Integer Arithmetic Instructions +VADDCUW 000100 ..... ..... ..... 00110000000 @VX VADDCUQ 000100 ..... ..... ..... 00101000000 @VX VADDUQM 000100 ..... ..... ..... 00100000000 @VX VADDEUQM 000100 ..... ..... ..... ..... 111100 @VA VADDECUQ 000100 ..... ..... ..... ..... 111101 @VA +VSUBCUW 000100 ..... ..... ..... 10110000000 @VX VSUBCUQ 000100 ..... ..... ..... 10101000000 @VX VSUBUQM 000100 ..... ..... ..... 10100000000 @VX diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index ae1ba8084d..f8dd12e8ae 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -492,15 +492,6 @@ static inline void set_vscr_sat(CPUPPCState *env) env->vscr_sat.u32[0] = 1; } -void helper_vaddcuw(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(r->u32); i++) { - r->u32[i] = ~a->u32[i] < b->u32[i]; - } -} - /* vprtybw */ void helper_vprtybw(ppc_avr_t *r, ppc_avr_t *b) { @@ -1962,15 +1953,6 @@ void helper_vsro(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) #endif } -void helper_vsubcuw(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(r->u32); i++) { - r->u32[i] = a->u32[i] >= b->u32[i]; - } -} - void helper_vsumsws(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) { int64_t t; diff --git a/target/ppc/translate/vmx-impl.c.inc b/target/ppc/translate/vmx-impl.c.inc index 3acd585a2f..f52485a5f1 100644 --- a/target/ppc/translate/vmx-impl.c.inc +++ b/target/ppc/translate/vmx-impl.c.inc @@ -803,8 +803,6 @@ GEN_VXFORM(vsrv, 2, 28); GEN_VXFORM(vslv, 2, 29); GEN_VXFORM(vslo, 6, 16); GEN_VXFORM(vsro, 6, 17); -GEN_VXFORM(vaddcuw, 0, 6); -GEN_VXFORM(vsubcuw, 0, 22); static bool do_vector_gvec3_VX(DisasContext *ctx, arg_VX *a, int vece, void (*gen_gvec)(unsigned, uint32_t, uint32_t, @@ -2847,8 +2845,6 @@ static void gen_xpnd04_2(DisasContext *ctx) } -GEN_VXFORM_DUAL(vsubcuw, PPC_ALTIVEC, PPC_NONE, \ - xpnd04_1, PPC_NONE, PPC2_ISA300) GEN_VXFORM_DUAL(vsubsws, PPC_ALTIVEC, PPC_NONE, \ xpnd04_2, PPC_NONE, PPC2_ISA300) @@ -3110,6 +3106,63 @@ TRANS_FLAGS2(ALTIVEC_207, VPMSUMD, do_vx_helper, gen_helper_VPMSUMD) TRANS_FLAGS2(ALTIVEC_207, VSUBCUQ, do_vx_helper, gen_helper_VSUBCUQ) TRANS_FLAGS2(ALTIVEC_207, VSUBUQM, do_vx_helper, gen_helper_VSUBUQM) +static void gen_VADDCUW_vec(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b) +{ + tcg_gen_not_vec(vece, a, a); + tcg_gen_cmp_vec(TCG_COND_LTU, vece, t, a, b); + tcg_gen_and_vec(vece, t, t, tcg_constant_vec_matching(t, vece, 1)); +} + +static void gen_VADDCUW_i32(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b) +{ + tcg_gen_not_i32(a, a); + tcg_gen_setcond_i32(TCG_COND_LTU, t, a, b); +} + +static void gen_VSUBCUW_vec(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b) +{ + tcg_gen_cmp_vec(TCG_COND_GEU, vece, t, a, b); + tcg_gen_and_vec(vece, t, t, tcg_constant_vec_matching(t, vece, 1)); +} + +static void gen_VSUBCUW_i32(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b) +{ + tcg_gen_setcond_i32(TCG_COND_GEU, t, a, b); +} + +static bool do_vx_vaddsubcuw(DisasContext *ctx, arg_VX *a, int add) +{ + static const TCGOpcode vecop_list[] = { + INDEX_op_cmp_vec, 0 + }; + + static const GVecGen3 op[] = { + { + .fniv = gen_VSUBCUW_vec, + .fni4 = gen_VSUBCUW_i32, + .opt_opc = vecop_list, + .vece = MO_32 + }, + { + .fniv = gen_VADDCUW_vec, + .fni4 = gen_VADDCUW_i32, + .opt_opc = vecop_list, + .vece = MO_32 + }, + }; + + REQUIRE_INSNS_FLAGS(ctx, ALTIVEC); + REQUIRE_VECTOR(ctx); + + tcg_gen_gvec_3(avr_full_offset(a->vrt), avr_full_offset(a->vra), + avr_full_offset(a->vrb), 16, 16, &op[add]); + + return true; +} + +TRANS(VSUBCUW, do_vx_vaddsubcuw, 0) +TRANS(VADDCUW, do_vx_vaddsubcuw, 1) + static bool do_vx_vmuleo(DisasContext *ctx, arg_VX *a, bool even, void (*gen_mul)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64)) { diff --git a/target/ppc/translate/vmx-ops.c.inc b/target/ppc/translate/vmx-ops.c.inc index 7cd9d40e06..ded0234123 100644 --- a/target/ppc/translate/vmx-ops.c.inc +++ b/target/ppc/translate/vmx-ops.c.inc @@ -106,12 +106,11 @@ GEN_VXFORM_300(vsrv, 2, 28), GEN_VXFORM_300(vslv, 2, 29), GEN_VXFORM(vslo, 6, 16), GEN_VXFORM(vsro, 6, 17), -GEN_VXFORM(vaddcuw, 0, 6), GEN_HANDLER_E_2(vprtybw, 0x4, 0x1, 0x18, 8, 0, PPC_NONE, PPC2_ISA300), GEN_HANDLER_E_2(vprtybd, 0x4, 0x1, 0x18, 9, 0, PPC_NONE, PPC2_ISA300), GEN_HANDLER_E_2(vprtybq, 0x4, 0x1, 0x18, 10, 0, PPC_NONE, PPC2_ISA300), -GEN_VXFORM_DUAL(vsubcuw, xpnd04_1, 0, 22, PPC_ALTIVEC, PPC_NONE), +GEN_VXFORM(xpnd04_1, 0, 22), GEN_VXFORM_300(bcdsr, 0, 23), GEN_VXFORM_300(bcdsr, 0, 31), GEN_VXFORM_DUAL(vaddubs, vmul10uq, 0, 8, PPC_ALTIVEC, PPC_NONE), From 90b5aadb09b1063dfc34636efe212c6862cbe32f Mon Sep 17 00:00:00 2001 From: "Lucas Mateus Castro (alqotel)" Date: Wed, 19 Oct 2022 09:50:32 -0300 Subject: [PATCH 346/705] target/ppc: Move VNEG[WD] to decodtree and use gvec Moved the instructions VNEGW and VNEGD to decodetree and used gvec to decode it. vnegw: rept loop master patch 8 12500 0,01053200 0,00548400 (-47.9%) 25 4000 0,01030500 0,00390000 (-62.2%) 100 1000 0,01096300 0,00395400 (-63.9%) 500 200 0,01472000 0,00712300 (-51.6%) 2500 40 0,03809000 0,02147700 (-43.6%) 8000 12 0,09957100 0,06202100 (-37.7%) vnegd: rept loop master patch 8 12500 0,00594600 0,00543800 (-8.5%) 25 4000 0,00575200 0,00396400 (-31.1%) 100 1000 0,00676100 0,00394800 (-41.6%) 500 200 0,01149300 0,00709400 (-38.3%) 2500 40 0,03441500 0,02169600 (-37.0%) 8000 12 0,09516900 0,06337000 (-33.4%) Signed-off-by: Lucas Mateus Castro (alqotel) Reviewed-by: Richard Henderson Message-Id: <20221019125040.48028-5-lucas.araujo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/helper.h | 2 -- target/ppc/insn32.decode | 3 +++ target/ppc/int_helper.c | 12 ------------ target/ppc/translate/vmx-impl.c.inc | 15 +++++++++++++-- target/ppc/translate/vmx-ops.c.inc | 2 -- 5 files changed, 16 insertions(+), 18 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index f7047ed2aa..b2e910b089 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -229,8 +229,6 @@ DEF_HELPER_FLAGS_2(VSTRIBL, TCG_CALL_NO_RWG, i32, avr, avr) DEF_HELPER_FLAGS_2(VSTRIBR, TCG_CALL_NO_RWG, i32, avr, avr) DEF_HELPER_FLAGS_2(VSTRIHL, TCG_CALL_NO_RWG, i32, avr, avr) DEF_HELPER_FLAGS_2(VSTRIHR, TCG_CALL_NO_RWG, i32, avr, avr) -DEF_HELPER_FLAGS_2(vnegw, TCG_CALL_NO_RWG, void, avr, avr) -DEF_HELPER_FLAGS_2(vnegd, TCG_CALL_NO_RWG, void, avr, avr) DEF_HELPER_FLAGS_2(vupkhpx, TCG_CALL_NO_RWG, void, avr, avr) DEF_HELPER_FLAGS_2(vupklpx, TCG_CALL_NO_RWG, void, avr, avr) DEF_HELPER_FLAGS_2(vupkhsb, TCG_CALL_NO_RWG, void, avr, avr) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index c985f8f1bf..2fafde075b 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -629,6 +629,9 @@ VEXTSH2D 000100 ..... 11001 ..... 11000000010 @VX_tb VEXTSW2D 000100 ..... 11010 ..... 11000000010 @VX_tb VEXTSD2Q 000100 ..... 11011 ..... 11000000010 @VX_tb +VNEGD 000100 ..... 00111 ..... 11000000010 @VX_tb +VNEGW 000100 ..... 00110 ..... 11000000010 @VX_tb + ## Vector Mask Manipulation Instructions MTVSRBM 000100 ..... 10000 ..... 11001000010 @VX_tb diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index f8dd12e8ae..c7fd0d1faa 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -1928,18 +1928,6 @@ XXBLEND(W, 32) XXBLEND(D, 64) #undef XXBLEND -#define VNEG(name, element) \ -void helper_##name(ppc_avr_t *r, ppc_avr_t *b) \ -{ \ - int i; \ - for (i = 0; i < ARRAY_SIZE(r->element); i++) { \ - r->element[i] = -b->element[i]; \ - } \ -} -VNEG(vnegw, s32) -VNEG(vnegd, s64) -#undef VNEG - void helper_vsro(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) { int sh = (b->VsrB(0xf) >> 3) & 0xf; diff --git a/target/ppc/translate/vmx-impl.c.inc b/target/ppc/translate/vmx-impl.c.inc index f52485a5f1..b9a9e83ab3 100644 --- a/target/ppc/translate/vmx-impl.c.inc +++ b/target/ppc/translate/vmx-impl.c.inc @@ -2625,8 +2625,19 @@ GEN_VXFORM_NOA(vclzb, 1, 28) GEN_VXFORM_NOA(vclzh, 1, 29) GEN_VXFORM_TRANS(vclzw, 1, 30) GEN_VXFORM_TRANS(vclzd, 1, 31) -GEN_VXFORM_NOA_2(vnegw, 1, 24, 6) -GEN_VXFORM_NOA_2(vnegd, 1, 24, 7) + +static bool do_vneg(DisasContext *ctx, arg_VX_tb *a, unsigned vece) +{ + REQUIRE_INSNS_FLAGS2(ctx, ISA300); + REQUIRE_VECTOR(ctx); + + tcg_gen_gvec_neg(vece, avr_full_offset(a->vrt), avr_full_offset(a->vrb), + 16, 16); + return true; +} + +TRANS(VNEGW, do_vneg, MO_32) +TRANS(VNEGD, do_vneg, MO_64) static void gen_vexts_i64(TCGv_i64 t, TCGv_i64 b, int64_t s) { diff --git a/target/ppc/translate/vmx-ops.c.inc b/target/ppc/translate/vmx-ops.c.inc index ded0234123..27908533dd 100644 --- a/target/ppc/translate/vmx-ops.c.inc +++ b/target/ppc/translate/vmx-ops.c.inc @@ -181,8 +181,6 @@ GEN_VXFORM_300_EXT(vextractd, 6, 11, 0x100000), GEN_VXFORM(vspltisb, 6, 12), GEN_VXFORM(vspltish, 6, 13), GEN_VXFORM(vspltisw, 6, 14), -GEN_VXFORM_300_EO(vnegw, 0x01, 0x18, 0x06), -GEN_VXFORM_300_EO(vnegd, 0x01, 0x18, 0x07), GEN_VXFORM_300_EO(vctzb, 0x01, 0x18, 0x1C), GEN_VXFORM_300_EO(vctzh, 0x01, 0x18, 0x1D), GEN_VXFORM_300_EO(vctzw, 0x01, 0x18, 0x1E), From d57fbd8fd9ea4f559cf4ed6c8fb6f064b73d6882 Mon Sep 17 00:00:00 2001 From: "Lucas Mateus Castro (alqotel)" Date: Wed, 19 Oct 2022 09:50:33 -0300 Subject: [PATCH 347/705] target/ppc: Move VPRTYB[WDQ] to decodetree and use gvec Moved VPRTYBW and VPRTYBD to use gvec and both of them and VPRTYBQ to decodetree. VPRTYBW and VPRTYBD now also use .fni4 and .fni8, respectively. vprtybw: rept loop master patch 8 12500 0,01198900 0,00703100 (-41.4%) 25 4000 0,01070100 0,00571400 (-46.6%) 100 1000 0,01123300 0,00678200 (-39.6%) 500 200 0,01601500 0,01535600 (-4.1%) 2500 40 0,03872900 0,05562100 (43.6%) 8000 12 0,10047000 0,16643000 (65.7%) vprtybd: rept loop master patch 8 12500 0,00757700 0,00788100 (4.0%) 25 4000 0,00652500 0,00669600 (2.6%) 100 1000 0,00714400 0,00825400 (15.5%) 500 200 0,01211000 0,01903700 (57.2%) 2500 40 0,03483800 0,07021200 (101.5%) 8000 12 0,09591800 0,21036200 (119.3%) vprtybq: rept loop master patch 8 12500 0,00675600 0,00667200 (-1.2%) 25 4000 0,00619400 0,00643200 (3.8%) 100 1000 0,00707100 0,00751100 (6.2%) 500 200 0,01199300 0,01342000 (11.9%) 2500 40 0,03490900 0,04092900 (17.2%) 8000 12 0,09588200 0,11465100 (19.6%) I wasn't expecting such a performance lost in both VPRTYBD and VPRTYBQ, I'm not sure if it's worth to move those instructions. Comparing the assembly of the helper with the TCGop they are pretty similar, so I'm not sure why vprtybd took so much more time. Signed-off-by: Lucas Mateus Castro (alqotel) Reviewed-by: Richard Henderson Message-Id: <20221019125040.48028-6-lucas.araujo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/helper.h | 4 +- target/ppc/insn32.decode | 4 ++ target/ppc/int_helper.c | 25 +---------- target/ppc/translate/vmx-impl.c.inc | 68 +++++++++++++++++++++++++++-- target/ppc/translate/vmx-ops.c.inc | 3 -- 5 files changed, 71 insertions(+), 33 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index b2e910b089..a06193bc67 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -193,9 +193,7 @@ DEF_HELPER_FLAGS_3(vslo, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_FLAGS_3(vsro, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_FLAGS_3(vsrv, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_FLAGS_3(vslv, TCG_CALL_NO_RWG, void, avr, avr, avr) -DEF_HELPER_FLAGS_2(vprtybw, TCG_CALL_NO_RWG, void, avr, avr) -DEF_HELPER_FLAGS_2(vprtybd, TCG_CALL_NO_RWG, void, avr, avr) -DEF_HELPER_FLAGS_2(vprtybq, TCG_CALL_NO_RWG, void, avr, avr) +DEF_HELPER_FLAGS_3(VPRTYBQ, TCG_CALL_NO_RWG, void, avr, avr, i32) DEF_HELPER_FLAGS_5(vaddsbs, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) DEF_HELPER_FLAGS_5(vaddshs, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) DEF_HELPER_FLAGS_5(vaddsws, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 2fafde075b..b05c89efee 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -529,6 +529,10 @@ VCTZDM 000100 ..... ..... ..... 11111000100 @VX VPDEPD 000100 ..... ..... ..... 10111001101 @VX VPEXTD 000100 ..... ..... ..... 10110001101 @VX +VPRTYBD 000100 ..... 01001 ..... 11000000010 @VX_tb +VPRTYBQ 000100 ..... 01010 ..... 11000000010 @VX_tb +VPRTYBW 000100 ..... 01000 ..... 11000000010 @VX_tb + ## Vector Permute and Formatting Instruction VEXTDUBVLX 000100 ..... ..... ..... ..... 011000 @VA diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index c7fd0d1faa..c6ce4665fa 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -492,31 +492,8 @@ static inline void set_vscr_sat(CPUPPCState *env) env->vscr_sat.u32[0] = 1; } -/* vprtybw */ -void helper_vprtybw(ppc_avr_t *r, ppc_avr_t *b) -{ - int i; - for (i = 0; i < ARRAY_SIZE(r->u32); i++) { - uint64_t res = b->u32[i] ^ (b->u32[i] >> 16); - res ^= res >> 8; - r->u32[i] = res & 1; - } -} - -/* vprtybd */ -void helper_vprtybd(ppc_avr_t *r, ppc_avr_t *b) -{ - int i; - for (i = 0; i < ARRAY_SIZE(r->u64); i++) { - uint64_t res = b->u64[i] ^ (b->u64[i] >> 32); - res ^= res >> 16; - res ^= res >> 8; - r->u64[i] = res & 1; - } -} - /* vprtybq */ -void helper_vprtybq(ppc_avr_t *r, ppc_avr_t *b) +void helper_VPRTYBQ(ppc_avr_t *r, ppc_avr_t *b, uint32_t v) { uint64_t res = b->u64[0] ^ b->u64[1]; res ^= res >> 32; diff --git a/target/ppc/translate/vmx-impl.c.inc b/target/ppc/translate/vmx-impl.c.inc index b9a9e83ab3..cbb2a3ebe7 100644 --- a/target/ppc/translate/vmx-impl.c.inc +++ b/target/ppc/translate/vmx-impl.c.inc @@ -1659,9 +1659,71 @@ GEN_VXFORM_NOA_ENV(vrfim, 5, 11); GEN_VXFORM_NOA_ENV(vrfin, 5, 8); GEN_VXFORM_NOA_ENV(vrfip, 5, 10); GEN_VXFORM_NOA_ENV(vrfiz, 5, 9); -GEN_VXFORM_NOA(vprtybw, 1, 24); -GEN_VXFORM_NOA(vprtybd, 1, 24); -GEN_VXFORM_NOA(vprtybq, 1, 24); + +static void gen_vprtyb_vec(unsigned vece, TCGv_vec t, TCGv_vec b) +{ + int i; + TCGv_vec tmp = tcg_temp_new_vec_matching(b); + /* MO_32 is 2, so 2 iteractions for MO_32 and 3 for MO_64 */ + for (i = 0; i < vece; i++) { + tcg_gen_shri_vec(vece, tmp, b, (4 << (vece - i))); + tcg_gen_xor_vec(vece, b, tmp, b); + } + tcg_gen_and_vec(vece, t, b, tcg_constant_vec_matching(t, vece, 1)); + tcg_temp_free_vec(tmp); +} + +/* vprtybw */ +static void gen_vprtyb_i32(TCGv_i32 t, TCGv_i32 b) +{ + tcg_gen_ctpop_i32(t, b); + tcg_gen_and_i32(t, t, tcg_constant_i32(1)); +} + +/* vprtybd */ +static void gen_vprtyb_i64(TCGv_i64 t, TCGv_i64 b) +{ + tcg_gen_ctpop_i64(t, b); + tcg_gen_and_i64(t, t, tcg_constant_i64(1)); +} + +static bool do_vx_vprtyb(DisasContext *ctx, arg_VX_tb *a, unsigned vece) +{ + static const TCGOpcode vecop_list[] = { + INDEX_op_shri_vec, 0 + }; + + static const GVecGen2 op[] = { + { + .fniv = gen_vprtyb_vec, + .fni4 = gen_vprtyb_i32, + .opt_opc = vecop_list, + .vece = MO_32 + }, + { + .fniv = gen_vprtyb_vec, + .fni8 = gen_vprtyb_i64, + .opt_opc = vecop_list, + .vece = MO_64 + }, + { + .fno = gen_helper_VPRTYBQ, + .vece = MO_128 + }, + }; + + REQUIRE_INSNS_FLAGS2(ctx, ISA300); + REQUIRE_VECTOR(ctx); + + tcg_gen_gvec_2(avr_full_offset(a->vrt), avr_full_offset(a->vrb), + 16, 16, &op[vece - MO_32]); + + return true; +} + +TRANS(VPRTYBW, do_vx_vprtyb, MO_32) +TRANS(VPRTYBD, do_vx_vprtyb, MO_64) +TRANS(VPRTYBQ, do_vx_vprtyb, MO_128) static void gen_vsplt(DisasContext *ctx, int vece) { diff --git a/target/ppc/translate/vmx-ops.c.inc b/target/ppc/translate/vmx-ops.c.inc index 27908533dd..46a620a232 100644 --- a/target/ppc/translate/vmx-ops.c.inc +++ b/target/ppc/translate/vmx-ops.c.inc @@ -106,9 +106,6 @@ GEN_VXFORM_300(vsrv, 2, 28), GEN_VXFORM_300(vslv, 2, 29), GEN_VXFORM(vslo, 6, 16), GEN_VXFORM(vsro, 6, 17), -GEN_HANDLER_E_2(vprtybw, 0x4, 0x1, 0x18, 8, 0, PPC_NONE, PPC2_ISA300), -GEN_HANDLER_E_2(vprtybd, 0x4, 0x1, 0x18, 9, 0, PPC_NONE, PPC2_ISA300), -GEN_HANDLER_E_2(vprtybq, 0x4, 0x1, 0x18, 10, 0, PPC_NONE, PPC2_ISA300), GEN_VXFORM(xpnd04_1, 0, 22), GEN_VXFORM_300(bcdsr, 0, 23), From c85929b2ddf6bbad737635c9b85213007ec043af Mon Sep 17 00:00:00 2001 From: "Lucas Mateus Castro (alqotel)" Date: Wed, 19 Oct 2022 09:50:34 -0300 Subject: [PATCH 348/705] target/ppc: Move VAVG[SU][BHW] to decodetree and use gvec Moved the instructions VAVGUB, VAVGUH, VAVGUW, VAVGSB, VAVGSH, VAVGSW, to decodetree and use gvec with them. For these one the right shift had to be made before the sum as to avoid an overflow, so add 1 at the end if any of the entries had 1 in its LSB as to replicate the "+ 1" before the shift described by the ISA. vavgub: rept loop master patch 8 12500 0,02616600 0,00754200 (-71.2%) 25 4000 0,02530000 0,00637700 (-74.8%) 100 1000 0,02604600 0,00790100 (-69.7%) 500 200 0,03189300 0,01838400 (-42.4%) 2500 40 0,06006900 0,06851000 (+14.1%) 8000 12 0,13941000 0,20548500 (+47.4%) vavguh: rept loop master patch 8 12500 0,01818200 0,00780600 (-57.1%) 25 4000 0,01789300 0,00641600 (-64.1%) 100 1000 0,01899100 0,00787200 (-58.5%) 500 200 0,02527200 0,01828400 (-27.7%) 2500 40 0,05361800 0,06773000 (+26.3%) 8000 12 0,12886600 0,20291400 (+57.5%) vavguw: rept loop master patch 8 12500 0,01423100 0,00776600 (-45.4%) 25 4000 0,01780800 0,00638600 (-64.1%) 100 1000 0,02085500 0,00787000 (-62.3%) 500 200 0,02737100 0,01828800 (-33.2%) 2500 40 0,05572600 0,06774200 (+21.6%) 8000 12 0,13101700 0,20311600 (+55.0%) vavgsb: rept loop master patch 8 12500 0,03006000 0,00788600 (-73.8%) 25 4000 0,02882200 0,00637800 (-77.9%) 100 1000 0,02958000 0,00791400 (-73.2%) 500 200 0,03548800 0,01860400 (-47.6%) 2500 40 0,06360000 0,06850800 (+7.7%) 8000 12 0,13816500 0,20550300 (+48.7%) vavgsh: rept loop master patch 8 12500 0,01965900 0,00776600 (-60.5%) 25 4000 0,01875400 0,00638700 (-65.9%) 100 1000 0,01952200 0,00786900 (-59.7%) 500 200 0,02562000 0,01760300 (-31.3%) 2500 40 0,05384300 0,06742800 (+25.2%) 8000 12 0,13240800 0,20330000 (+53.5%) vavgsw: rept loop master patch 8 12500 0,01407700 0,00775600 (-44.9%) 25 4000 0,01762300 0,00640000 (-63.7%) 100 1000 0,02046500 0,00788500 (-61.5%) 500 200 0,02745600 0,01843000 (-32.9%) 2500 40 0,05375500 0,06820500 (+26.9%) 8000 12 0,13068300 0,20304900 (+55.4%) These results to me seems to indicate that with gvec the results have a slower translation but faster execution. Signed-off-by: Lucas Mateus Castro (alqotel) Reviewed-by: Richard Henderson Message-Id: <20221019125040.48028-7-lucas.araujo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/helper.h | 12 ++-- target/ppc/insn32.decode | 9 +++ target/ppc/int_helper.c | 32 ++++----- target/ppc/translate/vmx-impl.c.inc | 106 ++++++++++++++++++++++++---- target/ppc/translate/vmx-ops.c.inc | 9 +-- 5 files changed, 127 insertions(+), 41 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index a06193bc67..71c22efc2e 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -143,15 +143,15 @@ DEF_HELPER_FLAGS_1(ftsqrt, TCG_CALL_NO_RWG_SE, i32, i64) #define dh_ctype_acc ppc_acc_t * #define dh_typecode_acc dh_typecode_ptr -DEF_HELPER_FLAGS_3(vavgub, TCG_CALL_NO_RWG, void, avr, avr, avr) -DEF_HELPER_FLAGS_3(vavguh, TCG_CALL_NO_RWG, void, avr, avr, avr) -DEF_HELPER_FLAGS_3(vavguw, TCG_CALL_NO_RWG, void, avr, avr, avr) +DEF_HELPER_FLAGS_4(VAVGUB, TCG_CALL_NO_RWG, void, avr, avr, avr, i32) +DEF_HELPER_FLAGS_4(VAVGUH, TCG_CALL_NO_RWG, void, avr, avr, avr, i32) +DEF_HELPER_FLAGS_4(VAVGUW, TCG_CALL_NO_RWG, void, avr, avr, avr, i32) DEF_HELPER_FLAGS_3(vabsdub, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_FLAGS_3(vabsduh, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_FLAGS_3(vabsduw, TCG_CALL_NO_RWG, void, avr, avr, avr) -DEF_HELPER_FLAGS_3(vavgsb, TCG_CALL_NO_RWG, void, avr, avr, avr) -DEF_HELPER_FLAGS_3(vavgsh, TCG_CALL_NO_RWG, void, avr, avr, avr) -DEF_HELPER_FLAGS_3(vavgsw, TCG_CALL_NO_RWG, void, avr, avr, avr) +DEF_HELPER_FLAGS_4(VAVGSB, TCG_CALL_NO_RWG, void, avr, avr, avr, i32) +DEF_HELPER_FLAGS_4(VAVGSH, TCG_CALL_NO_RWG, void, avr, avr, avr, i32) +DEF_HELPER_FLAGS_4(VAVGSW, TCG_CALL_NO_RWG, void, avr, avr, avr, i32) DEF_HELPER_4(vcmpeqfp, void, env, avr, avr, avr) DEF_HELPER_4(vcmpgefp, void, env, avr, avr, avr) DEF_HELPER_4(vcmpgtfp, void, env, avr, avr, avr) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index b05c89efee..53dd45bbab 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -519,6 +519,15 @@ VCMPNEZW 000100 ..... ..... ..... . 0110000111 @VC VCMPSQ 000100 ... -- ..... ..... 00101000001 @VX_bf VCMPUQ 000100 ... -- ..... ..... 00100000001 @VX_bf +## Vector Integer Average Instructions + +VAVGSB 000100 ..... ..... ..... 10100000010 @VX +VAVGSH 000100 ..... ..... ..... 10101000010 @VX +VAVGSW 000100 ..... ..... ..... 10110000010 @VX +VAVGUB 000100 ..... ..... ..... 10000000010 @VX +VAVGUH 000100 ..... ..... ..... 10001000010 @VX +VAVGUW 000100 ..... ..... ..... 10010000010 @VX + ## Vector Bit Manipulation Instruction VGNB 000100 ..... -- ... ..... 10011001100 @VX_n diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index c6ce4665fa..bda76e54d4 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -570,25 +570,23 @@ VARITHSAT_UNSIGNED(w, u32, uint64_t, cvtsduw) #undef VARITHSAT_SIGNED #undef VARITHSAT_UNSIGNED -#define VAVG_DO(name, element, etype) \ - void helper_v##name(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ - { \ - int i; \ - \ - for (i = 0; i < ARRAY_SIZE(r->element); i++) { \ - etype x = (etype)a->element[i] + (etype)b->element[i] + 1; \ - r->element[i] = x >> 1; \ - } \ +#define VAVG(name, element, etype) \ + void helper_##name(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, uint32_t v)\ + { \ + int i; \ + \ + for (i = 0; i < ARRAY_SIZE(r->element); i++) { \ + etype x = (etype)a->element[i] + (etype)b->element[i] + 1; \ + r->element[i] = x >> 1; \ + } \ } -#define VAVG(type, signed_element, signed_type, unsigned_element, \ - unsigned_type) \ - VAVG_DO(avgs##type, signed_element, signed_type) \ - VAVG_DO(avgu##type, unsigned_element, unsigned_type) -VAVG(b, s8, int16_t, u8, uint16_t) -VAVG(h, s16, int32_t, u16, uint32_t) -VAVG(w, s32, int64_t, u32, uint64_t) -#undef VAVG_DO +VAVG(VAVGSB, s8, int16_t) +VAVG(VAVGUB, u8, uint16_t) +VAVG(VAVGSH, s16, int32_t) +VAVG(VAVGUH, u16, uint32_t) +VAVG(VAVGSW, s32, int64_t) +VAVG(VAVGUW, u32, uint64_t) #undef VAVG #define VABSDU_DO(name, element) \ diff --git a/target/ppc/translate/vmx-impl.c.inc b/target/ppc/translate/vmx-impl.c.inc index cbb2a3ebe7..195c601f7a 100644 --- a/target/ppc/translate/vmx-impl.c.inc +++ b/target/ppc/translate/vmx-impl.c.inc @@ -431,21 +431,9 @@ GEN_VXFORM_V(vminsb, MO_8, tcg_gen_gvec_smin, 1, 12); GEN_VXFORM_V(vminsh, MO_16, tcg_gen_gvec_smin, 1, 13); GEN_VXFORM_V(vminsw, MO_32, tcg_gen_gvec_smin, 1, 14); GEN_VXFORM_V(vminsd, MO_64, tcg_gen_gvec_smin, 1, 15); -GEN_VXFORM(vavgub, 1, 16); GEN_VXFORM(vabsdub, 1, 16); -GEN_VXFORM_DUAL(vavgub, PPC_ALTIVEC, PPC_NONE, \ - vabsdub, PPC_NONE, PPC2_ISA300) -GEN_VXFORM(vavguh, 1, 17); GEN_VXFORM(vabsduh, 1, 17); -GEN_VXFORM_DUAL(vavguh, PPC_ALTIVEC, PPC_NONE, \ - vabsduh, PPC_NONE, PPC2_ISA300) -GEN_VXFORM(vavguw, 1, 18); GEN_VXFORM(vabsduw, 1, 18); -GEN_VXFORM_DUAL(vavguw, PPC_ALTIVEC, PPC_NONE, \ - vabsduw, PPC_NONE, PPC2_ISA300) -GEN_VXFORM(vavgsb, 1, 20); -GEN_VXFORM(vavgsh, 1, 21); -GEN_VXFORM(vavgsw, 1, 22); GEN_VXFORM(vmrghb, 6, 0); GEN_VXFORM(vmrghh, 6, 1); GEN_VXFORM(vmrghw, 6, 2); @@ -3373,6 +3361,100 @@ TRANS(VMULHSD, do_vx_mulh, true , do_vx_vmulhd_i64) TRANS(VMULHUW, do_vx_mulh, false, do_vx_vmulhw_i64) TRANS(VMULHUD, do_vx_mulh, false, do_vx_vmulhd_i64) +static void do_vavg(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b, + void (*gen_shr_vec)(unsigned, TCGv_vec, TCGv_vec, int64_t)) +{ + TCGv_vec tmp = tcg_temp_new_vec_matching(t); + tcg_gen_or_vec(vece, tmp, a, b); + tcg_gen_and_vec(vece, tmp, tmp, tcg_constant_vec_matching(t, vece, 1)); + gen_shr_vec(vece, a, a, 1); + gen_shr_vec(vece, b, b, 1); + tcg_gen_add_vec(vece, t, a, b); + tcg_gen_add_vec(vece, t, t, tmp); + tcg_temp_free_vec(tmp); +} + +QEMU_FLATTEN +static void gen_vavgu(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b) +{ + do_vavg(vece, t, a, b, tcg_gen_shri_vec); +} + +QEMU_FLATTEN +static void gen_vavgs(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b) +{ + do_vavg(vece, t, a, b, tcg_gen_sari_vec); +} + +static bool do_vx_vavg(DisasContext *ctx, arg_VX *a, int sign, int vece) +{ + static const TCGOpcode vecop_list_s[] = { + INDEX_op_add_vec, INDEX_op_sari_vec, 0 + }; + static const TCGOpcode vecop_list_u[] = { + INDEX_op_add_vec, INDEX_op_shri_vec, 0 + }; + + static const GVecGen3 op[2][3] = { + { + { + .fniv = gen_vavgu, + .fno = gen_helper_VAVGUB, + .opt_opc = vecop_list_u, + .vece = MO_8 + }, + { + .fniv = gen_vavgu, + .fno = gen_helper_VAVGUH, + .opt_opc = vecop_list_u, + .vece = MO_16 + }, + { + .fniv = gen_vavgu, + .fno = gen_helper_VAVGUW, + .opt_opc = vecop_list_u, + .vece = MO_32 + }, + }, + { + { + .fniv = gen_vavgs, + .fno = gen_helper_VAVGSB, + .opt_opc = vecop_list_s, + .vece = MO_8 + }, + { + .fniv = gen_vavgs, + .fno = gen_helper_VAVGSH, + .opt_opc = vecop_list_s, + .vece = MO_16 + }, + { + .fniv = gen_vavgs, + .fno = gen_helper_VAVGSW, + .opt_opc = vecop_list_s, + .vece = MO_32 + }, + }, + }; + + REQUIRE_VECTOR(ctx); + + tcg_gen_gvec_3(avr_full_offset(a->vrt), avr_full_offset(a->vra), + avr_full_offset(a->vrb), 16, 16, &op[sign][vece]); + + + return true; +} + + +TRANS_FLAGS(ALTIVEC, VAVGSB, do_vx_vavg, 1, MO_8) +TRANS_FLAGS(ALTIVEC, VAVGSH, do_vx_vavg, 1, MO_16) +TRANS_FLAGS(ALTIVEC, VAVGSW, do_vx_vavg, 1, MO_32) +TRANS_FLAGS(ALTIVEC, VAVGUB, do_vx_vavg, 0, MO_8) +TRANS_FLAGS(ALTIVEC, VAVGUH, do_vx_vavg, 0, MO_16) +TRANS_FLAGS(ALTIVEC, VAVGUW, do_vx_vavg, 0, MO_32) + static bool do_vdiv_vmod(DisasContext *ctx, arg_VX *a, const int vece, void (*func_32)(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b), void (*func_64)(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)) diff --git a/target/ppc/translate/vmx-ops.c.inc b/target/ppc/translate/vmx-ops.c.inc index 46a620a232..02db51def0 100644 --- a/target/ppc/translate/vmx-ops.c.inc +++ b/target/ppc/translate/vmx-ops.c.inc @@ -83,12 +83,9 @@ GEN_VXFORM(vminsb, 1, 12), GEN_VXFORM(vminsh, 1, 13), GEN_VXFORM(vminsw, 1, 14), GEN_VXFORM_207(vminsd, 1, 15), -GEN_VXFORM_DUAL(vavgub, vabsdub, 1, 16, PPC_ALTIVEC, PPC_NONE), -GEN_VXFORM_DUAL(vavguh, vabsduh, 1, 17, PPC_ALTIVEC, PPC_NONE), -GEN_VXFORM_DUAL(vavguw, vabsduw, 1, 18, PPC_ALTIVEC, PPC_NONE), -GEN_VXFORM(vavgsb, 1, 20), -GEN_VXFORM(vavgsh, 1, 21), -GEN_VXFORM(vavgsw, 1, 22), +GEN_VXFORM(vabsdub, 1, 16), +GEN_VXFORM(vabsduh, 1, 17), +GEN_VXFORM(vabsduw, 1, 18), GEN_VXFORM(vmrghb, 6, 0), GEN_VXFORM(vmrghh, 6, 1), GEN_VXFORM(vmrghw, 6, 2), From 26c964f85159c78f6ecf132de8f2f0093d3f2e89 Mon Sep 17 00:00:00 2001 From: "Lucas Mateus Castro (alqotel)" Date: Wed, 19 Oct 2022 09:50:35 -0300 Subject: [PATCH 349/705] target/ppc: Move VABSDU[BHW] to decodetree and use gvec Moved VABSDUB, VABSDUH and VABSDUW to decodetree and use gvec to translate them. vabsdub: rept loop master patch 8 12500 0,03601600 0,00688500 (-80.9%) 25 4000 0,03651000 0,00532100 (-85.4%) 100 1000 0,03666900 0,00595300 (-83.8%) 500 200 0,04305800 0,01244600 (-71.1%) 2500 40 0,06893300 0,04273700 (-38.0%) 8000 12 0,14633200 0,12660300 (-13.5%) vabsduh: rept loop master patch 8 12500 0,02172400 0,00687500 (-68.4%) 25 4000 0,02154100 0,00531500 (-75.3%) 100 1000 0,02235400 0,00596300 (-73.3%) 500 200 0,02827500 0,01245100 (-56.0%) 2500 40 0,05638400 0,04285500 (-24.0%) 8000 12 0,13166000 0,12641400 (-4.0%) vabsduw: rept loop master patch 8 12500 0,01646400 0,00688300 (-58.2%) 25 4000 0,01454500 0,00475500 (-67.3%) 100 1000 0,01545800 0,00511800 (-66.9%) 500 200 0,02168200 0,01114300 (-48.6%) 2500 40 0,04571300 0,04138800 (-9.5%) 8000 12 0,12209500 0,12178500 (-0.3%) Same as VADDCUW and VSUBCUW, overall performance gain but it uses more TCGop (4 before the patch, 6 after). Signed-off-by: Lucas Mateus Castro (alqotel) Reviewed-by: Richard Henderson Message-Id: <20221019125040.48028-8-lucas.araujo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/helper.h | 6 ++-- target/ppc/insn32.decode | 6 ++++ target/ppc/int_helper.c | 13 +++----- target/ppc/translate/vmx-impl.c.inc | 49 +++++++++++++++++++++++++++-- target/ppc/translate/vmx-ops.c.inc | 3 -- 5 files changed, 60 insertions(+), 17 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 71c22efc2e..fd8280dfa7 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -146,9 +146,9 @@ DEF_HELPER_FLAGS_1(ftsqrt, TCG_CALL_NO_RWG_SE, i32, i64) DEF_HELPER_FLAGS_4(VAVGUB, TCG_CALL_NO_RWG, void, avr, avr, avr, i32) DEF_HELPER_FLAGS_4(VAVGUH, TCG_CALL_NO_RWG, void, avr, avr, avr, i32) DEF_HELPER_FLAGS_4(VAVGUW, TCG_CALL_NO_RWG, void, avr, avr, avr, i32) -DEF_HELPER_FLAGS_3(vabsdub, TCG_CALL_NO_RWG, void, avr, avr, avr) -DEF_HELPER_FLAGS_3(vabsduh, TCG_CALL_NO_RWG, void, avr, avr, avr) -DEF_HELPER_FLAGS_3(vabsduw, TCG_CALL_NO_RWG, void, avr, avr, avr) +DEF_HELPER_FLAGS_4(VABSDUB, TCG_CALL_NO_RWG, void, avr, avr, avr, i32) +DEF_HELPER_FLAGS_4(VABSDUH, TCG_CALL_NO_RWG, void, avr, avr, avr, i32) +DEF_HELPER_FLAGS_4(VABSDUW, TCG_CALL_NO_RWG, void, avr, avr, avr, i32) DEF_HELPER_FLAGS_4(VAVGSB, TCG_CALL_NO_RWG, void, avr, avr, avr, i32) DEF_HELPER_FLAGS_4(VAVGSH, TCG_CALL_NO_RWG, void, avr, avr, avr, i32) DEF_HELPER_FLAGS_4(VAVGSW, TCG_CALL_NO_RWG, void, avr, avr, avr, i32) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 53dd45bbab..1214af7394 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -528,6 +528,12 @@ VAVGUB 000100 ..... ..... ..... 10000000010 @VX VAVGUH 000100 ..... ..... ..... 10001000010 @VX VAVGUW 000100 ..... ..... ..... 10010000010 @VX +## Vector Integer Absolute Difference Instructions + +VABSDUB 000100 ..... ..... ..... 10000000011 @VX +VABSDUH 000100 ..... ..... ..... 10001000011 @VX +VABSDUW 000100 ..... ..... ..... 10010000011 @VX + ## Vector Bit Manipulation Instruction VGNB 000100 ..... -- ... ..... 10011001100 @VX_n diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index bda76e54d4..d97a7f1f28 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -589,8 +589,8 @@ VAVG(VAVGSW, s32, int64_t) VAVG(VAVGUW, u32, uint64_t) #undef VAVG -#define VABSDU_DO(name, element) \ -void helper_v##name(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ +#define VABSDU(name, element) \ +void helper_##name(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, uint32_t v)\ { \ int i; \ \ @@ -606,12 +606,9 @@ void helper_v##name(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ * name - instruction mnemonic suffix (b: byte, h: halfword, w: word) * element - element type to access from vector */ -#define VABSDU(type, element) \ - VABSDU_DO(absdu##type, element) -VABSDU(b, u8) -VABSDU(h, u16) -VABSDU(w, u32) -#undef VABSDU_DO +VABSDU(VABSDUB, u8) +VABSDU(VABSDUH, u16) +VABSDU(VABSDUW, u32) #undef VABSDU #define VCF(suffix, cvt, element) \ diff --git a/target/ppc/translate/vmx-impl.c.inc b/target/ppc/translate/vmx-impl.c.inc index 195c601f7a..7741f2eb49 100644 --- a/target/ppc/translate/vmx-impl.c.inc +++ b/target/ppc/translate/vmx-impl.c.inc @@ -431,9 +431,6 @@ GEN_VXFORM_V(vminsb, MO_8, tcg_gen_gvec_smin, 1, 12); GEN_VXFORM_V(vminsh, MO_16, tcg_gen_gvec_smin, 1, 13); GEN_VXFORM_V(vminsw, MO_32, tcg_gen_gvec_smin, 1, 14); GEN_VXFORM_V(vminsd, MO_64, tcg_gen_gvec_smin, 1, 15); -GEN_VXFORM(vabsdub, 1, 16); -GEN_VXFORM(vabsduh, 1, 17); -GEN_VXFORM(vabsduw, 1, 18); GEN_VXFORM(vmrghb, 6, 0); GEN_VXFORM(vmrghh, 6, 1); GEN_VXFORM(vmrghw, 6, 2); @@ -3455,6 +3452,52 @@ TRANS_FLAGS(ALTIVEC, VAVGUB, do_vx_vavg, 0, MO_8) TRANS_FLAGS(ALTIVEC, VAVGUH, do_vx_vavg, 0, MO_16) TRANS_FLAGS(ALTIVEC, VAVGUW, do_vx_vavg, 0, MO_32) +static void gen_vabsdu(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b) +{ + tcg_gen_umax_vec(vece, t, a, b); + tcg_gen_umin_vec(vece, a, a, b); + tcg_gen_sub_vec(vece, t, t, a); +} + +static bool do_vabsdu(DisasContext *ctx, arg_VX *a, const int vece) +{ + static const TCGOpcode vecop_list[] = { + INDEX_op_umax_vec, INDEX_op_umin_vec, INDEX_op_sub_vec, 0 + }; + + static const GVecGen3 op[] = { + { + .fniv = gen_vabsdu, + .fno = gen_helper_VABSDUB, + .opt_opc = vecop_list, + .vece = MO_8 + }, + { + .fniv = gen_vabsdu, + .fno = gen_helper_VABSDUH, + .opt_opc = vecop_list, + .vece = MO_16 + }, + { + .fniv = gen_vabsdu, + .fno = gen_helper_VABSDUW, + .opt_opc = vecop_list, + .vece = MO_32 + }, + }; + + REQUIRE_VECTOR(ctx); + + tcg_gen_gvec_3(avr_full_offset(a->vrt), avr_full_offset(a->vra), + avr_full_offset(a->vrb), 16, 16, &op[vece]); + + return true; +} + +TRANS_FLAGS2(ISA300, VABSDUB, do_vabsdu, MO_8) +TRANS_FLAGS2(ISA300, VABSDUH, do_vabsdu, MO_16) +TRANS_FLAGS2(ISA300, VABSDUW, do_vabsdu, MO_32) + static bool do_vdiv_vmod(DisasContext *ctx, arg_VX *a, const int vece, void (*func_32)(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b), void (*func_64)(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)) diff --git a/target/ppc/translate/vmx-ops.c.inc b/target/ppc/translate/vmx-ops.c.inc index 02db51def0..33fec8aca4 100644 --- a/target/ppc/translate/vmx-ops.c.inc +++ b/target/ppc/translate/vmx-ops.c.inc @@ -83,9 +83,6 @@ GEN_VXFORM(vminsb, 1, 12), GEN_VXFORM(vminsh, 1, 13), GEN_VXFORM(vminsw, 1, 14), GEN_VXFORM_207(vminsd, 1, 15), -GEN_VXFORM(vabsdub, 1, 16), -GEN_VXFORM(vabsduh, 1, 17), -GEN_VXFORM(vabsduw, 1, 18), GEN_VXFORM(vmrghb, 6, 0), GEN_VXFORM(vmrghh, 6, 1), GEN_VXFORM(vmrghw, 6, 2), From a5b36805192ac12f114c45e9c8ccbe4ce9ba1cf9 Mon Sep 17 00:00:00 2001 From: "Lucas Mateus Castro (alqotel)" Date: Wed, 19 Oct 2022 09:50:36 -0300 Subject: [PATCH 350/705] target/ppc: Use gvec to decode XV[N]ABS[DS]P/XVNEG[DS]P Moved XVABSSP, XVABSDP, XVNABSSP,XVNABSDP, XVNEGSP and XVNEGDP to decodetree and used gvec to translate them. xvabssp: rept loop master patch 8 12500 0,00477900 0,00476000 (-0.4%) 25 4000 0,00442800 0,00353300 (-20.2%) 100 1000 0,00478700 0,00366100 (-23.5%) 500 200 0,00973200 0,00649400 (-33.3%) 2500 40 0,03165200 0,02226700 (-29.7%) 8000 12 0,09315900 0,06674900 (-28.3%) xvabsdp: rept loop master patch 8 12500 0,00475000 0,00474400 (-0.1%) 25 4000 0,00355600 0,00367500 (+3.3%) 100 1000 0,00444200 0,00366000 (-17.6%) 500 200 0,00942700 0,00732400 (-22.3%) 2500 40 0,02990000 0,02308500 (-22.8%) 8000 12 0,08770300 0,06683800 (-23.8%) xvnabssp: rept loop master patch 8 12500 0,00494500 0,00492900 (-0.3%) 25 4000 0,00397700 0,00338600 (-14.9%) 100 1000 0,00421400 0,00353500 (-16.1%) 500 200 0,01048000 0,00707100 (-32.5%) 2500 40 0,03251500 0,02238300 (-31.2%) 8000 12 0,08889100 0,06469800 (-27.2%) xvnabsdp: rept loop master patch 8 12500 0,00511000 0,00492700 (-3.6%) 25 4000 0,00398800 0,00381500 (-4.3%) 100 1000 0,00390500 0,00365900 (-6.3%) 500 200 0,00924800 0,00784600 (-15.2%) 2500 40 0,03138900 0,02391600 (-23.8%) 8000 12 0,09654200 0,05684600 (-41.1%) xvnegsp: rept loop master patch 8 12500 0,00493900 0,00452800 (-8.3%) 25 4000 0,00369100 0,00366800 (-0.6%) 100 1000 0,00371100 0,00380000 (+2.4%) 500 200 0,00991100 0,00652300 (-34.2%) 2500 40 0,03025800 0,02422300 (-19.9%) 8000 12 0,09251100 0,06457600 (-30.2%) xvnegdp: rept loop master patch 8 12500 0,00474900 0,00454400 (-4.3%) 25 4000 0,00353100 0,00325600 (-7.8%) 100 1000 0,00398600 0,00366800 (-8.0%) 500 200 0,01032300 0,00702400 (-32.0%) 2500 40 0,03125000 0,02422400 (-22.5%) 8000 12 0,09475100 0,06173000 (-34.9%) This one to me seemed the opposite of the previous instructions, as it looks like there was an improvement in the translation time (itself not a surprise as operations were done twice before so there was the need to translate twice as many TCGop) Signed-off-by: Lucas Mateus Castro (alqotel) Reviewed-by: Richard Henderson Message-Id: <20221019125040.48028-9-lucas.araujo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/insn32.decode | 9 ++++ target/ppc/translate/vsx-impl.c.inc | 73 ++++++++++++++++++++++++++--- target/ppc/translate/vsx-ops.c.inc | 6 --- 3 files changed, 76 insertions(+), 12 deletions(-) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 1214af7394..395339ce40 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -754,6 +754,15 @@ STXVRHX 011111 ..... ..... ..... 0010101101 . @X_TSX STXVRWX 011111 ..... ..... ..... 0011001101 . @X_TSX STXVRDX 011111 ..... ..... ..... 0011101101 . @X_TSX +## VSX Vector Binary Floating-Point Sign Manipulation Instructions + +XVABSDP 111100 ..... 00000 ..... 111011001 .. @XX2 +XVABSSP 111100 ..... 00000 ..... 110011001 .. @XX2 +XVNABSDP 111100 ..... 00000 ..... 111101001 .. @XX2 +XVNABSSP 111100 ..... 00000 ..... 110101001 .. @XX2 +XVNEGDP 111100 ..... 00000 ..... 111111001 .. @XX2 +XVNEGSP 111100 ..... 00000 ..... 110111001 .. @XX2 + ## VSX Scalar Multiply-Add Instructions XSMADDADP 111100 ..... ..... ..... 00100001 . . . @XX3 diff --git a/target/ppc/translate/vsx-impl.c.inc b/target/ppc/translate/vsx-impl.c.inc index e6e5c45ffd..8717e20d08 100644 --- a/target/ppc/translate/vsx-impl.c.inc +++ b/target/ppc/translate/vsx-impl.c.inc @@ -782,15 +782,76 @@ static void glue(gen_, name)(DisasContext *ctx) \ tcg_temp_free_i64(sgm); \ } -VSX_VECTOR_MOVE(xvabsdp, OP_ABS, SGN_MASK_DP) -VSX_VECTOR_MOVE(xvnabsdp, OP_NABS, SGN_MASK_DP) -VSX_VECTOR_MOVE(xvnegdp, OP_NEG, SGN_MASK_DP) VSX_VECTOR_MOVE(xvcpsgndp, OP_CPSGN, SGN_MASK_DP) -VSX_VECTOR_MOVE(xvabssp, OP_ABS, SGN_MASK_SP) -VSX_VECTOR_MOVE(xvnabssp, OP_NABS, SGN_MASK_SP) -VSX_VECTOR_MOVE(xvnegsp, OP_NEG, SGN_MASK_SP) VSX_VECTOR_MOVE(xvcpsgnsp, OP_CPSGN, SGN_MASK_SP) +#define TCG_OP_IMM_i64(FUNC, OP, IMM) \ + static void FUNC(TCGv_i64 t, TCGv_i64 b) \ + { \ + OP(t, b, IMM); \ + } + +TCG_OP_IMM_i64(do_xvabssp_i64, tcg_gen_andi_i64, ~SGN_MASK_SP) +TCG_OP_IMM_i64(do_xvnabssp_i64, tcg_gen_ori_i64, SGN_MASK_SP) +TCG_OP_IMM_i64(do_xvnegsp_i64, tcg_gen_xori_i64, SGN_MASK_SP) +TCG_OP_IMM_i64(do_xvabsdp_i64, tcg_gen_andi_i64, ~SGN_MASK_DP) +TCG_OP_IMM_i64(do_xvnabsdp_i64, tcg_gen_ori_i64, SGN_MASK_DP) +TCG_OP_IMM_i64(do_xvnegdp_i64, tcg_gen_xori_i64, SGN_MASK_DP) +#undef TCG_OP_IMM_i64 + +static void xv_msb_op1(unsigned vece, TCGv_vec t, TCGv_vec b, + void (*tcg_gen_op_vec)(unsigned, TCGv_vec, TCGv_vec, TCGv_vec)) +{ + uint64_t msb = (vece == MO_32) ? SGN_MASK_SP : SGN_MASK_DP; + tcg_gen_op_vec(vece, t, b, tcg_constant_vec_matching(t, vece, msb)); +} + +static void do_xvabs_vec(unsigned vece, TCGv_vec t, TCGv_vec b) +{ + xv_msb_op1(vece, t, b, tcg_gen_andc_vec); +} + +static void do_xvnabs_vec(unsigned vece, TCGv_vec t, TCGv_vec b) +{ + xv_msb_op1(vece, t, b, tcg_gen_or_vec); +} + +static void do_xvneg_vec(unsigned vece, TCGv_vec t, TCGv_vec b) +{ + xv_msb_op1(vece, t, b, tcg_gen_xor_vec); +} + +static bool do_vsx_msb_op(DisasContext *ctx, arg_XX2 *a, unsigned vece, + void (*vec)(unsigned, TCGv_vec, TCGv_vec), + void (*i64)(TCGv_i64, TCGv_i64)) +{ + static const TCGOpcode vecop_list[] = { + 0 + }; + + const GVecGen2 op = { + .fni8 = i64, + .fniv = vec, + .opt_opc = vecop_list, + .vece = vece + }; + + REQUIRE_INSNS_FLAGS2(ctx, VSX); + REQUIRE_VSX(ctx); + + tcg_gen_gvec_2(vsr_full_offset(a->xt), vsr_full_offset(a->xb), + 16, 16, &op); + + return true; +} + +TRANS(XVABSDP, do_vsx_msb_op, MO_64, do_xvabs_vec, do_xvabsdp_i64) +TRANS(XVNABSDP, do_vsx_msb_op, MO_64, do_xvnabs_vec, do_xvnabsdp_i64) +TRANS(XVNEGDP, do_vsx_msb_op, MO_64, do_xvneg_vec, do_xvnegdp_i64) +TRANS(XVABSSP, do_vsx_msb_op, MO_32, do_xvabs_vec, do_xvabssp_i64) +TRANS(XVNABSSP, do_vsx_msb_op, MO_32, do_xvnabs_vec, do_xvnabssp_i64) +TRANS(XVNEGSP, do_vsx_msb_op, MO_32, do_xvneg_vec, do_xvnegsp_i64) + #define VSX_CMP(name, op1, op2, inval, type) \ static void gen_##name(DisasContext *ctx) \ { \ diff --git a/target/ppc/translate/vsx-ops.c.inc b/target/ppc/translate/vsx-ops.c.inc index bff14bbece..b77324e0a8 100644 --- a/target/ppc/translate/vsx-ops.c.inc +++ b/target/ppc/translate/vsx-ops.c.inc @@ -165,13 +165,7 @@ GEN_XX3FORM(name, opc2, opc3 | 1, fl2) GEN_XX2FORM_DCMX(xvtstdcdp, 0x14, 0x1E, PPC2_ISA300), GEN_XX2FORM_DCMX(xvtstdcsp, 0x14, 0x1A, PPC2_ISA300), -GEN_XX2FORM(xvabsdp, 0x12, 0x1D, PPC2_VSX), -GEN_XX2FORM(xvnabsdp, 0x12, 0x1E, PPC2_VSX), -GEN_XX2FORM(xvnegdp, 0x12, 0x1F, PPC2_VSX), GEN_XX3FORM(xvcpsgndp, 0x00, 0x1E, PPC2_VSX), -GEN_XX2FORM(xvabssp, 0x12, 0x19, PPC2_VSX), -GEN_XX2FORM(xvnabssp, 0x12, 0x1A, PPC2_VSX), -GEN_XX2FORM(xvnegsp, 0x12, 0x1B, PPC2_VSX), GEN_XX3FORM(xvcpsgnsp, 0x00, 0x1A, PPC2_VSX), GEN_XX3FORM(xsadddp, 0x00, 0x04, PPC2_VSX), From 95a89d3118590aaed3a56b52e08246cdb51a108e Mon Sep 17 00:00:00 2001 From: "Lucas Mateus Castro (alqotel)" Date: Wed, 19 Oct 2022 09:50:37 -0300 Subject: [PATCH 351/705] target/ppc: Use gvec to decode XVCPSGN[SD]P Moved XVCPSGNSP and XVCPSGNDP to decodetree and used gvec to translate them. xvcpsgnsp: rept loop master patch 8 12500 0,00561400 0,00537900 (-4.2%) 25 4000 0,00562100 0,00400000 (-28.8%) 100 1000 0,00696900 0,00416300 (-40.3%) 500 200 0,02211900 0,00840700 (-62.0%) 2500 40 0,09328600 0,02728300 (-70.8%) 8000 12 0,27295300 0,06867800 (-74.8%) xvcpsgndp: rept loop master patch 8 12500 0,00556300 0,00584200 (+5.0%) 25 4000 0,00482700 0,00431700 (-10.6%) 100 1000 0,00585800 0,00464400 (-20.7%) 500 200 0,01565300 0,00839700 (-46.4%) 2500 40 0,05766500 0,02430600 (-57.8%) 8000 12 0,19875300 0,07947100 (-60.0%) Like the previous instructions there seemed to be a improvement on translation time. Signed-off-by: Lucas Mateus Castro (alqotel) Reviewed-by: Richard Henderson Message-Id: <20221019125040.48028-10-lucas.araujo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/insn32.decode | 2 + target/ppc/translate/vsx-impl.c.inc | 109 ++++++++++++++-------------- target/ppc/translate/vsx-ops.c.inc | 3 - 3 files changed, 55 insertions(+), 59 deletions(-) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 395339ce40..3594c0c960 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -762,6 +762,8 @@ XVNABSDP 111100 ..... 00000 ..... 111101001 .. @XX2 XVNABSSP 111100 ..... 00000 ..... 110101001 .. @XX2 XVNEGDP 111100 ..... 00000 ..... 111111001 .. @XX2 XVNEGSP 111100 ..... 00000 ..... 110111001 .. @XX2 +XVCPSGNDP 111100 ..... ..... ..... 11110000 ... @XX3 +XVCPSGNSP 111100 ..... ..... ..... 11010000 ... @XX3 ## VSX Scalar Multiply-Add Instructions diff --git a/target/ppc/translate/vsx-impl.c.inc b/target/ppc/translate/vsx-impl.c.inc index 8717e20d08..1c289238ec 100644 --- a/target/ppc/translate/vsx-impl.c.inc +++ b/target/ppc/translate/vsx-impl.c.inc @@ -729,62 +729,6 @@ VSX_SCALAR_MOVE_QP(xsnabsqp, OP_NABS, SGN_MASK_DP) VSX_SCALAR_MOVE_QP(xsnegqp, OP_NEG, SGN_MASK_DP) VSX_SCALAR_MOVE_QP(xscpsgnqp, OP_CPSGN, SGN_MASK_DP) -#define VSX_VECTOR_MOVE(name, op, sgn_mask) \ -static void glue(gen_, name)(DisasContext *ctx) \ - { \ - TCGv_i64 xbh, xbl, sgm; \ - if (unlikely(!ctx->vsx_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_VSXU); \ - return; \ - } \ - xbh = tcg_temp_new_i64(); \ - xbl = tcg_temp_new_i64(); \ - sgm = tcg_temp_new_i64(); \ - get_cpu_vsr(xbh, xB(ctx->opcode), true); \ - get_cpu_vsr(xbl, xB(ctx->opcode), false); \ - tcg_gen_movi_i64(sgm, sgn_mask); \ - switch (op) { \ - case OP_ABS: { \ - tcg_gen_andc_i64(xbh, xbh, sgm); \ - tcg_gen_andc_i64(xbl, xbl, sgm); \ - break; \ - } \ - case OP_NABS: { \ - tcg_gen_or_i64(xbh, xbh, sgm); \ - tcg_gen_or_i64(xbl, xbl, sgm); \ - break; \ - } \ - case OP_NEG: { \ - tcg_gen_xor_i64(xbh, xbh, sgm); \ - tcg_gen_xor_i64(xbl, xbl, sgm); \ - break; \ - } \ - case OP_CPSGN: { \ - TCGv_i64 xah = tcg_temp_new_i64(); \ - TCGv_i64 xal = tcg_temp_new_i64(); \ - get_cpu_vsr(xah, xA(ctx->opcode), true); \ - get_cpu_vsr(xal, xA(ctx->opcode), false); \ - tcg_gen_and_i64(xah, xah, sgm); \ - tcg_gen_and_i64(xal, xal, sgm); \ - tcg_gen_andc_i64(xbh, xbh, sgm); \ - tcg_gen_andc_i64(xbl, xbl, sgm); \ - tcg_gen_or_i64(xbh, xbh, xah); \ - tcg_gen_or_i64(xbl, xbl, xal); \ - tcg_temp_free_i64(xah); \ - tcg_temp_free_i64(xal); \ - break; \ - } \ - } \ - set_cpu_vsr(xT(ctx->opcode), xbh, true); \ - set_cpu_vsr(xT(ctx->opcode), xbl, false); \ - tcg_temp_free_i64(xbh); \ - tcg_temp_free_i64(xbl); \ - tcg_temp_free_i64(sgm); \ - } - -VSX_VECTOR_MOVE(xvcpsgndp, OP_CPSGN, SGN_MASK_DP) -VSX_VECTOR_MOVE(xvcpsgnsp, OP_CPSGN, SGN_MASK_SP) - #define TCG_OP_IMM_i64(FUNC, OP, IMM) \ static void FUNC(TCGv_i64 t, TCGv_i64 b) \ { \ @@ -852,6 +796,59 @@ TRANS(XVABSSP, do_vsx_msb_op, MO_32, do_xvabs_vec, do_xvabssp_i64) TRANS(XVNABSSP, do_vsx_msb_op, MO_32, do_xvnabs_vec, do_xvnabssp_i64) TRANS(XVNEGSP, do_vsx_msb_op, MO_32, do_xvneg_vec, do_xvnegsp_i64) +static void do_xvcpsgndp_i64(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b) +{ + tcg_gen_andi_i64(a, a, SGN_MASK_DP); + tcg_gen_andi_i64(b, b, ~SGN_MASK_DP); + tcg_gen_or_i64(t, a, b); +} + +static void do_xvcpsgnsp_i64(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b) +{ + tcg_gen_andi_i64(a, a, SGN_MASK_SP); + tcg_gen_andi_i64(b, b, ~SGN_MASK_SP); + tcg_gen_or_i64(t, a, b); +} + +static void do_xvcpsgn_vec(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b) +{ + uint64_t msb = (vece == MO_32) ? SGN_MASK_SP : SGN_MASK_DP; + tcg_gen_bitsel_vec(vece, t, tcg_constant_vec_matching(t, vece, msb), a, b); +} + +static bool do_xvcpsgn(DisasContext *ctx, arg_XX3 *a, unsigned vece) +{ + static const TCGOpcode vecop_list[] = { + 0 + }; + + static const GVecGen3 op[] = { + { + .fni8 = do_xvcpsgnsp_i64, + .fniv = do_xvcpsgn_vec, + .opt_opc = vecop_list, + .vece = MO_32 + }, + { + .fni8 = do_xvcpsgndp_i64, + .fniv = do_xvcpsgn_vec, + .opt_opc = vecop_list, + .vece = MO_64 + }, + }; + + REQUIRE_INSNS_FLAGS2(ctx, VSX); + REQUIRE_VSX(ctx); + + tcg_gen_gvec_3(vsr_full_offset(a->xt), vsr_full_offset(a->xa), + vsr_full_offset(a->xb), 16, 16, &op[vece - MO_32]); + + return true; +} + +TRANS(XVCPSGNSP, do_xvcpsgn, MO_32) +TRANS(XVCPSGNDP, do_xvcpsgn, MO_64) + #define VSX_CMP(name, op1, op2, inval, type) \ static void gen_##name(DisasContext *ctx) \ { \ diff --git a/target/ppc/translate/vsx-ops.c.inc b/target/ppc/translate/vsx-ops.c.inc index b77324e0a8..f7d7377379 100644 --- a/target/ppc/translate/vsx-ops.c.inc +++ b/target/ppc/translate/vsx-ops.c.inc @@ -165,9 +165,6 @@ GEN_XX3FORM(name, opc2, opc3 | 1, fl2) GEN_XX2FORM_DCMX(xvtstdcdp, 0x14, 0x1E, PPC2_ISA300), GEN_XX2FORM_DCMX(xvtstdcsp, 0x14, 0x1A, PPC2_ISA300), -GEN_XX3FORM(xvcpsgndp, 0x00, 0x1E, PPC2_VSX), -GEN_XX3FORM(xvcpsgnsp, 0x00, 0x1A, PPC2_VSX), - GEN_XX3FORM(xsadddp, 0x00, 0x04, PPC2_VSX), GEN_VSX_XFORM_300(xsaddqp, 0x04, 0x00, 0x0), GEN_XX3FORM(xssubdp, 0x00, 0x05, PPC2_VSX), From a70a5247104d3d7a8cf584f20d73f41bef643a19 Mon Sep 17 00:00:00 2001 From: "Lucas Mateus Castro (alqotel)" Date: Wed, 19 Oct 2022 09:50:38 -0300 Subject: [PATCH 352/705] target/ppc: Moved XVTSTDC[DS]P to decodetree Moved XVTSTDCSP and XVTSTDCDP to decodetree an restructured the helper to be simpler and do all decoding in the decodetree (so XB, XT and DCMX are all calculated outside the helper). Obs: The tests in this one are slightly different, these are the sum of these instructions with all possible immediate and those instructions are repeated 10 times. xvtstdcsp: rept loop master patch 8 12500 2,76402100 2,70699100 (-2.1%) 25 4000 2,64867100 2,67884100 (+1.1%) 100 1000 2,73806300 2,78701000 (+1.8%) 500 200 3,44666500 3,61027600 (+4.7%) 2500 40 5,85790200 6,47475500 (+10.5%) 8000 12 15,22102100 17,46062900 (+14.7%) xvtstdcdp: rept loop master patch 8 12500 2,11818000 1,61065300 (-24.0%) 25 4000 2,04573400 1,60132200 (-21.7%) 100 1000 2,13834100 1,69988100 (-20.5%) 500 200 2,73977000 2,48631700 (-9.3%) 2500 40 5,05067000 5,25914100 (+4.1%) 8000 12 14,60507800 15,93704900 (+9.1%) Signed-off-by: Lucas Mateus Castro (alqotel) Reviewed-by: Richard Henderson Message-Id: <20221019125040.48028-11-lucas.araujo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/fpu_helper.c | 39 +++++++++++++++++++++++++++-- target/ppc/helper.h | 4 +-- target/ppc/insn32.decode | 5 ++++ target/ppc/translate/vsx-impl.c.inc | 28 +++++++++++++++++++-- target/ppc/translate/vsx-ops.c.inc | 8 ------ 5 files changed, 70 insertions(+), 14 deletions(-) diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c index ae25f32d6e..960a76a8a5 100644 --- a/target/ppc/fpu_helper.c +++ b/target/ppc/fpu_helper.c @@ -3295,11 +3295,46 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ } \ } -VSX_TEST_DC(xvtstdcdp, 2, xB(opcode), float64, VsrD(i), VsrD(i), UINT64_MAX, 0) -VSX_TEST_DC(xvtstdcsp, 4, xB(opcode), float32, VsrW(i), VsrW(i), UINT32_MAX, 0) VSX_TEST_DC(xststdcdp, 1, xB(opcode), float64, VsrD(0), VsrD(0), 0, 1) VSX_TEST_DC(xststdcqp, 1, (rB(opcode) + 32), float128, f128, VsrD(0), 0, 1) +#define VSX_TSTDC(tp) \ +static int32_t tp##_tstdc(tp b, uint32_t dcmx) \ +{ \ + uint32_t match = 0; \ + uint32_t sign = tp##_is_neg(b); \ + if (tp##_is_any_nan(b)) { \ + match = extract32(dcmx, 6, 1); \ + } else if (tp##_is_infinity(b)) { \ + match = extract32(dcmx, 4 + !sign, 1); \ + } else if (tp##_is_zero(b)) { \ + match = extract32(dcmx, 2 + !sign, 1); \ + } else if (tp##_is_zero_or_denormal(b)) { \ + match = extract32(dcmx, 0 + !sign, 1); \ + } \ + return (match != 0); \ +} + +VSX_TSTDC(float32) +VSX_TSTDC(float64) +#undef VSX_TSTDC + +void helper_XVTSTDCDP(ppc_vsr_t *t, ppc_vsr_t *b, uint64_t dcmx, uint32_t v) +{ + int i; + for (i = 0; i < 2; i++) { + t->s64[i] = (int64_t)-float64_tstdc(b->f64[i], dcmx); + } +} + +void helper_XVTSTDCSP(ppc_vsr_t *t, ppc_vsr_t *b, uint64_t dcmx, uint32_t v) +{ + int i; + for (i = 0; i < 4; i++) { + t->s32[i] = (int32_t)-float32_tstdc(b->f32[i], dcmx); + } +} + void helper_xststdcsp(CPUPPCState *env, uint32_t opcode, ppc_vsr_t *xb) { uint32_t dcmx, sign, exp; diff --git a/target/ppc/helper.h b/target/ppc/helper.h index fd8280dfa7..9e5d11939b 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -517,8 +517,8 @@ DEF_HELPER_3(xvcvsxdsp, void, env, vsr, vsr) DEF_HELPER_3(xvcvuxdsp, void, env, vsr, vsr) DEF_HELPER_3(xvcvsxwsp, void, env, vsr, vsr) DEF_HELPER_3(xvcvuxwsp, void, env, vsr, vsr) -DEF_HELPER_2(xvtstdcsp, void, env, i32) -DEF_HELPER_2(xvtstdcdp, void, env, i32) +DEF_HELPER_FLAGS_4(XVTSTDCSP, TCG_CALL_NO_RWG, void, vsr, vsr, i64, i32) +DEF_HELPER_FLAGS_4(XVTSTDCDP, TCG_CALL_NO_RWG, void, vsr, vsr, i64, i32) DEF_HELPER_3(xvrspi, void, env, vsr, vsr) DEF_HELPER_3(xvrspic, void, env, vsr, vsr) DEF_HELPER_3(xvrspim, void, env, vsr, vsr) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 3594c0c960..44905edd29 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -199,6 +199,9 @@ @XX2_uim4 ...... ..... . uim:4 ..... ......... .. &XX2_uim xt=%xx_xt xb=%xx_xb +%xx_uim7 6:1 2:1 16:5 +@XX2_uim7 ...... ..... ..... ..... .... . ... . .. &XX2_uim xt=%xx_xt xb=%xx_xb uim=%xx_uim7 + &XX2_bf_xb bf xb @XX2_bf_xb ...... bf:3 .. ..... ..... ......... . . &XX2_bf_xb xb=%xx_xb @@ -848,6 +851,8 @@ XSCVSPDPN 111100 ..... ----- ..... 101001011 .. @XX2 ## VSX Binary Floating-Point Math Support Instructions XVXSIGSP 111100 ..... 01001 ..... 111011011 .. @XX2 +XVTSTDCDP 111100 ..... ..... ..... 1111 . 101 ... @XX2_uim7 +XVTSTDCSP 111100 ..... ..... ..... 1101 . 101 ... @XX2_uim7 ## VSX Vector Test Least-Significant Bit by Byte Instruction diff --git a/target/ppc/translate/vsx-impl.c.inc b/target/ppc/translate/vsx-impl.c.inc index 1c289238ec..287ea8e2ce 100644 --- a/target/ppc/translate/vsx-impl.c.inc +++ b/target/ppc/translate/vsx-impl.c.inc @@ -630,6 +630,8 @@ static void gen_mtvsrws(DisasContext *ctx) #define OP_CPSGN 4 #define SGN_MASK_DP 0x8000000000000000ull #define SGN_MASK_SP 0x8000000080000000ull +#define EXP_MASK_DP 0x7FF0000000000000ull +#define EXP_MASK_SP 0x7F8000007F800000ull #define VSX_SCALAR_MOVE(name, op, sgn_mask) \ static void glue(gen_, name)(DisasContext *ctx) \ @@ -1110,6 +1112,30 @@ GEN_VSX_HELPER_X2(xscvhpdp, 0x16, 0x15, 0x10, PPC2_ISA300) GEN_VSX_HELPER_R2(xscvsdqp, 0x04, 0x1A, 0x0A, PPC2_ISA300) GEN_VSX_HELPER_X2(xscvspdp, 0x12, 0x14, 0, PPC2_VSX) +static bool do_xvtstdc(DisasContext *ctx, arg_XX2_uim *a, unsigned vece) +{ + static const GVecGen2i op[] = { + { + .fnoi = gen_helper_XVTSTDCSP, + .vece = MO_32 + }, + { + .fnoi = gen_helper_XVTSTDCDP, + .vece = MO_64 + }, + }; + + REQUIRE_VSX(ctx); + + tcg_gen_gvec_2i(vsr_full_offset(a->xt), vsr_full_offset(a->xb), + 16, 16, (int32_t)(a->uim), &op[vece - MO_32]); + + return true; +} + +TRANS_FLAGS2(VSX, XVTSTDCSP, do_xvtstdc, MO_32) +TRANS_FLAGS2(VSX, XVTSTDCDP, do_xvtstdc, MO_64) + bool trans_XSCVSPDPN(DisasContext *ctx, arg_XX2 *a) { TCGv_i64 tmp; @@ -1213,8 +1239,6 @@ GEN_VSX_HELPER_X2(xvrspic, 0x16, 0x0A, 0, PPC2_VSX) GEN_VSX_HELPER_X2(xvrspim, 0x12, 0x0B, 0, PPC2_VSX) GEN_VSX_HELPER_X2(xvrspip, 0x12, 0x0A, 0, PPC2_VSX) GEN_VSX_HELPER_X2(xvrspiz, 0x12, 0x09, 0, PPC2_VSX) -GEN_VSX_HELPER_2(xvtstdcsp, 0x14, 0x1A, 0, PPC2_VSX) -GEN_VSX_HELPER_2(xvtstdcdp, 0x14, 0x1E, 0, PPC2_VSX) static bool trans_XXPERM(DisasContext *ctx, arg_XX3 *a) { diff --git a/target/ppc/translate/vsx-ops.c.inc b/target/ppc/translate/vsx-ops.c.inc index f7d7377379..4b317d4b06 100644 --- a/target/ppc/translate/vsx-ops.c.inc +++ b/target/ppc/translate/vsx-ops.c.inc @@ -157,14 +157,6 @@ GEN_XX2FORM_EO(xvxexpdp, 0x16, 0x1D, 0x00, PPC2_ISA300), GEN_XX2FORM_EO(xvxsigdp, 0x16, 0x1D, 0x01, PPC2_ISA300), GEN_XX2FORM_EO(xvxexpsp, 0x16, 0x1D, 0x08, PPC2_ISA300), -/* DCMX = bit[25] << 6 | bit[29] << 5 | bit[11:15] */ -#define GEN_XX2FORM_DCMX(name, opc2, opc3, fl2) \ -GEN_XX3FORM(name, opc2, opc3 | 0, fl2), \ -GEN_XX3FORM(name, opc2, opc3 | 1, fl2) - -GEN_XX2FORM_DCMX(xvtstdcdp, 0x14, 0x1E, PPC2_ISA300), -GEN_XX2FORM_DCMX(xvtstdcsp, 0x14, 0x1A, PPC2_ISA300), - GEN_XX3FORM(xsadddp, 0x00, 0x04, PPC2_VSX), GEN_VSX_XFORM_300(xsaddqp, 0x04, 0x00, 0x0), GEN_XX3FORM(xssubdp, 0x00, 0x05, PPC2_VSX), From da3c53bac3d8f3040b35ef3d98a64b592bb28a66 Mon Sep 17 00:00:00 2001 From: "Lucas Mateus Castro (alqotel)" Date: Wed, 19 Oct 2022 09:50:39 -0300 Subject: [PATCH 353/705] target/ppc: Moved XSTSTDC[QDS]P to decodetree Moved XSTSTDCSP, XSTSTDCDP and XSTSTDCQP to decodetree and moved some of its decoding away from the helper as previously the DCMX, XB and BF were calculated in the helper with the help of cpu_env, now that part was moved to the decodetree with the rest. xvtstdcsp: rept loop master patch 8 12500 1,85393600 1,94683600 (+5.0%) 25 4000 1,78779800 1,92479000 (+7.7%) 100 1000 2,12775000 2,28895500 (+7.6%) 500 200 2,99655300 3,23102900 (+7.8%) 2500 40 6,89082200 7,44827500 (+8.1%) 8000 12 17,50585500 18,95152100 (+8.3%) xvtstdcdp: rept loop master patch 8 12500 1,39043100 1,33539800 (-4.0%) 25 4000 1,35731800 1,37347800 (+1.2%) 100 1000 1,51514800 1,56053000 (+3.0%) 500 200 2,21014400 2,47906000 (+12.2%) 2500 40 5,39488200 6,68766700 (+24.0%) 8000 12 13,98623900 18,17661900 (+30.0%) xvtstdcdp: rept loop master patch 8 12500 1,35123800 1,34455800 (-0.5%) 25 4000 1,36441200 1,36759600 (+0.2%) 100 1000 1,49763500 1,54138400 (+2.9%) 500 200 2,19020200 2,46196400 (+12.4%) 2500 40 5,39265700 6,68147900 (+23.9%) 8000 12 14,04163600 18,19669600 (+29.6%) As some values are now decoded outside the helper and passed to it as an argument the number of arguments of the helper increased, the number of TCGop needed to load the arguments increased. I suspect that's why the slow-down in the tests with a high REPT but low LOOP. Signed-off-by: Lucas Mateus Castro (alqotel) Reviewed-by: Richard Henderson Message-Id: <20221019125040.48028-12-lucas.araujo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/fpu_helper.c | 108 ++++++++-------------------- target/ppc/helper.h | 6 +- target/ppc/insn32.decode | 6 ++ target/ppc/translate/vsx-impl.c.inc | 20 +++++- target/ppc/translate/vsx-ops.c.inc | 4 -- 5 files changed, 57 insertions(+), 87 deletions(-) diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c index 960a76a8a5..a66e16c212 100644 --- a/target/ppc/fpu_helper.c +++ b/target/ppc/fpu_helper.c @@ -3241,63 +3241,6 @@ void helper_XVXSIGSP(ppc_vsr_t *xt, ppc_vsr_t *xb) *xt = t; } -/* - * VSX_TEST_DC - VSX floating point test data class - * op - instruction mnemonic - * nels - number of elements (1, 2 or 4) - * xbn - VSR register number - * tp - type (float32 or float64) - * fld - vsr_t field (VsrD(*) or VsrW(*)) - * tfld - target vsr_t field (VsrD(*) or VsrW(*)) - * fld_max - target field max - * scrf - set result in CR and FPCC - */ -#define VSX_TEST_DC(op, nels, xbn, tp, fld, tfld, fld_max, scrf) \ -void helper_##op(CPUPPCState *env, uint32_t opcode) \ -{ \ - ppc_vsr_t *xt = &env->vsr[xT(opcode)]; \ - ppc_vsr_t *xb = &env->vsr[xbn]; \ - ppc_vsr_t t = { }; \ - uint32_t i, sign, dcmx; \ - uint32_t cc, match = 0; \ - \ - if (!scrf) { \ - dcmx = DCMX_XV(opcode); \ - } else { \ - t = *xt; \ - dcmx = DCMX(opcode); \ - } \ - \ - for (i = 0; i < nels; i++) { \ - sign = tp##_is_neg(xb->fld); \ - if (tp##_is_any_nan(xb->fld)) { \ - match = extract32(dcmx, 6, 1); \ - } else if (tp##_is_infinity(xb->fld)) { \ - match = extract32(dcmx, 4 + !sign, 1); \ - } else if (tp##_is_zero(xb->fld)) { \ - match = extract32(dcmx, 2 + !sign, 1); \ - } else if (tp##_is_zero_or_denormal(xb->fld)) { \ - match = extract32(dcmx, 0 + !sign, 1); \ - } \ - \ - if (scrf) { \ - cc = sign << CRF_LT_BIT | match << CRF_EQ_BIT; \ - env->fpscr &= ~FP_FPCC; \ - env->fpscr |= cc << FPSCR_FPCC; \ - env->crf[BF(opcode)] = cc; \ - } else { \ - t.tfld = match ? fld_max : 0; \ - } \ - match = 0; \ - } \ - if (!scrf) { \ - *xt = t; \ - } \ -} - -VSX_TEST_DC(xststdcdp, 1, xB(opcode), float64, VsrD(0), VsrD(0), 0, 1) -VSX_TEST_DC(xststdcqp, 1, (rB(opcode) + 32), float128, f128, VsrD(0), 0, 1) - #define VSX_TSTDC(tp) \ static int32_t tp##_tstdc(tp b, uint32_t dcmx) \ { \ @@ -3317,6 +3260,7 @@ static int32_t tp##_tstdc(tp b, uint32_t dcmx) \ VSX_TSTDC(float32) VSX_TSTDC(float64) +VSX_TSTDC(float128) #undef VSX_TSTDC void helper_XVTSTDCDP(ppc_vsr_t *t, ppc_vsr_t *b, uint64_t dcmx, uint32_t v) @@ -3335,34 +3279,44 @@ void helper_XVTSTDCSP(ppc_vsr_t *t, ppc_vsr_t *b, uint64_t dcmx, uint32_t v) } } -void helper_xststdcsp(CPUPPCState *env, uint32_t opcode, ppc_vsr_t *xb) +static bool not_SP_value(float64 val) { - uint32_t dcmx, sign, exp; - uint32_t cc, match = 0, not_sp = 0; - float64 arg = xb->VsrD(0); - float64 arg_sp; + return val != helper_todouble(helper_tosingle(val)); +} - dcmx = DCMX(opcode); - exp = (arg >> 52) & 0x7FF; - sign = float64_is_neg(arg); - - if (float64_is_any_nan(arg)) { - match = extract32(dcmx, 6, 1); - } else if (float64_is_infinity(arg)) { - match = extract32(dcmx, 4 + !sign, 1); - } else if (float64_is_zero(arg)) { - match = extract32(dcmx, 2 + !sign, 1); - } else if (float64_is_zero_or_denormal(arg) || (exp > 0 && exp < 0x381)) { - match = extract32(dcmx, 0 + !sign, 1); +/* + * VSX_XS_TSTDC - VSX Scalar Test Data Class + * NAME - instruction name + * FLD - vsr_t field (VsrD(0) or f128) + * TP - type (float64 or float128) + */ +#define VSX_XS_TSTDC(NAME, FLD, TP) \ + void helper_##NAME(CPUPPCState *env, uint32_t bf, \ + uint32_t dcmx, ppc_vsr_t *b) \ + { \ + uint32_t cc, match, sign = TP##_is_neg(b->FLD); \ + match = TP##_tstdc(b->FLD, dcmx); \ + cc = sign << CRF_LT_BIT | match << CRF_EQ_BIT; \ + env->fpscr &= ~FP_FPCC; \ + env->fpscr |= cc << FPSCR_FPCC; \ + env->crf[bf] = cc; \ } - arg_sp = helper_todouble(helper_tosingle(arg)); - not_sp = arg != arg_sp; +VSX_XS_TSTDC(XSTSTDCDP, VsrD(0), float64) +VSX_XS_TSTDC(XSTSTDCQP, f128, float128) +#undef VSX_XS_TSTDC +void helper_XSTSTDCSP(CPUPPCState *env, uint32_t bf, + uint32_t dcmx, ppc_vsr_t *b) +{ + uint32_t cc, match, sign = float64_is_neg(b->VsrD(0)); + uint32_t exp = (b->VsrD(0) >> 52) & 0x7FF; + int not_sp = (int)not_SP_value(b->VsrD(0)); + match = float64_tstdc(b->VsrD(0), dcmx) || (exp > 0 && exp < 0x381); cc = sign << CRF_LT_BIT | match << CRF_EQ_BIT | not_sp << CRF_SO_BIT; env->fpscr &= ~FP_FPCC; env->fpscr |= cc << FPSCR_FPCC; - env->crf[BF(opcode)] = cc; + env->crf[bf] = cc; } void helper_xsrqpi(CPUPPCState *env, uint32_t opcode, diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 9e5d11939b..8344fe39c6 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -417,9 +417,9 @@ DEF_HELPER_3(xscvuxdsp, void, env, vsr, vsr) DEF_HELPER_3(xscvsxdsp, void, env, vsr, vsr) DEF_HELPER_4(xscvudqp, void, env, i32, vsr, vsr) DEF_HELPER_3(xscvuxddp, void, env, vsr, vsr) -DEF_HELPER_3(xststdcsp, void, env, i32, vsr) -DEF_HELPER_2(xststdcdp, void, env, i32) -DEF_HELPER_2(xststdcqp, void, env, i32) +DEF_HELPER_4(XSTSTDCSP, void, env, i32, i32, vsr) +DEF_HELPER_4(XSTSTDCDP, void, env, i32, i32, vsr) +DEF_HELPER_4(XSTSTDCQP, void, env, i32, i32, vsr) DEF_HELPER_3(xsrdpi, void, env, vsr, vsr) DEF_HELPER_3(xsrdpic, void, env, vsr, vsr) DEF_HELPER_3(xsrdpim, void, env, vsr, vsr) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 44905edd29..f8f589e9fd 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -202,6 +202,9 @@ %xx_uim7 6:1 2:1 16:5 @XX2_uim7 ...... ..... ..... ..... .... . ... . .. &XX2_uim xt=%xx_xt xb=%xx_xb uim=%xx_uim7 +&XX2_bf_uim bf xb uim +@XX2_bf_uim ...... bf:3 uim:7 ..... ......... . . &XX2_bf_uim + &XX2_bf_xb bf xb @XX2_bf_xb ...... bf:3 .. ..... ..... ......... . . &XX2_bf_xb xb=%xx_xb @@ -853,6 +856,9 @@ XSCVSPDPN 111100 ..... ----- ..... 101001011 .. @XX2 XVXSIGSP 111100 ..... 01001 ..... 111011011 .. @XX2 XVTSTDCDP 111100 ..... ..... ..... 1111 . 101 ... @XX2_uim7 XVTSTDCSP 111100 ..... ..... ..... 1101 . 101 ... @XX2_uim7 +XSTSTDCSP 111100 ... ....... ..... 100101010 . - @XX2_bf_uim xb=%xx_xb +XSTSTDCDP 111100 ... ....... ..... 101101010 . - @XX2_bf_uim xb=%xx_xb +XSTSTDCQP 111111 ... ....... xb:5 1011000100 - @XX2_bf_uim ## VSX Vector Test Least-Significant Bit by Byte Instruction diff --git a/target/ppc/translate/vsx-impl.c.inc b/target/ppc/translate/vsx-impl.c.inc index 287ea8e2ce..af410cbf1b 100644 --- a/target/ppc/translate/vsx-impl.c.inc +++ b/target/ppc/translate/vsx-impl.c.inc @@ -1136,6 +1136,23 @@ static bool do_xvtstdc(DisasContext *ctx, arg_XX2_uim *a, unsigned vece) TRANS_FLAGS2(VSX, XVTSTDCSP, do_xvtstdc, MO_32) TRANS_FLAGS2(VSX, XVTSTDCDP, do_xvtstdc, MO_64) +static bool do_XX2_bf_uim(DisasContext *ctx, arg_XX2_bf_uim *a, bool vsr, + void (*gen_helper)(TCGv_env, TCGv_i32, TCGv_i32, TCGv_ptr)) +{ + TCGv_ptr xb; + + REQUIRE_VSX(ctx); + xb = vsr ? gen_vsr_ptr(a->xb) : gen_avr_ptr(a->xb); + gen_helper(cpu_env, tcg_constant_i32(a->bf), tcg_constant_i32(a->uim), xb); + tcg_temp_free_ptr(xb); + + return true; +} + +TRANS_FLAGS2(ISA300, XSTSTDCSP, do_XX2_bf_uim, true, gen_helper_XSTSTDCSP) +TRANS_FLAGS2(ISA300, XSTSTDCDP, do_XX2_bf_uim, true, gen_helper_XSTSTDCDP) +TRANS_FLAGS2(ISA300, XSTSTDCQP, do_XX2_bf_uim, false, gen_helper_XSTSTDCQP) + bool trans_XSCVSPDPN(DisasContext *ctx, arg_XX2 *a) { TCGv_i64 tmp; @@ -1182,9 +1199,6 @@ GEN_VSX_HELPER_X2(xssqrtsp, 0x16, 0x00, 0, PPC2_VSX207) GEN_VSX_HELPER_X2(xsrsqrtesp, 0x14, 0x00, 0, PPC2_VSX207) GEN_VSX_HELPER_X2(xscvsxdsp, 0x10, 0x13, 0, PPC2_VSX207) GEN_VSX_HELPER_X2(xscvuxdsp, 0x10, 0x12, 0, PPC2_VSX207) -GEN_VSX_HELPER_X1(xststdcsp, 0x14, 0x12, 0, PPC2_ISA300) -GEN_VSX_HELPER_2(xststdcdp, 0x14, 0x16, 0, PPC2_ISA300) -GEN_VSX_HELPER_2(xststdcqp, 0x04, 0x16, 0, PPC2_ISA300) GEN_VSX_HELPER_X3(xvadddp, 0x00, 0x0C, 0, PPC2_VSX) GEN_VSX_HELPER_X3(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX) diff --git a/target/ppc/translate/vsx-ops.c.inc b/target/ppc/translate/vsx-ops.c.inc index 4b317d4b06..a3ba094d62 100644 --- a/target/ppc/translate/vsx-ops.c.inc +++ b/target/ppc/translate/vsx-ops.c.inc @@ -147,10 +147,6 @@ GEN_HANDLER_E(xsiexpdp, 0x3C, 0x16, 0x1C, 0, PPC_NONE, PPC2_ISA300), GEN_VSX_XFORM_300(xsiexpqp, 0x4, 0x1B, 0x00000001), #endif -GEN_XX2FORM(xststdcdp, 0x14, 0x16, PPC2_ISA300), -GEN_XX2FORM(xststdcsp, 0x14, 0x12, PPC2_ISA300), -GEN_VSX_XFORM_300(xststdcqp, 0x04, 0x16, 0x00000001), - GEN_XX3FORM(xviexpsp, 0x00, 0x1B, PPC2_ISA300), GEN_XX3FORM(xviexpdp, 0x00, 0x1F, PPC2_ISA300), GEN_XX2FORM_EO(xvxexpdp, 0x16, 0x1D, 0x00, PPC2_ISA300), From bbd8dd5e45b831ef3fda585cf80d08f45cdaba95 Mon Sep 17 00:00:00 2001 From: "Lucas Mateus Castro (alqotel)" Date: Wed, 19 Oct 2022 09:50:40 -0300 Subject: [PATCH 354/705] target/ppc: Use gvec to decode XVTSTDC[DS]P Used gvec to translate XVTSTDCSP and XVTSTDCDP. xvtstdcsp: rept loop imm master version prev version current version 25 4000 0 0,206200 0,040730 (-80.2%) 0,040740 (-80.2%) 25 4000 1 0,205120 0,053650 (-73.8%) 0,053510 (-73.9%) 25 4000 3 0,206160 0,058630 (-71.6%) 0,058570 (-71.6%) 25 4000 51 0,217110 0,191490 (-11.8%) 0,192320 (-11.4%) 25 4000 127 0,206160 0,191490 (-7.1%) 0,192640 (-6.6%) 8000 12 0 1,234719 0,418833 (-66.1%) 0,386365 (-68.7%) 8000 12 1 1,232417 1,435979 (+16.5%) 1,462792 (+18.7%) 8000 12 3 1,232760 1,766073 (+43.3%) 1,743990 (+41.5%) 8000 12 51 1,239281 1,319562 (+6.5%) 1,423479 (+14.9%) 8000 12 127 1,231708 1,315760 (+6.8%) 1,426667 (+15.8%) xvtstdcdp: rept loop imm master version prev version current version 25 4000 0 0,159930 0,040830 (-74.5%) 0,040610 (-74.6%) 25 4000 1 0,160640 0,053670 (-66.6%) 0,053480 (-66.7%) 25 4000 3 0,160020 0,063030 (-60.6%) 0,062960 (-60.7%) 25 4000 51 0,160410 0,128620 (-19.8%) 0,127470 (-20.5%) 25 4000 127 0,160330 0,127670 (-20.4%) 0,128690 (-19.7%) 8000 12 0 1,190365 0,422146 (-64.5%) 0,388417 (-67.4%) 8000 12 1 1,191292 1,445312 (+21.3%) 1,428698 (+19.9%) 8000 12 3 1,188687 1,980656 (+66.6%) 1,975354 (+66.2%) 8000 12 51 1,191250 1,264500 (+6.1%) 1,355083 (+13.8%) 8000 12 127 1,197313 1,266729 (+5.8%) 1,349156 (+12.7%) Overall, these instructions are the hardest ones to measure performance as the gvec implementation is affected by the immediate. Above there are 5 different scenarios when it comes to immediate and 2 when it comes to rept/loop combination. The immediates scenarios are: all bits are 0 therefore the target register should just be changed to 0, with 1 bit set, with 2 bits set in a combination the new implementation can deal with using gvec, 4 bits set and the new implementation can't deal with it using gvec and all bits set. The rept/loop scenarios are high loop and low rept (so it should spend more time executing it than translating it) and high rept low loop (so it should spend more time translating it than executing this code). These comparisons are between the upstream version, a previous similar implementation and a one with a cleaner code(this one). For a comparison with o previous different implementation: <20221010191356.83659-13-lucas.araujo@eldorado.org.br> Signed-off-by: Lucas Mateus Castro (alqotel) Reviewed-by: Richard Henderson Message-Id: <20221019125040.48028-13-lucas.araujo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/translate/vsx-impl.c.inc | 167 ++++++++++++++++++++++++++-- 1 file changed, 157 insertions(+), 10 deletions(-) diff --git a/target/ppc/translate/vsx-impl.c.inc b/target/ppc/translate/vsx-impl.c.inc index af410cbf1b..4deb29ee42 100644 --- a/target/ppc/translate/vsx-impl.c.inc +++ b/target/ppc/translate/vsx-impl.c.inc @@ -632,6 +632,8 @@ static void gen_mtvsrws(DisasContext *ctx) #define SGN_MASK_SP 0x8000000080000000ull #define EXP_MASK_DP 0x7FF0000000000000ull #define EXP_MASK_SP 0x7F8000007F800000ull +#define FRC_MASK_DP (~(SGN_MASK_DP | EXP_MASK_DP)) +#define FRC_MASK_SP (~(SGN_MASK_SP | EXP_MASK_SP)) #define VSX_SCALAR_MOVE(name, op, sgn_mask) \ static void glue(gen_, name)(DisasContext *ctx) \ @@ -1112,23 +1114,168 @@ GEN_VSX_HELPER_X2(xscvhpdp, 0x16, 0x15, 0x10, PPC2_ISA300) GEN_VSX_HELPER_R2(xscvsdqp, 0x04, 0x1A, 0x0A, PPC2_ISA300) GEN_VSX_HELPER_X2(xscvspdp, 0x12, 0x14, 0, PPC2_VSX) +/* test if +Inf */ +static void gen_is_pos_inf(unsigned vece, TCGv_vec t, TCGv_vec b, int64_t v) +{ + uint64_t exp_msk = (vece == MO_32) ? (uint32_t)EXP_MASK_SP : EXP_MASK_DP; + tcg_gen_cmp_vec(TCG_COND_EQ, vece, t, b, + tcg_constant_vec_matching(t, vece, exp_msk)); +} + +/* test if -Inf */ +static void gen_is_neg_inf(unsigned vece, TCGv_vec t, TCGv_vec b, int64_t v) +{ + uint64_t exp_msk = (vece == MO_32) ? (uint32_t)EXP_MASK_SP : EXP_MASK_DP; + uint64_t sgn_msk = (vece == MO_32) ? (uint32_t)SGN_MASK_SP : SGN_MASK_DP; + tcg_gen_cmp_vec(TCG_COND_EQ, vece, t, b, + tcg_constant_vec_matching(t, vece, sgn_msk | exp_msk)); +} + +/* test if +Inf or -Inf */ +static void gen_is_any_inf(unsigned vece, TCGv_vec t, TCGv_vec b, int64_t v) +{ + uint64_t exp_msk = (vece == MO_32) ? (uint32_t)EXP_MASK_SP : EXP_MASK_DP; + uint64_t sgn_msk = (vece == MO_32) ? (uint32_t)SGN_MASK_SP : SGN_MASK_DP; + tcg_gen_andc_vec(vece, b, b, tcg_constant_vec_matching(t, vece, sgn_msk)); + tcg_gen_cmp_vec(TCG_COND_EQ, vece, t, b, + tcg_constant_vec_matching(t, vece, exp_msk)); +} + +/* test if +0 */ +static void gen_is_pos_zero(unsigned vece, TCGv_vec t, TCGv_vec b, int64_t v) +{ + tcg_gen_cmp_vec(TCG_COND_EQ, vece, t, b, + tcg_constant_vec_matching(t, vece, 0)); +} + +/* test if -0 */ +static void gen_is_neg_zero(unsigned vece, TCGv_vec t, TCGv_vec b, int64_t v) +{ + uint64_t sgn_msk = (vece == MO_32) ? (uint32_t)SGN_MASK_SP : SGN_MASK_DP; + tcg_gen_cmp_vec(TCG_COND_EQ, vece, t, b, + tcg_constant_vec_matching(t, vece, sgn_msk)); +} + +/* test if +0 or -0 */ +static void gen_is_any_zero(unsigned vece, TCGv_vec t, TCGv_vec b, int64_t v) +{ + uint64_t sgn_msk = (vece == MO_32) ? (uint32_t)SGN_MASK_SP : SGN_MASK_DP; + tcg_gen_andc_vec(vece, b, b, tcg_constant_vec_matching(t, vece, sgn_msk)); + tcg_gen_cmp_vec(TCG_COND_EQ, vece, t, b, + tcg_constant_vec_matching(t, vece, 0)); +} + +/* test if +Denormal */ +static void gen_is_pos_denormal(unsigned vece, TCGv_vec t, + TCGv_vec b, int64_t v) +{ + uint64_t frc_msk = (vece == MO_32) ? (uint32_t)FRC_MASK_SP : FRC_MASK_DP; + tcg_gen_cmp_vec(TCG_COND_LEU, vece, t, b, + tcg_constant_vec_matching(t, vece, frc_msk)); + tcg_gen_cmp_vec(TCG_COND_NE, vece, b, b, + tcg_constant_vec_matching(t, vece, 0)); + tcg_gen_and_vec(vece, t, t, b); +} + +/* test if -Denormal */ +static void gen_is_neg_denormal(unsigned vece, TCGv_vec t, + TCGv_vec b, int64_t v) +{ + uint64_t sgn_msk = (vece == MO_32) ? (uint32_t)SGN_MASK_SP : SGN_MASK_DP; + uint64_t frc_msk = (vece == MO_32) ? (uint32_t)FRC_MASK_SP : FRC_MASK_DP; + tcg_gen_cmp_vec(TCG_COND_LEU, vece, t, b, + tcg_constant_vec_matching(t, vece, sgn_msk | frc_msk)); + tcg_gen_cmp_vec(TCG_COND_GTU, vece, b, b, + tcg_constant_vec_matching(t, vece, sgn_msk)); + tcg_gen_and_vec(vece, t, t, b); +} + +/* test if +Denormal or -Denormal */ +static void gen_is_any_denormal(unsigned vece, TCGv_vec t, + TCGv_vec b, int64_t v) +{ + uint64_t sgn_msk = (vece == MO_32) ? (uint32_t)SGN_MASK_SP : SGN_MASK_DP; + uint64_t frc_msk = (vece == MO_32) ? (uint32_t)FRC_MASK_SP : FRC_MASK_DP; + tcg_gen_andc_vec(vece, b, b, tcg_constant_vec_matching(t, vece, sgn_msk)); + tcg_gen_cmp_vec(TCG_COND_LE, vece, t, b, + tcg_constant_vec_matching(t, vece, frc_msk)); + tcg_gen_cmp_vec(TCG_COND_NE, vece, b, b, + tcg_constant_vec_matching(t, vece, 0)); + tcg_gen_and_vec(vece, t, t, b); +} + +/* test if NaN */ +static void gen_is_nan(unsigned vece, TCGv_vec t, TCGv_vec b, int64_t v) +{ + uint64_t exp_msk = (vece == MO_32) ? (uint32_t)EXP_MASK_SP : EXP_MASK_DP; + uint64_t sgn_msk = (vece == MO_32) ? (uint32_t)SGN_MASK_SP : SGN_MASK_DP; + tcg_gen_and_vec(vece, b, b, tcg_constant_vec_matching(t, vece, ~sgn_msk)); + tcg_gen_cmp_vec(TCG_COND_GT, vece, t, b, + tcg_constant_vec_matching(t, vece, exp_msk)); +} + static bool do_xvtstdc(DisasContext *ctx, arg_XX2_uim *a, unsigned vece) { - static const GVecGen2i op[] = { - { - .fnoi = gen_helper_XVTSTDCSP, - .vece = MO_32 - }, - { - .fnoi = gen_helper_XVTSTDCDP, - .vece = MO_64 - }, + static const TCGOpcode vecop_list[] = { + INDEX_op_cmp_vec, 0 + }; + + GVecGen2i op = { + .fnoi = (vece == MO_32) ? gen_helper_XVTSTDCSP : gen_helper_XVTSTDCDP, + .vece = vece, + .opt_opc = vecop_list }; REQUIRE_VSX(ctx); + switch (a->uim) { + case 0: + set_cpu_vsr(a->xt, tcg_constant_i64(0), true); + set_cpu_vsr(a->xt, tcg_constant_i64(0), false); + return true; + case ((1 << 0) | (1 << 1)): + /* test if +Denormal or -Denormal */ + op.fniv = gen_is_any_denormal; + break; + case (1 << 0): + /* test if -Denormal */ + op.fniv = gen_is_neg_denormal; + break; + case (1 << 1): + /* test if +Denormal */ + op.fniv = gen_is_pos_denormal; + break; + case ((1 << 2) | (1 << 3)): + /* test if +0 or -0 */ + op.fniv = gen_is_any_zero; + break; + case (1 << 2): + /* test if -0 */ + op.fniv = gen_is_neg_zero; + break; + case (1 << 3): + /* test if +0 */ + op.fniv = gen_is_pos_zero; + break; + case ((1 << 4) | (1 << 5)): + /* test if +Inf or -Inf */ + op.fniv = gen_is_any_inf; + break; + case (1 << 4): + /* test if -Inf */ + op.fniv = gen_is_neg_inf; + break; + case (1 << 5): + /* test if +Inf */ + op.fniv = gen_is_pos_inf; + break; + case (1 << 6): + /* test if NaN */ + op.fniv = gen_is_nan; + break; + } tcg_gen_gvec_2i(vsr_full_offset(a->xt), vsr_full_offset(a->xb), - 16, 16, (int32_t)(a->uim), &op[vece - MO_32]); + 16, 16, a->uim, &op); return true; } From f003109f710bb39a78c27ce18aa10579340f5a3f Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Tue, 11 Oct 2022 17:48:01 -0300 Subject: [PATCH 355/705] target/ppc: define PPC_INTERRUPT_* values directly This enum defines the bit positions in env->pending_interrupts for each interrupt. However, except for the comparison in kvmppc_set_interrupt, the values are always used as (1 << PPC_INTERRUPT_*). Define them directly like that to save some clutter. No functional change intended. Reviewed-by: David Gibson Signed-off-by: Matheus Ferst Message-Id: <20221011204829.1641124-2-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/ppc.c | 10 +++--- hw/ppc/trace-events | 2 +- target/ppc/cpu.h | 40 +++++++++++----------- target/ppc/cpu_init.c | 56 +++++++++++++++--------------- target/ppc/excp_helper.c | 74 ++++++++++++++++++++-------------------- target/ppc/misc_helper.c | 6 ++-- 6 files changed, 94 insertions(+), 94 deletions(-) diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c index 690f448cb9..77e611e81c 100644 --- a/hw/ppc/ppc.c +++ b/hw/ppc/ppc.c @@ -40,7 +40,7 @@ static void cpu_ppc_tb_stop (CPUPPCState *env); static void cpu_ppc_tb_start (CPUPPCState *env); -void ppc_set_irq(PowerPCCPU *cpu, int n_IRQ, int level) +void ppc_set_irq(PowerPCCPU *cpu, int irq, int level) { CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; @@ -56,21 +56,21 @@ void ppc_set_irq(PowerPCCPU *cpu, int n_IRQ, int level) old_pending = env->pending_interrupts; if (level) { - env->pending_interrupts |= 1 << n_IRQ; + env->pending_interrupts |= irq; cpu_interrupt(cs, CPU_INTERRUPT_HARD); } else { - env->pending_interrupts &= ~(1 << n_IRQ); + env->pending_interrupts &= ~irq; if (env->pending_interrupts == 0) { cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } } if (old_pending != env->pending_interrupts) { - kvmppc_set_interrupt(cpu, n_IRQ, level); + kvmppc_set_interrupt(cpu, irq, level); } - trace_ppc_irq_set_exit(env, n_IRQ, level, env->pending_interrupts, + trace_ppc_irq_set_exit(env, irq, level, env->pending_interrupts, CPU(cpu)->interrupt_request); if (locked) { diff --git a/hw/ppc/trace-events b/hw/ppc/trace-events index a07d5aca0f..956938ebcd 100644 --- a/hw/ppc/trace-events +++ b/hw/ppc/trace-events @@ -127,7 +127,7 @@ ppc40x_set_tb_clk(uint32_t value) "new frequency %" PRIu32 ppc40x_timers_init(uint32_t value) "frequency %" PRIu32 ppc_irq_set(void *env, uint32_t pin, uint32_t level) "env [%p] pin %d level %d" -ppc_irq_set_exit(void *env, uint32_t n_IRQ, uint32_t level, uint32_t pending, uint32_t request) "env [%p] n_IRQ %d level %d => pending 0x%08" PRIx32 " req 0x%08" PRIx32 +ppc_irq_set_exit(void *env, uint32_t irq, uint32_t level, uint32_t pending, uint32_t request) "env [%p] irq 0x%05" PRIx32 " level %d => pending 0x%08" PRIx32 " req 0x%08" PRIx32 ppc_irq_set_state(const char *name, uint32_t level) "\"%s\" level %d" ppc_irq_reset(const char *name) "%s" ppc_irq_cpu(const char *action) "%s" diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index cca6c4e51c..2433756973 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -2416,27 +2416,27 @@ enum { /* Hardware exceptions definitions */ enum { /* External hardware exception sources */ - PPC_INTERRUPT_RESET = 0, /* Reset exception */ - PPC_INTERRUPT_WAKEUP, /* Wakeup exception */ - PPC_INTERRUPT_MCK, /* Machine check exception */ - PPC_INTERRUPT_EXT, /* External interrupt */ - PPC_INTERRUPT_SMI, /* System management interrupt */ - PPC_INTERRUPT_CEXT, /* Critical external interrupt */ - PPC_INTERRUPT_DEBUG, /* External debug exception */ - PPC_INTERRUPT_THERM, /* Thermal exception */ + PPC_INTERRUPT_RESET = 0x00001, /* Reset exception */ + PPC_INTERRUPT_WAKEUP = 0x00002, /* Wakeup exception */ + PPC_INTERRUPT_MCK = 0x00004, /* Machine check exception */ + PPC_INTERRUPT_EXT = 0x00008, /* External interrupt */ + PPC_INTERRUPT_SMI = 0x00010, /* System management interrupt */ + PPC_INTERRUPT_CEXT = 0x00020, /* Critical external interrupt */ + PPC_INTERRUPT_DEBUG = 0x00040, /* External debug exception */ + PPC_INTERRUPT_THERM = 0x00080, /* Thermal exception */ /* Internal hardware exception sources */ - PPC_INTERRUPT_DECR, /* Decrementer exception */ - PPC_INTERRUPT_HDECR, /* Hypervisor decrementer exception */ - PPC_INTERRUPT_PIT, /* Programmable interval timer interrupt */ - PPC_INTERRUPT_FIT, /* Fixed interval timer interrupt */ - PPC_INTERRUPT_WDT, /* Watchdog timer interrupt */ - PPC_INTERRUPT_CDOORBELL, /* Critical doorbell interrupt */ - PPC_INTERRUPT_DOORBELL, /* Doorbell interrupt */ - PPC_INTERRUPT_PERFM, /* Performance monitor interrupt */ - PPC_INTERRUPT_HMI, /* Hypervisor Maintenance interrupt */ - PPC_INTERRUPT_HDOORBELL, /* Hypervisor Doorbell interrupt */ - PPC_INTERRUPT_HVIRT, /* Hypervisor virtualization interrupt */ - PPC_INTERRUPT_EBB, /* Event-based Branch exception */ + PPC_INTERRUPT_DECR = 0x00100, /* Decrementer exception */ + PPC_INTERRUPT_HDECR = 0x00200, /* Hypervisor decrementer exception */ + PPC_INTERRUPT_PIT = 0x00400, /* Programmable interval timer int. */ + PPC_INTERRUPT_FIT = 0x00800, /* Fixed interval timer interrupt */ + PPC_INTERRUPT_WDT = 0x01000, /* Watchdog timer interrupt */ + PPC_INTERRUPT_CDOORBELL = 0x02000, /* Critical doorbell interrupt */ + PPC_INTERRUPT_DOORBELL = 0x04000, /* Doorbell interrupt */ + PPC_INTERRUPT_PERFM = 0x08000, /* Performance monitor interrupt */ + PPC_INTERRUPT_HMI = 0x10000, /* Hypervisor Maintenance interrupt */ + PPC_INTERRUPT_HDOORBELL = 0x20000, /* Hypervisor Doorbell interrupt */ + PPC_INTERRUPT_HVIRT = 0x40000, /* Hypervisor virtualization interrupt */ + PPC_INTERRUPT_EBB = 0x80000, /* Event-based Branch exception */ }; /* Processor Compatibility mask (PCR) */ diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index 335351c226..07171c679c 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -5969,23 +5969,23 @@ static bool cpu_has_work_POWER7(CPUState *cs) if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) { return false; } - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) && + if ((env->pending_interrupts & PPC_INTERRUPT_EXT) && (env->spr[SPR_LPCR] & LPCR_P7_PECE0)) { return true; } - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) && + if ((env->pending_interrupts & PPC_INTERRUPT_DECR) && (env->spr[SPR_LPCR] & LPCR_P7_PECE1)) { return true; } - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) && + if ((env->pending_interrupts & PPC_INTERRUPT_MCK) && (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) { return true; } - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) && + if ((env->pending_interrupts & PPC_INTERRUPT_HMI) && (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) { return true; } - if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) { + if (env->pending_interrupts & PPC_INTERRUPT_RESET) { return true; } return false; @@ -6142,31 +6142,31 @@ static bool cpu_has_work_POWER8(CPUState *cs) if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) { return false; } - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) && + if ((env->pending_interrupts & PPC_INTERRUPT_EXT) && (env->spr[SPR_LPCR] & LPCR_P8_PECE2)) { return true; } - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) && + if ((env->pending_interrupts & PPC_INTERRUPT_DECR) && (env->spr[SPR_LPCR] & LPCR_P8_PECE3)) { return true; } - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) && + if ((env->pending_interrupts & PPC_INTERRUPT_MCK) && (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) { return true; } - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) && + if ((env->pending_interrupts & PPC_INTERRUPT_HMI) && (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) { return true; } - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) && + if ((env->pending_interrupts & PPC_INTERRUPT_DOORBELL) && (env->spr[SPR_LPCR] & LPCR_P8_PECE0)) { return true; } - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) && + if ((env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) && (env->spr[SPR_LPCR] & LPCR_P8_PECE1)) { return true; } - if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) { + if (env->pending_interrupts & PPC_INTERRUPT_RESET) { return true; } return false; @@ -6368,7 +6368,7 @@ static bool cpu_has_work_POWER9(CPUState *cs) return true; } /* External Exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) && + if ((env->pending_interrupts & PPC_INTERRUPT_EXT) && (env->spr[SPR_LPCR] & LPCR_EEE)) { bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); if (!heic || !FIELD_EX64_HV(env->msr) || @@ -6377,31 +6377,31 @@ static bool cpu_has_work_POWER9(CPUState *cs) } } /* Decrementer Exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) && + if ((env->pending_interrupts & PPC_INTERRUPT_DECR) && (env->spr[SPR_LPCR] & LPCR_DEE)) { return true; } /* Machine Check or Hypervisor Maintenance Exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK | - 1u << PPC_INTERRUPT_HMI)) && (env->spr[SPR_LPCR] & LPCR_OEE)) { + if ((env->pending_interrupts & (PPC_INTERRUPT_MCK | PPC_INTERRUPT_HMI)) + && (env->spr[SPR_LPCR] & LPCR_OEE)) { return true; } /* Privileged Doorbell Exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) && + if ((env->pending_interrupts & PPC_INTERRUPT_DOORBELL) && (env->spr[SPR_LPCR] & LPCR_PDEE)) { return true; } /* Hypervisor Doorbell Exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) && + if ((env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) && (env->spr[SPR_LPCR] & LPCR_HDEE)) { return true; } /* Hypervisor virtualization exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HVIRT)) && + if ((env->pending_interrupts & PPC_INTERRUPT_HVIRT) && (env->spr[SPR_LPCR] & LPCR_HVEE)) { return true; } - if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) { + if (env->pending_interrupts & PPC_INTERRUPT_RESET) { return true; } return false; @@ -6601,7 +6601,7 @@ static bool cpu_has_work_POWER10(CPUState *cs) return true; } /* External Exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) && + if ((env->pending_interrupts & PPC_INTERRUPT_EXT) && (env->spr[SPR_LPCR] & LPCR_EEE)) { bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); if (!heic || !FIELD_EX64_HV(env->msr) || @@ -6610,31 +6610,31 @@ static bool cpu_has_work_POWER10(CPUState *cs) } } /* Decrementer Exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) && + if ((env->pending_interrupts & PPC_INTERRUPT_DECR) && (env->spr[SPR_LPCR] & LPCR_DEE)) { return true; } /* Machine Check or Hypervisor Maintenance Exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK | - 1u << PPC_INTERRUPT_HMI)) && (env->spr[SPR_LPCR] & LPCR_OEE)) { + if ((env->pending_interrupts & (PPC_INTERRUPT_MCK | PPC_INTERRUPT_HMI)) + && (env->spr[SPR_LPCR] & LPCR_OEE)) { return true; } /* Privileged Doorbell Exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) && + if ((env->pending_interrupts & PPC_INTERRUPT_DOORBELL) && (env->spr[SPR_LPCR] & LPCR_PDEE)) { return true; } /* Hypervisor Doorbell Exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) && + if ((env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) && (env->spr[SPR_LPCR] & LPCR_HDEE)) { return true; } /* Hypervisor virtualization exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HVIRT)) && + if ((env->pending_interrupts & PPC_INTERRUPT_HVIRT) && (env->spr[SPR_LPCR] & LPCR_HVEE)) { return true; } - if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) { + if (env->pending_interrupts & PPC_INTERRUPT_RESET) { return true; } return false; diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 43f2480e94..d168789fc0 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -1689,21 +1689,21 @@ static void ppc_hw_interrupt(CPUPPCState *env) bool async_deliver; /* External reset */ - if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) { - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET); + if (env->pending_interrupts & PPC_INTERRUPT_RESET) { + env->pending_interrupts &= ~PPC_INTERRUPT_RESET; powerpc_excp(cpu, POWERPC_EXCP_RESET); return; } /* Machine check exception */ - if (env->pending_interrupts & (1 << PPC_INTERRUPT_MCK)) { - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_MCK); + if (env->pending_interrupts & PPC_INTERRUPT_MCK) { + env->pending_interrupts &= ~PPC_INTERRUPT_MCK; powerpc_excp(cpu, POWERPC_EXCP_MCHECK); return; } #if 0 /* TODO */ /* External debug exception */ - if (env->pending_interrupts & (1 << PPC_INTERRUPT_DEBUG)) { - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DEBUG); + if (env->pending_interrupts & PPC_INTERRUPT_DEBUG) { + env->pending_interrupts &= ~PPC_INTERRUPT_DEBUG; powerpc_excp(cpu, POWERPC_EXCP_DEBUG); return; } @@ -1718,19 +1718,19 @@ static void ppc_hw_interrupt(CPUPPCState *env) async_deliver = FIELD_EX64(env->msr, MSR, EE) || env->resume_as_sreset; /* Hypervisor decrementer exception */ - if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) { + if (env->pending_interrupts & PPC_INTERRUPT_HDECR) { /* LPCR will be clear when not supported so this will work */ bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE); if ((async_deliver || !FIELD_EX64_HV(env->msr)) && hdice) { /* HDEC clears on delivery */ - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR); + env->pending_interrupts &= ~PPC_INTERRUPT_HDECR; powerpc_excp(cpu, POWERPC_EXCP_HDECR); return; } } /* Hypervisor virtualization interrupt */ - if (env->pending_interrupts & (1 << PPC_INTERRUPT_HVIRT)) { + if (env->pending_interrupts & PPC_INTERRUPT_HVIRT) { /* LPCR will be clear when not supported so this will work */ bool hvice = !!(env->spr[SPR_LPCR] & LPCR_HVICE); if ((async_deliver || !FIELD_EX64_HV(env->msr)) && hvice) { @@ -1740,7 +1740,7 @@ static void ppc_hw_interrupt(CPUPPCState *env) } /* External interrupt can ignore MSR:EE under some circumstances */ - if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) { + if (env->pending_interrupts & PPC_INTERRUPT_EXT) { bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); /* HEIC blocks delivery to the hypervisor */ @@ -1757,45 +1757,45 @@ static void ppc_hw_interrupt(CPUPPCState *env) } if (FIELD_EX64(env->msr, MSR, CE)) { /* External critical interrupt */ - if (env->pending_interrupts & (1 << PPC_INTERRUPT_CEXT)) { + if (env->pending_interrupts & PPC_INTERRUPT_CEXT) { powerpc_excp(cpu, POWERPC_EXCP_CRITICAL); return; } } if (async_deliver != 0) { /* Watchdog timer on embedded PowerPC */ - if (env->pending_interrupts & (1 << PPC_INTERRUPT_WDT)) { - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_WDT); + if (env->pending_interrupts & PPC_INTERRUPT_WDT) { + env->pending_interrupts &= ~PPC_INTERRUPT_WDT; powerpc_excp(cpu, POWERPC_EXCP_WDT); return; } - if (env->pending_interrupts & (1 << PPC_INTERRUPT_CDOORBELL)) { - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CDOORBELL); + if (env->pending_interrupts & PPC_INTERRUPT_CDOORBELL) { + env->pending_interrupts &= ~PPC_INTERRUPT_CDOORBELL; powerpc_excp(cpu, POWERPC_EXCP_DOORCI); return; } /* Fixed interval timer on embedded PowerPC */ - if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) { - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT); + if (env->pending_interrupts & PPC_INTERRUPT_FIT) { + env->pending_interrupts &= ~PPC_INTERRUPT_FIT; powerpc_excp(cpu, POWERPC_EXCP_FIT); return; } /* Programmable interval timer on embedded PowerPC */ - if (env->pending_interrupts & (1 << PPC_INTERRUPT_PIT)) { - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PIT); + if (env->pending_interrupts & PPC_INTERRUPT_PIT) { + env->pending_interrupts &= ~PPC_INTERRUPT_PIT; powerpc_excp(cpu, POWERPC_EXCP_PIT); return; } /* Decrementer exception */ - if (env->pending_interrupts & (1 << PPC_INTERRUPT_DECR)) { + if (env->pending_interrupts & PPC_INTERRUPT_DECR) { if (ppc_decr_clear_on_delivery(env)) { - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DECR); + env->pending_interrupts &= ~PPC_INTERRUPT_DECR; } powerpc_excp(cpu, POWERPC_EXCP_DECR); return; } - if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) { - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL); + if (env->pending_interrupts & PPC_INTERRUPT_DOORBELL) { + env->pending_interrupts &= ~PPC_INTERRUPT_DOORBELL; if (is_book3s_arch2x(env)) { powerpc_excp(cpu, POWERPC_EXCP_SDOOR); } else { @@ -1803,31 +1803,31 @@ static void ppc_hw_interrupt(CPUPPCState *env) } return; } - if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDOORBELL)) { - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDOORBELL); + if (env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) { + env->pending_interrupts &= ~PPC_INTERRUPT_HDOORBELL; powerpc_excp(cpu, POWERPC_EXCP_SDOOR_HV); return; } - if (env->pending_interrupts & (1 << PPC_INTERRUPT_PERFM)) { - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PERFM); + if (env->pending_interrupts & PPC_INTERRUPT_PERFM) { + env->pending_interrupts &= ~PPC_INTERRUPT_PERFM; powerpc_excp(cpu, POWERPC_EXCP_PERFM); return; } /* Thermal interrupt */ - if (env->pending_interrupts & (1 << PPC_INTERRUPT_THERM)) { - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_THERM); + if (env->pending_interrupts & PPC_INTERRUPT_THERM) { + env->pending_interrupts &= ~PPC_INTERRUPT_THERM; powerpc_excp(cpu, POWERPC_EXCP_THERM); return; } /* EBB exception */ - if (env->pending_interrupts & (1 << PPC_INTERRUPT_EBB)) { + if (env->pending_interrupts & PPC_INTERRUPT_EBB) { /* * EBB exception must be taken in problem state and * with BESCR_GE set. */ if (FIELD_EX64(env->msr, MSR, PR) && (env->spr[SPR_BESCR] & BESCR_GE)) { - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_EBB); + env->pending_interrupts &= ~PPC_INTERRUPT_EBB; if (env->spr[SPR_BESCR] & BESCR_PMEO) { powerpc_excp(cpu, POWERPC_EXCP_PERFM_EBB); @@ -2104,7 +2104,7 @@ static void do_ebb(CPUPPCState *env, int ebb_excp) if (FIELD_EX64(env->msr, MSR, PR)) { powerpc_excp(cpu, ebb_excp); } else { - env->pending_interrupts |= 1 << PPC_INTERRUPT_EBB; + env->pending_interrupts |= PPC_INTERRUPT_EBB; cpu_interrupt(cs, CPU_INTERRUPT_HARD); } } @@ -2298,7 +2298,7 @@ void helper_msgclr(CPUPPCState *env, target_ulong rb) return; } - env->pending_interrupts &= ~(1 << irq); + env->pending_interrupts &= ~irq; } void helper_msgsnd(target_ulong rb) @@ -2317,7 +2317,7 @@ void helper_msgsnd(target_ulong rb) CPUPPCState *cenv = &cpu->env; if ((rb & DBELL_BRDCAST) || (cenv->spr[SPR_BOOKE_PIR] == pir)) { - cenv->pending_interrupts |= 1 << irq; + cenv->pending_interrupts |= irq; cpu_interrupt(cs, CPU_INTERRUPT_HARD); } } @@ -2342,7 +2342,7 @@ void helper_book3s_msgclr(CPUPPCState *env, target_ulong rb) return; } - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDOORBELL); + env->pending_interrupts &= ~PPC_INTERRUPT_HDOORBELL; } static void book3s_msgsnd_common(int pir, int irq) @@ -2356,7 +2356,7 @@ static void book3s_msgsnd_common(int pir, int irq) /* TODO: broadcast message to all threads of the same processor */ if (cenv->spr_cb[SPR_PIR].default_value == pir) { - cenv->pending_interrupts |= 1 << irq; + cenv->pending_interrupts |= irq; cpu_interrupt(cs, CPU_INTERRUPT_HARD); } } @@ -2383,7 +2383,7 @@ void helper_book3s_msgclrp(CPUPPCState *env, target_ulong rb) return; } - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL); + env->pending_interrupts &= ~PPC_INTERRUPT_DOORBELL; } /* diff --git a/target/ppc/misc_helper.c b/target/ppc/misc_helper.c index b0a5e7ce76..05e35572bc 100644 --- a/target/ppc/misc_helper.c +++ b/target/ppc/misc_helper.c @@ -163,7 +163,7 @@ target_ulong helper_load_dpdes(CPUPPCState *env) helper_hfscr_facility_check(env, HFSCR_MSGP, "load DPDES", HFSCR_IC_MSGP); /* TODO: TCG supports only one thread */ - if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) { + if (env->pending_interrupts & PPC_INTERRUPT_DOORBELL) { dpdes = 1; } @@ -185,10 +185,10 @@ void helper_store_dpdes(CPUPPCState *env, target_ulong val) } if (val & 0x1) { - env->pending_interrupts |= 1 << PPC_INTERRUPT_DOORBELL; + env->pending_interrupts |= PPC_INTERRUPT_DOORBELL; cpu_interrupt(cs, CPU_INTERRUPT_HARD); } else { - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL); + env->pending_interrupts &= ~PPC_INTERRUPT_DOORBELL; } } #endif /* defined(TARGET_PPC64) */ From 7b694df6a6deeac8ede0512f983c70463968021a Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Tue, 11 Oct 2022 17:48:02 -0300 Subject: [PATCH 356/705] target/ppc: always use ppc_set_irq to set env->pending_interrupts Use ppc_set_irq to raise/clear interrupts to ensure CPU_INTERRUPT_HARD will be set/reset accordingly. Reviewed-by: Fabiano Rosas Signed-off-by: Matheus Ferst Message-Id: <20221011204829.1641124-3-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/excp_helper.c | 17 +++++++---------- target/ppc/misc_helper.c | 9 ++------- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index d168789fc0..37d352619b 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -23,6 +23,7 @@ #include "exec/exec-all.h" #include "internal.h" #include "helper_regs.h" +#include "hw/ppc/ppc.h" #include "trace.h" @@ -2086,7 +2087,6 @@ void helper_rfebb(CPUPPCState *env, target_ulong s) static void do_ebb(CPUPPCState *env, int ebb_excp) { PowerPCCPU *cpu = env_archcpu(env); - CPUState *cs = CPU(cpu); /* * FSCR_EBB and FSCR_IC_EBB are the same bits used with @@ -2104,8 +2104,7 @@ static void do_ebb(CPUPPCState *env, int ebb_excp) if (FIELD_EX64(env->msr, MSR, PR)) { powerpc_excp(cpu, ebb_excp); } else { - env->pending_interrupts |= PPC_INTERRUPT_EBB; - cpu_interrupt(cs, CPU_INTERRUPT_HARD); + ppc_set_irq(cpu, PPC_INTERRUPT_EBB, 1); } } @@ -2298,7 +2297,7 @@ void helper_msgclr(CPUPPCState *env, target_ulong rb) return; } - env->pending_interrupts &= ~irq; + ppc_set_irq(env_archcpu(env), irq, 0); } void helper_msgsnd(target_ulong rb) @@ -2317,8 +2316,7 @@ void helper_msgsnd(target_ulong rb) CPUPPCState *cenv = &cpu->env; if ((rb & DBELL_BRDCAST) || (cenv->spr[SPR_BOOKE_PIR] == pir)) { - cenv->pending_interrupts |= irq; - cpu_interrupt(cs, CPU_INTERRUPT_HARD); + ppc_set_irq(cpu, irq, 1); } } qemu_mutex_unlock_iothread(); @@ -2342,7 +2340,7 @@ void helper_book3s_msgclr(CPUPPCState *env, target_ulong rb) return; } - env->pending_interrupts &= ~PPC_INTERRUPT_HDOORBELL; + ppc_set_irq(env_archcpu(env), PPC_INTERRUPT_HDOORBELL, 0); } static void book3s_msgsnd_common(int pir, int irq) @@ -2356,8 +2354,7 @@ static void book3s_msgsnd_common(int pir, int irq) /* TODO: broadcast message to all threads of the same processor */ if (cenv->spr_cb[SPR_PIR].default_value == pir) { - cenv->pending_interrupts |= irq; - cpu_interrupt(cs, CPU_INTERRUPT_HARD); + ppc_set_irq(cpu, irq, 1); } } qemu_mutex_unlock_iothread(); @@ -2383,7 +2380,7 @@ void helper_book3s_msgclrp(CPUPPCState *env, target_ulong rb) return; } - env->pending_interrupts &= ~PPC_INTERRUPT_DOORBELL; + ppc_set_irq(env_archcpu(env), PPC_INTERRUPT_HDOORBELL, 0); } /* diff --git a/target/ppc/misc_helper.c b/target/ppc/misc_helper.c index 05e35572bc..a9bc1522e2 100644 --- a/target/ppc/misc_helper.c +++ b/target/ppc/misc_helper.c @@ -25,6 +25,7 @@ #include "qemu/error-report.h" #include "qemu/main-loop.h" #include "mmu-book3s-v3.h" +#include "hw/ppc/ppc.h" #include "helper_regs.h" @@ -173,7 +174,6 @@ target_ulong helper_load_dpdes(CPUPPCState *env) void helper_store_dpdes(CPUPPCState *env, target_ulong val) { PowerPCCPU *cpu = env_archcpu(env); - CPUState *cs = CPU(cpu); helper_hfscr_facility_check(env, HFSCR_MSGP, "store DPDES", HFSCR_IC_MSGP); @@ -184,12 +184,7 @@ void helper_store_dpdes(CPUPPCState *env, target_ulong val) return; } - if (val & 0x1) { - env->pending_interrupts |= PPC_INTERRUPT_DOORBELL; - cpu_interrupt(cs, CPU_INTERRUPT_HARD); - } else { - env->pending_interrupts &= ~PPC_INTERRUPT_DOORBELL; - } + ppc_set_irq(cpu, PPC_INTERRUPT_DOORBELL, val & 0x1); } #endif /* defined(TARGET_PPC64) */ From de76b85c961378795a9e3044881554b25a4db333 Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Tue, 11 Oct 2022 17:48:03 -0300 Subject: [PATCH 357/705] target/ppc: split interrupt masking and delivery from ppc_hw_interrupt Split ppc_hw_interrupt into an interrupt masking method, ppc_next_unmasked_interrupt, and an interrupt processing method, ppc_deliver_interrupt. Signed-off-by: Matheus Ferst Reviewed-by: Fabiano Rosas Message-Id: <20221011204829.1641124-4-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/excp_helper.c | 201 ++++++++++++++++++++++++--------------- 1 file changed, 125 insertions(+), 76 deletions(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 37d352619b..759bad582d 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -1684,29 +1684,22 @@ void ppc_cpu_do_interrupt(CPUState *cs) powerpc_excp(cpu, cs->exception_index); } -static void ppc_hw_interrupt(CPUPPCState *env) +static int ppc_next_unmasked_interrupt(CPUPPCState *env) { - PowerPCCPU *cpu = env_archcpu(env); bool async_deliver; /* External reset */ if (env->pending_interrupts & PPC_INTERRUPT_RESET) { - env->pending_interrupts &= ~PPC_INTERRUPT_RESET; - powerpc_excp(cpu, POWERPC_EXCP_RESET); - return; + return PPC_INTERRUPT_RESET; } /* Machine check exception */ if (env->pending_interrupts & PPC_INTERRUPT_MCK) { - env->pending_interrupts &= ~PPC_INTERRUPT_MCK; - powerpc_excp(cpu, POWERPC_EXCP_MCHECK); - return; + return PPC_INTERRUPT_MCK; } #if 0 /* TODO */ /* External debug exception */ if (env->pending_interrupts & PPC_INTERRUPT_DEBUG) { - env->pending_interrupts &= ~PPC_INTERRUPT_DEBUG; - powerpc_excp(cpu, POWERPC_EXCP_DEBUG); - return; + return PPC_INTERRUPT_DEBUG; } #endif @@ -1724,9 +1717,7 @@ static void ppc_hw_interrupt(CPUPPCState *env) bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE); if ((async_deliver || !FIELD_EX64_HV(env->msr)) && hdice) { /* HDEC clears on delivery */ - env->pending_interrupts &= ~PPC_INTERRUPT_HDECR; - powerpc_excp(cpu, POWERPC_EXCP_HDECR); - return; + return PPC_INTERRUPT_HDECR; } } @@ -1735,8 +1726,7 @@ static void ppc_hw_interrupt(CPUPPCState *env) /* LPCR will be clear when not supported so this will work */ bool hvice = !!(env->spr[SPR_LPCR] & LPCR_HVICE); if ((async_deliver || !FIELD_EX64_HV(env->msr)) && hvice) { - powerpc_excp(cpu, POWERPC_EXCP_HVIRT); - return; + return PPC_INTERRUPT_HVIRT; } } @@ -1748,77 +1738,47 @@ static void ppc_hw_interrupt(CPUPPCState *env) if ((async_deliver && !(heic && FIELD_EX64_HV(env->msr) && !FIELD_EX64(env->msr, MSR, PR))) || (env->has_hv_mode && !FIELD_EX64_HV(env->msr) && !lpes0)) { - if (books_vhyp_promotes_external_to_hvirt(cpu)) { - powerpc_excp(cpu, POWERPC_EXCP_HVIRT); - } else { - powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL); - } - return; + return PPC_INTERRUPT_EXT; } } if (FIELD_EX64(env->msr, MSR, CE)) { /* External critical interrupt */ if (env->pending_interrupts & PPC_INTERRUPT_CEXT) { - powerpc_excp(cpu, POWERPC_EXCP_CRITICAL); - return; + return PPC_INTERRUPT_CEXT; } } if (async_deliver != 0) { /* Watchdog timer on embedded PowerPC */ if (env->pending_interrupts & PPC_INTERRUPT_WDT) { - env->pending_interrupts &= ~PPC_INTERRUPT_WDT; - powerpc_excp(cpu, POWERPC_EXCP_WDT); - return; + return PPC_INTERRUPT_WDT; } if (env->pending_interrupts & PPC_INTERRUPT_CDOORBELL) { - env->pending_interrupts &= ~PPC_INTERRUPT_CDOORBELL; - powerpc_excp(cpu, POWERPC_EXCP_DOORCI); - return; + return PPC_INTERRUPT_CDOORBELL; } /* Fixed interval timer on embedded PowerPC */ if (env->pending_interrupts & PPC_INTERRUPT_FIT) { - env->pending_interrupts &= ~PPC_INTERRUPT_FIT; - powerpc_excp(cpu, POWERPC_EXCP_FIT); - return; + return PPC_INTERRUPT_FIT; } /* Programmable interval timer on embedded PowerPC */ if (env->pending_interrupts & PPC_INTERRUPT_PIT) { - env->pending_interrupts &= ~PPC_INTERRUPT_PIT; - powerpc_excp(cpu, POWERPC_EXCP_PIT); - return; + return PPC_INTERRUPT_PIT; } /* Decrementer exception */ if (env->pending_interrupts & PPC_INTERRUPT_DECR) { - if (ppc_decr_clear_on_delivery(env)) { - env->pending_interrupts &= ~PPC_INTERRUPT_DECR; - } - powerpc_excp(cpu, POWERPC_EXCP_DECR); - return; + return PPC_INTERRUPT_DECR; } if (env->pending_interrupts & PPC_INTERRUPT_DOORBELL) { - env->pending_interrupts &= ~PPC_INTERRUPT_DOORBELL; - if (is_book3s_arch2x(env)) { - powerpc_excp(cpu, POWERPC_EXCP_SDOOR); - } else { - powerpc_excp(cpu, POWERPC_EXCP_DOORI); - } - return; + return PPC_INTERRUPT_DOORBELL; } if (env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) { - env->pending_interrupts &= ~PPC_INTERRUPT_HDOORBELL; - powerpc_excp(cpu, POWERPC_EXCP_SDOOR_HV); - return; + return PPC_INTERRUPT_HDOORBELL; } if (env->pending_interrupts & PPC_INTERRUPT_PERFM) { - env->pending_interrupts &= ~PPC_INTERRUPT_PERFM; - powerpc_excp(cpu, POWERPC_EXCP_PERFM); - return; + return PPC_INTERRUPT_PERFM; } /* Thermal interrupt */ if (env->pending_interrupts & PPC_INTERRUPT_THERM) { - env->pending_interrupts &= ~PPC_INTERRUPT_THERM; - powerpc_excp(cpu, POWERPC_EXCP_THERM); - return; + return PPC_INTERRUPT_THERM; } /* EBB exception */ if (env->pending_interrupts & PPC_INTERRUPT_EBB) { @@ -1828,20 +1788,100 @@ static void ppc_hw_interrupt(CPUPPCState *env) */ if (FIELD_EX64(env->msr, MSR, PR) && (env->spr[SPR_BESCR] & BESCR_GE)) { - env->pending_interrupts &= ~PPC_INTERRUPT_EBB; - - if (env->spr[SPR_BESCR] & BESCR_PMEO) { - powerpc_excp(cpu, POWERPC_EXCP_PERFM_EBB); - } else if (env->spr[SPR_BESCR] & BESCR_EEO) { - powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL_EBB); - } - - return; + return PPC_INTERRUPT_EBB; } } } - if (env->resume_as_sreset) { + return 0; +} + +static void ppc_deliver_interrupt(CPUPPCState *env, int interrupt) +{ + PowerPCCPU *cpu = env_archcpu(env); + CPUState *cs = env_cpu(env); + + switch (interrupt) { + case PPC_INTERRUPT_RESET: /* External reset */ + env->pending_interrupts &= ~PPC_INTERRUPT_RESET; + powerpc_excp(cpu, POWERPC_EXCP_RESET); + break; + case PPC_INTERRUPT_MCK: /* Machine check exception */ + env->pending_interrupts &= ~PPC_INTERRUPT_MCK; + powerpc_excp(cpu, POWERPC_EXCP_MCHECK); + break; + + case PPC_INTERRUPT_HDECR: /* Hypervisor decrementer exception */ + /* HDEC clears on delivery */ + env->pending_interrupts &= ~PPC_INTERRUPT_HDECR; + powerpc_excp(cpu, POWERPC_EXCP_HDECR); + break; + case PPC_INTERRUPT_HVIRT: /* Hypervisor virtualization interrupt */ + powerpc_excp(cpu, POWERPC_EXCP_HVIRT); + break; + + case PPC_INTERRUPT_EXT: + if (books_vhyp_promotes_external_to_hvirt(cpu)) { + powerpc_excp(cpu, POWERPC_EXCP_HVIRT); + } else { + powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL); + } + break; + case PPC_INTERRUPT_CEXT: /* External critical interrupt */ + powerpc_excp(cpu, POWERPC_EXCP_CRITICAL); + break; + + case PPC_INTERRUPT_WDT: /* Watchdog timer on embedded PowerPC */ + env->pending_interrupts &= ~PPC_INTERRUPT_WDT; + powerpc_excp(cpu, POWERPC_EXCP_WDT); + break; + case PPC_INTERRUPT_CDOORBELL: + env->pending_interrupts &= ~PPC_INTERRUPT_CDOORBELL; + powerpc_excp(cpu, POWERPC_EXCP_DOORCI); + break; + case PPC_INTERRUPT_FIT: /* Fixed interval timer on embedded PowerPC */ + env->pending_interrupts &= ~PPC_INTERRUPT_FIT; + powerpc_excp(cpu, POWERPC_EXCP_FIT); + break; + case PPC_INTERRUPT_PIT: /* Programmable interval timer on embedded ppc */ + env->pending_interrupts &= ~PPC_INTERRUPT_PIT; + powerpc_excp(cpu, POWERPC_EXCP_PIT); + break; + case PPC_INTERRUPT_DECR: /* Decrementer exception */ + if (ppc_decr_clear_on_delivery(env)) { + env->pending_interrupts &= ~PPC_INTERRUPT_DECR; + } + powerpc_excp(cpu, POWERPC_EXCP_DECR); + break; + case PPC_INTERRUPT_DOORBELL: + env->pending_interrupts &= ~PPC_INTERRUPT_DOORBELL; + if (is_book3s_arch2x(env)) { + powerpc_excp(cpu, POWERPC_EXCP_SDOOR); + } else { + powerpc_excp(cpu, POWERPC_EXCP_DOORI); + } + break; + case PPC_INTERRUPT_HDOORBELL: + env->pending_interrupts &= ~PPC_INTERRUPT_HDOORBELL; + powerpc_excp(cpu, POWERPC_EXCP_SDOOR_HV); + break; + case PPC_INTERRUPT_PERFM: + env->pending_interrupts &= ~PPC_INTERRUPT_PERFM; + powerpc_excp(cpu, POWERPC_EXCP_PERFM); + break; + case PPC_INTERRUPT_THERM: /* Thermal interrupt */ + env->pending_interrupts &= ~PPC_INTERRUPT_THERM; + powerpc_excp(cpu, POWERPC_EXCP_THERM); + break; + case PPC_INTERRUPT_EBB: /* EBB exception */ + env->pending_interrupts &= ~PPC_INTERRUPT_EBB; + if (env->spr[SPR_BESCR] & BESCR_PMEO) { + powerpc_excp(cpu, POWERPC_EXCP_PERFM_EBB); + } else if (env->spr[SPR_BESCR] & BESCR_EEO) { + powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL_EBB); + } + break; + case 0: /* * This is a bug ! It means that has_work took us out of halt without * anything to deliver while in a PM state that requires getting @@ -1853,8 +1893,10 @@ static void ppc_hw_interrupt(CPUPPCState *env) * It generally means a discrepancy between the wakeup conditions in the * processor has_work implementation and the logic in this function. */ - cpu_abort(env_cpu(env), - "Wakeup from PM state but interrupt Undelivered"); + assert(!env->resume_as_sreset); + break; + default: + cpu_abort(cs, "Invalid PowerPC interrupt %d. Aborting\n", interrupt); } } @@ -1890,15 +1932,22 @@ bool ppc_cpu_exec_interrupt(CPUState *cs, int interrupt_request) { PowerPCCPU *cpu = POWERPC_CPU(cs); CPUPPCState *env = &cpu->env; + int interrupt; - if (interrupt_request & CPU_INTERRUPT_HARD) { - ppc_hw_interrupt(env); - if (env->pending_interrupts == 0) { - cs->interrupt_request &= ~CPU_INTERRUPT_HARD; - } - return true; + if ((interrupt_request & CPU_INTERRUPT_HARD) == 0) { + return false; } - return false; + + interrupt = ppc_next_unmasked_interrupt(env); + if (interrupt == 0) { + return false; + } + + ppc_deliver_interrupt(env, interrupt); + if (env->pending_interrupts == 0) { + cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); + } + return true; } #endif /* !CONFIG_USER_ONLY */ From ba2898f79f9d36320abfa7c0589c796810c7186b Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Tue, 11 Oct 2022 17:48:04 -0300 Subject: [PATCH 358/705] target/ppc: prepare to split interrupt masking and delivery by excp_model Signed-off-by: Matheus Ferst Reviewed-by: Fabiano Rosas Message-Id: <20221011204829.1641124-5-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/excp_helper.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 759bad582d..0e89d2e15b 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -1684,7 +1684,7 @@ void ppc_cpu_do_interrupt(CPUState *cs) powerpc_excp(cpu, cs->exception_index); } -static int ppc_next_unmasked_interrupt(CPUPPCState *env) +static int ppc_next_unmasked_interrupt_generic(CPUPPCState *env) { bool async_deliver; @@ -1796,7 +1796,15 @@ static int ppc_next_unmasked_interrupt(CPUPPCState *env) return 0; } -static void ppc_deliver_interrupt(CPUPPCState *env, int interrupt) +static int ppc_next_unmasked_interrupt(CPUPPCState *env) +{ + switch (env->excp_model) { + default: + return ppc_next_unmasked_interrupt_generic(env); + } +} + +static void ppc_deliver_interrupt_generic(CPUPPCState *env, int interrupt) { PowerPCCPU *cpu = env_archcpu(env); CPUState *cs = env_cpu(env); @@ -1900,6 +1908,14 @@ static void ppc_deliver_interrupt(CPUPPCState *env, int interrupt) } } +static void ppc_deliver_interrupt(CPUPPCState *env, int interrupt) +{ + switch (env->excp_model) { + default: + ppc_deliver_interrupt_generic(env, interrupt); + } +} + void ppc_cpu_do_system_reset(CPUState *cs) { PowerPCCPU *cpu = POWERPC_CPU(cs); From 2dfecf01952f6d4c9c7698ae55d7a425999acaed Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Tue, 11 Oct 2022 17:48:05 -0300 Subject: [PATCH 359/705] target/ppc: create an interrupt masking method for POWER9/POWER10 The new method is identical to ppc_next_unmasked_interrupt_generic, processor-specific code will be added/removed in the following patches. Signed-off-by: Matheus Ferst Reviewed-by: Fabiano Rosas Message-Id: <20221011204829.1641124-6-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/excp_helper.c | 113 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 0e89d2e15b..4d2fb2ebd1 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -1684,6 +1684,114 @@ void ppc_cpu_do_interrupt(CPUState *cs) powerpc_excp(cpu, cs->exception_index); } +#if defined(TARGET_PPC64) +static int p9_next_unmasked_interrupt(CPUPPCState *env) +{ + bool async_deliver; + + /* External reset */ + if (env->pending_interrupts & PPC_INTERRUPT_RESET) { + return PPC_INTERRUPT_RESET; + } + /* Machine check exception */ + if (env->pending_interrupts & PPC_INTERRUPT_MCK) { + return PPC_INTERRUPT_MCK; + } + + /* + * For interrupts that gate on MSR:EE, we need to do something a + * bit more subtle, as we need to let them through even when EE is + * clear when coming out of some power management states (in order + * for them to become a 0x100). + */ + async_deliver = FIELD_EX64(env->msr, MSR, EE) || env->resume_as_sreset; + + /* Hypervisor decrementer exception */ + if (env->pending_interrupts & PPC_INTERRUPT_HDECR) { + /* LPCR will be clear when not supported so this will work */ + bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE); + if ((async_deliver || !FIELD_EX64_HV(env->msr)) && hdice) { + /* HDEC clears on delivery */ + return PPC_INTERRUPT_HDECR; + } + } + + /* Hypervisor virtualization interrupt */ + if (env->pending_interrupts & PPC_INTERRUPT_HVIRT) { + /* LPCR will be clear when not supported so this will work */ + bool hvice = !!(env->spr[SPR_LPCR] & LPCR_HVICE); + if ((async_deliver || !FIELD_EX64_HV(env->msr)) && hvice) { + return PPC_INTERRUPT_HVIRT; + } + } + + /* External interrupt can ignore MSR:EE under some circumstances */ + if (env->pending_interrupts & PPC_INTERRUPT_EXT) { + bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); + bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); + /* HEIC blocks delivery to the hypervisor */ + if ((async_deliver && !(heic && FIELD_EX64_HV(env->msr) && + !FIELD_EX64(env->msr, MSR, PR))) || + (env->has_hv_mode && !FIELD_EX64_HV(env->msr) && !lpes0)) { + return PPC_INTERRUPT_EXT; + } + } + if (FIELD_EX64(env->msr, MSR, CE)) { + /* External critical interrupt */ + if (env->pending_interrupts & PPC_INTERRUPT_CEXT) { + return PPC_INTERRUPT_CEXT; + } + } + if (async_deliver != 0) { + /* Watchdog timer on embedded PowerPC */ + if (env->pending_interrupts & PPC_INTERRUPT_WDT) { + return PPC_INTERRUPT_WDT; + } + if (env->pending_interrupts & PPC_INTERRUPT_CDOORBELL) { + return PPC_INTERRUPT_CDOORBELL; + } + /* Fixed interval timer on embedded PowerPC */ + if (env->pending_interrupts & PPC_INTERRUPT_FIT) { + return PPC_INTERRUPT_FIT; + } + /* Programmable interval timer on embedded PowerPC */ + if (env->pending_interrupts & PPC_INTERRUPT_PIT) { + return PPC_INTERRUPT_PIT; + } + /* Decrementer exception */ + if (env->pending_interrupts & PPC_INTERRUPT_DECR) { + return PPC_INTERRUPT_DECR; + } + if (env->pending_interrupts & PPC_INTERRUPT_DOORBELL) { + return PPC_INTERRUPT_DOORBELL; + } + if (env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) { + return PPC_INTERRUPT_HDOORBELL; + } + if (env->pending_interrupts & PPC_INTERRUPT_PERFM) { + return PPC_INTERRUPT_PERFM; + } + /* Thermal interrupt */ + if (env->pending_interrupts & PPC_INTERRUPT_THERM) { + return PPC_INTERRUPT_THERM; + } + /* EBB exception */ + if (env->pending_interrupts & PPC_INTERRUPT_EBB) { + /* + * EBB exception must be taken in problem state and + * with BESCR_GE set. + */ + if (FIELD_EX64(env->msr, MSR, PR) && + (env->spr[SPR_BESCR] & BESCR_GE)) { + return PPC_INTERRUPT_EBB; + } + } + } + + return 0; +} +#endif + static int ppc_next_unmasked_interrupt_generic(CPUPPCState *env) { bool async_deliver; @@ -1799,6 +1907,11 @@ static int ppc_next_unmasked_interrupt_generic(CPUPPCState *env) static int ppc_next_unmasked_interrupt(CPUPPCState *env) { switch (env->excp_model) { +#if defined(TARGET_PPC64) + case POWERPC_EXCP_POWER9: + case POWERPC_EXCP_POWER10: + return p9_next_unmasked_interrupt(env); +#endif default: return ppc_next_unmasked_interrupt_generic(env); } From b00e9a2f2be384820a107c28ff97fb4d6ed84b8a Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Tue, 11 Oct 2022 17:48:06 -0300 Subject: [PATCH 360/705] target/ppc: remove unused interrupts from p9_next_unmasked_interrupt Remove the following unused interrupts from the POWER9 interrupt masking method: - PPC_INTERRUPT_RESET: only raised for 6xx, 7xx, 970 and POWER5p; - Debug Interrupt: removed in Power ISA v2.07; - Critical Input, Watchdog Timer, and Fixed Interval Timer: only defined for embedded CPUs; - Critical Doorbell Interrupt: removed in Power ISA v3.0; - Programmable Interval Timer: 40x-only. Signed-off-by: Matheus Ferst Reviewed-by: Fabiano Rosas Message-Id: <20221011204829.1641124-7-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/excp_helper.c | 36 +++++++----------------------------- 1 file changed, 7 insertions(+), 29 deletions(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 4d2fb2ebd1..740a5618b9 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -1685,14 +1685,17 @@ void ppc_cpu_do_interrupt(CPUState *cs) } #if defined(TARGET_PPC64) +#define P9_UNUSED_INTERRUPTS \ + (PPC_INTERRUPT_RESET | PPC_INTERRUPT_DEBUG | PPC_INTERRUPT_CEXT | \ + PPC_INTERRUPT_WDT | PPC_INTERRUPT_CDOORBELL | PPC_INTERRUPT_FIT | \ + PPC_INTERRUPT_PIT | PPC_INTERRUPT_THERM) + static int p9_next_unmasked_interrupt(CPUPPCState *env) { bool async_deliver; - /* External reset */ - if (env->pending_interrupts & PPC_INTERRUPT_RESET) { - return PPC_INTERRUPT_RESET; - } + assert((env->pending_interrupts & P9_UNUSED_INTERRUPTS) == 0); + /* Machine check exception */ if (env->pending_interrupts & PPC_INTERRUPT_MCK) { return PPC_INTERRUPT_MCK; @@ -1736,28 +1739,7 @@ static int p9_next_unmasked_interrupt(CPUPPCState *env) return PPC_INTERRUPT_EXT; } } - if (FIELD_EX64(env->msr, MSR, CE)) { - /* External critical interrupt */ - if (env->pending_interrupts & PPC_INTERRUPT_CEXT) { - return PPC_INTERRUPT_CEXT; - } - } if (async_deliver != 0) { - /* Watchdog timer on embedded PowerPC */ - if (env->pending_interrupts & PPC_INTERRUPT_WDT) { - return PPC_INTERRUPT_WDT; - } - if (env->pending_interrupts & PPC_INTERRUPT_CDOORBELL) { - return PPC_INTERRUPT_CDOORBELL; - } - /* Fixed interval timer on embedded PowerPC */ - if (env->pending_interrupts & PPC_INTERRUPT_FIT) { - return PPC_INTERRUPT_FIT; - } - /* Programmable interval timer on embedded PowerPC */ - if (env->pending_interrupts & PPC_INTERRUPT_PIT) { - return PPC_INTERRUPT_PIT; - } /* Decrementer exception */ if (env->pending_interrupts & PPC_INTERRUPT_DECR) { return PPC_INTERRUPT_DECR; @@ -1771,10 +1753,6 @@ static int p9_next_unmasked_interrupt(CPUPPCState *env) if (env->pending_interrupts & PPC_INTERRUPT_PERFM) { return PPC_INTERRUPT_PERFM; } - /* Thermal interrupt */ - if (env->pending_interrupts & PPC_INTERRUPT_THERM) { - return PPC_INTERRUPT_THERM; - } /* EBB exception */ if (env->pending_interrupts & PPC_INTERRUPT_EBB) { /* From 3654e238af02fb828b71aa85a4fc475770a3d91a Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Tue, 11 Oct 2022 17:48:07 -0300 Subject: [PATCH 361/705] target/ppc: create an interrupt deliver method for POWER9/POWER10 The new method is identical to ppc_deliver_interrupt, processor-specific code will be added/removed in the following patches. Signed-off-by: Matheus Ferst Reviewed-by: Fabiano Rosas Message-Id: <20221011204829.1641124-8-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/excp_helper.c | 112 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 740a5618b9..104b48dc43 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -1895,6 +1895,112 @@ static int ppc_next_unmasked_interrupt(CPUPPCState *env) } } +#if defined(TARGET_PPC64) +static void p9_deliver_interrupt(CPUPPCState *env, int interrupt) +{ + PowerPCCPU *cpu = env_archcpu(env); + CPUState *cs = env_cpu(env); + + switch (interrupt) { + case PPC_INTERRUPT_RESET: /* External reset */ + env->pending_interrupts &= ~PPC_INTERRUPT_RESET; + powerpc_excp(cpu, POWERPC_EXCP_RESET); + break; + case PPC_INTERRUPT_MCK: /* Machine check exception */ + env->pending_interrupts &= ~PPC_INTERRUPT_MCK; + powerpc_excp(cpu, POWERPC_EXCP_MCHECK); + break; + + case PPC_INTERRUPT_HDECR: /* Hypervisor decrementer exception */ + /* HDEC clears on delivery */ + env->pending_interrupts &= ~PPC_INTERRUPT_HDECR; + powerpc_excp(cpu, POWERPC_EXCP_HDECR); + break; + case PPC_INTERRUPT_HVIRT: /* Hypervisor virtualization interrupt */ + powerpc_excp(cpu, POWERPC_EXCP_HVIRT); + break; + + case PPC_INTERRUPT_EXT: + if (books_vhyp_promotes_external_to_hvirt(cpu)) { + powerpc_excp(cpu, POWERPC_EXCP_HVIRT); + } else { + powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL); + } + break; + case PPC_INTERRUPT_CEXT: /* External critical interrupt */ + powerpc_excp(cpu, POWERPC_EXCP_CRITICAL); + break; + + case PPC_INTERRUPT_WDT: /* Watchdog timer on embedded PowerPC */ + env->pending_interrupts &= ~PPC_INTERRUPT_WDT; + powerpc_excp(cpu, POWERPC_EXCP_WDT); + break; + case PPC_INTERRUPT_CDOORBELL: + env->pending_interrupts &= ~PPC_INTERRUPT_CDOORBELL; + powerpc_excp(cpu, POWERPC_EXCP_DOORCI); + break; + case PPC_INTERRUPT_FIT: /* Fixed interval timer on embedded PowerPC */ + env->pending_interrupts &= ~PPC_INTERRUPT_FIT; + powerpc_excp(cpu, POWERPC_EXCP_FIT); + break; + case PPC_INTERRUPT_PIT: /* Programmable interval timer on embedded ppc */ + env->pending_interrupts &= ~PPC_INTERRUPT_PIT; + powerpc_excp(cpu, POWERPC_EXCP_PIT); + break; + case PPC_INTERRUPT_DECR: /* Decrementer exception */ + if (ppc_decr_clear_on_delivery(env)) { + env->pending_interrupts &= ~PPC_INTERRUPT_DECR; + } + powerpc_excp(cpu, POWERPC_EXCP_DECR); + break; + case PPC_INTERRUPT_DOORBELL: + env->pending_interrupts &= ~PPC_INTERRUPT_DOORBELL; + if (is_book3s_arch2x(env)) { + powerpc_excp(cpu, POWERPC_EXCP_SDOOR); + } else { + powerpc_excp(cpu, POWERPC_EXCP_DOORI); + } + break; + case PPC_INTERRUPT_HDOORBELL: + env->pending_interrupts &= ~PPC_INTERRUPT_HDOORBELL; + powerpc_excp(cpu, POWERPC_EXCP_SDOOR_HV); + break; + case PPC_INTERRUPT_PERFM: + env->pending_interrupts &= ~PPC_INTERRUPT_PERFM; + powerpc_excp(cpu, POWERPC_EXCP_PERFM); + break; + case PPC_INTERRUPT_THERM: /* Thermal interrupt */ + env->pending_interrupts &= ~PPC_INTERRUPT_THERM; + powerpc_excp(cpu, POWERPC_EXCP_THERM); + break; + case PPC_INTERRUPT_EBB: /* EBB exception */ + env->pending_interrupts &= ~PPC_INTERRUPT_EBB; + if (env->spr[SPR_BESCR] & BESCR_PMEO) { + powerpc_excp(cpu, POWERPC_EXCP_PERFM_EBB); + } else if (env->spr[SPR_BESCR] & BESCR_EEO) { + powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL_EBB); + } + break; + case 0: + /* + * This is a bug ! It means that has_work took us out of halt without + * anything to deliver while in a PM state that requires getting + * out via a 0x100 + * + * This means we will incorrectly execute past the power management + * instruction instead of triggering a reset. + * + * It generally means a discrepancy between the wakeup conditions in the + * processor has_work implementation and the logic in this function. + */ + assert(!env->resume_as_sreset); + break; + default: + cpu_abort(cs, "Invalid PowerPC interrupt %d. Aborting\n", interrupt); + } +} +#endif + static void ppc_deliver_interrupt_generic(CPUPPCState *env, int interrupt) { PowerPCCPU *cpu = env_archcpu(env); @@ -2002,6 +2108,12 @@ static void ppc_deliver_interrupt_generic(CPUPPCState *env, int interrupt) static void ppc_deliver_interrupt(CPUPPCState *env, int interrupt) { switch (env->excp_model) { +#if defined(TARGET_PPC64) + case POWERPC_EXCP_POWER9: + case POWERPC_EXCP_POWER10: + p9_deliver_interrupt(env, interrupt); + break; +#endif default: ppc_deliver_interrupt_generic(env, interrupt); } From 1e75ffe40efcf07c3576a9ffb76235975ca96ce7 Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Tue, 11 Oct 2022 17:48:08 -0300 Subject: [PATCH 362/705] target/ppc: remove unused interrupts from p9_deliver_interrupt Remove the following unused interrupts from the POWER9 interrupt processing method: - PPC_INTERRUPT_RESET: only raised for 6xx, 7xx, 970 and POWER5p; - Debug Interrupt: removed in Power ISA v2.07; - Critical Input, Watchdog Timer, and Fixed Interval Timer: only defined for embedded CPUs; - Critical Doorbell Interrupt: removed in Power ISA v3.0; - Programmable Interval Timer: 40x-only. Signed-off-by: Matheus Ferst Reviewed-by: Fabiano Rosas Message-Id: <20221011204829.1641124-9-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/excp_helper.c | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 104b48dc43..288bb20deb 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -1902,10 +1902,6 @@ static void p9_deliver_interrupt(CPUPPCState *env, int interrupt) CPUState *cs = env_cpu(env); switch (interrupt) { - case PPC_INTERRUPT_RESET: /* External reset */ - env->pending_interrupts &= ~PPC_INTERRUPT_RESET; - powerpc_excp(cpu, POWERPC_EXCP_RESET); - break; case PPC_INTERRUPT_MCK: /* Machine check exception */ env->pending_interrupts &= ~PPC_INTERRUPT_MCK; powerpc_excp(cpu, POWERPC_EXCP_MCHECK); @@ -1927,26 +1923,7 @@ static void p9_deliver_interrupt(CPUPPCState *env, int interrupt) powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL); } break; - case PPC_INTERRUPT_CEXT: /* External critical interrupt */ - powerpc_excp(cpu, POWERPC_EXCP_CRITICAL); - break; - case PPC_INTERRUPT_WDT: /* Watchdog timer on embedded PowerPC */ - env->pending_interrupts &= ~PPC_INTERRUPT_WDT; - powerpc_excp(cpu, POWERPC_EXCP_WDT); - break; - case PPC_INTERRUPT_CDOORBELL: - env->pending_interrupts &= ~PPC_INTERRUPT_CDOORBELL; - powerpc_excp(cpu, POWERPC_EXCP_DOORCI); - break; - case PPC_INTERRUPT_FIT: /* Fixed interval timer on embedded PowerPC */ - env->pending_interrupts &= ~PPC_INTERRUPT_FIT; - powerpc_excp(cpu, POWERPC_EXCP_FIT); - break; - case PPC_INTERRUPT_PIT: /* Programmable interval timer on embedded ppc */ - env->pending_interrupts &= ~PPC_INTERRUPT_PIT; - powerpc_excp(cpu, POWERPC_EXCP_PIT); - break; case PPC_INTERRUPT_DECR: /* Decrementer exception */ if (ppc_decr_clear_on_delivery(env)) { env->pending_interrupts &= ~PPC_INTERRUPT_DECR; @@ -1969,10 +1946,6 @@ static void p9_deliver_interrupt(CPUPPCState *env, int interrupt) env->pending_interrupts &= ~PPC_INTERRUPT_PERFM; powerpc_excp(cpu, POWERPC_EXCP_PERFM); break; - case PPC_INTERRUPT_THERM: /* Thermal interrupt */ - env->pending_interrupts &= ~PPC_INTERRUPT_THERM; - powerpc_excp(cpu, POWERPC_EXCP_THERM); - break; case PPC_INTERRUPT_EBB: /* EBB exception */ env->pending_interrupts &= ~PPC_INTERRUPT_EBB; if (env->spr[SPR_BESCR] & BESCR_PMEO) { From ed3a24c95a9d8d870bf671d5675b8b4b32a0db75 Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Tue, 11 Oct 2022 17:48:09 -0300 Subject: [PATCH 363/705] target/ppc: remove generic architecture checks from p9_deliver_interrupt Signed-off-by: Matheus Ferst Reviewed-by: Fabiano Rosas Message-Id: <20221011204829.1641124-10-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/excp_helper.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 288bb20deb..238ce78235 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -1925,18 +1925,11 @@ static void p9_deliver_interrupt(CPUPPCState *env, int interrupt) break; case PPC_INTERRUPT_DECR: /* Decrementer exception */ - if (ppc_decr_clear_on_delivery(env)) { - env->pending_interrupts &= ~PPC_INTERRUPT_DECR; - } powerpc_excp(cpu, POWERPC_EXCP_DECR); break; case PPC_INTERRUPT_DOORBELL: env->pending_interrupts &= ~PPC_INTERRUPT_DOORBELL; - if (is_book3s_arch2x(env)) { - powerpc_excp(cpu, POWERPC_EXCP_SDOOR); - } else { - powerpc_excp(cpu, POWERPC_EXCP_DOORI); - } + powerpc_excp(cpu, POWERPC_EXCP_SDOOR); break; case PPC_INTERRUPT_HDOORBELL: env->pending_interrupts &= ~PPC_INTERRUPT_HDOORBELL; From 0ccd9d67b1ee9289dd96f2d133a618f97f7a89ab Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Tue, 11 Oct 2022 17:48:10 -0300 Subject: [PATCH 364/705] target/ppc: move power-saving interrupt masking out of cpu_has_work_POWER9 Move the interrupt masking logic out of cpu_has_work_POWER9 in a new method, p9_interrupt_powersave, that only returns an interrupt if it can wake the processor from power-saving mode. Signed-off-by: Matheus Ferst Reviewed-by: Fabiano Rosas Message-Id: <20221011204829.1641124-11-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/cpu_init.c | 126 +++++++++++++++++------------------------- 1 file changed, 50 insertions(+), 76 deletions(-) diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index 07171c679c..9ecea10b48 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -6351,6 +6351,52 @@ static bool ppc_pvr_match_power9(PowerPCCPUClass *pcc, uint32_t pvr, bool best) return false; } +static int p9_interrupt_powersave(CPUPPCState *env) +{ + /* External Exception */ + if ((env->pending_interrupts & PPC_INTERRUPT_EXT) && + (env->spr[SPR_LPCR] & LPCR_EEE)) { + bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); + if (!heic || !FIELD_EX64_HV(env->msr) || + FIELD_EX64(env->msr, MSR, PR)) { + return PPC_INTERRUPT_EXT; + } + } + /* Decrementer Exception */ + if ((env->pending_interrupts & PPC_INTERRUPT_DECR) && + (env->spr[SPR_LPCR] & LPCR_DEE)) { + return PPC_INTERRUPT_DECR; + } + /* Machine Check or Hypervisor Maintenance Exception */ + if (env->spr[SPR_LPCR] & LPCR_OEE) { + if (env->pending_interrupts & PPC_INTERRUPT_MCK) { + return PPC_INTERRUPT_MCK; + } + if (env->pending_interrupts & PPC_INTERRUPT_HMI) { + return PPC_INTERRUPT_HMI; + } + } + /* Privileged Doorbell Exception */ + if ((env->pending_interrupts & PPC_INTERRUPT_DOORBELL) && + (env->spr[SPR_LPCR] & LPCR_PDEE)) { + return PPC_INTERRUPT_DOORBELL; + } + /* Hypervisor Doorbell Exception */ + if ((env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) && + (env->spr[SPR_LPCR] & LPCR_HDEE)) { + return PPC_INTERRUPT_HDOORBELL; + } + /* Hypervisor virtualization exception */ + if ((env->pending_interrupts & PPC_INTERRUPT_HVIRT) && + (env->spr[SPR_LPCR] & LPCR_HVEE)) { + return PPC_INTERRUPT_HVIRT; + } + if (env->pending_interrupts & PPC_INTERRUPT_RESET) { + return PPC_INTERRUPT_RESET; + } + return 0; +} + static bool cpu_has_work_POWER9(CPUState *cs) { PowerPCCPU *cpu = POWERPC_CPU(cs); @@ -6367,44 +6413,8 @@ static bool cpu_has_work_POWER9(CPUState *cs) if (!(psscr & PSSCR_EC)) { return true; } - /* External Exception */ - if ((env->pending_interrupts & PPC_INTERRUPT_EXT) && - (env->spr[SPR_LPCR] & LPCR_EEE)) { - bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); - if (!heic || !FIELD_EX64_HV(env->msr) || - FIELD_EX64(env->msr, MSR, PR)) { - return true; - } - } - /* Decrementer Exception */ - if ((env->pending_interrupts & PPC_INTERRUPT_DECR) && - (env->spr[SPR_LPCR] & LPCR_DEE)) { - return true; - } - /* Machine Check or Hypervisor Maintenance Exception */ - if ((env->pending_interrupts & (PPC_INTERRUPT_MCK | PPC_INTERRUPT_HMI)) - && (env->spr[SPR_LPCR] & LPCR_OEE)) { - return true; - } - /* Privileged Doorbell Exception */ - if ((env->pending_interrupts & PPC_INTERRUPT_DOORBELL) && - (env->spr[SPR_LPCR] & LPCR_PDEE)) { - return true; - } - /* Hypervisor Doorbell Exception */ - if ((env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) && - (env->spr[SPR_LPCR] & LPCR_HDEE)) { - return true; - } - /* Hypervisor virtualization exception */ - if ((env->pending_interrupts & PPC_INTERRUPT_HVIRT) && - (env->spr[SPR_LPCR] & LPCR_HVEE)) { - return true; - } - if (env->pending_interrupts & PPC_INTERRUPT_RESET) { - return true; - } - return false; + + return p9_interrupt_powersave(env) != 0; } else { return FIELD_EX64(env->msr, MSR, EE) && (cs->interrupt_request & CPU_INTERRUPT_HARD); @@ -6600,44 +6610,8 @@ static bool cpu_has_work_POWER10(CPUState *cs) if (!(psscr & PSSCR_EC)) { return true; } - /* External Exception */ - if ((env->pending_interrupts & PPC_INTERRUPT_EXT) && - (env->spr[SPR_LPCR] & LPCR_EEE)) { - bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); - if (!heic || !FIELD_EX64_HV(env->msr) || - FIELD_EX64(env->msr, MSR, PR)) { - return true; - } - } - /* Decrementer Exception */ - if ((env->pending_interrupts & PPC_INTERRUPT_DECR) && - (env->spr[SPR_LPCR] & LPCR_DEE)) { - return true; - } - /* Machine Check or Hypervisor Maintenance Exception */ - if ((env->pending_interrupts & (PPC_INTERRUPT_MCK | PPC_INTERRUPT_HMI)) - && (env->spr[SPR_LPCR] & LPCR_OEE)) { - return true; - } - /* Privileged Doorbell Exception */ - if ((env->pending_interrupts & PPC_INTERRUPT_DOORBELL) && - (env->spr[SPR_LPCR] & LPCR_PDEE)) { - return true; - } - /* Hypervisor Doorbell Exception */ - if ((env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) && - (env->spr[SPR_LPCR] & LPCR_HDEE)) { - return true; - } - /* Hypervisor virtualization exception */ - if ((env->pending_interrupts & PPC_INTERRUPT_HVIRT) && - (env->spr[SPR_LPCR] & LPCR_HVEE)) { - return true; - } - if (env->pending_interrupts & PPC_INTERRUPT_RESET) { - return true; - } - return false; + + return p9_interrupt_powersave(env) != 0; } else { return FIELD_EX64(env->msr, MSR, EE) && (cs->interrupt_request & CPU_INTERRUPT_HARD); From 27796411271837b45c635c537e70d1ecfdcd4e1c Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Tue, 11 Oct 2022 17:48:11 -0300 Subject: [PATCH 365/705] target/ppc: add power-saving interrupt masking logic to p9_next_unmasked_interrupt Export p9_interrupt_powersave and use it in p9_next_unmasked_interrupt. Signed-off-by: Matheus Ferst Reviewed-by: Fabiano Rosas Message-Id: <20221011204829.1641124-12-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/cpu_init.c | 2 +- target/ppc/excp_helper.c | 46 ++++++++++++++++++++++++++++------------ target/ppc/internal.h | 4 ++++ 3 files changed, 38 insertions(+), 14 deletions(-) diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index 9ecea10b48..423d99d8d3 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -6351,7 +6351,7 @@ static bool ppc_pvr_match_power9(PowerPCCPUClass *pcc, uint32_t pvr, bool best) return false; } -static int p9_interrupt_powersave(CPUPPCState *env) +int p9_interrupt_powersave(CPUPPCState *env) { /* External Exception */ if ((env->pending_interrupts & PPC_INTERRUPT_EXT) && diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 238ce78235..836c90b9a8 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -1692,28 +1692,39 @@ void ppc_cpu_do_interrupt(CPUState *cs) static int p9_next_unmasked_interrupt(CPUPPCState *env) { - bool async_deliver; + PowerPCCPU *cpu = env_archcpu(env); + CPUState *cs = CPU(cpu); + /* Ignore MSR[EE] when coming out of some power management states */ + bool msr_ee = FIELD_EX64(env->msr, MSR, EE) || env->resume_as_sreset; assert((env->pending_interrupts & P9_UNUSED_INTERRUPTS) == 0); + if (cs->halted) { + if (env->spr[SPR_PSSCR] & PSSCR_EC) { + /* + * When PSSCR[EC] is set, LPCR[PECE] controls which interrupts can + * wakeup the processor + */ + return p9_interrupt_powersave(env); + } else { + /* + * When it's clear, any system-caused exception exits power-saving + * mode, even the ones that gate on MSR[EE]. + */ + msr_ee = true; + } + } + /* Machine check exception */ if (env->pending_interrupts & PPC_INTERRUPT_MCK) { return PPC_INTERRUPT_MCK; } - /* - * For interrupts that gate on MSR:EE, we need to do something a - * bit more subtle, as we need to let them through even when EE is - * clear when coming out of some power management states (in order - * for them to become a 0x100). - */ - async_deliver = FIELD_EX64(env->msr, MSR, EE) || env->resume_as_sreset; - /* Hypervisor decrementer exception */ if (env->pending_interrupts & PPC_INTERRUPT_HDECR) { /* LPCR will be clear when not supported so this will work */ bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE); - if ((async_deliver || !FIELD_EX64_HV(env->msr)) && hdice) { + if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hdice) { /* HDEC clears on delivery */ return PPC_INTERRUPT_HDECR; } @@ -1723,7 +1734,7 @@ static int p9_next_unmasked_interrupt(CPUPPCState *env) if (env->pending_interrupts & PPC_INTERRUPT_HVIRT) { /* LPCR will be clear when not supported so this will work */ bool hvice = !!(env->spr[SPR_LPCR] & LPCR_HVICE); - if ((async_deliver || !FIELD_EX64_HV(env->msr)) && hvice) { + if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hvice) { return PPC_INTERRUPT_HVIRT; } } @@ -1733,13 +1744,13 @@ static int p9_next_unmasked_interrupt(CPUPPCState *env) bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); /* HEIC blocks delivery to the hypervisor */ - if ((async_deliver && !(heic && FIELD_EX64_HV(env->msr) && + if ((msr_ee && !(heic && FIELD_EX64_HV(env->msr) && !FIELD_EX64(env->msr, MSR, PR))) || (env->has_hv_mode && !FIELD_EX64_HV(env->msr) && !lpes0)) { return PPC_INTERRUPT_EXT; } } - if (async_deliver != 0) { + if (msr_ee != 0) { /* Decrementer exception */ if (env->pending_interrupts & PPC_INTERRUPT_DECR) { return PPC_INTERRUPT_DECR; @@ -1901,6 +1912,15 @@ static void p9_deliver_interrupt(CPUPPCState *env, int interrupt) PowerPCCPU *cpu = env_archcpu(env); CPUState *cs = env_cpu(env); + if (cs->halted && !(env->spr[SPR_PSSCR] & PSSCR_EC) && + !FIELD_EX64(env->msr, MSR, EE)) { + /* + * A pending interrupt took us out of power-saving, but MSR[EE] says + * that we should return to NIP+4 instead of delivering it. + */ + return; + } + switch (interrupt) { case PPC_INTERRUPT_MCK: /* Machine check exception */ env->pending_interrupts &= ~PPC_INTERRUPT_MCK; diff --git a/target/ppc/internal.h b/target/ppc/internal.h index 337a362205..41e79adfdb 100644 --- a/target/ppc/internal.h +++ b/target/ppc/internal.h @@ -306,4 +306,8 @@ static inline int ger_pack_masks(int pmsk, int ymsk, int xmsk) return msk; } +#if defined(TARGET_PPC64) +int p9_interrupt_powersave(CPUPPCState *env); +#endif + #endif /* PPC_INTERNAL_H */ From a9899d42012c49169074fb85b61c78aa6e17af8e Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Tue, 11 Oct 2022 17:48:12 -0300 Subject: [PATCH 366/705] target/ppc: create an interrupt masking method for POWER8 The new method is identical to ppc_next_unmasked_interrupt_generic, processor-specific code will be added/removed in the following patches. Signed-off-by: Matheus Ferst Reviewed-by: Fabiano Rosas Message-Id: <20221011204829.1641124-13-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/excp_helper.c | 108 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 836c90b9a8..c7b303a9a7 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -1685,6 +1685,112 @@ void ppc_cpu_do_interrupt(CPUState *cs) } #if defined(TARGET_PPC64) +static int p8_next_unmasked_interrupt(CPUPPCState *env) +{ + bool async_deliver; + + /* External reset */ + if (env->pending_interrupts & PPC_INTERRUPT_RESET) { + return PPC_INTERRUPT_RESET; + } + /* Machine check exception */ + if (env->pending_interrupts & PPC_INTERRUPT_MCK) { + return PPC_INTERRUPT_MCK; + } + + /* + * For interrupts that gate on MSR:EE, we need to do something a + * bit more subtle, as we need to let them through even when EE is + * clear when coming out of some power management states (in order + * for them to become a 0x100). + */ + async_deliver = FIELD_EX64(env->msr, MSR, EE) || env->resume_as_sreset; + + /* Hypervisor decrementer exception */ + if (env->pending_interrupts & PPC_INTERRUPT_HDECR) { + /* LPCR will be clear when not supported so this will work */ + bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE); + if ((async_deliver || !FIELD_EX64_HV(env->msr)) && hdice) { + /* HDEC clears on delivery */ + return PPC_INTERRUPT_HDECR; + } + } + + /* Hypervisor virtualization interrupt */ + if (env->pending_interrupts & PPC_INTERRUPT_HVIRT) { + /* LPCR will be clear when not supported so this will work */ + bool hvice = !!(env->spr[SPR_LPCR] & LPCR_HVICE); + if ((async_deliver || !FIELD_EX64_HV(env->msr)) && hvice) { + return PPC_INTERRUPT_HVIRT; + } + } + + /* External interrupt can ignore MSR:EE under some circumstances */ + if (env->pending_interrupts & PPC_INTERRUPT_EXT) { + bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); + bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); + /* HEIC blocks delivery to the hypervisor */ + if ((async_deliver && !(heic && FIELD_EX64_HV(env->msr) && + !FIELD_EX64(env->msr, MSR, PR))) || + (env->has_hv_mode && !FIELD_EX64_HV(env->msr) && !lpes0)) { + return PPC_INTERRUPT_EXT; + } + } + if (FIELD_EX64(env->msr, MSR, CE)) { + /* External critical interrupt */ + if (env->pending_interrupts & PPC_INTERRUPT_CEXT) { + return PPC_INTERRUPT_CEXT; + } + } + if (async_deliver != 0) { + /* Watchdog timer on embedded PowerPC */ + if (env->pending_interrupts & PPC_INTERRUPT_WDT) { + return PPC_INTERRUPT_WDT; + } + if (env->pending_interrupts & PPC_INTERRUPT_CDOORBELL) { + return PPC_INTERRUPT_CDOORBELL; + } + /* Fixed interval timer on embedded PowerPC */ + if (env->pending_interrupts & PPC_INTERRUPT_FIT) { + return PPC_INTERRUPT_FIT; + } + /* Programmable interval timer on embedded PowerPC */ + if (env->pending_interrupts & PPC_INTERRUPT_PIT) { + return PPC_INTERRUPT_PIT; + } + /* Decrementer exception */ + if (env->pending_interrupts & PPC_INTERRUPT_DECR) { + return PPC_INTERRUPT_DECR; + } + if (env->pending_interrupts & PPC_INTERRUPT_DOORBELL) { + return PPC_INTERRUPT_DOORBELL; + } + if (env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) { + return PPC_INTERRUPT_HDOORBELL; + } + if (env->pending_interrupts & PPC_INTERRUPT_PERFM) { + return PPC_INTERRUPT_PERFM; + } + /* Thermal interrupt */ + if (env->pending_interrupts & PPC_INTERRUPT_THERM) { + return PPC_INTERRUPT_THERM; + } + /* EBB exception */ + if (env->pending_interrupts & PPC_INTERRUPT_EBB) { + /* + * EBB exception must be taken in problem state and + * with BESCR_GE set. + */ + if (FIELD_EX64(env->msr, MSR, PR) && + (env->spr[SPR_BESCR] & BESCR_GE)) { + return PPC_INTERRUPT_EBB; + } + } + } + + return 0; +} + #define P9_UNUSED_INTERRUPTS \ (PPC_INTERRUPT_RESET | PPC_INTERRUPT_DEBUG | PPC_INTERRUPT_CEXT | \ PPC_INTERRUPT_WDT | PPC_INTERRUPT_CDOORBELL | PPC_INTERRUPT_FIT | \ @@ -1897,6 +2003,8 @@ static int ppc_next_unmasked_interrupt(CPUPPCState *env) { switch (env->excp_model) { #if defined(TARGET_PPC64) + case POWERPC_EXCP_POWER8: + return p8_next_unmasked_interrupt(env); case POWERPC_EXCP_POWER9: case POWERPC_EXCP_POWER10: return p9_next_unmasked_interrupt(env); From f6194fdde2e37743d2833b66fc272472190e51cc Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Tue, 11 Oct 2022 17:48:13 -0300 Subject: [PATCH 367/705] target/ppc: remove unused interrupts from p8_next_unmasked_interrupt Remove the following unused interrupts from the POWER8 interrupt masking method: - PPC_INTERRUPT_RESET: only raised for 6xx, 7xx, 970, and POWER5p; - Debug Interrupt: removed in Power ISA v2.07; - Hypervisor Virtualization: introduced in Power ISA v3.0; - Critical Input, Watchdog Timer, and Fixed Interval Timer: only defined for embedded CPUs; - Critical Doorbell: processor does not implement the "Embedded.Processor Control" category; - Programmable Interval Timer: 40x-only; - PPC_INTERRUPT_THERM: only raised for 970 and POWER5p; Signed-off-by: Matheus Ferst Reviewed-by: Fabiano Rosas Message-Id: <20221011204829.1641124-14-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/excp_helper.c | 45 +++++++--------------------------------- 1 file changed, 7 insertions(+), 38 deletions(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index c7b303a9a7..2bb636a439 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -1685,14 +1685,17 @@ void ppc_cpu_do_interrupt(CPUState *cs) } #if defined(TARGET_PPC64) +#define P8_UNUSED_INTERRUPTS \ + (PPC_INTERRUPT_RESET | PPC_INTERRUPT_DEBUG | PPC_INTERRUPT_HVIRT | \ + PPC_INTERRUPT_CEXT | PPC_INTERRUPT_WDT | PPC_INTERRUPT_CDOORBELL | \ + PPC_INTERRUPT_FIT | PPC_INTERRUPT_PIT | PPC_INTERRUPT_THERM) + static int p8_next_unmasked_interrupt(CPUPPCState *env) { bool async_deliver; - /* External reset */ - if (env->pending_interrupts & PPC_INTERRUPT_RESET) { - return PPC_INTERRUPT_RESET; - } + assert((env->pending_interrupts & P8_UNUSED_INTERRUPTS) == 0); + /* Machine check exception */ if (env->pending_interrupts & PPC_INTERRUPT_MCK) { return PPC_INTERRUPT_MCK; @@ -1716,15 +1719,6 @@ static int p8_next_unmasked_interrupt(CPUPPCState *env) } } - /* Hypervisor virtualization interrupt */ - if (env->pending_interrupts & PPC_INTERRUPT_HVIRT) { - /* LPCR will be clear when not supported so this will work */ - bool hvice = !!(env->spr[SPR_LPCR] & LPCR_HVICE); - if ((async_deliver || !FIELD_EX64_HV(env->msr)) && hvice) { - return PPC_INTERRUPT_HVIRT; - } - } - /* External interrupt can ignore MSR:EE under some circumstances */ if (env->pending_interrupts & PPC_INTERRUPT_EXT) { bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); @@ -1736,28 +1730,7 @@ static int p8_next_unmasked_interrupt(CPUPPCState *env) return PPC_INTERRUPT_EXT; } } - if (FIELD_EX64(env->msr, MSR, CE)) { - /* External critical interrupt */ - if (env->pending_interrupts & PPC_INTERRUPT_CEXT) { - return PPC_INTERRUPT_CEXT; - } - } if (async_deliver != 0) { - /* Watchdog timer on embedded PowerPC */ - if (env->pending_interrupts & PPC_INTERRUPT_WDT) { - return PPC_INTERRUPT_WDT; - } - if (env->pending_interrupts & PPC_INTERRUPT_CDOORBELL) { - return PPC_INTERRUPT_CDOORBELL; - } - /* Fixed interval timer on embedded PowerPC */ - if (env->pending_interrupts & PPC_INTERRUPT_FIT) { - return PPC_INTERRUPT_FIT; - } - /* Programmable interval timer on embedded PowerPC */ - if (env->pending_interrupts & PPC_INTERRUPT_PIT) { - return PPC_INTERRUPT_PIT; - } /* Decrementer exception */ if (env->pending_interrupts & PPC_INTERRUPT_DECR) { return PPC_INTERRUPT_DECR; @@ -1771,10 +1744,6 @@ static int p8_next_unmasked_interrupt(CPUPPCState *env) if (env->pending_interrupts & PPC_INTERRUPT_PERFM) { return PPC_INTERRUPT_PERFM; } - /* Thermal interrupt */ - if (env->pending_interrupts & PPC_INTERRUPT_THERM) { - return PPC_INTERRUPT_THERM; - } /* EBB exception */ if (env->pending_interrupts & PPC_INTERRUPT_EBB) { /* From 6527e757db546fcdc4a0a695325fb3f1fb0804d5 Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Tue, 11 Oct 2022 17:48:14 -0300 Subject: [PATCH 368/705] target/ppc: create an interrupt deliver method for POWER8 The new method is identical to ppc_deliver_interrupt, processor-specific code will be added/removed in the following patches. Signed-off-by: Matheus Ferst Reviewed-by: Fabiano Rosas Message-Id: <20221011204829.1641124-15-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/excp_helper.c | 107 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 2bb636a439..c2ebb5280f 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -1984,6 +1984,110 @@ static int ppc_next_unmasked_interrupt(CPUPPCState *env) } #if defined(TARGET_PPC64) +static void p8_deliver_interrupt(CPUPPCState *env, int interrupt) +{ + PowerPCCPU *cpu = env_archcpu(env); + CPUState *cs = env_cpu(env); + + switch (interrupt) { + case PPC_INTERRUPT_RESET: /* External reset */ + env->pending_interrupts &= ~PPC_INTERRUPT_RESET; + powerpc_excp(cpu, POWERPC_EXCP_RESET); + break; + case PPC_INTERRUPT_MCK: /* Machine check exception */ + env->pending_interrupts &= ~PPC_INTERRUPT_MCK; + powerpc_excp(cpu, POWERPC_EXCP_MCHECK); + break; + + case PPC_INTERRUPT_HDECR: /* Hypervisor decrementer exception */ + /* HDEC clears on delivery */ + env->pending_interrupts &= ~PPC_INTERRUPT_HDECR; + powerpc_excp(cpu, POWERPC_EXCP_HDECR); + break; + case PPC_INTERRUPT_HVIRT: /* Hypervisor virtualization interrupt */ + powerpc_excp(cpu, POWERPC_EXCP_HVIRT); + break; + + case PPC_INTERRUPT_EXT: + if (books_vhyp_promotes_external_to_hvirt(cpu)) { + powerpc_excp(cpu, POWERPC_EXCP_HVIRT); + } else { + powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL); + } + break; + case PPC_INTERRUPT_CEXT: /* External critical interrupt */ + powerpc_excp(cpu, POWERPC_EXCP_CRITICAL); + break; + + case PPC_INTERRUPT_WDT: /* Watchdog timer on embedded PowerPC */ + env->pending_interrupts &= ~PPC_INTERRUPT_WDT; + powerpc_excp(cpu, POWERPC_EXCP_WDT); + break; + case PPC_INTERRUPT_CDOORBELL: + env->pending_interrupts &= ~PPC_INTERRUPT_CDOORBELL; + powerpc_excp(cpu, POWERPC_EXCP_DOORCI); + break; + case PPC_INTERRUPT_FIT: /* Fixed interval timer on embedded PowerPC */ + env->pending_interrupts &= ~PPC_INTERRUPT_FIT; + powerpc_excp(cpu, POWERPC_EXCP_FIT); + break; + case PPC_INTERRUPT_PIT: /* Programmable interval timer on embedded ppc */ + env->pending_interrupts &= ~PPC_INTERRUPT_PIT; + powerpc_excp(cpu, POWERPC_EXCP_PIT); + break; + case PPC_INTERRUPT_DECR: /* Decrementer exception */ + if (ppc_decr_clear_on_delivery(env)) { + env->pending_interrupts &= ~PPC_INTERRUPT_DECR; + } + powerpc_excp(cpu, POWERPC_EXCP_DECR); + break; + case PPC_INTERRUPT_DOORBELL: + env->pending_interrupts &= ~PPC_INTERRUPT_DOORBELL; + if (is_book3s_arch2x(env)) { + powerpc_excp(cpu, POWERPC_EXCP_SDOOR); + } else { + powerpc_excp(cpu, POWERPC_EXCP_DOORI); + } + break; + case PPC_INTERRUPT_HDOORBELL: + env->pending_interrupts &= ~PPC_INTERRUPT_HDOORBELL; + powerpc_excp(cpu, POWERPC_EXCP_SDOOR_HV); + break; + case PPC_INTERRUPT_PERFM: + env->pending_interrupts &= ~PPC_INTERRUPT_PERFM; + powerpc_excp(cpu, POWERPC_EXCP_PERFM); + break; + case PPC_INTERRUPT_THERM: /* Thermal interrupt */ + env->pending_interrupts &= ~PPC_INTERRUPT_THERM; + powerpc_excp(cpu, POWERPC_EXCP_THERM); + break; + case PPC_INTERRUPT_EBB: /* EBB exception */ + env->pending_interrupts &= ~PPC_INTERRUPT_EBB; + if (env->spr[SPR_BESCR] & BESCR_PMEO) { + powerpc_excp(cpu, POWERPC_EXCP_PERFM_EBB); + } else if (env->spr[SPR_BESCR] & BESCR_EEO) { + powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL_EBB); + } + break; + case 0: + /* + * This is a bug ! It means that has_work took us out of halt without + * anything to deliver while in a PM state that requires getting + * out via a 0x100 + * + * This means we will incorrectly execute past the power management + * instruction instead of triggering a reset. + * + * It generally means a discrepancy between the wakeup conditions in the + * processor has_work implementation and the logic in this function. + */ + assert(!env->resume_as_sreset); + break; + default: + cpu_abort(cs, "Invalid PowerPC interrupt %d. Aborting\n", interrupt); + } +} + static void p9_deliver_interrupt(CPUPPCState *env, int interrupt) { PowerPCCPU *cpu = env_archcpu(env); @@ -2172,6 +2276,9 @@ static void ppc_deliver_interrupt(CPUPPCState *env, int interrupt) { switch (env->excp_model) { #if defined(TARGET_PPC64) + case POWERPC_EXCP_POWER8: + p8_deliver_interrupt(env, interrupt); + break; case POWERPC_EXCP_POWER9: case POWERPC_EXCP_POWER10: p9_deliver_interrupt(env, interrupt); From 567372673e4e3aaaa0391bb5ea127e387f4dbd34 Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Tue, 11 Oct 2022 17:48:15 -0300 Subject: [PATCH 369/705] target/ppc: remove unused interrupts from p8_deliver_interrupt Remove the following unused interrupts from the POWER8 interrupt processing method: - PPC_INTERRUPT_RESET: only raised for 6xx, 7xx, 970 and POWER5p; - Debug Interrupt: removed in Power ISA v2.07; - Hypervisor Virtualization: introduced in Power ISA v3.0; - Critical Input, Watchdog Timer, and Fixed Interval Timer: only defined for embedded CPUs; - Critical Doorbell: processor does not implement the "Embedded.Processor Control" category; - Programmable Interval Timer: 40x-only; - PPC_INTERRUPT_THERM: only raised for 970 and POWER5p; Signed-off-by: Matheus Ferst Reviewed-by: Fabiano Rosas Message-Id: <20221011204829.1641124-16-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/excp_helper.c | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index c2ebb5280f..21cd8d02af 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -1990,10 +1990,6 @@ static void p8_deliver_interrupt(CPUPPCState *env, int interrupt) CPUState *cs = env_cpu(env); switch (interrupt) { - case PPC_INTERRUPT_RESET: /* External reset */ - env->pending_interrupts &= ~PPC_INTERRUPT_RESET; - powerpc_excp(cpu, POWERPC_EXCP_RESET); - break; case PPC_INTERRUPT_MCK: /* Machine check exception */ env->pending_interrupts &= ~PPC_INTERRUPT_MCK; powerpc_excp(cpu, POWERPC_EXCP_MCHECK); @@ -2004,9 +2000,6 @@ static void p8_deliver_interrupt(CPUPPCState *env, int interrupt) env->pending_interrupts &= ~PPC_INTERRUPT_HDECR; powerpc_excp(cpu, POWERPC_EXCP_HDECR); break; - case PPC_INTERRUPT_HVIRT: /* Hypervisor virtualization interrupt */ - powerpc_excp(cpu, POWERPC_EXCP_HVIRT); - break; case PPC_INTERRUPT_EXT: if (books_vhyp_promotes_external_to_hvirt(cpu)) { @@ -2015,26 +2008,7 @@ static void p8_deliver_interrupt(CPUPPCState *env, int interrupt) powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL); } break; - case PPC_INTERRUPT_CEXT: /* External critical interrupt */ - powerpc_excp(cpu, POWERPC_EXCP_CRITICAL); - break; - case PPC_INTERRUPT_WDT: /* Watchdog timer on embedded PowerPC */ - env->pending_interrupts &= ~PPC_INTERRUPT_WDT; - powerpc_excp(cpu, POWERPC_EXCP_WDT); - break; - case PPC_INTERRUPT_CDOORBELL: - env->pending_interrupts &= ~PPC_INTERRUPT_CDOORBELL; - powerpc_excp(cpu, POWERPC_EXCP_DOORCI); - break; - case PPC_INTERRUPT_FIT: /* Fixed interval timer on embedded PowerPC */ - env->pending_interrupts &= ~PPC_INTERRUPT_FIT; - powerpc_excp(cpu, POWERPC_EXCP_FIT); - break; - case PPC_INTERRUPT_PIT: /* Programmable interval timer on embedded ppc */ - env->pending_interrupts &= ~PPC_INTERRUPT_PIT; - powerpc_excp(cpu, POWERPC_EXCP_PIT); - break; case PPC_INTERRUPT_DECR: /* Decrementer exception */ if (ppc_decr_clear_on_delivery(env)) { env->pending_interrupts &= ~PPC_INTERRUPT_DECR; @@ -2057,10 +2031,6 @@ static void p8_deliver_interrupt(CPUPPCState *env, int interrupt) env->pending_interrupts &= ~PPC_INTERRUPT_PERFM; powerpc_excp(cpu, POWERPC_EXCP_PERFM); break; - case PPC_INTERRUPT_THERM: /* Thermal interrupt */ - env->pending_interrupts &= ~PPC_INTERRUPT_THERM; - powerpc_excp(cpu, POWERPC_EXCP_THERM); - break; case PPC_INTERRUPT_EBB: /* EBB exception */ env->pending_interrupts &= ~PPC_INTERRUPT_EBB; if (env->spr[SPR_BESCR] & BESCR_PMEO) { From d66b441d64ca63bb9b50d5d8a054b1836297a6e3 Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Tue, 11 Oct 2022 17:48:16 -0300 Subject: [PATCH 370/705] target/ppc: remove generic architecture checks from p8_deliver_interrupt Signed-off-by: Matheus Ferst Reviewed-by: Fabiano Rosas Message-Id: <20221011204829.1641124-17-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/excp_helper.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 21cd8d02af..b4afdc81ca 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -2010,9 +2010,6 @@ static void p8_deliver_interrupt(CPUPPCState *env, int interrupt) break; case PPC_INTERRUPT_DECR: /* Decrementer exception */ - if (ppc_decr_clear_on_delivery(env)) { - env->pending_interrupts &= ~PPC_INTERRUPT_DECR; - } powerpc_excp(cpu, POWERPC_EXCP_DECR); break; case PPC_INTERRUPT_DOORBELL: From 788ff1ce44b813475ddcb95726bdd3afdaa40d6d Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Tue, 11 Oct 2022 17:48:17 -0300 Subject: [PATCH 371/705] target/ppc: move power-saving interrupt masking out of cpu_has_work_POWER8 Move the interrupt masking logic out of cpu_has_work_POWER8 in a new method, p8_interrupt_powersave, that only returns an interrupt if it can wake the processor from power-saving mode. Signed-off-by: Matheus Ferst Reviewed-by: Fabiano Rosas Message-Id: <20221011204829.1641124-18-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/cpu_init.c | 61 +++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index 423d99d8d3..922390b938 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -6133,6 +6133,38 @@ static bool ppc_pvr_match_power8(PowerPCCPUClass *pcc, uint32_t pvr, bool best) return true; } +static int p8_interrupt_powersave(CPUPPCState *env) +{ + if ((env->pending_interrupts & PPC_INTERRUPT_EXT) && + (env->spr[SPR_LPCR] & LPCR_P8_PECE2)) { + return PPC_INTERRUPT_EXT; + } + if ((env->pending_interrupts & PPC_INTERRUPT_DECR) && + (env->spr[SPR_LPCR] & LPCR_P8_PECE3)) { + return PPC_INTERRUPT_DECR; + } + if ((env->pending_interrupts & PPC_INTERRUPT_MCK) && + (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) { + return PPC_INTERRUPT_MCK; + } + if ((env->pending_interrupts & PPC_INTERRUPT_HMI) && + (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) { + return PPC_INTERRUPT_HMI; + } + if ((env->pending_interrupts & PPC_INTERRUPT_DOORBELL) && + (env->spr[SPR_LPCR] & LPCR_P8_PECE0)) { + return PPC_INTERRUPT_DOORBELL; + } + if ((env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) && + (env->spr[SPR_LPCR] & LPCR_P8_PECE1)) { + return PPC_INTERRUPT_HDOORBELL; + } + if (env->pending_interrupts & PPC_INTERRUPT_RESET) { + return PPC_INTERRUPT_RESET; + } + return 0; +} + static bool cpu_has_work_POWER8(CPUState *cs) { PowerPCCPU *cpu = POWERPC_CPU(cs); @@ -6142,34 +6174,7 @@ static bool cpu_has_work_POWER8(CPUState *cs) if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) { return false; } - if ((env->pending_interrupts & PPC_INTERRUPT_EXT) && - (env->spr[SPR_LPCR] & LPCR_P8_PECE2)) { - return true; - } - if ((env->pending_interrupts & PPC_INTERRUPT_DECR) && - (env->spr[SPR_LPCR] & LPCR_P8_PECE3)) { - return true; - } - if ((env->pending_interrupts & PPC_INTERRUPT_MCK) && - (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) { - return true; - } - if ((env->pending_interrupts & PPC_INTERRUPT_HMI) && - (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) { - return true; - } - if ((env->pending_interrupts & PPC_INTERRUPT_DOORBELL) && - (env->spr[SPR_LPCR] & LPCR_P8_PECE0)) { - return true; - } - if ((env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) && - (env->spr[SPR_LPCR] & LPCR_P8_PECE1)) { - return true; - } - if (env->pending_interrupts & PPC_INTERRUPT_RESET) { - return true; - } - return false; + return p8_interrupt_powersave(env) != 0; } else { return FIELD_EX64(env->msr, MSR, EE) && (cs->interrupt_request & CPU_INTERRUPT_HARD); From 64a9b5eebef97d5b742b162625d5bc262be832ec Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Tue, 11 Oct 2022 17:48:18 -0300 Subject: [PATCH 372/705] target/ppc: add power-saving interrupt masking logic to p8_next_unmasked_interrupt Export p8_interrupt_powersave and use it in p8_next_unmasked_interrupt. Signed-off-by: Matheus Ferst Reviewed-by: Fabiano Rosas Message-Id: <20221011204829.1641124-19-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/cpu_init.c | 2 +- target/ppc/excp_helper.c | 24 ++++++++++++------------ target/ppc/internal.h | 1 + 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index 922390b938..68ae22d1f4 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -6133,7 +6133,7 @@ static bool ppc_pvr_match_power8(PowerPCCPUClass *pcc, uint32_t pvr, bool best) return true; } -static int p8_interrupt_powersave(CPUPPCState *env) +int p8_interrupt_powersave(CPUPPCState *env) { if ((env->pending_interrupts & PPC_INTERRUPT_EXT) && (env->spr[SPR_LPCR] & LPCR_P8_PECE2)) { diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index b4afdc81ca..9fa75c55c9 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -1692,28 +1692,28 @@ void ppc_cpu_do_interrupt(CPUState *cs) static int p8_next_unmasked_interrupt(CPUPPCState *env) { - bool async_deliver; + PowerPCCPU *cpu = env_archcpu(env); + CPUState *cs = CPU(cpu); + /* Ignore MSR[EE] when coming out of some power management states */ + bool msr_ee = FIELD_EX64(env->msr, MSR, EE) || env->resume_as_sreset; assert((env->pending_interrupts & P8_UNUSED_INTERRUPTS) == 0); + if (cs->halted) { + /* LPCR[PECE] controls which interrupts can exit power-saving mode */ + return p8_interrupt_powersave(env); + } + /* Machine check exception */ if (env->pending_interrupts & PPC_INTERRUPT_MCK) { return PPC_INTERRUPT_MCK; } - /* - * For interrupts that gate on MSR:EE, we need to do something a - * bit more subtle, as we need to let them through even when EE is - * clear when coming out of some power management states (in order - * for them to become a 0x100). - */ - async_deliver = FIELD_EX64(env->msr, MSR, EE) || env->resume_as_sreset; - /* Hypervisor decrementer exception */ if (env->pending_interrupts & PPC_INTERRUPT_HDECR) { /* LPCR will be clear when not supported so this will work */ bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE); - if ((async_deliver || !FIELD_EX64_HV(env->msr)) && hdice) { + if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hdice) { /* HDEC clears on delivery */ return PPC_INTERRUPT_HDECR; } @@ -1724,13 +1724,13 @@ static int p8_next_unmasked_interrupt(CPUPPCState *env) bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); /* HEIC blocks delivery to the hypervisor */ - if ((async_deliver && !(heic && FIELD_EX64_HV(env->msr) && + if ((msr_ee && !(heic && FIELD_EX64_HV(env->msr) && !FIELD_EX64(env->msr, MSR, PR))) || (env->has_hv_mode && !FIELD_EX64_HV(env->msr) && !lpes0)) { return PPC_INTERRUPT_EXT; } } - if (async_deliver != 0) { + if (msr_ee != 0) { /* Decrementer exception */ if (env->pending_interrupts & PPC_INTERRUPT_DECR) { return PPC_INTERRUPT_DECR; diff --git a/target/ppc/internal.h b/target/ppc/internal.h index 41e79adfdb..9069874adb 100644 --- a/target/ppc/internal.h +++ b/target/ppc/internal.h @@ -308,6 +308,7 @@ static inline int ger_pack_masks(int pmsk, int ymsk, int xmsk) #if defined(TARGET_PPC64) int p9_interrupt_powersave(CPUPPCState *env); +int p8_interrupt_powersave(CPUPPCState *env); #endif #endif /* PPC_INTERNAL_H */ From bf303fb3f11c3e131f315e44b792ad79a8ae07bb Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Tue, 11 Oct 2022 17:48:19 -0300 Subject: [PATCH 373/705] target/ppc: create an interrupt masking method for POWER7 The new method is identical to ppc_next_unmasked_interrupt_generic, processor-specific code will be added/removed in the following patches. Signed-off-by: Matheus Ferst Reviewed-by: Fabiano Rosas Message-Id: <20221011204829.1641124-20-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/excp_helper.c | 108 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 9fa75c55c9..d99b76ce22 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -1685,6 +1685,112 @@ void ppc_cpu_do_interrupt(CPUState *cs) } #if defined(TARGET_PPC64) +static int p7_next_unmasked_interrupt(CPUPPCState *env) +{ + bool async_deliver; + + /* External reset */ + if (env->pending_interrupts & PPC_INTERRUPT_RESET) { + return PPC_INTERRUPT_RESET; + } + /* Machine check exception */ + if (env->pending_interrupts & PPC_INTERRUPT_MCK) { + return PPC_INTERRUPT_MCK; + } + + /* + * For interrupts that gate on MSR:EE, we need to do something a + * bit more subtle, as we need to let them through even when EE is + * clear when coming out of some power management states (in order + * for them to become a 0x100). + */ + async_deliver = FIELD_EX64(env->msr, MSR, EE) || env->resume_as_sreset; + + /* Hypervisor decrementer exception */ + if (env->pending_interrupts & PPC_INTERRUPT_HDECR) { + /* LPCR will be clear when not supported so this will work */ + bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE); + if ((async_deliver || !FIELD_EX64_HV(env->msr)) && hdice) { + /* HDEC clears on delivery */ + return PPC_INTERRUPT_HDECR; + } + } + + /* Hypervisor virtualization interrupt */ + if (env->pending_interrupts & PPC_INTERRUPT_HVIRT) { + /* LPCR will be clear when not supported so this will work */ + bool hvice = !!(env->spr[SPR_LPCR] & LPCR_HVICE); + if ((async_deliver || !FIELD_EX64_HV(env->msr)) && hvice) { + return PPC_INTERRUPT_HVIRT; + } + } + + /* External interrupt can ignore MSR:EE under some circumstances */ + if (env->pending_interrupts & PPC_INTERRUPT_EXT) { + bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); + bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); + /* HEIC blocks delivery to the hypervisor */ + if ((async_deliver && !(heic && FIELD_EX64_HV(env->msr) && + !FIELD_EX64(env->msr, MSR, PR))) || + (env->has_hv_mode && !FIELD_EX64_HV(env->msr) && !lpes0)) { + return PPC_INTERRUPT_EXT; + } + } + if (FIELD_EX64(env->msr, MSR, CE)) { + /* External critical interrupt */ + if (env->pending_interrupts & PPC_INTERRUPT_CEXT) { + return PPC_INTERRUPT_CEXT; + } + } + if (async_deliver != 0) { + /* Watchdog timer on embedded PowerPC */ + if (env->pending_interrupts & PPC_INTERRUPT_WDT) { + return PPC_INTERRUPT_WDT; + } + if (env->pending_interrupts & PPC_INTERRUPT_CDOORBELL) { + return PPC_INTERRUPT_CDOORBELL; + } + /* Fixed interval timer on embedded PowerPC */ + if (env->pending_interrupts & PPC_INTERRUPT_FIT) { + return PPC_INTERRUPT_FIT; + } + /* Programmable interval timer on embedded PowerPC */ + if (env->pending_interrupts & PPC_INTERRUPT_PIT) { + return PPC_INTERRUPT_PIT; + } + /* Decrementer exception */ + if (env->pending_interrupts & PPC_INTERRUPT_DECR) { + return PPC_INTERRUPT_DECR; + } + if (env->pending_interrupts & PPC_INTERRUPT_DOORBELL) { + return PPC_INTERRUPT_DOORBELL; + } + if (env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) { + return PPC_INTERRUPT_HDOORBELL; + } + if (env->pending_interrupts & PPC_INTERRUPT_PERFM) { + return PPC_INTERRUPT_PERFM; + } + /* Thermal interrupt */ + if (env->pending_interrupts & PPC_INTERRUPT_THERM) { + return PPC_INTERRUPT_THERM; + } + /* EBB exception */ + if (env->pending_interrupts & PPC_INTERRUPT_EBB) { + /* + * EBB exception must be taken in problem state and + * with BESCR_GE set. + */ + if (FIELD_EX64(env->msr, MSR, PR) && + (env->spr[SPR_BESCR] & BESCR_GE)) { + return PPC_INTERRUPT_EBB; + } + } + } + + return 0; +} + #define P8_UNUSED_INTERRUPTS \ (PPC_INTERRUPT_RESET | PPC_INTERRUPT_DEBUG | PPC_INTERRUPT_HVIRT | \ PPC_INTERRUPT_CEXT | PPC_INTERRUPT_WDT | PPC_INTERRUPT_CDOORBELL | \ @@ -1972,6 +2078,8 @@ static int ppc_next_unmasked_interrupt(CPUPPCState *env) { switch (env->excp_model) { #if defined(TARGET_PPC64) + case POWERPC_EXCP_POWER7: + return p7_next_unmasked_interrupt(env); case POWERPC_EXCP_POWER8: return p8_next_unmasked_interrupt(env); case POWERPC_EXCP_POWER9: From c8e1de2e421fcb5ce88443bd819f919e3eab13f2 Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Tue, 11 Oct 2022 17:48:20 -0300 Subject: [PATCH 374/705] target/ppc: remove unused interrupts from p7_next_unmasked_interrupt Remove the following unused interrupts from the POWER7 interrupt masking method: - PPC_INTERRUPT_RESET: only raised for 6xx, 7xx, 970 and POWER5p; - Hypervisor Virtualization: introduced in Power ISA v3.0; - Hypervisor Doorbell and Event-Based Branch: introduced in Power ISA v2.07; - Critical Input, Watchdog Timer, and Fixed Interval Timer: only defined for embedded CPUs; - Doorbell and Critical Doorbell Interrupt: processor does not implement the Embedded.Processor Control category; - Programmable Interval Timer: 40x-only; - PPC_INTERRUPT_THERM: only raised for 970 and POWER5p; Signed-off-by: Matheus Ferst Reviewed-by: Fabiano Rosas Message-Id: <20221011204829.1641124-21-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/excp_helper.c | 63 +++++----------------------------------- 1 file changed, 8 insertions(+), 55 deletions(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index d99b76ce22..08db3a4658 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -1685,14 +1685,18 @@ void ppc_cpu_do_interrupt(CPUState *cs) } #if defined(TARGET_PPC64) +#define P7_UNUSED_INTERRUPTS \ + (PPC_INTERRUPT_RESET | PPC_INTERRUPT_HVIRT | PPC_INTERRUPT_CEXT | \ + PPC_INTERRUPT_WDT | PPC_INTERRUPT_CDOORBELL | PPC_INTERRUPT_FIT | \ + PPC_INTERRUPT_PIT | PPC_INTERRUPT_DOORBELL | PPC_INTERRUPT_HDOORBELL | \ + PPC_INTERRUPT_THERM | PPC_INTERRUPT_EBB) + static int p7_next_unmasked_interrupt(CPUPPCState *env) { bool async_deliver; - /* External reset */ - if (env->pending_interrupts & PPC_INTERRUPT_RESET) { - return PPC_INTERRUPT_RESET; - } + assert((env->pending_interrupts & P7_UNUSED_INTERRUPTS) == 0); + /* Machine check exception */ if (env->pending_interrupts & PPC_INTERRUPT_MCK) { return PPC_INTERRUPT_MCK; @@ -1716,15 +1720,6 @@ static int p7_next_unmasked_interrupt(CPUPPCState *env) } } - /* Hypervisor virtualization interrupt */ - if (env->pending_interrupts & PPC_INTERRUPT_HVIRT) { - /* LPCR will be clear when not supported so this will work */ - bool hvice = !!(env->spr[SPR_LPCR] & LPCR_HVICE); - if ((async_deliver || !FIELD_EX64_HV(env->msr)) && hvice) { - return PPC_INTERRUPT_HVIRT; - } - } - /* External interrupt can ignore MSR:EE under some circumstances */ if (env->pending_interrupts & PPC_INTERRUPT_EXT) { bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); @@ -1736,56 +1731,14 @@ static int p7_next_unmasked_interrupt(CPUPPCState *env) return PPC_INTERRUPT_EXT; } } - if (FIELD_EX64(env->msr, MSR, CE)) { - /* External critical interrupt */ - if (env->pending_interrupts & PPC_INTERRUPT_CEXT) { - return PPC_INTERRUPT_CEXT; - } - } if (async_deliver != 0) { - /* Watchdog timer on embedded PowerPC */ - if (env->pending_interrupts & PPC_INTERRUPT_WDT) { - return PPC_INTERRUPT_WDT; - } - if (env->pending_interrupts & PPC_INTERRUPT_CDOORBELL) { - return PPC_INTERRUPT_CDOORBELL; - } - /* Fixed interval timer on embedded PowerPC */ - if (env->pending_interrupts & PPC_INTERRUPT_FIT) { - return PPC_INTERRUPT_FIT; - } - /* Programmable interval timer on embedded PowerPC */ - if (env->pending_interrupts & PPC_INTERRUPT_PIT) { - return PPC_INTERRUPT_PIT; - } /* Decrementer exception */ if (env->pending_interrupts & PPC_INTERRUPT_DECR) { return PPC_INTERRUPT_DECR; } - if (env->pending_interrupts & PPC_INTERRUPT_DOORBELL) { - return PPC_INTERRUPT_DOORBELL; - } - if (env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) { - return PPC_INTERRUPT_HDOORBELL; - } if (env->pending_interrupts & PPC_INTERRUPT_PERFM) { return PPC_INTERRUPT_PERFM; } - /* Thermal interrupt */ - if (env->pending_interrupts & PPC_INTERRUPT_THERM) { - return PPC_INTERRUPT_THERM; - } - /* EBB exception */ - if (env->pending_interrupts & PPC_INTERRUPT_EBB) { - /* - * EBB exception must be taken in problem state and - * with BESCR_GE set. - */ - if (FIELD_EX64(env->msr, MSR, PR) && - (env->spr[SPR_BESCR] & BESCR_GE)) { - return PPC_INTERRUPT_EBB; - } - } } return 0; From d93a48561c59b08958c9c37191248492a7acb8e4 Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Tue, 11 Oct 2022 17:48:21 -0300 Subject: [PATCH 375/705] target/ppc: create an interrupt deliver method for POWER7 The new method is identical to ppc_deliver_interrupt, processor-specific code will be added/removed in the following patches. Signed-off-by: Matheus Ferst Reviewed-by: Fabiano Rosas Message-Id: <20221011204829.1641124-22-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/excp_helper.c | 107 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 08db3a4658..5bb05016fd 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -2045,6 +2045,110 @@ static int ppc_next_unmasked_interrupt(CPUPPCState *env) } #if defined(TARGET_PPC64) +static void p7_deliver_interrupt(CPUPPCState *env, int interrupt) +{ + PowerPCCPU *cpu = env_archcpu(env); + CPUState *cs = env_cpu(env); + + switch (interrupt) { + case PPC_INTERRUPT_RESET: /* External reset */ + env->pending_interrupts &= ~PPC_INTERRUPT_RESET; + powerpc_excp(cpu, POWERPC_EXCP_RESET); + break; + case PPC_INTERRUPT_MCK: /* Machine check exception */ + env->pending_interrupts &= ~PPC_INTERRUPT_MCK; + powerpc_excp(cpu, POWERPC_EXCP_MCHECK); + break; + + case PPC_INTERRUPT_HDECR: /* Hypervisor decrementer exception */ + /* HDEC clears on delivery */ + env->pending_interrupts &= ~PPC_INTERRUPT_HDECR; + powerpc_excp(cpu, POWERPC_EXCP_HDECR); + break; + case PPC_INTERRUPT_HVIRT: /* Hypervisor virtualization interrupt */ + powerpc_excp(cpu, POWERPC_EXCP_HVIRT); + break; + + case PPC_INTERRUPT_EXT: + if (books_vhyp_promotes_external_to_hvirt(cpu)) { + powerpc_excp(cpu, POWERPC_EXCP_HVIRT); + } else { + powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL); + } + break; + case PPC_INTERRUPT_CEXT: /* External critical interrupt */ + powerpc_excp(cpu, POWERPC_EXCP_CRITICAL); + break; + + case PPC_INTERRUPT_WDT: /* Watchdog timer on embedded PowerPC */ + env->pending_interrupts &= ~PPC_INTERRUPT_WDT; + powerpc_excp(cpu, POWERPC_EXCP_WDT); + break; + case PPC_INTERRUPT_CDOORBELL: + env->pending_interrupts &= ~PPC_INTERRUPT_CDOORBELL; + powerpc_excp(cpu, POWERPC_EXCP_DOORCI); + break; + case PPC_INTERRUPT_FIT: /* Fixed interval timer on embedded PowerPC */ + env->pending_interrupts &= ~PPC_INTERRUPT_FIT; + powerpc_excp(cpu, POWERPC_EXCP_FIT); + break; + case PPC_INTERRUPT_PIT: /* Programmable interval timer on embedded ppc */ + env->pending_interrupts &= ~PPC_INTERRUPT_PIT; + powerpc_excp(cpu, POWERPC_EXCP_PIT); + break; + case PPC_INTERRUPT_DECR: /* Decrementer exception */ + if (ppc_decr_clear_on_delivery(env)) { + env->pending_interrupts &= ~PPC_INTERRUPT_DECR; + } + powerpc_excp(cpu, POWERPC_EXCP_DECR); + break; + case PPC_INTERRUPT_DOORBELL: + env->pending_interrupts &= ~PPC_INTERRUPT_DOORBELL; + if (is_book3s_arch2x(env)) { + powerpc_excp(cpu, POWERPC_EXCP_SDOOR); + } else { + powerpc_excp(cpu, POWERPC_EXCP_DOORI); + } + break; + case PPC_INTERRUPT_HDOORBELL: + env->pending_interrupts &= ~PPC_INTERRUPT_HDOORBELL; + powerpc_excp(cpu, POWERPC_EXCP_SDOOR_HV); + break; + case PPC_INTERRUPT_PERFM: + env->pending_interrupts &= ~PPC_INTERRUPT_PERFM; + powerpc_excp(cpu, POWERPC_EXCP_PERFM); + break; + case PPC_INTERRUPT_THERM: /* Thermal interrupt */ + env->pending_interrupts &= ~PPC_INTERRUPT_THERM; + powerpc_excp(cpu, POWERPC_EXCP_THERM); + break; + case PPC_INTERRUPT_EBB: /* EBB exception */ + env->pending_interrupts &= ~PPC_INTERRUPT_EBB; + if (env->spr[SPR_BESCR] & BESCR_PMEO) { + powerpc_excp(cpu, POWERPC_EXCP_PERFM_EBB); + } else if (env->spr[SPR_BESCR] & BESCR_EEO) { + powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL_EBB); + } + break; + case 0: + /* + * This is a bug ! It means that has_work took us out of halt without + * anything to deliver while in a PM state that requires getting + * out via a 0x100 + * + * This means we will incorrectly execute past the power management + * instruction instead of triggering a reset. + * + * It generally means a discrepancy between the wakeup conditions in the + * processor has_work implementation and the logic in this function. + */ + assert(!env->resume_as_sreset); + break; + default: + cpu_abort(cs, "Invalid PowerPC interrupt %d. Aborting\n", interrupt); + } +} + static void p8_deliver_interrupt(CPUPPCState *env, int interrupt) { PowerPCCPU *cpu = env_archcpu(env); @@ -2304,6 +2408,9 @@ static void ppc_deliver_interrupt(CPUPPCState *env, int interrupt) { switch (env->excp_model) { #if defined(TARGET_PPC64) + case POWERPC_EXCP_POWER7: + p7_deliver_interrupt(env, interrupt); + break; case POWERPC_EXCP_POWER8: p8_deliver_interrupt(env, interrupt); break; From ec0f351af109e2b3d94ae50f5fe560a435b544d1 Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Tue, 11 Oct 2022 17:48:22 -0300 Subject: [PATCH 376/705] target/ppc: remove unused interrupts from p7_deliver_interrupt Remove the following unused interrupts from the POWER7 interrupt processing method: - PPC_INTERRUPT_RESET: only raised for 6xx, 7xx, 970 and POWER5p; - Hypervisor Virtualization: introduced in Power ISA v3.0; - Hypervisor Doorbell and Event-Based Branch: introduced in Power ISA v2.07; - Critical Input, Watchdog Timer, and Fixed Interval Timer: only defined for embedded CPUs; - Doorbell and Critical Doorbell Interrupt: processor does not implement the Embedded.Processor Control category; - Programmable Interval Timer: 40x-only; - PPC_INTERRUPT_THERM: only raised for 970 and POWER5p; Signed-off-by: Matheus Ferst Reviewed-by: Fabiano Rosas Message-Id: <20221011204829.1641124-23-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/excp_helper.c | 50 ---------------------------------------- 1 file changed, 50 deletions(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 5bb05016fd..5373e088b4 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -2051,10 +2051,6 @@ static void p7_deliver_interrupt(CPUPPCState *env, int interrupt) CPUState *cs = env_cpu(env); switch (interrupt) { - case PPC_INTERRUPT_RESET: /* External reset */ - env->pending_interrupts &= ~PPC_INTERRUPT_RESET; - powerpc_excp(cpu, POWERPC_EXCP_RESET); - break; case PPC_INTERRUPT_MCK: /* Machine check exception */ env->pending_interrupts &= ~PPC_INTERRUPT_MCK; powerpc_excp(cpu, POWERPC_EXCP_MCHECK); @@ -2065,9 +2061,6 @@ static void p7_deliver_interrupt(CPUPPCState *env, int interrupt) env->pending_interrupts &= ~PPC_INTERRUPT_HDECR; powerpc_excp(cpu, POWERPC_EXCP_HDECR); break; - case PPC_INTERRUPT_HVIRT: /* Hypervisor virtualization interrupt */ - powerpc_excp(cpu, POWERPC_EXCP_HVIRT); - break; case PPC_INTERRUPT_EXT: if (books_vhyp_promotes_external_to_hvirt(cpu)) { @@ -2076,60 +2069,17 @@ static void p7_deliver_interrupt(CPUPPCState *env, int interrupt) powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL); } break; - case PPC_INTERRUPT_CEXT: /* External critical interrupt */ - powerpc_excp(cpu, POWERPC_EXCP_CRITICAL); - break; - case PPC_INTERRUPT_WDT: /* Watchdog timer on embedded PowerPC */ - env->pending_interrupts &= ~PPC_INTERRUPT_WDT; - powerpc_excp(cpu, POWERPC_EXCP_WDT); - break; - case PPC_INTERRUPT_CDOORBELL: - env->pending_interrupts &= ~PPC_INTERRUPT_CDOORBELL; - powerpc_excp(cpu, POWERPC_EXCP_DOORCI); - break; - case PPC_INTERRUPT_FIT: /* Fixed interval timer on embedded PowerPC */ - env->pending_interrupts &= ~PPC_INTERRUPT_FIT; - powerpc_excp(cpu, POWERPC_EXCP_FIT); - break; - case PPC_INTERRUPT_PIT: /* Programmable interval timer on embedded ppc */ - env->pending_interrupts &= ~PPC_INTERRUPT_PIT; - powerpc_excp(cpu, POWERPC_EXCP_PIT); - break; case PPC_INTERRUPT_DECR: /* Decrementer exception */ if (ppc_decr_clear_on_delivery(env)) { env->pending_interrupts &= ~PPC_INTERRUPT_DECR; } powerpc_excp(cpu, POWERPC_EXCP_DECR); break; - case PPC_INTERRUPT_DOORBELL: - env->pending_interrupts &= ~PPC_INTERRUPT_DOORBELL; - if (is_book3s_arch2x(env)) { - powerpc_excp(cpu, POWERPC_EXCP_SDOOR); - } else { - powerpc_excp(cpu, POWERPC_EXCP_DOORI); - } - break; - case PPC_INTERRUPT_HDOORBELL: - env->pending_interrupts &= ~PPC_INTERRUPT_HDOORBELL; - powerpc_excp(cpu, POWERPC_EXCP_SDOOR_HV); - break; case PPC_INTERRUPT_PERFM: env->pending_interrupts &= ~PPC_INTERRUPT_PERFM; powerpc_excp(cpu, POWERPC_EXCP_PERFM); break; - case PPC_INTERRUPT_THERM: /* Thermal interrupt */ - env->pending_interrupts &= ~PPC_INTERRUPT_THERM; - powerpc_excp(cpu, POWERPC_EXCP_THERM); - break; - case PPC_INTERRUPT_EBB: /* EBB exception */ - env->pending_interrupts &= ~PPC_INTERRUPT_EBB; - if (env->spr[SPR_BESCR] & BESCR_PMEO) { - powerpc_excp(cpu, POWERPC_EXCP_PERFM_EBB); - } else if (env->spr[SPR_BESCR] & BESCR_EEO) { - powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL_EBB); - } - break; case 0: /* * This is a bug ! It means that has_work took us out of halt without From 3f34e809ac856831949843d2adc45fab00f8b244 Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Tue, 11 Oct 2022 17:48:23 -0300 Subject: [PATCH 377/705] target/ppc: remove generic architecture checks from p7_deliver_interrupt Signed-off-by: Matheus Ferst Reviewed-by: Fabiano Rosas Message-Id: <20221011204829.1641124-24-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/excp_helper.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 5373e088b4..9164dc2e0f 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -2071,9 +2071,6 @@ static void p7_deliver_interrupt(CPUPPCState *env, int interrupt) break; case PPC_INTERRUPT_DECR: /* Decrementer exception */ - if (ppc_decr_clear_on_delivery(env)) { - env->pending_interrupts &= ~PPC_INTERRUPT_DECR; - } powerpc_excp(cpu, POWERPC_EXCP_DECR); break; case PPC_INTERRUPT_PERFM: From b34d358a212908326a43216162e90934015b02e7 Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Tue, 11 Oct 2022 17:48:24 -0300 Subject: [PATCH 378/705] target/ppc: move power-saving interrupt masking out of cpu_has_work_POWER7 Move the interrupt masking logic out of cpu_has_work_POWER7 in a new method, p7_interrupt_powersave, that only returns an interrupt if it can wake the processor from power-saving mode. Signed-off-by: Matheus Ferst Reviewed-by: Fabiano Rosas Message-Id: <20221011204829.1641124-25-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/cpu_init.c | 45 ++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index 68ae22d1f4..0c5ada7826 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -5960,6 +5960,30 @@ static bool ppc_pvr_match_power7(PowerPCCPUClass *pcc, uint32_t pvr, bool best) return true; } +static int p7_interrupt_powersave(CPUPPCState *env) +{ + if ((env->pending_interrupts & PPC_INTERRUPT_EXT) && + (env->spr[SPR_LPCR] & LPCR_P7_PECE0)) { + return PPC_INTERRUPT_EXT; + } + if ((env->pending_interrupts & PPC_INTERRUPT_DECR) && + (env->spr[SPR_LPCR] & LPCR_P7_PECE1)) { + return PPC_INTERRUPT_DECR; + } + if ((env->pending_interrupts & PPC_INTERRUPT_MCK) && + (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) { + return PPC_INTERRUPT_MCK; + } + if ((env->pending_interrupts & PPC_INTERRUPT_HMI) && + (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) { + return PPC_INTERRUPT_HMI; + } + if (env->pending_interrupts & PPC_INTERRUPT_RESET) { + return PPC_INTERRUPT_RESET; + } + return 0; +} + static bool cpu_has_work_POWER7(CPUState *cs) { PowerPCCPU *cpu = POWERPC_CPU(cs); @@ -5969,26 +5993,7 @@ static bool cpu_has_work_POWER7(CPUState *cs) if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) { return false; } - if ((env->pending_interrupts & PPC_INTERRUPT_EXT) && - (env->spr[SPR_LPCR] & LPCR_P7_PECE0)) { - return true; - } - if ((env->pending_interrupts & PPC_INTERRUPT_DECR) && - (env->spr[SPR_LPCR] & LPCR_P7_PECE1)) { - return true; - } - if ((env->pending_interrupts & PPC_INTERRUPT_MCK) && - (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) { - return true; - } - if ((env->pending_interrupts & PPC_INTERRUPT_HMI) && - (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) { - return true; - } - if (env->pending_interrupts & PPC_INTERRUPT_RESET) { - return true; - } - return false; + return p7_interrupt_powersave(env) != 0; } else { return FIELD_EX64(env->msr, MSR, EE) && (cs->interrupt_request & CPU_INTERRUPT_HARD); From 022b7128535d0ec963f724008a5f8b6a842d92ae Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Tue, 11 Oct 2022 17:48:25 -0300 Subject: [PATCH 379/705] target/ppc: add power-saving interrupt masking logic to p7_next_unmasked_interrupt Export p7_interrupt_powersave and use it in p7_next_unmasked_interrupt. Signed-off-by: Matheus Ferst Reviewed-by: Fabiano Rosas Message-Id: <20221011204829.1641124-26-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/cpu_init.c | 2 +- target/ppc/excp_helper.c | 24 ++++++++++++------------ target/ppc/internal.h | 1 + 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index 0c5ada7826..5238229cd6 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -5960,7 +5960,7 @@ static bool ppc_pvr_match_power7(PowerPCCPUClass *pcc, uint32_t pvr, bool best) return true; } -static int p7_interrupt_powersave(CPUPPCState *env) +int p7_interrupt_powersave(CPUPPCState *env) { if ((env->pending_interrupts & PPC_INTERRUPT_EXT) && (env->spr[SPR_LPCR] & LPCR_P7_PECE0)) { diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 9164dc2e0f..14bec2490f 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -1693,28 +1693,28 @@ void ppc_cpu_do_interrupt(CPUState *cs) static int p7_next_unmasked_interrupt(CPUPPCState *env) { - bool async_deliver; + PowerPCCPU *cpu = env_archcpu(env); + CPUState *cs = CPU(cpu); + /* Ignore MSR[EE] when coming out of some power management states */ + bool msr_ee = FIELD_EX64(env->msr, MSR, EE) || env->resume_as_sreset; assert((env->pending_interrupts & P7_UNUSED_INTERRUPTS) == 0); + if (cs->halted) { + /* LPCR[PECE] controls which interrupts can exit power-saving mode */ + return p7_interrupt_powersave(env); + } + /* Machine check exception */ if (env->pending_interrupts & PPC_INTERRUPT_MCK) { return PPC_INTERRUPT_MCK; } - /* - * For interrupts that gate on MSR:EE, we need to do something a - * bit more subtle, as we need to let them through even when EE is - * clear when coming out of some power management states (in order - * for them to become a 0x100). - */ - async_deliver = FIELD_EX64(env->msr, MSR, EE) || env->resume_as_sreset; - /* Hypervisor decrementer exception */ if (env->pending_interrupts & PPC_INTERRUPT_HDECR) { /* LPCR will be clear when not supported so this will work */ bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE); - if ((async_deliver || !FIELD_EX64_HV(env->msr)) && hdice) { + if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hdice) { /* HDEC clears on delivery */ return PPC_INTERRUPT_HDECR; } @@ -1725,13 +1725,13 @@ static int p7_next_unmasked_interrupt(CPUPPCState *env) bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); /* HEIC blocks delivery to the hypervisor */ - if ((async_deliver && !(heic && FIELD_EX64_HV(env->msr) && + if ((msr_ee && !(heic && FIELD_EX64_HV(env->msr) && !FIELD_EX64(env->msr, MSR, PR))) || (env->has_hv_mode && !FIELD_EX64_HV(env->msr) && !lpes0)) { return PPC_INTERRUPT_EXT; } } - if (async_deliver != 0) { + if (msr_ee != 0) { /* Decrementer exception */ if (env->pending_interrupts & PPC_INTERRUPT_DECR) { return PPC_INTERRUPT_DECR; diff --git a/target/ppc/internal.h b/target/ppc/internal.h index 9069874adb..25827ebf6f 100644 --- a/target/ppc/internal.h +++ b/target/ppc/internal.h @@ -309,6 +309,7 @@ static inline int ger_pack_masks(int pmsk, int ymsk, int xmsk) #if defined(TARGET_PPC64) int p9_interrupt_powersave(CPUPPCState *env); int p8_interrupt_powersave(CPUPPCState *env); +int p7_interrupt_powersave(CPUPPCState *env); #endif #endif /* PPC_INTERNAL_H */ From 6a8e8188c3c99e987e3d5b9df614a68a5d4bd1e0 Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Tue, 11 Oct 2022 17:48:26 -0300 Subject: [PATCH 380/705] target/ppc: remove ppc_store_lpcr from CONFIG_USER_ONLY builds Writes to LPCR are hypervisor privileged. Signed-off-by: Matheus Ferst Reviewed-by: Fabiano Rosas Message-Id: <20221011204829.1641124-27-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/cpu.c | 2 ++ target/ppc/cpu.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/target/ppc/cpu.c b/target/ppc/cpu.c index 0ebac04bc4..e95b4c5ee1 100644 --- a/target/ppc/cpu.c +++ b/target/ppc/cpu.c @@ -73,6 +73,7 @@ void ppc_store_msr(CPUPPCState *env, target_ulong value) hreg_store_msr(env, value, 0); } +#if !defined(CONFIG_USER_ONLY) void ppc_store_lpcr(PowerPCCPU *cpu, target_ulong val) { PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); @@ -82,6 +83,7 @@ void ppc_store_lpcr(PowerPCCPU *cpu, target_ulong val) /* The gtse bit affects hflags */ hreg_compute_hflags(env); } +#endif static inline void fpscr_set_rounding_mode(CPUPPCState *env) { diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 2433756973..ad758b00e5 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1370,9 +1370,9 @@ void ppc_translate_init(void); #if !defined(CONFIG_USER_ONLY) void ppc_store_sdr1(CPUPPCState *env, target_ulong value); +void ppc_store_lpcr(PowerPCCPU *cpu, target_ulong val); #endif /* !defined(CONFIG_USER_ONLY) */ void ppc_store_msr(CPUPPCState *env, target_ulong value); -void ppc_store_lpcr(PowerPCCPU *cpu, target_ulong val); void ppc_cpu_list(void); From 2fdedcbc69564f52a1c33bedfa291707e998a132 Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Fri, 21 Oct 2022 11:21:54 -0300 Subject: [PATCH 381/705] target/ppc: introduce ppc_maybe_interrupt This new method will check if any pending interrupt was unmasked and then call cpu_interrupt/cpu_reset_interrupt accordingly. Code that raises/lowers or masks/unmasks interrupts should call this method to keep CPU_INTERRUPT_HARD coherent with env->pending_interrupts. Signed-off-by: Matheus Ferst Reviewed-by: Daniel Henrique Barboza Message-Id: <20221021142156.4134411-2-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/pnv_core.c | 1 + hw/ppc/ppc.c | 7 +------ hw/ppc/spapr_hcall.c | 6 ++++++ hw/ppc/spapr_rtas.c | 2 +- target/ppc/cpu.c | 2 ++ target/ppc/cpu.h | 1 + target/ppc/excp_helper.c | 42 ++++++++++++++++++++++++++++++++++++++++ target/ppc/helper.h | 1 + target/ppc/helper_regs.c | 2 ++ target/ppc/translate.c | 11 ++++++++++- 10 files changed, 67 insertions(+), 8 deletions(-) diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index 19e8eb885f..9ee79192dd 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -58,6 +58,7 @@ static void pnv_core_cpu_reset(PnvCore *pc, PowerPCCPU *cpu) env->msr |= MSR_HVB; /* Hypervisor mode */ env->spr[SPR_HRMOR] = pc->hrmor; hreg_compute_hflags(env); + ppc_maybe_interrupt(env); pcc->intc_reset(pc->chip, cpu); } diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c index 77e611e81c..dc86c1c7db 100644 --- a/hw/ppc/ppc.c +++ b/hw/ppc/ppc.c @@ -42,7 +42,6 @@ static void cpu_ppc_tb_start (CPUPPCState *env); void ppc_set_irq(PowerPCCPU *cpu, int irq, int level) { - CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; unsigned int old_pending; bool locked = false; @@ -57,19 +56,15 @@ void ppc_set_irq(PowerPCCPU *cpu, int irq, int level) if (level) { env->pending_interrupts |= irq; - cpu_interrupt(cs, CPU_INTERRUPT_HARD); } else { env->pending_interrupts &= ~irq; - if (env->pending_interrupts == 0) { - cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); - } } if (old_pending != env->pending_interrupts) { + ppc_maybe_interrupt(env); kvmppc_set_interrupt(cpu, irq, level); } - trace_ppc_irq_set_exit(env, irq, level, env->pending_interrupts, CPU(cpu)->interrupt_request); diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 891206e893..925ff523cc 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -490,6 +490,7 @@ static target_ulong h_cede(PowerPCCPU *cpu, SpaprMachineState *spapr, env->msr |= (1ULL << MSR_EE); hreg_compute_hflags(env); + ppc_maybe_interrupt(env); if (spapr_cpu->prod) { spapr_cpu->prod = false; @@ -500,6 +501,7 @@ static target_ulong h_cede(PowerPCCPU *cpu, SpaprMachineState *spapr, cs->halted = 1; cs->exception_index = EXCP_HLT; cs->exit_request = 1; + ppc_maybe_interrupt(env); } return H_SUCCESS; @@ -521,6 +523,7 @@ static target_ulong h_confer_self(PowerPCCPU *cpu) cs->halted = 1; cs->exception_index = EXCP_HALTED; cs->exit_request = 1; + ppc_maybe_interrupt(&cpu->env); return H_SUCCESS; } @@ -633,6 +636,7 @@ static target_ulong h_prod(PowerPCCPU *cpu, SpaprMachineState *spapr, spapr_cpu = spapr_cpu_state(tcpu); spapr_cpu->prod = true; cs->halted = 0; + ppc_maybe_interrupt(&cpu->env); qemu_cpu_kick(cs); return H_SUCCESS; @@ -1669,6 +1673,7 @@ static target_ulong h_enter_nested(PowerPCCPU *cpu, spapr_cpu->in_nested = true; hreg_compute_hflags(env); + ppc_maybe_interrupt(env); tlb_flush(cs); env->reserve_addr = -1; /* Reset the reservation */ @@ -1810,6 +1815,7 @@ out_restore_l1: spapr_cpu->in_nested = false; hreg_compute_hflags(env); + ppc_maybe_interrupt(env); tlb_flush(cs); env->reserve_addr = -1; /* Reset the reservation */ diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c index d58b65e88f..3f664ea02c 100644 --- a/hw/ppc/spapr_rtas.c +++ b/hw/ppc/spapr_rtas.c @@ -214,9 +214,9 @@ static void rtas_stop_self(PowerPCCPU *cpu, SpaprMachineState *spapr, * guest. * For the same reason, set PSSCR_EC. */ - ppc_store_lpcr(cpu, env->spr[SPR_LPCR] & ~pcc->lpcr_pm); env->spr[SPR_PSSCR] |= PSSCR_EC; cs->halted = 1; + ppc_store_lpcr(cpu, env->spr[SPR_LPCR] & ~pcc->lpcr_pm); kvmppc_set_reg_ppc_online(cpu, 0); qemu_cpu_kick(cs); } diff --git a/target/ppc/cpu.c b/target/ppc/cpu.c index e95b4c5ee1..1a97b41c6b 100644 --- a/target/ppc/cpu.c +++ b/target/ppc/cpu.c @@ -82,6 +82,8 @@ void ppc_store_lpcr(PowerPCCPU *cpu, target_ulong val) env->spr[SPR_LPCR] = val & pcc->lpcr_mask; /* The gtse bit affects hflags */ hreg_compute_hflags(env); + + ppc_maybe_interrupt(env); } #endif diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index ad758b00e5..cc2d0305ff 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1358,6 +1358,7 @@ int ppc64_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs, int ppc32_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs, int cpuid, DumpState *s); #ifndef CONFIG_USER_ONLY +void ppc_maybe_interrupt(CPUPPCState *env); void ppc_cpu_do_interrupt(CPUState *cpu); bool ppc_cpu_exec_interrupt(CPUState *cpu, int int_req); void ppc_cpu_do_system_reset(CPUState *cs); diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 14bec2490f..07480079f7 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -390,6 +390,7 @@ static void powerpc_set_excp_state(PowerPCCPU *cpu, target_ulong vector, env->nip = vector; env->msr = msr; hreg_compute_hflags(env); + ppc_maybe_interrupt(env); powerpc_reset_excp_state(cpu); @@ -2044,6 +2045,40 @@ static int ppc_next_unmasked_interrupt(CPUPPCState *env) } } +/* + * Sets CPU_INTERRUPT_HARD if there is at least one unmasked interrupt to be + * delivered and clears CPU_INTERRUPT_HARD otherwise. + * + * This method is called by ppc_set_interrupt when an interrupt is raised or + * lowered, and should also be called whenever an interrupt masking condition + * is changed, e.g.: + * - When relevant bits of MSR are altered, like EE, HV, PR, etc.; + * - When relevant bits of LPCR are altered, like PECE, HDICE, HVICE, etc.; + * - When PSSCR[EC] or env->resume_as_sreset are changed; + * - When cs->halted is changed and the CPU has a different interrupt masking + * logic in power-saving mode (e.g., POWER7/8/9/10); + */ +void ppc_maybe_interrupt(CPUPPCState *env) +{ + CPUState *cs = env_cpu(env); + bool locked = false; + + if (!qemu_mutex_iothread_locked()) { + locked = true; + qemu_mutex_lock_iothread(); + } + + if (ppc_next_unmasked_interrupt(env)) { + cpu_interrupt(cs, CPU_INTERRUPT_HARD); + } else { + cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); + } + + if (locked) { + qemu_mutex_unlock_iothread(); + } +} + #if defined(TARGET_PPC64) static void p7_deliver_interrupt(CPUPPCState *env, int interrupt) { @@ -2479,6 +2514,11 @@ void helper_store_msr(CPUPPCState *env, target_ulong val) } } +void helper_ppc_maybe_interrupt(CPUPPCState *env) +{ + ppc_maybe_interrupt(env); +} + #if defined(TARGET_PPC64) void helper_scv(CPUPPCState *env, uint32_t lev) { @@ -2499,6 +2539,8 @@ void helper_pminsn(CPUPPCState *env, powerpc_pm_insn_t insn) /* Condition for waking up at 0x100 */ env->resume_as_sreset = (insn != PPC_PM_STOP) || (env->spr[SPR_PSSCR] & PSSCR_EC); + + ppc_maybe_interrupt(env); } #endif /* defined(TARGET_PPC64) */ diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 8344fe39c6..25533b8f33 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -10,6 +10,7 @@ DEF_HELPER_4(HASHSTP, void, env, tl, tl, tl) DEF_HELPER_4(HASHCHKP, void, env, tl, tl, tl) #if !defined(CONFIG_USER_ONLY) DEF_HELPER_2(store_msr, void, env, tl) +DEF_HELPER_1(ppc_maybe_interrupt, void, env) DEF_HELPER_1(rfi, void, env) DEF_HELPER_1(40x_rfci, void, env) DEF_HELPER_1(rfci, void, env) diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c index 12235ea2e9..2e85e124ab 100644 --- a/target/ppc/helper_regs.c +++ b/target/ppc/helper_regs.c @@ -260,6 +260,8 @@ int hreg_store_msr(CPUPPCState *env, target_ulong value, int alter_hv) env->msr = value; hreg_compute_hflags(env); #if !defined(CONFIG_USER_ONLY) + ppc_maybe_interrupt(env); + if (unlikely(FIELD_EX64(env->msr, MSR, POW))) { if (!env->pending_interrupts && (*env->check_pow)(env)) { cs->halted = 1; diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 58fbc15954..29e4b728e2 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -305,6 +305,14 @@ static void gen_icount_io_start(DisasContext *ctx) } } +#if !defined(CONFIG_USER_ONLY) +static void gen_ppc_maybe_interrupt(DisasContext *ctx) +{ + gen_icount_io_start(ctx); + gen_helper_ppc_maybe_interrupt(cpu_env); +} +#endif + /* * Tells the caller what is the appropriate exception to generate and prepares * SPR registers for this exception. @@ -6161,7 +6169,6 @@ static void gen_tlbilx_booke206(DisasContext *ctx) #endif /* defined(CONFIG_USER_ONLY) */ } - /* wrtee */ static void gen_wrtee(DisasContext *ctx) { @@ -6175,6 +6182,7 @@ static void gen_wrtee(DisasContext *ctx) tcg_gen_andi_tl(t0, cpu_gpr[rD(ctx->opcode)], (1 << MSR_EE)); tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE)); tcg_gen_or_tl(cpu_msr, cpu_msr, t0); + gen_ppc_maybe_interrupt(ctx); tcg_temp_free(t0); /* * Stop translation to have a chance to raise an exception if we @@ -6193,6 +6201,7 @@ static void gen_wrteei(DisasContext *ctx) CHK_SV(ctx); if (ctx->opcode & 0x00008000) { tcg_gen_ori_tl(cpu_msr, cpu_msr, (1 << MSR_EE)); + gen_ppc_maybe_interrupt(ctx); /* Stop translation to have a chance to raise an exception */ ctx->base.is_jmp = DISAS_EXIT_UPDATE; } else { From ab9cfa04523e0312c741e16ca54c5fa4e1eee9e2 Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Fri, 21 Oct 2022 11:21:55 -0300 Subject: [PATCH 382/705] target/ppc: unify cpu->has_work based on cs->interrupt_request Now that cs->interrupt_request indicates if there is any unmasked interrupt, checking if the CPU has work to do can be simplified to a single check that works for all CPU models. Reviewed-by: Fabiano Rosas Signed-off-by: Matheus Ferst Message-Id: <20221021142156.4134411-3-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/cpu_init.c | 94 +------------------------------------------ 1 file changed, 1 insertion(+), 93 deletions(-) diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index 5238229cd6..b14905547c 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -5984,27 +5984,10 @@ int p7_interrupt_powersave(CPUPPCState *env) return 0; } -static bool cpu_has_work_POWER7(CPUState *cs) -{ - PowerPCCPU *cpu = POWERPC_CPU(cs); - CPUPPCState *env = &cpu->env; - - if (cs->halted) { - if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) { - return false; - } - return p7_interrupt_powersave(env) != 0; - } else { - return FIELD_EX64(env->msr, MSR, EE) && - (cs->interrupt_request & CPU_INTERRUPT_HARD); - } -} - POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - CPUClass *cc = CPU_CLASS(oc); dc->fw_name = "PowerPC,POWER7"; dc->desc = "POWER7"; @@ -6013,7 +5996,6 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data) pcc->pcr_supported = PCR_COMPAT_2_06 | PCR_COMPAT_2_05; pcc->init_proc = init_proc_POWER7; pcc->check_pow = check_pow_nocheck; - cc->has_work = cpu_has_work_POWER7; pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | @@ -6170,27 +6152,10 @@ int p8_interrupt_powersave(CPUPPCState *env) return 0; } -static bool cpu_has_work_POWER8(CPUState *cs) -{ - PowerPCCPU *cpu = POWERPC_CPU(cs); - CPUPPCState *env = &cpu->env; - - if (cs->halted) { - if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) { - return false; - } - return p8_interrupt_powersave(env) != 0; - } else { - return FIELD_EX64(env->msr, MSR, EE) && - (cs->interrupt_request & CPU_INTERRUPT_HARD); - } -} - POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - CPUClass *cc = CPU_CLASS(oc); dc->fw_name = "PowerPC,POWER8"; dc->desc = "POWER8"; @@ -6199,7 +6164,6 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data) pcc->pcr_supported = PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_COMPAT_2_05; pcc->init_proc = init_proc_POWER8; pcc->check_pow = check_pow_nocheck; - cc->has_work = cpu_has_work_POWER8; pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | @@ -6407,35 +6371,10 @@ int p9_interrupt_powersave(CPUPPCState *env) return 0; } -static bool cpu_has_work_POWER9(CPUState *cs) -{ - PowerPCCPU *cpu = POWERPC_CPU(cs); - CPUPPCState *env = &cpu->env; - - if (cs->halted) { - uint64_t psscr = env->spr[SPR_PSSCR]; - - if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) { - return false; - } - - /* If EC is clear, just return true on any pending interrupt */ - if (!(psscr & PSSCR_EC)) { - return true; - } - - return p9_interrupt_powersave(env) != 0; - } else { - return FIELD_EX64(env->msr, MSR, EE) && - (cs->interrupt_request & CPU_INTERRUPT_HARD); - } -} - POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - CPUClass *cc = CPU_CLASS(oc); dc->fw_name = "PowerPC,POWER9"; dc->desc = "POWER9"; @@ -6445,7 +6384,6 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data) PCR_COMPAT_2_05; pcc->init_proc = init_proc_POWER9; pcc->check_pow = check_pow_nocheck; - cc->has_work = cpu_has_work_POWER9; pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | @@ -6604,35 +6542,10 @@ static bool ppc_pvr_match_power10(PowerPCCPUClass *pcc, uint32_t pvr, bool best) return false; } -static bool cpu_has_work_POWER10(CPUState *cs) -{ - PowerPCCPU *cpu = POWERPC_CPU(cs); - CPUPPCState *env = &cpu->env; - - if (cs->halted) { - uint64_t psscr = env->spr[SPR_PSSCR]; - - if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) { - return false; - } - - /* If EC is clear, just return true on any pending interrupt */ - if (!(psscr & PSSCR_EC)) { - return true; - } - - return p9_interrupt_powersave(env) != 0; - } else { - return FIELD_EX64(env->msr, MSR, EE) && - (cs->interrupt_request & CPU_INTERRUPT_HARD); - } -} - POWERPC_FAMILY(POWER10)(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - CPUClass *cc = CPU_CLASS(oc); dc->fw_name = "PowerPC,POWER10"; dc->desc = "POWER10"; @@ -6643,7 +6556,6 @@ POWERPC_FAMILY(POWER10)(ObjectClass *oc, void *data) PCR_COMPAT_2_06 | PCR_COMPAT_2_05; pcc->init_proc = init_proc_POWER10; pcc->check_pow = check_pow_nocheck; - cc->has_work = cpu_has_work_POWER10; pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | @@ -7216,11 +7128,7 @@ static void ppc_restore_state_to_opc(CPUState *cs, static bool ppc_cpu_has_work(CPUState *cs) { - PowerPCCPU *cpu = POWERPC_CPU(cs); - CPUPPCState *env = &cpu->env; - - return FIELD_EX64(env->msr, MSR, EE) && - (cs->interrupt_request & CPU_INTERRUPT_HARD); + return cs->interrupt_request & CPU_INTERRUPT_HARD; } static void ppc_cpu_reset(DeviceState *dev) From 9c713713dac70fe7eaa9b403234a71024a729eb4 Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Fri, 21 Oct 2022 11:21:56 -0300 Subject: [PATCH 383/705] target/ppc: move the p*_interrupt_powersave methods to excp_helper.c Move the methods to excp_helper.c and make them static. Reviewed-by: Fabiano Rosas Signed-off-by: Matheus Ferst Message-Id: <20221021142156.4134411-4-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/cpu_init.c | 102 --------------------------------------- target/ppc/excp_helper.c | 102 +++++++++++++++++++++++++++++++++++++++ target/ppc/internal.h | 6 --- 3 files changed, 102 insertions(+), 108 deletions(-) diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index b14905547c..32e94153d1 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -5960,30 +5960,6 @@ static bool ppc_pvr_match_power7(PowerPCCPUClass *pcc, uint32_t pvr, bool best) return true; } -int p7_interrupt_powersave(CPUPPCState *env) -{ - if ((env->pending_interrupts & PPC_INTERRUPT_EXT) && - (env->spr[SPR_LPCR] & LPCR_P7_PECE0)) { - return PPC_INTERRUPT_EXT; - } - if ((env->pending_interrupts & PPC_INTERRUPT_DECR) && - (env->spr[SPR_LPCR] & LPCR_P7_PECE1)) { - return PPC_INTERRUPT_DECR; - } - if ((env->pending_interrupts & PPC_INTERRUPT_MCK) && - (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) { - return PPC_INTERRUPT_MCK; - } - if ((env->pending_interrupts & PPC_INTERRUPT_HMI) && - (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) { - return PPC_INTERRUPT_HMI; - } - if (env->pending_interrupts & PPC_INTERRUPT_RESET) { - return PPC_INTERRUPT_RESET; - } - return 0; -} - POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); @@ -6120,38 +6096,6 @@ static bool ppc_pvr_match_power8(PowerPCCPUClass *pcc, uint32_t pvr, bool best) return true; } -int p8_interrupt_powersave(CPUPPCState *env) -{ - if ((env->pending_interrupts & PPC_INTERRUPT_EXT) && - (env->spr[SPR_LPCR] & LPCR_P8_PECE2)) { - return PPC_INTERRUPT_EXT; - } - if ((env->pending_interrupts & PPC_INTERRUPT_DECR) && - (env->spr[SPR_LPCR] & LPCR_P8_PECE3)) { - return PPC_INTERRUPT_DECR; - } - if ((env->pending_interrupts & PPC_INTERRUPT_MCK) && - (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) { - return PPC_INTERRUPT_MCK; - } - if ((env->pending_interrupts & PPC_INTERRUPT_HMI) && - (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) { - return PPC_INTERRUPT_HMI; - } - if ((env->pending_interrupts & PPC_INTERRUPT_DOORBELL) && - (env->spr[SPR_LPCR] & LPCR_P8_PECE0)) { - return PPC_INTERRUPT_DOORBELL; - } - if ((env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) && - (env->spr[SPR_LPCR] & LPCR_P8_PECE1)) { - return PPC_INTERRUPT_HDOORBELL; - } - if (env->pending_interrupts & PPC_INTERRUPT_RESET) { - return PPC_INTERRUPT_RESET; - } - return 0; -} - POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); @@ -6325,52 +6269,6 @@ static bool ppc_pvr_match_power9(PowerPCCPUClass *pcc, uint32_t pvr, bool best) return false; } -int p9_interrupt_powersave(CPUPPCState *env) -{ - /* External Exception */ - if ((env->pending_interrupts & PPC_INTERRUPT_EXT) && - (env->spr[SPR_LPCR] & LPCR_EEE)) { - bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); - if (!heic || !FIELD_EX64_HV(env->msr) || - FIELD_EX64(env->msr, MSR, PR)) { - return PPC_INTERRUPT_EXT; - } - } - /* Decrementer Exception */ - if ((env->pending_interrupts & PPC_INTERRUPT_DECR) && - (env->spr[SPR_LPCR] & LPCR_DEE)) { - return PPC_INTERRUPT_DECR; - } - /* Machine Check or Hypervisor Maintenance Exception */ - if (env->spr[SPR_LPCR] & LPCR_OEE) { - if (env->pending_interrupts & PPC_INTERRUPT_MCK) { - return PPC_INTERRUPT_MCK; - } - if (env->pending_interrupts & PPC_INTERRUPT_HMI) { - return PPC_INTERRUPT_HMI; - } - } - /* Privileged Doorbell Exception */ - if ((env->pending_interrupts & PPC_INTERRUPT_DOORBELL) && - (env->spr[SPR_LPCR] & LPCR_PDEE)) { - return PPC_INTERRUPT_DOORBELL; - } - /* Hypervisor Doorbell Exception */ - if ((env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) && - (env->spr[SPR_LPCR] & LPCR_HDEE)) { - return PPC_INTERRUPT_HDOORBELL; - } - /* Hypervisor virtualization exception */ - if ((env->pending_interrupts & PPC_INTERRUPT_HVIRT) && - (env->spr[SPR_LPCR] & LPCR_HVEE)) { - return PPC_INTERRUPT_HVIRT; - } - if (env->pending_interrupts & PPC_INTERRUPT_RESET) { - return PPC_INTERRUPT_RESET; - } - return 0; -} - POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 07480079f7..09a81561d4 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -1692,6 +1692,30 @@ void ppc_cpu_do_interrupt(CPUState *cs) PPC_INTERRUPT_PIT | PPC_INTERRUPT_DOORBELL | PPC_INTERRUPT_HDOORBELL | \ PPC_INTERRUPT_THERM | PPC_INTERRUPT_EBB) +static int p7_interrupt_powersave(CPUPPCState *env) +{ + if ((env->pending_interrupts & PPC_INTERRUPT_EXT) && + (env->spr[SPR_LPCR] & LPCR_P7_PECE0)) { + return PPC_INTERRUPT_EXT; + } + if ((env->pending_interrupts & PPC_INTERRUPT_DECR) && + (env->spr[SPR_LPCR] & LPCR_P7_PECE1)) { + return PPC_INTERRUPT_DECR; + } + if ((env->pending_interrupts & PPC_INTERRUPT_MCK) && + (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) { + return PPC_INTERRUPT_MCK; + } + if ((env->pending_interrupts & PPC_INTERRUPT_HMI) && + (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) { + return PPC_INTERRUPT_HMI; + } + if (env->pending_interrupts & PPC_INTERRUPT_RESET) { + return PPC_INTERRUPT_RESET; + } + return 0; +} + static int p7_next_unmasked_interrupt(CPUPPCState *env) { PowerPCCPU *cpu = env_archcpu(env); @@ -1750,6 +1774,38 @@ static int p7_next_unmasked_interrupt(CPUPPCState *env) PPC_INTERRUPT_CEXT | PPC_INTERRUPT_WDT | PPC_INTERRUPT_CDOORBELL | \ PPC_INTERRUPT_FIT | PPC_INTERRUPT_PIT | PPC_INTERRUPT_THERM) +static int p8_interrupt_powersave(CPUPPCState *env) +{ + if ((env->pending_interrupts & PPC_INTERRUPT_EXT) && + (env->spr[SPR_LPCR] & LPCR_P8_PECE2)) { + return PPC_INTERRUPT_EXT; + } + if ((env->pending_interrupts & PPC_INTERRUPT_DECR) && + (env->spr[SPR_LPCR] & LPCR_P8_PECE3)) { + return PPC_INTERRUPT_DECR; + } + if ((env->pending_interrupts & PPC_INTERRUPT_MCK) && + (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) { + return PPC_INTERRUPT_MCK; + } + if ((env->pending_interrupts & PPC_INTERRUPT_HMI) && + (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) { + return PPC_INTERRUPT_HMI; + } + if ((env->pending_interrupts & PPC_INTERRUPT_DOORBELL) && + (env->spr[SPR_LPCR] & LPCR_P8_PECE0)) { + return PPC_INTERRUPT_DOORBELL; + } + if ((env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) && + (env->spr[SPR_LPCR] & LPCR_P8_PECE1)) { + return PPC_INTERRUPT_HDOORBELL; + } + if (env->pending_interrupts & PPC_INTERRUPT_RESET) { + return PPC_INTERRUPT_RESET; + } + return 0; +} + static int p8_next_unmasked_interrupt(CPUPPCState *env) { PowerPCCPU *cpu = env_archcpu(env); @@ -1825,6 +1881,52 @@ static int p8_next_unmasked_interrupt(CPUPPCState *env) PPC_INTERRUPT_WDT | PPC_INTERRUPT_CDOORBELL | PPC_INTERRUPT_FIT | \ PPC_INTERRUPT_PIT | PPC_INTERRUPT_THERM) +static int p9_interrupt_powersave(CPUPPCState *env) +{ + /* External Exception */ + if ((env->pending_interrupts & PPC_INTERRUPT_EXT) && + (env->spr[SPR_LPCR] & LPCR_EEE)) { + bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); + if (!heic || !FIELD_EX64_HV(env->msr) || + FIELD_EX64(env->msr, MSR, PR)) { + return PPC_INTERRUPT_EXT; + } + } + /* Decrementer Exception */ + if ((env->pending_interrupts & PPC_INTERRUPT_DECR) && + (env->spr[SPR_LPCR] & LPCR_DEE)) { + return PPC_INTERRUPT_DECR; + } + /* Machine Check or Hypervisor Maintenance Exception */ + if (env->spr[SPR_LPCR] & LPCR_OEE) { + if (env->pending_interrupts & PPC_INTERRUPT_MCK) { + return PPC_INTERRUPT_MCK; + } + if (env->pending_interrupts & PPC_INTERRUPT_HMI) { + return PPC_INTERRUPT_HMI; + } + } + /* Privileged Doorbell Exception */ + if ((env->pending_interrupts & PPC_INTERRUPT_DOORBELL) && + (env->spr[SPR_LPCR] & LPCR_PDEE)) { + return PPC_INTERRUPT_DOORBELL; + } + /* Hypervisor Doorbell Exception */ + if ((env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) && + (env->spr[SPR_LPCR] & LPCR_HDEE)) { + return PPC_INTERRUPT_HDOORBELL; + } + /* Hypervisor virtualization exception */ + if ((env->pending_interrupts & PPC_INTERRUPT_HVIRT) && + (env->spr[SPR_LPCR] & LPCR_HVEE)) { + return PPC_INTERRUPT_HVIRT; + } + if (env->pending_interrupts & PPC_INTERRUPT_RESET) { + return PPC_INTERRUPT_RESET; + } + return 0; +} + static int p9_next_unmasked_interrupt(CPUPPCState *env) { PowerPCCPU *cpu = env_archcpu(env); diff --git a/target/ppc/internal.h b/target/ppc/internal.h index 25827ebf6f..337a362205 100644 --- a/target/ppc/internal.h +++ b/target/ppc/internal.h @@ -306,10 +306,4 @@ static inline int ger_pack_masks(int pmsk, int ymsk, int xmsk) return msk; } -#if defined(TARGET_PPC64) -int p9_interrupt_powersave(CPUPPCState *env); -int p8_interrupt_powersave(CPUPPCState *env); -int p7_interrupt_powersave(CPUPPCState *env); -#endif - #endif /* PPC_INTERNAL_H */ From 2a48dd7cbd456ac2e27b3cf66cfb7e2e1886dbf4 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Wed, 19 Oct 2022 18:02:52 +0200 Subject: [PATCH 384/705] ppc440_uc.c: Move DDR2 SDRAM controller model to ppc4xx_sdram.c In order to move PPC4xx SDRAM controller models together move out the DDR2 controller model from ppc440_uc.c into a new ppc4xx_sdram.c file. Signed-off-by: BALATON Zoltan Reviewed-by: Daniel Henrique Barboza Message-Id: <2f2900f93e997480e54b7bf9c32bb482a0fb1022.1666194485.git.balaton@eik.bme.hu> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/meson.build | 3 +- hw/ppc/ppc440_uc.c | 332 ---------------------------------------- hw/ppc/ppc4xx_sdram.c | 348 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 350 insertions(+), 333 deletions(-) create mode 100644 hw/ppc/ppc4xx_sdram.c diff --git a/hw/ppc/meson.build b/hw/ppc/meson.build index 32babc9b48..c927337da0 100644 --- a/hw/ppc/meson.build +++ b/hw/ppc/meson.build @@ -59,8 +59,9 @@ ppc_ss.add(when: 'CONFIG_PPC440', if_true: files( 'ppc440_bamboo.c', 'ppc440_pcix.c', 'ppc440_uc.c')) ppc_ss.add(when: 'CONFIG_PPC4XX', if_true: files( + 'ppc4xx_devs.c', 'ppc4xx_pci.c', - 'ppc4xx_devs.c')) + 'ppc4xx_sdram.c')) ppc_ss.add(when: 'CONFIG_SAM460EX', if_true: files('sam460ex.c')) # PReP ppc_ss.add(when: 'CONFIG_PREP', if_true: files('prep.c')) diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c index 5fbf44009e..651263926e 100644 --- a/hw/ppc/ppc440_uc.c +++ b/hw/ppc/ppc440_uc.c @@ -10,21 +10,14 @@ #include "qemu/osdep.h" #include "qemu/units.h" -#include "qemu/error-report.h" #include "qapi/error.h" #include "qemu/log.h" -#include "qemu/module.h" #include "hw/irq.h" -#include "exec/memory.h" -#include "cpu.h" #include "hw/ppc/ppc4xx.h" #include "hw/qdev-properties.h" #include "hw/pci/pci.h" -#include "sysemu/block-backend.h" #include "sysemu/reset.h" #include "ppc440.h" -#include "qom/object.h" -#include "trace.h" /*****************************************************************************/ /* L2 Cache as SRAM */ @@ -478,331 +471,6 @@ void ppc4xx_sdr_init(CPUPPCState *env) sdr, &dcr_read_sdr, &dcr_write_sdr); } -/*****************************************************************************/ -/* SDRAM controller */ -enum { - SDRAM0_CFGADDR = 0x10, - SDRAM0_CFGDATA, - SDRAM_R0BAS = 0x40, - SDRAM_R1BAS, - SDRAM_R2BAS, - SDRAM_R3BAS, - SDRAM_CONF1HB = 0x45, - SDRAM_PLBADDULL = 0x4a, - SDRAM_CONF1LL = 0x4b, - SDRAM_CONFPATHB = 0x4f, - SDRAM_PLBADDUHB = 0x50, -}; - -static uint32_t sdram_ddr2_bcr(hwaddr ram_base, hwaddr ram_size) -{ - uint32_t bcr; - - switch (ram_size) { - case 8 * MiB: - bcr = 0xffc0; - break; - case 16 * MiB: - bcr = 0xff80; - break; - case 32 * MiB: - bcr = 0xff00; - break; - case 64 * MiB: - bcr = 0xfe00; - break; - case 128 * MiB: - bcr = 0xfc00; - break; - case 256 * MiB: - bcr = 0xf800; - break; - case 512 * MiB: - bcr = 0xf000; - break; - case 1 * GiB: - bcr = 0xe000; - break; - case 2 * GiB: - bcr = 0xc000; - break; - case 4 * GiB: - bcr = 0x8000; - break; - default: - error_report("invalid RAM size " TARGET_FMT_plx, ram_size); - return 0; - } - bcr |= ram_base >> 2 & 0xffe00000; - bcr |= 1; - - return bcr; -} - -static inline hwaddr sdram_ddr2_base(uint32_t bcr) -{ - return (bcr & 0xffe00000) << 2; -} - -static uint64_t sdram_ddr2_size(uint32_t bcr) -{ - uint64_t size; - int sh; - - sh = 1024 - ((bcr >> 6) & 0x3ff); - size = 8 * MiB * sh; - - return size; -} - -static void sdram_bank_map(Ppc4xxSdramBank *bank) -{ - memory_region_init(&bank->container, NULL, "sdram-container", bank->size); - memory_region_add_subregion(&bank->container, 0, &bank->ram); - memory_region_add_subregion(get_system_memory(), bank->base, - &bank->container); -} - -static void sdram_bank_unmap(Ppc4xxSdramBank *bank) -{ - memory_region_del_subregion(get_system_memory(), &bank->container); - memory_region_del_subregion(&bank->container, &bank->ram); - object_unparent(OBJECT(&bank->container)); -} - -static void sdram_ddr2_set_bcr(Ppc4xxSdramDdr2State *sdram, int i, - uint32_t bcr, int enabled) -{ - if (sdram->bank[i].bcr & 1) { - /* First unmap RAM if enabled */ - trace_ppc4xx_sdram_unmap(sdram_ddr2_base(sdram->bank[i].bcr), - sdram_ddr2_size(sdram->bank[i].bcr)); - sdram_bank_unmap(&sdram->bank[i]); - } - sdram->bank[i].bcr = bcr & 0xffe0ffc1; - if (enabled && (bcr & 1)) { - trace_ppc4xx_sdram_map(sdram_ddr2_base(bcr), sdram_ddr2_size(bcr)); - sdram_bank_map(&sdram->bank[i]); - } -} - -static void sdram_ddr2_map_bcr(Ppc4xxSdramDdr2State *sdram) -{ - int i; - - for (i = 0; i < sdram->nbanks; i++) { - if (sdram->bank[i].size) { - sdram_ddr2_set_bcr(sdram, i, - sdram_ddr2_bcr(sdram->bank[i].base, - sdram->bank[i].size), 1); - } else { - sdram_ddr2_set_bcr(sdram, i, 0, 0); - } - } -} - -static void sdram_ddr2_unmap_bcr(Ppc4xxSdramDdr2State *sdram) -{ - int i; - - for (i = 0; i < sdram->nbanks; i++) { - if (sdram->bank[i].size) { - sdram_ddr2_set_bcr(sdram, i, sdram->bank[i].bcr & ~1, 0); - } - } -} - -static uint32_t sdram_ddr2_dcr_read(void *opaque, int dcrn) -{ - Ppc4xxSdramDdr2State *sdram = opaque; - uint32_t ret = 0; - - switch (dcrn) { - case SDRAM_R0BAS: - case SDRAM_R1BAS: - case SDRAM_R2BAS: - case SDRAM_R3BAS: - if (sdram->bank[dcrn - SDRAM_R0BAS].size) { - ret = sdram_ddr2_bcr(sdram->bank[dcrn - SDRAM_R0BAS].base, - sdram->bank[dcrn - SDRAM_R0BAS].size); - } - break; - case SDRAM_CONF1HB: - case SDRAM_CONF1LL: - case SDRAM_CONFPATHB: - case SDRAM_PLBADDULL: - case SDRAM_PLBADDUHB: - break; - case SDRAM0_CFGADDR: - ret = sdram->addr; - break; - case SDRAM0_CFGDATA: - switch (sdram->addr) { - case 0x14: /* SDRAM_MCSTAT (405EX) */ - case 0x1F: - ret = 0x80000000; - break; - case 0x21: /* SDRAM_MCOPT2 */ - ret = sdram->mcopt2; - break; - case 0x40: /* SDRAM_MB0CF */ - ret = 0x00008001; - break; - case 0x7A: /* SDRAM_DLCR */ - ret = 0x02000000; - break; - case 0xE1: /* SDR0_DDR0 */ - ret = SDR0_DDR0_DDRM_ENCODE(1) | SDR0_DDR0_DDRM_DDR1; - break; - default: - break; - } - break; - default: - break; - } - - return ret; -} - -#define SDRAM_DDR2_MCOPT2_DCEN BIT(27) - -static void sdram_ddr2_dcr_write(void *opaque, int dcrn, uint32_t val) -{ - Ppc4xxSdramDdr2State *sdram = opaque; - - switch (dcrn) { - case SDRAM_R0BAS: - case SDRAM_R1BAS: - case SDRAM_R2BAS: - case SDRAM_R3BAS: - case SDRAM_CONF1HB: - case SDRAM_CONF1LL: - case SDRAM_CONFPATHB: - case SDRAM_PLBADDULL: - case SDRAM_PLBADDUHB: - break; - case SDRAM0_CFGADDR: - sdram->addr = val; - break; - case SDRAM0_CFGDATA: - switch (sdram->addr) { - case 0x00: /* B0CR */ - break; - case 0x21: /* SDRAM_MCOPT2 */ - if (!(sdram->mcopt2 & SDRAM_DDR2_MCOPT2_DCEN) && - (val & SDRAM_DDR2_MCOPT2_DCEN)) { - trace_ppc4xx_sdram_enable("enable"); - /* validate all RAM mappings */ - sdram_ddr2_map_bcr(sdram); - sdram->mcopt2 |= SDRAM_DDR2_MCOPT2_DCEN; - } else if ((sdram->mcopt2 & SDRAM_DDR2_MCOPT2_DCEN) && - !(val & SDRAM_DDR2_MCOPT2_DCEN)) { - trace_ppc4xx_sdram_enable("disable"); - /* invalidate all RAM mappings */ - sdram_ddr2_unmap_bcr(sdram); - sdram->mcopt2 &= ~SDRAM_DDR2_MCOPT2_DCEN; - } - break; - default: - break; - } - break; - default: - break; - } -} - -static void ppc4xx_sdram_ddr2_reset(DeviceState *dev) -{ - Ppc4xxSdramDdr2State *sdram = PPC4xx_SDRAM_DDR2(dev); - - sdram->addr = 0; - sdram->mcopt2 = 0; -} - -static void ppc4xx_sdram_ddr2_realize(DeviceState *dev, Error **errp) -{ - Ppc4xxSdramDdr2State *s = PPC4xx_SDRAM_DDR2(dev); - Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev); - /* - * SoC also has 4 GiB but that causes problem with 32 bit - * builds (4*GiB overflows the 32 bit ram_addr_t). - */ - const ram_addr_t valid_bank_sizes[] = { - 2 * GiB, 1 * GiB, 512 * MiB, 256 * MiB, 128 * MiB, - 64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 0 - }; - - if (s->nbanks < 1 || s->nbanks > 4) { - error_setg(errp, "Invalid number of RAM banks"); - return; - } - if (!s->dram_mr) { - error_setg(errp, "Missing dram memory region"); - return; - } - ppc4xx_sdram_banks(s->dram_mr, s->nbanks, s->bank, valid_bank_sizes); - - ppc4xx_dcr_register(dcr, SDRAM0_CFGADDR, - s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); - ppc4xx_dcr_register(dcr, SDRAM0_CFGDATA, - s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); - - ppc4xx_dcr_register(dcr, SDRAM_R0BAS, - s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); - ppc4xx_dcr_register(dcr, SDRAM_R1BAS, - s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); - ppc4xx_dcr_register(dcr, SDRAM_R2BAS, - s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); - ppc4xx_dcr_register(dcr, SDRAM_R3BAS, - s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); - ppc4xx_dcr_register(dcr, SDRAM_CONF1HB, - s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); - ppc4xx_dcr_register(dcr, SDRAM_PLBADDULL, - s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); - ppc4xx_dcr_register(dcr, SDRAM_CONF1LL, - s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); - ppc4xx_dcr_register(dcr, SDRAM_CONFPATHB, - s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); - ppc4xx_dcr_register(dcr, SDRAM_PLBADDUHB, - s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); -} - -static Property ppc4xx_sdram_ddr2_props[] = { - DEFINE_PROP_LINK("dram", Ppc4xxSdramDdr2State, dram_mr, TYPE_MEMORY_REGION, - MemoryRegion *), - DEFINE_PROP_UINT32("nbanks", Ppc4xxSdramDdr2State, nbanks, 4), - DEFINE_PROP_END_OF_LIST(), -}; - -static void ppc4xx_sdram_ddr2_class_init(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - - dc->realize = ppc4xx_sdram_ddr2_realize; - dc->reset = ppc4xx_sdram_ddr2_reset; - /* Reason: only works as function of a ppc4xx SoC */ - dc->user_creatable = false; - device_class_set_props(dc, ppc4xx_sdram_ddr2_props); -} - -void ppc4xx_sdram_ddr2_enable(Ppc4xxSdramDdr2State *s) -{ - sdram_ddr2_dcr_write(s, SDRAM0_CFGADDR, 0x21); - sdram_ddr2_dcr_write(s, SDRAM0_CFGDATA, 0x08000000); -} - -static const TypeInfo ppc4xx_types[] = { - { - .name = TYPE_PPC4xx_SDRAM_DDR2, - .parent = TYPE_PPC4xx_DCR_DEVICE, - .instance_size = sizeof(Ppc4xxSdramDdr2State), - .class_init = ppc4xx_sdram_ddr2_class_init, - } -}; -DEFINE_TYPES(ppc4xx_types) - /*****************************************************************************/ /* PLB to AHB bridge */ enum { diff --git a/hw/ppc/ppc4xx_sdram.c b/hw/ppc/ppc4xx_sdram.c new file mode 100644 index 0000000000..b49a7ed60a --- /dev/null +++ b/hw/ppc/ppc4xx_sdram.c @@ -0,0 +1,348 @@ +/* + * DDR2 SDRAM controller: + * Copyright (c) 2012 François Revol + * Copyright (c) 2016-2019 BALATON Zoltan + * + * This work is licensed under the GNU GPL license version 2 or later. + */ + +#include "qemu/osdep.h" +#include "qemu/units.h" +#include "qapi/error.h" +#include "exec/address-spaces.h" /* get_system_memory() */ +#include "hw/irq.h" +#include "hw/qdev-properties.h" +#include "hw/ppc/ppc4xx.h" +#include "trace.h" + +/*****************************************************************************/ +/* Shared functions */ + +static void sdram_bank_map(Ppc4xxSdramBank *bank) +{ + memory_region_init(&bank->container, NULL, "sdram-container", bank->size); + memory_region_add_subregion(&bank->container, 0, &bank->ram); + memory_region_add_subregion(get_system_memory(), bank->base, + &bank->container); +} + +static void sdram_bank_unmap(Ppc4xxSdramBank *bank) +{ + memory_region_del_subregion(get_system_memory(), &bank->container); + memory_region_del_subregion(&bank->container, &bank->ram); + object_unparent(OBJECT(&bank->container)); +} + +enum { + SDRAM0_CFGADDR = 0x010, + SDRAM0_CFGDATA = 0x011, +}; + +/*****************************************************************************/ +/* DDR2 SDRAM controller */ +enum { + SDRAM_R0BAS = 0x40, + SDRAM_R1BAS, + SDRAM_R2BAS, + SDRAM_R3BAS, + SDRAM_CONF1HB = 0x45, + SDRAM_PLBADDULL = 0x4a, + SDRAM_CONF1LL = 0x4b, + SDRAM_CONFPATHB = 0x4f, + SDRAM_PLBADDUHB = 0x50, +}; + +static uint32_t sdram_ddr2_bcr(hwaddr ram_base, hwaddr ram_size) +{ + uint32_t bcr; + + switch (ram_size) { + case 8 * MiB: + bcr = 0xffc0; + break; + case 16 * MiB: + bcr = 0xff80; + break; + case 32 * MiB: + bcr = 0xff00; + break; + case 64 * MiB: + bcr = 0xfe00; + break; + case 128 * MiB: + bcr = 0xfc00; + break; + case 256 * MiB: + bcr = 0xf800; + break; + case 512 * MiB: + bcr = 0xf000; + break; + case 1 * GiB: + bcr = 0xe000; + break; + case 2 * GiB: + bcr = 0xc000; + break; + case 4 * GiB: + bcr = 0x8000; + break; + default: + error_report("invalid RAM size " TARGET_FMT_plx, ram_size); + return 0; + } + bcr |= ram_base >> 2 & 0xffe00000; + bcr |= 1; + + return bcr; +} + +static inline hwaddr sdram_ddr2_base(uint32_t bcr) +{ + return (bcr & 0xffe00000) << 2; +} + +static uint64_t sdram_ddr2_size(uint32_t bcr) +{ + uint64_t size; + int sh; + + sh = 1024 - ((bcr >> 6) & 0x3ff); + size = 8 * MiB * sh; + + return size; +} + +static void sdram_ddr2_set_bcr(Ppc4xxSdramDdr2State *sdram, int i, + uint32_t bcr, int enabled) +{ + if (sdram->bank[i].bcr & 1) { + /* First unmap RAM if enabled */ + trace_ppc4xx_sdram_unmap(sdram_ddr2_base(sdram->bank[i].bcr), + sdram_ddr2_size(sdram->bank[i].bcr)); + sdram_bank_unmap(&sdram->bank[i]); + } + sdram->bank[i].bcr = bcr & 0xffe0ffc1; + if (enabled && (bcr & 1)) { + trace_ppc4xx_sdram_map(sdram_ddr2_base(bcr), sdram_ddr2_size(bcr)); + sdram_bank_map(&sdram->bank[i]); + } +} + +static void sdram_ddr2_map_bcr(Ppc4xxSdramDdr2State *sdram) +{ + int i; + + for (i = 0; i < sdram->nbanks; i++) { + if (sdram->bank[i].size) { + sdram_ddr2_set_bcr(sdram, i, + sdram_ddr2_bcr(sdram->bank[i].base, + sdram->bank[i].size), 1); + } else { + sdram_ddr2_set_bcr(sdram, i, 0, 0); + } + } +} + +static void sdram_ddr2_unmap_bcr(Ppc4xxSdramDdr2State *sdram) +{ + int i; + + for (i = 0; i < sdram->nbanks; i++) { + if (sdram->bank[i].size) { + sdram_ddr2_set_bcr(sdram, i, sdram->bank[i].bcr & ~1, 0); + } + } +} + +static uint32_t sdram_ddr2_dcr_read(void *opaque, int dcrn) +{ + Ppc4xxSdramDdr2State *sdram = opaque; + uint32_t ret = 0; + + switch (dcrn) { + case SDRAM_R0BAS: + case SDRAM_R1BAS: + case SDRAM_R2BAS: + case SDRAM_R3BAS: + if (sdram->bank[dcrn - SDRAM_R0BAS].size) { + ret = sdram_ddr2_bcr(sdram->bank[dcrn - SDRAM_R0BAS].base, + sdram->bank[dcrn - SDRAM_R0BAS].size); + } + break; + case SDRAM_CONF1HB: + case SDRAM_CONF1LL: + case SDRAM_CONFPATHB: + case SDRAM_PLBADDULL: + case SDRAM_PLBADDUHB: + break; + case SDRAM0_CFGADDR: + ret = sdram->addr; + break; + case SDRAM0_CFGDATA: + switch (sdram->addr) { + case 0x14: /* SDRAM_MCSTAT (405EX) */ + case 0x1F: + ret = 0x80000000; + break; + case 0x21: /* SDRAM_MCOPT2 */ + ret = sdram->mcopt2; + break; + case 0x40: /* SDRAM_MB0CF */ + ret = 0x00008001; + break; + case 0x7A: /* SDRAM_DLCR */ + ret = 0x02000000; + break; + case 0xE1: /* SDR0_DDR0 */ + ret = SDR0_DDR0_DDRM_ENCODE(1) | SDR0_DDR0_DDRM_DDR1; + break; + default: + break; + } + break; + default: + break; + } + + return ret; +} + +#define SDRAM_DDR2_MCOPT2_DCEN BIT(27) + +static void sdram_ddr2_dcr_write(void *opaque, int dcrn, uint32_t val) +{ + Ppc4xxSdramDdr2State *sdram = opaque; + + switch (dcrn) { + case SDRAM_R0BAS: + case SDRAM_R1BAS: + case SDRAM_R2BAS: + case SDRAM_R3BAS: + case SDRAM_CONF1HB: + case SDRAM_CONF1LL: + case SDRAM_CONFPATHB: + case SDRAM_PLBADDULL: + case SDRAM_PLBADDUHB: + break; + case SDRAM0_CFGADDR: + sdram->addr = val; + break; + case SDRAM0_CFGDATA: + switch (sdram->addr) { + case 0x00: /* B0CR */ + break; + case 0x21: /* SDRAM_MCOPT2 */ + if (!(sdram->mcopt2 & SDRAM_DDR2_MCOPT2_DCEN) && + (val & SDRAM_DDR2_MCOPT2_DCEN)) { + trace_ppc4xx_sdram_enable("enable"); + /* validate all RAM mappings */ + sdram_ddr2_map_bcr(sdram); + sdram->mcopt2 |= SDRAM_DDR2_MCOPT2_DCEN; + } else if ((sdram->mcopt2 & SDRAM_DDR2_MCOPT2_DCEN) && + !(val & SDRAM_DDR2_MCOPT2_DCEN)) { + trace_ppc4xx_sdram_enable("disable"); + /* invalidate all RAM mappings */ + sdram_ddr2_unmap_bcr(sdram); + sdram->mcopt2 &= ~SDRAM_DDR2_MCOPT2_DCEN; + } + break; + default: + break; + } + break; + default: + break; + } +} + +static void ppc4xx_sdram_ddr2_reset(DeviceState *dev) +{ + Ppc4xxSdramDdr2State *sdram = PPC4xx_SDRAM_DDR2(dev); + + sdram->addr = 0; + sdram->mcopt2 = 0; +} + +static void ppc4xx_sdram_ddr2_realize(DeviceState *dev, Error **errp) +{ + Ppc4xxSdramDdr2State *s = PPC4xx_SDRAM_DDR2(dev); + Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev); + /* + * SoC also has 4 GiB but that causes problem with 32 bit + * builds (4*GiB overflows the 32 bit ram_addr_t). + */ + const ram_addr_t valid_bank_sizes[] = { + 2 * GiB, 1 * GiB, 512 * MiB, 256 * MiB, 128 * MiB, + 64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 0 + }; + + if (s->nbanks < 1 || s->nbanks > 4) { + error_setg(errp, "Invalid number of RAM banks"); + return; + } + if (!s->dram_mr) { + error_setg(errp, "Missing dram memory region"); + return; + } + ppc4xx_sdram_banks(s->dram_mr, s->nbanks, s->bank, valid_bank_sizes); + + ppc4xx_dcr_register(dcr, SDRAM0_CFGADDR, + s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); + ppc4xx_dcr_register(dcr, SDRAM0_CFGDATA, + s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); + + ppc4xx_dcr_register(dcr, SDRAM_R0BAS, + s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); + ppc4xx_dcr_register(dcr, SDRAM_R1BAS, + s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); + ppc4xx_dcr_register(dcr, SDRAM_R2BAS, + s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); + ppc4xx_dcr_register(dcr, SDRAM_R3BAS, + s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); + ppc4xx_dcr_register(dcr, SDRAM_CONF1HB, + s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); + ppc4xx_dcr_register(dcr, SDRAM_PLBADDULL, + s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); + ppc4xx_dcr_register(dcr, SDRAM_CONF1LL, + s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); + ppc4xx_dcr_register(dcr, SDRAM_CONFPATHB, + s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); + ppc4xx_dcr_register(dcr, SDRAM_PLBADDUHB, + s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); +} + +static Property ppc4xx_sdram_ddr2_props[] = { + DEFINE_PROP_LINK("dram", Ppc4xxSdramDdr2State, dram_mr, TYPE_MEMORY_REGION, + MemoryRegion *), + DEFINE_PROP_UINT32("nbanks", Ppc4xxSdramDdr2State, nbanks, 4), + DEFINE_PROP_END_OF_LIST(), +}; + +static void ppc4xx_sdram_ddr2_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + + dc->realize = ppc4xx_sdram_ddr2_realize; + dc->reset = ppc4xx_sdram_ddr2_reset; + /* Reason: only works as function of a ppc4xx SoC */ + dc->user_creatable = false; + device_class_set_props(dc, ppc4xx_sdram_ddr2_props); +} + +void ppc4xx_sdram_ddr2_enable(Ppc4xxSdramDdr2State *s) +{ + sdram_ddr2_dcr_write(s, SDRAM0_CFGADDR, 0x21); + sdram_ddr2_dcr_write(s, SDRAM0_CFGDATA, 0x08000000); +} + +static const TypeInfo ppc4xx_sdram_types[] = { + { + .name = TYPE_PPC4xx_SDRAM_DDR2, + .parent = TYPE_PPC4xx_DCR_DEVICE, + .instance_size = sizeof(Ppc4xxSdramDdr2State), + .class_init = ppc4xx_sdram_ddr2_class_init, + } +}; + +DEFINE_TYPES(ppc4xx_sdram_types) From fa446fc54082c0c87a2edf7048bd17112773f0ef Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Wed, 19 Oct 2022 18:02:53 +0200 Subject: [PATCH 385/705] ppc4xx_devs.c: Move DDR SDRAM controller model to ppc4xx_sdram.c Signed-off-by: BALATON Zoltan Reviewed-by: Daniel Henrique Barboza Message-Id: <3ea98072dbeb757942e25dcfcdd6a7a47738d2ca.1666194485.git.balaton@eik.bme.hu> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/ppc4xx_devs.c | 352 ---------------------------------------- hw/ppc/ppc4xx_sdram.c | 365 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 365 insertions(+), 352 deletions(-) diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c index 12af90f244..f737dbb3d6 100644 --- a/hw/ppc/ppc4xx_devs.c +++ b/hw/ppc/ppc4xx_devs.c @@ -24,357 +24,10 @@ #include "qemu/osdep.h" #include "qemu/units.h" -#include "sysemu/reset.h" #include "cpu.h" -#include "hw/irq.h" -#include "hw/ppc/ppc.h" #include "hw/ppc/ppc4xx.h" #include "hw/qdev-properties.h" -#include "qemu/log.h" -#include "exec/address-spaces.h" -#include "qemu/error-report.h" #include "qapi/error.h" -#include "trace.h" - -/*****************************************************************************/ -/* SDRAM controller */ -enum { - SDRAM0_CFGADDR = 0x010, - SDRAM0_CFGDATA = 0x011, -}; - -/* - * XXX: TOFIX: some patches have made this code become inconsistent: - * there are type inconsistencies, mixing hwaddr, target_ulong - * and uint32_t - */ -static uint32_t sdram_ddr_bcr(hwaddr ram_base, hwaddr ram_size) -{ - uint32_t bcr; - - switch (ram_size) { - case 4 * MiB: - bcr = 0; - break; - case 8 * MiB: - bcr = 0x20000; - break; - case 16 * MiB: - bcr = 0x40000; - break; - case 32 * MiB: - bcr = 0x60000; - break; - case 64 * MiB: - bcr = 0x80000; - break; - case 128 * MiB: - bcr = 0xA0000; - break; - case 256 * MiB: - bcr = 0xC0000; - break; - default: - qemu_log_mask(LOG_GUEST_ERROR, - "%s: invalid RAM size 0x%" HWADDR_PRIx "\n", __func__, - ram_size); - return 0; - } - bcr |= ram_base & 0xFF800000; - bcr |= 1; - - return bcr; -} - -static inline hwaddr sdram_ddr_base(uint32_t bcr) -{ - return bcr & 0xFF800000; -} - -static target_ulong sdram_ddr_size(uint32_t bcr) -{ - target_ulong size; - int sh; - - sh = (bcr >> 17) & 0x7; - if (sh == 7) { - size = -1; - } else { - size = (4 * MiB) << sh; - } - - return size; -} - -static void sdram_ddr_set_bcr(Ppc4xxSdramDdrState *sdram, int i, - uint32_t bcr, int enabled) -{ - if (sdram->bank[i].bcr & 1) { - /* Unmap RAM */ - trace_ppc4xx_sdram_unmap(sdram_ddr_base(sdram->bank[i].bcr), - sdram_ddr_size(sdram->bank[i].bcr)); - memory_region_del_subregion(get_system_memory(), - &sdram->bank[i].container); - memory_region_del_subregion(&sdram->bank[i].container, - &sdram->bank[i].ram); - object_unparent(OBJECT(&sdram->bank[i].container)); - } - sdram->bank[i].bcr = bcr & 0xFFDEE001; - if (enabled && (bcr & 1)) { - trace_ppc4xx_sdram_map(sdram_ddr_base(bcr), sdram_ddr_size(bcr)); - memory_region_init(&sdram->bank[i].container, NULL, "sdram-container", - sdram_ddr_size(bcr)); - memory_region_add_subregion(&sdram->bank[i].container, 0, - &sdram->bank[i].ram); - memory_region_add_subregion(get_system_memory(), - sdram_ddr_base(bcr), - &sdram->bank[i].container); - } -} - -static void sdram_ddr_map_bcr(Ppc4xxSdramDdrState *sdram) -{ - int i; - - for (i = 0; i < sdram->nbanks; i++) { - if (sdram->bank[i].size != 0) { - sdram_ddr_set_bcr(sdram, i, sdram_ddr_bcr(sdram->bank[i].base, - sdram->bank[i].size), 1); - } else { - sdram_ddr_set_bcr(sdram, i, 0, 0); - } - } -} - -static void sdram_ddr_unmap_bcr(Ppc4xxSdramDdrState *sdram) -{ - int i; - - for (i = 0; i < sdram->nbanks; i++) { - trace_ppc4xx_sdram_unmap(sdram_ddr_base(sdram->bank[i].bcr), - sdram_ddr_size(sdram->bank[i].bcr)); - memory_region_del_subregion(get_system_memory(), - &sdram->bank[i].ram); - } -} - -static uint32_t sdram_ddr_dcr_read(void *opaque, int dcrn) -{ - Ppc4xxSdramDdrState *sdram = opaque; - uint32_t ret; - - switch (dcrn) { - case SDRAM0_CFGADDR: - ret = sdram->addr; - break; - case SDRAM0_CFGDATA: - switch (sdram->addr) { - case 0x00: /* SDRAM_BESR0 */ - ret = sdram->besr0; - break; - case 0x08: /* SDRAM_BESR1 */ - ret = sdram->besr1; - break; - case 0x10: /* SDRAM_BEAR */ - ret = sdram->bear; - break; - case 0x20: /* SDRAM_CFG */ - ret = sdram->cfg; - break; - case 0x24: /* SDRAM_STATUS */ - ret = sdram->status; - break; - case 0x30: /* SDRAM_RTR */ - ret = sdram->rtr; - break; - case 0x34: /* SDRAM_PMIT */ - ret = sdram->pmit; - break; - case 0x40: /* SDRAM_B0CR */ - ret = sdram->bank[0].bcr; - break; - case 0x44: /* SDRAM_B1CR */ - ret = sdram->bank[1].bcr; - break; - case 0x48: /* SDRAM_B2CR */ - ret = sdram->bank[2].bcr; - break; - case 0x4C: /* SDRAM_B3CR */ - ret = sdram->bank[3].bcr; - break; - case 0x80: /* SDRAM_TR */ - ret = -1; /* ? */ - break; - case 0x94: /* SDRAM_ECCCFG */ - ret = sdram->ecccfg; - break; - case 0x98: /* SDRAM_ECCESR */ - ret = sdram->eccesr; - break; - default: /* Error */ - ret = -1; - break; - } - break; - default: - /* Avoid gcc warning */ - ret = 0; - break; - } - - return ret; -} - -static void sdram_ddr_dcr_write(void *opaque, int dcrn, uint32_t val) -{ - Ppc4xxSdramDdrState *sdram = opaque; - - switch (dcrn) { - case SDRAM0_CFGADDR: - sdram->addr = val; - break; - case SDRAM0_CFGDATA: - switch (sdram->addr) { - case 0x00: /* SDRAM_BESR0 */ - sdram->besr0 &= ~val; - break; - case 0x08: /* SDRAM_BESR1 */ - sdram->besr1 &= ~val; - break; - case 0x10: /* SDRAM_BEAR */ - sdram->bear = val; - break; - case 0x20: /* SDRAM_CFG */ - val &= 0xFFE00000; - if (!(sdram->cfg & 0x80000000) && (val & 0x80000000)) { - trace_ppc4xx_sdram_enable("enable"); - /* validate all RAM mappings */ - sdram_ddr_map_bcr(sdram); - sdram->status &= ~0x80000000; - } else if ((sdram->cfg & 0x80000000) && !(val & 0x80000000)) { - trace_ppc4xx_sdram_enable("disable"); - /* invalidate all RAM mappings */ - sdram_ddr_unmap_bcr(sdram); - sdram->status |= 0x80000000; - } - if (!(sdram->cfg & 0x40000000) && (val & 0x40000000)) { - sdram->status |= 0x40000000; - } else if ((sdram->cfg & 0x40000000) && !(val & 0x40000000)) { - sdram->status &= ~0x40000000; - } - sdram->cfg = val; - break; - case 0x24: /* SDRAM_STATUS */ - /* Read-only register */ - break; - case 0x30: /* SDRAM_RTR */ - sdram->rtr = val & 0x3FF80000; - break; - case 0x34: /* SDRAM_PMIT */ - sdram->pmit = (val & 0xF8000000) | 0x07C00000; - break; - case 0x40: /* SDRAM_B0CR */ - sdram_ddr_set_bcr(sdram, 0, val, sdram->cfg & 0x80000000); - break; - case 0x44: /* SDRAM_B1CR */ - sdram_ddr_set_bcr(sdram, 1, val, sdram->cfg & 0x80000000); - break; - case 0x48: /* SDRAM_B2CR */ - sdram_ddr_set_bcr(sdram, 2, val, sdram->cfg & 0x80000000); - break; - case 0x4C: /* SDRAM_B3CR */ - sdram_ddr_set_bcr(sdram, 3, val, sdram->cfg & 0x80000000); - break; - case 0x80: /* SDRAM_TR */ - sdram->tr = val & 0x018FC01F; - break; - case 0x94: /* SDRAM_ECCCFG */ - sdram->ecccfg = val & 0x00F00000; - break; - case 0x98: /* SDRAM_ECCESR */ - val &= 0xFFF0F000; - if (sdram->eccesr == 0 && val != 0) { - qemu_irq_raise(sdram->irq); - } else if (sdram->eccesr != 0 && val == 0) { - qemu_irq_lower(sdram->irq); - } - sdram->eccesr = val; - break; - default: /* Error */ - break; - } - break; - } -} - -static void ppc4xx_sdram_ddr_reset(DeviceState *dev) -{ - Ppc4xxSdramDdrState *sdram = PPC4xx_SDRAM_DDR(dev); - - sdram->addr = 0; - sdram->bear = 0; - sdram->besr0 = 0; /* No error */ - sdram->besr1 = 0; /* No error */ - sdram->cfg = 0; - sdram->ecccfg = 0; /* No ECC */ - sdram->eccesr = 0; /* No error */ - sdram->pmit = 0x07C00000; - sdram->rtr = 0x05F00000; - sdram->tr = 0x00854009; - /* We pre-initialize RAM banks */ - sdram->status = 0; - sdram->cfg = 0x00800000; -} - -static void ppc4xx_sdram_ddr_realize(DeviceState *dev, Error **errp) -{ - Ppc4xxSdramDdrState *s = PPC4xx_SDRAM_DDR(dev); - Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev); - const ram_addr_t valid_bank_sizes[] = { - 256 * MiB, 128 * MiB, 64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 4 * MiB, 0 - }; - - if (s->nbanks < 1 || s->nbanks > 4) { - error_setg(errp, "Invalid number of RAM banks"); - return; - } - if (!s->dram_mr) { - error_setg(errp, "Missing dram memory region"); - return; - } - ppc4xx_sdram_banks(s->dram_mr, s->nbanks, s->bank, valid_bank_sizes); - - sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq); - - ppc4xx_dcr_register(dcr, SDRAM0_CFGADDR, - s, &sdram_ddr_dcr_read, &sdram_ddr_dcr_write); - ppc4xx_dcr_register(dcr, SDRAM0_CFGDATA, - s, &sdram_ddr_dcr_read, &sdram_ddr_dcr_write); -} - -static Property ppc4xx_sdram_ddr_props[] = { - DEFINE_PROP_LINK("dram", Ppc4xxSdramDdrState, dram_mr, TYPE_MEMORY_REGION, - MemoryRegion *), - DEFINE_PROP_UINT32("nbanks", Ppc4xxSdramDdrState, nbanks, 4), - DEFINE_PROP_END_OF_LIST(), -}; - -static void ppc4xx_sdram_ddr_class_init(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - - dc->realize = ppc4xx_sdram_ddr_realize; - dc->reset = ppc4xx_sdram_ddr_reset; - /* Reason: only works as function of a ppc4xx SoC */ - dc->user_creatable = false; - device_class_set_props(dc, ppc4xx_sdram_ddr_props); -} - -void ppc4xx_sdram_ddr_enable(Ppc4xxSdramDdrState *s) -{ - sdram_ddr_dcr_write(s, SDRAM0_CFGADDR, 0x20); - sdram_ddr_dcr_write(s, SDRAM0_CFGDATA, 0x80000000); -} /* * Split RAM between SDRAM banks. @@ -963,11 +616,6 @@ static void ppc4xx_dcr_class_init(ObjectClass *oc, void *data) static const TypeInfo ppc4xx_types[] = { { - .name = TYPE_PPC4xx_SDRAM_DDR, - .parent = TYPE_PPC4xx_DCR_DEVICE, - .instance_size = sizeof(Ppc4xxSdramDdrState), - .class_init = ppc4xx_sdram_ddr_class_init, - }, { .name = TYPE_PPC4xx_MAL, .parent = TYPE_PPC4xx_DCR_DEVICE, .instance_size = sizeof(Ppc4xxMalState), diff --git a/hw/ppc/ppc4xx_sdram.c b/hw/ppc/ppc4xx_sdram.c index b49a7ed60a..d88363bc3d 100644 --- a/hw/ppc/ppc4xx_sdram.c +++ b/hw/ppc/ppc4xx_sdram.c @@ -1,4 +1,27 @@ /* + * QEMU PowerPC 4xx embedded processors SDRAM controller emulation + * + * DDR SDRAM controller: + * Copyright (c) 2007 Jocelyn Mayer + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * * DDR2 SDRAM controller: * Copyright (c) 2012 François Revol * Copyright (c) 2016-2019 BALATON Zoltan @@ -9,7 +32,9 @@ #include "qemu/osdep.h" #include "qemu/units.h" #include "qapi/error.h" +#include "qemu/log.h" #include "exec/address-spaces.h" /* get_system_memory() */ +#include "exec/cpu-defs.h" /* target_ulong */ #include "hw/irq.h" #include "hw/qdev-properties.h" #include "hw/ppc/ppc4xx.h" @@ -38,6 +63,341 @@ enum { SDRAM0_CFGDATA = 0x011, }; +/*****************************************************************************/ +/* DDR SDRAM controller */ +/* + * XXX: TOFIX: some patches have made this code become inconsistent: + * there are type inconsistencies, mixing hwaddr, target_ulong + * and uint32_t + */ +static uint32_t sdram_ddr_bcr(hwaddr ram_base, hwaddr ram_size) +{ + uint32_t bcr; + + switch (ram_size) { + case 4 * MiB: + bcr = 0; + break; + case 8 * MiB: + bcr = 0x20000; + break; + case 16 * MiB: + bcr = 0x40000; + break; + case 32 * MiB: + bcr = 0x60000; + break; + case 64 * MiB: + bcr = 0x80000; + break; + case 128 * MiB: + bcr = 0xA0000; + break; + case 256 * MiB: + bcr = 0xC0000; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid RAM size 0x%" HWADDR_PRIx "\n", __func__, + ram_size); + return 0; + } + bcr |= ram_base & 0xFF800000; + bcr |= 1; + + return bcr; +} + +static inline hwaddr sdram_ddr_base(uint32_t bcr) +{ + return bcr & 0xFF800000; +} + +static target_ulong sdram_ddr_size(uint32_t bcr) +{ + target_ulong size; + int sh; + + sh = (bcr >> 17) & 0x7; + if (sh == 7) { + size = -1; + } else { + size = (4 * MiB) << sh; + } + + return size; +} + +static void sdram_ddr_set_bcr(Ppc4xxSdramDdrState *sdram, int i, + uint32_t bcr, int enabled) +{ + if (sdram->bank[i].bcr & 1) { + /* Unmap RAM */ + trace_ppc4xx_sdram_unmap(sdram_ddr_base(sdram->bank[i].bcr), + sdram_ddr_size(sdram->bank[i].bcr)); + memory_region_del_subregion(get_system_memory(), + &sdram->bank[i].container); + memory_region_del_subregion(&sdram->bank[i].container, + &sdram->bank[i].ram); + object_unparent(OBJECT(&sdram->bank[i].container)); + } + sdram->bank[i].bcr = bcr & 0xFFDEE001; + if (enabled && (bcr & 1)) { + trace_ppc4xx_sdram_map(sdram_ddr_base(bcr), sdram_ddr_size(bcr)); + memory_region_init(&sdram->bank[i].container, NULL, "sdram-container", + sdram_ddr_size(bcr)); + memory_region_add_subregion(&sdram->bank[i].container, 0, + &sdram->bank[i].ram); + memory_region_add_subregion(get_system_memory(), + sdram_ddr_base(bcr), + &sdram->bank[i].container); + } +} + +static void sdram_ddr_map_bcr(Ppc4xxSdramDdrState *sdram) +{ + int i; + + for (i = 0; i < sdram->nbanks; i++) { + if (sdram->bank[i].size != 0) { + sdram_ddr_set_bcr(sdram, i, sdram_ddr_bcr(sdram->bank[i].base, + sdram->bank[i].size), 1); + } else { + sdram_ddr_set_bcr(sdram, i, 0, 0); + } + } +} + +static void sdram_ddr_unmap_bcr(Ppc4xxSdramDdrState *sdram) +{ + int i; + + for (i = 0; i < sdram->nbanks; i++) { + trace_ppc4xx_sdram_unmap(sdram_ddr_base(sdram->bank[i].bcr), + sdram_ddr_size(sdram->bank[i].bcr)); + memory_region_del_subregion(get_system_memory(), + &sdram->bank[i].ram); + } +} + +static uint32_t sdram_ddr_dcr_read(void *opaque, int dcrn) +{ + Ppc4xxSdramDdrState *sdram = opaque; + uint32_t ret; + + switch (dcrn) { + case SDRAM0_CFGADDR: + ret = sdram->addr; + break; + case SDRAM0_CFGDATA: + switch (sdram->addr) { + case 0x00: /* SDRAM_BESR0 */ + ret = sdram->besr0; + break; + case 0x08: /* SDRAM_BESR1 */ + ret = sdram->besr1; + break; + case 0x10: /* SDRAM_BEAR */ + ret = sdram->bear; + break; + case 0x20: /* SDRAM_CFG */ + ret = sdram->cfg; + break; + case 0x24: /* SDRAM_STATUS */ + ret = sdram->status; + break; + case 0x30: /* SDRAM_RTR */ + ret = sdram->rtr; + break; + case 0x34: /* SDRAM_PMIT */ + ret = sdram->pmit; + break; + case 0x40: /* SDRAM_B0CR */ + ret = sdram->bank[0].bcr; + break; + case 0x44: /* SDRAM_B1CR */ + ret = sdram->bank[1].bcr; + break; + case 0x48: /* SDRAM_B2CR */ + ret = sdram->bank[2].bcr; + break; + case 0x4C: /* SDRAM_B3CR */ + ret = sdram->bank[3].bcr; + break; + case 0x80: /* SDRAM_TR */ + ret = -1; /* ? */ + break; + case 0x94: /* SDRAM_ECCCFG */ + ret = sdram->ecccfg; + break; + case 0x98: /* SDRAM_ECCESR */ + ret = sdram->eccesr; + break; + default: /* Error */ + ret = -1; + break; + } + break; + default: + /* Avoid gcc warning */ + ret = 0; + break; + } + + return ret; +} + +static void sdram_ddr_dcr_write(void *opaque, int dcrn, uint32_t val) +{ + Ppc4xxSdramDdrState *sdram = opaque; + + switch (dcrn) { + case SDRAM0_CFGADDR: + sdram->addr = val; + break; + case SDRAM0_CFGDATA: + switch (sdram->addr) { + case 0x00: /* SDRAM_BESR0 */ + sdram->besr0 &= ~val; + break; + case 0x08: /* SDRAM_BESR1 */ + sdram->besr1 &= ~val; + break; + case 0x10: /* SDRAM_BEAR */ + sdram->bear = val; + break; + case 0x20: /* SDRAM_CFG */ + val &= 0xFFE00000; + if (!(sdram->cfg & 0x80000000) && (val & 0x80000000)) { + trace_ppc4xx_sdram_enable("enable"); + /* validate all RAM mappings */ + sdram_ddr_map_bcr(sdram); + sdram->status &= ~0x80000000; + } else if ((sdram->cfg & 0x80000000) && !(val & 0x80000000)) { + trace_ppc4xx_sdram_enable("disable"); + /* invalidate all RAM mappings */ + sdram_ddr_unmap_bcr(sdram); + sdram->status |= 0x80000000; + } + if (!(sdram->cfg & 0x40000000) && (val & 0x40000000)) { + sdram->status |= 0x40000000; + } else if ((sdram->cfg & 0x40000000) && !(val & 0x40000000)) { + sdram->status &= ~0x40000000; + } + sdram->cfg = val; + break; + case 0x24: /* SDRAM_STATUS */ + /* Read-only register */ + break; + case 0x30: /* SDRAM_RTR */ + sdram->rtr = val & 0x3FF80000; + break; + case 0x34: /* SDRAM_PMIT */ + sdram->pmit = (val & 0xF8000000) | 0x07C00000; + break; + case 0x40: /* SDRAM_B0CR */ + sdram_ddr_set_bcr(sdram, 0, val, sdram->cfg & 0x80000000); + break; + case 0x44: /* SDRAM_B1CR */ + sdram_ddr_set_bcr(sdram, 1, val, sdram->cfg & 0x80000000); + break; + case 0x48: /* SDRAM_B2CR */ + sdram_ddr_set_bcr(sdram, 2, val, sdram->cfg & 0x80000000); + break; + case 0x4C: /* SDRAM_B3CR */ + sdram_ddr_set_bcr(sdram, 3, val, sdram->cfg & 0x80000000); + break; + case 0x80: /* SDRAM_TR */ + sdram->tr = val & 0x018FC01F; + break; + case 0x94: /* SDRAM_ECCCFG */ + sdram->ecccfg = val & 0x00F00000; + break; + case 0x98: /* SDRAM_ECCESR */ + val &= 0xFFF0F000; + if (sdram->eccesr == 0 && val != 0) { + qemu_irq_raise(sdram->irq); + } else if (sdram->eccesr != 0 && val == 0) { + qemu_irq_lower(sdram->irq); + } + sdram->eccesr = val; + break; + default: /* Error */ + break; + } + break; + } +} + +static void ppc4xx_sdram_ddr_reset(DeviceState *dev) +{ + Ppc4xxSdramDdrState *sdram = PPC4xx_SDRAM_DDR(dev); + + sdram->addr = 0; + sdram->bear = 0; + sdram->besr0 = 0; /* No error */ + sdram->besr1 = 0; /* No error */ + sdram->cfg = 0; + sdram->ecccfg = 0; /* No ECC */ + sdram->eccesr = 0; /* No error */ + sdram->pmit = 0x07C00000; + sdram->rtr = 0x05F00000; + sdram->tr = 0x00854009; + /* We pre-initialize RAM banks */ + sdram->status = 0; + sdram->cfg = 0x00800000; +} + +static void ppc4xx_sdram_ddr_realize(DeviceState *dev, Error **errp) +{ + Ppc4xxSdramDdrState *s = PPC4xx_SDRAM_DDR(dev); + Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev); + const ram_addr_t valid_bank_sizes[] = { + 256 * MiB, 128 * MiB, 64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 4 * MiB, 0 + }; + + if (s->nbanks < 1 || s->nbanks > 4) { + error_setg(errp, "Invalid number of RAM banks"); + return; + } + if (!s->dram_mr) { + error_setg(errp, "Missing dram memory region"); + return; + } + ppc4xx_sdram_banks(s->dram_mr, s->nbanks, s->bank, valid_bank_sizes); + + sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq); + + ppc4xx_dcr_register(dcr, SDRAM0_CFGADDR, + s, &sdram_ddr_dcr_read, &sdram_ddr_dcr_write); + ppc4xx_dcr_register(dcr, SDRAM0_CFGDATA, + s, &sdram_ddr_dcr_read, &sdram_ddr_dcr_write); +} + +static Property ppc4xx_sdram_ddr_props[] = { + DEFINE_PROP_LINK("dram", Ppc4xxSdramDdrState, dram_mr, TYPE_MEMORY_REGION, + MemoryRegion *), + DEFINE_PROP_UINT32("nbanks", Ppc4xxSdramDdrState, nbanks, 4), + DEFINE_PROP_END_OF_LIST(), +}; + +static void ppc4xx_sdram_ddr_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + + dc->realize = ppc4xx_sdram_ddr_realize; + dc->reset = ppc4xx_sdram_ddr_reset; + /* Reason: only works as function of a ppc4xx SoC */ + dc->user_creatable = false; + device_class_set_props(dc, ppc4xx_sdram_ddr_props); +} + +void ppc4xx_sdram_ddr_enable(Ppc4xxSdramDdrState *s) +{ + sdram_ddr_dcr_write(s, SDRAM0_CFGADDR, 0x20); + sdram_ddr_dcr_write(s, SDRAM0_CFGDATA, 0x80000000); +} + /*****************************************************************************/ /* DDR2 SDRAM controller */ enum { @@ -338,6 +698,11 @@ void ppc4xx_sdram_ddr2_enable(Ppc4xxSdramDdr2State *s) static const TypeInfo ppc4xx_sdram_types[] = { { + .name = TYPE_PPC4xx_SDRAM_DDR, + .parent = TYPE_PPC4xx_DCR_DEVICE, + .instance_size = sizeof(Ppc4xxSdramDdrState), + .class_init = ppc4xx_sdram_ddr_class_init, + }, { .name = TYPE_PPC4xx_SDRAM_DDR2, .parent = TYPE_PPC4xx_DCR_DEVICE, .instance_size = sizeof(Ppc4xxSdramDdr2State), From 080741abc293e79b6e860e2c8d66bfe519090c86 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Wed, 19 Oct 2022 18:02:54 +0200 Subject: [PATCH 386/705] ppc4xx_sdram: Move ppc4xx_sdram_banks() to ppc4xx_sdram.c This function is only used by the ppc4xx memory controller models so it can be made static. Signed-off-by: BALATON Zoltan Reviewed-by: Daniel Henrique Barboza Message-Id: Signed-off-by: Daniel Henrique Barboza --- hw/ppc/ppc4xx_devs.c | 62 ----------------------------------------- hw/ppc/ppc4xx_sdram.c | 61 ++++++++++++++++++++++++++++++++++++++++ include/hw/ppc/ppc4xx.h | 20 ++++++------- 3 files changed, 69 insertions(+), 74 deletions(-) diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c index f737dbb3d6..c1d111465d 100644 --- a/hw/ppc/ppc4xx_devs.c +++ b/hw/ppc/ppc4xx_devs.c @@ -23,73 +23,11 @@ */ #include "qemu/osdep.h" -#include "qemu/units.h" #include "cpu.h" #include "hw/ppc/ppc4xx.h" #include "hw/qdev-properties.h" #include "qapi/error.h" -/* - * Split RAM between SDRAM banks. - * - * sdram_bank_sizes[] must be in descending order, that is sizes[i] > sizes[i+1] - * and must be 0-terminated. - * - * The 4xx SDRAM controller supports a small number of banks, and each bank - * must be one of a small set of sizes. The number of banks and the supported - * sizes varies by SoC. - */ -void ppc4xx_sdram_banks(MemoryRegion *ram, int nr_banks, - Ppc4xxSdramBank ram_banks[], - const ram_addr_t sdram_bank_sizes[]) -{ - ram_addr_t size_left = memory_region_size(ram); - ram_addr_t base = 0; - ram_addr_t bank_size; - int i; - int j; - - for (i = 0; i < nr_banks; i++) { - for (j = 0; sdram_bank_sizes[j] != 0; j++) { - bank_size = sdram_bank_sizes[j]; - if (bank_size <= size_left) { - char name[32]; - - ram_banks[i].base = base; - ram_banks[i].size = bank_size; - base += bank_size; - size_left -= bank_size; - snprintf(name, sizeof(name), "ppc4xx.sdram%d", i); - memory_region_init_alias(&ram_banks[i].ram, NULL, name, ram, - ram_banks[i].base, ram_banks[i].size); - break; - } - } - if (!size_left) { - /* No need to use the remaining banks. */ - break; - } - } - - if (size_left) { - ram_addr_t used_size = memory_region_size(ram) - size_left; - GString *s = g_string_new(NULL); - - for (i = 0; sdram_bank_sizes[i]; i++) { - g_string_append_printf(s, "%" PRIi64 "%s", - sdram_bank_sizes[i] / MiB, - sdram_bank_sizes[i + 1] ? ", " : ""); - } - error_report("at most %d bank%s of %s MiB each supported", - nr_banks, nr_banks == 1 ? "" : "s", s->str); - error_printf("Possible valid RAM size: %" PRIi64 " MiB\n", - used_size ? used_size / MiB : sdram_bank_sizes[i - 1] / MiB); - - g_string_free(s, true); - exit(EXIT_FAILURE); - } -} - /*****************************************************************************/ /* MAL */ diff --git a/hw/ppc/ppc4xx_sdram.c b/hw/ppc/ppc4xx_sdram.c index d88363bc3d..62ef7d8f0d 100644 --- a/hw/ppc/ppc4xx_sdram.c +++ b/hw/ppc/ppc4xx_sdram.c @@ -43,6 +43,67 @@ /*****************************************************************************/ /* Shared functions */ +/* + * Split RAM between SDRAM banks. + * + * sdram_bank_sizes[] must be in descending order, that is sizes[i] > sizes[i+1] + * and must be 0-terminated. + * + * The 4xx SDRAM controller supports a small number of banks, and each bank + * must be one of a small set of sizes. The number of banks and the supported + * sizes varies by SoC. + */ +static void ppc4xx_sdram_banks(MemoryRegion *ram, int nr_banks, + Ppc4xxSdramBank ram_banks[], + const ram_addr_t sdram_bank_sizes[]) +{ + ram_addr_t size_left = memory_region_size(ram); + ram_addr_t base = 0; + ram_addr_t bank_size; + int i; + int j; + + for (i = 0; i < nr_banks; i++) { + for (j = 0; sdram_bank_sizes[j] != 0; j++) { + bank_size = sdram_bank_sizes[j]; + if (bank_size <= size_left) { + char name[32]; + + ram_banks[i].base = base; + ram_banks[i].size = bank_size; + base += bank_size; + size_left -= bank_size; + snprintf(name, sizeof(name), "ppc4xx.sdram%d", i); + memory_region_init_alias(&ram_banks[i].ram, NULL, name, ram, + ram_banks[i].base, ram_banks[i].size); + break; + } + } + if (!size_left) { + /* No need to use the remaining banks. */ + break; + } + } + + if (size_left) { + ram_addr_t used_size = memory_region_size(ram) - size_left; + GString *s = g_string_new(NULL); + + for (i = 0; sdram_bank_sizes[i]; i++) { + g_string_append_printf(s, "%" PRIi64 "%s", + sdram_bank_sizes[i] / MiB, + sdram_bank_sizes[i + 1] ? ", " : ""); + } + error_report("at most %d bank%s of %s MiB each supported", + nr_banks, nr_banks == 1 ? "" : "s", s->str); + error_printf("Possible valid RAM size: %" PRIi64 " MiB\n", + used_size ? used_size / MiB : sdram_bank_sizes[i - 1] / MiB); + + g_string_free(s, true); + exit(EXIT_FAILURE); + } +} + static void sdram_bank_map(Ppc4xxSdramBank *bank) { memory_region_init(&bank->container, NULL, "sdram-container", bank->size); diff --git a/include/hw/ppc/ppc4xx.h b/include/hw/ppc/ppc4xx.h index 10c6dd535f..f8c86e09ec 100644 --- a/include/hw/ppc/ppc4xx.h +++ b/include/hw/ppc/ppc4xx.h @@ -29,18 +29,6 @@ #include "exec/memory.h" #include "hw/sysbus.h" -typedef struct { - MemoryRegion ram; - MemoryRegion container; /* used for clipping */ - hwaddr base; - hwaddr size; - uint32_t bcr; -} Ppc4xxSdramBank; - -void ppc4xx_sdram_banks(MemoryRegion *ram, int nr_banks, - Ppc4xxSdramBank ram_banks[], - const ram_addr_t sdram_bank_sizes[]); - #define TYPE_PPC4xx_PCI_HOST_BRIDGE "ppc4xx-pcihost" /* @@ -111,6 +99,14 @@ struct Ppc4xxEbcState { }; /* SDRAM DDR controller */ +typedef struct { + MemoryRegion ram; + MemoryRegion container; /* used for clipping */ + hwaddr base; + hwaddr size; + uint32_t bcr; +} Ppc4xxSdramBank; + #define SDR0_DDR0_DDRM_ENCODE(n) ((((unsigned long)(n)) & 0x03) << 29) #define SDR0_DDR0_DDRM_DDR1 0x20000000 #define SDR0_DDR0_DDRM_DDR2 0x40000000 From c8c6d68af7e7fba666a684c684f86ddbf9f20bee Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Wed, 19 Oct 2022 18:02:55 +0200 Subject: [PATCH 387/705] ppc4xx_sdram: Use hwaddr for memory bank size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This resolves the target_ulong dependency that's clearly wrong and was also noted in a fixme comment. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Message-Id: <92fdc5f9cc76bf45831428b3ec8d9fc6241b7190.1666194485.git.balaton@eik.bme.hu> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/ppc4xx_sdram.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/hw/ppc/ppc4xx_sdram.c b/hw/ppc/ppc4xx_sdram.c index 62ef7d8f0d..2294747594 100644 --- a/hw/ppc/ppc4xx_sdram.c +++ b/hw/ppc/ppc4xx_sdram.c @@ -34,7 +34,6 @@ #include "qapi/error.h" #include "qemu/log.h" #include "exec/address-spaces.h" /* get_system_memory() */ -#include "exec/cpu-defs.h" /* target_ulong */ #include "hw/irq.h" #include "hw/qdev-properties.h" #include "hw/ppc/ppc4xx.h" @@ -126,11 +125,6 @@ enum { /*****************************************************************************/ /* DDR SDRAM controller */ -/* - * XXX: TOFIX: some patches have made this code become inconsistent: - * there are type inconsistencies, mixing hwaddr, target_ulong - * and uint32_t - */ static uint32_t sdram_ddr_bcr(hwaddr ram_base, hwaddr ram_size) { uint32_t bcr; @@ -174,9 +168,9 @@ static inline hwaddr sdram_ddr_base(uint32_t bcr) return bcr & 0xFF800000; } -static target_ulong sdram_ddr_size(uint32_t bcr) +static hwaddr sdram_ddr_size(uint32_t bcr) { - target_ulong size; + hwaddr size; int sh; sh = (bcr >> 17) & 0x7; @@ -523,9 +517,9 @@ static inline hwaddr sdram_ddr2_base(uint32_t bcr) return (bcr & 0xffe00000) << 2; } -static uint64_t sdram_ddr2_size(uint32_t bcr) +static hwaddr sdram_ddr2_size(uint32_t bcr) { - uint64_t size; + hwaddr size; int sh; sh = 1024 - ((bcr >> 6) & 0x3ff); From 61cfe0df903c1c1a0654781db0788da9cd4da32a Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Wed, 19 Oct 2022 18:02:56 +0200 Subject: [PATCH 388/705] ppc4xx_sdram: Rename local state variable for brevity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename the sdram local state variable to s in dcr read/write functions and reset methods for better readability and to match realize methods. Other places not converted will be changed or removed in subsequent patches. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Message-Id: <8e7539cb1fccd7556b68351c4dcf62534c3a69cf.1666194485.git.balaton@eik.bme.hu> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/ppc4xx_sdram.c | 156 +++++++++++++++++++++--------------------- 1 file changed, 78 insertions(+), 78 deletions(-) diff --git a/hw/ppc/ppc4xx_sdram.c b/hw/ppc/ppc4xx_sdram.c index 2294747594..4bc53c8f01 100644 --- a/hw/ppc/ppc4xx_sdram.c +++ b/hw/ppc/ppc4xx_sdram.c @@ -237,56 +237,56 @@ static void sdram_ddr_unmap_bcr(Ppc4xxSdramDdrState *sdram) static uint32_t sdram_ddr_dcr_read(void *opaque, int dcrn) { - Ppc4xxSdramDdrState *sdram = opaque; + Ppc4xxSdramDdrState *s = opaque; uint32_t ret; switch (dcrn) { case SDRAM0_CFGADDR: - ret = sdram->addr; + ret = s->addr; break; case SDRAM0_CFGDATA: - switch (sdram->addr) { + switch (s->addr) { case 0x00: /* SDRAM_BESR0 */ - ret = sdram->besr0; + ret = s->besr0; break; case 0x08: /* SDRAM_BESR1 */ - ret = sdram->besr1; + ret = s->besr1; break; case 0x10: /* SDRAM_BEAR */ - ret = sdram->bear; + ret = s->bear; break; case 0x20: /* SDRAM_CFG */ - ret = sdram->cfg; + ret = s->cfg; break; case 0x24: /* SDRAM_STATUS */ - ret = sdram->status; + ret = s->status; break; case 0x30: /* SDRAM_RTR */ - ret = sdram->rtr; + ret = s->rtr; break; case 0x34: /* SDRAM_PMIT */ - ret = sdram->pmit; + ret = s->pmit; break; case 0x40: /* SDRAM_B0CR */ - ret = sdram->bank[0].bcr; + ret = s->bank[0].bcr; break; case 0x44: /* SDRAM_B1CR */ - ret = sdram->bank[1].bcr; + ret = s->bank[1].bcr; break; case 0x48: /* SDRAM_B2CR */ - ret = sdram->bank[2].bcr; + ret = s->bank[2].bcr; break; case 0x4C: /* SDRAM_B3CR */ - ret = sdram->bank[3].bcr; + ret = s->bank[3].bcr; break; case 0x80: /* SDRAM_TR */ ret = -1; /* ? */ break; case 0x94: /* SDRAM_ECCCFG */ - ret = sdram->ecccfg; + ret = s->ecccfg; break; case 0x98: /* SDRAM_ECCESR */ - ret = sdram->eccesr; + ret = s->eccesr; break; default: /* Error */ ret = -1; @@ -304,78 +304,78 @@ static uint32_t sdram_ddr_dcr_read(void *opaque, int dcrn) static void sdram_ddr_dcr_write(void *opaque, int dcrn, uint32_t val) { - Ppc4xxSdramDdrState *sdram = opaque; + Ppc4xxSdramDdrState *s = opaque; switch (dcrn) { case SDRAM0_CFGADDR: - sdram->addr = val; + s->addr = val; break; case SDRAM0_CFGDATA: - switch (sdram->addr) { + switch (s->addr) { case 0x00: /* SDRAM_BESR0 */ - sdram->besr0 &= ~val; + s->besr0 &= ~val; break; case 0x08: /* SDRAM_BESR1 */ - sdram->besr1 &= ~val; + s->besr1 &= ~val; break; case 0x10: /* SDRAM_BEAR */ - sdram->bear = val; + s->bear = val; break; case 0x20: /* SDRAM_CFG */ val &= 0xFFE00000; - if (!(sdram->cfg & 0x80000000) && (val & 0x80000000)) { + if (!(s->cfg & 0x80000000) && (val & 0x80000000)) { trace_ppc4xx_sdram_enable("enable"); /* validate all RAM mappings */ - sdram_ddr_map_bcr(sdram); - sdram->status &= ~0x80000000; - } else if ((sdram->cfg & 0x80000000) && !(val & 0x80000000)) { + sdram_ddr_map_bcr(s); + s->status &= ~0x80000000; + } else if ((s->cfg & 0x80000000) && !(val & 0x80000000)) { trace_ppc4xx_sdram_enable("disable"); /* invalidate all RAM mappings */ - sdram_ddr_unmap_bcr(sdram); - sdram->status |= 0x80000000; + sdram_ddr_unmap_bcr(s); + s->status |= 0x80000000; } - if (!(sdram->cfg & 0x40000000) && (val & 0x40000000)) { - sdram->status |= 0x40000000; - } else if ((sdram->cfg & 0x40000000) && !(val & 0x40000000)) { - sdram->status &= ~0x40000000; + if (!(s->cfg & 0x40000000) && (val & 0x40000000)) { + s->status |= 0x40000000; + } else if ((s->cfg & 0x40000000) && !(val & 0x40000000)) { + s->status &= ~0x40000000; } - sdram->cfg = val; + s->cfg = val; break; case 0x24: /* SDRAM_STATUS */ /* Read-only register */ break; case 0x30: /* SDRAM_RTR */ - sdram->rtr = val & 0x3FF80000; + s->rtr = val & 0x3FF80000; break; case 0x34: /* SDRAM_PMIT */ - sdram->pmit = (val & 0xF8000000) | 0x07C00000; + s->pmit = (val & 0xF8000000) | 0x07C00000; break; case 0x40: /* SDRAM_B0CR */ - sdram_ddr_set_bcr(sdram, 0, val, sdram->cfg & 0x80000000); + sdram_ddr_set_bcr(s, 0, val, s->cfg & 0x80000000); break; case 0x44: /* SDRAM_B1CR */ - sdram_ddr_set_bcr(sdram, 1, val, sdram->cfg & 0x80000000); + sdram_ddr_set_bcr(s, 1, val, s->cfg & 0x80000000); break; case 0x48: /* SDRAM_B2CR */ - sdram_ddr_set_bcr(sdram, 2, val, sdram->cfg & 0x80000000); + sdram_ddr_set_bcr(s, 2, val, s->cfg & 0x80000000); break; case 0x4C: /* SDRAM_B3CR */ - sdram_ddr_set_bcr(sdram, 3, val, sdram->cfg & 0x80000000); + sdram_ddr_set_bcr(s, 3, val, s->cfg & 0x80000000); break; case 0x80: /* SDRAM_TR */ - sdram->tr = val & 0x018FC01F; + s->tr = val & 0x018FC01F; break; case 0x94: /* SDRAM_ECCCFG */ - sdram->ecccfg = val & 0x00F00000; + s->ecccfg = val & 0x00F00000; break; case 0x98: /* SDRAM_ECCESR */ val &= 0xFFF0F000; - if (sdram->eccesr == 0 && val != 0) { - qemu_irq_raise(sdram->irq); - } else if (sdram->eccesr != 0 && val == 0) { - qemu_irq_lower(sdram->irq); + if (s->eccesr == 0 && val != 0) { + qemu_irq_raise(s->irq); + } else if (s->eccesr != 0 && val == 0) { + qemu_irq_lower(s->irq); } - sdram->eccesr = val; + s->eccesr = val; break; default: /* Error */ break; @@ -386,21 +386,21 @@ static void sdram_ddr_dcr_write(void *opaque, int dcrn, uint32_t val) static void ppc4xx_sdram_ddr_reset(DeviceState *dev) { - Ppc4xxSdramDdrState *sdram = PPC4xx_SDRAM_DDR(dev); + Ppc4xxSdramDdrState *s = PPC4xx_SDRAM_DDR(dev); - sdram->addr = 0; - sdram->bear = 0; - sdram->besr0 = 0; /* No error */ - sdram->besr1 = 0; /* No error */ - sdram->cfg = 0; - sdram->ecccfg = 0; /* No ECC */ - sdram->eccesr = 0; /* No error */ - sdram->pmit = 0x07C00000; - sdram->rtr = 0x05F00000; - sdram->tr = 0x00854009; + s->addr = 0; + s->bear = 0; + s->besr0 = 0; /* No error */ + s->besr1 = 0; /* No error */ + s->cfg = 0; + s->ecccfg = 0; /* No ECC */ + s->eccesr = 0; /* No error */ + s->pmit = 0x07C00000; + s->rtr = 0x05F00000; + s->tr = 0x00854009; /* We pre-initialize RAM banks */ - sdram->status = 0; - sdram->cfg = 0x00800000; + s->status = 0; + s->cfg = 0x00800000; } static void ppc4xx_sdram_ddr_realize(DeviceState *dev, Error **errp) @@ -572,7 +572,7 @@ static void sdram_ddr2_unmap_bcr(Ppc4xxSdramDdr2State *sdram) static uint32_t sdram_ddr2_dcr_read(void *opaque, int dcrn) { - Ppc4xxSdramDdr2State *sdram = opaque; + Ppc4xxSdramDdr2State *s = opaque; uint32_t ret = 0; switch (dcrn) { @@ -580,9 +580,9 @@ static uint32_t sdram_ddr2_dcr_read(void *opaque, int dcrn) case SDRAM_R1BAS: case SDRAM_R2BAS: case SDRAM_R3BAS: - if (sdram->bank[dcrn - SDRAM_R0BAS].size) { - ret = sdram_ddr2_bcr(sdram->bank[dcrn - SDRAM_R0BAS].base, - sdram->bank[dcrn - SDRAM_R0BAS].size); + if (s->bank[dcrn - SDRAM_R0BAS].size) { + ret = sdram_ddr2_bcr(s->bank[dcrn - SDRAM_R0BAS].base, + s->bank[dcrn - SDRAM_R0BAS].size); } break; case SDRAM_CONF1HB: @@ -592,16 +592,16 @@ static uint32_t sdram_ddr2_dcr_read(void *opaque, int dcrn) case SDRAM_PLBADDUHB: break; case SDRAM0_CFGADDR: - ret = sdram->addr; + ret = s->addr; break; case SDRAM0_CFGDATA: - switch (sdram->addr) { + switch (s->addr) { case 0x14: /* SDRAM_MCSTAT (405EX) */ case 0x1F: ret = 0x80000000; break; case 0x21: /* SDRAM_MCOPT2 */ - ret = sdram->mcopt2; + ret = s->mcopt2; break; case 0x40: /* SDRAM_MB0CF */ ret = 0x00008001; @@ -627,7 +627,7 @@ static uint32_t sdram_ddr2_dcr_read(void *opaque, int dcrn) static void sdram_ddr2_dcr_write(void *opaque, int dcrn, uint32_t val) { - Ppc4xxSdramDdr2State *sdram = opaque; + Ppc4xxSdramDdr2State *s = opaque; switch (dcrn) { case SDRAM_R0BAS: @@ -641,25 +641,25 @@ static void sdram_ddr2_dcr_write(void *opaque, int dcrn, uint32_t val) case SDRAM_PLBADDUHB: break; case SDRAM0_CFGADDR: - sdram->addr = val; + s->addr = val; break; case SDRAM0_CFGDATA: - switch (sdram->addr) { + switch (s->addr) { case 0x00: /* B0CR */ break; case 0x21: /* SDRAM_MCOPT2 */ - if (!(sdram->mcopt2 & SDRAM_DDR2_MCOPT2_DCEN) && + if (!(s->mcopt2 & SDRAM_DDR2_MCOPT2_DCEN) && (val & SDRAM_DDR2_MCOPT2_DCEN)) { trace_ppc4xx_sdram_enable("enable"); /* validate all RAM mappings */ - sdram_ddr2_map_bcr(sdram); - sdram->mcopt2 |= SDRAM_DDR2_MCOPT2_DCEN; - } else if ((sdram->mcopt2 & SDRAM_DDR2_MCOPT2_DCEN) && + sdram_ddr2_map_bcr(s); + s->mcopt2 |= SDRAM_DDR2_MCOPT2_DCEN; + } else if ((s->mcopt2 & SDRAM_DDR2_MCOPT2_DCEN) && !(val & SDRAM_DDR2_MCOPT2_DCEN)) { trace_ppc4xx_sdram_enable("disable"); /* invalidate all RAM mappings */ - sdram_ddr2_unmap_bcr(sdram); - sdram->mcopt2 &= ~SDRAM_DDR2_MCOPT2_DCEN; + sdram_ddr2_unmap_bcr(s); + s->mcopt2 &= ~SDRAM_DDR2_MCOPT2_DCEN; } break; default: @@ -673,10 +673,10 @@ static void sdram_ddr2_dcr_write(void *opaque, int dcrn, uint32_t val) static void ppc4xx_sdram_ddr2_reset(DeviceState *dev) { - Ppc4xxSdramDdr2State *sdram = PPC4xx_SDRAM_DDR2(dev); + Ppc4xxSdramDdr2State *s = PPC4xx_SDRAM_DDR2(dev); - sdram->addr = 0; - sdram->mcopt2 = 0; + s->addr = 0; + s->mcopt2 = 0; } static void ppc4xx_sdram_ddr2_realize(DeviceState *dev, Error **errp) From 424a660c58a6b950363d42b79a30e651c1037550 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Wed, 19 Oct 2022 18:02:57 +0200 Subject: [PATCH 389/705] ppc4xx_sdram: Generalise bank setup Currently only base and size are set on initial bank creation and bcr value is computed on mapping the region. Set bcr at init so the bcr encoding method becomes local to the controller model and mapping and unmapping can operate on the bank so it can be shared between different controller models. This patch converts the DDR2 controller. Signed-off-by: BALATON Zoltan Message-Id: <51b957b4b2d714a1072aa2589b979e08411640df.1666194485.git.balaton@eik.bme.hu> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/ppc4xx_sdram.c | 91 ++++++++++++++++++++++--------------------- hw/ppc/trace-events | 1 + 2 files changed, 48 insertions(+), 44 deletions(-) diff --git a/hw/ppc/ppc4xx_sdram.c b/hw/ppc/ppc4xx_sdram.c index 4bc53c8f01..63a33b8fd4 100644 --- a/hw/ppc/ppc4xx_sdram.c +++ b/hw/ppc/ppc4xx_sdram.c @@ -105,6 +105,7 @@ static void ppc4xx_sdram_banks(MemoryRegion *ram, int nr_banks, static void sdram_bank_map(Ppc4xxSdramBank *bank) { + trace_ppc4xx_sdram_map(bank->base, bank->size); memory_region_init(&bank->container, NULL, "sdram-container", bank->size); memory_region_add_subregion(&bank->container, 0, &bank->ram); memory_region_add_subregion(get_system_memory(), bank->base, @@ -113,11 +114,26 @@ static void sdram_bank_map(Ppc4xxSdramBank *bank) static void sdram_bank_unmap(Ppc4xxSdramBank *bank) { + trace_ppc4xx_sdram_unmap(bank->base, bank->size); memory_region_del_subregion(get_system_memory(), &bank->container); memory_region_del_subregion(&bank->container, &bank->ram); object_unparent(OBJECT(&bank->container)); } +static void sdram_bank_set_bcr(Ppc4xxSdramBank *bank, uint32_t bcr, + hwaddr base, hwaddr size, int enabled) +{ + if (memory_region_is_mapped(&bank->container)) { + sdram_bank_unmap(bank); + } + bank->bcr = bcr; + bank->base = base; + bank->size = size; + if (enabled && (bcr & 1)) { + sdram_bank_map(bank); + } +} + enum { SDRAM0_CFGADDR = 0x010, SDRAM0_CFGDATA = 0x011, @@ -455,6 +471,8 @@ void ppc4xx_sdram_ddr_enable(Ppc4xxSdramDdrState *s) /*****************************************************************************/ /* DDR2 SDRAM controller */ +#define SDRAM_DDR2_BCR_MASK 0xffe0ffc1 + enum { SDRAM_R0BAS = 0x40, SDRAM_R1BAS, @@ -528,48 +546,6 @@ static hwaddr sdram_ddr2_size(uint32_t bcr) return size; } -static void sdram_ddr2_set_bcr(Ppc4xxSdramDdr2State *sdram, int i, - uint32_t bcr, int enabled) -{ - if (sdram->bank[i].bcr & 1) { - /* First unmap RAM if enabled */ - trace_ppc4xx_sdram_unmap(sdram_ddr2_base(sdram->bank[i].bcr), - sdram_ddr2_size(sdram->bank[i].bcr)); - sdram_bank_unmap(&sdram->bank[i]); - } - sdram->bank[i].bcr = bcr & 0xffe0ffc1; - if (enabled && (bcr & 1)) { - trace_ppc4xx_sdram_map(sdram_ddr2_base(bcr), sdram_ddr2_size(bcr)); - sdram_bank_map(&sdram->bank[i]); - } -} - -static void sdram_ddr2_map_bcr(Ppc4xxSdramDdr2State *sdram) -{ - int i; - - for (i = 0; i < sdram->nbanks; i++) { - if (sdram->bank[i].size) { - sdram_ddr2_set_bcr(sdram, i, - sdram_ddr2_bcr(sdram->bank[i].base, - sdram->bank[i].size), 1); - } else { - sdram_ddr2_set_bcr(sdram, i, 0, 0); - } - } -} - -static void sdram_ddr2_unmap_bcr(Ppc4xxSdramDdr2State *sdram) -{ - int i; - - for (i = 0; i < sdram->nbanks; i++) { - if (sdram->bank[i].size) { - sdram_ddr2_set_bcr(sdram, i, sdram->bank[i].bcr & ~1, 0); - } - } -} - static uint32_t sdram_ddr2_dcr_read(void *opaque, int dcrn) { Ppc4xxSdramDdr2State *s = opaque; @@ -628,6 +604,7 @@ static uint32_t sdram_ddr2_dcr_read(void *opaque, int dcrn) static void sdram_ddr2_dcr_write(void *opaque, int dcrn, uint32_t val) { Ppc4xxSdramDdr2State *s = opaque; + int i; switch (dcrn) { case SDRAM_R0BAS: @@ -652,13 +629,25 @@ static void sdram_ddr2_dcr_write(void *opaque, int dcrn, uint32_t val) (val & SDRAM_DDR2_MCOPT2_DCEN)) { trace_ppc4xx_sdram_enable("enable"); /* validate all RAM mappings */ - sdram_ddr2_map_bcr(s); + for (i = 0; i < s->nbanks; i++) { + if (s->bank[i].size) { + sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr, + s->bank[i].base, s->bank[i].size, + 1); + } + } s->mcopt2 |= SDRAM_DDR2_MCOPT2_DCEN; } else if ((s->mcopt2 & SDRAM_DDR2_MCOPT2_DCEN) && !(val & SDRAM_DDR2_MCOPT2_DCEN)) { trace_ppc4xx_sdram_enable("disable"); /* invalidate all RAM mappings */ - sdram_ddr2_unmap_bcr(s); + for (i = 0; i < s->nbanks; i++) { + if (s->bank[i].size) { + sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr, + s->bank[i].base, s->bank[i].size, + 0); + } + } s->mcopt2 &= ~SDRAM_DDR2_MCOPT2_DCEN; } break; @@ -691,6 +680,7 @@ static void ppc4xx_sdram_ddr2_realize(DeviceState *dev, Error **errp) 2 * GiB, 1 * GiB, 512 * MiB, 256 * MiB, 128 * MiB, 64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 0 }; + int i; if (s->nbanks < 1 || s->nbanks > 4) { error_setg(errp, "Invalid number of RAM banks"); @@ -701,6 +691,19 @@ static void ppc4xx_sdram_ddr2_realize(DeviceState *dev, Error **errp) return; } ppc4xx_sdram_banks(s->dram_mr, s->nbanks, s->bank, valid_bank_sizes); + for (i = 0; i < s->nbanks; i++) { + if (s->bank[i].size) { + s->bank[i].bcr = sdram_ddr2_bcr(s->bank[i].base, s->bank[i].size); + s->bank[i].bcr &= SDRAM_DDR2_BCR_MASK; + sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr, + s->bank[i].base, s->bank[i].size, 0); + } else { + sdram_bank_set_bcr(&s->bank[i], 0, 0, 0, 0); + } + trace_ppc4xx_sdram_init(sdram_ddr2_base(s->bank[i].bcr), + sdram_ddr2_size(s->bank[i].bcr), + s->bank[i].bcr); + } ppc4xx_dcr_register(dcr, SDRAM0_CFGADDR, s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); diff --git a/hw/ppc/trace-events b/hw/ppc/trace-events index 956938ebcd..f670e8906c 100644 --- a/hw/ppc/trace-events +++ b/hw/ppc/trace-events @@ -179,3 +179,4 @@ ppc405ep_clocks_setup(const char *trace) "%s" ppc4xx_sdram_enable(const char *trace) "%s SDRAM controller" ppc4xx_sdram_unmap(uint64_t addr, uint64_t size) "Unmap RAM area 0x%" PRIx64 " size 0x%" PRIx64 ppc4xx_sdram_map(uint64_t addr, uint64_t size) "Map RAM area 0x%" PRIx64 " size 0x%" PRIx64 +ppc4xx_sdram_init(uint64_t base, uint64_t size, uint32_t bcr) "Init RAM area 0x%" PRIx64 " size 0x%" PRIx64 " bcr 0x%x" From 54a3527e427b7df33ffcea3ad0ab56f7a0a61dd9 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Wed, 19 Oct 2022 18:02:58 +0200 Subject: [PATCH 390/705] ppc4xx_sdram: Convert DDR SDRAM controller to new bank handling Use the generic bank handling introduced in previous patch in the DDR SDRAM controller too. This also fixes previously broken region unmap due to sdram_ddr_unmap_bcr() ignoring container region so it crashed with an assert when the guest tried to disable the controller. Signed-off-by: BALATON Zoltan Message-Id: Signed-off-by: Daniel Henrique Barboza --- hw/ppc/ppc4xx_sdram.c | 98 ++++++++++++++++--------------------------- 1 file changed, 37 insertions(+), 61 deletions(-) diff --git a/hw/ppc/ppc4xx_sdram.c b/hw/ppc/ppc4xx_sdram.c index 63a33b8fd4..7c097efe20 100644 --- a/hw/ppc/ppc4xx_sdram.c +++ b/hw/ppc/ppc4xx_sdram.c @@ -141,6 +141,8 @@ enum { /*****************************************************************************/ /* DDR SDRAM controller */ +#define SDRAM_DDR_BCR_MASK 0xFFDEE001 + static uint32_t sdram_ddr_bcr(hwaddr ram_base, hwaddr ram_size) { uint32_t bcr; @@ -199,58 +201,6 @@ static hwaddr sdram_ddr_size(uint32_t bcr) return size; } -static void sdram_ddr_set_bcr(Ppc4xxSdramDdrState *sdram, int i, - uint32_t bcr, int enabled) -{ - if (sdram->bank[i].bcr & 1) { - /* Unmap RAM */ - trace_ppc4xx_sdram_unmap(sdram_ddr_base(sdram->bank[i].bcr), - sdram_ddr_size(sdram->bank[i].bcr)); - memory_region_del_subregion(get_system_memory(), - &sdram->bank[i].container); - memory_region_del_subregion(&sdram->bank[i].container, - &sdram->bank[i].ram); - object_unparent(OBJECT(&sdram->bank[i].container)); - } - sdram->bank[i].bcr = bcr & 0xFFDEE001; - if (enabled && (bcr & 1)) { - trace_ppc4xx_sdram_map(sdram_ddr_base(bcr), sdram_ddr_size(bcr)); - memory_region_init(&sdram->bank[i].container, NULL, "sdram-container", - sdram_ddr_size(bcr)); - memory_region_add_subregion(&sdram->bank[i].container, 0, - &sdram->bank[i].ram); - memory_region_add_subregion(get_system_memory(), - sdram_ddr_base(bcr), - &sdram->bank[i].container); - } -} - -static void sdram_ddr_map_bcr(Ppc4xxSdramDdrState *sdram) -{ - int i; - - for (i = 0; i < sdram->nbanks; i++) { - if (sdram->bank[i].size != 0) { - sdram_ddr_set_bcr(sdram, i, sdram_ddr_bcr(sdram->bank[i].base, - sdram->bank[i].size), 1); - } else { - sdram_ddr_set_bcr(sdram, i, 0, 0); - } - } -} - -static void sdram_ddr_unmap_bcr(Ppc4xxSdramDdrState *sdram) -{ - int i; - - for (i = 0; i < sdram->nbanks; i++) { - trace_ppc4xx_sdram_unmap(sdram_ddr_base(sdram->bank[i].bcr), - sdram_ddr_size(sdram->bank[i].bcr)); - memory_region_del_subregion(get_system_memory(), - &sdram->bank[i].ram); - } -} - static uint32_t sdram_ddr_dcr_read(void *opaque, int dcrn) { Ppc4xxSdramDdrState *s = opaque; @@ -321,6 +271,7 @@ static uint32_t sdram_ddr_dcr_read(void *opaque, int dcrn) static void sdram_ddr_dcr_write(void *opaque, int dcrn, uint32_t val) { Ppc4xxSdramDdrState *s = opaque; + int i; switch (dcrn) { case SDRAM0_CFGADDR: @@ -342,12 +293,24 @@ static void sdram_ddr_dcr_write(void *opaque, int dcrn, uint32_t val) if (!(s->cfg & 0x80000000) && (val & 0x80000000)) { trace_ppc4xx_sdram_enable("enable"); /* validate all RAM mappings */ - sdram_ddr_map_bcr(s); + for (i = 0; i < s->nbanks; i++) { + if (s->bank[i].size) { + sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr, + s->bank[i].base, s->bank[i].size, + 1); + } + } s->status &= ~0x80000000; } else if ((s->cfg & 0x80000000) && !(val & 0x80000000)) { trace_ppc4xx_sdram_enable("disable"); /* invalidate all RAM mappings */ - sdram_ddr_unmap_bcr(s); + for (i = 0; i < s->nbanks; i++) { + if (s->bank[i].size) { + sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr, + s->bank[i].base, s->bank[i].size, + 0); + } + } s->status |= 0x80000000; } if (!(s->cfg & 0x40000000) && (val & 0x40000000)) { @@ -367,16 +330,16 @@ static void sdram_ddr_dcr_write(void *opaque, int dcrn, uint32_t val) s->pmit = (val & 0xF8000000) | 0x07C00000; break; case 0x40: /* SDRAM_B0CR */ - sdram_ddr_set_bcr(s, 0, val, s->cfg & 0x80000000); - break; case 0x44: /* SDRAM_B1CR */ - sdram_ddr_set_bcr(s, 1, val, s->cfg & 0x80000000); - break; case 0x48: /* SDRAM_B2CR */ - sdram_ddr_set_bcr(s, 2, val, s->cfg & 0x80000000); - break; case 0x4C: /* SDRAM_B3CR */ - sdram_ddr_set_bcr(s, 3, val, s->cfg & 0x80000000); + i = (s->addr - 0x40) / 4; + val &= SDRAM_DDR_BCR_MASK; + if (s->bank[i].size) { + sdram_bank_set_bcr(&s->bank[i], val, + sdram_ddr_base(val), sdram_ddr_size(val), + s->cfg & 0x80000000); + } break; case 0x80: /* SDRAM_TR */ s->tr = val & 0x018FC01F; @@ -426,6 +389,7 @@ static void ppc4xx_sdram_ddr_realize(DeviceState *dev, Error **errp) const ram_addr_t valid_bank_sizes[] = { 256 * MiB, 128 * MiB, 64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 4 * MiB, 0 }; + int i; if (s->nbanks < 1 || s->nbanks > 4) { error_setg(errp, "Invalid number of RAM banks"); @@ -436,6 +400,18 @@ static void ppc4xx_sdram_ddr_realize(DeviceState *dev, Error **errp) return; } ppc4xx_sdram_banks(s->dram_mr, s->nbanks, s->bank, valid_bank_sizes); + for (i = 0; i < s->nbanks; i++) { + if (s->bank[i].size) { + s->bank[i].bcr = sdram_ddr_bcr(s->bank[i].base, s->bank[i].size); + sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr, + s->bank[i].base, s->bank[i].size, 0); + } else { + sdram_bank_set_bcr(&s->bank[i], 0, 0, 0, 0); + } + trace_ppc4xx_sdram_init(sdram_ddr_base(s->bank[i].bcr), + sdram_ddr_size(s->bank[i].bcr), + s->bank[i].bcr); + } sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq); From 286787f105c3216028841fd86c4e563af6b1b9e0 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Wed, 19 Oct 2022 18:02:59 +0200 Subject: [PATCH 391/705] ppc4xx_sdram: Add errp parameter to ppc4xx_sdram_banks() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do not exit from ppc4xx_sdram_banks() but report error via an errp parameter instead. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Message-Id: <04bb3445439c2f37b99e74b3fdf4e62c2e6f7e04.1666194485.git.balaton@eik.bme.hu> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/ppc4xx_sdram.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/hw/ppc/ppc4xx_sdram.c b/hw/ppc/ppc4xx_sdram.c index 7c097efe20..8d7137faf3 100644 --- a/hw/ppc/ppc4xx_sdram.c +++ b/hw/ppc/ppc4xx_sdram.c @@ -52,10 +52,12 @@ * must be one of a small set of sizes. The number of banks and the supported * sizes varies by SoC. */ -static void ppc4xx_sdram_banks(MemoryRegion *ram, int nr_banks, +static bool ppc4xx_sdram_banks(MemoryRegion *ram, int nr_banks, Ppc4xxSdramBank ram_banks[], - const ram_addr_t sdram_bank_sizes[]) + const ram_addr_t sdram_bank_sizes[], + Error **errp) { + ERRP_GUARD(); ram_addr_t size_left = memory_region_size(ram); ram_addr_t base = 0; ram_addr_t bank_size; @@ -93,14 +95,16 @@ static void ppc4xx_sdram_banks(MemoryRegion *ram, int nr_banks, sdram_bank_sizes[i] / MiB, sdram_bank_sizes[i + 1] ? ", " : ""); } - error_report("at most %d bank%s of %s MiB each supported", - nr_banks, nr_banks == 1 ? "" : "s", s->str); - error_printf("Possible valid RAM size: %" PRIi64 " MiB\n", - used_size ? used_size / MiB : sdram_bank_sizes[i - 1] / MiB); + error_setg(errp, "Invalid SDRAM banks"); + error_append_hint(errp, "at most %d bank%s of %s MiB each supported\n", + nr_banks, nr_banks == 1 ? "" : "s", s->str); + error_append_hint(errp, "Possible valid RAM size: %" PRIi64 " MiB\n", + used_size ? used_size / MiB : sdram_bank_sizes[i - 1] / MiB); g_string_free(s, true); - exit(EXIT_FAILURE); + return false; } + return true; } static void sdram_bank_map(Ppc4xxSdramBank *bank) @@ -399,7 +403,10 @@ static void ppc4xx_sdram_ddr_realize(DeviceState *dev, Error **errp) error_setg(errp, "Missing dram memory region"); return; } - ppc4xx_sdram_banks(s->dram_mr, s->nbanks, s->bank, valid_bank_sizes); + if (!ppc4xx_sdram_banks(s->dram_mr, s->nbanks, s->bank, + valid_bank_sizes, errp)) { + return; + } for (i = 0; i < s->nbanks; i++) { if (s->bank[i].size) { s->bank[i].bcr = sdram_ddr_bcr(s->bank[i].base, s->bank[i].size); @@ -666,7 +673,10 @@ static void ppc4xx_sdram_ddr2_realize(DeviceState *dev, Error **errp) error_setg(errp, "Missing dram memory region"); return; } - ppc4xx_sdram_banks(s->dram_mr, s->nbanks, s->bank, valid_bank_sizes); + if (!ppc4xx_sdram_banks(s->dram_mr, s->nbanks, s->bank, + valid_bank_sizes, errp)) { + return; + } for (i = 0; i < s->nbanks; i++) { if (s->bank[i].size) { s->bank[i].bcr = sdram_ddr2_bcr(s->bank[i].base, s->bank[i].size); From 8b3d1c49a9f0f315d2b292c1791430c0f382afa4 Mon Sep 17 00:00:00 2001 From: Leandro Lupori Date: Tue, 25 Oct 2022 17:24:23 -0300 Subject: [PATCH 392/705] target/ppc: Add new PMC HFLAGS Add 2 new PMC related HFLAGS: - HFLAGS_PMCJCE - value of MMCR0 PMCjCE bit - HFLAGS_PMC_OTHER - set if a PMC other than PMC5-6 is enabled These flags allow further optimization of PMC5 update code, by allowing frequently tested conditions to be performed at translation time. Signed-off-by: Leandro Lupori Reviewed-by: Daniel Henrique Barboza Message-Id: <20221025202424.195984-3-leandro.lupori@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/cpu.h | 4 +++- target/ppc/helper_regs.c | 6 ++++++ target/ppc/translate.c | 4 ++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index cc2d0305ff..81d4263a07 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -696,7 +696,9 @@ enum { HFLAGS_PR = 14, /* MSR_PR */ HFLAGS_PMCC0 = 15, /* MMCR0 PMCC bit 0 */ HFLAGS_PMCC1 = 16, /* MMCR0 PMCC bit 1 */ - HFLAGS_INSN_CNT = 17, /* PMU instruction count enabled */ + HFLAGS_PMCJCE = 17, /* MMCR0 PMCjCE bit */ + HFLAGS_PMC_OTHER = 18, /* PMC other than PMC5-6 is enabled */ + HFLAGS_INSN_CNT = 19, /* PMU instruction count enabled */ HFLAGS_VSX = 23, /* MSR_VSX if cpu has VSX */ HFLAGS_VR = 25, /* MSR_VR if cpu has VRE */ diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c index 2e85e124ab..c0aee5855b 100644 --- a/target/ppc/helper_regs.c +++ b/target/ppc/helper_regs.c @@ -109,6 +109,9 @@ static uint32_t hreg_compute_hflags_value(CPUPPCState *env) if (env->spr[SPR_POWER_MMCR0] & MMCR0_PMCC1) { hflags |= 1 << HFLAGS_PMCC1; } + if (env->spr[SPR_POWER_MMCR0] & MMCR0_PMCjCE) { + hflags |= 1 << HFLAGS_PMCJCE; + } #ifndef CONFIG_USER_ONLY if (!env->has_hv_mode || (msr & (1ull << MSR_HV))) { @@ -119,6 +122,9 @@ static uint32_t hreg_compute_hflags_value(CPUPPCState *env) if (env->pmc_ins_cnt) { hflags |= 1 << HFLAGS_INSN_CNT; } + if (env->pmc_ins_cnt & 0x1e) { + hflags |= 1 << HFLAGS_PMC_OTHER; + } #endif /* diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 29e4b728e2..8d79522f98 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -177,6 +177,8 @@ struct DisasContext { bool hr; bool mmcr0_pmcc0; bool mmcr0_pmcc1; + bool mmcr0_pmcjce; + bool pmc_other; bool pmu_insn_cnt; ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */ int singlestep_enabled; @@ -7512,6 +7514,8 @@ static void ppc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) ctx->hr = (hflags >> HFLAGS_HR) & 1; ctx->mmcr0_pmcc0 = (hflags >> HFLAGS_PMCC0) & 1; ctx->mmcr0_pmcc1 = (hflags >> HFLAGS_PMCC1) & 1; + ctx->mmcr0_pmcjce = (hflags >> HFLAGS_PMCJCE) & 1; + ctx->pmc_other = (hflags >> HFLAGS_PMC_OTHER) & 1; ctx->pmu_insn_cnt = (hflags >> HFLAGS_INSN_CNT) & 1; ctx->singlestep_enabled = 0; From eeaaefe9fa8b95a7ed39ee86257f3bf1af751804 Mon Sep 17 00:00:00 2001 From: Leandro Lupori Date: Tue, 25 Oct 2022 17:24:24 -0300 Subject: [PATCH 393/705] target/ppc: Increment PMC5 with inline insns Profiling QEMU during Fedora 35 for PPC64 boot revealed that 6.39% of total time was being spent in helper_insns_inc(), on a POWER9 machine. To avoid calling this helper every time PMCs had to be incremented, an inline implementation of PMC5 increment and check for overflow was developed. This led to a reduction of about 12% in Fedora's boot time. Signed-off-by: Leandro Lupori Reviewed-by: Daniel Henrique Barboza Message-Id: <20221025202424.195984-4-leandro.lupori@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/helper.h | 1 + target/ppc/power8-pmu.c | 78 +++++++++++++++++++++-------------------- target/ppc/power8-pmu.h | 3 ++ target/ppc/translate.c | 28 +++++++++++++-- 4 files changed, 69 insertions(+), 41 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 25533b8f33..8dd22a35e4 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -30,6 +30,7 @@ DEF_HELPER_2(store_mmcr1, void, env, tl) DEF_HELPER_3(store_pmc, void, env, i32, i64) DEF_HELPER_2(read_pmc, tl, env, i32) DEF_HELPER_2(insns_inc, void, env, i32) +DEF_HELPER_1(handle_pmc5_overflow, void, env) #endif DEF_HELPER_1(check_tlb_flush_local, void, env) DEF_HELPER_1(check_tlb_flush_global, void, env) diff --git a/target/ppc/power8-pmu.c b/target/ppc/power8-pmu.c index beeab5c494..1381072b9e 100644 --- a/target/ppc/power8-pmu.c +++ b/target/ppc/power8-pmu.c @@ -22,8 +22,6 @@ #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) -#define PMC_COUNTER_NEGATIVE_VAL 0x80000000UL - static bool pmc_has_overflow_enabled(CPUPPCState *env, int sprn) { if (sprn == SPR_POWER_PMC1) { @@ -88,49 +86,47 @@ static bool pmu_increment_insns(CPUPPCState *env, uint32_t num_insns) bool overflow_triggered = false; target_ulong tmp; - if (unlikely(ins_cnt & 0x1e)) { - if (ins_cnt & (1 << 1)) { - tmp = env->spr[SPR_POWER_PMC1]; - tmp += num_insns; - if (tmp >= PMC_COUNTER_NEGATIVE_VAL && (mmcr0 & MMCR0_PMC1CE)) { - tmp = PMC_COUNTER_NEGATIVE_VAL; - overflow_triggered = true; - } - env->spr[SPR_POWER_PMC1] = tmp; + if (ins_cnt & (1 << 1)) { + tmp = env->spr[SPR_POWER_PMC1]; + tmp += num_insns; + if (tmp >= PMC_COUNTER_NEGATIVE_VAL && (mmcr0 & MMCR0_PMC1CE)) { + tmp = PMC_COUNTER_NEGATIVE_VAL; + overflow_triggered = true; } + env->spr[SPR_POWER_PMC1] = tmp; + } - if (ins_cnt & (1 << 2)) { - tmp = env->spr[SPR_POWER_PMC2]; + if (ins_cnt & (1 << 2)) { + tmp = env->spr[SPR_POWER_PMC2]; + tmp += num_insns; + if (tmp >= PMC_COUNTER_NEGATIVE_VAL && (mmcr0 & MMCR0_PMCjCE)) { + tmp = PMC_COUNTER_NEGATIVE_VAL; + overflow_triggered = true; + } + env->spr[SPR_POWER_PMC2] = tmp; + } + + if (ins_cnt & (1 << 3)) { + tmp = env->spr[SPR_POWER_PMC3]; + tmp += num_insns; + if (tmp >= PMC_COUNTER_NEGATIVE_VAL && (mmcr0 & MMCR0_PMCjCE)) { + tmp = PMC_COUNTER_NEGATIVE_VAL; + overflow_triggered = true; + } + env->spr[SPR_POWER_PMC3] = tmp; + } + + if (ins_cnt & (1 << 4)) { + target_ulong mmcr1 = env->spr[SPR_POWER_MMCR1]; + int sel = extract64(mmcr1, MMCR1_PMC4EVT_EXTR, MMCR1_EVT_SIZE); + if (sel == 0x02 || (env->spr[SPR_CTRL] & CTRL_RUN)) { + tmp = env->spr[SPR_POWER_PMC4]; tmp += num_insns; if (tmp >= PMC_COUNTER_NEGATIVE_VAL && (mmcr0 & MMCR0_PMCjCE)) { tmp = PMC_COUNTER_NEGATIVE_VAL; overflow_triggered = true; } - env->spr[SPR_POWER_PMC2] = tmp; - } - - if (ins_cnt & (1 << 3)) { - tmp = env->spr[SPR_POWER_PMC3]; - tmp += num_insns; - if (tmp >= PMC_COUNTER_NEGATIVE_VAL && (mmcr0 & MMCR0_PMCjCE)) { - tmp = PMC_COUNTER_NEGATIVE_VAL; - overflow_triggered = true; - } - env->spr[SPR_POWER_PMC3] = tmp; - } - - if (ins_cnt & (1 << 4)) { - target_ulong mmcr1 = env->spr[SPR_POWER_MMCR1]; - int sel = extract64(mmcr1, MMCR1_PMC4EVT_EXTR, MMCR1_EVT_SIZE); - if (sel == 0x02 || (env->spr[SPR_CTRL] & CTRL_RUN)) { - tmp = env->spr[SPR_POWER_PMC4]; - tmp += num_insns; - if (tmp >= PMC_COUNTER_NEGATIVE_VAL && (mmcr0 & MMCR0_PMCjCE)) { - tmp = PMC_COUNTER_NEGATIVE_VAL; - overflow_triggered = true; - } - env->spr[SPR_POWER_PMC4] = tmp; - } + env->spr[SPR_POWER_PMC4] = tmp; } } @@ -310,6 +306,12 @@ static void fire_PMC_interrupt(PowerPCCPU *cpu) raise_ebb_perfm_exception(env); } +void helper_handle_pmc5_overflow(CPUPPCState *env) +{ + env->spr[SPR_POWER_PMC5] = PMC_COUNTER_NEGATIVE_VAL; + fire_PMC_interrupt(env_archcpu(env)); +} + /* This helper assumes that the PMC is running. */ void helper_insns_inc(CPUPPCState *env, uint32_t num_insns) { diff --git a/target/ppc/power8-pmu.h b/target/ppc/power8-pmu.h index 9692dd765e..c0093e2219 100644 --- a/target/ppc/power8-pmu.h +++ b/target/ppc/power8-pmu.h @@ -14,6 +14,9 @@ #define POWER8_PMU_H #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) + +#define PMC_COUNTER_NEGATIVE_VAL 0x80000000UL + void cpu_ppc_pmu_init(CPUPPCState *env); void pmu_update_summaries(CPUPPCState *env); #else diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 8d79522f98..19c1d17cb0 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -36,6 +36,7 @@ #include "exec/log.h" #include "qemu/atomic128.h" #include "spr_common.h" +#include "power8-pmu.h" #include "qemu/qemu-print.h" #include "qapi/error.h" @@ -4271,6 +4272,9 @@ static void pmu_count_insns(DisasContext *ctx) } #if !defined(CONFIG_USER_ONLY) + TCGLabel *l; + TCGv t0; + /* * The PMU insns_inc() helper stops the internal PMU timer if a * counter overflows happens. In that case, if the guest is @@ -4279,8 +4283,26 @@ static void pmu_count_insns(DisasContext *ctx) */ gen_icount_io_start(ctx); - gen_helper_insns_inc(cpu_env, tcg_constant_i32(ctx->base.num_insns)); -#else + /* Avoid helper calls when only PMC5-6 are enabled. */ + if (!ctx->pmc_other) { + l = gen_new_label(); + t0 = tcg_temp_new(); + + gen_load_spr(t0, SPR_POWER_PMC5); + tcg_gen_addi_tl(t0, t0, ctx->base.num_insns); + gen_store_spr(SPR_POWER_PMC5, t0); + /* Check for overflow, if it's enabled */ + if (ctx->mmcr0_pmcjce) { + tcg_gen_brcondi_tl(TCG_COND_LT, t0, PMC_COUNTER_NEGATIVE_VAL, l); + gen_helper_handle_pmc5_overflow(cpu_env); + } + + gen_set_label(l); + tcg_temp_free(t0); + } else { + gen_helper_insns_inc(cpu_env, tcg_constant_i32(ctx->base.num_insns)); + } + #else /* * User mode can read (but not write) PMC5 and start/stop * the PMU via MMCR0_FC. In this case just increment @@ -4293,7 +4315,7 @@ static void pmu_count_insns(DisasContext *ctx) gen_store_spr(SPR_POWER_PMC5, t0); tcg_temp_free(t0); -#endif /* #if !defined(CONFIG_USER_ONLY) */ + #endif /* #if !defined(CONFIG_USER_ONLY) */ } #else static void pmu_count_insns(DisasContext *ctx) From c593d1cc2555c5fe6a6a558f4d2bdc3bfd6713de Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Tue, 18 Oct 2022 23:01:40 +0200 Subject: [PATCH 394/705] docs/system/ppc/ppce500: Use qemu-system-ppc64 across the board(s) The documentation suggests that there is a qemu-system-ppc32 binary while the 32 bit version is actually just named qemu-system-ppc. Settle on qemu-system-ppc64 which also works for 32 bit machines and causes less clutter in the documentation. Found-by: BALATON Zoltan Suggested-by: Bin Meng Reviewed-by: Daniel Henrique Barboza Signed-off-by: Bernhard Beschow Message-Id: <20221018210146.193159-2-shentey@gmail.com> Signed-off-by: Daniel Henrique Barboza --- docs/system/ppc/ppce500.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/system/ppc/ppce500.rst b/docs/system/ppc/ppce500.rst index ba6bcb7314..7b5eb3c4ee 100644 --- a/docs/system/ppc/ppce500.rst +++ b/docs/system/ppc/ppce500.rst @@ -113,7 +113,7 @@ To boot the 32-bit Linux kernel: .. code-block:: bash - $ qemu-system-ppc{64|32} -M ppce500 -cpu e500mc -smp 4 -m 2G \ + $ qemu-system-ppc64 -M ppce500 -cpu e500mc -smp 4 -m 2G \ -display none -serial stdio \ -kernel vmlinux \ -initrd /path/to/rootfs.cpio \ @@ -154,10 +154,10 @@ interface at PCI address 0.1.0, but we can switch that to an e1000 NIC by: .. code-block:: bash - $ qemu-system-ppc -M ppce500 -smp 4 -m 2G \ - -display none -serial stdio \ - -bios u-boot \ - -nic tap,ifname=tap0,script=no,downscript=no,model=e1000 + $ qemu-system-ppc64 -M ppce500 -smp 4 -m 2G \ + -display none -serial stdio \ + -bios u-boot \ + -nic tap,ifname=tap0,script=no,downscript=no,model=e1000 The QEMU ``ppce500`` machine can also dynamically instantiate an eTSEC device if “-device eTSEC” is given to QEMU: From 334c388f25707a234c4a0dea05b9df08d7746638 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Tue, 18 Oct 2022 23:01:41 +0200 Subject: [PATCH 395/705] hw/block/pflash_cfi0{1, 2}: Error out if device length isn't a power of two MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to the JEDEC standard the device length is communicated to an OS as an exponent (power of two). Signed-off-by: Bernhard Beschow Reviewed-by: Bin Meng Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20221018210146.193159-3-shentey@gmail.com> Signed-off-by: Daniel Henrique Barboza --- hw/block/pflash_cfi01.c | 8 ++++++-- hw/block/pflash_cfi02.c | 5 +++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c index 0cbc2fb4cb..9c235bf66e 100644 --- a/hw/block/pflash_cfi01.c +++ b/hw/block/pflash_cfi01.c @@ -690,7 +690,7 @@ static const MemoryRegionOps pflash_cfi01_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -static void pflash_cfi01_fill_cfi_table(PFlashCFI01 *pfl) +static void pflash_cfi01_fill_cfi_table(PFlashCFI01 *pfl, Error **errp) { uint64_t blocks_per_device, sector_len_per_device, device_len; int num_devices; @@ -708,6 +708,10 @@ static void pflash_cfi01_fill_cfi_table(PFlashCFI01 *pfl) sector_len_per_device = pfl->sector_len / num_devices; } device_len = sector_len_per_device * blocks_per_device; + if (!is_power_of_2(device_len)) { + error_setg(errp, "Device size must be a power of two."); + return; + } /* Hardcoded CFI table */ /* Standard "QRY" string */ @@ -865,7 +869,7 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp) */ pfl->cmd = 0x00; pfl->status = 0x80; /* WSM ready */ - pflash_cfi01_fill_cfi_table(pfl); + pflash_cfi01_fill_cfi_table(pfl, errp); } static void pflash_cfi01_system_reset(DeviceState *dev) diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c index 2a99b286b0..ff2fe154c1 100644 --- a/hw/block/pflash_cfi02.c +++ b/hw/block/pflash_cfi02.c @@ -880,6 +880,11 @@ static void pflash_cfi02_realize(DeviceState *dev, Error **errp) return; } + if (!is_power_of_2(pfl->chip_len)) { + error_setg(errp, "Device size must be a power of two."); + return; + } + memory_region_init_rom_device(&pfl->orig_mem, OBJECT(pfl), &pflash_cfi02_ops, pfl, pfl->name, pfl->chip_len, errp); From c038e5745eca4851bb2ba515324f3e97c68f27ce Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Tue, 18 Oct 2022 23:01:42 +0200 Subject: [PATCH 396/705] hw/sd/sdhci-internal: Unexport ESDHC defines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These defines aren't used outside of sdhci.c, so can be defined there. Signed-off-by: Bernhard Beschow Reviewed-by: Bin Meng Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20221018210146.193159-4-shentey@gmail.com> Signed-off-by: Daniel Henrique Barboza --- hw/sd/sdhci-internal.h | 20 -------------------- hw/sd/sdhci.c | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/hw/sd/sdhci-internal.h b/hw/sd/sdhci-internal.h index e8c753d6d1..964570f8e8 100644 --- a/hw/sd/sdhci-internal.h +++ b/hw/sd/sdhci-internal.h @@ -288,26 +288,6 @@ enum { extern const VMStateDescription sdhci_vmstate; - -#define ESDHC_MIX_CTRL 0x48 - -#define ESDHC_VENDOR_SPEC 0xc0 -#define ESDHC_IMX_FRC_SDCLK_ON (1 << 8) - -#define ESDHC_DLL_CTRL 0x60 - -#define ESDHC_TUNING_CTRL 0xcc -#define ESDHC_TUNE_CTRL_STATUS 0x68 -#define ESDHC_WTMK_LVL 0x44 - -/* Undocumented register used by guests working around erratum ERR004536 */ -#define ESDHC_UNDOCUMENTED_REG27 0x6c - -#define ESDHC_CTRL_4BITBUS (0x1 << 1) -#define ESDHC_CTRL_8BITBUS (0x2 << 1) - -#define ESDHC_PRNSTS_SDSTB (1 << 3) - /* * Default SD/MMC host controller features information, which will be * presented in CAPABILITIES register of generic SD host controller at reset. diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c index 0e5e988927..6da5e2c781 100644 --- a/hw/sd/sdhci.c +++ b/hw/sd/sdhci.c @@ -1577,6 +1577,25 @@ static const TypeInfo sdhci_bus_info = { /* --- qdev i.MX eSDHC --- */ +#define ESDHC_MIX_CTRL 0x48 + +#define ESDHC_VENDOR_SPEC 0xc0 +#define ESDHC_IMX_FRC_SDCLK_ON (1 << 8) + +#define ESDHC_DLL_CTRL 0x60 + +#define ESDHC_TUNING_CTRL 0xcc +#define ESDHC_TUNE_CTRL_STATUS 0x68 +#define ESDHC_WTMK_LVL 0x44 + +/* Undocumented register used by guests working around erratum ERR004536 */ +#define ESDHC_UNDOCUMENTED_REG27 0x6c + +#define ESDHC_CTRL_4BITBUS (0x1 << 1) +#define ESDHC_CTRL_8BITBUS (0x2 << 1) + +#define ESDHC_PRNSTS_SDSTB (1 << 3) + static uint64_t usdhc_read(void *opaque, hwaddr offset, unsigned size) { SDHCIState *s = SYSBUS_SDHCI(opaque); From 1e76667f7adf48c6c3596aaa26b8886b57b8498d Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Tue, 18 Oct 2022 23:01:43 +0200 Subject: [PATCH 397/705] hw/sd/sdhci: Rename ESDHC_* defines to USDHC_* The device model's functions start with "usdhc_", so rename the defines accordingly for consistency. Signed-off-by: Bernhard Beschow Reviewed-by: Bin Meng Message-Id: <20221018210146.193159-5-shentey@gmail.com> Signed-off-by: Daniel Henrique Barboza --- hw/sd/sdhci.c | 66 +++++++++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c index 6da5e2c781..306070c872 100644 --- a/hw/sd/sdhci.c +++ b/hw/sd/sdhci.c @@ -1577,24 +1577,24 @@ static const TypeInfo sdhci_bus_info = { /* --- qdev i.MX eSDHC --- */ -#define ESDHC_MIX_CTRL 0x48 +#define USDHC_MIX_CTRL 0x48 -#define ESDHC_VENDOR_SPEC 0xc0 -#define ESDHC_IMX_FRC_SDCLK_ON (1 << 8) +#define USDHC_VENDOR_SPEC 0xc0 +#define USDHC_IMX_FRC_SDCLK_ON (1 << 8) -#define ESDHC_DLL_CTRL 0x60 +#define USDHC_DLL_CTRL 0x60 -#define ESDHC_TUNING_CTRL 0xcc -#define ESDHC_TUNE_CTRL_STATUS 0x68 -#define ESDHC_WTMK_LVL 0x44 +#define USDHC_TUNING_CTRL 0xcc +#define USDHC_TUNE_CTRL_STATUS 0x68 +#define USDHC_WTMK_LVL 0x44 /* Undocumented register used by guests working around erratum ERR004536 */ -#define ESDHC_UNDOCUMENTED_REG27 0x6c +#define USDHC_UNDOCUMENTED_REG27 0x6c -#define ESDHC_CTRL_4BITBUS (0x1 << 1) -#define ESDHC_CTRL_8BITBUS (0x2 << 1) +#define USDHC_CTRL_4BITBUS (0x1 << 1) +#define USDHC_CTRL_8BITBUS (0x2 << 1) -#define ESDHC_PRNSTS_SDSTB (1 << 3) +#define USDHC_PRNSTS_SDSTB (1 << 3) static uint64_t usdhc_read(void *opaque, hwaddr offset, unsigned size) { @@ -1615,11 +1615,11 @@ static uint64_t usdhc_read(void *opaque, hwaddr offset, unsigned size) hostctl1 = SDHC_DMA_TYPE(s->hostctl1) << (8 - 3); if (s->hostctl1 & SDHC_CTRL_8BITBUS) { - hostctl1 |= ESDHC_CTRL_8BITBUS; + hostctl1 |= USDHC_CTRL_8BITBUS; } if (s->hostctl1 & SDHC_CTRL_4BITBUS) { - hostctl1 |= ESDHC_CTRL_4BITBUS; + hostctl1 |= USDHC_CTRL_4BITBUS; } ret = hostctl1; @@ -1630,21 +1630,21 @@ static uint64_t usdhc_read(void *opaque, hwaddr offset, unsigned size) case SDHC_PRNSTS: /* Add SDSTB (SD Clock Stable) bit to PRNSTS */ - ret = sdhci_read(opaque, offset, size) & ~ESDHC_PRNSTS_SDSTB; + ret = sdhci_read(opaque, offset, size) & ~USDHC_PRNSTS_SDSTB; if (s->clkcon & SDHC_CLOCK_INT_STABLE) { - ret |= ESDHC_PRNSTS_SDSTB; + ret |= USDHC_PRNSTS_SDSTB; } break; - case ESDHC_VENDOR_SPEC: + case USDHC_VENDOR_SPEC: ret = s->vendor_spec; break; - case ESDHC_DLL_CTRL: - case ESDHC_TUNE_CTRL_STATUS: - case ESDHC_UNDOCUMENTED_REG27: - case ESDHC_TUNING_CTRL: - case ESDHC_MIX_CTRL: - case ESDHC_WTMK_LVL: + case USDHC_DLL_CTRL: + case USDHC_TUNE_CTRL_STATUS: + case USDHC_UNDOCUMENTED_REG27: + case USDHC_TUNING_CTRL: + case USDHC_MIX_CTRL: + case USDHC_WTMK_LVL: ret = 0; break; } @@ -1660,18 +1660,18 @@ usdhc_write(void *opaque, hwaddr offset, uint64_t val, unsigned size) uint32_t value = (uint32_t)val; switch (offset) { - case ESDHC_DLL_CTRL: - case ESDHC_TUNE_CTRL_STATUS: - case ESDHC_UNDOCUMENTED_REG27: - case ESDHC_TUNING_CTRL: - case ESDHC_WTMK_LVL: + case USDHC_DLL_CTRL: + case USDHC_TUNE_CTRL_STATUS: + case USDHC_UNDOCUMENTED_REG27: + case USDHC_TUNING_CTRL: + case USDHC_WTMK_LVL: break; - case ESDHC_VENDOR_SPEC: + case USDHC_VENDOR_SPEC: s->vendor_spec = value; switch (s->vendor) { case SDHCI_VENDOR_IMX: - if (value & ESDHC_IMX_FRC_SDCLK_ON) { + if (value & USDHC_IMX_FRC_SDCLK_ON) { s->prnsts &= ~SDHC_IMX_CLOCK_GATE_OFF; } else { s->prnsts |= SDHC_IMX_CLOCK_GATE_OFF; @@ -1740,12 +1740,12 @@ usdhc_write(void *opaque, hwaddr offset, uint64_t val, unsigned size) * Second, split "Data Transfer Width" from bits 2 and 1 in to * bits 5 and 1 */ - if (value & ESDHC_CTRL_8BITBUS) { + if (value & USDHC_CTRL_8BITBUS) { hostctl1 |= SDHC_CTRL_8BITBUS; } - if (value & ESDHC_CTRL_4BITBUS) { - hostctl1 |= ESDHC_CTRL_4BITBUS; + if (value & USDHC_CTRL_4BITBUS) { + hostctl1 |= USDHC_CTRL_4BITBUS; } /* @@ -1768,7 +1768,7 @@ usdhc_write(void *opaque, hwaddr offset, uint64_t val, unsigned size) sdhci_write(opaque, offset, value, size); break; - case ESDHC_MIX_CTRL: + case USDHC_MIX_CTRL: /* * So, when SD/MMC stack in Linux tries to write to "Transfer * Mode Register", ESDHC i.MX quirk code will translate it From 63e4bf8e84721231ea447b0e4afcb0a4378763c2 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Tue, 18 Oct 2022 23:01:44 +0200 Subject: [PATCH 398/705] hw/ppc/e500: Implement pflash handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allows e500 boards to have their root file system reside on flash using only builtin devices located in the eLBC memory region. Note that the flash memory area is only created when a -pflash argument is given, and that the size is determined by the given file. The idea is to put users into control. Signed-off-by: Bernhard Beschow Reviewed-by: Daniel Henrique Barboza Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20221018210146.193159-6-shentey@gmail.com> [danielhb: use memory_region_size() in mmio_size] Signed-off-by: Daniel Henrique Barboza --- docs/system/ppc/ppce500.rst | 15 +++++++ hw/ppc/Kconfig | 1 + hw/ppc/e500.c | 79 +++++++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+) diff --git a/docs/system/ppc/ppce500.rst b/docs/system/ppc/ppce500.rst index 7b5eb3c4ee..fa40e57d18 100644 --- a/docs/system/ppc/ppce500.rst +++ b/docs/system/ppc/ppce500.rst @@ -165,3 +165,18 @@ if “-device eTSEC” is given to QEMU: .. code-block:: bash -netdev tap,ifname=tap0,script=no,downscript=no,id=net0 -device eTSEC,netdev=net0 + +Root file system on flash drive +------------------------------- + +Rather than using a root file system on ram disk, it is possible to have it on +CFI flash. Given an ext2 image whose size must be a power of two, it can be used +as follows: + +.. code-block:: bash + + $ qemu-system-ppc64 -M ppce500 -cpu e500mc -smp 4 -m 2G \ + -display none -serial stdio \ + -kernel vmlinux \ + -drive if=pflash,file=/path/to/rootfs.ext2,format=raw \ + -append "rootwait root=/dev/mtdblock0" diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig index 791fe78a50..769a1ead1c 100644 --- a/hw/ppc/Kconfig +++ b/hw/ppc/Kconfig @@ -126,6 +126,7 @@ config E500 select ETSEC select GPIO_MPC8XXX select OPENPIC + select PFLASH_CFI01 select PLATFORM_BUS select PPCE500_PCI select SERIAL diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c index 3e950ea3ba..2fe496677c 100644 --- a/hw/ppc/e500.c +++ b/hw/ppc/e500.c @@ -23,8 +23,10 @@ #include "e500-ccsr.h" #include "net/net.h" #include "qemu/config-file.h" +#include "hw/block/flash.h" #include "hw/char/serial.h" #include "hw/pci/pci.h" +#include "sysemu/block-backend-io.h" #include "sysemu/sysemu.h" #include "sysemu/kvm.h" #include "sysemu/reset.h" @@ -267,6 +269,31 @@ static void sysbus_device_create_devtree(SysBusDevice *sbdev, void *opaque) } } +static void create_devtree_flash(SysBusDevice *sbdev, + PlatformDevtreeData *data) +{ + g_autofree char *name = NULL; + uint64_t num_blocks = object_property_get_uint(OBJECT(sbdev), + "num-blocks", + &error_fatal); + uint64_t sector_length = object_property_get_uint(OBJECT(sbdev), + "sector-length", + &error_fatal); + uint64_t bank_width = object_property_get_uint(OBJECT(sbdev), + "width", + &error_fatal); + hwaddr flashbase = 0; + hwaddr flashsize = num_blocks * sector_length; + void *fdt = data->fdt; + + name = g_strdup_printf("%s/nor@%" PRIx64, data->node, flashbase); + qemu_fdt_add_subnode(fdt, name); + qemu_fdt_setprop_string(fdt, name, "compatible", "cfi-flash"); + qemu_fdt_setprop_sized_cells(fdt, name, "reg", + 1, flashbase, 1, flashsize); + qemu_fdt_setprop_cell(fdt, name, "bank-width", bank_width); +} + static void platform_bus_create_devtree(PPCE500MachineState *pms, void *fdt, const char *mpic) { @@ -276,6 +303,8 @@ static void platform_bus_create_devtree(PPCE500MachineState *pms, uint64_t addr = pmc->platform_bus_base; uint64_t size = pmc->platform_bus_size; int irq_start = pmc->platform_bus_first_irq; + SysBusDevice *sbdev; + bool ambiguous; /* Create a /platform node that we can put all devices into */ @@ -302,6 +331,13 @@ static void platform_bus_create_devtree(PPCE500MachineState *pms, /* Loop through all dynamic sysbus devices and create nodes for them */ foreach_dynamic_sysbus_device(sysbus_device_create_devtree, &data); + sbdev = SYS_BUS_DEVICE(object_resolve_path_type("", TYPE_PFLASH_CFI01, + &ambiguous)); + if (sbdev) { + assert(!ambiguous); + create_devtree_flash(sbdev, &data); + } + g_free(node); } @@ -856,6 +892,7 @@ void ppce500_init(MachineState *machine) unsigned int pci_irq_nrs[PCI_NUM_PINS] = {1, 2, 3, 4}; IrqLines *irqs; DeviceState *dev, *mpicdev; + DriveInfo *dinfo; CPUPPCState *firstenv = NULL; MemoryRegion *ccsr_addr_space; SysBusDevice *s; @@ -1024,6 +1061,48 @@ void ppce500_init(MachineState *machine) pmc->platform_bus_base, &pms->pbus_dev->mmio); + dinfo = drive_get(IF_PFLASH, 0, 0); + if (dinfo) { + BlockBackend *blk = blk_by_legacy_dinfo(dinfo); + BlockDriverState *bs = blk_bs(blk); + uint64_t mmio_size = memory_region_size(&pms->pbus_dev->mmio); + uint64_t size = bdrv_getlength(bs); + uint32_t sector_len = 64 * KiB; + + if (!is_power_of_2(size)) { + error_report("Size of pflash file must be a power of two."); + exit(1); + } + + if (size > mmio_size) { + error_report("Size of pflash file must not be bigger than %" PRIu64 + " bytes.", mmio_size); + exit(1); + } + + if (!QEMU_IS_ALIGNED(size, sector_len)) { + error_report("Size of pflash file must be a multiple of %" PRIu32 + ".", sector_len); + exit(1); + } + + dev = qdev_new(TYPE_PFLASH_CFI01); + qdev_prop_set_drive(dev, "drive", blk); + qdev_prop_set_uint32(dev, "num-blocks", size / sector_len); + qdev_prop_set_uint64(dev, "sector-length", sector_len); + qdev_prop_set_uint8(dev, "width", 2); + qdev_prop_set_bit(dev, "big-endian", true); + qdev_prop_set_uint16(dev, "id0", 0x89); + qdev_prop_set_uint16(dev, "id1", 0x18); + qdev_prop_set_uint16(dev, "id2", 0x0000); + qdev_prop_set_uint16(dev, "id3", 0x0); + qdev_prop_set_string(dev, "name", "e500.flash"); + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); + + memory_region_add_subregion(&pms->pbus_dev->mmio, 0, + pflash_cfi01_get_memory(PFLASH_CFI01(dev))); + } + /* * Smart firmware defaults ahead! * From fb22d743b93b49b73930aff40d3ba9d252f81a56 Mon Sep 17 00:00:00 2001 From: Leandro Lupori Date: Fri, 28 Oct 2022 15:36:17 -0300 Subject: [PATCH 399/705] target/ppc: Fix regression in Radix MMU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 47e83d9107 ended up unintentionally changing the control flow of ppc_radix64_process_scoped_xlate(). When guest_visible is false, it must not raise an exception, even if the radix configuration is not valid. This regression prevented Linux boot in a nested environment with L1 using TCG and emulating KVM (cap-nested-hv=on) and L2 using KVM. L2 would hang on Linux's futex_init(), when it tested how a futex_atomic_cmpxchg_inatomic() handled a fault, because L1 would start a loop of trying to perform partition scoped translations and raising exceptions. Fixes: 47e83d9107 ("target/ppc: Improve Radix xlate level validation") Reported-by: Victor Colombo Signed-off-by: Leandro Lupori Tested-by: Víctor Colombo Reviewed-by: Daniel Henrique Barboza Message-Id: <20221028183617.121786-1-leandro.lupori@eldorado.org.br> [danielhb: use %"PRIu64" to print 'nls'] Signed-off-by: Daniel Henrique Barboza --- target/ppc/mmu-radix64.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c index 00f2e9fa2e..031efda0df 100644 --- a/target/ppc/mmu-radix64.c +++ b/target/ppc/mmu-radix64.c @@ -238,6 +238,8 @@ static void ppc_radix64_set_rc(PowerPCCPU *cpu, MMUAccessType access_type, static bool ppc_radix64_is_valid_level(int level, int psize, uint64_t nls) { + bool ret; + /* * Check if this is a valid level, according to POWER9 and POWER10 * Processor User's Manuals, sections 4.10.4.1 and 5.10.6.1, respectively: @@ -249,16 +251,25 @@ static bool ppc_radix64_is_valid_level(int level, int psize, uint64_t nls) */ switch (level) { case 0: /* Root Page Dir */ - return psize == 52 && nls == 13; + ret = psize == 52 && nls == 13; + break; case 1: case 2: - return nls == 9; + ret = nls == 9; + break; case 3: - return nls == 9 || nls == 5; + ret = nls == 9 || nls == 5; + break; default: - qemu_log_mask(LOG_GUEST_ERROR, "invalid radix level: %d\n", level); - return false; + ret = false; } + + if (unlikely(!ret)) { + qemu_log_mask(LOG_GUEST_ERROR, "invalid radix configuration: " + "level %d size %d nls %"PRIu64"\n", + level, psize, nls); + } + return ret; } static int ppc_radix64_next_level(AddressSpace *as, vaddr eaddr, @@ -519,11 +530,13 @@ static int ppc_radix64_process_scoped_xlate(PowerPCCPU *cpu, if (!ppc_radix64_is_valid_level(level++, *g_page_size, nls)) { fault_cause |= DSISR_R_BADCONFIG; - return 1; + ret = 1; + } else { + ret = ppc_radix64_next_level(cs->as, eaddr & R_EADDR_MASK, + &h_raddr, &nls, g_page_size, + &pte, &fault_cause); } - ret = ppc_radix64_next_level(cs->as, eaddr & R_EADDR_MASK, &h_raddr, - &nls, g_page_size, &pte, &fault_cause); if (ret) { /* No valid pte */ if (guest_visible) { From 121531751087ad3f8d87ad17068835bbcd14fb02 Mon Sep 17 00:00:00 2001 From: Qi Hu Date: Mon, 24 Oct 2022 10:41:55 +0200 Subject: [PATCH 400/705] target/i386: Fix calculation of LOCK NEG eflags After: lock negl -0x14(%rbp) pushf pop %rax %rax will contain the wrong value because the "lock neg" calculates the wrong eflags. Simple test: #include int main() { __volatile__ unsigned test = 0x2363a; __volatile__ char cond = 0; asm( "lock negl %0 \n\t" "sets %1" : "=m"(test), "=r"(cond)); assert(cond & 1); return 0; } Reported-by: Jinyang Shen Co-Developed-by: Xuehai Chen Signed-off-by: Xuehai Chen Signed-off-by: Qi Hu Signed-off-by: Paolo Bonzini --- target/i386/tcg/translate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c index 546c427c23..c477a10f41 100644 --- a/target/i386/tcg/translate.c +++ b/target/i386/tcg/translate.c @@ -3300,7 +3300,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu) tcg_temp_free(t2); tcg_temp_free(a0); - tcg_gen_mov_tl(s->T0, t0); + tcg_gen_neg_tl(s->T0, t0); tcg_temp_free(t0); } else { tcg_gen_neg_tl(s->T0, s->T0); From c891c24b1a4f5496cdb5f6afff9dae146334c7d3 Mon Sep 17 00:00:00 2001 From: Claudio Imbrenda Date: Fri, 12 Aug 2022 15:34:53 +0200 Subject: [PATCH 401/705] os-posix: asynchronous teardown for shutdown on Linux This patch adds support for asynchronously tearing down a VM on Linux. When qemu terminates, either naturally or because of a fatal signal, the VM is torn down. If the VM is huge, it can take a considerable amount of time for it to be cleaned up. In case of a protected VM, it might take even longer than a non-protected VM (this is the case on s390x, for example). Some users might want to shut down a VM and restart it immediately, without having to wait. This is especially true if management infrastructure like libvirt is used. This patch implements a simple trick on Linux to allow qemu to return immediately, with the teardown of the VM being performed asynchronously. If the new commandline option -async-teardown is used, a new process is spawned from qemu at startup, using the clone syscall, in such way that it will share its address space with qemu.The new process will have the name "cleanup/". It will wait until qemu terminates completely, and then it will exit itself. This allows qemu to terminate quickly, without having to wait for the whole address space to be torn down. The cleanup process will exit after qemu, so it will be the last user of the address space, and therefore it will take care of the actual teardown. The cleanup process will share the same cgroups as qemu, so both memory usage and cpu time will be accounted properly. If possible, close_range will be used in the cleanup process to close all open file descriptors. If it is not available or if it fails, /proc will be used to determine which file descriptors to close. If the cleanup process is forcefully killed with SIGKILL before the main qemu process has terminated completely, the mechanism is defeated and the teardown will not be asynchronous. This feature can already be used with libvirt by adding the following to the XML domain definition to pass the parameter to qemu directly: Signed-off-by: Claudio Imbrenda Reviewed-by: Murilo Opsfelder Araujo Tested-by: Murilo Opsfelder Araujo Message-Id: <20220812133453.82671-1-imbrenda@linux.ibm.com> Signed-off-by: Paolo Bonzini --- include/qemu/async-teardown.h | 22 +++++ meson.build | 1 + os-posix.c | 6 ++ qemu-options.hx | 19 +++++ util/async-teardown.c | 150 ++++++++++++++++++++++++++++++++++ util/meson.build | 1 + 6 files changed, 199 insertions(+) create mode 100644 include/qemu/async-teardown.h create mode 100644 util/async-teardown.c diff --git a/include/qemu/async-teardown.h b/include/qemu/async-teardown.h new file mode 100644 index 0000000000..092e7a37e7 --- /dev/null +++ b/include/qemu/async-teardown.h @@ -0,0 +1,22 @@ +/* + * Asynchronous teardown + * + * Copyright IBM, Corp. 2022 + * + * Authors: + * Claudio Imbrenda + * + * This work is licensed under the terms of the GNU GPL, version 2 or (at your + * option) any later version. See the COPYING file in the top-level directory. + * + */ +#ifndef QEMU_ASYNC_TEARDOWN_H +#define QEMU_ASYNC_TEARDOWN_H + +#include "config-host.h" + +#ifdef CONFIG_LINUX +void init_async_teardown(void); +#endif + +#endif diff --git a/meson.build b/meson.build index 37737913df..17834b3c3d 100644 --- a/meson.build +++ b/meson.build @@ -1949,6 +1949,7 @@ if targetos == 'windows' endif # has_function +config_host_data.set('CONFIG_CLOSE_RANGE', cc.has_function('close_range')) config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4')) config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime')) config_host_data.set('CONFIG_DUP3', cc.has_function('dup3')) diff --git a/os-posix.c b/os-posix.c index 321fc4bd13..4858650c3e 100644 --- a/os-posix.c +++ b/os-posix.c @@ -39,6 +39,7 @@ #ifdef CONFIG_LINUX #include +#include "qemu/async-teardown.h" #endif /* @@ -150,6 +151,11 @@ int os_parse_cmd_args(int index, const char *optarg) case QEMU_OPTION_daemonize: daemonize = 1; break; +#if defined(CONFIG_LINUX) + case QEMU_OPTION_asyncteardown: + init_async_teardown(); + break; +#endif default: return -1; } diff --git a/qemu-options.hx b/qemu-options.hx index eb38e5dc40..e26d1dad39 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4774,6 +4774,25 @@ HXCOMM Internal use DEF("qtest", HAS_ARG, QEMU_OPTION_qtest, "", QEMU_ARCH_ALL) DEF("qtest-log", HAS_ARG, QEMU_OPTION_qtest_log, "", QEMU_ARCH_ALL) +#ifdef __linux__ +DEF("async-teardown", 0, QEMU_OPTION_asyncteardown, + "-async-teardown enable asynchronous teardown\n", + QEMU_ARCH_ALL) +#endif +SRST +``-async-teardown`` + Enable asynchronous teardown. A new process called "cleanup/" + will be created at startup sharing the address space with the main qemu + process, using clone. It will wait for the main qemu process to + terminate completely, and then exit. + This allows qemu to terminate very quickly even if the guest was + huge, leaving the teardown of the address space to the cleanup + process. Since the cleanup process shares the same cgroups as the + main qemu process, accounting is performed correctly. This only + works if the cleanup process is not forcefully killed with SIGKILL + before the main qemu process has terminated completely. +ERST + DEF("msg", HAS_ARG, QEMU_OPTION_msg, "-msg [timestamp[=on|off]][,guest-name=[on|off]]\n" " control error message format\n" diff --git a/util/async-teardown.c b/util/async-teardown.c new file mode 100644 index 0000000000..62bfce1b3c --- /dev/null +++ b/util/async-teardown.c @@ -0,0 +1,150 @@ +/* + * Asynchronous teardown + * + * Copyright IBM, Corp. 2022 + * + * Authors: + * Claudio Imbrenda + * + * This work is licensed under the terms of the GNU GPL, version 2 or (at your + * option) any later version. See the COPYING file in the top-level directory. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "qemu/osdep.h" +#include "qemu/async-teardown.h" + +#ifdef _SC_THREAD_STACK_MIN +#define CLONE_STACK_SIZE sysconf(_SC_THREAD_STACK_MIN) +#else +#define CLONE_STACK_SIZE 16384 +#endif + +static pid_t the_ppid; + +/* + * Close all open file descriptors. + */ +static void close_all_open_fd(void) +{ + struct dirent *de; + int fd, dfd; + DIR *dir; + +#ifdef CONFIG_CLOSE_RANGE + int r = close_range(0, ~0U, 0); + if (!r) { + /* Success, no need to try other ways. */ + return; + } +#endif + + dir = opendir("/proc/self/fd"); + if (!dir) { + /* If /proc is not mounted, there is nothing that can be done. */ + return; + } + /* Avoid closing the directory. */ + dfd = dirfd(dir); + + for (de = readdir(dir); de; de = readdir(dir)) { + fd = atoi(de->d_name); + if (fd != dfd) { + close(fd); + } + } + closedir(dir); +} + +static void hup_handler(int signal) +{ + /* Check every second if this process has been reparented. */ + while (the_ppid == getppid()) { + /* sleep() is safe to use in a signal handler. */ + sleep(1); + } + + /* At this point the parent process has terminated completely. */ + _exit(0); +} + +static int async_teardown_fn(void *arg) +{ + struct sigaction sa = { .sa_handler = hup_handler }; + sigset_t hup_signal; + char name[16]; + + /* Set a meaningful name for this process. */ + snprintf(name, 16, "cleanup/%d", the_ppid); + prctl(PR_SET_NAME, (unsigned long)name); + + /* + * Close all file descriptors that might have been inherited from the + * main qemu process when doing clone, needed to make libvirt happy. + * Not using close_range for increased compatibility with older kernels. + */ + close_all_open_fd(); + + /* Set up a handler for SIGHUP and unblock SIGHUP. */ + sigaction(SIGHUP, &sa, NULL); + sigemptyset(&hup_signal); + sigaddset(&hup_signal, SIGHUP); + sigprocmask(SIG_UNBLOCK, &hup_signal, NULL); + + /* Ask to receive SIGHUP when the parent dies. */ + prctl(PR_SET_PDEATHSIG, SIGHUP); + + /* + * Sleep forever, unless the parent process has already terminated. The + * only interruption can come from the SIGHUP signal, which in normal + * operation is received when the parent process dies. + */ + if (the_ppid == getppid()) { + pause(); + } + + /* At this point the parent process has terminated completely. */ + _exit(0); +} + +/* + * Allocate a new stack of a reasonable size, and return a pointer to its top. + */ +static void *new_stack_for_clone(void) +{ + size_t stack_size = CLONE_STACK_SIZE; + char *stack_ptr; + + /* Allocate a new stack and get a pointer to its top. */ + stack_ptr = qemu_alloc_stack(&stack_size); +#if !defined(HOST_HPPA) + /* The top is at the end of the area, except on HPPA. */ + stack_ptr += stack_size; +#endif + + return stack_ptr; +} + +/* + * Block all signals, start (clone) a new process sharing the address space + * with qemu (CLONE_VM), then restore signals. + */ +void init_async_teardown(void) +{ + sigset_t all_signals, old_signals; + + the_ppid = getpid(); + + sigfillset(&all_signals); + sigprocmask(SIG_BLOCK, &all_signals, &old_signals); + clone(async_teardown_fn, new_stack_for_clone(), CLONE_VM, NULL); + sigprocmask(SIG_SETMASK, &old_signals, NULL); +} diff --git a/util/meson.build b/util/meson.build index 5e282130df..63acd59bb0 100644 --- a/util/meson.build +++ b/util/meson.build @@ -2,6 +2,7 @@ util_ss.add(files('osdep.c', 'cutils.c', 'unicode.c', 'qemu-timer-common.c')) if not config_host_data.get('CONFIG_ATOMIC64') util_ss.add(files('atomic64.c')) endif +util_ss.add(when: 'CONFIG_LINUX', if_true: files('async-teardown.c')) util_ss.add(when: 'CONFIG_POSIX', if_true: files('aio-posix.c')) util_ss.add(when: 'CONFIG_POSIX', if_true: files('fdmon-poll.c')) if config_host_data.get('CONFIG_EPOLL_CREATE1') From 19e2a9fb9da067acba95b3be83588bda5a3f6a99 Mon Sep 17 00:00:00 2001 From: Zeng Guang Date: Thu, 25 Aug 2022 10:52:46 +0800 Subject: [PATCH 402/705] target/i386: Set maximum APIC ID to KVM prior to vCPU creation Specify maximum possible APIC ID assigned for current VM session to KVM prior to the creation of vCPUs. By this setting, KVM can set up VM-scoped data structure indexed by the APIC ID, e.g. Posted-Interrupt Descriptor pointer table to support Intel IPI virtualization, with the most optimal memory footprint. It can be achieved by calling KVM_ENABLE_CAP for KVM_CAP_MAX_VCPU_ID capability once KVM has enabled it. Ignoring the return error if KVM doesn't support this capability yet. Signed-off-by: Zeng Guang Acked-by: Peter Xu Acked-by: Michael S. Tsirkin Message-Id: <20220825025246.26618-1-guang.zeng@intel.com> Signed-off-by: Paolo Bonzini --- hw/i386/x86.c | 4 ++++ target/i386/kvm/kvm-stub.c | 5 +++++ target/i386/kvm/kvm.c | 5 +++++ target/i386/kvm/kvm_i386.h | 2 ++ 4 files changed, 16 insertions(+) diff --git a/hw/i386/x86.c b/hw/i386/x86.c index bd50a064a3..78cc131926 100644 --- a/hw/i386/x86.c +++ b/hw/i386/x86.c @@ -140,6 +140,10 @@ void x86_cpus_init(X86MachineState *x86ms, int default_cpu_version) exit(EXIT_FAILURE); } + if (kvm_enabled()) { + kvm_set_max_apic_id(x86ms->apic_id_limit); + } + possible_cpus = mc->possible_cpu_arch_ids(ms); for (i = 0; i < ms->smp.cpus; i++) { x86_cpu_new(x86ms, possible_cpus->cpus[i].arch_id, &error_fatal); diff --git a/target/i386/kvm/kvm-stub.c b/target/i386/kvm/kvm-stub.c index f6e7e4466e..e052f1c7b0 100644 --- a/target/i386/kvm/kvm-stub.c +++ b/target/i386/kvm/kvm-stub.c @@ -44,3 +44,8 @@ bool kvm_hyperv_expand_features(X86CPU *cpu, Error **errp) { abort(); } + +void kvm_set_max_apic_id(uint32_t max_apic_id) +{ + return; +} diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index 4df0428089..a213209379 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -5723,3 +5723,8 @@ void kvm_arch_accel_class_init(ObjectClass *oc) "Clock cycles without an event window " "after which a notification VM exit occurs"); } + +void kvm_set_max_apic_id(uint32_t max_apic_id) +{ + kvm_vm_enable_cap(kvm_state, KVM_CAP_MAX_VCPU_ID, 0, max_apic_id); +} diff --git a/target/i386/kvm/kvm_i386.h b/target/i386/kvm/kvm_i386.h index b7c38ba2c4..6a5c24e3dc 100644 --- a/target/i386/kvm/kvm_i386.h +++ b/target/i386/kvm/kvm_i386.h @@ -66,4 +66,6 @@ typedef struct kvm_msr_handlers { bool kvm_filter_msr(KVMState *s, uint32_t msr, QEMURDMSRHandler *rdmsr, QEMUWRMSRHandler *wrmsr); +void kvm_set_max_apic_id(uint32_t max_apic_id); + #endif From eff3de52f265df39c6fc668415ad317ec1f24051 Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Fri, 21 Oct 2022 12:57:34 +0200 Subject: [PATCH 403/705] util/log: Close per-thread log file on thread termination When `-D ${logfile} -d tid` is passed, qemu_log_trylock() creates a dedicated log file for the current thread and opens it. The corresponding file descriptor is cached in a __thread variable. Nothing is done to close the corresponding file descriptor when the thread terminates though and the file descriptor is leaked. The issue was found during code inspection and reproduced manually. Fix that with an atexit notifier. Fixes: 4e51069d6793 ("util/log: Support per-thread log files") Cc: richard.henderson@linaro.org Signed-off-by: Greg Kurz Message-Id: <20221021105734.555797-1-groug@kaod.org> Signed-off-by: Paolo Bonzini --- util/log.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/util/log.c b/util/log.c index d6eb0378c3..39866bdaf2 100644 --- a/util/log.c +++ b/util/log.c @@ -42,6 +42,7 @@ static QemuMutex global_mutex; static char *global_filename; static FILE *global_file; static __thread FILE *thread_file; +static __thread Notifier qemu_log_thread_cleanup_notifier; int qemu_loglevel; static bool log_append; @@ -77,6 +78,12 @@ static int log_thread_id(void) #endif } +static void qemu_log_thread_cleanup(Notifier *n, void *unused) +{ + fclose(thread_file); + thread_file = NULL; +} + /* Lock/unlock output. */ FILE *qemu_log_trylock(void) @@ -93,6 +100,8 @@ FILE *qemu_log_trylock(void) return NULL; } thread_file = logfile; + qemu_log_thread_cleanup_notifier.notify = qemu_log_thread_cleanup; + qemu_thread_atexit_add(&qemu_log_thread_cleanup_notifier); } else { rcu_read_lock(); /* From 7f8c044018555dcc36eb5af1d5d6cebc85ebd330 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 8 Sep 2022 21:28:11 +0800 Subject: [PATCH 404/705] scripts/nsis.py: Drop the unnecessary path separator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no need to append a path separator to the destination directory that is passed to "make install". Signed-off-by: Bin Meng Message-Id: <20220908132817.1831008-2-bmeng.cn@gmail.com> Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Stefan Weil Signed-off-by: Stefan Weil --- scripts/nsis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/nsis.py b/scripts/nsis.py index 462d6cac3b..bbb41d9386 100644 --- a/scripts/nsis.py +++ b/scripts/nsis.py @@ -30,7 +30,7 @@ def main(): destdir = tempfile.mkdtemp() try: - subprocess.run(["make", "install", "DESTDIR=" + destdir + os.path.sep]) + subprocess.run(["make", "install", "DESTDIR=" + destdir]) with open( os.path.join(destdir + args.prefix, "system-emulations.nsh"), "w" ) as nsh, open( From 93dbca2ce9f112ee8bfd641fa2ea6ff0771c6c39 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 8 Sep 2022 21:28:12 +0800 Subject: [PATCH 405/705] scripts/nsis.py: Fix destination directory name when invoked on Windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "make installer" on Windows fails with the following message: Traceback (most recent call last): File "G:\msys64\home\foo\git\qemu\scripts\nsis.py", line 89, in main() File "G:\msys64\home\foo\git\qemu\scripts\nsis.py", line 34, in main with open( OSError: [Errno 22] Invalid argument: 'R:/Temp/tmpw83xhjquG:/msys64/qemu/system-emulations.nsh' ninja: build stopped: subcommand failed. Use os.path.splitdrive() to form a canonical path without the drive letter on Windows. This works with cross-build on Linux too. Fixes: 8adfeba953e0 ("meson: add NSIS building") Signed-off-by: Bin Meng Message-Id: <20220908132817.1831008-3-bmeng.cn@gmail.com> Reviewed-by: Marc-André Lureau Reviewed-by: Philippe Mathieu-Daudé Tested-by: Stefan Weil Signed-off-by: Stefan Weil --- scripts/nsis.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/scripts/nsis.py b/scripts/nsis.py index bbb41d9386..baa6ef9594 100644 --- a/scripts/nsis.py +++ b/scripts/nsis.py @@ -28,16 +28,18 @@ def main(): parser.add_argument("nsisargs", nargs="*") args = parser.parse_args() + # canonicalize the Windows native prefix path + prefix = os.path.splitdrive(args.prefix)[1] destdir = tempfile.mkdtemp() try: subprocess.run(["make", "install", "DESTDIR=" + destdir]) with open( - os.path.join(destdir + args.prefix, "system-emulations.nsh"), "w" + os.path.join(destdir + prefix, "system-emulations.nsh"), "w" ) as nsh, open( - os.path.join(destdir + args.prefix, "system-mui-text.nsh"), "w" + os.path.join(destdir + prefix, "system-mui-text.nsh"), "w" ) as muinsh: for exe in sorted(glob.glob( - os.path.join(destdir + args.prefix, "qemu-system-*.exe") + os.path.join(destdir + prefix, "qemu-system-*.exe") )): exe = os.path.basename(exe) arch = exe[12:-4] @@ -61,7 +63,7 @@ def main(): !insertmacro MUI_DESCRIPTION_TEXT ${{Section_{0}}} "{1}" """.format(arch, desc)) - for exe in glob.glob(os.path.join(destdir + args.prefix, "*.exe")): + for exe in glob.glob(os.path.join(destdir + prefix, "*.exe")): signcode(exe) makensis = [ @@ -69,7 +71,7 @@ def main(): "-V2", "-NOCD", "-DSRCDIR=" + args.srcdir, - "-DBINDIR=" + destdir + args.prefix, + "-DBINDIR=" + destdir + prefix, ] dlldir = "w32" if args.cpu == "x86_64": From a3c1e6458dbbe3647ccadfb39cbb585fdc4373a5 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 8 Sep 2022 21:28:13 +0800 Subject: [PATCH 406/705] scripts/nsis.py: Automatically package required DLLs of QEMU executables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At present packaging the required DLLs of QEMU executables is a manual process, and error prone. Actually build/config-host.mak contains a GLIB_BINDIR variable which is the directory where glib and other DLLs reside. This works for both Windows native build and cross-build on Linux. We can use it as the search directory for DLLs and automate the whole DLL packaging process. Signed-off-by: Bin Meng Message-Id: <20220908132817.1831008-4-bmeng.cn@gmail.com> Reviewed-by: Marc-André Lureau Tested-by: Stefan Weil Signed-off-by: Stefan Weil --- meson.build | 1 + scripts/nsis.py | 46 ++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/meson.build b/meson.build index 37737913df..d0a186e7f5 100644 --- a/meson.build +++ b/meson.build @@ -3616,6 +3616,7 @@ if host_machine.system() == 'windows' '@OUTPUT@', get_option('prefix'), meson.current_source_dir(), + config_host['GLIB_BINDIR'], host_machine.cpu(), '--', '-DDISPLAYVERSION=' + meson.project_version(), diff --git a/scripts/nsis.py b/scripts/nsis.py index baa6ef9594..03ed7608a2 100644 --- a/scripts/nsis.py +++ b/scripts/nsis.py @@ -18,12 +18,36 @@ def signcode(path): return subprocess.run([cmd, path]) +def find_deps(exe_or_dll, search_path, analyzed_deps): + deps = [exe_or_dll] + output = subprocess.check_output(["objdump", "-p", exe_or_dll], text=True) + output = output.split("\n") + for line in output: + if not line.startswith("\tDLL Name: "): + continue + + dep = line.split("DLL Name: ")[1].strip() + if dep in analyzed_deps: + continue + + dll = os.path.join(search_path, dep) + if not os.path.exists(dll): + # assume it's a Windows provided dll, skip it + continue + + analyzed_deps.add(dep) + # locate the dll dependencies recursively + rdeps = find_deps(dll, search_path, analyzed_deps) + deps.extend(rdeps) + + return deps def main(): parser = argparse.ArgumentParser(description="QEMU NSIS build helper.") parser.add_argument("outfile") parser.add_argument("prefix") parser.add_argument("srcdir") + parser.add_argument("dlldir") parser.add_argument("cpu") parser.add_argument("nsisargs", nargs="*") args = parser.parse_args() @@ -63,9 +87,26 @@ def main(): !insertmacro MUI_DESCRIPTION_TEXT ${{Section_{0}}} "{1}" """.format(arch, desc)) + search_path = args.dlldir + print("Searching '%s' for the dependent dlls ..." % search_path) + dlldir = os.path.join(destdir + prefix, "dll") + os.mkdir(dlldir) + for exe in glob.glob(os.path.join(destdir + prefix, "*.exe")): signcode(exe) + # find all dll dependencies + deps = set(find_deps(exe, search_path, set())) + deps.remove(exe) + + # copy all dlls to the DLLDIR + for dep in deps: + dllfile = os.path.join(dlldir, os.path.basename(dep)) + if (os.path.exists(dllfile)): + continue + print("Copying '%s' to '%s'" % (dep, dllfile)) + shutil.copy(dep, dllfile) + makensis = [ "makensis", "-V2", @@ -73,12 +114,9 @@ def main(): "-DSRCDIR=" + args.srcdir, "-DBINDIR=" + destdir + prefix, ] - dlldir = "w32" if args.cpu == "x86_64": - dlldir = "w64" makensis += ["-DW64"] - if os.path.exists(os.path.join(args.srcdir, "dll")): - makensis += ["-DDLLDIR={0}/dll/{1}".format(args.srcdir, dlldir)] + makensis += ["-DDLLDIR=" + dlldir] makensis += ["-DOUTFILE=" + args.outfile] + args.nsisargs subprocess.run(makensis) From 588fec8a4c3fe9e0d1cb3f7ea6fdd46221e42814 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 8 Sep 2022 21:28:15 +0800 Subject: [PATCH 407/705] block/nfs: Fix 32-bit Windows build libnfs.h declares nfs_fstat() as the following for win32: int nfs_fstat(struct nfs_context *nfs, struct nfsfh *nfsfh, struct __stat64 *st); The 'st' parameter should be of type 'struct __stat64'. The codes happen to build successfully for 64-bit Windows, but it does not build for 32-bit Windows. Fixes: 6542aa9c75bc ("block: add native support for NFS") Fixes: 18a8056e0bc7 ("block/nfs: cache allocated filesize for read-only files") Signed-off-by: Bin Meng Message-Id: <20220908132817.1831008-6-bmeng.cn@gmail.com> Reviewed-by: Stefan Weil Signed-off-by: Stefan Weil --- block/nfs.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/block/nfs.c b/block/nfs.c index 596ebe98cb..ece22353ac 100644 --- a/block/nfs.c +++ b/block/nfs.c @@ -418,7 +418,11 @@ static int64_t nfs_client_open(NFSClient *client, BlockdevOptionsNfs *opts, int flags, int open_flags, Error **errp) { int64_t ret = -EINVAL; +#ifdef _WIN32 + struct __stat64 st; +#else struct stat st; +#endif char *file = NULL, *strp = NULL; qemu_mutex_init(&client->mutex); @@ -781,7 +785,11 @@ static int nfs_reopen_prepare(BDRVReopenState *state, BlockReopenQueue *queue, Error **errp) { NFSClient *client = state->bs->opaque; +#ifdef _WIN32 + struct __stat64 st; +#else struct stat st; +#endif int ret = 0; if (state->flags & BDRV_O_RDWR && bdrv_is_read_only(state->bs)) { From 8e4022a8d6934d02c0d95058a6e9b0e0f93f36b2 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Thu, 1 Sep 2022 13:41:15 +0200 Subject: [PATCH 408/705] hw/isa/vt82c686: Resolve chip-specific realize methods MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The object creation now happens in chip-specific init methods which allows the realize methods to be consolidated into one method. Shifting the logic into the init methods has the addidional advantage that the parent object's init methods are called implicitly - like constructors in object-oriented languages. Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20220901114127.53914-2-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/isa/vt82c686.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 8f656251b8..0217c98fe4 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -544,7 +544,7 @@ struct ViaISAState { qemu_irq cpu_intr; qemu_irq *isa_irqs; ISABus *isa_bus; - ViaSuperIOState *via_sio; + ViaSuperIOState via_sio; }; static const VMStateDescription vmstate_via = { @@ -602,6 +602,11 @@ static void via_isa_realize(PCIDevice *d, Error **errp) d->wmask[i] = 0; } } + + /* Super I/O */ + if (!qdev_realize(DEVICE(&s->via_sio), BUS(s->isa_bus), errp)) { + return; + } } /* TYPE_VT82C686B_ISA */ @@ -615,7 +620,7 @@ static void vt82c686b_write_config(PCIDevice *d, uint32_t addr, pci_default_write_config(d, addr, val, len); if (addr == 0x85) { /* BIT(1): enable or disable superio config io ports */ - via_superio_io_enable(s->via_sio, val & BIT(1)); + via_superio_io_enable(&s->via_sio, val & BIT(1)); } } @@ -639,13 +644,11 @@ static void vt82c686b_isa_reset(DeviceState *dev) pci_conf[0x77] = 0x10; /* GPIO Control 1/2/3/4 */ } -static void vt82c686b_realize(PCIDevice *d, Error **errp) +static void vt82c686b_init(Object *obj) { - ViaISAState *s = VIA_ISA(d); + ViaISAState *s = VIA_ISA(obj); - via_isa_realize(d, errp); - s->via_sio = VIA_SUPERIO(isa_create_simple(s->isa_bus, - TYPE_VT82C686B_SUPERIO)); + object_initialize_child(obj, "sio", &s->via_sio, TYPE_VT82C686B_SUPERIO); } static void vt82c686b_class_init(ObjectClass *klass, void *data) @@ -653,7 +656,7 @@ static void vt82c686b_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); - k->realize = vt82c686b_realize; + k->realize = via_isa_realize; k->config_write = vt82c686b_write_config; k->vendor_id = PCI_VENDOR_ID_VIA; k->device_id = PCI_DEVICE_ID_VIA_82C686B_ISA; @@ -670,6 +673,7 @@ static const TypeInfo vt82c686b_isa_info = { .name = TYPE_VT82C686B_ISA, .parent = TYPE_VIA_ISA, .instance_size = sizeof(ViaISAState), + .instance_init = vt82c686b_init, .class_init = vt82c686b_class_init, }; @@ -684,7 +688,7 @@ static void vt8231_write_config(PCIDevice *d, uint32_t addr, pci_default_write_config(d, addr, val, len); if (addr == 0x50) { /* BIT(2): enable or disable superio config io ports */ - via_superio_io_enable(s->via_sio, val & BIT(2)); + via_superio_io_enable(&s->via_sio, val & BIT(2)); } } @@ -703,13 +707,11 @@ static void vt8231_isa_reset(DeviceState *dev) pci_conf[0x6b] = 0x01; /* Fast IR I/O Base */ } -static void vt8231_realize(PCIDevice *d, Error **errp) +static void vt8231_init(Object *obj) { - ViaISAState *s = VIA_ISA(d); + ViaISAState *s = VIA_ISA(obj); - via_isa_realize(d, errp); - s->via_sio = VIA_SUPERIO(isa_create_simple(s->isa_bus, - TYPE_VT8231_SUPERIO)); + object_initialize_child(obj, "sio", &s->via_sio, TYPE_VT8231_SUPERIO); } static void vt8231_class_init(ObjectClass *klass, void *data) @@ -717,7 +719,7 @@ static void vt8231_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); - k->realize = vt8231_realize; + k->realize = via_isa_realize; k->config_write = vt8231_write_config; k->vendor_id = PCI_VENDOR_ID_VIA; k->device_id = PCI_DEVICE_ID_VIA_8231_ISA; @@ -734,6 +736,7 @@ static const TypeInfo vt8231_isa_info = { .name = TYPE_VT8231_ISA, .parent = TYPE_VIA_ISA, .instance_size = sizeof(ViaISAState), + .instance_init = vt8231_init, .class_init = vt8231_class_init, }; From 91ba92d1a33e5a9ded66bfbaa14a98938165934f Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Thu, 1 Sep 2022 13:41:16 +0200 Subject: [PATCH 409/705] hw/isa/vt82c686: Resolve unneeded attribute MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that also the super io device is realized in the common realize method, the isa_bus attribute can be turned into a temporary. Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20220901114127.53914-3-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/isa/vt82c686.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 0217c98fe4..9d12e1cae4 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -543,7 +543,6 @@ struct ViaISAState { PCIDevice dev; qemu_irq cpu_intr; qemu_irq *isa_irqs; - ISABus *isa_bus; ViaSuperIOState via_sio; }; @@ -585,17 +584,18 @@ static void via_isa_realize(PCIDevice *d, Error **errp) ViaISAState *s = VIA_ISA(d); DeviceState *dev = DEVICE(d); qemu_irq *isa_irq; + ISABus *isa_bus; int i; qdev_init_gpio_out(dev, &s->cpu_intr, 1); isa_irq = qemu_allocate_irqs(via_isa_request_i8259_irq, s, 1); - s->isa_bus = isa_bus_new(dev, get_system_memory(), pci_address_space_io(d), + isa_bus = isa_bus_new(dev, get_system_memory(), pci_address_space_io(d), &error_fatal); - s->isa_irqs = i8259_init(s->isa_bus, *isa_irq); - isa_bus_irqs(s->isa_bus, s->isa_irqs); - i8254_pit_init(s->isa_bus, 0x40, 0, NULL); - i8257_dma_init(s->isa_bus, 0); - mc146818_rtc_init(s->isa_bus, 2000, NULL); + s->isa_irqs = i8259_init(isa_bus, *isa_irq); + isa_bus_irqs(isa_bus, s->isa_irqs); + i8254_pit_init(isa_bus, 0x40, 0, NULL); + i8257_dma_init(isa_bus, 0); + mc146818_rtc_init(isa_bus, 2000, NULL); for (i = 0; i < PCI_CONFIG_HEADER_SIZE; i++) { if (i < PCI_COMMAND || i >= PCI_REVISION_ID) { @@ -604,7 +604,7 @@ static void via_isa_realize(PCIDevice *d, Error **errp) } /* Super I/O */ - if (!qdev_realize(DEVICE(&s->via_sio), BUS(s->isa_bus), errp)) { + if (!qdev_realize(DEVICE(&s->via_sio), BUS(isa_bus), errp)) { return; } } From dd28cc87aa0295743b577145a8afc76cc9292618 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Thu, 1 Sep 2022 13:41:17 +0200 Subject: [PATCH 410/705] hw/isa/vt82c686: Prefer pci_address_space() over get_system_memory() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unlike get_system_memory(), pci_address_space() respects the memory tree available to the parent device. Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20220901114127.53914-4-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/isa/vt82c686.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 9d12e1cae4..5582c0b179 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -589,7 +589,7 @@ static void via_isa_realize(PCIDevice *d, Error **errp) qdev_init_gpio_out(dev, &s->cpu_intr, 1); isa_irq = qemu_allocate_irqs(via_isa_request_i8259_irq, s, 1); - isa_bus = isa_bus_new(dev, get_system_memory(), pci_address_space_io(d), + isa_bus = isa_bus_new(dev, pci_address_space(d), pci_address_space_io(d), &error_fatal); s->isa_irqs = i8259_init(isa_bus, *isa_irq); isa_bus_irqs(isa_bus, s->isa_irqs); From c1561d1deba5a58c49b57afb72785e70ccb08dc9 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Thu, 1 Sep 2022 13:41:18 +0200 Subject: [PATCH 411/705] hw/isa/vt82c686: Reuse errp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rather than terminating abruptly, make use of the already present errp and propagate the error to the caller. Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20220901114127.53914-5-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/isa/vt82c686.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 5582c0b179..37e37b3855 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -590,7 +590,12 @@ static void via_isa_realize(PCIDevice *d, Error **errp) qdev_init_gpio_out(dev, &s->cpu_intr, 1); isa_irq = qemu_allocate_irqs(via_isa_request_i8259_irq, s, 1); isa_bus = isa_bus_new(dev, pci_address_space(d), pci_address_space_io(d), - &error_fatal); + errp); + + if (!isa_bus) { + return; + } + s->isa_irqs = i8259_init(isa_bus, *isa_irq); isa_bus_irqs(isa_bus, s->isa_irqs); i8254_pit_init(isa_bus, 0x40, 0, NULL); From 4b8fd0661a6c57f6a94b55e462626d522fa9c5cc Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Thu, 1 Sep 2022 13:41:19 +0200 Subject: [PATCH 412/705] hw/isa/vt82c686: Introduce TYPE_VIA_IDE define MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Establishes consistency with other (VIA) devices. Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Acked-by: Daniel Henrique Barboza Message-Id: <20220901114127.53914-6-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/ide/via.c | 2 +- hw/mips/fuloong2e.c | 2 +- hw/ppc/pegasos2.c | 2 +- include/hw/isa/vt82c686.h | 1 + 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/hw/ide/via.c b/hw/ide/via.c index 82def819c4..e1a429405d 100644 --- a/hw/ide/via.c +++ b/hw/ide/via.c @@ -230,7 +230,7 @@ static void via_ide_class_init(ObjectClass *klass, void *data) } static const TypeInfo via_ide_info = { - .name = "via-ide", + .name = TYPE_VIA_IDE, .parent = TYPE_PCI_IDE, .class_init = via_ide_class_init, }; diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c index 5ee546f5f6..44225fbe33 100644 --- a/hw/mips/fuloong2e.c +++ b/hw/mips/fuloong2e.c @@ -205,7 +205,7 @@ static void vt82c686b_southbridge_init(PCIBus *pci_bus, int slot, qemu_irq intc, TYPE_VT82C686B_ISA); qdev_connect_gpio_out(DEVICE(dev), 0, intc); - dev = pci_create_simple(pci_bus, PCI_DEVFN(slot, 1), "via-ide"); + dev = pci_create_simple(pci_bus, PCI_DEVFN(slot, 1), TYPE_VIA_IDE); pci_ide_create_devs(dev); pci_create_simple(pci_bus, PCI_DEVFN(slot, 2), "vt82c686b-usb-uhci"); diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c index bb4d008ba9..506f273b93 100644 --- a/hw/ppc/pegasos2.c +++ b/hw/ppc/pegasos2.c @@ -166,7 +166,7 @@ static void pegasos2_init(MachineState *machine) qdev_get_gpio_in_named(pm->mv, "gpp", 31)); /* VT8231 function 1: IDE Controller */ - dev = pci_create_simple(pci_bus, PCI_DEVFN(12, 1), "via-ide"); + dev = pci_create_simple(pci_bus, PCI_DEVFN(12, 1), TYPE_VIA_IDE); pci_ide_create_devs(dev); /* VT8231 function 2-3: USB Ports */ diff --git a/include/hw/isa/vt82c686.h b/include/hw/isa/vt82c686.h index 56ac141be3..87aca3e5bb 100644 --- a/include/hw/isa/vt82c686.h +++ b/include/hw/isa/vt82c686.h @@ -8,6 +8,7 @@ #define TYPE_VT8231_ISA "vt8231-isa" #define TYPE_VT8231_PM "vt8231-pm" #define TYPE_VIA_AC97 "via-ac97" +#define TYPE_VIA_IDE "via-ide" #define TYPE_VIA_MC97 "via-mc97" void via_isa_set_irq(PCIDevice *d, int n, int level); From 9eb6abbf6aea3116b3a4a7a6fbbb89ec836c0551 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Mon, 13 Jun 2022 19:24:55 +0200 Subject: [PATCH 413/705] hw/isa/vt82c686: Instantiate IDE function in host device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The IDE function is closely tied to the ISA function (e.g. the IDE interrupt routing happens there), so it makes sense that the IDE function is instantiated within the south bridge itself. Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Acked-by: Daniel Henrique Barboza Message-Id: <20220901114127.53914-7-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- configs/devices/mips64el-softmmu/default.mak | 1 - hw/isa/Kconfig | 1 + hw/isa/vt82c686.c | 17 +++++++++++++++++ hw/mips/fuloong2e.c | 8 ++++---- hw/ppc/Kconfig | 1 - hw/ppc/pegasos2.c | 9 ++++----- 6 files changed, 26 insertions(+), 11 deletions(-) diff --git a/configs/devices/mips64el-softmmu/default.mak b/configs/devices/mips64el-softmmu/default.mak index c610749ac1..d5188f7ea5 100644 --- a/configs/devices/mips64el-softmmu/default.mak +++ b/configs/devices/mips64el-softmmu/default.mak @@ -1,7 +1,6 @@ # Default configuration for mips64el-softmmu include ../mips-softmmu/common.mak -CONFIG_IDE_VIA=y CONFIG_FULOONG=y CONFIG_LOONGSON3V=y CONFIG_ATI_VGA=y diff --git a/hw/isa/Kconfig b/hw/isa/Kconfig index d42143a991..20de7e9294 100644 --- a/hw/isa/Kconfig +++ b/hw/isa/Kconfig @@ -53,6 +53,7 @@ config VT82C686 select I8254 select I8257 select I8259 + select IDE_VIA select MC146818RTC select PARALLEL diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 37e37b3855..63c1e3b8ce 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -17,6 +17,7 @@ #include "hw/isa/vt82c686.h" #include "hw/pci/pci.h" #include "hw/qdev-properties.h" +#include "hw/ide/pci.h" #include "hw/isa/isa.h" #include "hw/isa/superio.h" #include "hw/intc/i8259.h" @@ -544,6 +545,7 @@ struct ViaISAState { qemu_irq cpu_intr; qemu_irq *isa_irqs; ViaSuperIOState via_sio; + PCIIDEState ide; }; static const VMStateDescription vmstate_via = { @@ -556,10 +558,18 @@ static const VMStateDescription vmstate_via = { } }; +static void via_isa_init(Object *obj) +{ + ViaISAState *s = VIA_ISA(obj); + + object_initialize_child(obj, "ide", &s->ide, TYPE_VIA_IDE); +} + static const TypeInfo via_isa_info = { .name = TYPE_VIA_ISA, .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(ViaISAState), + .instance_init = via_isa_init, .abstract = true, .interfaces = (InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, @@ -583,6 +593,7 @@ static void via_isa_realize(PCIDevice *d, Error **errp) { ViaISAState *s = VIA_ISA(d); DeviceState *dev = DEVICE(d); + PCIBus *pci_bus = pci_get_bus(d); qemu_irq *isa_irq; ISABus *isa_bus; int i; @@ -612,6 +623,12 @@ static void via_isa_realize(PCIDevice *d, Error **errp) if (!qdev_realize(DEVICE(&s->via_sio), BUS(isa_bus), errp)) { return; } + + /* Function 1: IDE */ + qdev_prop_set_int32(DEVICE(&s->ide), "addr", d->devfn + 1); + if (!qdev_realize(DEVICE(&s->ide), BUS(pci_bus), errp)) { + return; + } } /* TYPE_VT82C686B_ISA */ diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c index 44225fbe33..32605901e7 100644 --- a/hw/mips/fuloong2e.c +++ b/hw/mips/fuloong2e.c @@ -199,13 +199,13 @@ static void main_cpu_reset(void *opaque) static void vt82c686b_southbridge_init(PCIBus *pci_bus, int slot, qemu_irq intc, I2CBus **i2c_bus) { - PCIDevice *dev; + PCIDevice *dev, *via; - dev = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(slot, 0), true, + via = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(slot, 0), true, TYPE_VT82C686B_ISA); - qdev_connect_gpio_out(DEVICE(dev), 0, intc); + qdev_connect_gpio_out(DEVICE(via), 0, intc); - dev = pci_create_simple(pci_bus, PCI_DEVFN(slot, 1), TYPE_VIA_IDE); + dev = PCI_DEVICE(object_resolve_path_component(OBJECT(via), "ide")); pci_ide_create_devs(dev); pci_create_simple(pci_bus, PCI_DEVFN(slot, 2), "vt82c686b-usb-uhci"); diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig index 791fe78a50..76a4612d96 100644 --- a/hw/ppc/Kconfig +++ b/hw/ppc/Kconfig @@ -74,7 +74,6 @@ config PEGASOS2 imply ATI_VGA select MV64361 select VT82C686 - select IDE_VIA select SMBUS_EEPROM select VOF # This should come with VT82C686 diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c index 506f273b93..dcb66428dc 100644 --- a/hw/ppc/pegasos2.c +++ b/hw/ppc/pegasos2.c @@ -102,7 +102,7 @@ static void pegasos2_init(MachineState *machine) CPUPPCState *env; MemoryRegion *rom = g_new(MemoryRegion, 1); PCIBus *pci_bus; - PCIDevice *dev; + PCIDevice *dev, *via; I2CBus *i2c_bus; const char *fwname = machine->firmware ?: PROM_FILENAME; char *filename; @@ -160,13 +160,12 @@ static void pegasos2_init(MachineState *machine) /* VIA VT8231 South Bridge (multifunction PCI device) */ /* VT8231 function 0: PCI-to-ISA Bridge */ - dev = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0), true, + via = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0), true, TYPE_VT8231_ISA); - qdev_connect_gpio_out(DEVICE(dev), 0, + qdev_connect_gpio_out(DEVICE(via), 0, qdev_get_gpio_in_named(pm->mv, "gpp", 31)); - /* VT8231 function 1: IDE Controller */ - dev = pci_create_simple(pci_bus, PCI_DEVFN(12, 1), TYPE_VIA_IDE); + dev = PCI_DEVICE(object_resolve_path_component(OBJECT(via), "ide")); pci_ide_create_devs(dev); /* VT8231 function 2-3: USB Ports */ From 65c69e9a9f05ac407ebb2df48b5261f3da21afc9 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Thu, 1 Sep 2022 13:41:21 +0200 Subject: [PATCH 414/705] hw/isa/vt82c686: Introduce TYPE_VT82C686B_USB_UHCI define MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Suggested-by: BALATON Zoltan Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Acked-by: Daniel Henrique Barboza Message-Id: <20220901114127.53914-8-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/mips/fuloong2e.c | 4 ++-- hw/ppc/pegasos2.c | 4 ++-- hw/usb/vt82c686-uhci-pci.c | 4 ++-- include/hw/isa/vt82c686.h | 1 + 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c index 32605901e7..6b7370f2aa 100644 --- a/hw/mips/fuloong2e.c +++ b/hw/mips/fuloong2e.c @@ -208,8 +208,8 @@ static void vt82c686b_southbridge_init(PCIBus *pci_bus, int slot, qemu_irq intc, dev = PCI_DEVICE(object_resolve_path_component(OBJECT(via), "ide")); pci_ide_create_devs(dev); - pci_create_simple(pci_bus, PCI_DEVFN(slot, 2), "vt82c686b-usb-uhci"); - pci_create_simple(pci_bus, PCI_DEVFN(slot, 3), "vt82c686b-usb-uhci"); + pci_create_simple(pci_bus, PCI_DEVFN(slot, 2), TYPE_VT82C686B_USB_UHCI); + pci_create_simple(pci_bus, PCI_DEVFN(slot, 3), TYPE_VT82C686B_USB_UHCI); dev = pci_create_simple(pci_bus, PCI_DEVFN(slot, 4), TYPE_VT82C686B_PM); *i2c_bus = I2C_BUS(qdev_get_child_bus(DEVICE(dev), "i2c")); diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c index dcb66428dc..f999f56565 100644 --- a/hw/ppc/pegasos2.c +++ b/hw/ppc/pegasos2.c @@ -169,8 +169,8 @@ static void pegasos2_init(MachineState *machine) pci_ide_create_devs(dev); /* VT8231 function 2-3: USB Ports */ - pci_create_simple(pci_bus, PCI_DEVFN(12, 2), "vt82c686b-usb-uhci"); - pci_create_simple(pci_bus, PCI_DEVFN(12, 3), "vt82c686b-usb-uhci"); + pci_create_simple(pci_bus, PCI_DEVFN(12, 2), TYPE_VT82C686B_USB_UHCI); + pci_create_simple(pci_bus, PCI_DEVFN(12, 3), TYPE_VT82C686B_USB_UHCI); /* VT8231 function 4: Power Management Controller */ dev = pci_create_simple(pci_bus, PCI_DEVFN(12, 4), TYPE_VT8231_PM); diff --git a/hw/usb/vt82c686-uhci-pci.c b/hw/usb/vt82c686-uhci-pci.c index 0bf2b72ff0..46a901f56f 100644 --- a/hw/usb/vt82c686-uhci-pci.c +++ b/hw/usb/vt82c686-uhci-pci.c @@ -31,7 +31,7 @@ static void usb_uhci_vt82c686b_realize(PCIDevice *dev, Error **errp) static UHCIInfo uhci_info[] = { { - .name = "vt82c686b-usb-uhci", + .name = TYPE_VT82C686B_USB_UHCI, .vendor_id = PCI_VENDOR_ID_VIA, .device_id = PCI_DEVICE_ID_VIA_UHCI, .revision = 0x01, @@ -45,7 +45,7 @@ static UHCIInfo uhci_info[] = { static const TypeInfo vt82c686b_usb_uhci_type_info = { .parent = TYPE_UHCI, - .name = "vt82c686b-usb-uhci", + .name = TYPE_VT82C686B_USB_UHCI, .class_init = uhci_data_class_init, .class_data = uhci_info, }; diff --git a/include/hw/isa/vt82c686.h b/include/hw/isa/vt82c686.h index 87aca3e5bb..e6f6dd4d43 100644 --- a/include/hw/isa/vt82c686.h +++ b/include/hw/isa/vt82c686.h @@ -5,6 +5,7 @@ #define TYPE_VT82C686B_ISA "vt82c686b-isa" #define TYPE_VT82C686B_PM "vt82c686b-pm" +#define TYPE_VT82C686B_USB_UHCI "vt82c686b-usb-uhci" #define TYPE_VT8231_ISA "vt8231-isa" #define TYPE_VT8231_PM "vt8231-pm" #define TYPE_VIA_AC97 "via-ac97" From 1a99ddbe3529bc1b683ef77a1fe29bbb13bf244d Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Thu, 1 Sep 2022 13:41:22 +0200 Subject: [PATCH 415/705] hw/isa/vt82c686: Instantiate USB functions in host device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The USB functions can be enabled/disabled through the ISA function. Also its interrupt routing can be influenced there. Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Acked-by: Daniel Henrique Barboza Message-Id: <20220901114127.53914-9-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/isa/vt82c686.c | 12 ++++++++++++ hw/mips/fuloong2e.c | 3 --- hw/ppc/pegasos2.c | 4 ---- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 63c1e3b8ce..f05fd9948a 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -23,6 +23,7 @@ #include "hw/intc/i8259.h" #include "hw/irq.h" #include "hw/dma/i8257.h" +#include "hw/usb/hcd-uhci.h" #include "hw/timer/i8254.h" #include "hw/rtc/mc146818rtc.h" #include "migration/vmstate.h" @@ -546,6 +547,7 @@ struct ViaISAState { qemu_irq *isa_irqs; ViaSuperIOState via_sio; PCIIDEState ide; + UHCIState uhci[2]; }; static const VMStateDescription vmstate_via = { @@ -563,6 +565,8 @@ static void via_isa_init(Object *obj) ViaISAState *s = VIA_ISA(obj); object_initialize_child(obj, "ide", &s->ide, TYPE_VIA_IDE); + object_initialize_child(obj, "uhci1", &s->uhci[0], TYPE_VT82C686B_USB_UHCI); + object_initialize_child(obj, "uhci2", &s->uhci[1], TYPE_VT82C686B_USB_UHCI); } static const TypeInfo via_isa_info = { @@ -629,6 +633,14 @@ static void via_isa_realize(PCIDevice *d, Error **errp) if (!qdev_realize(DEVICE(&s->ide), BUS(pci_bus), errp)) { return; } + + /* Functions 2-3: USB Ports */ + for (i = 0; i < ARRAY_SIZE(s->uhci); i++) { + qdev_prop_set_int32(DEVICE(&s->uhci[i]), "addr", d->devfn + 2 + i); + if (!qdev_realize(DEVICE(&s->uhci[i]), BUS(pci_bus), errp)) { + return; + } + } } /* TYPE_VT82C686B_ISA */ diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c index 6b7370f2aa..dc92223b76 100644 --- a/hw/mips/fuloong2e.c +++ b/hw/mips/fuloong2e.c @@ -208,9 +208,6 @@ static void vt82c686b_southbridge_init(PCIBus *pci_bus, int slot, qemu_irq intc, dev = PCI_DEVICE(object_resolve_path_component(OBJECT(via), "ide")); pci_ide_create_devs(dev); - pci_create_simple(pci_bus, PCI_DEVFN(slot, 2), TYPE_VT82C686B_USB_UHCI); - pci_create_simple(pci_bus, PCI_DEVFN(slot, 3), TYPE_VT82C686B_USB_UHCI); - dev = pci_create_simple(pci_bus, PCI_DEVFN(slot, 4), TYPE_VT82C686B_PM); *i2c_bus = I2C_BUS(qdev_get_child_bus(DEVICE(dev), "i2c")); diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c index f999f56565..341ca499dd 100644 --- a/hw/ppc/pegasos2.c +++ b/hw/ppc/pegasos2.c @@ -168,10 +168,6 @@ static void pegasos2_init(MachineState *machine) dev = PCI_DEVICE(object_resolve_path_component(OBJECT(via), "ide")); pci_ide_create_devs(dev); - /* VT8231 function 2-3: USB Ports */ - pci_create_simple(pci_bus, PCI_DEVFN(12, 2), TYPE_VT82C686B_USB_UHCI); - pci_create_simple(pci_bus, PCI_DEVFN(12, 3), TYPE_VT82C686B_USB_UHCI); - /* VT8231 function 4: Power Management Controller */ dev = pci_create_simple(pci_bus, PCI_DEVFN(12, 4), TYPE_VT8231_PM); i2c_bus = I2C_BUS(qdev_get_child_bus(DEVICE(dev), "i2c")); From d105377264a87573ba4207d05c1641bb3708710a Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Thu, 1 Sep 2022 13:41:23 +0200 Subject: [PATCH 416/705] hw/isa/vt82c686: Instantiate PM function in host device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PM controller has activity bits which monitor activity of other built-in devices in the host device. Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Acked-by: Daniel Henrique Barboza Message-Id: <20220901114127.53914-10-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/isa/vt82c686.c | 13 +++++++++++++ hw/mips/fuloong2e.c | 2 +- hw/ppc/pegasos2.c | 3 +-- include/hw/isa/vt82c686.h | 2 -- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index f05fd9948a..d048607079 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -250,6 +250,8 @@ static const ViaPMInitInfo vt82c686b_pm_init_info = { .device_id = PCI_DEVICE_ID_VIA_82C686B_PM, }; +#define TYPE_VT82C686B_PM "vt82c686b-pm" + static const TypeInfo vt82c686b_pm_info = { .name = TYPE_VT82C686B_PM, .parent = TYPE_VIA_PM, @@ -261,6 +263,8 @@ static const ViaPMInitInfo vt8231_pm_init_info = { .device_id = PCI_DEVICE_ID_VIA_8231_PM, }; +#define TYPE_VT8231_PM "vt8231-pm" + static const TypeInfo vt8231_pm_info = { .name = TYPE_VT8231_PM, .parent = TYPE_VIA_PM, @@ -548,6 +552,7 @@ struct ViaISAState { ViaSuperIOState via_sio; PCIIDEState ide; UHCIState uhci[2]; + ViaPMState pm; }; static const VMStateDescription vmstate_via = { @@ -641,6 +646,12 @@ static void via_isa_realize(PCIDevice *d, Error **errp) return; } } + + /* Function 4: Power Management */ + qdev_prop_set_int32(DEVICE(&s->pm), "addr", d->devfn + 4); + if (!qdev_realize(DEVICE(&s->pm), BUS(pci_bus), errp)) { + return; + } } /* TYPE_VT82C686B_ISA */ @@ -683,6 +694,7 @@ static void vt82c686b_init(Object *obj) ViaISAState *s = VIA_ISA(obj); object_initialize_child(obj, "sio", &s->via_sio, TYPE_VT82C686B_SUPERIO); + object_initialize_child(obj, "pm", &s->pm, TYPE_VT82C686B_PM); } static void vt82c686b_class_init(ObjectClass *klass, void *data) @@ -746,6 +758,7 @@ static void vt8231_init(Object *obj) ViaISAState *s = VIA_ISA(obj); object_initialize_child(obj, "sio", &s->via_sio, TYPE_VT8231_SUPERIO); + object_initialize_child(obj, "pm", &s->pm, TYPE_VT8231_PM); } static void vt8231_class_init(ObjectClass *klass, void *data) diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c index dc92223b76..377108d313 100644 --- a/hw/mips/fuloong2e.c +++ b/hw/mips/fuloong2e.c @@ -208,7 +208,7 @@ static void vt82c686b_southbridge_init(PCIBus *pci_bus, int slot, qemu_irq intc, dev = PCI_DEVICE(object_resolve_path_component(OBJECT(via), "ide")); pci_ide_create_devs(dev); - dev = pci_create_simple(pci_bus, PCI_DEVFN(slot, 4), TYPE_VT82C686B_PM); + dev = PCI_DEVICE(object_resolve_path_component(OBJECT(via), "pm")); *i2c_bus = I2C_BUS(qdev_get_child_bus(DEVICE(dev), "i2c")); /* Audio support */ diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c index 341ca499dd..1443f90a8c 100644 --- a/hw/ppc/pegasos2.c +++ b/hw/ppc/pegasos2.c @@ -168,8 +168,7 @@ static void pegasos2_init(MachineState *machine) dev = PCI_DEVICE(object_resolve_path_component(OBJECT(via), "ide")); pci_ide_create_devs(dev); - /* VT8231 function 4: Power Management Controller */ - dev = pci_create_simple(pci_bus, PCI_DEVFN(12, 4), TYPE_VT8231_PM); + dev = PCI_DEVICE(object_resolve_path_component(OBJECT(via), "pm")); i2c_bus = I2C_BUS(qdev_get_child_bus(DEVICE(dev), "i2c")); spd_data = spd_data_generate(DDR, machine->ram_size); smbus_eeprom_init_one(i2c_bus, 0x57, spd_data); diff --git a/include/hw/isa/vt82c686.h b/include/hw/isa/vt82c686.h index e6f6dd4d43..eaa07881c5 100644 --- a/include/hw/isa/vt82c686.h +++ b/include/hw/isa/vt82c686.h @@ -4,10 +4,8 @@ #include "hw/pci/pci.h" #define TYPE_VT82C686B_ISA "vt82c686b-isa" -#define TYPE_VT82C686B_PM "vt82c686b-pm" #define TYPE_VT82C686B_USB_UHCI "vt82c686b-usb-uhci" #define TYPE_VT8231_ISA "vt8231-isa" -#define TYPE_VT8231_PM "vt8231-pm" #define TYPE_VIA_AC97 "via-ac97" #define TYPE_VIA_IDE "via-ide" #define TYPE_VIA_MC97 "via-mc97" From 0a8d405d69394f84a28cde79949612ec36d3fcda Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Thu, 1 Sep 2022 13:41:24 +0200 Subject: [PATCH 417/705] hw/isa/vt82c686: Instantiate AC97 and MC97 functions in host device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The AC97 function's wakeup status is wired to the PM function and both the AC97 and MC97 interrupt routing is determined by the ISA function. Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Acked-by: Daniel Henrique Barboza Message-Id: <20220901114127.53914-11-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/isa/vt82c686.c | 16 ++++++++++++++++ hw/mips/fuloong2e.c | 4 ---- hw/ppc/pegasos2.c | 5 ----- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index d048607079..91686e9570 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -553,6 +553,8 @@ struct ViaISAState { PCIIDEState ide; UHCIState uhci[2]; ViaPMState pm; + PCIDevice ac97; + PCIDevice mc97; }; static const VMStateDescription vmstate_via = { @@ -572,6 +574,8 @@ static void via_isa_init(Object *obj) object_initialize_child(obj, "ide", &s->ide, TYPE_VIA_IDE); object_initialize_child(obj, "uhci1", &s->uhci[0], TYPE_VT82C686B_USB_UHCI); object_initialize_child(obj, "uhci2", &s->uhci[1], TYPE_VT82C686B_USB_UHCI); + object_initialize_child(obj, "ac97", &s->ac97, TYPE_VIA_AC97); + object_initialize_child(obj, "mc97", &s->mc97, TYPE_VIA_MC97); } static const TypeInfo via_isa_info = { @@ -652,6 +656,18 @@ static void via_isa_realize(PCIDevice *d, Error **errp) if (!qdev_realize(DEVICE(&s->pm), BUS(pci_bus), errp)) { return; } + + /* Function 5: AC97 Audio */ + qdev_prop_set_int32(DEVICE(&s->ac97), "addr", d->devfn + 5); + if (!qdev_realize(DEVICE(&s->ac97), BUS(pci_bus), errp)) { + return; + } + + /* Function 6: MC97 Modem */ + qdev_prop_set_int32(DEVICE(&s->mc97), "addr", d->devfn + 6); + if (!qdev_realize(DEVICE(&s->mc97), BUS(pci_bus), errp)) { + return; + } } /* TYPE_VT82C686B_ISA */ diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c index 377108d313..2d8723ab74 100644 --- a/hw/mips/fuloong2e.c +++ b/hw/mips/fuloong2e.c @@ -210,10 +210,6 @@ static void vt82c686b_southbridge_init(PCIBus *pci_bus, int slot, qemu_irq intc, dev = PCI_DEVICE(object_resolve_path_component(OBJECT(via), "pm")); *i2c_bus = I2C_BUS(qdev_get_child_bus(DEVICE(dev), "i2c")); - - /* Audio support */ - pci_create_simple(pci_bus, PCI_DEVFN(slot, 5), TYPE_VIA_AC97); - pci_create_simple(pci_bus, PCI_DEVFN(slot, 6), TYPE_VIA_MC97); } /* Network support */ diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c index 1443f90a8c..7dafac4064 100644 --- a/hw/ppc/pegasos2.c +++ b/hw/ppc/pegasos2.c @@ -159,7 +159,6 @@ static void pegasos2_init(MachineState *machine) pci_bus = mv64361_get_pci_bus(pm->mv, 1); /* VIA VT8231 South Bridge (multifunction PCI device) */ - /* VT8231 function 0: PCI-to-ISA Bridge */ via = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0), true, TYPE_VT8231_ISA); qdev_connect_gpio_out(DEVICE(via), 0, @@ -173,10 +172,6 @@ static void pegasos2_init(MachineState *machine) spd_data = spd_data_generate(DDR, machine->ram_size); smbus_eeprom_init_one(i2c_bus, 0x57, spd_data); - /* VT8231 function 5-6: AC97 Audio & Modem */ - pci_create_simple(pci_bus, PCI_DEVFN(12, 5), TYPE_VIA_AC97); - pci_create_simple(pci_bus, PCI_DEVFN(12, 6), TYPE_VIA_MC97); - /* other PC hardware */ pci_vga_init(pci_bus); From 4ff5328bf7d503805cc1baba9e4de47216f407d0 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Thu, 1 Sep 2022 13:41:25 +0200 Subject: [PATCH 418/705] hw/mips/fuloong2e: Inline vt82c686b_southbridge_init() and remove it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous patches moved most of this function into the via-isa device model such that it has become fairly trivial. So inline it for simplicity. Suggested-by: BALATON Zoltan Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20220901114127.53914-12-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/mips/fuloong2e.c | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c index 2d8723ab74..3c46215616 100644 --- a/hw/mips/fuloong2e.c +++ b/hw/mips/fuloong2e.c @@ -196,22 +196,6 @@ static void main_cpu_reset(void *opaque) } } -static void vt82c686b_southbridge_init(PCIBus *pci_bus, int slot, qemu_irq intc, - I2CBus **i2c_bus) -{ - PCIDevice *dev, *via; - - via = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(slot, 0), true, - TYPE_VT82C686B_ISA); - qdev_connect_gpio_out(DEVICE(via), 0, intc); - - dev = PCI_DEVICE(object_resolve_path_component(OBJECT(via), "ide")); - pci_ide_create_devs(dev); - - dev = PCI_DEVICE(object_resolve_path_component(OBJECT(via), "pm")); - *i2c_bus = I2C_BUS(qdev_get_child_bus(DEVICE(dev), "i2c")); -} - /* Network support */ static void network_init(PCIBus *pci_bus) { @@ -308,8 +292,16 @@ static void mips_fuloong2e_init(MachineState *machine) pci_bus = bonito_init((qemu_irq *)&(env->irq[2])); /* South bridge -> IP5 */ - vt82c686b_southbridge_init(pci_bus, FULOONG2E_VIA_SLOT, env->irq[5], - &smbus); + pci_dev = pci_create_simple_multifunction(pci_bus, + PCI_DEVFN(FULOONG2E_VIA_SLOT, 0), + true, TYPE_VT82C686B_ISA); + qdev_connect_gpio_out(DEVICE(pci_dev), 0, env->irq[5]); + + dev = DEVICE(object_resolve_path_component(OBJECT(pci_dev), "ide")); + pci_ide_create_devs(PCI_DEVICE(dev)); + + dev = DEVICE(object_resolve_path_component(OBJECT(pci_dev), "pm")); + smbus = I2C_BUS(qdev_get_child_bus(dev, "i2c")); /* GPU */ if (vga_interface_type != VGA_NONE) { From 3ecb2e62f98b876d5134429f84437e6f6956d212 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Thu, 1 Sep 2022 13:41:26 +0200 Subject: [PATCH 419/705] hw/isa/vt82c686: Embed RTCState in host device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Embed the rtc in the host device, analoguous to the other child devices and analoguous to PIIX4. Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20220901114127.53914-13-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/isa/vt82c686.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 91686e9570..48cd4d0036 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -550,6 +550,7 @@ struct ViaISAState { qemu_irq cpu_intr; qemu_irq *isa_irqs; ViaSuperIOState via_sio; + RTCState rtc; PCIIDEState ide; UHCIState uhci[2]; ViaPMState pm; @@ -571,6 +572,7 @@ static void via_isa_init(Object *obj) { ViaISAState *s = VIA_ISA(obj); + object_initialize_child(obj, "rtc", &s->rtc, TYPE_MC146818_RTC); object_initialize_child(obj, "ide", &s->ide, TYPE_VIA_IDE); object_initialize_child(obj, "uhci1", &s->uhci[0], TYPE_VT82C686B_USB_UHCI); object_initialize_child(obj, "uhci2", &s->uhci[1], TYPE_VT82C686B_USB_UHCI); @@ -624,7 +626,15 @@ static void via_isa_realize(PCIDevice *d, Error **errp) isa_bus_irqs(isa_bus, s->isa_irqs); i8254_pit_init(isa_bus, 0x40, 0, NULL); i8257_dma_init(isa_bus, 0); - mc146818_rtc_init(isa_bus, 2000, NULL); + + /* RTC */ + qdev_prop_set_int32(DEVICE(&s->rtc), "base_year", 2000); + if (!qdev_realize(DEVICE(&s->rtc), BUS(isa_bus), errp)) { + return; + } + object_property_add_alias(qdev_get_machine(), "rtc-time", OBJECT(&s->rtc), + "date"); + isa_connect_gpio_out(ISA_DEVICE(&s->rtc), 0, s->rtc.isairq); for (i = 0; i < PCI_CONFIG_HEADER_SIZE; i++) { if (i < PCI_COMMAND || i >= PCI_REVISION_ID) { From ff9105dabc5edeab8328e0b639a21c7ef555161e Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Thu, 1 Sep 2022 13:41:27 +0200 Subject: [PATCH 420/705] hw/isa/vt82c686: Create rtc-time alias in boards instead MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to good QOM practice, an object should only deal with objects of its own sub tree. Having devices create an alias on the machine object doesn't respect this good practice. To resolve this, create the alias in the machine's code. Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Acked-by: Daniel Henrique Barboza Message-Id: <20220901114127.53914-14-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/isa/vt82c686.c | 2 -- hw/mips/fuloong2e.c | 4 ++++ hw/ppc/pegasos2.c | 4 ++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 48cd4d0036..3f9bd0c04d 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -632,8 +632,6 @@ static void via_isa_realize(PCIDevice *d, Error **errp) if (!qdev_realize(DEVICE(&s->rtc), BUS(isa_bus), errp)) { return; } - object_property_add_alias(qdev_get_machine(), "rtc-time", OBJECT(&s->rtc), - "date"); isa_connect_gpio_out(ISA_DEVICE(&s->rtc), 0, s->rtc.isairq); for (i = 0; i < PCI_CONFIG_HEADER_SIZE; i++) { diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c index 3c46215616..b478483706 100644 --- a/hw/mips/fuloong2e.c +++ b/hw/mips/fuloong2e.c @@ -295,6 +295,10 @@ static void mips_fuloong2e_init(MachineState *machine) pci_dev = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(FULOONG2E_VIA_SLOT, 0), true, TYPE_VT82C686B_ISA); + object_property_add_alias(OBJECT(machine), "rtc-time", + object_resolve_path_component(OBJECT(pci_dev), + "rtc"), + "date"); qdev_connect_gpio_out(DEVICE(pci_dev), 0, env->irq[5]); dev = DEVICE(object_resolve_path_component(OBJECT(pci_dev), "ide")); diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c index 7dafac4064..f46d4bf51d 100644 --- a/hw/ppc/pegasos2.c +++ b/hw/ppc/pegasos2.c @@ -161,6 +161,10 @@ static void pegasos2_init(MachineState *machine) /* VIA VT8231 South Bridge (multifunction PCI device) */ via = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0), true, TYPE_VT8231_ISA); + object_property_add_alias(OBJECT(machine), "rtc-time", + object_resolve_path_component(OBJECT(via), + "rtc"), + "date"); qdev_connect_gpio_out(DEVICE(via), 0, qdev_get_gpio_in_named(pm->mv, "gpp", 31)); From 8466405eb0c77d81be5f8c2e3608fdfeb00bb1b9 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Sat, 17 Sep 2022 13:51:36 +0200 Subject: [PATCH 421/705] hw: Remove unused MAX_IDE_BUS define MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Several machines have an unused MAX_IDE_BUS define. Remove it from these machines that don't need it. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20220917115136.A32EF746E06@zero.eik.bme.hu> Signed-off-by: Philippe Mathieu-Daudé --- hw/alpha/dp264.c | 2 -- hw/hppa/machine.c | 2 -- hw/mips/fuloong2e.c | 1 - hw/mips/malta.c | 2 -- hw/ppc/prep.c | 2 -- hw/sparc64/sun4u.c | 1 - 6 files changed, 10 deletions(-) diff --git a/hw/alpha/dp264.c b/hw/alpha/dp264.c index f4349eba83..c502c8c62a 100644 --- a/hw/alpha/dp264.c +++ b/hw/alpha/dp264.c @@ -20,8 +20,6 @@ #include "qemu/datadir.h" #include "net/net.h" -#define MAX_IDE_BUS 2 - static uint64_t cpu_alpha_superpage_to_phys(void *opaque, uint64_t addr) { if (((addr >> 41) & 3) == 2) { diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c index 19ea7c2c66..de1cc7ab71 100644 --- a/hw/hppa/machine.c +++ b/hw/hppa/machine.c @@ -30,8 +30,6 @@ #include "qemu/log.h" #include "net/net.h" -#define MAX_IDE_BUS 2 - #define MIN_SEABIOS_HPPA_VERSION 6 /* require at least this fw version */ #define HPA_POWER_BUTTON (FIRMWARE_END - 0x10) diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c index b478483706..50c61f0e4a 100644 --- a/hw/mips/fuloong2e.c +++ b/hw/mips/fuloong2e.c @@ -49,7 +49,6 @@ /* Fuloong 2e has a 512k flash: Winbond W39L040AP70Z */ #define BIOS_SIZE (512 * KiB) -#define MAX_IDE_BUS 2 /* * PMON is not part of qemu and released with BSD license, anyone diff --git a/hw/mips/malta.c b/hw/mips/malta.c index 7c3ad0974b..2d4341bd50 100644 --- a/hw/mips/malta.c +++ b/hw/mips/malta.c @@ -70,8 +70,6 @@ #define FLASH_SIZE 0x400000 -#define MAX_IDE_BUS 2 - typedef struct { MemoryRegion iomem; MemoryRegion iomem_lo; /* 0 - 0x900 */ diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c index f08714f2ec..fcbe4c5837 100644 --- a/hw/ppc/prep.c +++ b/hw/ppc/prep.c @@ -50,8 +50,6 @@ /* SMP is not enabled, for now */ #define MAX_CPUS 1 -#define MAX_IDE_BUS 2 - #define CFG_ADDR 0xf0000510 #define KERNEL_LOAD_ADDR 0x01000000 diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c index 0e27715ac4..387181ff77 100644 --- a/hw/sparc64/sun4u.c +++ b/hw/sparc64/sun4u.c @@ -66,7 +66,6 @@ #define PBM_PCI_IO_BASE (PBM_SPECIAL_BASE + 0x02000000ULL) #define PROM_FILENAME "openbios-sparc64" #define NVRAM_SIZE 0x2000 -#define MAX_IDE_BUS 2 #define BIOS_CFG_IOPORT 0x510 #define FW_CFG_SPARC64_WIDTH (FW_CFG_ARCH_LOCAL + 0x00) #define FW_CFG_SPARC64_HEIGHT (FW_CFG_ARCH_LOCAL + 0x01) From c52316925c4e3bf6aef1b12e6cfec5ba53e4ff28 Mon Sep 17 00:00:00 2001 From: Milica Lazarevic Date: Mon, 12 Sep 2022 14:26:12 +0200 Subject: [PATCH 422/705] disas/nanomips: Remove namespace img MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since there's no namespace feature in C, namespace img has been replaced with adding the prefix "img" to the namespace members. Prefix "img" has been added to the function names of functions that used to be wrapped in namespace img. Those are img::format() functions. I.e. replaced img::format with the img_format. Typedef address that used to belong to namespace img now is called img_address. Signed-off-by: Milica Lazarevic Reviewed-by: Thomas Huth Reviewed-by: Richard Henderson Message-Id: <20220912122635.74032-2-milica.lazarevic@syrmia.com> Signed-off-by: Philippe Mathieu-Daudé --- disas/nanomips.cpp | 1433 ++++++++++++++++++++++---------------------- disas/nanomips.h | 10 +- 2 files changed, 712 insertions(+), 731 deletions(-) diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp index 9be8df75dd..84529685bf 100644 --- a/disas/nanomips.cpp +++ b/disas/nanomips.cpp @@ -137,131 +137,118 @@ int print_insn_nanomips(bfd_vma memaddr, struct disassemble_info *info) } -namespace img +std::string img_format(const char *format, ...) { - address addr32(address a) - { - return a; + char buffer[256]; + va_list args; + va_start(args, format); + int err = vsprintf(buffer, format, args); + if (err < 0) { + perror(buffer); } + va_end(args); + return buffer; +} - std::string format(const char *format, ...) - { - char buffer[256]; - va_list args; - va_start(args, format); - int err = vsprintf(buffer, format, args); - if (err < 0) { - perror(buffer); - } - va_end(args); - return buffer; - } +std::string img_format(const char *format, + std::string s) +{ + char buffer[256]; - std::string format(const char *format, - std::string s) - { - char buffer[256]; + sprintf(buffer, format, s.c_str()); - sprintf(buffer, format, s.c_str()); + return buffer; +} - return buffer; - } +std::string img_format(const char *format, + std::string s1, + std::string s2) +{ + char buffer[256]; - std::string format(const char *format, - std::string s1, - std::string s2) - { - char buffer[256]; + sprintf(buffer, format, s1.c_str(), s2.c_str()); - sprintf(buffer, format, s1.c_str(), s2.c_str()); + return buffer; +} - return buffer; - } +std::string img_format(const char *format, + std::string s1, + std::string s2, + std::string s3) +{ + char buffer[256]; - std::string format(const char *format, - std::string s1, - std::string s2, - std::string s3) - { - char buffer[256]; + sprintf(buffer, format, s1.c_str(), s2.c_str(), s3.c_str()); - sprintf(buffer, format, s1.c_str(), s2.c_str(), s3.c_str()); + return buffer; +} - return buffer; - } +std::string img_format(const char *format, + std::string s1, + std::string s2, + std::string s3, + std::string s4) +{ + char buffer[256]; - std::string format(const char *format, - std::string s1, - std::string s2, - std::string s3, - std::string s4) - { - char buffer[256]; + sprintf(buffer, format, s1.c_str(), s2.c_str(), s3.c_str(), + s4.c_str()); - sprintf(buffer, format, s1.c_str(), s2.c_str(), s3.c_str(), - s4.c_str()); + return buffer; +} - return buffer; - } +std::string img_format(const char *format, + std::string s1, + std::string s2, + std::string s3, + std::string s4, + std::string s5) +{ + char buffer[256]; - std::string format(const char *format, - std::string s1, - std::string s2, - std::string s3, - std::string s4, - std::string s5) - { - char buffer[256]; + sprintf(buffer, format, s1.c_str(), s2.c_str(), s3.c_str(), + s4.c_str(), s5.c_str()); - sprintf(buffer, format, s1.c_str(), s2.c_str(), s3.c_str(), - s4.c_str(), s5.c_str()); + return buffer; +} - return buffer; - } +std::string img_format(const char *format, + uint64 d, + std::string s2) +{ + char buffer[256]; - std::string format(const char *format, - uint64 d, - std::string s2) - { - char buffer[256]; + sprintf(buffer, format, d, s2.c_str()); - sprintf(buffer, format, d, s2.c_str()); + return buffer; +} - return buffer; - } +std::string img_format(const char *format, + std::string s1, + uint64 d, + std::string s2) +{ + char buffer[256]; - std::string format(const char *format, - std::string s1, - uint64 d, - std::string s2) - { - char buffer[256]; + sprintf(buffer, format, s1.c_str(), d, s2.c_str()); - sprintf(buffer, format, s1.c_str(), d, s2.c_str()); + return buffer; +} - return buffer; - } +std::string img_format(const char *format, + std::string s1, + std::string s2, + uint64 d) +{ + char buffer[256]; - std::string format(const char *format, - std::string s1, - std::string s2, - uint64 d) - { - char buffer[256]; + sprintf(buffer, format, s1.c_str(), s2.c_str(), d); - sprintf(buffer, format, s1.c_str(), s2.c_str(), d); - - return buffer; - } - - char as_char(int c) - { - return static_cast(c); - } -}; + return buffer; +} -std::string to_string(img::address a) +std::string to_string(img_address a) { char buffer[256]; sprintf(buffer, "0x%" PRIx64, a); @@ -289,7 +276,7 @@ uint64 NMD::renumber_registers(uint64 index, uint64 *register_list, return register_list[index]; } - throw std::runtime_error(img::format( + throw std::runtime_error(img_format( "Invalid register mapping index %" PRIu64 ", size of list = %zu", index, register_list_size)); @@ -683,7 +670,7 @@ std::string NMD::save_restore_list(uint64 rt, uint64 count, uint64 gp) for (uint64 counter = 0; counter != count; counter++) { bool use_gp = gp && (counter == count - 1); uint64 this_rt = use_gp ? 28 : ((rt & 0x10) | (rt + counter)) & 0x1f; - str += img::format(",%s", GPR(this_rt)); + str += img_format(",%s", GPR(this_rt)); } return str; @@ -703,7 +690,7 @@ std::string NMD::GPR(uint64 reg) return gpr_reg[reg]; } - throw std::runtime_error(img::format("Invalid GPR register index %" PRIu64, + throw std::runtime_error(img_format("Invalid GPR register index %" PRIu64, reg)); } @@ -721,7 +708,7 @@ std::string NMD::FPR(uint64 reg) return fpr_reg[reg]; } - throw std::runtime_error(img::format("Invalid FPR register index %" PRIu64, + throw std::runtime_error(img_format("Invalid FPR register index %" PRIu64, reg)); } @@ -736,37 +723,35 @@ std::string NMD::AC(uint64 reg) return ac_reg[reg]; } - throw std::runtime_error(img::format("Invalid AC register index %" PRIu64, + throw std::runtime_error(img_format("Invalid AC register index %" PRIu64, reg)); } std::string NMD::IMMEDIATE(uint64 value) { - return img::format("0x%" PRIx64, value); + return img_format("0x%" PRIx64, value); } std::string NMD::IMMEDIATE(int64 value) { - return img::format("%" PRId64, value); + return img_format("%" PRId64, value); } std::string NMD::CPR(uint64 reg) { /* needs more work */ - return img::format("CP%" PRIu64, reg); + return img_format("CP%" PRIu64, reg); } std::string NMD::ADDRESS(uint64 value, int instruction_size) { /* token for string replace */ - /* const char TOKEN_REPLACE = (char)0xa2; */ - img::address address = m_pc + value + instruction_size; + img_address address = m_pc + value + instruction_size; /* symbol replacement */ - /* return img::as_char(TOKEN_REPLACE) + to_string(address); */ return to_string(address); } @@ -1807,7 +1792,7 @@ std::string NMD::ABS_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string fd = FPR(copy(fd_value)); - return img::format("ABS.D %s, %s", fd, fs); + return img_format("ABS.D %s, %s", fd, fs); } @@ -1829,7 +1814,7 @@ std::string NMD::ABS_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string fd = FPR(copy(fd_value)); - return img::format("ABS.S %s, %s", fd, fs); + return img_format("ABS.S %s, %s", fd, fs); } @@ -1851,7 +1836,7 @@ std::string NMD::ABSQ_S_PH(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("ABSQ_S.PH %s, %s", rt, rs); + return img_format("ABSQ_S.PH %s, %s", rt, rs); } @@ -1873,7 +1858,7 @@ std::string NMD::ABSQ_S_QB(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("ABSQ_S.QB %s, %s", rt, rs); + return img_format("ABSQ_S.QB %s, %s", rt, rs); } @@ -1895,7 +1880,7 @@ std::string NMD::ABSQ_S_W(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("ABSQ_S.W %s, %s", rt, rs); + return img_format("ABSQ_S.W %s, %s", rt, rs); } @@ -1918,7 +1903,7 @@ std::string NMD::ACLR(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("ACLR %s, %s(%s)", bit, s, rs); + return img_format("ACLR %s, %s(%s)", bit, s, rs); } @@ -1941,7 +1926,7 @@ std::string NMD::ADD(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("ADD %s, %s, %s", rd, rs, rt); + return img_format("ADD %s, %s, %s", rd, rs, rt); } @@ -1966,7 +1951,7 @@ std::string NMD::ADD_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string fd = FPR(copy(fd_value)); - return img::format("ADD.D %s, %s, %s", fd, fs, ft); + return img_format("ADD.D %s, %s, %s", fd, fs, ft); } @@ -1991,7 +1976,7 @@ std::string NMD::ADD_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string fd = FPR(copy(fd_value)); - return img::format("ADD.S %s, %s, %s", fd, fs, ft); + return img_format("ADD.S %s, %s, %s", fd, fs, ft); } @@ -2014,7 +1999,7 @@ std::string NMD::ADDIU_32_(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string u = IMMEDIATE(copy(u_value)); - return img::format("ADDIU %s, %s, %s", rt, rs, u); + return img_format("ADDIU %s, %s, %s", rt, rs, u); } @@ -2035,7 +2020,7 @@ std::string NMD::ADDIU_48_(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string s = IMMEDIATE(copy(s_value)); - return img::format("ADDIU %s, %s", rt, s); + return img_format("ADDIU %s, %s", rt, s); } @@ -2056,7 +2041,7 @@ std::string NMD::ADDIU_GP48_(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string s = IMMEDIATE(copy(s_value)); - return img::format("ADDIU %s, $%d, %s", rt, 28, s); + return img_format("ADDIU %s, $%d, %s", rt, 28, s); } @@ -2077,7 +2062,7 @@ std::string NMD::ADDIU_GP_B_(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string u = IMMEDIATE(copy(u_value)); - return img::format("ADDIU %s, $%d, %s", rt, 28, u); + return img_format("ADDIU %s, $%d, %s", rt, 28, u); } @@ -2098,7 +2083,7 @@ std::string NMD::ADDIU_GP_W_(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string u = IMMEDIATE(copy(u_value)); - return img::format("ADDIU %s, $%d, %s", rt, 28, u); + return img_format("ADDIU %s, $%d, %s", rt, 28, u); } @@ -2121,7 +2106,7 @@ std::string NMD::ADDIU_NEG_(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string u = IMMEDIATE(neg_copy(u_value)); - return img::format("ADDIU %s, %s, %s", rt, rs, u); + return img_format("ADDIU %s, %s, %s", rt, rs, u); } @@ -2142,7 +2127,7 @@ std::string NMD::ADDIU_R1_SP_(uint64 instruction) std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); std::string u = IMMEDIATE(copy(u_value)); - return img::format("ADDIU %s, $%d, %s", rt3, 29, u); + return img_format("ADDIU %s, $%d, %s", rt3, 29, u); } @@ -2165,7 +2150,7 @@ std::string NMD::ADDIU_R2_(uint64 instruction) std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); std::string u = IMMEDIATE(copy(u_value)); - return img::format("ADDIU %s, %s, %s", rt3, rs3, u); + return img_format("ADDIU %s, %s, %s", rt3, rs3, u); } @@ -2185,7 +2170,7 @@ std::string NMD::ADDIU_RS5_(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string s = IMMEDIATE(copy(s_value)); - return img::format("ADDIU %s, %s", rt, s); + return img_format("ADDIU %s, %s", rt, s); } @@ -2207,7 +2192,7 @@ std::string NMD::ADDIUPC_32_(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string s = ADDRESS(encode_s_from_address(s_value), 4); - return img::format("ADDIUPC %s, %s", rt, s); + return img_format("ADDIUPC %s, %s", rt, s); } @@ -2229,7 +2214,7 @@ std::string NMD::ADDIUPC_48_(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string s = ADDRESS(encode_s_from_address(s_value), 6); - return img::format("ADDIUPC %s, %s", rt, s); + return img_format("ADDIUPC %s, %s", rt, s); } @@ -2253,7 +2238,7 @@ std::string NMD::ADDQ_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("ADDQ.PH %s, %s, %s", rd, rs, rt); + return img_format("ADDQ.PH %s, %s, %s", rd, rs, rt); } @@ -2278,7 +2263,7 @@ std::string NMD::ADDQ_S_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("ADDQ_S.PH %s, %s, %s", rd, rs, rt); + return img_format("ADDQ_S.PH %s, %s, %s", rd, rs, rt); } @@ -2302,7 +2287,7 @@ std::string NMD::ADDQ_S_W(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("ADDQ_S.W %s, %s, %s", rd, rs, rt); + return img_format("ADDQ_S.W %s, %s, %s", rd, rs, rt); } @@ -2327,7 +2312,7 @@ std::string NMD::ADDQH_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("ADDQH.PH %s, %s, %s", rd, rs, rt); + return img_format("ADDQH.PH %s, %s, %s", rd, rs, rt); } @@ -2352,7 +2337,7 @@ std::string NMD::ADDQH_R_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("ADDQH_R.PH %s, %s, %s", rd, rs, rt); + return img_format("ADDQH_R.PH %s, %s, %s", rd, rs, rt); } @@ -2377,7 +2362,7 @@ std::string NMD::ADDQH_R_W(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("ADDQH_R.W %s, %s, %s", rd, rs, rt); + return img_format("ADDQH_R.W %s, %s, %s", rd, rs, rt); } @@ -2402,7 +2387,7 @@ std::string NMD::ADDQH_W(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("ADDQH.W %s, %s, %s", rd, rs, rt); + return img_format("ADDQH.W %s, %s, %s", rd, rs, rt); } @@ -2426,7 +2411,7 @@ std::string NMD::ADDSC(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("ADDSC %s, %s, %s", rd, rs, rt); + return img_format("ADDSC %s, %s, %s", rd, rs, rt); } @@ -2449,7 +2434,7 @@ std::string NMD::ADDU_16_(uint64 instruction) std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); std::string rd3 = GPR(decode_gpr_gpr3(rd3_value)); - return img::format("ADDU %s, %s, %s", rd3, rs3, rt3); + return img_format("ADDU %s, %s, %s", rd3, rs3, rt3); } @@ -2473,7 +2458,7 @@ std::string NMD::ADDU_32_(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("ADDU %s, %s, %s", rd, rs, rt); + return img_format("ADDU %s, %s, %s", rd, rs, rt); } @@ -2495,7 +2480,7 @@ std::string NMD::ADDU_4X4_(uint64 instruction) std::string rs4 = GPR(decode_gpr_gpr4(rs4_value)); std::string rt4 = GPR(decode_gpr_gpr4(rt4_value)); - return img::format("ADDU %s, %s", rs4, rt4); + return img_format("ADDU %s, %s", rs4, rt4); } @@ -2519,7 +2504,7 @@ std::string NMD::ADDU_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("ADDU.PH %s, %s, %s", rd, rs, rt); + return img_format("ADDU.PH %s, %s, %s", rd, rs, rt); } @@ -2543,7 +2528,7 @@ std::string NMD::ADDU_QB(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("ADDU.QB %s, %s, %s", rd, rs, rt); + return img_format("ADDU.QB %s, %s, %s", rd, rs, rt); } @@ -2568,7 +2553,7 @@ std::string NMD::ADDU_S_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("ADDU_S.PH %s, %s, %s", rd, rs, rt); + return img_format("ADDU_S.PH %s, %s, %s", rd, rs, rt); } @@ -2592,7 +2577,7 @@ std::string NMD::ADDU_S_QB(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("ADDU_S.QB %s, %s, %s", rd, rs, rt); + return img_format("ADDU_S.QB %s, %s, %s", rd, rs, rt); } @@ -2617,7 +2602,7 @@ std::string NMD::ADDUH_QB(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("ADDUH.QB %s, %s, %s", rd, rs, rt); + return img_format("ADDUH.QB %s, %s, %s", rd, rs, rt); } @@ -2642,7 +2627,7 @@ std::string NMD::ADDUH_R_QB(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("ADDUH_R.QB %s, %s, %s", rd, rs, rt); + return img_format("ADDUH_R.QB %s, %s, %s", rd, rs, rt); } /* @@ -2665,7 +2650,7 @@ std::string NMD::ADDWC(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("ADDWC %s, %s, %s", rd, rs, rt); + return img_format("ADDWC %s, %s, %s", rd, rs, rt); } @@ -2687,7 +2672,7 @@ std::string NMD::ALUIPC(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string s = ADDRESS(encode_s_from_address(s_value), 4); - return img::format("ALUIPC %s, %%pcrel_hi(%s)", rt, s); + return img_format("ALUIPC %s, %%pcrel_hi(%s)", rt, s); } @@ -2708,7 +2693,7 @@ std::string NMD::AND_16_(uint64 instruction) std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); - return img::format("AND %s, %s", rs3, rt3); + return img_format("AND %s, %s", rs3, rt3); } @@ -2732,7 +2717,7 @@ std::string NMD::AND_32_(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("AND %s, %s, %s", rd, rs, rt); + return img_format("AND %s, %s, %s", rd, rs, rt); } @@ -2755,7 +2740,7 @@ std::string NMD::ANDI_16_(uint64 instruction) std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); std::string eu = IMMEDIATE(encode_eu_from_u_andi16(eu_value)); - return img::format("ANDI %s, %s, %s", rt3, rs3, eu); + return img_format("ANDI %s, %s, %s", rt3, rs3, eu); } @@ -2779,7 +2764,7 @@ std::string NMD::ANDI_32_(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string u = IMMEDIATE(copy(u_value)); - return img::format("ANDI %s, %s, %s", rt, rs, u); + return img_format("ANDI %s, %s, %s", rt, rs, u); } @@ -2803,7 +2788,7 @@ std::string NMD::APPEND(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string sa = IMMEDIATE(copy(sa_value)); - return img::format("APPEND %s, %s, %s", rt, rs, sa); + return img_format("APPEND %s, %s, %s", rt, rs, sa); } @@ -2827,7 +2812,7 @@ std::string NMD::ASET(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("ASET %s, %s(%s)", bit, s, rs); + return img_format("ASET %s, %s(%s)", bit, s, rs); } @@ -2847,7 +2832,7 @@ std::string NMD::BALC_16_(uint64 instruction) std::string s = ADDRESS(encode_s_from_address(s_value), 2); - return img::format("BALC %s", s); + return img_format("BALC %s", s); } @@ -2867,7 +2852,7 @@ std::string NMD::BALC_32_(uint64 instruction) std::string s = ADDRESS(encode_s_from_address(s_value), 4); - return img::format("BALC %s", s); + return img_format("BALC %s", s); } @@ -2889,7 +2874,7 @@ std::string NMD::BALRSC(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("BALRSC %s, %s", rt, rs); + return img_format("BALRSC %s, %s", rt, rs); } @@ -2913,7 +2898,7 @@ std::string NMD::BBEQZC(uint64 instruction) std::string bit = IMMEDIATE(copy(bit_value)); std::string s = ADDRESS(encode_s_from_address(s_value), 4); - return img::format("BBEQZC %s, %s, %s", rt, bit, s); + return img_format("BBEQZC %s, %s, %s", rt, bit, s); } @@ -2937,7 +2922,7 @@ std::string NMD::BBNEZC(uint64 instruction) std::string bit = IMMEDIATE(copy(bit_value)); std::string s = ADDRESS(encode_s_from_address(s_value), 4); - return img::format("BBNEZC %s, %s, %s", rt, bit, s); + return img_format("BBNEZC %s, %s, %s", rt, bit, s); } @@ -2957,7 +2942,7 @@ std::string NMD::BC_16_(uint64 instruction) std::string s = ADDRESS(encode_s_from_address(s_value), 2); - return img::format("BC %s", s); + return img_format("BC %s", s); } @@ -2977,7 +2962,7 @@ std::string NMD::BC_32_(uint64 instruction) std::string s = ADDRESS(encode_s_from_address(s_value), 4); - return img::format("BC %s", s); + return img_format("BC %s", s); } @@ -2999,7 +2984,7 @@ std::string NMD::BC1EQZC(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string s = ADDRESS(encode_s_from_address(s_value), 4); - return img::format("BC1EQZC %s, %s", ft, s); + return img_format("BC1EQZC %s, %s", ft, s); } @@ -3021,7 +3006,7 @@ std::string NMD::BC1NEZC(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string s = ADDRESS(encode_s_from_address(s_value), 4); - return img::format("BC1NEZC %s, %s", ft, s); + return img_format("BC1NEZC %s, %s", ft, s); } @@ -3043,7 +3028,7 @@ std::string NMD::BC2EQZC(uint64 instruction) std::string ct = CPR(copy(ct_value)); std::string s = ADDRESS(encode_s_from_address(s_value), 4); - return img::format("BC2EQZC %s, %s", ct, s); + return img_format("BC2EQZC %s, %s", ct, s); } @@ -3065,7 +3050,7 @@ std::string NMD::BC2NEZC(uint64 instruction) std::string ct = CPR(copy(ct_value)); std::string s = ADDRESS(encode_s_from_address(s_value), 4); - return img::format("BC2NEZC %s, %s", ct, s); + return img_format("BC2NEZC %s, %s", ct, s); } @@ -3089,7 +3074,7 @@ std::string NMD::BEQC_16_(uint64 instruction) std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); std::string u = ADDRESS(encode_u_from_address(u_value), 2); - return img::format("BEQC %s, %s, %s", rs3, rt3, u); + return img_format("BEQC %s, %s, %s", rs3, rt3, u); } @@ -3113,7 +3098,7 @@ std::string NMD::BEQC_32_(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string s = ADDRESS(encode_s_from_address(s_value), 4); - return img::format("BEQC %s, %s, %s", rs, rt, s); + return img_format("BEQC %s, %s, %s", rs, rt, s); } @@ -3137,7 +3122,7 @@ std::string NMD::BEQIC(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string s = ADDRESS(encode_s_from_address(s_value), 4); - return img::format("BEQIC %s, %s, %s", rt, u, s); + return img_format("BEQIC %s, %s, %s", rt, u, s); } @@ -3159,7 +3144,7 @@ std::string NMD::BEQZC_16_(uint64 instruction) std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); std::string s = ADDRESS(encode_s_from_address(s_value), 2); - return img::format("BEQZC %s, %s", rt3, s); + return img_format("BEQZC %s, %s", rt3, s); } @@ -3183,7 +3168,7 @@ std::string NMD::BGEC(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string s = ADDRESS(encode_s_from_address(s_value), 4); - return img::format("BGEC %s, %s, %s", rs, rt, s); + return img_format("BGEC %s, %s, %s", rs, rt, s); } @@ -3207,7 +3192,7 @@ std::string NMD::BGEIC(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string s = ADDRESS(encode_s_from_address(s_value), 4); - return img::format("BGEIC %s, %s, %s", rt, u, s); + return img_format("BGEIC %s, %s, %s", rt, u, s); } @@ -3231,7 +3216,7 @@ std::string NMD::BGEIUC(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string s = ADDRESS(encode_s_from_address(s_value), 4); - return img::format("BGEIUC %s, %s, %s", rt, u, s); + return img_format("BGEIUC %s, %s, %s", rt, u, s); } @@ -3255,7 +3240,7 @@ std::string NMD::BGEUC(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string s = ADDRESS(encode_s_from_address(s_value), 4); - return img::format("BGEUC %s, %s, %s", rs, rt, s); + return img_format("BGEUC %s, %s, %s", rs, rt, s); } @@ -3279,7 +3264,7 @@ std::string NMD::BLTC(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string s = ADDRESS(encode_s_from_address(s_value), 4); - return img::format("BLTC %s, %s, %s", rs, rt, s); + return img_format("BLTC %s, %s, %s", rs, rt, s); } @@ -3303,7 +3288,7 @@ std::string NMD::BLTIC(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string s = ADDRESS(encode_s_from_address(s_value), 4); - return img::format("BLTIC %s, %s, %s", rt, u, s); + return img_format("BLTIC %s, %s, %s", rt, u, s); } @@ -3327,7 +3312,7 @@ std::string NMD::BLTIUC(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string s = ADDRESS(encode_s_from_address(s_value), 4); - return img::format("BLTIUC %s, %s, %s", rt, u, s); + return img_format("BLTIUC %s, %s, %s", rt, u, s); } @@ -3351,7 +3336,7 @@ std::string NMD::BLTUC(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string s = ADDRESS(encode_s_from_address(s_value), 4); - return img::format("BLTUC %s, %s, %s", rs, rt, s); + return img_format("BLTUC %s, %s, %s", rs, rt, s); } @@ -3375,7 +3360,7 @@ std::string NMD::BNEC_16_(uint64 instruction) std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); std::string u = ADDRESS(encode_u_from_address(u_value), 2); - return img::format("BNEC %s, %s, %s", rs3, rt3, u); + return img_format("BNEC %s, %s, %s", rs3, rt3, u); } @@ -3399,7 +3384,7 @@ std::string NMD::BNEC_32_(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string s = ADDRESS(encode_s_from_address(s_value), 4); - return img::format("BNEC %s, %s, %s", rs, rt, s); + return img_format("BNEC %s, %s, %s", rs, rt, s); } @@ -3423,7 +3408,7 @@ std::string NMD::BNEIC(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string s = ADDRESS(encode_s_from_address(s_value), 4); - return img::format("BNEIC %s, %s, %s", rt, u, s); + return img_format("BNEIC %s, %s, %s", rt, u, s); } @@ -3445,7 +3430,7 @@ std::string NMD::BNEZC_16_(uint64 instruction) std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); std::string s = ADDRESS(encode_s_from_address(s_value), 2); - return img::format("BNEZC %s, %s", rt3, s); + return img_format("BNEZC %s, %s", rt3, s); } @@ -3465,7 +3450,7 @@ std::string NMD::BPOSGE32C(uint64 instruction) std::string s = ADDRESS(encode_s_from_address(s_value), 4); - return img::format("BPOSGE32C %s", s); + return img_format("BPOSGE32C %s", s); } @@ -3485,7 +3470,7 @@ std::string NMD::BREAK_16_(uint64 instruction) std::string code = IMMEDIATE(copy(code_value)); - return img::format("BREAK %s", code); + return img_format("BREAK %s", code); } @@ -3505,7 +3490,7 @@ std::string NMD::BREAK_32_(uint64 instruction) std::string code = IMMEDIATE(copy(code_value)); - return img::format("BREAK %s", code); + return img_format("BREAK %s", code); } @@ -3525,7 +3510,7 @@ std::string NMD::BRSC(uint64 instruction) std::string rs = GPR(copy(rs_value)); - return img::format("BRSC %s", rs); + return img_format("BRSC %s", rs); } @@ -3549,7 +3534,7 @@ std::string NMD::CACHE(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("CACHE %s, %s(%s)", op, s, rs); + return img_format("CACHE %s, %s(%s)", op, s, rs); } @@ -3573,7 +3558,7 @@ std::string NMD::CACHEE(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("CACHEE %s, %s(%s)", op, s, rs); + return img_format("CACHEE %s, %s(%s)", op, s, rs); } @@ -3595,7 +3580,7 @@ std::string NMD::CEIL_L_D(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("CEIL.L.D %s, %s", ft, fs); + return img_format("CEIL.L.D %s, %s", ft, fs); } @@ -3617,7 +3602,7 @@ std::string NMD::CEIL_L_S(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("CEIL.L.S %s, %s", ft, fs); + return img_format("CEIL.L.S %s, %s", ft, fs); } @@ -3639,7 +3624,7 @@ std::string NMD::CEIL_W_D(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("CEIL.W.D %s, %s", ft, fs); + return img_format("CEIL.W.D %s, %s", ft, fs); } @@ -3661,7 +3646,7 @@ std::string NMD::CEIL_W_S(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("CEIL.W.S %s, %s", ft, fs); + return img_format("CEIL.W.S %s, %s", ft, fs); } @@ -3683,7 +3668,7 @@ std::string NMD::CFC1(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string cs = CPR(copy(cs_value)); - return img::format("CFC1 %s, %s", rt, cs); + return img_format("CFC1 %s, %s", rt, cs); } @@ -3705,7 +3690,7 @@ std::string NMD::CFC2(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string cs = CPR(copy(cs_value)); - return img::format("CFC2 %s, %s", rt, cs); + return img_format("CFC2 %s, %s", rt, cs); } @@ -3727,7 +3712,7 @@ std::string NMD::CLASS_D(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("CLASS.D %s, %s", ft, fs); + return img_format("CLASS.D %s, %s", ft, fs); } @@ -3749,7 +3734,7 @@ std::string NMD::CLASS_S(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("CLASS.S %s, %s", ft, fs); + return img_format("CLASS.S %s, %s", ft, fs); } @@ -3771,7 +3756,7 @@ std::string NMD::CLO(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("CLO %s, %s", rt, rs); + return img_format("CLO %s, %s", rt, rs); } @@ -3793,7 +3778,7 @@ std::string NMD::CLZ(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("CLZ %s, %s", rt, rs); + return img_format("CLZ %s, %s", rt, rs); } @@ -3817,7 +3802,7 @@ std::string NMD::CMP_AF_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.AF.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.AF.D %s, %s, %s", fd, fs, ft); } @@ -3841,7 +3826,7 @@ std::string NMD::CMP_AF_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.AF.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.AF.S %s, %s, %s", fd, fs, ft); } @@ -3865,7 +3850,7 @@ std::string NMD::CMP_EQ_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.EQ.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.EQ.D %s, %s, %s", fd, fs, ft); } @@ -3886,7 +3871,7 @@ std::string NMD::CMP_EQ_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("CMP.EQ.PH %s, %s", rs, rt); + return img_format("CMP.EQ.PH %s, %s", rs, rt); } @@ -3910,7 +3895,7 @@ std::string NMD::CMP_EQ_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.EQ.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.EQ.S %s, %s, %s", fd, fs, ft); } @@ -3934,7 +3919,7 @@ std::string NMD::CMP_LE_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.LE.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.LE.D %s, %s, %s", fd, fs, ft); } @@ -3955,7 +3940,7 @@ std::string NMD::CMP_LE_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("CMP.LE.PH %s, %s", rs, rt); + return img_format("CMP.LE.PH %s, %s", rs, rt); } @@ -3979,7 +3964,7 @@ std::string NMD::CMP_LE_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.LE.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.LE.S %s, %s, %s", fd, fs, ft); } @@ -4003,7 +3988,7 @@ std::string NMD::CMP_LT_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.LT.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.LT.D %s, %s, %s", fd, fs, ft); } @@ -4024,7 +4009,7 @@ std::string NMD::CMP_LT_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("CMP.LT.PH %s, %s", rs, rt); + return img_format("CMP.LT.PH %s, %s", rs, rt); } @@ -4048,7 +4033,7 @@ std::string NMD::CMP_LT_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.LT.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.LT.S %s, %s, %s", fd, fs, ft); } @@ -4072,7 +4057,7 @@ std::string NMD::CMP_NE_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.NE.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.NE.D %s, %s, %s", fd, fs, ft); } @@ -4096,7 +4081,7 @@ std::string NMD::CMP_NE_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.NE.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.NE.S %s, %s, %s", fd, fs, ft); } @@ -4120,7 +4105,7 @@ std::string NMD::CMP_OR_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.OR.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.OR.D %s, %s, %s", fd, fs, ft); } @@ -4144,7 +4129,7 @@ std::string NMD::CMP_OR_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.OR.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.OR.S %s, %s, %s", fd, fs, ft); } @@ -4168,7 +4153,7 @@ std::string NMD::CMP_SAF_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.SAF.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.SAF.D %s, %s, %s", fd, fs, ft); } @@ -4192,7 +4177,7 @@ std::string NMD::CMP_SAF_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.SAF.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.SAF.S %s, %s, %s", fd, fs, ft); } @@ -4216,7 +4201,7 @@ std::string NMD::CMP_SEQ_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.SEQ.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.SEQ.D %s, %s, %s", fd, fs, ft); } @@ -4240,7 +4225,7 @@ std::string NMD::CMP_SEQ_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.SEQ.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.SEQ.S %s, %s, %s", fd, fs, ft); } @@ -4264,7 +4249,7 @@ std::string NMD::CMP_SLE_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.SLE.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.SLE.D %s, %s, %s", fd, fs, ft); } @@ -4288,7 +4273,7 @@ std::string NMD::CMP_SLE_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.SLE.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.SLE.S %s, %s, %s", fd, fs, ft); } @@ -4312,7 +4297,7 @@ std::string NMD::CMP_SLT_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.SLT.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.SLT.D %s, %s, %s", fd, fs, ft); } @@ -4336,7 +4321,7 @@ std::string NMD::CMP_SLT_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.SLT.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.SLT.S %s, %s, %s", fd, fs, ft); } @@ -4360,7 +4345,7 @@ std::string NMD::CMP_SNE_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.SNE.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.SNE.D %s, %s, %s", fd, fs, ft); } @@ -4384,7 +4369,7 @@ std::string NMD::CMP_SNE_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.SNE.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.SNE.S %s, %s, %s", fd, fs, ft); } @@ -4408,7 +4393,7 @@ std::string NMD::CMP_SOR_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.SOR.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.SOR.D %s, %s, %s", fd, fs, ft); } @@ -4432,7 +4417,7 @@ std::string NMD::CMP_SOR_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.SOR.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.SOR.S %s, %s, %s", fd, fs, ft); } @@ -4456,7 +4441,7 @@ std::string NMD::CMP_SUEQ_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.SUEQ.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.SUEQ.D %s, %s, %s", fd, fs, ft); } @@ -4480,7 +4465,7 @@ std::string NMD::CMP_SUEQ_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.SUEQ.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.SUEQ.S %s, %s, %s", fd, fs, ft); } @@ -4504,7 +4489,7 @@ std::string NMD::CMP_SULE_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.SULE.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.SULE.D %s, %s, %s", fd, fs, ft); } @@ -4528,7 +4513,7 @@ std::string NMD::CMP_SULE_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.SULE.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.SULE.S %s, %s, %s", fd, fs, ft); } @@ -4552,7 +4537,7 @@ std::string NMD::CMP_SULT_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.SULT.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.SULT.D %s, %s, %s", fd, fs, ft); } @@ -4576,7 +4561,7 @@ std::string NMD::CMP_SULT_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.SULT.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.SULT.S %s, %s, %s", fd, fs, ft); } @@ -4600,7 +4585,7 @@ std::string NMD::CMP_SUN_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.SUN.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.SUN.D %s, %s, %s", fd, fs, ft); } @@ -4624,7 +4609,7 @@ std::string NMD::CMP_SUNE_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.SUNE.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.SUNE.D %s, %s, %s", fd, fs, ft); } @@ -4648,7 +4633,7 @@ std::string NMD::CMP_SUNE_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.SUNE.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.SUNE.S %s, %s, %s", fd, fs, ft); } @@ -4672,7 +4657,7 @@ std::string NMD::CMP_SUN_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.SUN.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.SUN.S %s, %s, %s", fd, fs, ft); } @@ -4696,7 +4681,7 @@ std::string NMD::CMP_UEQ_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.UEQ.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.UEQ.D %s, %s, %s", fd, fs, ft); } @@ -4720,7 +4705,7 @@ std::string NMD::CMP_UEQ_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.UEQ.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.UEQ.S %s, %s, %s", fd, fs, ft); } @@ -4744,7 +4729,7 @@ std::string NMD::CMP_ULE_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.ULE.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.ULE.D %s, %s, %s", fd, fs, ft); } @@ -4768,7 +4753,7 @@ std::string NMD::CMP_ULE_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.ULE.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.ULE.S %s, %s, %s", fd, fs, ft); } @@ -4792,7 +4777,7 @@ std::string NMD::CMP_ULT_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.ULT.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.ULT.D %s, %s, %s", fd, fs, ft); } @@ -4816,7 +4801,7 @@ std::string NMD::CMP_ULT_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.ULT.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.ULT.S %s, %s, %s", fd, fs, ft); } @@ -4840,7 +4825,7 @@ std::string NMD::CMP_UN_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.UN.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.UN.D %s, %s, %s", fd, fs, ft); } @@ -4864,7 +4849,7 @@ std::string NMD::CMP_UNE_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.UNE.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.UNE.D %s, %s, %s", fd, fs, ft); } @@ -4888,7 +4873,7 @@ std::string NMD::CMP_UNE_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.UNE.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.UNE.S %s, %s, %s", fd, fs, ft); } @@ -4912,7 +4897,7 @@ std::string NMD::CMP_UN_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("CMP.UN.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.UN.S %s, %s, %s", fd, fs, ft); } @@ -4937,7 +4922,7 @@ std::string NMD::CMPGDU_EQ_QB(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("CMPGDU.EQ.QB %s, %s, %s", rd, rs, rt); + return img_format("CMPGDU.EQ.QB %s, %s, %s", rd, rs, rt); } @@ -4962,7 +4947,7 @@ std::string NMD::CMPGDU_LE_QB(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("CMPGDU.LE.QB %s, %s, %s", rd, rs, rt); + return img_format("CMPGDU.LE.QB %s, %s, %s", rd, rs, rt); } @@ -4987,7 +4972,7 @@ std::string NMD::CMPGDU_LT_QB(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("CMPGDU.LT.QB %s, %s, %s", rd, rs, rt); + return img_format("CMPGDU.LT.QB %s, %s, %s", rd, rs, rt); } @@ -5012,7 +4997,7 @@ std::string NMD::CMPGU_EQ_QB(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("CMPGU.EQ.QB %s, %s, %s", rd, rs, rt); + return img_format("CMPGU.EQ.QB %s, %s, %s", rd, rs, rt); } @@ -5037,7 +5022,7 @@ std::string NMD::CMPGU_LE_QB(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("CMPGU.LE.QB %s, %s, %s", rd, rs, rt); + return img_format("CMPGU.LE.QB %s, %s, %s", rd, rs, rt); } @@ -5062,7 +5047,7 @@ std::string NMD::CMPGU_LT_QB(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("CMPGU.LT.QB %s, %s, %s", rd, rs, rt); + return img_format("CMPGU.LT.QB %s, %s, %s", rd, rs, rt); } @@ -5084,7 +5069,7 @@ std::string NMD::CMPU_EQ_QB(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("CMPU.EQ.QB %s, %s", rs, rt); + return img_format("CMPU.EQ.QB %s, %s", rs, rt); } @@ -5106,7 +5091,7 @@ std::string NMD::CMPU_LE_QB(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("CMPU.LE.QB %s, %s", rs, rt); + return img_format("CMPU.LE.QB %s, %s", rs, rt); } @@ -5128,7 +5113,7 @@ std::string NMD::CMPU_LT_QB(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("CMPU.LT.QB %s, %s", rs, rt); + return img_format("CMPU.LT.QB %s, %s", rs, rt); } @@ -5148,7 +5133,7 @@ std::string NMD::COP2_1(uint64 instruction) std::string cofun = IMMEDIATE(copy(cofun_value)); - return img::format("COP2_1 %s", cofun); + return img_format("COP2_1 %s", cofun); } @@ -5170,7 +5155,7 @@ std::string NMD::CTC1(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string cs = CPR(copy(cs_value)); - return img::format("CTC1 %s, %s", rt, cs); + return img_format("CTC1 %s, %s", rt, cs); } @@ -5192,7 +5177,7 @@ std::string NMD::CTC2(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string cs = CPR(copy(cs_value)); - return img::format("CTC2 %s, %s", rt, cs); + return img_format("CTC2 %s, %s", rt, cs); } @@ -5214,7 +5199,7 @@ std::string NMD::CVT_D_L(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("CVT.D.L %s, %s", ft, fs); + return img_format("CVT.D.L %s, %s", ft, fs); } @@ -5236,7 +5221,7 @@ std::string NMD::CVT_D_S(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("CVT.D.S %s, %s", ft, fs); + return img_format("CVT.D.S %s, %s", ft, fs); } @@ -5258,7 +5243,7 @@ std::string NMD::CVT_D_W(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("CVT.D.W %s, %s", ft, fs); + return img_format("CVT.D.W %s, %s", ft, fs); } @@ -5280,7 +5265,7 @@ std::string NMD::CVT_L_D(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("CVT.L.D %s, %s", ft, fs); + return img_format("CVT.L.D %s, %s", ft, fs); } @@ -5302,7 +5287,7 @@ std::string NMD::CVT_L_S(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("CVT.L.S %s, %s", ft, fs); + return img_format("CVT.L.S %s, %s", ft, fs); } @@ -5324,7 +5309,7 @@ std::string NMD::CVT_S_D(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("CVT.S.D %s, %s", ft, fs); + return img_format("CVT.S.D %s, %s", ft, fs); } @@ -5346,7 +5331,7 @@ std::string NMD::CVT_S_L(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("CVT.S.L %s, %s", ft, fs); + return img_format("CVT.S.L %s, %s", ft, fs); } @@ -5368,7 +5353,7 @@ std::string NMD::CVT_S_PL(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("CVT.S.PL %s, %s", ft, fs); + return img_format("CVT.S.PL %s, %s", ft, fs); } @@ -5390,7 +5375,7 @@ std::string NMD::CVT_S_PU(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("CVT.S.PU %s, %s", ft, fs); + return img_format("CVT.S.PU %s, %s", ft, fs); } @@ -5412,7 +5397,7 @@ std::string NMD::CVT_S_W(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("CVT.S.W %s, %s", ft, fs); + return img_format("CVT.S.W %s, %s", ft, fs); } @@ -5434,7 +5419,7 @@ std::string NMD::CVT_W_D(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("CVT.W.D %s, %s", ft, fs); + return img_format("CVT.W.D %s, %s", ft, fs); } @@ -5456,7 +5441,7 @@ std::string NMD::CVT_W_S(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("CVT.W.S %s, %s", ft, fs); + return img_format("CVT.W.S %s, %s", ft, fs); } @@ -5478,7 +5463,7 @@ std::string NMD::DADDIU_48_(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string s = IMMEDIATE(copy(s_value)); - return img::format("DADDIU %s, %s", rt, s); + return img_format("DADDIU %s, %s", rt, s); } @@ -5502,7 +5487,7 @@ std::string NMD::DADDIU_NEG_(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string u = IMMEDIATE(neg_copy(u_value)); - return img::format("DADDIU %s, %s, %s", rt, rs, u); + return img_format("DADDIU %s, %s, %s", rt, rs, u); } @@ -5526,7 +5511,7 @@ std::string NMD::DADDIU_U12_(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string u = IMMEDIATE(copy(u_value)); - return img::format("DADDIU %s, %s, %s", rt, rs, u); + return img_format("DADDIU %s, %s, %s", rt, rs, u); } @@ -5550,7 +5535,7 @@ std::string NMD::DADD(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DADD %s, %s, %s", rd, rs, rt); + return img_format("DADD %s, %s, %s", rd, rs, rt); } @@ -5574,7 +5559,7 @@ std::string NMD::DADDU(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DADDU %s, %s, %s", rd, rs, rt); + return img_format("DADDU %s, %s, %s", rd, rs, rt); } @@ -5596,7 +5581,7 @@ std::string NMD::DCLO(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("DCLO %s, %s", rt, rs); + return img_format("DCLO %s, %s", rt, rs); } @@ -5618,7 +5603,7 @@ std::string NMD::DCLZ(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("DCLZ %s, %s", rt, rs); + return img_format("DCLZ %s, %s", rt, rs); } @@ -5642,7 +5627,7 @@ std::string NMD::DDIV(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DDIV %s, %s, %s", rd, rs, rt); + return img_format("DDIV %s, %s, %s", rd, rs, rt); } @@ -5666,7 +5651,7 @@ std::string NMD::DDIVU(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DDIVU %s, %s, %s", rd, rs, rt); + return img_format("DDIVU %s, %s, %s", rd, rs, rt); } @@ -5710,7 +5695,7 @@ std::string NMD::DEXTM(uint64 instruction) std::string lsb = IMMEDIATE(copy(lsb_value)); std::string msbd = IMMEDIATE(encode_msbd_from_size(msbd_value)); - return img::format("DEXTM %s, %s, %s, %s", rt, rs, lsb, msbd); + return img_format("DEXTM %s, %s, %s, %s", rt, rs, lsb, msbd); } @@ -5736,7 +5721,7 @@ std::string NMD::DEXT(uint64 instruction) std::string lsb = IMMEDIATE(copy(lsb_value)); std::string msbd = IMMEDIATE(encode_msbd_from_size(msbd_value)); - return img::format("DEXT %s, %s, %s, %s", rt, rs, lsb, msbd); + return img_format("DEXT %s, %s, %s, %s", rt, rs, lsb, msbd); } @@ -5762,7 +5747,7 @@ std::string NMD::DEXTU(uint64 instruction) std::string lsb = IMMEDIATE(copy(lsb_value)); std::string msbd = IMMEDIATE(encode_msbd_from_size(msbd_value)); - return img::format("DEXTU %s, %s, %s, %s", rt, rs, lsb, msbd); + return img_format("DEXTU %s, %s, %s, %s", rt, rs, lsb, msbd); } @@ -5789,7 +5774,7 @@ std::string NMD::DINSM(uint64 instruction) std::string size = IMMEDIATE(encode_lsb_from_pos_and_size(msbd_value)); /* !!!!!!!!!! - no conversion function */ - return img::format("DINSM %s, %s, %s, %s", rt, rs, pos, size); + return img_format("DINSM %s, %s, %s, %s", rt, rs, pos, size); /* hand edited */ } @@ -5817,7 +5802,7 @@ std::string NMD::DINS(uint64 instruction) std::string size = IMMEDIATE(encode_lsb_from_pos_and_size(msbd_value)); /* !!!!!!!!!! - no conversion function */ - return img::format("DINS %s, %s, %s, %s", rt, rs, pos, size); + return img_format("DINS %s, %s, %s, %s", rt, rs, pos, size); /* hand edited */ } @@ -5845,7 +5830,7 @@ std::string NMD::DINSU(uint64 instruction) std::string size = IMMEDIATE(encode_lsb_from_pos_and_size(msbd_value)); /* !!!!!!!!!! - no conversion function */ - return img::format("DINSU %s, %s, %s, %s", rt, rs, pos, size); + return img_format("DINSU %s, %s, %s, %s", rt, rs, pos, size); /* hand edited */ } @@ -5866,7 +5851,7 @@ std::string NMD::DI(uint64 instruction) std::string rt = GPR(copy(rt_value)); - return img::format("DI %s", rt); + return img_format("DI %s", rt); } @@ -5890,7 +5875,7 @@ std::string NMD::DIV(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DIV %s, %s, %s", rd, rs, rt); + return img_format("DIV %s, %s, %s", rd, rs, rt); } @@ -5914,7 +5899,7 @@ std::string NMD::DIV_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("DIV.D %s, %s, %s", fd, fs, ft); + return img_format("DIV.D %s, %s, %s", fd, fs, ft); } @@ -5938,7 +5923,7 @@ std::string NMD::DIV_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("DIV.S %s, %s, %s", fd, fs, ft); + return img_format("DIV.S %s, %s, %s", fd, fs, ft); } @@ -5962,7 +5947,7 @@ std::string NMD::DIVU(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DIVU %s, %s, %s", rd, rs, rt); + return img_format("DIVU %s, %s, %s", rd, rs, rt); } @@ -5988,7 +5973,7 @@ std::string NMD::DLSA(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string u2 = IMMEDIATE(copy(u2_value)); - return img::format("DLSA %s, %s, %s, %s", rd, rs, rt, u2); + return img_format("DLSA %s, %s, %s, %s", rd, rs, rt, u2); } @@ -6010,7 +5995,7 @@ std::string NMD::DLUI_48_(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string u = IMMEDIATE(copy(u_value)); - return img::format("DLUI %s, %s", rt, u); + return img_format("DLUI %s, %s", rt, u); } @@ -6034,7 +6019,7 @@ std::string NMD::DMFC0(uint64 instruction) std::string c0s = CPR(copy(c0s_value)); std::string sel = IMMEDIATE(copy(sel_value)); - return img::format("DMFC0 %s, %s, %s", rt, c0s, sel); + return img_format("DMFC0 %s, %s, %s", rt, c0s, sel); } @@ -6056,7 +6041,7 @@ std::string NMD::DMFC1(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string fs = FPR(copy(fs_value)); - return img::format("DMFC1 %s, %s", rt, fs); + return img_format("DMFC1 %s, %s", rt, fs); } @@ -6078,7 +6063,7 @@ std::string NMD::DMFC2(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string cs = CPR(copy(cs_value)); - return img::format("DMFC2 %s, %s", rt, cs); + return img_format("DMFC2 %s, %s", rt, cs); } @@ -6102,7 +6087,7 @@ std::string NMD::DMFGC0(uint64 instruction) std::string c0s = CPR(copy(c0s_value)); std::string sel = IMMEDIATE(copy(sel_value)); - return img::format("DMFGC0 %s, %s, %s", rt, c0s, sel); + return img_format("DMFGC0 %s, %s, %s", rt, c0s, sel); } @@ -6126,7 +6111,7 @@ std::string NMD::DMOD(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DMOD %s, %s, %s", rd, rs, rt); + return img_format("DMOD %s, %s, %s", rd, rs, rt); } @@ -6150,7 +6135,7 @@ std::string NMD::DMODU(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DMODU %s, %s, %s", rd, rs, rt); + return img_format("DMODU %s, %s, %s", rd, rs, rt); } @@ -6174,7 +6159,7 @@ std::string NMD::DMTC0(uint64 instruction) std::string c0s = CPR(copy(c0s_value)); std::string sel = IMMEDIATE(copy(sel_value)); - return img::format("DMTC0 %s, %s, %s", rt, c0s, sel); + return img_format("DMTC0 %s, %s, %s", rt, c0s, sel); } @@ -6196,7 +6181,7 @@ std::string NMD::DMTC1(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string fs = FPR(copy(fs_value)); - return img::format("DMTC1 %s, %s", rt, fs); + return img_format("DMTC1 %s, %s", rt, fs); } @@ -6218,7 +6203,7 @@ std::string NMD::DMTC2(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string cs = CPR(copy(cs_value)); - return img::format("DMTC2 %s, %s", rt, cs); + return img_format("DMTC2 %s, %s", rt, cs); } @@ -6242,7 +6227,7 @@ std::string NMD::DMTGC0(uint64 instruction) std::string c0s = CPR(copy(c0s_value)); std::string sel = IMMEDIATE(copy(sel_value)); - return img::format("DMTGC0 %s, %s, %s", rt, c0s, sel); + return img_format("DMTGC0 %s, %s, %s", rt, c0s, sel); } @@ -6262,7 +6247,7 @@ std::string NMD::DMT(uint64 instruction) std::string rt = GPR(copy(rt_value)); - return img::format("DMT %s", rt); + return img_format("DMT %s", rt); } @@ -6286,7 +6271,7 @@ std::string NMD::DMUH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DMUH %s, %s, %s", rd, rs, rt); + return img_format("DMUH %s, %s, %s", rd, rs, rt); } @@ -6310,7 +6295,7 @@ std::string NMD::DMUHU(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DMUHU %s, %s, %s", rd, rs, rt); + return img_format("DMUHU %s, %s, %s", rd, rs, rt); } @@ -6334,7 +6319,7 @@ std::string NMD::DMUL(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DMUL %s, %s, %s", rd, rs, rt); + return img_format("DMUL %s, %s, %s", rd, rs, rt); } @@ -6358,7 +6343,7 @@ std::string NMD::DMULU(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DMULU %s, %s, %s", rd, rs, rt); + return img_format("DMULU %s, %s, %s", rd, rs, rt); } @@ -6383,7 +6368,7 @@ std::string NMD::DPA_W_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DPA.W.PH %s, %s, %s", ac, rs, rt); + return img_format("DPA.W.PH %s, %s, %s", ac, rs, rt); } @@ -6407,7 +6392,7 @@ std::string NMD::DPAQ_SA_L_W(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DPAQ_SA.L.W %s, %s, %s", ac, rs, rt); + return img_format("DPAQ_SA.L.W %s, %s, %s", ac, rs, rt); } @@ -6431,7 +6416,7 @@ std::string NMD::DPAQ_S_W_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DPAQ_S.W.PH %s, %s, %s", ac, rs, rt); + return img_format("DPAQ_S.W.PH %s, %s, %s", ac, rs, rt); } @@ -6455,7 +6440,7 @@ std::string NMD::DPAQX_SA_W_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DPAQX_SA.W.PH %s, %s, %s", ac, rs, rt); + return img_format("DPAQX_SA.W.PH %s, %s, %s", ac, rs, rt); } @@ -6479,7 +6464,7 @@ std::string NMD::DPAQX_S_W_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DPAQX_S.W.PH %s, %s, %s", ac, rs, rt); + return img_format("DPAQX_S.W.PH %s, %s, %s", ac, rs, rt); } @@ -6503,7 +6488,7 @@ std::string NMD::DPAU_H_QBL(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DPAU.H.QBL %s, %s, %s", ac, rs, rt); + return img_format("DPAU.H.QBL %s, %s, %s", ac, rs, rt); } @@ -6527,7 +6512,7 @@ std::string NMD::DPAU_H_QBR(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DPAU.H.QBR %s, %s, %s", ac, rs, rt); + return img_format("DPAU.H.QBR %s, %s, %s", ac, rs, rt); } @@ -6551,7 +6536,7 @@ std::string NMD::DPAX_W_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DPAX.W.PH %s, %s, %s", ac, rs, rt); + return img_format("DPAX.W.PH %s, %s, %s", ac, rs, rt); } @@ -6575,7 +6560,7 @@ std::string NMD::DPS_W_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DPS.W.PH %s, %s, %s", ac, rs, rt); + return img_format("DPS.W.PH %s, %s, %s", ac, rs, rt); } @@ -6599,7 +6584,7 @@ std::string NMD::DPSQ_SA_L_W(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DPSQ_SA.L.W %s, %s, %s", ac, rs, rt); + return img_format("DPSQ_SA.L.W %s, %s, %s", ac, rs, rt); } @@ -6623,7 +6608,7 @@ std::string NMD::DPSQ_S_W_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DPSQ_S.W.PH %s, %s, %s", ac, rs, rt); + return img_format("DPSQ_S.W.PH %s, %s, %s", ac, rs, rt); } @@ -6647,7 +6632,7 @@ std::string NMD::DPSQX_SA_W_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DPSQX_SA.W.PH %s, %s, %s", ac, rs, rt); + return img_format("DPSQX_SA.W.PH %s, %s, %s", ac, rs, rt); } @@ -6671,7 +6656,7 @@ std::string NMD::DPSQX_S_W_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DPSQX_S.W.PH %s, %s, %s", ac, rs, rt); + return img_format("DPSQX_S.W.PH %s, %s, %s", ac, rs, rt); } @@ -6695,7 +6680,7 @@ std::string NMD::DPSU_H_QBL(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DPSU.H.QBL %s, %s, %s", ac, rs, rt); + return img_format("DPSU.H.QBL %s, %s, %s", ac, rs, rt); } @@ -6719,7 +6704,7 @@ std::string NMD::DPSU_H_QBR(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DPSU.H.QBR %s, %s, %s", ac, rs, rt); + return img_format("DPSU.H.QBR %s, %s, %s", ac, rs, rt); } @@ -6743,7 +6728,7 @@ std::string NMD::DPSX_W_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DPSX.W.PH %s, %s, %s", ac, rs, rt); + return img_format("DPSX.W.PH %s, %s, %s", ac, rs, rt); } @@ -6767,7 +6752,7 @@ std::string NMD::DROTR(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string shift = IMMEDIATE(copy(shift_value)); - return img::format("DROTR %s, %s, %s", rt, rs, shift); + return img_format("DROTR %s, %s, %s", rt, rs, shift); } @@ -6791,7 +6776,7 @@ std::string NMD::DROTR32(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string shift = IMMEDIATE(copy(shift_value)); - return img::format("DROTR32 %s, %s, %s", rt, rs, shift); + return img_format("DROTR32 %s, %s, %s", rt, rs, shift); } @@ -6815,7 +6800,7 @@ std::string NMD::DROTRV(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DROTRV %s, %s, %s", rd, rs, rt); + return img_format("DROTRV %s, %s, %s", rd, rs, rt); } @@ -6841,7 +6826,7 @@ std::string NMD::DROTX(uint64 instruction) std::string shift = IMMEDIATE(copy(shift_value)); std::string shiftx = IMMEDIATE(copy(shiftx_value)); - return img::format("DROTX %s, %s, %s, %s", rt, rs, shift, shiftx); + return img_format("DROTX %s, %s, %s, %s", rt, rs, shift, shiftx); } @@ -6865,7 +6850,7 @@ std::string NMD::DSLL(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string shift = IMMEDIATE(copy(shift_value)); - return img::format("DSLL %s, %s, %s", rt, rs, shift); + return img_format("DSLL %s, %s, %s", rt, rs, shift); } @@ -6889,7 +6874,7 @@ std::string NMD::DSLL32(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string shift = IMMEDIATE(copy(shift_value)); - return img::format("DSLL32 %s, %s, %s", rt, rs, shift); + return img_format("DSLL32 %s, %s, %s", rt, rs, shift); } @@ -6913,7 +6898,7 @@ std::string NMD::DSLLV(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DSLLV %s, %s, %s", rd, rs, rt); + return img_format("DSLLV %s, %s, %s", rd, rs, rt); } @@ -6937,7 +6922,7 @@ std::string NMD::DSRA(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string shift = IMMEDIATE(copy(shift_value)); - return img::format("DSRA %s, %s, %s", rt, rs, shift); + return img_format("DSRA %s, %s, %s", rt, rs, shift); } @@ -6961,7 +6946,7 @@ std::string NMD::DSRA32(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string shift = IMMEDIATE(copy(shift_value)); - return img::format("DSRA32 %s, %s, %s", rt, rs, shift); + return img_format("DSRA32 %s, %s, %s", rt, rs, shift); } @@ -6985,7 +6970,7 @@ std::string NMD::DSRAV(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DSRAV %s, %s, %s", rd, rs, rt); + return img_format("DSRAV %s, %s, %s", rd, rs, rt); } @@ -7009,7 +6994,7 @@ std::string NMD::DSRL(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string shift = IMMEDIATE(copy(shift_value)); - return img::format("DSRL %s, %s, %s", rt, rs, shift); + return img_format("DSRL %s, %s, %s", rt, rs, shift); } @@ -7033,7 +7018,7 @@ std::string NMD::DSRL32(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string shift = IMMEDIATE(copy(shift_value)); - return img::format("DSRL32 %s, %s, %s", rt, rs, shift); + return img_format("DSRL32 %s, %s, %s", rt, rs, shift); } @@ -7057,7 +7042,7 @@ std::string NMD::DSRLV(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DSRLV %s, %s, %s", rd, rs, rt); + return img_format("DSRLV %s, %s, %s", rd, rs, rt); } @@ -7081,7 +7066,7 @@ std::string NMD::DSUB(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DSUB %s, %s, %s", rd, rs, rt); + return img_format("DSUB %s, %s, %s", rd, rs, rt); } @@ -7105,7 +7090,7 @@ std::string NMD::DSUBU(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("DSUBU %s, %s, %s", rd, rs, rt); + return img_format("DSUBU %s, %s, %s", rd, rs, rt); } @@ -7125,7 +7110,7 @@ std::string NMD::DVPE(uint64 instruction) std::string rt = GPR(copy(rt_value)); - return img::format("DVPE %s", rt); + return img_format("DVPE %s", rt); } @@ -7145,7 +7130,7 @@ std::string NMD::DVP(uint64 instruction) std::string rt = GPR(copy(rt_value)); - return img::format("DVP %s", rt); + return img_format("DVP %s", rt); } @@ -7183,7 +7168,7 @@ std::string NMD::EI(uint64 instruction) std::string rt = GPR(copy(rt_value)); - return img::format("EI %s", rt); + return img_format("EI %s", rt); } @@ -7203,7 +7188,7 @@ std::string NMD::EMT(uint64 instruction) std::string rt = GPR(copy(rt_value)); - return img::format("EMT %s", rt); + return img_format("EMT %s", rt); } @@ -7259,7 +7244,7 @@ std::string NMD::EVP(uint64 instruction) std::string rt = GPR(copy(rt_value)); - return img::format("EVP %s", rt); + return img_format("EVP %s", rt); } @@ -7279,7 +7264,7 @@ std::string NMD::EVPE(uint64 instruction) std::string rt = GPR(copy(rt_value)); - return img::format("EVPE %s", rt); + return img_format("EVPE %s", rt); } @@ -7305,7 +7290,7 @@ std::string NMD::EXT(uint64 instruction) std::string lsb = IMMEDIATE(copy(lsb_value)); std::string msbd = IMMEDIATE(encode_msbd_from_size(msbd_value)); - return img::format("EXT %s, %s, %s, %s", rt, rs, lsb, msbd); + return img_format("EXT %s, %s, %s, %s", rt, rs, lsb, msbd); } @@ -7331,7 +7316,7 @@ std::string NMD::EXTD(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string shift = IMMEDIATE(copy(shift_value)); - return img::format("EXTD %s, %s, %s, %s", rd, rs, rt, shift); + return img_format("EXTD %s, %s, %s, %s", rd, rs, rt, shift); } @@ -7357,7 +7342,7 @@ std::string NMD::EXTD32(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string shift = IMMEDIATE(copy(shift_value)); - return img::format("EXTD32 %s, %s, %s, %s", rd, rs, rt, shift); + return img_format("EXTD32 %s, %s, %s, %s", rd, rs, rt, shift); } @@ -7381,7 +7366,7 @@ std::string NMD::EXTPDP(uint64 instruction) std::string ac = AC(copy(ac_value)); std::string size = IMMEDIATE(copy(size_value)); - return img::format("EXTPDP %s, %s, %s", rt, ac, size); + return img_format("EXTPDP %s, %s, %s", rt, ac, size); } @@ -7405,7 +7390,7 @@ std::string NMD::EXTPDPV(uint64 instruction) std::string ac = AC(copy(ac_value)); std::string rs = GPR(copy(rs_value)); - return img::format("EXTPDPV %s, %s, %s", rt, ac, rs); + return img_format("EXTPDPV %s, %s, %s", rt, ac, rs); } @@ -7429,7 +7414,7 @@ std::string NMD::EXTP(uint64 instruction) std::string ac = AC(copy(ac_value)); std::string size = IMMEDIATE(copy(size_value)); - return img::format("EXTP %s, %s, %s", rt, ac, size); + return img_format("EXTP %s, %s, %s", rt, ac, size); } @@ -7453,7 +7438,7 @@ std::string NMD::EXTPV(uint64 instruction) std::string ac = AC(copy(ac_value)); std::string rs = GPR(copy(rs_value)); - return img::format("EXTPV %s, %s, %s", rt, ac, rs); + return img_format("EXTPV %s, %s, %s", rt, ac, rs); } @@ -7478,7 +7463,7 @@ std::string NMD::EXTR_RS_W(uint64 instruction) std::string ac = AC(copy(ac_value)); std::string shift = IMMEDIATE(copy(shift_value)); - return img::format("EXTR_RS.W %s, %s, %s", rt, ac, shift); + return img_format("EXTR_RS.W %s, %s, %s", rt, ac, shift); } @@ -7503,7 +7488,7 @@ std::string NMD::EXTR_R_W(uint64 instruction) std::string ac = AC(copy(ac_value)); std::string shift = IMMEDIATE(copy(shift_value)); - return img::format("EXTR_R.W %s, %s, %s", rt, ac, shift); + return img_format("EXTR_R.W %s, %s, %s", rt, ac, shift); } @@ -7528,7 +7513,7 @@ std::string NMD::EXTR_S_H(uint64 instruction) std::string ac = AC(copy(ac_value)); std::string shift = IMMEDIATE(copy(shift_value)); - return img::format("EXTR_S.H %s, %s, %s", rt, ac, shift); + return img_format("EXTR_S.H %s, %s, %s", rt, ac, shift); } @@ -7553,7 +7538,7 @@ std::string NMD::EXTR_W(uint64 instruction) std::string ac = AC(copy(ac_value)); std::string shift = IMMEDIATE(copy(shift_value)); - return img::format("EXTR.W %s, %s, %s", rt, ac, shift); + return img_format("EXTR.W %s, %s, %s", rt, ac, shift); } @@ -7578,7 +7563,7 @@ std::string NMD::EXTRV_RS_W(uint64 instruction) std::string ac = AC(copy(ac_value)); std::string rs = GPR(copy(rs_value)); - return img::format("EXTRV_RS.W %s, %s, %s", rt, ac, rs); + return img_format("EXTRV_RS.W %s, %s, %s", rt, ac, rs); } @@ -7603,7 +7588,7 @@ std::string NMD::EXTRV_R_W(uint64 instruction) std::string ac = AC(copy(ac_value)); std::string rs = GPR(copy(rs_value)); - return img::format("EXTRV_R.W %s, %s, %s", rt, ac, rs); + return img_format("EXTRV_R.W %s, %s, %s", rt, ac, rs); } @@ -7628,7 +7613,7 @@ std::string NMD::EXTRV_S_H(uint64 instruction) std::string ac = AC(copy(ac_value)); std::string rs = GPR(copy(rs_value)); - return img::format("EXTRV_S.H %s, %s, %s", rt, ac, rs); + return img_format("EXTRV_S.H %s, %s, %s", rt, ac, rs); } @@ -7653,7 +7638,7 @@ std::string NMD::EXTRV_W(uint64 instruction) std::string ac = AC(copy(ac_value)); std::string rs = GPR(copy(rs_value)); - return img::format("EXTRV.W %s, %s, %s", rt, ac, rs); + return img_format("EXTRV.W %s, %s, %s", rt, ac, rs); } @@ -7680,7 +7665,7 @@ std::string NMD::EXTW(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string shift = IMMEDIATE(copy(shift_value)); - return img::format("EXTW %s, %s, %s, %s", rd, rs, rt, shift); + return img_format("EXTW %s, %s, %s, %s", rd, rs, rt, shift); } @@ -7702,7 +7687,7 @@ std::string NMD::FLOOR_L_D(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("FLOOR.L.D %s, %s", ft, fs); + return img_format("FLOOR.L.D %s, %s", ft, fs); } @@ -7724,7 +7709,7 @@ std::string NMD::FLOOR_L_S(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("FLOOR.L.S %s, %s", ft, fs); + return img_format("FLOOR.L.S %s, %s", ft, fs); } @@ -7746,7 +7731,7 @@ std::string NMD::FLOOR_W_D(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("FLOOR.W.D %s, %s", ft, fs); + return img_format("FLOOR.W.D %s, %s", ft, fs); } @@ -7768,7 +7753,7 @@ std::string NMD::FLOOR_W_S(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("FLOOR.W.S %s, %s", ft, fs); + return img_format("FLOOR.W.S %s, %s", ft, fs); } @@ -7792,7 +7777,7 @@ std::string NMD::FORK(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("FORK %s, %s, %s", rd, rs, rt); + return img_format("FORK %s, %s, %s", rd, rs, rt); } @@ -7812,7 +7797,7 @@ std::string NMD::HYPCALL(uint64 instruction) std::string code = IMMEDIATE(copy(code_value)); - return img::format("HYPCALL %s", code); + return img_format("HYPCALL %s", code); } @@ -7832,7 +7817,7 @@ std::string NMD::HYPCALL_16_(uint64 instruction) std::string code = IMMEDIATE(copy(code_value)); - return img::format("HYPCALL %s", code); + return img_format("HYPCALL %s", code); } @@ -7859,7 +7844,7 @@ std::string NMD::INS(uint64 instruction) std::string size = IMMEDIATE(encode_lsb_from_pos_and_size(msbd_value)); /* !!!!!!!!!! - no conversion function */ - return img::format("INS %s, %s, %s, %s", rt, rs, pos, size); + return img_format("INS %s, %s, %s, %s", rt, rs, pos, size); /* hand edited */ } @@ -7881,7 +7866,7 @@ std::string NMD::INSV(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("INSV %s, %s", rt, rs); + return img_format("INSV %s, %s", rt, rs); } @@ -7919,7 +7904,7 @@ std::string NMD::JALRC_16_(uint64 instruction) std::string rt = GPR(copy(rt_value)); - return img::format("JALRC $%d, %s", 31, rt); + return img_format("JALRC $%d, %s", 31, rt); } @@ -7941,7 +7926,7 @@ std::string NMD::JALRC_32_(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("JALRC %s, %s", rt, rs); + return img_format("JALRC %s, %s", rt, rs); } @@ -7963,7 +7948,7 @@ std::string NMD::JALRC_HB(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("JALRC.HB %s, %s", rt, rs); + return img_format("JALRC.HB %s, %s", rt, rs); } @@ -7983,7 +7968,7 @@ std::string NMD::JRC(uint64 instruction) std::string rt = GPR(copy(rt_value)); - return img::format("JRC %s", rt); + return img_format("JRC %s", rt); } @@ -8007,7 +7992,7 @@ std::string NMD::LB_16_(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); - return img::format("LB %s, %s(%s)", rt3, u, rs3); + return img_format("LB %s, %s(%s)", rt3, u, rs3); } @@ -8029,7 +8014,7 @@ std::string NMD::LB_GP_(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string u = IMMEDIATE(copy(u_value)); - return img::format("LB %s, %s($%d)", rt, u, 28); + return img_format("LB %s, %s($%d)", rt, u, 28); } @@ -8053,7 +8038,7 @@ std::string NMD::LB_S9_(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("LB %s, %s(%s)", rt, s, rs); + return img_format("LB %s, %s(%s)", rt, s, rs); } @@ -8077,7 +8062,7 @@ std::string NMD::LB_U12_(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string rs = GPR(copy(rs_value)); - return img::format("LB %s, %s(%s)", rt, u, rs); + return img_format("LB %s, %s(%s)", rt, u, rs); } @@ -8101,7 +8086,7 @@ std::string NMD::LBE(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("LBE %s, %s(%s)", rt, s, rs); + return img_format("LBE %s, %s(%s)", rt, s, rs); } @@ -8125,7 +8110,7 @@ std::string NMD::LBU_16_(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); - return img::format("LBU %s, %s(%s)", rt3, u, rs3); + return img_format("LBU %s, %s(%s)", rt3, u, rs3); } @@ -8147,7 +8132,7 @@ std::string NMD::LBU_GP_(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string u = IMMEDIATE(copy(u_value)); - return img::format("LBU %s, %s($%d)", rt, u, 28); + return img_format("LBU %s, %s($%d)", rt, u, 28); } @@ -8171,7 +8156,7 @@ std::string NMD::LBU_S9_(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("LBU %s, %s(%s)", rt, s, rs); + return img_format("LBU %s, %s(%s)", rt, s, rs); } @@ -8195,7 +8180,7 @@ std::string NMD::LBU_U12_(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string rs = GPR(copy(rs_value)); - return img::format("LBU %s, %s(%s)", rt, u, rs); + return img_format("LBU %s, %s(%s)", rt, u, rs); } @@ -8219,7 +8204,7 @@ std::string NMD::LBUE(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("LBUE %s, %s(%s)", rt, s, rs); + return img_format("LBUE %s, %s(%s)", rt, s, rs); } @@ -8243,7 +8228,7 @@ std::string NMD::LBUX(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("LBUX %s, %s(%s)", rd, rs, rt); + return img_format("LBUX %s, %s(%s)", rd, rs, rt); } @@ -8267,7 +8252,7 @@ std::string NMD::LBX(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("LBX %s, %s(%s)", rd, rs, rt); + return img_format("LBX %s, %s(%s)", rd, rs, rt); } @@ -8289,7 +8274,7 @@ std::string NMD::LD_GP_(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string u = IMMEDIATE(copy(u_value)); - return img::format("LD %s, %s($%d)", rt, u, 28); + return img_format("LD %s, %s($%d)", rt, u, 28); } @@ -8313,7 +8298,7 @@ std::string NMD::LD_S9_(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("LD %s, %s(%s)", rt, s, rs); + return img_format("LD %s, %s(%s)", rt, s, rs); } @@ -8337,7 +8322,7 @@ std::string NMD::LD_U12_(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string rs = GPR(copy(rs_value)); - return img::format("LD %s, %s(%s)", rt, u, rs); + return img_format("LD %s, %s(%s)", rt, u, rs); } @@ -8359,7 +8344,7 @@ std::string NMD::LDC1_GP_(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string u = IMMEDIATE(copy(u_value)); - return img::format("LDC1 %s, %s($%d)", ft, u, 28); + return img_format("LDC1 %s, %s($%d)", ft, u, 28); } @@ -8383,7 +8368,7 @@ std::string NMD::LDC1_S9_(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("LDC1 %s, %s(%s)", ft, s, rs); + return img_format("LDC1 %s, %s(%s)", ft, s, rs); } @@ -8407,7 +8392,7 @@ std::string NMD::LDC1_U12_(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string rs = GPR(copy(rs_value)); - return img::format("LDC1 %s, %s(%s)", ft, u, rs); + return img_format("LDC1 %s, %s(%s)", ft, u, rs); } @@ -8431,7 +8416,7 @@ std::string NMD::LDC1XS(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("LDC1XS %s, %s(%s)", ft, rs, rt); + return img_format("LDC1XS %s, %s(%s)", ft, rs, rt); } @@ -8455,7 +8440,7 @@ std::string NMD::LDC1X(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("LDC1X %s, %s(%s)", ft, rs, rt); + return img_format("LDC1X %s, %s(%s)", ft, rs, rt); } @@ -8479,7 +8464,7 @@ std::string NMD::LDC2(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("LDC2 %s, %s(%s)", ct, s, rs); + return img_format("LDC2 %s, %s(%s)", ct, s, rs); } @@ -8505,7 +8490,7 @@ std::string NMD::LDM(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string count3 = IMMEDIATE(encode_count3_from_count(count3_value)); - return img::format("LDM %s, %s(%s), %s", rt, s, rs, count3); + return img_format("LDM %s, %s(%s), %s", rt, s, rs, count3); } @@ -8527,7 +8512,7 @@ std::string NMD::LDPC_48_(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string s = ADDRESS(encode_s_from_address(s_value), 6); - return img::format("LDPC %s, %s", rt, s); + return img_format("LDPC %s, %s", rt, s); } @@ -8551,7 +8536,7 @@ std::string NMD::LDX(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("LDX %s, %s(%s)", rd, rs, rt); + return img_format("LDX %s, %s(%s)", rd, rs, rt); } @@ -8575,7 +8560,7 @@ std::string NMD::LDXS(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("LDXS %s, %s(%s)", rd, rs, rt); + return img_format("LDXS %s, %s(%s)", rd, rs, rt); } @@ -8599,7 +8584,7 @@ std::string NMD::LH_16_(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); - return img::format("LH %s, %s(%s)", rt3, u, rs3); + return img_format("LH %s, %s(%s)", rt3, u, rs3); } @@ -8621,7 +8606,7 @@ std::string NMD::LH_GP_(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string u = IMMEDIATE(copy(u_value)); - return img::format("LH %s, %s($%d)", rt, u, 28); + return img_format("LH %s, %s($%d)", rt, u, 28); } @@ -8645,7 +8630,7 @@ std::string NMD::LH_S9_(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("LH %s, %s(%s)", rt, s, rs); + return img_format("LH %s, %s(%s)", rt, s, rs); } @@ -8669,7 +8654,7 @@ std::string NMD::LH_U12_(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string rs = GPR(copy(rs_value)); - return img::format("LH %s, %s(%s)", rt, u, rs); + return img_format("LH %s, %s(%s)", rt, u, rs); } @@ -8693,7 +8678,7 @@ std::string NMD::LHE(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("LHE %s, %s(%s)", rt, s, rs); + return img_format("LHE %s, %s(%s)", rt, s, rs); } @@ -8717,7 +8702,7 @@ std::string NMD::LHU_16_(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); - return img::format("LHU %s, %s(%s)", rt3, u, rs3); + return img_format("LHU %s, %s(%s)", rt3, u, rs3); } @@ -8739,7 +8724,7 @@ std::string NMD::LHU_GP_(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string u = IMMEDIATE(copy(u_value)); - return img::format("LHU %s, %s($%d)", rt, u, 28); + return img_format("LHU %s, %s($%d)", rt, u, 28); } @@ -8763,7 +8748,7 @@ std::string NMD::LHU_S9_(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("LHU %s, %s(%s)", rt, s, rs); + return img_format("LHU %s, %s(%s)", rt, s, rs); } @@ -8787,7 +8772,7 @@ std::string NMD::LHU_U12_(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string rs = GPR(copy(rs_value)); - return img::format("LHU %s, %s(%s)", rt, u, rs); + return img_format("LHU %s, %s(%s)", rt, u, rs); } @@ -8811,7 +8796,7 @@ std::string NMD::LHUE(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("LHUE %s, %s(%s)", rt, s, rs); + return img_format("LHUE %s, %s(%s)", rt, s, rs); } @@ -8835,7 +8820,7 @@ std::string NMD::LHUX(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("LHUX %s, %s(%s)", rd, rs, rt); + return img_format("LHUX %s, %s(%s)", rd, rs, rt); } @@ -8859,7 +8844,7 @@ std::string NMD::LHUXS(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("LHUXS %s, %s(%s)", rd, rs, rt); + return img_format("LHUXS %s, %s(%s)", rd, rs, rt); } @@ -8883,7 +8868,7 @@ std::string NMD::LHXS(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("LHXS %s, %s(%s)", rd, rs, rt); + return img_format("LHXS %s, %s(%s)", rd, rs, rt); } @@ -8907,7 +8892,7 @@ std::string NMD::LHX(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("LHX %s, %s(%s)", rd, rs, rt); + return img_format("LHX %s, %s(%s)", rd, rs, rt); } @@ -8929,7 +8914,7 @@ std::string NMD::LI_16_(uint64 instruction) std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); std::string eu = IMMEDIATE(encode_eu_from_s_li16(eu_value)); - return img::format("LI %s, %s", rt3, eu); + return img_format("LI %s, %s", rt3, eu); } @@ -8951,7 +8936,7 @@ std::string NMD::LI_48_(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string s = IMMEDIATE(copy(s_value)); - return img::format("LI %s, %s", rt, s); + return img_format("LI %s, %s", rt, s); } @@ -8975,7 +8960,7 @@ std::string NMD::LL(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("LL %s, %s(%s)", rt, s, rs); + return img_format("LL %s, %s(%s)", rt, s, rs); } @@ -8999,7 +8984,7 @@ std::string NMD::LLD(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("LLD %s, %s(%s)", rt, s, rs); + return img_format("LLD %s, %s(%s)", rt, s, rs); } @@ -9023,7 +9008,7 @@ std::string NMD::LLDP(uint64 instruction) std::string ru = GPR(copy(ru_value)); std::string rs = GPR(copy(rs_value)); - return img::format("LLDP %s, %s, (%s)", rt, ru, rs); + return img_format("LLDP %s, %s, (%s)", rt, ru, rs); } @@ -9047,7 +9032,7 @@ std::string NMD::LLE(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("LLE %s, %s(%s)", rt, s, rs); + return img_format("LLE %s, %s(%s)", rt, s, rs); } @@ -9071,7 +9056,7 @@ std::string NMD::LLWP(uint64 instruction) std::string ru = GPR(copy(ru_value)); std::string rs = GPR(copy(rs_value)); - return img::format("LLWP %s, %s, (%s)", rt, ru, rs); + return img_format("LLWP %s, %s, (%s)", rt, ru, rs); } @@ -9095,7 +9080,7 @@ std::string NMD::LLWPE(uint64 instruction) std::string ru = GPR(copy(ru_value)); std::string rs = GPR(copy(rs_value)); - return img::format("LLWPE %s, %s, (%s)", rt, ru, rs); + return img_format("LLWPE %s, %s, (%s)", rt, ru, rs); } @@ -9121,7 +9106,7 @@ std::string NMD::LSA(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string u2 = IMMEDIATE(copy(u2_value)); - return img::format("LSA %s, %s, %s, %s", rd, rs, rt, u2); + return img_format("LSA %s, %s, %s, %s", rd, rs, rt, u2); } @@ -9143,7 +9128,7 @@ std::string NMD::LUI(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string s = IMMEDIATE(copy(s_value)); - return img::format("LUI %s, %%hi(%s)", rt, s); + return img_format("LUI %s, %%hi(%s)", rt, s); } @@ -9167,7 +9152,7 @@ std::string NMD::LW_16_(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); - return img::format("LW %s, %s(%s)", rt3, u, rs3); + return img_format("LW %s, %s(%s)", rt3, u, rs3); } @@ -9191,7 +9176,7 @@ std::string NMD::LW_4X4_(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string rs4 = GPR(decode_gpr_gpr4(rs4_value)); - return img::format("LW %s, %s(%s)", rt4, u, rs4); + return img_format("LW %s, %s(%s)", rt4, u, rs4); } @@ -9213,7 +9198,7 @@ std::string NMD::LW_GP_(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string u = IMMEDIATE(copy(u_value)); - return img::format("LW %s, %s($%d)", rt, u, 28); + return img_format("LW %s, %s($%d)", rt, u, 28); } @@ -9235,7 +9220,7 @@ std::string NMD::LW_GP16_(uint64 instruction) std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); std::string u = IMMEDIATE(copy(u_value)); - return img::format("LW %s, %s($%d)", rt3, u, 28); + return img_format("LW %s, %s($%d)", rt3, u, 28); } @@ -9259,7 +9244,7 @@ std::string NMD::LW_S9_(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("LW %s, %s(%s)", rt, s, rs); + return img_format("LW %s, %s(%s)", rt, s, rs); } @@ -9281,7 +9266,7 @@ std::string NMD::LW_SP_(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string u = IMMEDIATE(copy(u_value)); - return img::format("LW %s, %s($%d)", rt, u, 29); + return img_format("LW %s, %s($%d)", rt, u, 29); } @@ -9305,7 +9290,7 @@ std::string NMD::LW_U12_(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string rs = GPR(copy(rs_value)); - return img::format("LW %s, %s(%s)", rt, u, rs); + return img_format("LW %s, %s(%s)", rt, u, rs); } @@ -9327,7 +9312,7 @@ std::string NMD::LWC1_GP_(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string u = IMMEDIATE(copy(u_value)); - return img::format("LWC1 %s, %s($%d)", ft, u, 28); + return img_format("LWC1 %s, %s($%d)", ft, u, 28); } @@ -9351,7 +9336,7 @@ std::string NMD::LWC1_S9_(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("LWC1 %s, %s(%s)", ft, s, rs); + return img_format("LWC1 %s, %s(%s)", ft, s, rs); } @@ -9375,7 +9360,7 @@ std::string NMD::LWC1_U12_(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string rs = GPR(copy(rs_value)); - return img::format("LWC1 %s, %s(%s)", ft, u, rs); + return img_format("LWC1 %s, %s(%s)", ft, u, rs); } @@ -9399,7 +9384,7 @@ std::string NMD::LWC1X(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("LWC1X %s, %s(%s)", ft, rs, rt); + return img_format("LWC1X %s, %s(%s)", ft, rs, rt); } @@ -9423,7 +9408,7 @@ std::string NMD::LWC1XS(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("LWC1XS %s, %s(%s)", ft, rs, rt); + return img_format("LWC1XS %s, %s(%s)", ft, rs, rt); } @@ -9447,7 +9432,7 @@ std::string NMD::LWC2(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("LWC2 %s, %s(%s)", ct, s, rs); + return img_format("LWC2 %s, %s(%s)", ct, s, rs); } @@ -9471,7 +9456,7 @@ std::string NMD::LWE(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("LWE %s, %s(%s)", rt, s, rs); + return img_format("LWE %s, %s(%s)", rt, s, rs); } @@ -9497,7 +9482,7 @@ std::string NMD::LWM(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string count3 = IMMEDIATE(encode_count3_from_count(count3_value)); - return img::format("LWM %s, %s(%s), %s", rt, s, rs, count3); + return img_format("LWM %s, %s(%s), %s", rt, s, rs, count3); } @@ -9519,7 +9504,7 @@ std::string NMD::LWPC_48_(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string s = ADDRESS(encode_s_from_address(s_value), 6); - return img::format("LWPC %s, %s", rt, s); + return img_format("LWPC %s, %s", rt, s); } @@ -9541,7 +9526,7 @@ std::string NMD::LWU_GP_(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string u = IMMEDIATE(copy(u_value)); - return img::format("LWU %s, %s($%d)", rt, u, 28); + return img_format("LWU %s, %s($%d)", rt, u, 28); } @@ -9565,7 +9550,7 @@ std::string NMD::LWU_S9_(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("LWU %s, %s(%s)", rt, s, rs); + return img_format("LWU %s, %s(%s)", rt, s, rs); } @@ -9589,7 +9574,7 @@ std::string NMD::LWU_U12_(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string rs = GPR(copy(rs_value)); - return img::format("LWU %s, %s(%s)", rt, u, rs); + return img_format("LWU %s, %s(%s)", rt, u, rs); } @@ -9613,7 +9598,7 @@ std::string NMD::LWUX(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("LWUX %s, %s(%s)", rd, rs, rt); + return img_format("LWUX %s, %s(%s)", rd, rs, rt); } @@ -9637,7 +9622,7 @@ std::string NMD::LWUXS(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("LWUXS %s, %s(%s)", rd, rs, rt); + return img_format("LWUXS %s, %s(%s)", rd, rs, rt); } @@ -9661,7 +9646,7 @@ std::string NMD::LWX(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("LWX %s, %s(%s)", rd, rs, rt); + return img_format("LWX %s, %s(%s)", rd, rs, rt); } @@ -9685,7 +9670,7 @@ std::string NMD::LWXS_16_(uint64 instruction) std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); std::string rt3 = IMMEDIATE(decode_gpr_gpr3(rt3_value)); - return img::format("LWXS %s, %s(%s)", rd3, rs3, rt3); + return img_format("LWXS %s, %s(%s)", rd3, rs3, rt3); } @@ -9709,7 +9694,7 @@ std::string NMD::LWXS_32_(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("LWXS %s, %s(%s)", rd, rs, rt); + return img_format("LWXS %s, %s(%s)", rd, rs, rt); } @@ -9734,7 +9719,7 @@ std::string NMD::MADD_DSP_(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("MADD %s, %s, %s", ac, rs, rt); + return img_format("MADD %s, %s, %s", ac, rs, rt); } @@ -9758,7 +9743,7 @@ std::string NMD::MADDF_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("MADDF.D %s, %s, %s", fd, fs, ft); + return img_format("MADDF.D %s, %s, %s", fd, fs, ft); } @@ -9782,7 +9767,7 @@ std::string NMD::MADDF_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("MADDF.S %s, %s, %s", fd, fs, ft); + return img_format("MADDF.S %s, %s, %s", fd, fs, ft); } @@ -9807,7 +9792,7 @@ std::string NMD::MADDU_DSP_(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("MADDU %s, %s, %s", ac, rs, rt); + return img_format("MADDU %s, %s, %s", ac, rs, rt); } @@ -9832,7 +9817,7 @@ std::string NMD::MAQ_S_W_PHL(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("MAQ_S.W.PHL %s, %s, %s", ac, rs, rt); + return img_format("MAQ_S.W.PHL %s, %s, %s", ac, rs, rt); } @@ -9857,7 +9842,7 @@ std::string NMD::MAQ_S_W_PHR(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("MAQ_S.W.PHR %s, %s, %s", ac, rs, rt); + return img_format("MAQ_S.W.PHR %s, %s, %s", ac, rs, rt); } @@ -9882,7 +9867,7 @@ std::string NMD::MAQ_SA_W_PHL(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("MAQ_SA.W.PHL %s, %s, %s", ac, rs, rt); + return img_format("MAQ_SA.W.PHL %s, %s, %s", ac, rs, rt); } @@ -9907,7 +9892,7 @@ std::string NMD::MAQ_SA_W_PHR(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("MAQ_SA.W.PHR %s, %s, %s", ac, rs, rt); + return img_format("MAQ_SA.W.PHR %s, %s, %s", ac, rs, rt); } @@ -9931,7 +9916,7 @@ std::string NMD::MAX_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("MAX.D %s, %s, %s", fd, fs, ft); + return img_format("MAX.D %s, %s, %s", fd, fs, ft); } @@ -9955,7 +9940,7 @@ std::string NMD::MAX_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("MAX.S %s, %s, %s", fd, fs, ft); + return img_format("MAX.S %s, %s, %s", fd, fs, ft); } @@ -9979,7 +9964,7 @@ std::string NMD::MAXA_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("MAXA.D %s, %s, %s", fd, fs, ft); + return img_format("MAXA.D %s, %s, %s", fd, fs, ft); } @@ -10003,7 +9988,7 @@ std::string NMD::MAXA_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("MAXA.S %s, %s, %s", fd, fs, ft); + return img_format("MAXA.S %s, %s, %s", fd, fs, ft); } @@ -10027,7 +10012,7 @@ std::string NMD::MFC0(uint64 instruction) std::string c0s = CPR(copy(c0s_value)); std::string sel = IMMEDIATE(copy(sel_value)); - return img::format("MFC0 %s, %s, %s", rt, c0s, sel); + return img_format("MFC0 %s, %s, %s", rt, c0s, sel); } @@ -10049,7 +10034,7 @@ std::string NMD::MFC1(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string fs = FPR(copy(fs_value)); - return img::format("MFC1 %s, %s", rt, fs); + return img_format("MFC1 %s, %s", rt, fs); } @@ -10071,7 +10056,7 @@ std::string NMD::MFC2(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string cs = CPR(copy(cs_value)); - return img::format("MFC2 %s, %s", rt, cs); + return img_format("MFC2 %s, %s", rt, cs); } @@ -10095,7 +10080,7 @@ std::string NMD::MFGC0(uint64 instruction) std::string c0s = CPR(copy(c0s_value)); std::string sel = IMMEDIATE(copy(sel_value)); - return img::format("MFGC0 %s, %s, %s", rt, c0s, sel); + return img_format("MFGC0 %s, %s, %s", rt, c0s, sel); } @@ -10119,7 +10104,7 @@ std::string NMD::MFHC0(uint64 instruction) std::string c0s = CPR(copy(c0s_value)); std::string sel = IMMEDIATE(copy(sel_value)); - return img::format("MFHC0 %s, %s, %s", rt, c0s, sel); + return img_format("MFHC0 %s, %s, %s", rt, c0s, sel); } @@ -10141,7 +10126,7 @@ std::string NMD::MFHC1(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string fs = FPR(copy(fs_value)); - return img::format("MFHC1 %s, %s", rt, fs); + return img_format("MFHC1 %s, %s", rt, fs); } @@ -10163,7 +10148,7 @@ std::string NMD::MFHC2(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string cs = CPR(copy(cs_value)); - return img::format("MFHC2 %s, %s", rt, cs); + return img_format("MFHC2 %s, %s", rt, cs); } @@ -10187,7 +10172,7 @@ std::string NMD::MFHGC0(uint64 instruction) std::string c0s = CPR(copy(c0s_value)); std::string sel = IMMEDIATE(copy(sel_value)); - return img::format("MFHGC0 %s, %s, %s", rt, c0s, sel); + return img_format("MFHGC0 %s, %s, %s", rt, c0s, sel); } @@ -10208,7 +10193,7 @@ std::string NMD::MFHI_DSP_(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string ac = AC(copy(ac_value)); - return img::format("MFHI %s, %s", rt, ac); + return img_format("MFHI %s, %s", rt, ac); } @@ -10234,7 +10219,7 @@ std::string NMD::MFHTR(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string sel = IMMEDIATE(copy(sel_value)); - return img::format("MFHTR %s, %s, %s, %s", rt, c0s, u, sel); + return img_format("MFHTR %s, %s, %s, %s", rt, c0s, u, sel); } @@ -10255,7 +10240,7 @@ std::string NMD::MFLO_DSP_(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string ac = AC(copy(ac_value)); - return img::format("MFLO %s, %s", rt, ac); + return img_format("MFLO %s, %s", rt, ac); } @@ -10281,7 +10266,7 @@ std::string NMD::MFTR(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string sel = IMMEDIATE(copy(sel_value)); - return img::format("MFTR %s, %s, %s, %s", rt, c0s, u, sel); + return img_format("MFTR %s, %s, %s, %s", rt, c0s, u, sel); } @@ -10305,7 +10290,7 @@ std::string NMD::MIN_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("MIN.D %s, %s, %s", fd, fs, ft); + return img_format("MIN.D %s, %s, %s", fd, fs, ft); } @@ -10329,7 +10314,7 @@ std::string NMD::MIN_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("MIN.S %s, %s, %s", fd, fs, ft); + return img_format("MIN.S %s, %s, %s", fd, fs, ft); } @@ -10353,7 +10338,7 @@ std::string NMD::MINA_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("MINA.D %s, %s, %s", fd, fs, ft); + return img_format("MINA.D %s, %s, %s", fd, fs, ft); } @@ -10377,7 +10362,7 @@ std::string NMD::MINA_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("MINA.S %s, %s, %s", fd, fs, ft); + return img_format("MINA.S %s, %s, %s", fd, fs, ft); } @@ -10401,7 +10386,7 @@ std::string NMD::MOD(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("MOD %s, %s, %s", rd, rs, rt); + return img_format("MOD %s, %s, %s", rd, rs, rt); } @@ -10425,7 +10410,7 @@ std::string NMD::MODSUB(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("MODSUB %s, %s, %s", rd, rs, rt); + return img_format("MODSUB %s, %s, %s", rd, rs, rt); } @@ -10449,7 +10434,7 @@ std::string NMD::MODU(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("MODU %s, %s, %s", rd, rs, rt); + return img_format("MODU %s, %s, %s", rd, rs, rt); } @@ -10471,7 +10456,7 @@ std::string NMD::MOV_D(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("MOV.D %s, %s", ft, fs); + return img_format("MOV.D %s, %s", ft, fs); } @@ -10493,7 +10478,7 @@ std::string NMD::MOV_S(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("MOV.S %s, %s", ft, fs); + return img_format("MOV.S %s, %s", ft, fs); } @@ -10517,7 +10502,7 @@ std::string NMD::MOVE_BALC(uint64 instruction) std::string rtz4 = GPR(decode_gpr_gpr4_zero(rtz4_value)); std::string s = ADDRESS(encode_s_from_address(s_value), 4); - return img::format("MOVE.BALC %s, %s, %s", rd1, rtz4, s); + return img_format("MOVE.BALC %s, %s, %s", rd1, rtz4, s); } @@ -10543,7 +10528,7 @@ std::string NMD::MOVEP(uint64 instruction) std::string rsz4 = GPR(decode_gpr_gpr4_zero(rsz4_value)); std::string rtz4 = GPR(decode_gpr_gpr4_zero(rtz4_value)); - return img::format("MOVEP %s, %s, %s, %s", rd2, re2, rsz4, rtz4); + return img_format("MOVEP %s, %s, %s, %s", rd2, re2, rsz4, rtz4); /* hand edited */ } @@ -10570,7 +10555,7 @@ std::string NMD::MOVEP_REV_(uint64 instruction) std::string rs2 = GPR(decode_gpr_gpr2_reg2(rd2_value)); /* !!!!!!!!!! - no conversion function */ - return img::format("MOVEP %s, %s, %s, %s", rs4, rt4, rd2, rs2); + return img_format("MOVEP %s, %s, %s, %s", rs4, rt4, rd2, rs2); /* hand edited */ } @@ -10593,7 +10578,7 @@ std::string NMD::MOVE(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("MOVE %s, %s", rt, rs); + return img_format("MOVE %s, %s", rt, rs); } @@ -10617,7 +10602,7 @@ std::string NMD::MOVN(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("MOVN %s, %s, %s", rd, rs, rt); + return img_format("MOVN %s, %s, %s", rd, rs, rt); } @@ -10641,7 +10626,7 @@ std::string NMD::MOVZ(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("MOVZ %s, %s, %s", rd, rs, rt); + return img_format("MOVZ %s, %s, %s", rd, rs, rt); } @@ -10665,7 +10650,7 @@ std::string NMD::MSUB_DSP_(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("MSUB %s, %s, %s", ac, rs, rt); + return img_format("MSUB %s, %s, %s", ac, rs, rt); } @@ -10689,7 +10674,7 @@ std::string NMD::MSUBF_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("MSUBF.D %s, %s, %s", fd, fs, ft); + return img_format("MSUBF.D %s, %s, %s", fd, fs, ft); } @@ -10713,7 +10698,7 @@ std::string NMD::MSUBF_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("MSUBF.S %s, %s, %s", fd, fs, ft); + return img_format("MSUBF.S %s, %s, %s", fd, fs, ft); } @@ -10737,7 +10722,7 @@ std::string NMD::MSUBU_DSP_(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("MSUBU %s, %s, %s", ac, rs, rt); + return img_format("MSUBU %s, %s, %s", ac, rs, rt); } @@ -10761,7 +10746,7 @@ std::string NMD::MTC0(uint64 instruction) std::string c0s = CPR(copy(c0s_value)); std::string sel = IMMEDIATE(copy(sel_value)); - return img::format("MTC0 %s, %s, %s", rt, c0s, sel); + return img_format("MTC0 %s, %s, %s", rt, c0s, sel); } @@ -10783,7 +10768,7 @@ std::string NMD::MTC1(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string fs = FPR(copy(fs_value)); - return img::format("MTC1 %s, %s", rt, fs); + return img_format("MTC1 %s, %s", rt, fs); } @@ -10805,7 +10790,7 @@ std::string NMD::MTC2(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string cs = CPR(copy(cs_value)); - return img::format("MTC2 %s, %s", rt, cs); + return img_format("MTC2 %s, %s", rt, cs); } @@ -10829,7 +10814,7 @@ std::string NMD::MTGC0(uint64 instruction) std::string c0s = CPR(copy(c0s_value)); std::string sel = IMMEDIATE(copy(sel_value)); - return img::format("MTGC0 %s, %s, %s", rt, c0s, sel); + return img_format("MTGC0 %s, %s, %s", rt, c0s, sel); } @@ -10853,7 +10838,7 @@ std::string NMD::MTHC0(uint64 instruction) std::string c0s = CPR(copy(c0s_value)); std::string sel = IMMEDIATE(copy(sel_value)); - return img::format("MTHC0 %s, %s, %s", rt, c0s, sel); + return img_format("MTHC0 %s, %s, %s", rt, c0s, sel); } @@ -10875,7 +10860,7 @@ std::string NMD::MTHC1(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string fs = FPR(copy(fs_value)); - return img::format("MTHC1 %s, %s", rt, fs); + return img_format("MTHC1 %s, %s", rt, fs); } @@ -10897,7 +10882,7 @@ std::string NMD::MTHC2(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string cs = CPR(copy(cs_value)); - return img::format("MTHC2 %s, %s", rt, cs); + return img_format("MTHC2 %s, %s", rt, cs); } @@ -10921,7 +10906,7 @@ std::string NMD::MTHGC0(uint64 instruction) std::string c0s = CPR(copy(c0s_value)); std::string sel = IMMEDIATE(copy(sel_value)); - return img::format("MTHGC0 %s, %s, %s", rt, c0s, sel); + return img_format("MTHGC0 %s, %s, %s", rt, c0s, sel); } @@ -10942,7 +10927,7 @@ std::string NMD::MTHI_DSP_(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string ac = AC(copy(ac_value)); - return img::format("MTHI %s, %s", rs, ac); + return img_format("MTHI %s, %s", rs, ac); } @@ -10963,7 +10948,7 @@ std::string NMD::MTHLIP(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string ac = AC(copy(ac_value)); - return img::format("MTHLIP %s, %s", rs, ac); + return img_format("MTHLIP %s, %s", rs, ac); } @@ -10989,7 +10974,7 @@ std::string NMD::MTHTR(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string sel = IMMEDIATE(copy(sel_value)); - return img::format("MTHTR %s, %s, %s, %s", rt, c0s, u, sel); + return img_format("MTHTR %s, %s, %s, %s", rt, c0s, u, sel); } @@ -11010,7 +10995,7 @@ std::string NMD::MTLO_DSP_(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string ac = AC(copy(ac_value)); - return img::format("MTLO %s, %s", rs, ac); + return img_format("MTLO %s, %s", rs, ac); } @@ -11036,7 +11021,7 @@ std::string NMD::MTTR(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string sel = IMMEDIATE(copy(sel_value)); - return img::format("MTTR %s, %s, %s, %s", rt, c0s, u, sel); + return img_format("MTTR %s, %s, %s, %s", rt, c0s, u, sel); } @@ -11060,7 +11045,7 @@ std::string NMD::MUH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("MUH %s, %s, %s", rd, rs, rt); + return img_format("MUH %s, %s, %s", rd, rs, rt); } @@ -11084,7 +11069,7 @@ std::string NMD::MUHU(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("MUHU %s, %s, %s", rd, rs, rt); + return img_format("MUHU %s, %s, %s", rd, rs, rt); } @@ -11108,7 +11093,7 @@ std::string NMD::MUL_32_(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("MUL %s, %s, %s", rd, rs, rt); + return img_format("MUL %s, %s, %s", rd, rs, rt); } @@ -11130,7 +11115,7 @@ std::string NMD::MUL_4X4_(uint64 instruction) std::string rs4 = GPR(decode_gpr_gpr4(rs4_value)); std::string rt4 = GPR(decode_gpr_gpr4(rt4_value)); - return img::format("MUL %s, %s", rs4, rt4); + return img_format("MUL %s, %s", rs4, rt4); } @@ -11154,7 +11139,7 @@ std::string NMD::MUL_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("MUL.D %s, %s, %s", fd, fs, ft); + return img_format("MUL.D %s, %s, %s", fd, fs, ft); } @@ -11179,7 +11164,7 @@ std::string NMD::MUL_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("MUL.PH %s, %s, %s", rd, rs, rt); + return img_format("MUL.PH %s, %s, %s", rd, rs, rt); } @@ -11204,7 +11189,7 @@ std::string NMD::MUL_S_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("MUL_S.PH %s, %s, %s", rd, rs, rt); + return img_format("MUL_S.PH %s, %s, %s", rd, rs, rt); } @@ -11228,7 +11213,7 @@ std::string NMD::MUL_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("MUL.S %s, %s, %s", fd, fs, ft); + return img_format("MUL.S %s, %s, %s", fd, fs, ft); } @@ -11253,7 +11238,7 @@ std::string NMD::MULEQ_S_W_PHL(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("MULEQ_S.W.PHL %s, %s, %s", rd, rs, rt); + return img_format("MULEQ_S.W.PHL %s, %s, %s", rd, rs, rt); } @@ -11278,7 +11263,7 @@ std::string NMD::MULEQ_S_W_PHR(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("MULEQ_S.W.PHR %s, %s, %s", rd, rs, rt); + return img_format("MULEQ_S.W.PHR %s, %s, %s", rd, rs, rt); } @@ -11303,7 +11288,7 @@ std::string NMD::MULEU_S_PH_QBL(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("MULEU_S.PH.QBL %s, %s, %s", rd, rs, rt); + return img_format("MULEU_S.PH.QBL %s, %s, %s", rd, rs, rt); } @@ -11328,7 +11313,7 @@ std::string NMD::MULEU_S_PH_QBR(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("MULEU_S.PH.QBR %s, %s, %s", rd, rs, rt); + return img_format("MULEU_S.PH.QBR %s, %s, %s", rd, rs, rt); } @@ -11353,7 +11338,7 @@ std::string NMD::MULQ_RS_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("MULQ_RS.PH %s, %s, %s", rd, rs, rt); + return img_format("MULQ_RS.PH %s, %s, %s", rd, rs, rt); } @@ -11378,7 +11363,7 @@ std::string NMD::MULQ_RS_W(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("MULQ_RS.W %s, %s, %s", rd, rs, rt); + return img_format("MULQ_RS.W %s, %s, %s", rd, rs, rt); } @@ -11403,7 +11388,7 @@ std::string NMD::MULQ_S_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("MULQ_S.PH %s, %s, %s", rd, rs, rt); + return img_format("MULQ_S.PH %s, %s, %s", rd, rs, rt); } @@ -11428,7 +11413,7 @@ std::string NMD::MULQ_S_W(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("MULQ_S.W %s, %s, %s", rd, rs, rt); + return img_format("MULQ_S.W %s, %s, %s", rd, rs, rt); } @@ -11453,7 +11438,7 @@ std::string NMD::MULSA_W_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("MULSA.W.PH %s, %s, %s", ac, rs, rt); + return img_format("MULSA.W.PH %s, %s, %s", ac, rs, rt); } @@ -11478,7 +11463,7 @@ std::string NMD::MULSAQ_S_W_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("MULSAQ_S.W.PH %s, %s, %s", ac, rs, rt); + return img_format("MULSAQ_S.W.PH %s, %s, %s", ac, rs, rt); } @@ -11502,7 +11487,7 @@ std::string NMD::MULT_DSP_(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("MULT %s, %s, %s", ac, rs, rt); + return img_format("MULT %s, %s, %s", ac, rs, rt); } @@ -11526,7 +11511,7 @@ std::string NMD::MULTU_DSP_(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("MULTU %s, %s, %s", ac, rs, rt); + return img_format("MULTU %s, %s, %s", ac, rs, rt); } @@ -11550,7 +11535,7 @@ std::string NMD::MULU(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("MULU %s, %s, %s", rd, rs, rt); + return img_format("MULU %s, %s, %s", rd, rs, rt); } @@ -11572,7 +11557,7 @@ std::string NMD::NEG_D(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("NEG.D %s, %s", ft, fs); + return img_format("NEG.D %s, %s", ft, fs); } @@ -11594,7 +11579,7 @@ std::string NMD::NEG_S(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("NEG.S %s, %s", ft, fs); + return img_format("NEG.S %s, %s", ft, fs); } @@ -11654,7 +11639,7 @@ std::string NMD::NOR(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("NOR %s, %s, %s", rd, rs, rt); + return img_format("NOR %s, %s, %s", rd, rs, rt); } @@ -11676,7 +11661,7 @@ std::string NMD::NOT_16_(uint64 instruction) std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); - return img::format("NOT %s, %s", rt3, rs3); + return img_format("NOT %s, %s", rt3, rs3); } @@ -11698,7 +11683,7 @@ std::string NMD::OR_16_(uint64 instruction) std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - return img::format("OR %s, %s", rs3, rt3); + return img_format("OR %s, %s", rs3, rt3); } @@ -11722,7 +11707,7 @@ std::string NMD::OR_32_(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("OR %s, %s, %s", rd, rs, rt); + return img_format("OR %s, %s, %s", rd, rs, rt); } @@ -11746,7 +11731,7 @@ std::string NMD::ORI(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string u = IMMEDIATE(copy(u_value)); - return img::format("ORI %s, %s, %s", rt, rs, u); + return img_format("ORI %s, %s, %s", rt, rs, u); } @@ -11771,7 +11756,7 @@ std::string NMD::PACKRL_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("PACKRL.PH %s, %s, %s", rd, rs, rt); + return img_format("PACKRL.PH %s, %s, %s", rd, rs, rt); } @@ -11814,7 +11799,7 @@ std::string NMD::PICK_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("PICK.PH %s, %s, %s", rd, rs, rt); + return img_format("PICK.PH %s, %s, %s", rd, rs, rt); } @@ -11839,7 +11824,7 @@ std::string NMD::PICK_QB(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("PICK.QB %s, %s, %s", rd, rs, rt); + return img_format("PICK.QB %s, %s, %s", rd, rs, rt); } @@ -11862,7 +11847,7 @@ std::string NMD::PRECEQ_W_PHL(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("PRECEQ.W.PHL %s, %s", rt, rs); + return img_format("PRECEQ.W.PHL %s, %s", rt, rs); } @@ -11885,7 +11870,7 @@ std::string NMD::PRECEQ_W_PHR(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("PRECEQ.W.PHR %s, %s", rt, rs); + return img_format("PRECEQ.W.PHR %s, %s", rt, rs); } @@ -11908,7 +11893,7 @@ std::string NMD::PRECEQU_PH_QBLA(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("PRECEQU.PH.QBLA %s, %s", rt, rs); + return img_format("PRECEQU.PH.QBLA %s, %s", rt, rs); } @@ -11931,7 +11916,7 @@ std::string NMD::PRECEQU_PH_QBL(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("PRECEQU.PH.QBL %s, %s", rt, rs); + return img_format("PRECEQU.PH.QBL %s, %s", rt, rs); } @@ -11954,7 +11939,7 @@ std::string NMD::PRECEQU_PH_QBRA(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("PRECEQU.PH.QBRA %s, %s", rt, rs); + return img_format("PRECEQU.PH.QBRA %s, %s", rt, rs); } @@ -11977,7 +11962,7 @@ std::string NMD::PRECEQU_PH_QBR(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("PRECEQU.PH.QBR %s, %s", rt, rs); + return img_format("PRECEQU.PH.QBR %s, %s", rt, rs); } @@ -12001,7 +11986,7 @@ std::string NMD::PRECEU_PH_QBLA(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("PRECEU.PH.QBLA %s, %s", rt, rs); + return img_format("PRECEU.PH.QBLA %s, %s", rt, rs); } @@ -12024,7 +12009,7 @@ std::string NMD::PRECEU_PH_QBL(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("PRECEU.PH.QBL %s, %s", rt, rs); + return img_format("PRECEU.PH.QBL %s, %s", rt, rs); } @@ -12048,7 +12033,7 @@ std::string NMD::PRECEU_PH_QBRA(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("PRECEU.PH.QBRA %s, %s", rt, rs); + return img_format("PRECEU.PH.QBRA %s, %s", rt, rs); } @@ -12071,7 +12056,7 @@ std::string NMD::PRECEU_PH_QBR(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("PRECEU.PH.QBR %s, %s", rt, rs); + return img_format("PRECEU.PH.QBR %s, %s", rt, rs); } @@ -12096,7 +12081,7 @@ std::string NMD::PRECR_QB_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("PRECR.QB.PH %s, %s, %s", rd, rs, rt); + return img_format("PRECR.QB.PH %s, %s, %s", rd, rs, rt); } @@ -12121,7 +12106,7 @@ std::string NMD::PRECR_SRA_PH_W(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string sa = IMMEDIATE(copy(sa_value)); - return img::format("PRECR_SRA.PH.W %s, %s, %s", rt, rs, sa); + return img_format("PRECR_SRA.PH.W %s, %s, %s", rt, rs, sa); } @@ -12146,7 +12131,7 @@ std::string NMD::PRECR_SRA_R_PH_W(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string sa = IMMEDIATE(copy(sa_value)); - return img::format("PRECR_SRA_R.PH.W %s, %s, %s", rt, rs, sa); + return img_format("PRECR_SRA_R.PH.W %s, %s, %s", rt, rs, sa); } @@ -12171,7 +12156,7 @@ std::string NMD::PRECRQ_PH_W(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("PRECRQ.PH.W %s, %s, %s", rd, rs, rt); + return img_format("PRECRQ.PH.W %s, %s, %s", rd, rs, rt); } @@ -12196,7 +12181,7 @@ std::string NMD::PRECRQ_QB_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("PRECRQ.QB.PH %s, %s, %s", rd, rs, rt); + return img_format("PRECRQ.QB.PH %s, %s, %s", rd, rs, rt); } @@ -12221,7 +12206,7 @@ std::string NMD::PRECRQ_RS_PH_W(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("PRECRQ_RS.PH.W %s, %s, %s", rd, rs, rt); + return img_format("PRECRQ_RS.PH.W %s, %s, %s", rd, rs, rt); } @@ -12246,7 +12231,7 @@ std::string NMD::PRECRQU_S_QB_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("PRECRQU_S.QB.PH %s, %s, %s", rd, rs, rt); + return img_format("PRECRQU_S.QB.PH %s, %s, %s", rd, rs, rt); } @@ -12270,7 +12255,7 @@ std::string NMD::PREF_S9_(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("PREF %s, %s(%s)", hint, s, rs); + return img_format("PREF %s, %s(%s)", hint, s, rs); } @@ -12294,7 +12279,7 @@ std::string NMD::PREF_U12_(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string rs = GPR(copy(rs_value)); - return img::format("PREF %s, %s(%s)", hint, u, rs); + return img_format("PREF %s, %s(%s)", hint, u, rs); } @@ -12318,7 +12303,7 @@ std::string NMD::PREFE(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("PREFE %s, %s(%s)", hint, s, rs); + return img_format("PREFE %s, %s(%s)", hint, s, rs); } @@ -12342,7 +12327,7 @@ std::string NMD::PREPEND(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string sa = IMMEDIATE(copy(sa_value)); - return img::format("PREPEND %s, %s, %s", rt, rs, sa); + return img_format("PREPEND %s, %s, %s", rt, rs, sa); } @@ -12363,7 +12348,7 @@ std::string NMD::RADDU_W_QB(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("RADDU.W.QB %s, %s", rt, rs); + return img_format("RADDU.W.QB %s, %s", rt, rs); } @@ -12384,7 +12369,7 @@ std::string NMD::RDDSP(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string mask = IMMEDIATE(copy(mask_value)); - return img::format("RDDSP %s, %s", rt, mask); + return img_format("RDDSP %s, %s", rt, mask); } @@ -12408,7 +12393,7 @@ std::string NMD::RDHWR(uint64 instruction) std::string hs = CPR(copy(hs_value)); std::string sel = IMMEDIATE(copy(sel_value)); - return img::format("RDHWR %s, %s, %s", rt, hs, sel); + return img_format("RDHWR %s, %s, %s", rt, hs, sel); } @@ -12430,7 +12415,7 @@ std::string NMD::RDPGPR(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("RDPGPR %s, %s", rt, rs); + return img_format("RDPGPR %s, %s", rt, rs); } @@ -12452,7 +12437,7 @@ std::string NMD::RECIP_D(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("RECIP.D %s, %s", ft, fs); + return img_format("RECIP.D %s, %s", ft, fs); } @@ -12474,7 +12459,7 @@ std::string NMD::RECIP_S(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("RECIP.S %s, %s", ft, fs); + return img_format("RECIP.S %s, %s", ft, fs); } @@ -12496,7 +12481,7 @@ std::string NMD::REPL_PH(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string s = IMMEDIATE(copy(s_value)); - return img::format("REPL.PH %s, %s", rt, s); + return img_format("REPL.PH %s, %s", rt, s); } @@ -12518,7 +12503,7 @@ std::string NMD::REPL_QB(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string u = IMMEDIATE(copy(u_value)); - return img::format("REPL.QB %s, %s", rt, u); + return img_format("REPL.QB %s, %s", rt, u); } @@ -12540,7 +12525,7 @@ std::string NMD::REPLV_PH(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("REPLV.PH %s, %s", rt, rs); + return img_format("REPLV.PH %s, %s", rt, rs); } @@ -12561,7 +12546,7 @@ std::string NMD::REPLV_QB(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("REPLV.QB %s, %s", rt, rs); + return img_format("REPLV.QB %s, %s", rt, rs); } @@ -12583,7 +12568,7 @@ std::string NMD::RESTORE_32_(uint64 instruction) uint64 gp_value = extract_gp_2(instruction); std::string u = IMMEDIATE(copy(u_value)); - return img::format("RESTORE %s%s", u, + return img_format("RESTORE %s%s", u, save_restore_list(rt_value, count_value, gp_value)); } @@ -12605,7 +12590,7 @@ std::string NMD::RESTORE_JRC_16_(uint64 instruction) uint64 count_value = extract_count_3_2_1_0(instruction); std::string u = IMMEDIATE(copy(u_value)); - return img::format("RESTORE.JRC %s%s", u, + return img_format("RESTORE.JRC %s%s", u, save_restore_list(encode_rt1_from_rt(rt1_value), count_value, 0)); } @@ -12628,7 +12613,7 @@ std::string NMD::RESTORE_JRC_32_(uint64 instruction) uint64 gp_value = extract_gp_2(instruction); std::string u = IMMEDIATE(copy(u_value)); - return img::format("RESTORE.JRC %s%s", u, + return img_format("RESTORE.JRC %s%s", u, save_restore_list(rt_value, count_value, gp_value)); } @@ -12651,7 +12636,7 @@ std::string NMD::RESTOREF(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string count = IMMEDIATE(copy(count_value)); - return img::format("RESTOREF %s, %s", u, count); + return img_format("RESTOREF %s, %s", u, count); } @@ -12673,7 +12658,7 @@ std::string NMD::RINT_D(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("RINT.D %s, %s", ft, fs); + return img_format("RINT.D %s, %s", ft, fs); } @@ -12695,7 +12680,7 @@ std::string NMD::RINT_S(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("RINT.S %s, %s", ft, fs); + return img_format("RINT.S %s, %s", ft, fs); } @@ -12719,7 +12704,7 @@ std::string NMD::ROTR(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string shift = IMMEDIATE(copy(shift_value)); - return img::format("ROTR %s, %s, %s", rt, rs, shift); + return img_format("ROTR %s, %s, %s", rt, rs, shift); } @@ -12743,7 +12728,7 @@ std::string NMD::ROTRV(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("ROTRV %s, %s, %s", rd, rs, rt); + return img_format("ROTRV %s, %s, %s", rd, rs, rt); } @@ -12771,7 +12756,7 @@ std::string NMD::ROTX(uint64 instruction) std::string shiftx = IMMEDIATE(copy(shiftx_value)); std::string stripe = IMMEDIATE(copy(stripe_value)); - return img::format("ROTX %s, %s, %s, %s, %s", + return img_format("ROTX %s, %s, %s, %s, %s", rt, rs, shift, shiftx, stripe); } @@ -12794,7 +12779,7 @@ std::string NMD::ROUND_L_D(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("ROUND.L.D %s, %s", ft, fs); + return img_format("ROUND.L.D %s, %s", ft, fs); } @@ -12816,7 +12801,7 @@ std::string NMD::ROUND_L_S(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("ROUND.L.S %s, %s", ft, fs); + return img_format("ROUND.L.S %s, %s", ft, fs); } @@ -12838,7 +12823,7 @@ std::string NMD::ROUND_W_D(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("ROUND.W.D %s, %s", ft, fs); + return img_format("ROUND.W.D %s, %s", ft, fs); } @@ -12860,7 +12845,7 @@ std::string NMD::ROUND_W_S(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("ROUND.W.S %s, %s", ft, fs); + return img_format("ROUND.W.S %s, %s", ft, fs); } @@ -12882,7 +12867,7 @@ std::string NMD::RSQRT_D(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("RSQRT.D %s, %s", ft, fs); + return img_format("RSQRT.D %s, %s", ft, fs); } @@ -12904,7 +12889,7 @@ std::string NMD::RSQRT_S(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("RSQRT.S %s, %s", ft, fs); + return img_format("RSQRT.S %s, %s", ft, fs); } @@ -12925,7 +12910,7 @@ std::string NMD::SAVE_16_(uint64 instruction) uint64 count_value = extract_count_3_2_1_0(instruction); std::string u = IMMEDIATE(copy(u_value)); - return img::format("SAVE %s%s", u, + return img_format("SAVE %s%s", u, save_restore_list(encode_rt1_from_rt(rt1_value), count_value, 0)); } @@ -12948,7 +12933,7 @@ std::string NMD::SAVE_32_(uint64 instruction) uint64 gp_value = extract_gp_2(instruction); std::string u = IMMEDIATE(copy(u_value)); - return img::format("SAVE %s%s", u, + return img_format("SAVE %s%s", u, save_restore_list(rt_value, count_value, gp_value)); } @@ -12971,7 +12956,7 @@ std::string NMD::SAVEF(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string count = IMMEDIATE(copy(count_value)); - return img::format("SAVEF %s, %s", u, count); + return img_format("SAVEF %s, %s", u, count); } @@ -12995,7 +12980,7 @@ std::string NMD::SB_16_(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); - return img::format("SB %s, %s(%s)", rtz3, u, rs3); + return img_format("SB %s, %s(%s)", rtz3, u, rs3); } @@ -13017,7 +13002,7 @@ std::string NMD::SB_GP_(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string u = IMMEDIATE(copy(u_value)); - return img::format("SB %s, %s($%d)", rt, u, 28); + return img_format("SB %s, %s($%d)", rt, u, 28); } @@ -13041,7 +13026,7 @@ std::string NMD::SB_S9_(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SB %s, %s(%s)", rt, s, rs); + return img_format("SB %s, %s(%s)", rt, s, rs); } @@ -13065,7 +13050,7 @@ std::string NMD::SB_U12_(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SB %s, %s(%s)", rt, u, rs); + return img_format("SB %s, %s(%s)", rt, u, rs); } @@ -13089,7 +13074,7 @@ std::string NMD::SBE(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SBE %s, %s(%s)", rt, s, rs); + return img_format("SBE %s, %s(%s)", rt, s, rs); } @@ -13113,7 +13098,7 @@ std::string NMD::SBX(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("SBX %s, %s(%s)", rd, rs, rt); + return img_format("SBX %s, %s(%s)", rd, rs, rt); } @@ -13137,7 +13122,7 @@ std::string NMD::SC(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SC %s, %s(%s)", rt, s, rs); + return img_format("SC %s, %s(%s)", rt, s, rs); } @@ -13161,7 +13146,7 @@ std::string NMD::SCD(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SCD %s, %s(%s)", rt, s, rs); + return img_format("SCD %s, %s(%s)", rt, s, rs); } @@ -13185,7 +13170,7 @@ std::string NMD::SCDP(uint64 instruction) std::string ru = GPR(copy(ru_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SCDP %s, %s, (%s)", rt, ru, rs); + return img_format("SCDP %s, %s, (%s)", rt, ru, rs); } @@ -13209,7 +13194,7 @@ std::string NMD::SCE(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SCE %s, %s(%s)", rt, s, rs); + return img_format("SCE %s, %s(%s)", rt, s, rs); } @@ -13233,7 +13218,7 @@ std::string NMD::SCWP(uint64 instruction) std::string ru = GPR(copy(ru_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SCWP %s, %s, (%s)", rt, ru, rs); + return img_format("SCWP %s, %s, (%s)", rt, ru, rs); } @@ -13257,7 +13242,7 @@ std::string NMD::SCWPE(uint64 instruction) std::string ru = GPR(copy(ru_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SCWPE %s, %s, (%s)", rt, ru, rs); + return img_format("SCWPE %s, %s, (%s)", rt, ru, rs); } @@ -13279,7 +13264,7 @@ std::string NMD::SD_GP_(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string u = IMMEDIATE(copy(u_value)); - return img::format("SD %s, %s($%d)", rt, u, 28); + return img_format("SD %s, %s($%d)", rt, u, 28); } @@ -13303,7 +13288,7 @@ std::string NMD::SD_S9_(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SD %s, %s(%s)", rt, s, rs); + return img_format("SD %s, %s(%s)", rt, s, rs); } @@ -13327,7 +13312,7 @@ std::string NMD::SD_U12_(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SD %s, %s(%s)", rt, u, rs); + return img_format("SD %s, %s(%s)", rt, u, rs); } @@ -13347,7 +13332,7 @@ std::string NMD::SDBBP_16_(uint64 instruction) std::string code = IMMEDIATE(copy(code_value)); - return img::format("SDBBP %s", code); + return img_format("SDBBP %s", code); } @@ -13367,7 +13352,7 @@ std::string NMD::SDBBP_32_(uint64 instruction) std::string code = IMMEDIATE(copy(code_value)); - return img::format("SDBBP %s", code); + return img_format("SDBBP %s", code); } @@ -13389,7 +13374,7 @@ std::string NMD::SDC1_GP_(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string u = IMMEDIATE(copy(u_value)); - return img::format("SDC1 %s, %s($%d)", ft, u, 28); + return img_format("SDC1 %s, %s($%d)", ft, u, 28); } @@ -13413,7 +13398,7 @@ std::string NMD::SDC1_S9_(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SDC1 %s, %s(%s)", ft, s, rs); + return img_format("SDC1 %s, %s(%s)", ft, s, rs); } @@ -13437,7 +13422,7 @@ std::string NMD::SDC1_U12_(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SDC1 %s, %s(%s)", ft, u, rs); + return img_format("SDC1 %s, %s(%s)", ft, u, rs); } @@ -13461,7 +13446,7 @@ std::string NMD::SDC1X(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("SDC1X %s, %s(%s)", ft, rs, rt); + return img_format("SDC1X %s, %s(%s)", ft, rs, rt); } @@ -13485,7 +13470,7 @@ std::string NMD::SDC1XS(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("SDC1XS %s, %s(%s)", ft, rs, rt); + return img_format("SDC1XS %s, %s(%s)", ft, rs, rt); } @@ -13509,7 +13494,7 @@ std::string NMD::SDC2(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SDC2 %s, %s(%s)", cs, s, rs); + return img_format("SDC2 %s, %s(%s)", cs, s, rs); } @@ -13535,7 +13520,7 @@ std::string NMD::SDM(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string count3 = IMMEDIATE(encode_count3_from_count(count3_value)); - return img::format("SDM %s, %s(%s), %s", rt, s, rs, count3); + return img_format("SDM %s, %s(%s), %s", rt, s, rs, count3); } @@ -13557,7 +13542,7 @@ std::string NMD::SDPC_48_(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string s = ADDRESS(encode_s_from_address(s_value), 6); - return img::format("SDPC %s, %s", rt, s); + return img_format("SDPC %s, %s", rt, s); } @@ -13581,7 +13566,7 @@ std::string NMD::SDXS(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("SDXS %s, %s(%s)", rd, rs, rt); + return img_format("SDXS %s, %s(%s)", rd, rs, rt); } @@ -13605,7 +13590,7 @@ std::string NMD::SDX(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("SDX %s, %s(%s)", rd, rs, rt); + return img_format("SDX %s, %s(%s)", rd, rs, rt); } @@ -13627,7 +13612,7 @@ std::string NMD::SEB(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SEB %s, %s", rt, rs); + return img_format("SEB %s, %s", rt, rs); } @@ -13649,7 +13634,7 @@ std::string NMD::SEH(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SEH %s, %s", rt, rs); + return img_format("SEH %s, %s", rt, rs); } @@ -13673,7 +13658,7 @@ std::string NMD::SEL_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("SEL.D %s, %s, %s", fd, fs, ft); + return img_format("SEL.D %s, %s, %s", fd, fs, ft); } @@ -13697,7 +13682,7 @@ std::string NMD::SEL_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("SEL.S %s, %s, %s", fd, fs, ft); + return img_format("SEL.S %s, %s, %s", fd, fs, ft); } @@ -13721,7 +13706,7 @@ std::string NMD::SELEQZ_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("SELEQZ.D %s, %s, %s", fd, fs, ft); + return img_format("SELEQZ.D %s, %s, %s", fd, fs, ft); } @@ -13745,7 +13730,7 @@ std::string NMD::SELEQZ_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("SELEQZ.S %s, %s, %s", fd, fs, ft); + return img_format("SELEQZ.S %s, %s, %s", fd, fs, ft); } @@ -13769,7 +13754,7 @@ std::string NMD::SELNEZ_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("SELNEZ.D %s, %s, %s", fd, fs, ft); + return img_format("SELNEZ.D %s, %s, %s", fd, fs, ft); } @@ -13793,7 +13778,7 @@ std::string NMD::SELNEZ_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("SELNEZ.S %s, %s, %s", fd, fs, ft); + return img_format("SELNEZ.S %s, %s, %s", fd, fs, ft); } @@ -13817,7 +13802,7 @@ std::string NMD::SEQI(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string u = IMMEDIATE(copy(u_value)); - return img::format("SEQI %s, %s, %s", rt, rs, u); + return img_format("SEQI %s, %s, %s", rt, rs, u); } @@ -13841,7 +13826,7 @@ std::string NMD::SH_16_(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); - return img::format("SH %s, %s(%s)", rtz3, u, rs3); + return img_format("SH %s, %s(%s)", rtz3, u, rs3); } @@ -13863,7 +13848,7 @@ std::string NMD::SH_GP_(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string u = IMMEDIATE(copy(u_value)); - return img::format("SH %s, %s($%d)", rt, u, 28); + return img_format("SH %s, %s($%d)", rt, u, 28); } @@ -13887,7 +13872,7 @@ std::string NMD::SH_S9_(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SH %s, %s(%s)", rt, s, rs); + return img_format("SH %s, %s(%s)", rt, s, rs); } @@ -13911,7 +13896,7 @@ std::string NMD::SH_U12_(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SH %s, %s(%s)", rt, u, rs); + return img_format("SH %s, %s(%s)", rt, u, rs); } @@ -13935,7 +13920,7 @@ std::string NMD::SHE(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SHE %s, %s(%s)", rt, s, rs); + return img_format("SHE %s, %s(%s)", rt, s, rs); } @@ -13957,7 +13942,7 @@ std::string NMD::SHILO(uint64 instruction) std::string shift = IMMEDIATE(copy(shift_value)); std::string ac = AC(copy(ac_value)); - return img::format("SHILO %s, %s", ac, shift); + return img_format("SHILO %s, %s", ac, shift); } @@ -13979,7 +13964,7 @@ std::string NMD::SHILOV(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string ac = AC(copy(ac_value)); - return img::format("SHILOV %s, %s", ac, rs); + return img_format("SHILOV %s, %s", ac, rs); } @@ -14003,7 +13988,7 @@ std::string NMD::SHLL_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string sa = IMMEDIATE(copy(sa_value)); - return img::format("SHLL.PH %s, %s, %s", rt, rs, sa); + return img_format("SHLL.PH %s, %s, %s", rt, rs, sa); } @@ -14027,7 +14012,7 @@ std::string NMD::SHLL_QB(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string sa = IMMEDIATE(copy(sa_value)); - return img::format("SHLL.QB %s, %s, %s", rt, rs, sa); + return img_format("SHLL.QB %s, %s, %s", rt, rs, sa); } @@ -14052,7 +14037,7 @@ std::string NMD::SHLL_S_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string sa = IMMEDIATE(copy(sa_value)); - return img::format("SHLL_S.PH %s, %s, %s", rt, rs, sa); + return img_format("SHLL_S.PH %s, %s, %s", rt, rs, sa); } @@ -14076,7 +14061,7 @@ std::string NMD::SHLL_S_W(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string sa = IMMEDIATE(copy(sa_value)); - return img::format("SHLL_S.W %s, %s, %s", rt, rs, sa); + return img_format("SHLL_S.W %s, %s, %s", rt, rs, sa); } @@ -14101,7 +14086,7 @@ std::string NMD::SHLLV_PH(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SHLLV.PH %s, %s, %s", rd, rt, rs); + return img_format("SHLLV.PH %s, %s, %s", rd, rt, rs); } @@ -14125,7 +14110,7 @@ std::string NMD::SHLLV_QB(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SHLLV.QB %s, %s, %s", rd, rt, rs); + return img_format("SHLLV.QB %s, %s, %s", rd, rt, rs); } @@ -14150,7 +14135,7 @@ std::string NMD::SHLLV_S_PH(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SHLLV_S.PH %s, %s, %s", rd, rt, rs); + return img_format("SHLLV_S.PH %s, %s, %s", rd, rt, rs); } @@ -14174,7 +14159,7 @@ std::string NMD::SHLLV_S_W(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SHLLV_S.W %s, %s, %s", rd, rt, rs); + return img_format("SHLLV_S.W %s, %s, %s", rd, rt, rs); } @@ -14198,7 +14183,7 @@ std::string NMD::SHRA_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string sa = IMMEDIATE(copy(sa_value)); - return img::format("SHRA.PH %s, %s, %s", rt, rs, sa); + return img_format("SHRA.PH %s, %s, %s", rt, rs, sa); } @@ -14222,7 +14207,7 @@ std::string NMD::SHRA_QB(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string sa = IMMEDIATE(copy(sa_value)); - return img::format("SHRA.QB %s, %s, %s", rt, rs, sa); + return img_format("SHRA.QB %s, %s, %s", rt, rs, sa); } @@ -14246,7 +14231,7 @@ std::string NMD::SHRA_R_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string sa = IMMEDIATE(copy(sa_value)); - return img::format("SHRA_R.PH %s, %s, %s", rt, rs, sa); + return img_format("SHRA_R.PH %s, %s, %s", rt, rs, sa); } @@ -14270,7 +14255,7 @@ std::string NMD::SHRA_R_QB(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string sa = IMMEDIATE(copy(sa_value)); - return img::format("SHRA_R.QB %s, %s, %s", rt, rs, sa); + return img_format("SHRA_R.QB %s, %s, %s", rt, rs, sa); } @@ -14294,7 +14279,7 @@ std::string NMD::SHRA_R_W(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string sa = IMMEDIATE(copy(sa_value)); - return img::format("SHRA_R.W %s, %s, %s", rt, rs, sa); + return img_format("SHRA_R.W %s, %s, %s", rt, rs, sa); } @@ -14318,7 +14303,7 @@ std::string NMD::SHRAV_PH(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SHRAV.PH %s, %s, %s", rd, rt, rs); + return img_format("SHRAV.PH %s, %s, %s", rd, rt, rs); } @@ -14342,7 +14327,7 @@ std::string NMD::SHRAV_QB(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SHRAV.QB %s, %s, %s", rd, rt, rs); + return img_format("SHRAV.QB %s, %s, %s", rd, rt, rs); } @@ -14366,7 +14351,7 @@ std::string NMD::SHRAV_R_PH(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SHRAV_R.PH %s, %s, %s", rd, rt, rs); + return img_format("SHRAV_R.PH %s, %s, %s", rd, rt, rs); } @@ -14390,7 +14375,7 @@ std::string NMD::SHRAV_R_QB(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SHRAV_R.QB %s, %s, %s", rd, rt, rs); + return img_format("SHRAV_R.QB %s, %s, %s", rd, rt, rs); } @@ -14414,7 +14399,7 @@ std::string NMD::SHRAV_R_W(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SHRAV_R.W %s, %s, %s", rd, rt, rs); + return img_format("SHRAV_R.W %s, %s, %s", rd, rt, rs); } @@ -14438,7 +14423,7 @@ std::string NMD::SHRL_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string sa = IMMEDIATE(copy(sa_value)); - return img::format("SHRL.PH %s, %s, %s", rt, rs, sa); + return img_format("SHRL.PH %s, %s, %s", rt, rs, sa); } @@ -14462,7 +14447,7 @@ std::string NMD::SHRL_QB(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string sa = IMMEDIATE(copy(sa_value)); - return img::format("SHRL.QB %s, %s, %s", rt, rs, sa); + return img_format("SHRL.QB %s, %s, %s", rt, rs, sa); } @@ -14487,7 +14472,7 @@ std::string NMD::SHRLV_PH(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SHRLV.PH %s, %s, %s", rd, rt, rs); + return img_format("SHRLV.PH %s, %s, %s", rd, rt, rs); } @@ -14511,7 +14496,7 @@ std::string NMD::SHRLV_QB(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SHRLV.QB %s, %s, %s", rd, rt, rs); + return img_format("SHRLV.QB %s, %s, %s", rd, rt, rs); } @@ -14535,7 +14520,7 @@ std::string NMD::SHX(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("SHX %s, %s(%s)", rd, rs, rt); + return img_format("SHX %s, %s(%s)", rd, rs, rt); } @@ -14559,7 +14544,7 @@ std::string NMD::SHXS(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("SHXS %s, %s(%s)", rd, rs, rt); + return img_format("SHXS %s, %s(%s)", rd, rs, rt); } @@ -14579,7 +14564,7 @@ std::string NMD::SIGRIE(uint64 instruction) std::string code = IMMEDIATE(copy(code_value)); - return img::format("SIGRIE %s", code); + return img_format("SIGRIE %s", code); } @@ -14603,7 +14588,7 @@ std::string NMD::SLL_16_(uint64 instruction) std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); std::string shift3 = IMMEDIATE(encode_shift3_from_shift(shift3_value)); - return img::format("SLL %s, %s, %s", rt3, rs3, shift3); + return img_format("SLL %s, %s, %s", rt3, rs3, shift3); } @@ -14627,7 +14612,7 @@ std::string NMD::SLL_32_(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string shift = IMMEDIATE(copy(shift_value)); - return img::format("SLL %s, %s, %s", rt, rs, shift); + return img_format("SLL %s, %s, %s", rt, rs, shift); } @@ -14651,7 +14636,7 @@ std::string NMD::SLLV(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("SLLV %s, %s, %s", rd, rs, rt); + return img_format("SLLV %s, %s, %s", rd, rs, rt); } @@ -14675,7 +14660,7 @@ std::string NMD::SLT(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("SLT %s, %s, %s", rd, rs, rt); + return img_format("SLT %s, %s, %s", rd, rs, rt); } @@ -14699,7 +14684,7 @@ std::string NMD::SLTI(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string u = IMMEDIATE(copy(u_value)); - return img::format("SLTI %s, %s, %s", rt, rs, u); + return img_format("SLTI %s, %s, %s", rt, rs, u); } @@ -14723,7 +14708,7 @@ std::string NMD::SLTIU(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string u = IMMEDIATE(copy(u_value)); - return img::format("SLTIU %s, %s, %s", rt, rs, u); + return img_format("SLTIU %s, %s, %s", rt, rs, u); } @@ -14747,7 +14732,7 @@ std::string NMD::SLTU(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("SLTU %s, %s, %s", rd, rs, rt); + return img_format("SLTU %s, %s, %s", rd, rs, rt); } @@ -14771,7 +14756,7 @@ std::string NMD::SOV(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("SOV %s, %s, %s", rd, rs, rt); + return img_format("SOV %s, %s, %s", rd, rs, rt); } @@ -14791,7 +14776,7 @@ std::string NMD::SPECIAL2(uint64 instruction) std::string op = IMMEDIATE(copy(op_value)); - return img::format("SPECIAL2 %s", op); + return img_format("SPECIAL2 %s", op); } @@ -14813,7 +14798,7 @@ std::string NMD::SQRT_D(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("SQRT.D %s, %s", ft, fs); + return img_format("SQRT.D %s, %s", ft, fs); } @@ -14835,7 +14820,7 @@ std::string NMD::SQRT_S(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("SQRT.S %s, %s", ft, fs); + return img_format("SQRT.S %s, %s", ft, fs); } @@ -14859,7 +14844,7 @@ std::string NMD::SRA(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string shift = IMMEDIATE(copy(shift_value)); - return img::format("SRA %s, %s, %s", rt, rs, shift); + return img_format("SRA %s, %s, %s", rt, rs, shift); } @@ -14883,7 +14868,7 @@ std::string NMD::SRAV(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("SRAV %s, %s, %s", rd, rs, rt); + return img_format("SRAV %s, %s, %s", rd, rs, rt); } @@ -14907,7 +14892,7 @@ std::string NMD::SRL_16_(uint64 instruction) std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); std::string shift3 = IMMEDIATE(encode_shift3_from_shift(shift3_value)); - return img::format("SRL %s, %s, %s", rt3, rs3, shift3); + return img_format("SRL %s, %s, %s", rt3, rs3, shift3); } @@ -14931,7 +14916,7 @@ std::string NMD::SRL_32_(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string shift = IMMEDIATE(copy(shift_value)); - return img::format("SRL %s, %s, %s", rt, rs, shift); + return img_format("SRL %s, %s, %s", rt, rs, shift); } @@ -14955,7 +14940,7 @@ std::string NMD::SRLV(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("SRLV %s, %s, %s", rd, rs, rt); + return img_format("SRLV %s, %s, %s", rd, rs, rt); } @@ -14979,7 +14964,7 @@ std::string NMD::SUB(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("SUB %s, %s, %s", rd, rs, rt); + return img_format("SUB %s, %s, %s", rd, rs, rt); } @@ -15003,7 +14988,7 @@ std::string NMD::SUB_D(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("SUB.D %s, %s, %s", fd, fs, ft); + return img_format("SUB.D %s, %s, %s", fd, fs, ft); } @@ -15027,7 +15012,7 @@ std::string NMD::SUB_S(uint64 instruction) std::string fs = FPR(copy(fs_value)); std::string ft = FPR(copy(ft_value)); - return img::format("SUB.S %s, %s, %s", fd, fs, ft); + return img_format("SUB.S %s, %s, %s", fd, fs, ft); } @@ -15051,7 +15036,7 @@ std::string NMD::SUBQ_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("SUBQ.PH %s, %s, %s", rd, rs, rt); + return img_format("SUBQ.PH %s, %s, %s", rd, rs, rt); } @@ -15076,7 +15061,7 @@ std::string NMD::SUBQ_S_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("SUBQ_S.PH %s, %s, %s", rd, rs, rt); + return img_format("SUBQ_S.PH %s, %s, %s", rd, rs, rt); } @@ -15101,7 +15086,7 @@ std::string NMD::SUBQ_S_W(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("SUBQ_S.W %s, %s, %s", rd, rs, rt); + return img_format("SUBQ_S.W %s, %s, %s", rd, rs, rt); } @@ -15126,7 +15111,7 @@ std::string NMD::SUBQH_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("SUBQH.PH %s, %s, %s", rd, rs, rt); + return img_format("SUBQH.PH %s, %s, %s", rd, rs, rt); } @@ -15151,7 +15136,7 @@ std::string NMD::SUBQH_R_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("SUBQH_R.PH %s, %s, %s", rd, rs, rt); + return img_format("SUBQH_R.PH %s, %s, %s", rd, rs, rt); } @@ -15176,7 +15161,7 @@ std::string NMD::SUBQH_R_W(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("SUBQH_R.W %s, %s, %s", rd, rs, rt); + return img_format("SUBQH_R.W %s, %s, %s", rd, rs, rt); } @@ -15201,7 +15186,7 @@ std::string NMD::SUBQH_W(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("SUBQH.W %s, %s, %s", rd, rs, rt); + return img_format("SUBQH.W %s, %s, %s", rd, rs, rt); } @@ -15225,7 +15210,7 @@ std::string NMD::SUBU_16_(uint64 instruction) std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - return img::format("SUBU %s, %s, %s", rd3, rs3, rt3); + return img_format("SUBU %s, %s, %s", rd3, rs3, rt3); } @@ -15249,7 +15234,7 @@ std::string NMD::SUBU_32_(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("SUBU %s, %s, %s", rd, rs, rt); + return img_format("SUBU %s, %s, %s", rd, rs, rt); } @@ -15273,7 +15258,7 @@ std::string NMD::SUBU_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("SUBU.PH %s, %s, %s", rd, rs, rt); + return img_format("SUBU.PH %s, %s, %s", rd, rs, rt); } @@ -15297,7 +15282,7 @@ std::string NMD::SUBU_QB(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("SUBU.QB %s, %s, %s", rd, rs, rt); + return img_format("SUBU.QB %s, %s, %s", rd, rs, rt); } @@ -15322,7 +15307,7 @@ std::string NMD::SUBU_S_PH(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("SUBU_S.PH %s, %s, %s", rd, rs, rt); + return img_format("SUBU_S.PH %s, %s, %s", rd, rs, rt); } @@ -15347,7 +15332,7 @@ std::string NMD::SUBU_S_QB(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("SUBU_S.QB %s, %s, %s", rd, rs, rt); + return img_format("SUBU_S.QB %s, %s, %s", rd, rs, rt); } @@ -15372,7 +15357,7 @@ std::string NMD::SUBUH_QB(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("SUBUH.QB %s, %s, %s", rd, rs, rt); + return img_format("SUBUH.QB %s, %s, %s", rd, rs, rt); } @@ -15397,7 +15382,7 @@ std::string NMD::SUBUH_R_QB(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("SUBUH_R.QB %s, %s, %s", rd, rs, rt); + return img_format("SUBUH_R.QB %s, %s, %s", rd, rs, rt); } @@ -15421,7 +15406,7 @@ std::string NMD::SW_16_(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); - return img::format("SW %s, %s(%s)", rtz3, u, rs3); + return img_format("SW %s, %s(%s)", rtz3, u, rs3); } @@ -15445,7 +15430,7 @@ std::string NMD::SW_4X4_(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string rs4 = GPR(decode_gpr_gpr4(rs4_value)); - return img::format("SW %s, %s(%s)", rtz4, u, rs4); + return img_format("SW %s, %s(%s)", rtz4, u, rs4); } @@ -15467,7 +15452,7 @@ std::string NMD::SW_GP16_(uint64 instruction) std::string rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value)); std::string u = IMMEDIATE(copy(u_value)); - return img::format("SW %s, %s($%d)", rtz3, u, 28); + return img_format("SW %s, %s($%d)", rtz3, u, 28); } @@ -15489,7 +15474,7 @@ std::string NMD::SW_GP_(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string u = IMMEDIATE(copy(u_value)); - return img::format("SW %s, %s($%d)", rt, u, 28); + return img_format("SW %s, %s($%d)", rt, u, 28); } @@ -15513,7 +15498,7 @@ std::string NMD::SW_S9_(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SW %s, %s(%s)", rt, s, rs); + return img_format("SW %s, %s(%s)", rt, s, rs); } @@ -15535,7 +15520,7 @@ std::string NMD::SW_SP_(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string u = IMMEDIATE(copy(u_value)); - return img::format("SW %s, %s($%d)", rt, u, 29); + return img_format("SW %s, %s($%d)", rt, u, 29); } @@ -15559,7 +15544,7 @@ std::string NMD::SW_U12_(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SW %s, %s(%s)", rt, u, rs); + return img_format("SW %s, %s(%s)", rt, u, rs); } @@ -15581,7 +15566,7 @@ std::string NMD::SWC1_GP_(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string u = IMMEDIATE(copy(u_value)); - return img::format("SWC1 %s, %s($%d)", ft, u, 28); + return img_format("SWC1 %s, %s($%d)", ft, u, 28); } @@ -15605,7 +15590,7 @@ std::string NMD::SWC1_S9_(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SWC1 %s, %s(%s)", ft, s, rs); + return img_format("SWC1 %s, %s(%s)", ft, s, rs); } @@ -15629,7 +15614,7 @@ std::string NMD::SWC1_U12_(uint64 instruction) std::string u = IMMEDIATE(copy(u_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SWC1 %s, %s(%s)", ft, u, rs); + return img_format("SWC1 %s, %s(%s)", ft, u, rs); } @@ -15653,7 +15638,7 @@ std::string NMD::SWC1X(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("SWC1X %s, %s(%s)", ft, rs, rt); + return img_format("SWC1X %s, %s(%s)", ft, rs, rt); } @@ -15677,7 +15662,7 @@ std::string NMD::SWC1XS(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("SWC1XS %s, %s(%s)", ft, rs, rt); + return img_format("SWC1XS %s, %s(%s)", ft, rs, rt); } @@ -15701,7 +15686,7 @@ std::string NMD::SWC2(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SWC2 %s, %s(%s)", cs, s, rs); + return img_format("SWC2 %s, %s(%s)", cs, s, rs); } @@ -15725,7 +15710,7 @@ std::string NMD::SWE(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SWE %s, %s(%s)", rt, s, rs); + return img_format("SWE %s, %s(%s)", rt, s, rs); } @@ -15751,7 +15736,7 @@ std::string NMD::SWM(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string count3 = IMMEDIATE(encode_count3_from_count(count3_value)); - return img::format("SWM %s, %s(%s), %s", rt, s, rs, count3); + return img_format("SWM %s, %s(%s), %s", rt, s, rs, count3); } @@ -15773,7 +15758,7 @@ std::string NMD::SWPC_48_(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string s = ADDRESS(encode_s_from_address(s_value), 6); - return img::format("SWPC %s, %s", rt, s); + return img_format("SWPC %s, %s", rt, s); } @@ -15797,7 +15782,7 @@ std::string NMD::SWX(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("SWX %s, %s(%s)", rd, rs, rt); + return img_format("SWX %s, %s(%s)", rd, rs, rt); } @@ -15821,7 +15806,7 @@ std::string NMD::SWXS(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("SWXS %s, %s(%s)", rd, rs, rt); + return img_format("SWXS %s, %s(%s)", rd, rs, rt); } @@ -15841,7 +15826,7 @@ std::string NMD::SYNC(uint64 instruction) std::string stype = IMMEDIATE(copy(stype_value)); - return img::format("SYNC %s", stype); + return img_format("SYNC %s", stype); } @@ -15863,7 +15848,7 @@ std::string NMD::SYNCI(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SYNCI %s(%s)", s, rs); + return img_format("SYNCI %s(%s)", s, rs); } @@ -15885,7 +15870,7 @@ std::string NMD::SYNCIE(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("SYNCIE %s(%s)", s, rs); + return img_format("SYNCIE %s(%s)", s, rs); } @@ -15905,7 +15890,7 @@ std::string NMD::SYSCALL_16_(uint64 instruction) std::string code = IMMEDIATE(copy(code_value)); - return img::format("SYSCALL %s", code); + return img_format("SYSCALL %s", code); } @@ -15923,7 +15908,7 @@ std::string NMD::SYSCALL_32_(uint64 instruction) std::string code = IMMEDIATE(copy(code_value)); - return img::format("SYSCALL %s", code); + return img_format("SYSCALL %s", code); } @@ -15945,7 +15930,7 @@ std::string NMD::TEQ(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("TEQ %s, %s", rs, rt); + return img_format("TEQ %s, %s", rs, rt); } @@ -16183,7 +16168,7 @@ std::string NMD::TNE(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("TNE %s, %s", rs, rt); + return img_format("TNE %s, %s", rs, rt); } @@ -16205,7 +16190,7 @@ std::string NMD::TRUNC_L_D(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("TRUNC.L.D %s, %s", ft, fs); + return img_format("TRUNC.L.D %s, %s", ft, fs); } @@ -16227,7 +16212,7 @@ std::string NMD::TRUNC_L_S(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("TRUNC.L.S %s, %s", ft, fs); + return img_format("TRUNC.L.S %s, %s", ft, fs); } @@ -16249,7 +16234,7 @@ std::string NMD::TRUNC_W_D(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("TRUNC.W.D %s, %s", ft, fs); + return img_format("TRUNC.W.D %s, %s", ft, fs); } @@ -16271,7 +16256,7 @@ std::string NMD::TRUNC_W_S(uint64 instruction) std::string ft = FPR(copy(ft_value)); std::string fs = FPR(copy(fs_value)); - return img::format("TRUNC.W.S %s, %s", ft, fs); + return img_format("TRUNC.W.S %s, %s", ft, fs); } @@ -16297,7 +16282,7 @@ std::string NMD::UALDM(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string count3 = IMMEDIATE(encode_count3_from_count(count3_value)); - return img::format("UALDM %s, %s(%s), %s", rt, s, rs, count3); + return img_format("UALDM %s, %s(%s), %s", rt, s, rs, count3); } @@ -16321,7 +16306,7 @@ std::string NMD::UALH(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("UALH %s, %s(%s)", rt, s, rs); + return img_format("UALH %s, %s(%s)", rt, s, rs); } @@ -16347,7 +16332,7 @@ std::string NMD::UALWM(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string count3 = IMMEDIATE(encode_count3_from_count(count3_value)); - return img::format("UALWM %s, %s(%s), %s", rt, s, rs, count3); + return img_format("UALWM %s, %s(%s), %s", rt, s, rs, count3); } @@ -16373,7 +16358,7 @@ std::string NMD::UASDM(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string count3 = IMMEDIATE(encode_count3_from_count(count3_value)); - return img::format("UASDM %s, %s(%s), %s", rt, s, rs, count3); + return img_format("UASDM %s, %s(%s), %s", rt, s, rs, count3); } @@ -16397,7 +16382,7 @@ std::string NMD::UASH(uint64 instruction) std::string s = IMMEDIATE(copy(s_value)); std::string rs = GPR(copy(rs_value)); - return img::format("UASH %s, %s(%s)", rt, s, rs); + return img_format("UASH %s, %s(%s)", rt, s, rs); } @@ -16423,7 +16408,7 @@ std::string NMD::UASWM(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string count3 = IMMEDIATE(encode_count3_from_count(count3_value)); - return img::format("UASWM %s, %s(%s), %s", rt, s, rs, count3); + return img_format("UASWM %s, %s(%s), %s", rt, s, rs, count3); } @@ -16443,7 +16428,7 @@ std::string NMD::UDI(uint64 instruction) std::string op = IMMEDIATE(copy(op_value)); - return img::format("UDI %s", op); + return img_format("UDI %s", op); } @@ -16461,7 +16446,7 @@ std::string NMD::WAIT(uint64 instruction) std::string code = IMMEDIATE(copy(code_value)); - return img::format("WAIT %s", code); + return img_format("WAIT %s", code); } @@ -16483,7 +16468,7 @@ std::string NMD::WRDSP(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string mask = IMMEDIATE(copy(mask_value)); - return img::format("WRDSP %s, %s", rt, mask); + return img_format("WRDSP %s, %s", rt, mask); } @@ -16505,7 +16490,7 @@ std::string NMD::WRPGPR(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("WRPGPR %s, %s", rt, rs); + return img_format("WRPGPR %s, %s", rt, rs); } @@ -16527,7 +16512,7 @@ std::string NMD::XOR_16_(uint64 instruction) std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - return img::format("XOR %s, %s", rs3, rt3); + return img_format("XOR %s, %s", rs3, rt3); } @@ -16551,7 +16536,7 @@ std::string NMD::XOR_32_(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - return img::format("XOR %s, %s, %s", rd, rs, rt); + return img_format("XOR %s, %s, %s", rd, rs, rt); } @@ -16575,7 +16560,7 @@ std::string NMD::XORI(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string u = IMMEDIATE(copy(u_value)); - return img::format("XORI %s, %s, %s", rt, rs, u); + return img_format("XORI %s, %s, %s", rt, rs, u); } @@ -16596,7 +16581,7 @@ std::string NMD::YIELD(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string rs = GPR(copy(rs_value)); - return img::format("YIELD %s, %s", rt, rs); + return img_format("YIELD %s, %s", rt, rs); } diff --git a/disas/nanomips.h b/disas/nanomips.h index a0a2225301..9fe0cc67da 100644 --- a/disas/nanomips.h +++ b/disas/nanomips.h @@ -29,11 +29,7 @@ typedef int64_t int64; typedef uint64_t uint64; typedef uint32_t uint32; typedef uint16_t uint16; - -namespace img -{ - typedef uint64_t address; -} +typedef uint64_t img_address; class NMD @@ -70,7 +66,7 @@ public: }; - NMD(img::address pc, TABLE_ATTRIBUTE_TYPE requested_instruction_categories) + NMD(img_address pc, TABLE_ATTRIBUTE_TYPE requested_instruction_categories) : m_pc(pc) , m_requested_instruction_categories(requested_instruction_categories) { @@ -81,7 +77,7 @@ public: private: - img::address m_pc; + img_address m_pc; TABLE_ATTRIBUTE_TYPE m_requested_instruction_categories; typedef std::string(NMD:: *disassembly_function)(uint64 instruction); From bfffba15b24582a78f956d17f155c2f18aaf001c Mon Sep 17 00:00:00 2001 From: Milica Lazarevic Date: Mon, 12 Sep 2022 14:26:13 +0200 Subject: [PATCH 423/705] disas/nanomips: Extract enums out of the NMD class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Definitions of enums TABLE_ENTRY_TYPE and TABLE_ATTRIBUTE_TYPE are moved out of the NMD class. The main goal is to remove NMD class completely. Signed-off-by: Milica Lazarevic Reviewed-by: Thomas Huth Reviewed-by: Richard Henderson Message-Id: <20220912122635.74032-3-milica.lazarevic@syrmia.com> Signed-off-by: Philippe Mathieu-Daudé --- disas/nanomips.cpp | 8 +++---- disas/nanomips.h | 59 +++++++++++++++++++++++----------------------- 2 files changed, 33 insertions(+), 34 deletions(-) diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp index 84529685bf..bdc640b38b 100644 --- a/disas/nanomips.cpp +++ b/disas/nanomips.cpp @@ -50,8 +50,8 @@ int nanomips_dis(char *buf, std::string disasm; uint16 bits[3] = {one, two, three}; - NMD::TABLE_ENTRY_TYPE type; - NMD d(address, NMD::ALL_ATTRIBUTES); + TABLE_ENTRY_TYPE type; + NMD d(address, ALL_ATTRIBUTES); int size = d.Disassemble(bits, disasm, type); strcpy(buf, disasm.c_str()); @@ -772,7 +772,7 @@ uint64 NMD::extract_op_code_value(const uint16 * data, int size) int NMD::Disassemble(const uint16 * data, std::string & dis, - NMD::TABLE_ENTRY_TYPE & type) + TABLE_ENTRY_TYPE & type) { return Disassemble(data, dis, type, MAJOR, 2); } @@ -790,7 +790,7 @@ int NMD::Disassemble(const uint16 * data, std::string & dis, * disassembly string - on error will constain error string */ int NMD::Disassemble(const uint16 * data, std::string & dis, - NMD::TABLE_ENTRY_TYPE & type, const Pool *table, + TABLE_ENTRY_TYPE & type, const Pool *table, int table_size) { try diff --git a/disas/nanomips.h b/disas/nanomips.h index 9fe0cc67da..f65a0957b8 100644 --- a/disas/nanomips.h +++ b/disas/nanomips.h @@ -31,41 +31,40 @@ typedef uint32_t uint32; typedef uint16_t uint16; typedef uint64_t img_address; +enum TABLE_ENTRY_TYPE { + instruction, + call_instruction, + branch_instruction, + return_instruction, + reserved_block, + pool, +}; + +enum TABLE_ATTRIBUTE_TYPE { + MIPS64_ = 0x00000001, + XNP_ = 0x00000002, + XMMS_ = 0x00000004, + EVA_ = 0x00000008, + DSP_ = 0x00000010, + MT_ = 0x00000020, + EJTAG_ = 0x00000040, + TLBINV_ = 0x00000080, + CP0_ = 0x00000100, + CP1_ = 0x00000200, + CP2_ = 0x00000400, + UDI_ = 0x00000800, + MCU_ = 0x00001000, + VZ_ = 0x00002000, + TLB_ = 0x00004000, + MVH_ = 0x00008000, + ALL_ATTRIBUTES = 0xffffffffull, +}; + class NMD { public: - enum TABLE_ENTRY_TYPE { - instruction, - call_instruction, - branch_instruction, - return_instruction, - reserved_block, - pool, - }; - - enum TABLE_ATTRIBUTE_TYPE { - MIPS64_ = 0x00000001, - XNP_ = 0x00000002, - XMMS_ = 0x00000004, - EVA_ = 0x00000008, - DSP_ = 0x00000010, - MT_ = 0x00000020, - EJTAG_ = 0x00000040, - TLBINV_ = 0x00000080, - CP0_ = 0x00000100, - CP1_ = 0x00000200, - CP2_ = 0x00000400, - UDI_ = 0x00000800, - MCU_ = 0x00001000, - VZ_ = 0x00002000, - TLB_ = 0x00004000, - MVH_ = 0x00008000, - ALL_ATTRIBUTES = 0xffffffffull, - }; - - NMD(img_address pc, TABLE_ATTRIBUTE_TYPE requested_instruction_categories) : m_pc(pc) , m_requested_instruction_categories(requested_instruction_categories) From 0c2a3b43a1d818b31e2fce81db2085ffeb9a4400 Mon Sep 17 00:00:00 2001 From: Milica Lazarevic Date: Mon, 12 Sep 2022 14:26:14 +0200 Subject: [PATCH 424/705] disas/nanomips: Delete NMD class field MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The m_requested_instruction_categories field always has the same value, ALL_ATTRIBUTES. The only use of that field is within the if statement. When replaced with a specific value, the if statement is always false, so it has been removed. Now, when the only use of the m_requested_instruction_categories field is removed, we can delete the field declaration and initialization in the NMD class. Also, we're changing the way of the construction of the NMD object in the nanomips_dis function. Signed-off-by: Milica Lazarevic Reviewed-by: Richard Henderson Message-Id: <20220912122635.74032-4-milica.lazarevic@syrmia.com> Signed-off-by: Philippe Mathieu-Daudé --- disas/nanomips.cpp | 13 +------------ disas/nanomips.h | 4 +--- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp index bdc640b38b..721ca3f52b 100644 --- a/disas/nanomips.cpp +++ b/disas/nanomips.cpp @@ -51,7 +51,7 @@ int nanomips_dis(char *buf, uint16 bits[3] = {one, two, three}; TABLE_ENTRY_TYPE type; - NMD d(address, ALL_ATTRIBUTES); + NMD d(address); int size = d.Disassemble(bits, disasm, type); strcpy(buf, disasm.c_str()); @@ -812,17 +812,6 @@ int NMD::Disassemble(const uint16 * data, std::string & dis, (table[i].type == call_instruction) || (table[i].type == branch_instruction) || (table[i].type == return_instruction)) { - if ((table[i].attributes != 0) && - (m_requested_instruction_categories & - table[i].attributes) == 0) { - /* - * failed due to instruction having - * an ASE attribute and the requested version - * not having that attribute - */ - dis = "ASE attribute mismatch"; - return -5; - } disassembly_function dis_fn = table[i].disassembly; if (dis_fn == 0) { dis = "disassembler failure - bad table entry"; diff --git a/disas/nanomips.h b/disas/nanomips.h index f65a0957b8..5bdfe1e30b 100644 --- a/disas/nanomips.h +++ b/disas/nanomips.h @@ -65,9 +65,8 @@ class NMD { public: - NMD(img_address pc, TABLE_ATTRIBUTE_TYPE requested_instruction_categories) + NMD(img_address pc) : m_pc(pc) - , m_requested_instruction_categories(requested_instruction_categories) { } @@ -77,7 +76,6 @@ public: private: img_address m_pc; - TABLE_ATTRIBUTE_TYPE m_requested_instruction_categories; typedef std::string(NMD:: *disassembly_function)(uint64 instruction); typedef bool(NMD:: *conditional_function)(uint64 instruction); From 9972c8fa7c5126311417b1d3cf355d28a6955d3d Mon Sep 17 00:00:00 2001 From: Milica Lazarevic Date: Mon, 12 Sep 2022 14:26:15 +0200 Subject: [PATCH 425/705] disas/nanomips: Delete NMD class second field MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We're deleting the m_pc field of the NMD class. It's now part of the Dis_info struct that this patch introduces. Currently, the Dis_info struct has just one field, m_pc, which we need for address calculation in the ADDRESS function. We're filling Dis_info at the entrance of the nanoMIPS disassembler. I.e. print_insn_nanomips. Next, we're adding that information as an argument wherever we need to. Since NMD class now has no more fields, the NMD constructor is also deleted. Signed-off-by: Milica Lazarevic Reviewed-by: Richard Henderson Message-Id: <20220912122635.74032-5-milica.lazarevic@syrmia.com> Signed-off-by: Philippe Mathieu-Daudé --- disas/nanomips.cpp | 1368 ++++++++++++++++++++++---------------------- disas/nanomips.h | 1292 +++++++++++++++++++++-------------------- 2 files changed, 1331 insertions(+), 1329 deletions(-) diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp index 721ca3f52b..9005f26ee3 100644 --- a/disas/nanomips.cpp +++ b/disas/nanomips.cpp @@ -42,7 +42,7 @@ int nanomips_dis(char *buf, - unsigned address, + Dis_info *info, unsigned short one, unsigned short two, unsigned short three) @@ -51,8 +51,8 @@ int nanomips_dis(char *buf, uint16 bits[3] = {one, two, three}; TABLE_ENTRY_TYPE type; - NMD d(address); - int size = d.Disassemble(bits, disasm, type); + NMD d; + int size = d.Disassemble(bits, disasm, type, info); strcpy(buf, disasm.c_str()); return size; @@ -74,6 +74,9 @@ int print_insn_nanomips(bfd_vma memaddr, struct disassemble_info *info) info->target = 0; info->target2 = 0; + Dis_info disassm_info; + disassm_info.m_pc = memaddr; + status = (*info->read_memory_func)(memaddr, buffer, 2, info); if (status != 0) { (*info->memory_error_func)(status, memaddr, info); @@ -122,7 +125,7 @@ int print_insn_nanomips(bfd_vma memaddr, struct disassemble_info *info) (*info->fprintf_func)(info->stream, " "); } - int length = nanomips_dis(buf, memaddr, insn1, insn2, insn3); + int length = nanomips_dis(buf, &disassm_info, insn1, insn2, insn3); /* FIXME: Should probably use a hash table on the major opcode here. */ @@ -747,10 +750,10 @@ std::string NMD::CPR(uint64 reg) } -std::string NMD::ADDRESS(uint64 value, int instruction_size) +std::string NMD::ADDRESS(uint64 value, int instruction_size, Dis_info *info) { /* token for string replace */ - img_address address = m_pc + value + instruction_size; + img_address address = info->m_pc + value + instruction_size; /* symbol replacement */ return to_string(address); } @@ -772,9 +775,9 @@ uint64 NMD::extract_op_code_value(const uint16 * data, int size) int NMD::Disassemble(const uint16 * data, std::string & dis, - TABLE_ENTRY_TYPE & type) + TABLE_ENTRY_TYPE & type, Dis_info *info) { - return Disassemble(data, dis, type, MAJOR, 2); + return Disassemble(data, dis, type, MAJOR, 2, info); } @@ -791,7 +794,7 @@ int NMD::Disassemble(const uint16 * data, std::string & dis, */ int NMD::Disassemble(const uint16 * data, std::string & dis, TABLE_ENTRY_TYPE & type, const Pool *table, - int table_size) + int table_size, Dis_info *info) { try { @@ -807,7 +810,8 @@ int NMD::Disassemble(const uint16 * data, std::string & dis, if (table[i].type == pool) { return Disassemble(data, dis, type, table[i].next_table, - table[i].next_table_size); + table[i].next_table_size, + info); } else if ((table[i].type == instruction) || (table[i].type == call_instruction) || (table[i].type == branch_instruction) || @@ -818,7 +822,7 @@ int NMD::Disassemble(const uint16 * data, std::string & dis, return -6; } type = table[i].type; - dis = (this->*dis_fn)(op_code); + dis = (this->*dis_fn)(op_code, info); return table[i].instructions_size; } else { dis = "reserved instruction"; @@ -1773,7 +1777,7 @@ bool NMD::SLTU_cond(uint64 instruction) * fs ----- * fd ----- */ -std::string NMD::ABS_D(uint64 instruction) +std::string NMD::ABS_D(uint64 instruction, Dis_info *info) { uint64 fd_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -1795,7 +1799,7 @@ std::string NMD::ABS_D(uint64 instruction) * fd ----- * fs ----- */ -std::string NMD::ABS_S(uint64 instruction) +std::string NMD::ABS_S(uint64 instruction, Dis_info *info) { uint64 fd_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -1817,7 +1821,7 @@ std::string NMD::ABS_S(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::ABSQ_S_PH(uint64 instruction) +std::string NMD::ABSQ_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -1839,7 +1843,7 @@ std::string NMD::ABSQ_S_PH(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::ABSQ_S_QB(uint64 instruction) +std::string NMD::ABSQ_S_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -1861,7 +1865,7 @@ std::string NMD::ABSQ_S_QB(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::ABSQ_S_W(uint64 instruction) +std::string NMD::ABSQ_S_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -1882,7 +1886,7 @@ std::string NMD::ABSQ_S_W(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::ACLR(uint64 instruction) +std::string NMD::ACLR(uint64 instruction, Dis_info *info) { uint64 bit_value = extract_bit_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -1905,7 +1909,7 @@ std::string NMD::ACLR(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::ADD(uint64 instruction) +std::string NMD::ADD(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -1930,7 +1934,7 @@ std::string NMD::ADD(uint64 instruction) * fs ----- * fd ----- */ -std::string NMD::ADD_D(uint64 instruction) +std::string NMD::ADD_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -1955,7 +1959,7 @@ std::string NMD::ADD_D(uint64 instruction) * fs ----- * fd ----- */ -std::string NMD::ADD_S(uint64 instruction) +std::string NMD::ADD_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -1978,7 +1982,7 @@ std::string NMD::ADD_S(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::ADDIU_32_(uint64 instruction) +std::string NMD::ADDIU_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2001,7 +2005,7 @@ std::string NMD::ADDIU_32_(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::ADDIU_48_(uint64 instruction) +std::string NMD::ADDIU_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); @@ -2022,7 +2026,7 @@ std::string NMD::ADDIU_48_(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::ADDIU_GP48_(uint64 instruction) +std::string NMD::ADDIU_GP48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); @@ -2043,7 +2047,7 @@ std::string NMD::ADDIU_GP48_(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::ADDIU_GP_B_(uint64 instruction) +std::string NMD::ADDIU_GP_B_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_0(instruction); @@ -2064,7 +2068,7 @@ std::string NMD::ADDIU_GP_B_(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::ADDIU_GP_W_(uint64 instruction) +std::string NMD::ADDIU_GP_W_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_to_2__s2(instruction); @@ -2085,7 +2089,7 @@ std::string NMD::ADDIU_GP_W_(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::ADDIU_NEG_(uint64 instruction) +std::string NMD::ADDIU_NEG_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2108,7 +2112,7 @@ std::string NMD::ADDIU_NEG_(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::ADDIU_R1_SP_(uint64 instruction) +std::string NMD::ADDIU_R1_SP_(uint64 instruction, Dis_info *info) { uint64 u_value = extract_u_5_4_3_2_1_0__s2(instruction); uint64 rt3_value = extract_rt3_9_8_7(instruction); @@ -2129,7 +2133,7 @@ std::string NMD::ADDIU_R1_SP_(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::ADDIU_R2_(uint64 instruction) +std::string NMD::ADDIU_R2_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -2151,7 +2155,7 @@ std::string NMD::ADDIU_R2_(uint64 instruction) * rt ----- * s - --- */ -std::string NMD::ADDIU_RS5_(uint64 instruction) +std::string NMD::ADDIU_RS5_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_9_8_7_6_5(instruction); int64 s_value = extract_s__se3_4_2_1_0(instruction); @@ -2173,13 +2177,13 @@ std::string NMD::ADDIU_RS5_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDIUPC_32_(uint64 instruction) +std::string NMD::ADDIUPC_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); int64 s_value = extract_s__se21_0_20_to_1_s1(instruction); std::string rt = GPR(copy(rt_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); return img_format("ADDIUPC %s, %s", rt, s); } @@ -2195,13 +2199,13 @@ std::string NMD::ADDIUPC_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDIUPC_48_(uint64 instruction) +std::string NMD::ADDIUPC_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); std::string rt = GPR(copy(rt_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 6); + std::string s = ADDRESS(encode_s_from_address(s_value), 6, info); return img_format("ADDIUPC %s, %s", rt, s); } @@ -2217,7 +2221,7 @@ std::string NMD::ADDIUPC_48_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDQ_PH(uint64 instruction) +std::string NMD::ADDQ_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2242,7 +2246,7 @@ std::string NMD::ADDQ_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDQ_S_PH(uint64 instruction) +std::string NMD::ADDQ_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2266,7 +2270,7 @@ std::string NMD::ADDQ_S_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDQ_S_W(uint64 instruction) +std::string NMD::ADDQ_S_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2291,7 +2295,7 @@ std::string NMD::ADDQ_S_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDQH_PH(uint64 instruction) +std::string NMD::ADDQH_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2316,7 +2320,7 @@ std::string NMD::ADDQH_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDQH_R_PH(uint64 instruction) +std::string NMD::ADDQH_R_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2341,7 +2345,7 @@ std::string NMD::ADDQH_R_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDQH_R_W(uint64 instruction) +std::string NMD::ADDQH_R_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2366,7 +2370,7 @@ std::string NMD::ADDQH_R_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDQH_W(uint64 instruction) +std::string NMD::ADDQH_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2390,7 +2394,7 @@ std::string NMD::ADDQH_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDSC(uint64 instruction) +std::string NMD::ADDSC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2413,7 +2417,7 @@ std::string NMD::ADDSC(uint64 instruction) * rs3 --- * rd3 --- */ -std::string NMD::ADDU_16_(uint64 instruction) +std::string NMD::ADDU_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -2437,7 +2441,7 @@ std::string NMD::ADDU_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDU_32_(uint64 instruction) +std::string NMD::ADDU_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2461,7 +2465,7 @@ std::string NMD::ADDU_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDU_4X4_(uint64 instruction) +std::string NMD::ADDU_4X4_(uint64 instruction, Dis_info *info) { uint64 rt4_value = extract_rt4_9_7_6_5(instruction); uint64 rs4_value = extract_rs4_4_2_1_0(instruction); @@ -2483,7 +2487,7 @@ std::string NMD::ADDU_4X4_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDU_PH(uint64 instruction) +std::string NMD::ADDU_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2507,7 +2511,7 @@ std::string NMD::ADDU_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDU_QB(uint64 instruction) +std::string NMD::ADDU_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2532,7 +2536,7 @@ std::string NMD::ADDU_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDU_S_PH(uint64 instruction) +std::string NMD::ADDU_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2556,7 +2560,7 @@ std::string NMD::ADDU_S_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDU_S_QB(uint64 instruction) +std::string NMD::ADDU_S_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2581,7 +2585,7 @@ std::string NMD::ADDU_S_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDUH_QB(uint64 instruction) +std::string NMD::ADDUH_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2606,7 +2610,7 @@ std::string NMD::ADDUH_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDUH_R_QB(uint64 instruction) +std::string NMD::ADDUH_R_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2629,7 +2633,7 @@ std::string NMD::ADDUH_R_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDWC(uint64 instruction) +std::string NMD::ADDWC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2653,13 +2657,13 @@ std::string NMD::ADDWC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ALUIPC(uint64 instruction) +std::string NMD::ALUIPC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); int64 s_value = extract_s__se31_0_11_to_2_20_to_12_s12(instruction); std::string rt = GPR(copy(rt_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); return img_format("ALUIPC %s, %%pcrel_hi(%s)", rt, s); } @@ -2674,7 +2678,7 @@ std::string NMD::ALUIPC(uint64 instruction) * rs3 --- * eu ---- */ -std::string NMD::AND_16_(uint64 instruction) +std::string NMD::AND_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -2696,7 +2700,7 @@ std::string NMD::AND_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::AND_32_(uint64 instruction) +std::string NMD::AND_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2719,7 +2723,7 @@ std::string NMD::AND_32_(uint64 instruction) * rs3 --- * eu ---- */ -std::string NMD::ANDI_16_(uint64 instruction) +std::string NMD::ANDI_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -2743,7 +2747,7 @@ std::string NMD::ANDI_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ANDI_32_(uint64 instruction) +std::string NMD::ANDI_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2767,7 +2771,7 @@ std::string NMD::ANDI_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::APPEND(uint64 instruction) +std::string NMD::APPEND(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2791,7 +2795,7 @@ std::string NMD::APPEND(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ASET(uint64 instruction) +std::string NMD::ASET(uint64 instruction, Dis_info *info) { uint64 bit_value = extract_bit_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2815,11 +2819,11 @@ std::string NMD::ASET(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BALC_16_(uint64 instruction) +std::string NMD::BALC_16_(uint64 instruction, Dis_info *info) { int64 s_value = extract_s__se10_0_9_8_7_6_5_4_3_2_1_s1(instruction); - std::string s = ADDRESS(encode_s_from_address(s_value), 2); + std::string s = ADDRESS(encode_s_from_address(s_value), 2, info); return img_format("BALC %s", s); } @@ -2835,11 +2839,11 @@ std::string NMD::BALC_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BALC_32_(uint64 instruction) +std::string NMD::BALC_32_(uint64 instruction, Dis_info *info) { int64 s_value = extract_s__se25_0_24_to_1_s1(instruction); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); return img_format("BALC %s", s); } @@ -2855,7 +2859,7 @@ std::string NMD::BALC_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BALRSC(uint64 instruction) +std::string NMD::BALRSC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2877,7 +2881,7 @@ std::string NMD::BALRSC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BBEQZC(uint64 instruction) +std::string NMD::BBEQZC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 bit_value = extract_bit_16_15_14_13_12_11(instruction); @@ -2885,7 +2889,7 @@ std::string NMD::BBEQZC(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string bit = IMMEDIATE(copy(bit_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); return img_format("BBEQZC %s, %s, %s", rt, bit, s); } @@ -2901,7 +2905,7 @@ std::string NMD::BBEQZC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BBNEZC(uint64 instruction) +std::string NMD::BBNEZC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 bit_value = extract_bit_16_15_14_13_12_11(instruction); @@ -2909,7 +2913,7 @@ std::string NMD::BBNEZC(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string bit = IMMEDIATE(copy(bit_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); return img_format("BBNEZC %s, %s, %s", rt, bit, s); } @@ -2925,11 +2929,11 @@ std::string NMD::BBNEZC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BC_16_(uint64 instruction) +std::string NMD::BC_16_(uint64 instruction, Dis_info *info) { int64 s_value = extract_s__se10_0_9_8_7_6_5_4_3_2_1_s1(instruction); - std::string s = ADDRESS(encode_s_from_address(s_value), 2); + std::string s = ADDRESS(encode_s_from_address(s_value), 2, info); return img_format("BC %s", s); } @@ -2945,11 +2949,11 @@ std::string NMD::BC_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BC_32_(uint64 instruction) +std::string NMD::BC_32_(uint64 instruction, Dis_info *info) { int64 s_value = extract_s__se25_0_24_to_1_s1(instruction); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); return img_format("BC %s", s); } @@ -2965,13 +2969,13 @@ std::string NMD::BC_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BC1EQZC(uint64 instruction) +std::string NMD::BC1EQZC(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); std::string ft = FPR(copy(ft_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); return img_format("BC1EQZC %s, %s", ft, s); } @@ -2987,13 +2991,13 @@ std::string NMD::BC1EQZC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BC1NEZC(uint64 instruction) +std::string NMD::BC1NEZC(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); std::string ft = FPR(copy(ft_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); return img_format("BC1NEZC %s, %s", ft, s); } @@ -3009,13 +3013,13 @@ std::string NMD::BC1NEZC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BC2EQZC(uint64 instruction) +std::string NMD::BC2EQZC(uint64 instruction, Dis_info *info) { uint64 ct_value = extract_ct_25_24_23_22_21(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); std::string ct = CPR(copy(ct_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); return img_format("BC2EQZC %s, %s", ct, s); } @@ -3031,13 +3035,13 @@ std::string NMD::BC2EQZC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BC2NEZC(uint64 instruction) +std::string NMD::BC2NEZC(uint64 instruction, Dis_info *info) { uint64 ct_value = extract_ct_25_24_23_22_21(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); std::string ct = CPR(copy(ct_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); return img_format("BC2NEZC %s, %s", ct, s); } @@ -3053,7 +3057,7 @@ std::string NMD::BC2NEZC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BEQC_16_(uint64 instruction) +std::string NMD::BEQC_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -3061,7 +3065,7 @@ std::string NMD::BEQC_16_(uint64 instruction) std::string rs3 = GPR(encode_rs3_and_check_rs3_lt_rt3(rs3_value)); std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string u = ADDRESS(encode_u_from_address(u_value), 2); + std::string u = ADDRESS(encode_u_from_address(u_value), 2, info); return img_format("BEQC %s, %s, %s", rs3, rt3, u); } @@ -3077,7 +3081,7 @@ std::string NMD::BEQC_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BEQC_32_(uint64 instruction) +std::string NMD::BEQC_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -3085,7 +3089,7 @@ std::string NMD::BEQC_32_(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); return img_format("BEQC %s, %s, %s", rs, rt, s); } @@ -3101,7 +3105,7 @@ std::string NMD::BEQC_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BEQIC(uint64 instruction) +std::string NMD::BEQIC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); @@ -3109,7 +3113,7 @@ std::string NMD::BEQIC(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string u = IMMEDIATE(copy(u_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); return img_format("BEQIC %s, %s, %s", rt, u, s); } @@ -3125,13 +3129,13 @@ std::string NMD::BEQIC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BEQZC_16_(uint64 instruction) +std::string NMD::BEQZC_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); int64 s_value = extract_s__se7_0_6_5_4_3_2_1_s1(instruction); std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 2); + std::string s = ADDRESS(encode_s_from_address(s_value), 2, info); return img_format("BEQZC %s, %s", rt3, s); } @@ -3147,7 +3151,7 @@ std::string NMD::BEQZC_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BGEC(uint64 instruction) +std::string NMD::BGEC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -3155,7 +3159,7 @@ std::string NMD::BGEC(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); return img_format("BGEC %s, %s, %s", rs, rt, s); } @@ -3171,7 +3175,7 @@ std::string NMD::BGEC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BGEIC(uint64 instruction) +std::string NMD::BGEIC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); @@ -3179,7 +3183,7 @@ std::string NMD::BGEIC(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string u = IMMEDIATE(copy(u_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); return img_format("BGEIC %s, %s, %s", rt, u, s); } @@ -3195,7 +3199,7 @@ std::string NMD::BGEIC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BGEIUC(uint64 instruction) +std::string NMD::BGEIUC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); @@ -3203,7 +3207,7 @@ std::string NMD::BGEIUC(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string u = IMMEDIATE(copy(u_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); return img_format("BGEIUC %s, %s, %s", rt, u, s); } @@ -3219,7 +3223,7 @@ std::string NMD::BGEIUC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BGEUC(uint64 instruction) +std::string NMD::BGEUC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -3227,7 +3231,7 @@ std::string NMD::BGEUC(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); return img_format("BGEUC %s, %s, %s", rs, rt, s); } @@ -3243,7 +3247,7 @@ std::string NMD::BGEUC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BLTC(uint64 instruction) +std::string NMD::BLTC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -3251,7 +3255,7 @@ std::string NMD::BLTC(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); return img_format("BLTC %s, %s, %s", rs, rt, s); } @@ -3267,7 +3271,7 @@ std::string NMD::BLTC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BLTIC(uint64 instruction) +std::string NMD::BLTIC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); @@ -3275,7 +3279,7 @@ std::string NMD::BLTIC(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string u = IMMEDIATE(copy(u_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); return img_format("BLTIC %s, %s, %s", rt, u, s); } @@ -3291,7 +3295,7 @@ std::string NMD::BLTIC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BLTIUC(uint64 instruction) +std::string NMD::BLTIUC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); @@ -3299,7 +3303,7 @@ std::string NMD::BLTIUC(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string u = IMMEDIATE(copy(u_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); return img_format("BLTIUC %s, %s, %s", rt, u, s); } @@ -3315,7 +3319,7 @@ std::string NMD::BLTIUC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BLTUC(uint64 instruction) +std::string NMD::BLTUC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -3323,7 +3327,7 @@ std::string NMD::BLTUC(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); return img_format("BLTUC %s, %s, %s", rs, rt, s); } @@ -3339,7 +3343,7 @@ std::string NMD::BLTUC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BNEC_16_(uint64 instruction) +std::string NMD::BNEC_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -3347,7 +3351,7 @@ std::string NMD::BNEC_16_(uint64 instruction) std::string rs3 = GPR(encode_rs3_and_check_rs3_ge_rt3(rs3_value)); std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string u = ADDRESS(encode_u_from_address(u_value), 2); + std::string u = ADDRESS(encode_u_from_address(u_value), 2, info); return img_format("BNEC %s, %s, %s", rs3, rt3, u); } @@ -3363,7 +3367,7 @@ std::string NMD::BNEC_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BNEC_32_(uint64 instruction) +std::string NMD::BNEC_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -3371,7 +3375,7 @@ std::string NMD::BNEC_32_(uint64 instruction) std::string rs = GPR(copy(rs_value)); std::string rt = GPR(copy(rt_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); return img_format("BNEC %s, %s, %s", rs, rt, s); } @@ -3387,7 +3391,7 @@ std::string NMD::BNEC_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BNEIC(uint64 instruction) +std::string NMD::BNEIC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); @@ -3395,7 +3399,7 @@ std::string NMD::BNEIC(uint64 instruction) std::string rt = GPR(copy(rt_value)); std::string u = IMMEDIATE(copy(u_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); return img_format("BNEIC %s, %s, %s", rt, u, s); } @@ -3411,13 +3415,13 @@ std::string NMD::BNEIC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BNEZC_16_(uint64 instruction) +std::string NMD::BNEZC_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); int64 s_value = extract_s__se7_0_6_5_4_3_2_1_s1(instruction); std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 2); + std::string s = ADDRESS(encode_s_from_address(s_value), 2, info); return img_format("BNEZC %s, %s", rt3, s); } @@ -3433,11 +3437,11 @@ std::string NMD::BNEZC_16_(uint64 instruction) * s[13:1] ------------- * s[14] - */ -std::string NMD::BPOSGE32C(uint64 instruction) +std::string NMD::BPOSGE32C(uint64 instruction, Dis_info *info) { int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); return img_format("BPOSGE32C %s", s); } @@ -3453,7 +3457,7 @@ std::string NMD::BPOSGE32C(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BREAK_16_(uint64 instruction) +std::string NMD::BREAK_16_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_2_1_0(instruction); @@ -3473,7 +3477,7 @@ std::string NMD::BREAK_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BREAK_32_(uint64 instruction) +std::string NMD::BREAK_32_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_18_to_0(instruction); @@ -3493,7 +3497,7 @@ std::string NMD::BREAK_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BRSC(uint64 instruction) +std::string NMD::BRSC(uint64 instruction, Dis_info *info) { uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -3513,7 +3517,7 @@ std::string NMD::BRSC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CACHE(uint64 instruction) +std::string NMD::CACHE(uint64 instruction, Dis_info *info) { uint64 op_value = extract_op_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -3537,7 +3541,7 @@ std::string NMD::CACHE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CACHEE(uint64 instruction) +std::string NMD::CACHEE(uint64 instruction, Dis_info *info) { uint64 op_value = extract_op_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -3561,7 +3565,7 @@ std::string NMD::CACHEE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CEIL_L_D(uint64 instruction) +std::string NMD::CEIL_L_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -3583,7 +3587,7 @@ std::string NMD::CEIL_L_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CEIL_L_S(uint64 instruction) +std::string NMD::CEIL_L_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -3605,7 +3609,7 @@ std::string NMD::CEIL_L_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CEIL_W_D(uint64 instruction) +std::string NMD::CEIL_W_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -3627,7 +3631,7 @@ std::string NMD::CEIL_W_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CEIL_W_S(uint64 instruction) +std::string NMD::CEIL_W_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -3649,7 +3653,7 @@ std::string NMD::CEIL_W_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CFC1(uint64 instruction) +std::string NMD::CFC1(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); @@ -3671,7 +3675,7 @@ std::string NMD::CFC1(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CFC2(uint64 instruction) +std::string NMD::CFC2(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); @@ -3693,7 +3697,7 @@ std::string NMD::CFC2(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CLASS_D(uint64 instruction) +std::string NMD::CLASS_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -3715,7 +3719,7 @@ std::string NMD::CLASS_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CLASS_S(uint64 instruction) +std::string NMD::CLASS_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -3737,7 +3741,7 @@ std::string NMD::CLASS_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CLO(uint64 instruction) +std::string NMD::CLO(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -3759,7 +3763,7 @@ std::string NMD::CLO(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CLZ(uint64 instruction) +std::string NMD::CLZ(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -3781,7 +3785,7 @@ std::string NMD::CLZ(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_AF_D(uint64 instruction) +std::string NMD::CMP_AF_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -3805,7 +3809,7 @@ std::string NMD::CMP_AF_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_AF_S(uint64 instruction) +std::string NMD::CMP_AF_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -3829,7 +3833,7 @@ std::string NMD::CMP_AF_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_EQ_D(uint64 instruction) +std::string NMD::CMP_EQ_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -3852,7 +3856,7 @@ std::string NMD::CMP_EQ_D(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::CMP_EQ_PH(uint64 instruction) +std::string NMD::CMP_EQ_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -3874,7 +3878,7 @@ std::string NMD::CMP_EQ_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_EQ_S(uint64 instruction) +std::string NMD::CMP_EQ_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -3898,7 +3902,7 @@ std::string NMD::CMP_EQ_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_LE_D(uint64 instruction) +std::string NMD::CMP_LE_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -3921,7 +3925,7 @@ std::string NMD::CMP_LE_D(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::CMP_LE_PH(uint64 instruction) +std::string NMD::CMP_LE_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -3943,7 +3947,7 @@ std::string NMD::CMP_LE_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_LE_S(uint64 instruction) +std::string NMD::CMP_LE_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -3967,7 +3971,7 @@ std::string NMD::CMP_LE_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_LT_D(uint64 instruction) +std::string NMD::CMP_LT_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -3990,7 +3994,7 @@ std::string NMD::CMP_LT_D(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::CMP_LT_PH(uint64 instruction) +std::string NMD::CMP_LT_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -4012,7 +4016,7 @@ std::string NMD::CMP_LT_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_LT_S(uint64 instruction) +std::string NMD::CMP_LT_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4036,7 +4040,7 @@ std::string NMD::CMP_LT_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_NE_D(uint64 instruction) +std::string NMD::CMP_NE_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4060,7 +4064,7 @@ std::string NMD::CMP_NE_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_NE_S(uint64 instruction) +std::string NMD::CMP_NE_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4084,7 +4088,7 @@ std::string NMD::CMP_NE_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_OR_D(uint64 instruction) +std::string NMD::CMP_OR_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4108,7 +4112,7 @@ std::string NMD::CMP_OR_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_OR_S(uint64 instruction) +std::string NMD::CMP_OR_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4132,7 +4136,7 @@ std::string NMD::CMP_OR_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SAF_D(uint64 instruction) +std::string NMD::CMP_SAF_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4156,7 +4160,7 @@ std::string NMD::CMP_SAF_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SAF_S(uint64 instruction) +std::string NMD::CMP_SAF_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4180,7 +4184,7 @@ std::string NMD::CMP_SAF_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SEQ_D(uint64 instruction) +std::string NMD::CMP_SEQ_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4204,7 +4208,7 @@ std::string NMD::CMP_SEQ_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SEQ_S(uint64 instruction) +std::string NMD::CMP_SEQ_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4228,7 +4232,7 @@ std::string NMD::CMP_SEQ_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SLE_D(uint64 instruction) +std::string NMD::CMP_SLE_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4252,7 +4256,7 @@ std::string NMD::CMP_SLE_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SLE_S(uint64 instruction) +std::string NMD::CMP_SLE_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4276,7 +4280,7 @@ std::string NMD::CMP_SLE_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SLT_D(uint64 instruction) +std::string NMD::CMP_SLT_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4300,7 +4304,7 @@ std::string NMD::CMP_SLT_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SLT_S(uint64 instruction) +std::string NMD::CMP_SLT_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4324,7 +4328,7 @@ std::string NMD::CMP_SLT_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SNE_D(uint64 instruction) +std::string NMD::CMP_SNE_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4348,7 +4352,7 @@ std::string NMD::CMP_SNE_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SNE_S(uint64 instruction) +std::string NMD::CMP_SNE_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4372,7 +4376,7 @@ std::string NMD::CMP_SNE_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SOR_D(uint64 instruction) +std::string NMD::CMP_SOR_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4396,7 +4400,7 @@ std::string NMD::CMP_SOR_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SOR_S(uint64 instruction) +std::string NMD::CMP_SOR_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4420,7 +4424,7 @@ std::string NMD::CMP_SOR_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SUEQ_D(uint64 instruction) +std::string NMD::CMP_SUEQ_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4444,7 +4448,7 @@ std::string NMD::CMP_SUEQ_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SUEQ_S(uint64 instruction) +std::string NMD::CMP_SUEQ_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4468,7 +4472,7 @@ std::string NMD::CMP_SUEQ_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SULE_D(uint64 instruction) +std::string NMD::CMP_SULE_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4492,7 +4496,7 @@ std::string NMD::CMP_SULE_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SULE_S(uint64 instruction) +std::string NMD::CMP_SULE_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4516,7 +4520,7 @@ std::string NMD::CMP_SULE_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SULT_D(uint64 instruction) +std::string NMD::CMP_SULT_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4540,7 +4544,7 @@ std::string NMD::CMP_SULT_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SULT_S(uint64 instruction) +std::string NMD::CMP_SULT_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4564,7 +4568,7 @@ std::string NMD::CMP_SULT_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SUN_D(uint64 instruction) +std::string NMD::CMP_SUN_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4588,7 +4592,7 @@ std::string NMD::CMP_SUN_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SUNE_D(uint64 instruction) +std::string NMD::CMP_SUNE_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4612,7 +4616,7 @@ std::string NMD::CMP_SUNE_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SUNE_S(uint64 instruction) +std::string NMD::CMP_SUNE_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4636,7 +4640,7 @@ std::string NMD::CMP_SUNE_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SUN_S(uint64 instruction) +std::string NMD::CMP_SUN_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4660,7 +4664,7 @@ std::string NMD::CMP_SUN_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_UEQ_D(uint64 instruction) +std::string NMD::CMP_UEQ_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4684,7 +4688,7 @@ std::string NMD::CMP_UEQ_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_UEQ_S(uint64 instruction) +std::string NMD::CMP_UEQ_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4708,7 +4712,7 @@ std::string NMD::CMP_UEQ_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_ULE_D(uint64 instruction) +std::string NMD::CMP_ULE_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4732,7 +4736,7 @@ std::string NMD::CMP_ULE_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_ULE_S(uint64 instruction) +std::string NMD::CMP_ULE_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4756,7 +4760,7 @@ std::string NMD::CMP_ULE_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_ULT_D(uint64 instruction) +std::string NMD::CMP_ULT_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4780,7 +4784,7 @@ std::string NMD::CMP_ULT_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_ULT_S(uint64 instruction) +std::string NMD::CMP_ULT_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4804,7 +4808,7 @@ std::string NMD::CMP_ULT_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_UN_D(uint64 instruction) +std::string NMD::CMP_UN_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4828,7 +4832,7 @@ std::string NMD::CMP_UN_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_UNE_D(uint64 instruction) +std::string NMD::CMP_UNE_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4852,7 +4856,7 @@ std::string NMD::CMP_UNE_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_UNE_S(uint64 instruction) +std::string NMD::CMP_UNE_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4876,7 +4880,7 @@ std::string NMD::CMP_UNE_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_UN_S(uint64 instruction) +std::string NMD::CMP_UN_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4901,7 +4905,7 @@ std::string NMD::CMP_UN_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMPGDU_EQ_QB(uint64 instruction) +std::string NMD::CMPGDU_EQ_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -4926,7 +4930,7 @@ std::string NMD::CMPGDU_EQ_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMPGDU_LE_QB(uint64 instruction) +std::string NMD::CMPGDU_LE_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -4951,7 +4955,7 @@ std::string NMD::CMPGDU_LE_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMPGDU_LT_QB(uint64 instruction) +std::string NMD::CMPGDU_LT_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -4976,7 +4980,7 @@ std::string NMD::CMPGDU_LT_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMPGU_EQ_QB(uint64 instruction) +std::string NMD::CMPGU_EQ_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5001,7 +5005,7 @@ std::string NMD::CMPGU_EQ_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMPGU_LE_QB(uint64 instruction) +std::string NMD::CMPGU_LE_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5026,7 +5030,7 @@ std::string NMD::CMPGU_LE_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMPGU_LT_QB(uint64 instruction) +std::string NMD::CMPGU_LT_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5050,7 +5054,7 @@ std::string NMD::CMPGU_LT_QB(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::CMPU_EQ_QB(uint64 instruction) +std::string NMD::CMPU_EQ_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5072,7 +5076,7 @@ std::string NMD::CMPU_EQ_QB(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::CMPU_LE_QB(uint64 instruction) +std::string NMD::CMPU_LE_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5094,7 +5098,7 @@ std::string NMD::CMPU_LE_QB(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::CMPU_LT_QB(uint64 instruction) +std::string NMD::CMPU_LT_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5116,7 +5120,7 @@ std::string NMD::CMPU_LT_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::COP2_1(uint64 instruction) +std::string NMD::COP2_1(uint64 instruction, Dis_info *info) { uint64 cofun_value = extract_cofun_25_24_23(instruction); @@ -5136,7 +5140,7 @@ std::string NMD::COP2_1(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CTC1(uint64 instruction) +std::string NMD::CTC1(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); @@ -5158,7 +5162,7 @@ std::string NMD::CTC1(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CTC2(uint64 instruction) +std::string NMD::CTC2(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); @@ -5180,7 +5184,7 @@ std::string NMD::CTC2(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CVT_D_L(uint64 instruction) +std::string NMD::CVT_D_L(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -5202,7 +5206,7 @@ std::string NMD::CVT_D_L(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CVT_D_S(uint64 instruction) +std::string NMD::CVT_D_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -5224,7 +5228,7 @@ std::string NMD::CVT_D_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CVT_D_W(uint64 instruction) +std::string NMD::CVT_D_W(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -5246,7 +5250,7 @@ std::string NMD::CVT_D_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CVT_L_D(uint64 instruction) +std::string NMD::CVT_L_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -5268,7 +5272,7 @@ std::string NMD::CVT_L_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CVT_L_S(uint64 instruction) +std::string NMD::CVT_L_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -5290,7 +5294,7 @@ std::string NMD::CVT_L_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CVT_S_D(uint64 instruction) +std::string NMD::CVT_S_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -5312,7 +5316,7 @@ std::string NMD::CVT_S_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CVT_S_L(uint64 instruction) +std::string NMD::CVT_S_L(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -5334,7 +5338,7 @@ std::string NMD::CVT_S_L(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CVT_S_PL(uint64 instruction) +std::string NMD::CVT_S_PL(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -5356,7 +5360,7 @@ std::string NMD::CVT_S_PL(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CVT_S_PU(uint64 instruction) +std::string NMD::CVT_S_PU(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -5378,7 +5382,7 @@ std::string NMD::CVT_S_PU(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CVT_S_W(uint64 instruction) +std::string NMD::CVT_S_W(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -5400,7 +5404,7 @@ std::string NMD::CVT_S_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CVT_W_D(uint64 instruction) +std::string NMD::CVT_W_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -5422,7 +5426,7 @@ std::string NMD::CVT_W_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CVT_W_S(uint64 instruction) +std::string NMD::CVT_W_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -5444,7 +5448,7 @@ std::string NMD::CVT_W_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DADDIU_48_(uint64 instruction) +std::string NMD::DADDIU_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); @@ -5466,7 +5470,7 @@ std::string NMD::DADDIU_48_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DADDIU_NEG_(uint64 instruction) +std::string NMD::DADDIU_NEG_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5490,7 +5494,7 @@ std::string NMD::DADDIU_NEG_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DADDIU_U12_(uint64 instruction) +std::string NMD::DADDIU_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5514,7 +5518,7 @@ std::string NMD::DADDIU_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DADD(uint64 instruction) +std::string NMD::DADD(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5538,7 +5542,7 @@ std::string NMD::DADD(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DADDU(uint64 instruction) +std::string NMD::DADDU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5562,7 +5566,7 @@ std::string NMD::DADDU(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DCLO(uint64 instruction) +std::string NMD::DCLO(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5584,7 +5588,7 @@ std::string NMD::DCLO(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DCLZ(uint64 instruction) +std::string NMD::DCLZ(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5606,7 +5610,7 @@ std::string NMD::DCLZ(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DDIV(uint64 instruction) +std::string NMD::DDIV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5630,7 +5634,7 @@ std::string NMD::DDIV(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DDIVU(uint64 instruction) +std::string NMD::DDIVU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5654,7 +5658,7 @@ std::string NMD::DDIVU(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DERET(uint64 instruction) +std::string NMD::DERET(uint64 instruction, Dis_info *info) { (void)instruction; @@ -5672,7 +5676,7 @@ std::string NMD::DERET(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DEXTM(uint64 instruction) +std::string NMD::DEXTM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5698,7 +5702,7 @@ std::string NMD::DEXTM(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DEXT(uint64 instruction) +std::string NMD::DEXT(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5724,7 +5728,7 @@ std::string NMD::DEXT(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DEXTU(uint64 instruction) +std::string NMD::DEXTU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5750,7 +5754,7 @@ std::string NMD::DEXTU(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DINSM(uint64 instruction) +std::string NMD::DINSM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5778,7 +5782,7 @@ std::string NMD::DINSM(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DINS(uint64 instruction) +std::string NMD::DINS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5806,7 +5810,7 @@ std::string NMD::DINS(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DINSU(uint64 instruction) +std::string NMD::DINSU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5834,7 +5838,7 @@ std::string NMD::DINSU(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DI(uint64 instruction) +std::string NMD::DI(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); @@ -5854,7 +5858,7 @@ std::string NMD::DI(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DIV(uint64 instruction) +std::string NMD::DIV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5878,7 +5882,7 @@ std::string NMD::DIV(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DIV_D(uint64 instruction) +std::string NMD::DIV_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -5902,7 +5906,7 @@ std::string NMD::DIV_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DIV_S(uint64 instruction) +std::string NMD::DIV_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -5926,7 +5930,7 @@ std::string NMD::DIV_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DIVU(uint64 instruction) +std::string NMD::DIVU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5950,7 +5954,7 @@ std::string NMD::DIVU(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DLSA(uint64 instruction) +std::string NMD::DLSA(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5976,7 +5980,7 @@ std::string NMD::DLSA(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DLUI_48_(uint64 instruction) +std::string NMD::DLUI_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); uint64 u_value = extract_u_31_to_0__s32(instruction); @@ -5998,7 +6002,7 @@ std::string NMD::DLUI_48_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DMFC0(uint64 instruction) +std::string NMD::DMFC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); @@ -6022,7 +6026,7 @@ std::string NMD::DMFC0(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DMFC1(uint64 instruction) +std::string NMD::DMFC1(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -6044,7 +6048,7 @@ std::string NMD::DMFC1(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DMFC2(uint64 instruction) +std::string NMD::DMFC2(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); @@ -6066,7 +6070,7 @@ std::string NMD::DMFC2(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DMFGC0(uint64 instruction) +std::string NMD::DMFGC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); @@ -6090,7 +6094,7 @@ std::string NMD::DMFGC0(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DMOD(uint64 instruction) +std::string NMD::DMOD(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6114,7 +6118,7 @@ std::string NMD::DMOD(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DMODU(uint64 instruction) +std::string NMD::DMODU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6138,7 +6142,7 @@ std::string NMD::DMODU(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DMTC0(uint64 instruction) +std::string NMD::DMTC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); @@ -6162,7 +6166,7 @@ std::string NMD::DMTC0(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DMTC1(uint64 instruction) +std::string NMD::DMTC1(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -6184,7 +6188,7 @@ std::string NMD::DMTC1(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DMTC2(uint64 instruction) +std::string NMD::DMTC2(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); @@ -6206,7 +6210,7 @@ std::string NMD::DMTC2(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DMTGC0(uint64 instruction) +std::string NMD::DMTGC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); @@ -6230,7 +6234,7 @@ std::string NMD::DMTGC0(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DMT(uint64 instruction) +std::string NMD::DMT(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); @@ -6250,7 +6254,7 @@ std::string NMD::DMT(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DMUH(uint64 instruction) +std::string NMD::DMUH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6274,7 +6278,7 @@ std::string NMD::DMUH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DMUHU(uint64 instruction) +std::string NMD::DMUHU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6298,7 +6302,7 @@ std::string NMD::DMUHU(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DMUL(uint64 instruction) +std::string NMD::DMUL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6322,7 +6326,7 @@ std::string NMD::DMUL(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DMULU(uint64 instruction) +std::string NMD::DMULU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6347,7 +6351,7 @@ std::string NMD::DMULU(uint64 instruction) * rs ----- * ac -- */ -std::string NMD::DPA_W_PH(uint64 instruction) +std::string NMD::DPA_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6371,7 +6375,7 @@ std::string NMD::DPA_W_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DPAQ_SA_L_W(uint64 instruction) +std::string NMD::DPAQ_SA_L_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6395,7 +6399,7 @@ std::string NMD::DPAQ_SA_L_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DPAQ_S_W_PH(uint64 instruction) +std::string NMD::DPAQ_S_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6419,7 +6423,7 @@ std::string NMD::DPAQ_S_W_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DPAQX_SA_W_PH(uint64 instruction) +std::string NMD::DPAQX_SA_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6443,7 +6447,7 @@ std::string NMD::DPAQX_SA_W_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DPAQX_S_W_PH(uint64 instruction) +std::string NMD::DPAQX_S_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6467,7 +6471,7 @@ std::string NMD::DPAQX_S_W_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DPAU_H_QBL(uint64 instruction) +std::string NMD::DPAU_H_QBL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6491,7 +6495,7 @@ std::string NMD::DPAU_H_QBL(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DPAU_H_QBR(uint64 instruction) +std::string NMD::DPAU_H_QBR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6515,7 +6519,7 @@ std::string NMD::DPAU_H_QBR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DPAX_W_PH(uint64 instruction) +std::string NMD::DPAX_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6539,7 +6543,7 @@ std::string NMD::DPAX_W_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DPS_W_PH(uint64 instruction) +std::string NMD::DPS_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6563,7 +6567,7 @@ std::string NMD::DPS_W_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DPSQ_SA_L_W(uint64 instruction) +std::string NMD::DPSQ_SA_L_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6587,7 +6591,7 @@ std::string NMD::DPSQ_SA_L_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DPSQ_S_W_PH(uint64 instruction) +std::string NMD::DPSQ_S_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6611,7 +6615,7 @@ std::string NMD::DPSQ_S_W_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DPSQX_SA_W_PH(uint64 instruction) +std::string NMD::DPSQX_SA_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6635,7 +6639,7 @@ std::string NMD::DPSQX_SA_W_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DPSQX_S_W_PH(uint64 instruction) +std::string NMD::DPSQX_S_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6659,7 +6663,7 @@ std::string NMD::DPSQX_S_W_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DPSU_H_QBL(uint64 instruction) +std::string NMD::DPSU_H_QBL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6683,7 +6687,7 @@ std::string NMD::DPSU_H_QBL(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DPSU_H_QBR(uint64 instruction) +std::string NMD::DPSU_H_QBR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6707,7 +6711,7 @@ std::string NMD::DPSU_H_QBR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DPSX_W_PH(uint64 instruction) +std::string NMD::DPSX_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6731,7 +6735,7 @@ std::string NMD::DPSX_W_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DROTR(uint64 instruction) +std::string NMD::DROTR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6755,7 +6759,7 @@ std::string NMD::DROTR(uint64 instruction) * rs ----- * shift ----- */ -std::string NMD::DROTR32(uint64 instruction) +std::string NMD::DROTR32(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6779,7 +6783,7 @@ std::string NMD::DROTR32(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DROTRV(uint64 instruction) +std::string NMD::DROTRV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6803,7 +6807,7 @@ std::string NMD::DROTRV(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DROTX(uint64 instruction) +std::string NMD::DROTX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6829,7 +6833,7 @@ std::string NMD::DROTX(uint64 instruction) * rs ----- * shift ----- */ -std::string NMD::DSLL(uint64 instruction) +std::string NMD::DSLL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6853,7 +6857,7 @@ std::string NMD::DSLL(uint64 instruction) * rs ----- * shift ----- */ -std::string NMD::DSLL32(uint64 instruction) +std::string NMD::DSLL32(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6877,7 +6881,7 @@ std::string NMD::DSLL32(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DSLLV(uint64 instruction) +std::string NMD::DSLLV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6901,7 +6905,7 @@ std::string NMD::DSLLV(uint64 instruction) * rs ----- * shift ----- */ -std::string NMD::DSRA(uint64 instruction) +std::string NMD::DSRA(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6925,7 +6929,7 @@ std::string NMD::DSRA(uint64 instruction) * rs ----- * shift ----- */ -std::string NMD::DSRA32(uint64 instruction) +std::string NMD::DSRA32(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6949,7 +6953,7 @@ std::string NMD::DSRA32(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DSRAV(uint64 instruction) +std::string NMD::DSRAV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6973,7 +6977,7 @@ std::string NMD::DSRAV(uint64 instruction) * rs ----- * shift ----- */ -std::string NMD::DSRL(uint64 instruction) +std::string NMD::DSRL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6997,7 +7001,7 @@ std::string NMD::DSRL(uint64 instruction) * rs ----- * shift ----- */ -std::string NMD::DSRL32(uint64 instruction) +std::string NMD::DSRL32(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7021,7 +7025,7 @@ std::string NMD::DSRL32(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DSRLV(uint64 instruction) +std::string NMD::DSRLV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7045,7 +7049,7 @@ std::string NMD::DSRLV(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DSUB(uint64 instruction) +std::string NMD::DSUB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7069,7 +7073,7 @@ std::string NMD::DSUB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DSUBU(uint64 instruction) +std::string NMD::DSUBU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7093,7 +7097,7 @@ std::string NMD::DSUBU(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DVPE(uint64 instruction) +std::string NMD::DVPE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); @@ -7113,7 +7117,7 @@ std::string NMD::DVPE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DVP(uint64 instruction) +std::string NMD::DVP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); @@ -7133,7 +7137,7 @@ std::string NMD::DVP(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::EHB(uint64 instruction) +std::string NMD::EHB(uint64 instruction, Dis_info *info) { (void)instruction; @@ -7151,7 +7155,7 @@ std::string NMD::EHB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::EI(uint64 instruction) +std::string NMD::EI(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); @@ -7171,7 +7175,7 @@ std::string NMD::EI(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::EMT(uint64 instruction) +std::string NMD::EMT(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); @@ -7191,7 +7195,7 @@ std::string NMD::EMT(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ERET(uint64 instruction) +std::string NMD::ERET(uint64 instruction, Dis_info *info) { (void)instruction; @@ -7209,7 +7213,7 @@ std::string NMD::ERET(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ERETNC(uint64 instruction) +std::string NMD::ERETNC(uint64 instruction, Dis_info *info) { (void)instruction; @@ -7227,7 +7231,7 @@ std::string NMD::ERETNC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::EVP(uint64 instruction) +std::string NMD::EVP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); @@ -7247,7 +7251,7 @@ std::string NMD::EVP(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::EVPE(uint64 instruction) +std::string NMD::EVPE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); @@ -7267,7 +7271,7 @@ std::string NMD::EVPE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::EXT(uint64 instruction) +std::string NMD::EXT(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7293,7 +7297,7 @@ std::string NMD::EXT(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::EXTD(uint64 instruction) +std::string NMD::EXTD(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7319,7 +7323,7 @@ std::string NMD::EXTD(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::EXTD32(uint64 instruction) +std::string NMD::EXTD32(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7345,7 +7349,7 @@ std::string NMD::EXTD32(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::EXTPDP(uint64 instruction) +std::string NMD::EXTPDP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 size_value = extract_size_20_19_18_17_16(instruction); @@ -7369,7 +7373,7 @@ std::string NMD::EXTPDP(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::EXTPDPV(uint64 instruction) +std::string NMD::EXTPDPV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7393,7 +7397,7 @@ std::string NMD::EXTPDPV(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::EXTP(uint64 instruction) +std::string NMD::EXTP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 size_value = extract_size_20_19_18_17_16(instruction); @@ -7417,7 +7421,7 @@ std::string NMD::EXTP(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::EXTPV(uint64 instruction) +std::string NMD::EXTPV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7442,7 +7446,7 @@ std::string NMD::EXTPV(uint64 instruction) * shift ----- * ac -- */ -std::string NMD::EXTR_RS_W(uint64 instruction) +std::string NMD::EXTR_RS_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 shift_value = extract_shift_20_19_18_17_16(instruction); @@ -7467,7 +7471,7 @@ std::string NMD::EXTR_RS_W(uint64 instruction) * shift ----- * ac -- */ -std::string NMD::EXTR_R_W(uint64 instruction) +std::string NMD::EXTR_R_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 shift_value = extract_shift_20_19_18_17_16(instruction); @@ -7492,7 +7496,7 @@ std::string NMD::EXTR_R_W(uint64 instruction) * shift ----- * ac -- */ -std::string NMD::EXTR_S_H(uint64 instruction) +std::string NMD::EXTR_S_H(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 shift_value = extract_shift_20_19_18_17_16(instruction); @@ -7517,7 +7521,7 @@ std::string NMD::EXTR_S_H(uint64 instruction) * shift ----- * ac -- */ -std::string NMD::EXTR_W(uint64 instruction) +std::string NMD::EXTR_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 shift_value = extract_shift_20_19_18_17_16(instruction); @@ -7542,7 +7546,7 @@ std::string NMD::EXTR_W(uint64 instruction) * rs ----- * ac -- */ -std::string NMD::EXTRV_RS_W(uint64 instruction) +std::string NMD::EXTRV_RS_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7567,7 +7571,7 @@ std::string NMD::EXTRV_RS_W(uint64 instruction) * rs ----- * ac -- */ -std::string NMD::EXTRV_R_W(uint64 instruction) +std::string NMD::EXTRV_R_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7592,7 +7596,7 @@ std::string NMD::EXTRV_R_W(uint64 instruction) * rs ----- * ac -- */ -std::string NMD::EXTRV_S_H(uint64 instruction) +std::string NMD::EXTRV_S_H(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7617,7 +7621,7 @@ std::string NMD::EXTRV_S_H(uint64 instruction) * rs ----- * ac -- */ -std::string NMD::EXTRV_W(uint64 instruction) +std::string NMD::EXTRV_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7642,7 +7646,7 @@ std::string NMD::EXTRV_W(uint64 instruction) * rd ----- * shift ----- */ -std::string NMD::EXTW(uint64 instruction) +std::string NMD::EXTW(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7668,7 +7672,7 @@ std::string NMD::EXTW(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::FLOOR_L_D(uint64 instruction) +std::string NMD::FLOOR_L_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -7690,7 +7694,7 @@ std::string NMD::FLOOR_L_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::FLOOR_L_S(uint64 instruction) +std::string NMD::FLOOR_L_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -7712,7 +7716,7 @@ std::string NMD::FLOOR_L_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::FLOOR_W_D(uint64 instruction) +std::string NMD::FLOOR_W_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -7734,7 +7738,7 @@ std::string NMD::FLOOR_W_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::FLOOR_W_S(uint64 instruction) +std::string NMD::FLOOR_W_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -7756,7 +7760,7 @@ std::string NMD::FLOOR_W_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::FORK(uint64 instruction) +std::string NMD::FORK(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7780,7 +7784,7 @@ std::string NMD::FORK(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::HYPCALL(uint64 instruction) +std::string NMD::HYPCALL(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_17_to_0(instruction); @@ -7800,7 +7804,7 @@ std::string NMD::HYPCALL(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::HYPCALL_16_(uint64 instruction) +std::string NMD::HYPCALL_16_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_1_0(instruction); @@ -7820,7 +7824,7 @@ std::string NMD::HYPCALL_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::INS(uint64 instruction) +std::string NMD::INS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7847,7 +7851,7 @@ std::string NMD::INS(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::INSV(uint64 instruction) +std::string NMD::INSV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7869,7 +7873,7 @@ std::string NMD::INSV(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::IRET(uint64 instruction) +std::string NMD::IRET(uint64 instruction, Dis_info *info) { (void)instruction; @@ -7887,7 +7891,7 @@ std::string NMD::IRET(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::JALRC_16_(uint64 instruction) +std::string NMD::JALRC_16_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_9_8_7_6_5(instruction); @@ -7907,7 +7911,7 @@ std::string NMD::JALRC_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::JALRC_32_(uint64 instruction) +std::string NMD::JALRC_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7929,7 +7933,7 @@ std::string NMD::JALRC_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::JALRC_HB(uint64 instruction) +std::string NMD::JALRC_HB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7951,7 +7955,7 @@ std::string NMD::JALRC_HB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::JRC(uint64 instruction) +std::string NMD::JRC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_9_8_7_6_5(instruction); @@ -7971,7 +7975,7 @@ std::string NMD::JRC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LB_16_(uint64 instruction) +std::string NMD::LB_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -7995,7 +7999,7 @@ std::string NMD::LB_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LB_GP_(uint64 instruction) +std::string NMD::LB_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_0(instruction); @@ -8017,7 +8021,7 @@ std::string NMD::LB_GP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LB_S9_(uint64 instruction) +std::string NMD::LB_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8041,7 +8045,7 @@ std::string NMD::LB_S9_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LB_U12_(uint64 instruction) +std::string NMD::LB_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8065,7 +8069,7 @@ std::string NMD::LB_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LBE(uint64 instruction) +std::string NMD::LBE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8089,7 +8093,7 @@ std::string NMD::LBE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LBU_16_(uint64 instruction) +std::string NMD::LBU_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -8113,7 +8117,7 @@ std::string NMD::LBU_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LBU_GP_(uint64 instruction) +std::string NMD::LBU_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_0(instruction); @@ -8135,7 +8139,7 @@ std::string NMD::LBU_GP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LBU_S9_(uint64 instruction) +std::string NMD::LBU_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8159,7 +8163,7 @@ std::string NMD::LBU_S9_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LBU_U12_(uint64 instruction) +std::string NMD::LBU_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8183,7 +8187,7 @@ std::string NMD::LBU_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LBUE(uint64 instruction) +std::string NMD::LBUE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8207,7 +8211,7 @@ std::string NMD::LBUE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LBUX(uint64 instruction) +std::string NMD::LBUX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8231,7 +8235,7 @@ std::string NMD::LBUX(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LBX(uint64 instruction) +std::string NMD::LBX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8255,7 +8259,7 @@ std::string NMD::LBX(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LD_GP_(uint64 instruction) +std::string NMD::LD_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_to_3__s3(instruction); @@ -8277,7 +8281,7 @@ std::string NMD::LD_GP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LD_S9_(uint64 instruction) +std::string NMD::LD_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8301,7 +8305,7 @@ std::string NMD::LD_S9_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LD_U12_(uint64 instruction) +std::string NMD::LD_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8325,7 +8329,7 @@ std::string NMD::LD_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LDC1_GP_(uint64 instruction) +std::string NMD::LDC1_GP_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_2__s2(instruction); @@ -8347,7 +8351,7 @@ std::string NMD::LDC1_GP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LDC1_S9_(uint64 instruction) +std::string NMD::LDC1_S9_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8371,7 +8375,7 @@ std::string NMD::LDC1_S9_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LDC1_U12_(uint64 instruction) +std::string NMD::LDC1_U12_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8395,7 +8399,7 @@ std::string NMD::LDC1_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LDC1XS(uint64 instruction) +std::string NMD::LDC1XS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8419,7 +8423,7 @@ std::string NMD::LDC1XS(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LDC1X(uint64 instruction) +std::string NMD::LDC1X(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8443,7 +8447,7 @@ std::string NMD::LDC1X(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LDC2(uint64 instruction) +std::string NMD::LDC2(uint64 instruction, Dis_info *info) { uint64 ct_value = extract_ct_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8467,7 +8471,7 @@ std::string NMD::LDC2(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LDM(uint64 instruction) +std::string NMD::LDM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8493,13 +8497,13 @@ std::string NMD::LDM(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LDPC_48_(uint64 instruction) +std::string NMD::LDPC_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); std::string rt = GPR(copy(rt_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 6); + std::string s = ADDRESS(encode_s_from_address(s_value), 6, info); return img_format("LDPC %s, %s", rt, s); } @@ -8515,7 +8519,7 @@ std::string NMD::LDPC_48_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LDX(uint64 instruction) +std::string NMD::LDX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8539,7 +8543,7 @@ std::string NMD::LDX(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LDXS(uint64 instruction) +std::string NMD::LDXS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8563,7 +8567,7 @@ std::string NMD::LDXS(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LH_16_(uint64 instruction) +std::string NMD::LH_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -8587,7 +8591,7 @@ std::string NMD::LH_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LH_GP_(uint64 instruction) +std::string NMD::LH_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_1__s1(instruction); @@ -8609,7 +8613,7 @@ std::string NMD::LH_GP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LH_S9_(uint64 instruction) +std::string NMD::LH_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8633,7 +8637,7 @@ std::string NMD::LH_S9_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LH_U12_(uint64 instruction) +std::string NMD::LH_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8657,7 +8661,7 @@ std::string NMD::LH_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LHE(uint64 instruction) +std::string NMD::LHE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8681,7 +8685,7 @@ std::string NMD::LHE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LHU_16_(uint64 instruction) +std::string NMD::LHU_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -8705,7 +8709,7 @@ std::string NMD::LHU_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LHU_GP_(uint64 instruction) +std::string NMD::LHU_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_1__s1(instruction); @@ -8727,7 +8731,7 @@ std::string NMD::LHU_GP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LHU_S9_(uint64 instruction) +std::string NMD::LHU_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8751,7 +8755,7 @@ std::string NMD::LHU_S9_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LHU_U12_(uint64 instruction) +std::string NMD::LHU_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8775,7 +8779,7 @@ std::string NMD::LHU_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LHUE(uint64 instruction) +std::string NMD::LHUE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8799,7 +8803,7 @@ std::string NMD::LHUE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LHUX(uint64 instruction) +std::string NMD::LHUX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8823,7 +8827,7 @@ std::string NMD::LHUX(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LHUXS(uint64 instruction) +std::string NMD::LHUXS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8847,7 +8851,7 @@ std::string NMD::LHUXS(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LHXS(uint64 instruction) +std::string NMD::LHXS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8871,7 +8875,7 @@ std::string NMD::LHXS(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LHX(uint64 instruction) +std::string NMD::LHX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8895,7 +8899,7 @@ std::string NMD::LHX(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LI_16_(uint64 instruction) +std::string NMD::LI_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 eu_value = extract_eu_6_5_4_3_2_1_0(instruction); @@ -8917,7 +8921,7 @@ std::string NMD::LI_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LI_48_(uint64 instruction) +std::string NMD::LI_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); @@ -8939,7 +8943,7 @@ std::string NMD::LI_48_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LL(uint64 instruction) +std::string NMD::LL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8963,7 +8967,7 @@ std::string NMD::LL(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LLD(uint64 instruction) +std::string NMD::LLD(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8987,7 +8991,7 @@ std::string NMD::LLD(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LLDP(uint64 instruction) +std::string NMD::LLDP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9011,7 +9015,7 @@ std::string NMD::LLDP(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LLE(uint64 instruction) +std::string NMD::LLE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9035,7 +9039,7 @@ std::string NMD::LLE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LLWP(uint64 instruction) +std::string NMD::LLWP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9059,7 +9063,7 @@ std::string NMD::LLWP(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LLWPE(uint64 instruction) +std::string NMD::LLWPE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9083,7 +9087,7 @@ std::string NMD::LLWPE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LSA(uint64 instruction) +std::string NMD::LSA(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9109,7 +9113,7 @@ std::string NMD::LSA(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LUI(uint64 instruction) +std::string NMD::LUI(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); int64 s_value = extract_s__se31_0_11_to_2_20_to_12_s12(instruction); @@ -9131,7 +9135,7 @@ std::string NMD::LUI(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LW_16_(uint64 instruction) +std::string NMD::LW_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -9155,7 +9159,7 @@ std::string NMD::LW_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LW_4X4_(uint64 instruction) +std::string NMD::LW_4X4_(uint64 instruction, Dis_info *info) { uint64 rt4_value = extract_rt4_9_7_6_5(instruction); uint64 rs4_value = extract_rs4_4_2_1_0(instruction); @@ -9179,7 +9183,7 @@ std::string NMD::LW_4X4_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LW_GP_(uint64 instruction) +std::string NMD::LW_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_to_2__s2(instruction); @@ -9201,7 +9205,7 @@ std::string NMD::LW_GP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LW_GP16_(uint64 instruction) +std::string NMD::LW_GP16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 u_value = extract_u_6_5_4_3_2_1_0__s2(instruction); @@ -9223,7 +9227,7 @@ std::string NMD::LW_GP16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LW_S9_(uint64 instruction) +std::string NMD::LW_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9247,7 +9251,7 @@ std::string NMD::LW_S9_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LW_SP_(uint64 instruction) +std::string NMD::LW_SP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_9_8_7_6_5(instruction); uint64 u_value = extract_u_4_3_2_1_0__s2(instruction); @@ -9269,7 +9273,7 @@ std::string NMD::LW_SP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LW_U12_(uint64 instruction) +std::string NMD::LW_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9293,7 +9297,7 @@ std::string NMD::LW_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWC1_GP_(uint64 instruction) +std::string NMD::LWC1_GP_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_2__s2(instruction); @@ -9315,7 +9319,7 @@ std::string NMD::LWC1_GP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWC1_S9_(uint64 instruction) +std::string NMD::LWC1_S9_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9339,7 +9343,7 @@ std::string NMD::LWC1_S9_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWC1_U12_(uint64 instruction) +std::string NMD::LWC1_U12_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9363,7 +9367,7 @@ std::string NMD::LWC1_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWC1X(uint64 instruction) +std::string NMD::LWC1X(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9387,7 +9391,7 @@ std::string NMD::LWC1X(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWC1XS(uint64 instruction) +std::string NMD::LWC1XS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9411,7 +9415,7 @@ std::string NMD::LWC1XS(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWC2(uint64 instruction) +std::string NMD::LWC2(uint64 instruction, Dis_info *info) { uint64 ct_value = extract_ct_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9435,7 +9439,7 @@ std::string NMD::LWC2(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWE(uint64 instruction) +std::string NMD::LWE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9459,7 +9463,7 @@ std::string NMD::LWE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWM(uint64 instruction) +std::string NMD::LWM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9485,13 +9489,13 @@ std::string NMD::LWM(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWPC_48_(uint64 instruction) +std::string NMD::LWPC_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); std::string rt = GPR(copy(rt_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 6); + std::string s = ADDRESS(encode_s_from_address(s_value), 6, info); return img_format("LWPC %s, %s", rt, s); } @@ -9507,7 +9511,7 @@ std::string NMD::LWPC_48_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWU_GP_(uint64 instruction) +std::string NMD::LWU_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_2__s2(instruction); @@ -9529,7 +9533,7 @@ std::string NMD::LWU_GP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWU_S9_(uint64 instruction) +std::string NMD::LWU_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9553,7 +9557,7 @@ std::string NMD::LWU_S9_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWU_U12_(uint64 instruction) +std::string NMD::LWU_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9577,7 +9581,7 @@ std::string NMD::LWU_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWUX(uint64 instruction) +std::string NMD::LWUX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9601,7 +9605,7 @@ std::string NMD::LWUX(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWUXS(uint64 instruction) +std::string NMD::LWUXS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9625,7 +9629,7 @@ std::string NMD::LWUXS(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWX(uint64 instruction) +std::string NMD::LWX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9649,7 +9653,7 @@ std::string NMD::LWX(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWXS_16_(uint64 instruction) +std::string NMD::LWXS_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -9673,7 +9677,7 @@ std::string NMD::LWXS_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWXS_32_(uint64 instruction) +std::string NMD::LWXS_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9698,7 +9702,7 @@ std::string NMD::LWXS_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MADD_DSP_(uint64 instruction) +std::string NMD::MADD_DSP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9722,7 +9726,7 @@ std::string NMD::MADD_DSP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MADDF_D(uint64 instruction) +std::string NMD::MADDF_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -9746,7 +9750,7 @@ std::string NMD::MADDF_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MADDF_S(uint64 instruction) +std::string NMD::MADDF_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -9771,7 +9775,7 @@ std::string NMD::MADDF_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MADDU_DSP_(uint64 instruction) +std::string NMD::MADDU_DSP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9796,7 +9800,7 @@ std::string NMD::MADDU_DSP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MAQ_S_W_PHL(uint64 instruction) +std::string NMD::MAQ_S_W_PHL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9821,7 +9825,7 @@ std::string NMD::MAQ_S_W_PHL(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MAQ_S_W_PHR(uint64 instruction) +std::string NMD::MAQ_S_W_PHR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9846,7 +9850,7 @@ std::string NMD::MAQ_S_W_PHR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MAQ_SA_W_PHL(uint64 instruction) +std::string NMD::MAQ_SA_W_PHL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9871,7 +9875,7 @@ std::string NMD::MAQ_SA_W_PHL(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MAQ_SA_W_PHR(uint64 instruction) +std::string NMD::MAQ_SA_W_PHR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9895,7 +9899,7 @@ std::string NMD::MAQ_SA_W_PHR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MAX_D(uint64 instruction) +std::string NMD::MAX_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -9919,7 +9923,7 @@ std::string NMD::MAX_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MAX_S(uint64 instruction) +std::string NMD::MAX_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -9943,7 +9947,7 @@ std::string NMD::MAX_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MAXA_D(uint64 instruction) +std::string NMD::MAXA_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -9967,7 +9971,7 @@ std::string NMD::MAXA_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MAXA_S(uint64 instruction) +std::string NMD::MAXA_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -9991,7 +9995,7 @@ std::string NMD::MAXA_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MFC0(uint64 instruction) +std::string NMD::MFC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); @@ -10015,7 +10019,7 @@ std::string NMD::MFC0(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MFC1(uint64 instruction) +std::string NMD::MFC1(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -10037,7 +10041,7 @@ std::string NMD::MFC1(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MFC2(uint64 instruction) +std::string NMD::MFC2(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); @@ -10059,7 +10063,7 @@ std::string NMD::MFC2(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MFGC0(uint64 instruction) +std::string NMD::MFGC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); @@ -10083,7 +10087,7 @@ std::string NMD::MFGC0(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MFHC0(uint64 instruction) +std::string NMD::MFHC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); @@ -10107,7 +10111,7 @@ std::string NMD::MFHC0(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MFHC1(uint64 instruction) +std::string NMD::MFHC1(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -10129,7 +10133,7 @@ std::string NMD::MFHC1(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MFHC2(uint64 instruction) +std::string NMD::MFHC2(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); @@ -10151,7 +10155,7 @@ std::string NMD::MFHC2(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MFHGC0(uint64 instruction) +std::string NMD::MFHGC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); @@ -10174,7 +10178,7 @@ std::string NMD::MFHGC0(uint64 instruction) * rt ----- * ac -- */ -std::string NMD::MFHI_DSP_(uint64 instruction) +std::string NMD::MFHI_DSP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 ac_value = extract_ac_15_14(instruction); @@ -10196,7 +10200,7 @@ std::string NMD::MFHI_DSP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MFHTR(uint64 instruction) +std::string NMD::MFHTR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); @@ -10221,7 +10225,7 @@ std::string NMD::MFHTR(uint64 instruction) * rt ----- * ac -- */ -std::string NMD::MFLO_DSP_(uint64 instruction) +std::string NMD::MFLO_DSP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 ac_value = extract_ac_15_14(instruction); @@ -10243,7 +10247,7 @@ std::string NMD::MFLO_DSP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MFTR(uint64 instruction) +std::string NMD::MFTR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); @@ -10269,7 +10273,7 @@ std::string NMD::MFTR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MIN_D(uint64 instruction) +std::string NMD::MIN_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -10293,7 +10297,7 @@ std::string NMD::MIN_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MIN_S(uint64 instruction) +std::string NMD::MIN_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -10317,7 +10321,7 @@ std::string NMD::MIN_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MINA_D(uint64 instruction) +std::string NMD::MINA_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -10341,7 +10345,7 @@ std::string NMD::MINA_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MINA_S(uint64 instruction) +std::string NMD::MINA_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -10365,7 +10369,7 @@ std::string NMD::MINA_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MOD(uint64 instruction) +std::string NMD::MOD(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -10389,7 +10393,7 @@ std::string NMD::MOD(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MODSUB(uint64 instruction) +std::string NMD::MODSUB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -10413,7 +10417,7 @@ std::string NMD::MODSUB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MODU(uint64 instruction) +std::string NMD::MODU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -10437,7 +10441,7 @@ std::string NMD::MODU(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MOV_D(uint64 instruction) +std::string NMD::MOV_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -10459,7 +10463,7 @@ std::string NMD::MOV_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MOV_S(uint64 instruction) +std::string NMD::MOV_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -10481,7 +10485,7 @@ std::string NMD::MOV_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MOVE_BALC(uint64 instruction) +std::string NMD::MOVE_BALC(uint64 instruction, Dis_info *info) { uint64 rtz4_value = extract_rtz4_27_26_25_23_22_21(instruction); uint64 rd1_value = extract_rdl_25_24(instruction); @@ -10489,7 +10493,7 @@ std::string NMD::MOVE_BALC(uint64 instruction) std::string rd1 = GPR(decode_gpr_gpr1(rd1_value)); std::string rtz4 = GPR(decode_gpr_gpr4_zero(rtz4_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); return img_format("MOVE.BALC %s, %s, %s", rd1, rtz4, s); } @@ -10505,7 +10509,7 @@ std::string NMD::MOVE_BALC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MOVEP(uint64 instruction) +std::string NMD::MOVEP(uint64 instruction, Dis_info *info) { uint64 rtz4_value = extract_rtz4_9_7_6_5(instruction); uint64 rd2_value = extract_rd2_3_8(instruction); @@ -10532,7 +10536,7 @@ std::string NMD::MOVEP(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MOVEP_REV_(uint64 instruction) +std::string NMD::MOVEP_REV_(uint64 instruction, Dis_info *info) { uint64 rt4_value = extract_rt4_9_7_6_5(instruction); uint64 rd2_value = extract_rd2_3_8(instruction); @@ -10559,7 +10563,7 @@ std::string NMD::MOVEP_REV_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MOVE(uint64 instruction) +std::string NMD::MOVE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_9_8_7_6_5(instruction); uint64 rs_value = extract_rs_4_3_2_1_0(instruction); @@ -10581,7 +10585,7 @@ std::string NMD::MOVE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MOVN(uint64 instruction) +std::string NMD::MOVN(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -10605,7 +10609,7 @@ std::string NMD::MOVN(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MOVZ(uint64 instruction) +std::string NMD::MOVZ(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -10629,7 +10633,7 @@ std::string NMD::MOVZ(uint64 instruction) * rs ----- * ac -- */ -std::string NMD::MSUB_DSP_(uint64 instruction) +std::string NMD::MSUB_DSP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -10653,7 +10657,7 @@ std::string NMD::MSUB_DSP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MSUBF_D(uint64 instruction) +std::string NMD::MSUBF_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -10677,7 +10681,7 @@ std::string NMD::MSUBF_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MSUBF_S(uint64 instruction) +std::string NMD::MSUBF_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -10701,7 +10705,7 @@ std::string NMD::MSUBF_S(uint64 instruction) * rs ----- * ac -- */ -std::string NMD::MSUBU_DSP_(uint64 instruction) +std::string NMD::MSUBU_DSP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -10725,7 +10729,7 @@ std::string NMD::MSUBU_DSP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MTC0(uint64 instruction) +std::string NMD::MTC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); @@ -10749,7 +10753,7 @@ std::string NMD::MTC0(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MTC1(uint64 instruction) +std::string NMD::MTC1(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -10771,7 +10775,7 @@ std::string NMD::MTC1(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MTC2(uint64 instruction) +std::string NMD::MTC2(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); @@ -10793,7 +10797,7 @@ std::string NMD::MTC2(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MTGC0(uint64 instruction) +std::string NMD::MTGC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); @@ -10817,7 +10821,7 @@ std::string NMD::MTGC0(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MTHC0(uint64 instruction) +std::string NMD::MTHC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); @@ -10841,7 +10845,7 @@ std::string NMD::MTHC0(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MTHC1(uint64 instruction) +std::string NMD::MTHC1(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -10863,7 +10867,7 @@ std::string NMD::MTHC1(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MTHC2(uint64 instruction) +std::string NMD::MTHC2(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); @@ -10885,7 +10889,7 @@ std::string NMD::MTHC2(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MTHGC0(uint64 instruction) +std::string NMD::MTHGC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); @@ -10908,7 +10912,7 @@ std::string NMD::MTHGC0(uint64 instruction) * rs ----- * ac -- */ -std::string NMD::MTHI_DSP_(uint64 instruction) +std::string NMD::MTHI_DSP_(uint64 instruction, Dis_info *info) { uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); @@ -10929,7 +10933,7 @@ std::string NMD::MTHI_DSP_(uint64 instruction) * rs ----- * ac -- */ -std::string NMD::MTHLIP(uint64 instruction) +std::string NMD::MTHLIP(uint64 instruction, Dis_info *info) { uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); @@ -10951,7 +10955,7 @@ std::string NMD::MTHLIP(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MTHTR(uint64 instruction) +std::string NMD::MTHTR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); @@ -10976,7 +10980,7 @@ std::string NMD::MTHTR(uint64 instruction) * rs ----- * ac -- */ -std::string NMD::MTLO_DSP_(uint64 instruction) +std::string NMD::MTLO_DSP_(uint64 instruction, Dis_info *info) { uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); @@ -10998,7 +11002,7 @@ std::string NMD::MTLO_DSP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MTTR(uint64 instruction) +std::string NMD::MTTR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); @@ -11024,7 +11028,7 @@ std::string NMD::MTTR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MUH(uint64 instruction) +std::string NMD::MUH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11048,7 +11052,7 @@ std::string NMD::MUH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MUHU(uint64 instruction) +std::string NMD::MUHU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11072,7 +11076,7 @@ std::string NMD::MUHU(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MUL_32_(uint64 instruction) +std::string NMD::MUL_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11096,7 +11100,7 @@ std::string NMD::MUL_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MUL_4X4_(uint64 instruction) +std::string NMD::MUL_4X4_(uint64 instruction, Dis_info *info) { uint64 rt4_value = extract_rt4_9_7_6_5(instruction); uint64 rs4_value = extract_rs4_4_2_1_0(instruction); @@ -11118,7 +11122,7 @@ std::string NMD::MUL_4X4_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MUL_D(uint64 instruction) +std::string NMD::MUL_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -11143,7 +11147,7 @@ std::string NMD::MUL_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MUL_PH(uint64 instruction) +std::string NMD::MUL_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11168,7 +11172,7 @@ std::string NMD::MUL_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MUL_S_PH(uint64 instruction) +std::string NMD::MUL_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11192,7 +11196,7 @@ std::string NMD::MUL_S_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MUL_S(uint64 instruction) +std::string NMD::MUL_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -11217,7 +11221,7 @@ std::string NMD::MUL_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MULEQ_S_W_PHL(uint64 instruction) +std::string NMD::MULEQ_S_W_PHL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11242,7 +11246,7 @@ std::string NMD::MULEQ_S_W_PHL(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MULEQ_S_W_PHR(uint64 instruction) +std::string NMD::MULEQ_S_W_PHR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11267,7 +11271,7 @@ std::string NMD::MULEQ_S_W_PHR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MULEU_S_PH_QBL(uint64 instruction) +std::string NMD::MULEU_S_PH_QBL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11292,7 +11296,7 @@ std::string NMD::MULEU_S_PH_QBL(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MULEU_S_PH_QBR(uint64 instruction) +std::string NMD::MULEU_S_PH_QBR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11317,7 +11321,7 @@ std::string NMD::MULEU_S_PH_QBR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MULQ_RS_PH(uint64 instruction) +std::string NMD::MULQ_RS_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11342,7 +11346,7 @@ std::string NMD::MULQ_RS_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MULQ_RS_W(uint64 instruction) +std::string NMD::MULQ_RS_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11367,7 +11371,7 @@ std::string NMD::MULQ_RS_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MULQ_S_PH(uint64 instruction) +std::string NMD::MULQ_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11392,7 +11396,7 @@ std::string NMD::MULQ_S_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MULQ_S_W(uint64 instruction) +std::string NMD::MULQ_S_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11417,7 +11421,7 @@ std::string NMD::MULQ_S_W(uint64 instruction) * rs ----- * ac -- */ -std::string NMD::MULSA_W_PH(uint64 instruction) +std::string NMD::MULSA_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11442,7 +11446,7 @@ std::string NMD::MULSA_W_PH(uint64 instruction) * rs ----- * ac -- */ -std::string NMD::MULSAQ_S_W_PH(uint64 instruction) +std::string NMD::MULSAQ_S_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11466,7 +11470,7 @@ std::string NMD::MULSAQ_S_W_PH(uint64 instruction) * rs ----- * ac -- */ -std::string NMD::MULT_DSP_(uint64 instruction) +std::string NMD::MULT_DSP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11490,7 +11494,7 @@ std::string NMD::MULT_DSP_(uint64 instruction) * rs ----- * ac -- */ -std::string NMD::MULTU_DSP_(uint64 instruction) +std::string NMD::MULTU_DSP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11514,7 +11518,7 @@ std::string NMD::MULTU_DSP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MULU(uint64 instruction) +std::string NMD::MULU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11538,7 +11542,7 @@ std::string NMD::MULU(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::NEG_D(uint64 instruction) +std::string NMD::NEG_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -11560,7 +11564,7 @@ std::string NMD::NEG_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::NEG_S(uint64 instruction) +std::string NMD::NEG_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -11582,7 +11586,7 @@ std::string NMD::NEG_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::NOP_16_(uint64 instruction) +std::string NMD::NOP_16_(uint64 instruction, Dis_info *info) { (void)instruction; @@ -11600,7 +11604,7 @@ std::string NMD::NOP_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::NOP_32_(uint64 instruction) +std::string NMD::NOP_32_(uint64 instruction, Dis_info *info) { (void)instruction; @@ -11618,7 +11622,7 @@ std::string NMD::NOP_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::NOR(uint64 instruction) +std::string NMD::NOR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11642,7 +11646,7 @@ std::string NMD::NOR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::NOT_16_(uint64 instruction) +std::string NMD::NOT_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -11664,7 +11668,7 @@ std::string NMD::NOT_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::OR_16_(uint64 instruction) +std::string NMD::OR_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -11686,7 +11690,7 @@ std::string NMD::OR_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::OR_32_(uint64 instruction) +std::string NMD::OR_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11710,7 +11714,7 @@ std::string NMD::OR_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ORI(uint64 instruction) +std::string NMD::ORI(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11735,7 +11739,7 @@ std::string NMD::ORI(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PACKRL_PH(uint64 instruction) +std::string NMD::PACKRL_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11759,7 +11763,7 @@ std::string NMD::PACKRL_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PAUSE(uint64 instruction) +std::string NMD::PAUSE(uint64 instruction, Dis_info *info) { (void)instruction; @@ -11778,7 +11782,7 @@ std::string NMD::PAUSE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PICK_PH(uint64 instruction) +std::string NMD::PICK_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11803,7 +11807,7 @@ std::string NMD::PICK_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PICK_QB(uint64 instruction) +std::string NMD::PICK_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11828,7 +11832,7 @@ std::string NMD::PICK_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECEQ_W_PHL(uint64 instruction) +std::string NMD::PRECEQ_W_PHL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11851,7 +11855,7 @@ std::string NMD::PRECEQ_W_PHL(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECEQ_W_PHR(uint64 instruction) +std::string NMD::PRECEQ_W_PHR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11874,7 +11878,7 @@ std::string NMD::PRECEQ_W_PHR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECEQU_PH_QBLA(uint64 instruction) +std::string NMD::PRECEQU_PH_QBLA(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11897,7 +11901,7 @@ std::string NMD::PRECEQU_PH_QBLA(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECEQU_PH_QBL(uint64 instruction) +std::string NMD::PRECEQU_PH_QBL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11920,7 +11924,7 @@ std::string NMD::PRECEQU_PH_QBL(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECEQU_PH_QBRA(uint64 instruction) +std::string NMD::PRECEQU_PH_QBRA(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11943,7 +11947,7 @@ std::string NMD::PRECEQU_PH_QBRA(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECEQU_PH_QBR(uint64 instruction) +std::string NMD::PRECEQU_PH_QBR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11967,7 +11971,7 @@ std::string NMD::PRECEQU_PH_QBR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECEU_PH_QBLA(uint64 instruction) +std::string NMD::PRECEU_PH_QBLA(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11990,7 +11994,7 @@ std::string NMD::PRECEU_PH_QBLA(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECEU_PH_QBL(uint64 instruction) +std::string NMD::PRECEU_PH_QBL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12014,7 +12018,7 @@ std::string NMD::PRECEU_PH_QBL(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECEU_PH_QBRA(uint64 instruction) +std::string NMD::PRECEU_PH_QBRA(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12037,7 +12041,7 @@ std::string NMD::PRECEU_PH_QBRA(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECEU_PH_QBR(uint64 instruction) +std::string NMD::PRECEU_PH_QBR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12060,7 +12064,7 @@ std::string NMD::PRECEU_PH_QBR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECR_QB_PH(uint64 instruction) +std::string NMD::PRECR_QB_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12085,7 +12089,7 @@ std::string NMD::PRECR_QB_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECR_SRA_PH_W(uint64 instruction) +std::string NMD::PRECR_SRA_PH_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12110,7 +12114,7 @@ std::string NMD::PRECR_SRA_PH_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECR_SRA_R_PH_W(uint64 instruction) +std::string NMD::PRECR_SRA_R_PH_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12135,7 +12139,7 @@ std::string NMD::PRECR_SRA_R_PH_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECRQ_PH_W(uint64 instruction) +std::string NMD::PRECRQ_PH_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12160,7 +12164,7 @@ std::string NMD::PRECRQ_PH_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECRQ_QB_PH(uint64 instruction) +std::string NMD::PRECRQ_QB_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12185,7 +12189,7 @@ std::string NMD::PRECRQ_QB_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECRQ_RS_PH_W(uint64 instruction) +std::string NMD::PRECRQ_RS_PH_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12210,7 +12214,7 @@ std::string NMD::PRECRQ_RS_PH_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECRQU_S_QB_PH(uint64 instruction) +std::string NMD::PRECRQU_S_QB_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12234,7 +12238,7 @@ std::string NMD::PRECRQU_S_QB_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PREF_S9_(uint64 instruction) +std::string NMD::PREF_S9_(uint64 instruction, Dis_info *info) { uint64 hint_value = extract_hint_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12258,7 +12262,7 @@ std::string NMD::PREF_S9_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PREF_U12_(uint64 instruction) +std::string NMD::PREF_U12_(uint64 instruction, Dis_info *info) { uint64 hint_value = extract_hint_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12282,7 +12286,7 @@ std::string NMD::PREF_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PREFE(uint64 instruction) +std::string NMD::PREFE(uint64 instruction, Dis_info *info) { uint64 hint_value = extract_hint_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12306,7 +12310,7 @@ std::string NMD::PREFE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PREPEND(uint64 instruction) +std::string NMD::PREPEND(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12329,7 +12333,7 @@ std::string NMD::PREPEND(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::RADDU_W_QB(uint64 instruction) +std::string NMD::RADDU_W_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12350,7 +12354,7 @@ std::string NMD::RADDU_W_QB(uint64 instruction) * rt ----- * mask ------- */ -std::string NMD::RDDSP(uint64 instruction) +std::string NMD::RDDSP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 mask_value = extract_mask_20_19_18_17_16_15_14(instruction); @@ -12372,7 +12376,7 @@ std::string NMD::RDDSP(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::RDHWR(uint64 instruction) +std::string NMD::RDHWR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 hs_value = extract_hs_20_19_18_17_16(instruction); @@ -12396,7 +12400,7 @@ std::string NMD::RDHWR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::RDPGPR(uint64 instruction) +std::string NMD::RDPGPR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12418,7 +12422,7 @@ std::string NMD::RDPGPR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::RECIP_D(uint64 instruction) +std::string NMD::RECIP_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -12440,7 +12444,7 @@ std::string NMD::RECIP_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::RECIP_S(uint64 instruction) +std::string NMD::RECIP_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -12462,7 +12466,7 @@ std::string NMD::RECIP_S(uint64 instruction) * rt ----- * s ---------- */ -std::string NMD::REPL_PH(uint64 instruction) +std::string NMD::REPL_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); int64 s_value = extract_s__se9_20_19_18_17_16_15_14_13_12_11(instruction); @@ -12484,7 +12488,7 @@ std::string NMD::REPL_PH(uint64 instruction) * rt ----- * u -------- */ -std::string NMD::REPL_QB(uint64 instruction) +std::string NMD::REPL_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_19_18_17_16_15_14_13(instruction); @@ -12506,7 +12510,7 @@ std::string NMD::REPL_QB(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::REPLV_PH(uint64 instruction) +std::string NMD::REPLV_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12527,7 +12531,7 @@ std::string NMD::REPLV_PH(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::REPLV_QB(uint64 instruction) +std::string NMD::REPLV_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12549,7 +12553,7 @@ std::string NMD::REPLV_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::RESTORE_32_(uint64 instruction) +std::string NMD::RESTORE_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 count_value = extract_count_19_18_17_16(instruction); @@ -12572,7 +12576,7 @@ std::string NMD::RESTORE_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::RESTORE_JRC_16_(uint64 instruction) +std::string NMD::RESTORE_JRC_16_(uint64 instruction, Dis_info *info) { uint64 rt1_value = extract_rtl_11(instruction); uint64 u_value = extract_u_7_6_5_4__s4(instruction); @@ -12594,7 +12598,7 @@ std::string NMD::RESTORE_JRC_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::RESTORE_JRC_32_(uint64 instruction) +std::string NMD::RESTORE_JRC_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 count_value = extract_count_19_18_17_16(instruction); @@ -12617,7 +12621,7 @@ std::string NMD::RESTORE_JRC_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::RESTOREF(uint64 instruction) +std::string NMD::RESTOREF(uint64 instruction, Dis_info *info) { uint64 count_value = extract_count_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3__s3(instruction); @@ -12639,7 +12643,7 @@ std::string NMD::RESTOREF(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::RINT_D(uint64 instruction) +std::string NMD::RINT_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -12661,7 +12665,7 @@ std::string NMD::RINT_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::RINT_S(uint64 instruction) +std::string NMD::RINT_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -12683,7 +12687,7 @@ std::string NMD::RINT_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ROTR(uint64 instruction) +std::string NMD::ROTR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12707,7 +12711,7 @@ std::string NMD::ROTR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ROTRV(uint64 instruction) +std::string NMD::ROTRV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12731,7 +12735,7 @@ std::string NMD::ROTRV(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ROTX(uint64 instruction) +std::string NMD::ROTX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12760,7 +12764,7 @@ std::string NMD::ROTX(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ROUND_L_D(uint64 instruction) +std::string NMD::ROUND_L_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -12782,7 +12786,7 @@ std::string NMD::ROUND_L_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ROUND_L_S(uint64 instruction) +std::string NMD::ROUND_L_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -12804,7 +12808,7 @@ std::string NMD::ROUND_L_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ROUND_W_D(uint64 instruction) +std::string NMD::ROUND_W_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -12826,7 +12830,7 @@ std::string NMD::ROUND_W_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ROUND_W_S(uint64 instruction) +std::string NMD::ROUND_W_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -12848,7 +12852,7 @@ std::string NMD::ROUND_W_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::RSQRT_D(uint64 instruction) +std::string NMD::RSQRT_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -12870,7 +12874,7 @@ std::string NMD::RSQRT_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::RSQRT_S(uint64 instruction) +std::string NMD::RSQRT_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -12892,7 +12896,7 @@ std::string NMD::RSQRT_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SAVE_16_(uint64 instruction) +std::string NMD::SAVE_16_(uint64 instruction, Dis_info *info) { uint64 rt1_value = extract_rtl_11(instruction); uint64 u_value = extract_u_7_6_5_4__s4(instruction); @@ -12914,7 +12918,7 @@ std::string NMD::SAVE_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SAVE_32_(uint64 instruction) +std::string NMD::SAVE_32_(uint64 instruction, Dis_info *info) { uint64 count_value = extract_count_19_18_17_16(instruction); uint64 rt_value = extract_rt_25_24_23_22_21(instruction); @@ -12937,7 +12941,7 @@ std::string NMD::SAVE_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SAVEF(uint64 instruction) +std::string NMD::SAVEF(uint64 instruction, Dis_info *info) { uint64 count_value = extract_count_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3__s3(instruction); @@ -12959,7 +12963,7 @@ std::string NMD::SAVEF(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SB_16_(uint64 instruction) +std::string NMD::SB_16_(uint64 instruction, Dis_info *info) { uint64 rtz3_value = extract_rtz3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -12983,7 +12987,7 @@ std::string NMD::SB_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SB_GP_(uint64 instruction) +std::string NMD::SB_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_0(instruction); @@ -13005,7 +13009,7 @@ std::string NMD::SB_GP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SB_S9_(uint64 instruction) +std::string NMD::SB_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13029,7 +13033,7 @@ std::string NMD::SB_S9_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SB_U12_(uint64 instruction) +std::string NMD::SB_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13053,7 +13057,7 @@ std::string NMD::SB_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SBE(uint64 instruction) +std::string NMD::SBE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13077,7 +13081,7 @@ std::string NMD::SBE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SBX(uint64 instruction) +std::string NMD::SBX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13101,7 +13105,7 @@ std::string NMD::SBX(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SC(uint64 instruction) +std::string NMD::SC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13125,7 +13129,7 @@ std::string NMD::SC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SCD(uint64 instruction) +std::string NMD::SCD(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13149,7 +13153,7 @@ std::string NMD::SCD(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SCDP(uint64 instruction) +std::string NMD::SCDP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13173,7 +13177,7 @@ std::string NMD::SCDP(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SCE(uint64 instruction) +std::string NMD::SCE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13197,7 +13201,7 @@ std::string NMD::SCE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SCWP(uint64 instruction) +std::string NMD::SCWP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13221,7 +13225,7 @@ std::string NMD::SCWP(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SCWPE(uint64 instruction) +std::string NMD::SCWPE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13245,7 +13249,7 @@ std::string NMD::SCWPE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SD_GP_(uint64 instruction) +std::string NMD::SD_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_to_3__s3(instruction); @@ -13267,7 +13271,7 @@ std::string NMD::SD_GP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SD_S9_(uint64 instruction) +std::string NMD::SD_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13291,7 +13295,7 @@ std::string NMD::SD_S9_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SD_U12_(uint64 instruction) +std::string NMD::SD_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13315,7 +13319,7 @@ std::string NMD::SD_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SDBBP_16_(uint64 instruction) +std::string NMD::SDBBP_16_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_2_1_0(instruction); @@ -13335,7 +13339,7 @@ std::string NMD::SDBBP_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SDBBP_32_(uint64 instruction) +std::string NMD::SDBBP_32_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_18_to_0(instruction); @@ -13355,7 +13359,7 @@ std::string NMD::SDBBP_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SDC1_GP_(uint64 instruction) +std::string NMD::SDC1_GP_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_2__s2(instruction); @@ -13377,7 +13381,7 @@ std::string NMD::SDC1_GP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SDC1_S9_(uint64 instruction) +std::string NMD::SDC1_S9_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13401,7 +13405,7 @@ std::string NMD::SDC1_S9_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SDC1_U12_(uint64 instruction) +std::string NMD::SDC1_U12_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13425,7 +13429,7 @@ std::string NMD::SDC1_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SDC1X(uint64 instruction) +std::string NMD::SDC1X(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13449,7 +13453,7 @@ std::string NMD::SDC1X(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SDC1XS(uint64 instruction) +std::string NMD::SDC1XS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13473,7 +13477,7 @@ std::string NMD::SDC1XS(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SDC2(uint64 instruction) +std::string NMD::SDC2(uint64 instruction, Dis_info *info) { uint64 cs_value = extract_cs_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13497,7 +13501,7 @@ std::string NMD::SDC2(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SDM(uint64 instruction) +std::string NMD::SDM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13523,13 +13527,13 @@ std::string NMD::SDM(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SDPC_48_(uint64 instruction) +std::string NMD::SDPC_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); std::string rt = GPR(copy(rt_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 6); + std::string s = ADDRESS(encode_s_from_address(s_value), 6, info); return img_format("SDPC %s, %s", rt, s); } @@ -13545,7 +13549,7 @@ std::string NMD::SDPC_48_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SDXS(uint64 instruction) +std::string NMD::SDXS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13569,7 +13573,7 @@ std::string NMD::SDXS(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SDX(uint64 instruction) +std::string NMD::SDX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13593,7 +13597,7 @@ std::string NMD::SDX(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SEB(uint64 instruction) +std::string NMD::SEB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13615,7 +13619,7 @@ std::string NMD::SEB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SEH(uint64 instruction) +std::string NMD::SEH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13637,7 +13641,7 @@ std::string NMD::SEH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SEL_D(uint64 instruction) +std::string NMD::SEL_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -13661,7 +13665,7 @@ std::string NMD::SEL_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SEL_S(uint64 instruction) +std::string NMD::SEL_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -13685,7 +13689,7 @@ std::string NMD::SEL_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SELEQZ_D(uint64 instruction) +std::string NMD::SELEQZ_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -13709,7 +13713,7 @@ std::string NMD::SELEQZ_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SELEQZ_S(uint64 instruction) +std::string NMD::SELEQZ_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -13733,7 +13737,7 @@ std::string NMD::SELEQZ_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SELNEZ_D(uint64 instruction) +std::string NMD::SELNEZ_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -13757,7 +13761,7 @@ std::string NMD::SELNEZ_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SELNEZ_S(uint64 instruction) +std::string NMD::SELNEZ_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -13781,7 +13785,7 @@ std::string NMD::SELNEZ_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SEQI(uint64 instruction) +std::string NMD::SEQI(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13805,7 +13809,7 @@ std::string NMD::SEQI(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SH_16_(uint64 instruction) +std::string NMD::SH_16_(uint64 instruction, Dis_info *info) { uint64 rtz3_value = extract_rtz3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -13829,7 +13833,7 @@ std::string NMD::SH_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SH_GP_(uint64 instruction) +std::string NMD::SH_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_1__s1(instruction); @@ -13851,7 +13855,7 @@ std::string NMD::SH_GP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SH_S9_(uint64 instruction) +std::string NMD::SH_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13875,7 +13879,7 @@ std::string NMD::SH_S9_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SH_U12_(uint64 instruction) +std::string NMD::SH_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13899,7 +13903,7 @@ std::string NMD::SH_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHE(uint64 instruction) +std::string NMD::SHE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13923,7 +13927,7 @@ std::string NMD::SHE(uint64 instruction) * shift ------ * ac -- */ -std::string NMD::SHILO(uint64 instruction) +std::string NMD::SHILO(uint64 instruction, Dis_info *info) { int64 shift_value = extract_shift__se5_21_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); @@ -13945,7 +13949,7 @@ std::string NMD::SHILO(uint64 instruction) * rs ----- * ac -- */ -std::string NMD::SHILOV(uint64 instruction) +std::string NMD::SHILOV(uint64 instruction, Dis_info *info) { uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); @@ -13967,7 +13971,7 @@ std::string NMD::SHILOV(uint64 instruction) * rs ----- * sa ---- */ -std::string NMD::SHLL_PH(uint64 instruction) +std::string NMD::SHLL_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13991,7 +13995,7 @@ std::string NMD::SHLL_PH(uint64 instruction) * rs ----- * sa --- */ -std::string NMD::SHLL_QB(uint64 instruction) +std::string NMD::SHLL_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14016,7 +14020,7 @@ std::string NMD::SHLL_QB(uint64 instruction) * rs ----- * sa ---- */ -std::string NMD::SHLL_S_PH(uint64 instruction) +std::string NMD::SHLL_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14040,7 +14044,7 @@ std::string NMD::SHLL_S_PH(uint64 instruction) * rs ----- * sa ----- */ -std::string NMD::SHLL_S_W(uint64 instruction) +std::string NMD::SHLL_S_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14065,7 +14069,7 @@ std::string NMD::SHLL_S_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHLLV_PH(uint64 instruction) +std::string NMD::SHLLV_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14089,7 +14093,7 @@ std::string NMD::SHLLV_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHLLV_QB(uint64 instruction) +std::string NMD::SHLLV_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14114,7 +14118,7 @@ std::string NMD::SHLLV_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHLLV_S_PH(uint64 instruction) +std::string NMD::SHLLV_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14138,7 +14142,7 @@ std::string NMD::SHLLV_S_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHLLV_S_W(uint64 instruction) +std::string NMD::SHLLV_S_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14162,7 +14166,7 @@ std::string NMD::SHLLV_S_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHRA_PH(uint64 instruction) +std::string NMD::SHRA_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14186,7 +14190,7 @@ std::string NMD::SHRA_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHRA_QB(uint64 instruction) +std::string NMD::SHRA_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14210,7 +14214,7 @@ std::string NMD::SHRA_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHRA_R_PH(uint64 instruction) +std::string NMD::SHRA_R_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14234,7 +14238,7 @@ std::string NMD::SHRA_R_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHRA_R_QB(uint64 instruction) +std::string NMD::SHRA_R_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14258,7 +14262,7 @@ std::string NMD::SHRA_R_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHRA_R_W(uint64 instruction) +std::string NMD::SHRA_R_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14282,7 +14286,7 @@ std::string NMD::SHRA_R_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHRAV_PH(uint64 instruction) +std::string NMD::SHRAV_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14306,7 +14310,7 @@ std::string NMD::SHRAV_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHRAV_QB(uint64 instruction) +std::string NMD::SHRAV_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14330,7 +14334,7 @@ std::string NMD::SHRAV_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHRAV_R_PH(uint64 instruction) +std::string NMD::SHRAV_R_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14354,7 +14358,7 @@ std::string NMD::SHRAV_R_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHRAV_R_QB(uint64 instruction) +std::string NMD::SHRAV_R_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14378,7 +14382,7 @@ std::string NMD::SHRAV_R_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHRAV_R_W(uint64 instruction) +std::string NMD::SHRAV_R_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14402,7 +14406,7 @@ std::string NMD::SHRAV_R_W(uint64 instruction) * rs ----- * sa ---- */ -std::string NMD::SHRL_PH(uint64 instruction) +std::string NMD::SHRL_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14426,7 +14430,7 @@ std::string NMD::SHRL_PH(uint64 instruction) * rs ----- * sa --- */ -std::string NMD::SHRL_QB(uint64 instruction) +std::string NMD::SHRL_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14451,7 +14455,7 @@ std::string NMD::SHRL_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHRLV_PH(uint64 instruction) +std::string NMD::SHRLV_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14475,7 +14479,7 @@ std::string NMD::SHRLV_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHRLV_QB(uint64 instruction) +std::string NMD::SHRLV_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14499,7 +14503,7 @@ std::string NMD::SHRLV_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHX(uint64 instruction) +std::string NMD::SHX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14523,7 +14527,7 @@ std::string NMD::SHX(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHXS(uint64 instruction) +std::string NMD::SHXS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14547,7 +14551,7 @@ std::string NMD::SHXS(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SIGRIE(uint64 instruction) +std::string NMD::SIGRIE(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_18_to_0(instruction); @@ -14567,7 +14571,7 @@ std::string NMD::SIGRIE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SLL_16_(uint64 instruction) +std::string NMD::SLL_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -14591,7 +14595,7 @@ std::string NMD::SLL_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SLL_32_(uint64 instruction) +std::string NMD::SLL_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14615,7 +14619,7 @@ std::string NMD::SLL_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SLLV(uint64 instruction) +std::string NMD::SLLV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14639,7 +14643,7 @@ std::string NMD::SLLV(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SLT(uint64 instruction) +std::string NMD::SLT(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14663,7 +14667,7 @@ std::string NMD::SLT(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SLTI(uint64 instruction) +std::string NMD::SLTI(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14687,7 +14691,7 @@ std::string NMD::SLTI(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SLTIU(uint64 instruction) +std::string NMD::SLTIU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14711,7 +14715,7 @@ std::string NMD::SLTIU(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SLTU(uint64 instruction) +std::string NMD::SLTU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14735,7 +14739,7 @@ std::string NMD::SLTU(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SOV(uint64 instruction) +std::string NMD::SOV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14759,7 +14763,7 @@ std::string NMD::SOV(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SPECIAL2(uint64 instruction) +std::string NMD::SPECIAL2(uint64 instruction, Dis_info *info) { uint64 op_value = extract_op_25_to_3(instruction); @@ -14779,7 +14783,7 @@ std::string NMD::SPECIAL2(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SQRT_D(uint64 instruction) +std::string NMD::SQRT_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -14801,7 +14805,7 @@ std::string NMD::SQRT_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SQRT_S(uint64 instruction) +std::string NMD::SQRT_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -14823,7 +14827,7 @@ std::string NMD::SQRT_S(uint64 instruction) * rd ----- * sa ----- */ -std::string NMD::SRA(uint64 instruction) +std::string NMD::SRA(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14847,7 +14851,7 @@ std::string NMD::SRA(uint64 instruction) * rt ----- * rd ----- */ -std::string NMD::SRAV(uint64 instruction) +std::string NMD::SRAV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14871,7 +14875,7 @@ std::string NMD::SRAV(uint64 instruction) * rt ----- * rd ----- */ -std::string NMD::SRL_16_(uint64 instruction) +std::string NMD::SRL_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -14895,7 +14899,7 @@ std::string NMD::SRL_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SRL_32_(uint64 instruction) +std::string NMD::SRL_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14919,7 +14923,7 @@ std::string NMD::SRL_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SRLV(uint64 instruction) +std::string NMD::SRLV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14943,7 +14947,7 @@ std::string NMD::SRLV(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUB(uint64 instruction) +std::string NMD::SUB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14967,7 +14971,7 @@ std::string NMD::SUB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUB_D(uint64 instruction) +std::string NMD::SUB_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -14991,7 +14995,7 @@ std::string NMD::SUB_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUB_S(uint64 instruction) +std::string NMD::SUB_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -15015,7 +15019,7 @@ std::string NMD::SUB_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUBQ_PH(uint64 instruction) +std::string NMD::SUBQ_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15040,7 +15044,7 @@ std::string NMD::SUBQ_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUBQ_S_PH(uint64 instruction) +std::string NMD::SUBQ_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15065,7 +15069,7 @@ std::string NMD::SUBQ_S_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUBQ_S_W(uint64 instruction) +std::string NMD::SUBQ_S_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15090,7 +15094,7 @@ std::string NMD::SUBQ_S_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUBQH_PH(uint64 instruction) +std::string NMD::SUBQH_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15115,7 +15119,7 @@ std::string NMD::SUBQH_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUBQH_R_PH(uint64 instruction) +std::string NMD::SUBQH_R_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15140,7 +15144,7 @@ std::string NMD::SUBQH_R_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUBQH_R_W(uint64 instruction) +std::string NMD::SUBQH_R_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15165,7 +15169,7 @@ std::string NMD::SUBQH_R_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUBQH_W(uint64 instruction) +std::string NMD::SUBQH_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15189,7 +15193,7 @@ std::string NMD::SUBQH_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUBU_16_(uint64 instruction) +std::string NMD::SUBU_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -15213,7 +15217,7 @@ std::string NMD::SUBU_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUBU_32_(uint64 instruction) +std::string NMD::SUBU_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15237,7 +15241,7 @@ std::string NMD::SUBU_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUBU_PH(uint64 instruction) +std::string NMD::SUBU_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15261,7 +15265,7 @@ std::string NMD::SUBU_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUBU_QB(uint64 instruction) +std::string NMD::SUBU_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15286,7 +15290,7 @@ std::string NMD::SUBU_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUBU_S_PH(uint64 instruction) +std::string NMD::SUBU_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15311,7 +15315,7 @@ std::string NMD::SUBU_S_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUBU_S_QB(uint64 instruction) +std::string NMD::SUBU_S_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15336,7 +15340,7 @@ std::string NMD::SUBU_S_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUBUH_QB(uint64 instruction) +std::string NMD::SUBUH_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15361,7 +15365,7 @@ std::string NMD::SUBUH_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUBUH_R_QB(uint64 instruction) +std::string NMD::SUBUH_R_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15385,7 +15389,7 @@ std::string NMD::SUBUH_R_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SW_16_(uint64 instruction) +std::string NMD::SW_16_(uint64 instruction, Dis_info *info) { uint64 rtz3_value = extract_rtz3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -15409,7 +15413,7 @@ std::string NMD::SW_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SW_4X4_(uint64 instruction) +std::string NMD::SW_4X4_(uint64 instruction, Dis_info *info) { uint64 rtz4_value = extract_rtz4_9_7_6_5(instruction); uint64 rs4_value = extract_rs4_4_2_1_0(instruction); @@ -15433,7 +15437,7 @@ std::string NMD::SW_4X4_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SW_GP16_(uint64 instruction) +std::string NMD::SW_GP16_(uint64 instruction, Dis_info *info) { uint64 u_value = extract_u_6_5_4_3_2_1_0__s2(instruction); uint64 rtz3_value = extract_rtz3_9_8_7(instruction); @@ -15455,7 +15459,7 @@ std::string NMD::SW_GP16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SW_GP_(uint64 instruction) +std::string NMD::SW_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_to_2__s2(instruction); @@ -15477,7 +15481,7 @@ std::string NMD::SW_GP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SW_S9_(uint64 instruction) +std::string NMD::SW_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); @@ -15501,7 +15505,7 @@ std::string NMD::SW_S9_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SW_SP_(uint64 instruction) +std::string NMD::SW_SP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_9_8_7_6_5(instruction); uint64 u_value = extract_u_4_3_2_1_0__s2(instruction); @@ -15523,7 +15527,7 @@ std::string NMD::SW_SP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SW_U12_(uint64 instruction) +std::string NMD::SW_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15547,7 +15551,7 @@ std::string NMD::SW_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SWC1_GP_(uint64 instruction) +std::string NMD::SWC1_GP_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_2__s2(instruction); @@ -15569,7 +15573,7 @@ std::string NMD::SWC1_GP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SWC1_S9_(uint64 instruction) +std::string NMD::SWC1_S9_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15593,7 +15597,7 @@ std::string NMD::SWC1_S9_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SWC1_U12_(uint64 instruction) +std::string NMD::SWC1_U12_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15617,7 +15621,7 @@ std::string NMD::SWC1_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SWC1X(uint64 instruction) +std::string NMD::SWC1X(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15641,7 +15645,7 @@ std::string NMD::SWC1X(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SWC1XS(uint64 instruction) +std::string NMD::SWC1XS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15665,7 +15669,7 @@ std::string NMD::SWC1XS(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SWC2(uint64 instruction) +std::string NMD::SWC2(uint64 instruction, Dis_info *info) { uint64 cs_value = extract_cs_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15689,7 +15693,7 @@ std::string NMD::SWC2(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SWE(uint64 instruction) +std::string NMD::SWE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15713,7 +15717,7 @@ std::string NMD::SWE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SWM(uint64 instruction) +std::string NMD::SWM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15739,13 +15743,13 @@ std::string NMD::SWM(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SWPC_48_(uint64 instruction) +std::string NMD::SWPC_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); std::string rt = GPR(copy(rt_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 6); + std::string s = ADDRESS(encode_s_from_address(s_value), 6, info); return img_format("SWPC %s, %s", rt, s); } @@ -15761,7 +15765,7 @@ std::string NMD::SWPC_48_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SWX(uint64 instruction) +std::string NMD::SWX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15785,7 +15789,7 @@ std::string NMD::SWX(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SWXS(uint64 instruction) +std::string NMD::SWXS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15809,7 +15813,7 @@ std::string NMD::SWXS(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SYNC(uint64 instruction) +std::string NMD::SYNC(uint64 instruction, Dis_info *info) { uint64 stype_value = extract_stype_20_19_18_17_16(instruction); @@ -15829,7 +15833,7 @@ std::string NMD::SYNC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SYNCI(uint64 instruction) +std::string NMD::SYNCI(uint64 instruction, Dis_info *info) { uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); @@ -15851,7 +15855,7 @@ std::string NMD::SYNCI(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SYNCIE(uint64 instruction) +std::string NMD::SYNCIE(uint64 instruction, Dis_info *info) { uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); @@ -15873,7 +15877,7 @@ std::string NMD::SYNCIE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SYSCALL_16_(uint64 instruction) +std::string NMD::SYSCALL_16_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_1_0(instruction); @@ -15891,7 +15895,7 @@ std::string NMD::SYSCALL_16_(uint64 instruction) * 00000000000010 * code ------------------ */ -std::string NMD::SYSCALL_32_(uint64 instruction) +std::string NMD::SYSCALL_32_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_17_to_0(instruction); @@ -15911,7 +15915,7 @@ std::string NMD::SYSCALL_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TEQ(uint64 instruction) +std::string NMD::TEQ(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15933,7 +15937,7 @@ std::string NMD::TEQ(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TLBGINV(uint64 instruction) +std::string NMD::TLBGINV(uint64 instruction, Dis_info *info) { (void)instruction; @@ -15951,7 +15955,7 @@ std::string NMD::TLBGINV(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TLBGINVF(uint64 instruction) +std::string NMD::TLBGINVF(uint64 instruction, Dis_info *info) { (void)instruction; @@ -15969,7 +15973,7 @@ std::string NMD::TLBGINVF(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TLBGP(uint64 instruction) +std::string NMD::TLBGP(uint64 instruction, Dis_info *info) { (void)instruction; @@ -15987,7 +15991,7 @@ std::string NMD::TLBGP(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TLBGR(uint64 instruction) +std::string NMD::TLBGR(uint64 instruction, Dis_info *info) { (void)instruction; @@ -16005,7 +16009,7 @@ std::string NMD::TLBGR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TLBGWI(uint64 instruction) +std::string NMD::TLBGWI(uint64 instruction, Dis_info *info) { (void)instruction; @@ -16023,7 +16027,7 @@ std::string NMD::TLBGWI(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TLBGWR(uint64 instruction) +std::string NMD::TLBGWR(uint64 instruction, Dis_info *info) { (void)instruction; @@ -16041,7 +16045,7 @@ std::string NMD::TLBGWR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TLBINV(uint64 instruction) +std::string NMD::TLBINV(uint64 instruction, Dis_info *info) { (void)instruction; @@ -16059,7 +16063,7 @@ std::string NMD::TLBINV(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TLBINVF(uint64 instruction) +std::string NMD::TLBINVF(uint64 instruction, Dis_info *info) { (void)instruction; @@ -16077,7 +16081,7 @@ std::string NMD::TLBINVF(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TLBP(uint64 instruction) +std::string NMD::TLBP(uint64 instruction, Dis_info *info) { (void)instruction; @@ -16095,7 +16099,7 @@ std::string NMD::TLBP(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TLBR(uint64 instruction) +std::string NMD::TLBR(uint64 instruction, Dis_info *info) { (void)instruction; @@ -16113,7 +16117,7 @@ std::string NMD::TLBR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TLBWI(uint64 instruction) +std::string NMD::TLBWI(uint64 instruction, Dis_info *info) { (void)instruction; @@ -16131,7 +16135,7 @@ std::string NMD::TLBWI(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TLBWR(uint64 instruction) +std::string NMD::TLBWR(uint64 instruction, Dis_info *info) { (void)instruction; @@ -16149,7 +16153,7 @@ std::string NMD::TLBWR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TNE(uint64 instruction) +std::string NMD::TNE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -16171,7 +16175,7 @@ std::string NMD::TNE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TRUNC_L_D(uint64 instruction) +std::string NMD::TRUNC_L_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -16193,7 +16197,7 @@ std::string NMD::TRUNC_L_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TRUNC_L_S(uint64 instruction) +std::string NMD::TRUNC_L_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -16215,7 +16219,7 @@ std::string NMD::TRUNC_L_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TRUNC_W_D(uint64 instruction) +std::string NMD::TRUNC_W_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -16237,7 +16241,7 @@ std::string NMD::TRUNC_W_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TRUNC_W_S(uint64 instruction) +std::string NMD::TRUNC_W_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -16259,7 +16263,7 @@ std::string NMD::TRUNC_W_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::UALDM(uint64 instruction) +std::string NMD::UALDM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -16285,7 +16289,7 @@ std::string NMD::UALDM(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::UALH(uint64 instruction) +std::string NMD::UALH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -16309,7 +16313,7 @@ std::string NMD::UALH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::UALWM(uint64 instruction) +std::string NMD::UALWM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -16335,7 +16339,7 @@ std::string NMD::UALWM(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::UASDM(uint64 instruction) +std::string NMD::UASDM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -16361,7 +16365,7 @@ std::string NMD::UASDM(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::UASH(uint64 instruction) +std::string NMD::UASH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -16385,7 +16389,7 @@ std::string NMD::UASH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::UASWM(uint64 instruction) +std::string NMD::UASWM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -16411,7 +16415,7 @@ std::string NMD::UASWM(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::UDI(uint64 instruction) +std::string NMD::UDI(uint64 instruction, Dis_info *info) { uint64 op_value = extract_op_25_to_3(instruction); @@ -16429,7 +16433,7 @@ std::string NMD::UDI(uint64 instruction) * 001000 1100001101111111 * code ---------- */ -std::string NMD::WAIT(uint64 instruction) +std::string NMD::WAIT(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_25_24_23_22_21_20_19_18_17_16(instruction); @@ -16449,7 +16453,7 @@ std::string NMD::WAIT(uint64 instruction) * rt ----- * mask ------- */ -std::string NMD::WRDSP(uint64 instruction) +std::string NMD::WRDSP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 mask_value = extract_mask_20_19_18_17_16_15_14(instruction); @@ -16471,7 +16475,7 @@ std::string NMD::WRDSP(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::WRPGPR(uint64 instruction) +std::string NMD::WRPGPR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -16493,7 +16497,7 @@ std::string NMD::WRPGPR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::XOR_16_(uint64 instruction) +std::string NMD::XOR_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -16515,7 +16519,7 @@ std::string NMD::XOR_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::XOR_32_(uint64 instruction) +std::string NMD::XOR_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -16539,7 +16543,7 @@ std::string NMD::XOR_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::XORI(uint64 instruction) +std::string NMD::XORI(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -16562,7 +16566,7 @@ std::string NMD::XORI(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::YIELD(uint64 instruction) +std::string NMD::YIELD(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); diff --git a/disas/nanomips.h b/disas/nanomips.h index 5bdfe1e30b..fcd41c405c 100644 --- a/disas/nanomips.h +++ b/disas/nanomips.h @@ -60,24 +60,21 @@ enum TABLE_ATTRIBUTE_TYPE { ALL_ATTRIBUTES = 0xffffffffull, }; +typedef struct Dis_info { + img_address m_pc; +} Dis_info; class NMD { public: - NMD(img_address pc) - : m_pc(pc) - { - } - int Disassemble(const uint16 *data, std::string & dis, - TABLE_ENTRY_TYPE & type); + TABLE_ENTRY_TYPE & type, Dis_info *info); private: - img_address m_pc; - - typedef std::string(NMD:: *disassembly_function)(uint64 instruction); + typedef std::string(NMD:: *disassembly_function)(uint64 instruction, + Dis_info *info); typedef bool(NMD:: *conditional_function)(uint64 instruction); struct Pool { @@ -94,7 +91,8 @@ private: uint64 extract_op_code_value(const uint16 *data, int size); int Disassemble(const uint16 *data, std::string & dis, - TABLE_ENTRY_TYPE & type, const Pool *table, int table_size); + TABLE_ENTRY_TYPE & type, const Pool *table, int table_size, + Dis_info *info); uint64 renumber_registers(uint64 index, uint64 *register_list, size_t register_list_size); @@ -135,7 +133,7 @@ private: std::string IMMEDIATE(uint64 value); std::string IMMEDIATE(int64 value); std::string CPR(uint64 reg); - std::string ADDRESS(uint64 value, int instruction_size); + std::string ADDRESS(uint64 value, int instruction_size, Dis_info *info); int64 extract_s__se3_4_2_1_0(uint64 instruction); int64 extract_s__se7_0_6_5_4_3_2_1_s1(uint64 instruction); @@ -251,642 +249,642 @@ private: bool PREFE_cond(uint64 instruction); bool SLTU_cond(uint64 instruction); - std::string ABS_D(uint64 instruction); - std::string ABS_S(uint64 instruction); - std::string ABSQ_S_PH(uint64 instruction); - std::string ABSQ_S_QB(uint64 instruction); - std::string ABSQ_S_W(uint64 instruction); - std::string ACLR(uint64 instruction); - std::string ADD(uint64 instruction); - std::string ADD_D(uint64 instruction); - std::string ADD_S(uint64 instruction); - std::string ADDIU_32_(uint64 instruction); - std::string ADDIU_48_(uint64 instruction); - std::string ADDIU_GP48_(uint64 instruction); - std::string ADDIU_GP_B_(uint64 instruction); - std::string ADDIU_GP_W_(uint64 instruction); - std::string ADDIU_NEG_(uint64 instruction); - std::string ADDIU_R1_SP_(uint64 instruction); - std::string ADDIU_R2_(uint64 instruction); - std::string ADDIU_RS5_(uint64 instruction); - std::string ADDIUPC_32_(uint64 instruction); - std::string ADDIUPC_48_(uint64 instruction); - std::string ADDQ_PH(uint64 instruction); - std::string ADDQ_S_PH(uint64 instruction); - std::string ADDQ_S_W(uint64 instruction); - std::string ADDQH_PH(uint64 instruction); - std::string ADDQH_R_PH(uint64 instruction); - std::string ADDQH_R_W(uint64 instruction); - std::string ADDQH_W(uint64 instruction); - std::string ADDSC(uint64 instruction); - std::string ADDU_16_(uint64 instruction); - std::string ADDU_32_(uint64 instruction); - std::string ADDU_4X4_(uint64 instruction); - std::string ADDU_PH(uint64 instruction); - std::string ADDU_QB(uint64 instruction); - std::string ADDU_S_PH(uint64 instruction); - std::string ADDU_S_QB(uint64 instruction); - std::string ADDUH_QB(uint64 instruction); - std::string ADDUH_R_QB(uint64 instruction); - std::string ADDWC(uint64 instruction); - std::string ALUIPC(uint64 instruction); - std::string AND_16_(uint64 instruction); - std::string AND_32_(uint64 instruction); - std::string ANDI_16_(uint64 instruction); - std::string ANDI_32_(uint64 instruction); - std::string APPEND(uint64 instruction); - std::string ASET(uint64 instruction); - std::string BALC_16_(uint64 instruction); - std::string BALC_32_(uint64 instruction); - std::string BALRSC(uint64 instruction); - std::string BBEQZC(uint64 instruction); - std::string BBNEZC(uint64 instruction); - std::string BC_16_(uint64 instruction); - std::string BC_32_(uint64 instruction); - std::string BC1EQZC(uint64 instruction); - std::string BC1NEZC(uint64 instruction); - std::string BC2EQZC(uint64 instruction); - std::string BC2NEZC(uint64 instruction); - std::string BEQC_16_(uint64 instruction); - std::string BEQC_32_(uint64 instruction); - std::string BEQIC(uint64 instruction); - std::string BEQZC_16_(uint64 instruction); - std::string BGEC(uint64 instruction); - std::string BGEIC(uint64 instruction); - std::string BGEIUC(uint64 instruction); - std::string BGEUC(uint64 instruction); - std::string BLTC(uint64 instruction); - std::string BLTIC(uint64 instruction); - std::string BLTIUC(uint64 instruction); - std::string BLTUC(uint64 instruction); - std::string BNEC_16_(uint64 instruction); - std::string BNEC_32_(uint64 instruction); - std::string BNEIC(uint64 instruction); - std::string BNEZC_16_(uint64 instruction); - std::string BPOSGE32C(uint64 instruction); - std::string BREAK_16_(uint64 instruction); - std::string BREAK_32_(uint64 instruction); - std::string BRSC(uint64 instruction); - std::string CACHE(uint64 instruction); - std::string CACHEE(uint64 instruction); - std::string CEIL_L_D(uint64 instruction); - std::string CEIL_L_S(uint64 instruction); - std::string CEIL_W_D(uint64 instruction); - std::string CEIL_W_S(uint64 instruction); - std::string CFC1(uint64 instruction); - std::string CFC2(uint64 instruction); - std::string CLASS_D(uint64 instruction); - std::string CLASS_S(uint64 instruction); - std::string CLO(uint64 instruction); - std::string CLZ(uint64 instruction); - std::string CMP_AF_D(uint64 instruction); - std::string CMP_AF_S(uint64 instruction); - std::string CMP_EQ_D(uint64 instruction); - std::string CMP_EQ_PH(uint64 instruction); - std::string CMP_EQ_S(uint64 instruction); - std::string CMP_LE_D(uint64 instruction); - std::string CMP_LE_PH(uint64 instruction); - std::string CMP_LE_S(uint64 instruction); - std::string CMP_LT_D(uint64 instruction); - std::string CMP_LT_PH(uint64 instruction); - std::string CMP_LT_S(uint64 instruction); - std::string CMP_NE_D(uint64 instruction); - std::string CMP_NE_S(uint64 instruction); - std::string CMP_OR_D(uint64 instruction); - std::string CMP_OR_S(uint64 instruction); - std::string CMP_SAF_D(uint64 instruction); - std::string CMP_SAF_S(uint64 instruction); - std::string CMP_SEQ_D(uint64 instruction); - std::string CMP_SEQ_S(uint64 instruction); - std::string CMP_SLE_D(uint64 instruction); - std::string CMP_SLE_S(uint64 instruction); - std::string CMP_SLT_D(uint64 instruction); - std::string CMP_SLT_S(uint64 instruction); - std::string CMP_SNE_D(uint64 instruction); - std::string CMP_SNE_S(uint64 instruction); - std::string CMP_SOR_D(uint64 instruction); - std::string CMP_SOR_S(uint64 instruction); - std::string CMP_SUEQ_D(uint64 instruction); - std::string CMP_SUEQ_S(uint64 instruction); - std::string CMP_SULE_D(uint64 instruction); - std::string CMP_SULE_S(uint64 instruction); - std::string CMP_SULT_D(uint64 instruction); - std::string CMP_SULT_S(uint64 instruction); - std::string CMP_SUN_D(uint64 instruction); - std::string CMP_SUN_S(uint64 instruction); - std::string CMP_SUNE_D(uint64 instruction); - std::string CMP_SUNE_S(uint64 instruction); - std::string CMP_UEQ_D(uint64 instruction); - std::string CMP_UEQ_S(uint64 instruction); - std::string CMP_ULE_D(uint64 instruction); - std::string CMP_ULE_S(uint64 instruction); - std::string CMP_ULT_D(uint64 instruction); - std::string CMP_ULT_S(uint64 instruction); - std::string CMP_UN_D(uint64 instruction); - std::string CMP_UN_S(uint64 instruction); - std::string CMP_UNE_D(uint64 instruction); - std::string CMP_UNE_S(uint64 instruction); - std::string CMPGDU_EQ_QB(uint64 instruction); - std::string CMPGDU_LE_QB(uint64 instruction); - std::string CMPGDU_LT_QB(uint64 instruction); - std::string CMPGU_EQ_QB(uint64 instruction); - std::string CMPGU_LE_QB(uint64 instruction); - std::string CMPGU_LT_QB(uint64 instruction); - std::string CMPU_EQ_QB(uint64 instruction); - std::string CMPU_LE_QB(uint64 instruction); - std::string CMPU_LT_QB(uint64 instruction); - std::string COP2_1(uint64 instruction); - std::string CTC1(uint64 instruction); - std::string CTC2(uint64 instruction); - std::string CVT_D_L(uint64 instruction); - std::string CVT_D_S(uint64 instruction); - std::string CVT_D_W(uint64 instruction); - std::string CVT_L_D(uint64 instruction); - std::string CVT_L_S(uint64 instruction); - std::string CVT_S_D(uint64 instruction); - std::string CVT_S_L(uint64 instruction); - std::string CVT_S_PL(uint64 instruction); - std::string CVT_S_PU(uint64 instruction); - std::string CVT_S_W(uint64 instruction); - std::string CVT_W_D(uint64 instruction); - std::string CVT_W_S(uint64 instruction); - std::string DADDIU_48_(uint64 instruction); - std::string DADDIU_NEG_(uint64 instruction); - std::string DADDIU_U12_(uint64 instruction); - std::string DADD(uint64 instruction); - std::string DADDU(uint64 instruction); - std::string DCLO(uint64 instruction); - std::string DCLZ(uint64 instruction); - std::string DDIV(uint64 instruction); - std::string DDIVU(uint64 instruction); - std::string DERET(uint64 instruction); - std::string DEXTM(uint64 instruction); - std::string DEXT(uint64 instruction); - std::string DEXTU(uint64 instruction); - std::string DINSM(uint64 instruction); - std::string DINS(uint64 instruction); - std::string DINSU(uint64 instruction); - std::string DI(uint64 instruction); - std::string DIV(uint64 instruction); - std::string DIV_D(uint64 instruction); - std::string DIV_S(uint64 instruction); - std::string DIVU(uint64 instruction); - std::string DLSA(uint64 instruction); - std::string DLUI_48_(uint64 instruction); - std::string DMFC0(uint64 instruction); - std::string DMFC1(uint64 instruction); - std::string DMFC2(uint64 instruction); - std::string DMFGC0(uint64 instruction); - std::string DMOD(uint64 instruction); - std::string DMODU(uint64 instruction); - std::string DMTC0(uint64 instruction); - std::string DMTC1(uint64 instruction); - std::string DMTC2(uint64 instruction); - std::string DMTGC0(uint64 instruction); - std::string DMT(uint64 instruction); - std::string DMUH(uint64 instruction); - std::string DMUHU(uint64 instruction); - std::string DMUL(uint64 instruction); - std::string DMULU(uint64 instruction); - std::string DPAQ_S_W_PH(uint64 instruction); - std::string DPAQ_SA_L_W(uint64 instruction); - std::string DPAQX_S_W_PH(uint64 instruction); - std::string DPAQX_SA_W_PH(uint64 instruction); - std::string DPAU_H_QBL(uint64 instruction); - std::string DPAU_H_QBR(uint64 instruction); - std::string DPA_W_PH(uint64 instruction); - std::string DPAX_W_PH(uint64 instruction); - std::string DPS_W_PH(uint64 instruction); - std::string DPSQ_SA_L_W(uint64 instruction); - std::string DPSQ_S_W_PH(uint64 instruction); - std::string DPSQX_SA_W_PH(uint64 instruction); - std::string DPSQX_S_W_PH(uint64 instruction); - std::string DPSU_H_QBL(uint64 instruction); - std::string DPSU_H_QBR(uint64 instruction); - std::string DPSX_W_PH(uint64 instruction); - std::string DROTR(uint64 instruction); - std::string DROTR32(uint64 instruction); - std::string DROTRV(uint64 instruction); - std::string DROTX(uint64 instruction); - std::string DSLL(uint64 instruction); - std::string DSLL32(uint64 instruction); - std::string DSLLV(uint64 instruction); - std::string DSRA(uint64 instruction); - std::string DSRA32(uint64 instruction); - std::string DSRAV(uint64 instruction); - std::string DSRL32(uint64 instruction); - std::string DSRL(uint64 instruction); - std::string DSRLV(uint64 instruction); - std::string DSUB(uint64 instruction); - std::string DSUBU(uint64 instruction); - std::string DVP(uint64 instruction); - std::string DVPE(uint64 instruction); - std::string EHB(uint64 instruction); - std::string EI(uint64 instruction); - std::string EMT(uint64 instruction); - std::string ERET(uint64 instruction); - std::string ERETNC(uint64 instruction); - std::string EVP(uint64 instruction); - std::string EVPE(uint64 instruction); - std::string EXT(uint64 instruction); - std::string EXTD(uint64 instruction); - std::string EXTD32(uint64 instruction); - std::string EXTP(uint64 instruction); - std::string EXTPDP(uint64 instruction); - std::string EXTPDPV(uint64 instruction); - std::string EXTPV(uint64 instruction); - std::string EXTR_RS_W(uint64 instruction); - std::string EXTR_R_W(uint64 instruction); - std::string EXTR_S_H(uint64 instruction); - std::string EXTR_W(uint64 instruction); - std::string EXTRV_R_W(uint64 instruction); - std::string EXTRV_RS_W(uint64 instruction); - std::string EXTRV_S_H(uint64 instruction); - std::string EXTRV_W(uint64 instruction); - std::string EXTW(uint64 instruction); - std::string FLOOR_L_D(uint64 instruction); - std::string FLOOR_L_S(uint64 instruction); - std::string FLOOR_W_D(uint64 instruction); - std::string FLOOR_W_S(uint64 instruction); - std::string FORK(uint64 instruction); - std::string HYPCALL(uint64 instruction); - std::string HYPCALL_16_(uint64 instruction); - std::string INS(uint64 instruction); - std::string INSV(uint64 instruction); - std::string IRET(uint64 instruction); - std::string JALRC_16_(uint64 instruction); - std::string JALRC_32_(uint64 instruction); - std::string JALRC_HB(uint64 instruction); - std::string JRC(uint64 instruction); - std::string LB_16_(uint64 instruction); - std::string LB_GP_(uint64 instruction); - std::string LB_S9_(uint64 instruction); - std::string LB_U12_(uint64 instruction); - std::string LBE(uint64 instruction); - std::string LBU_16_(uint64 instruction); - std::string LBU_GP_(uint64 instruction); - std::string LBU_S9_(uint64 instruction); - std::string LBU_U12_(uint64 instruction); - std::string LBUE(uint64 instruction); - std::string LBUX(uint64 instruction); - std::string LBX(uint64 instruction); - std::string LD_GP_(uint64 instruction); - std::string LD_S9_(uint64 instruction); - std::string LD_U12_(uint64 instruction); - std::string LDC1_GP_(uint64 instruction); - std::string LDC1_S9_(uint64 instruction); - std::string LDC1_U12_(uint64 instruction); - std::string LDC1X(uint64 instruction); - std::string LDC1XS(uint64 instruction); - std::string LDC2(uint64 instruction); - std::string LDM(uint64 instruction); - std::string LDPC_48_(uint64 instruction); - std::string LDX(uint64 instruction); - std::string LDXS(uint64 instruction); - std::string LH_16_(uint64 instruction); - std::string LH_GP_(uint64 instruction); - std::string LH_S9_(uint64 instruction); - std::string LH_U12_(uint64 instruction); - std::string LHE(uint64 instruction); - std::string LHU_16_(uint64 instruction); - std::string LHU_GP_(uint64 instruction); - std::string LHU_S9_(uint64 instruction); - std::string LHU_U12_(uint64 instruction); - std::string LHUE(uint64 instruction); - std::string LHUX(uint64 instruction); - std::string LHUXS(uint64 instruction); - std::string LHX(uint64 instruction); - std::string LHXS(uint64 instruction); - std::string LI_16_(uint64 instruction); - std::string LI_48_(uint64 instruction); - std::string LL(uint64 instruction); - std::string LLD(uint64 instruction); - std::string LLDP(uint64 instruction); - std::string LLE(uint64 instruction); - std::string LLWP(uint64 instruction); - std::string LLWPE(uint64 instruction); - std::string LSA(uint64 instruction); - std::string LUI(uint64 instruction); - std::string LW_16_(uint64 instruction); - std::string LW_4X4_(uint64 instruction); - std::string LWC1_GP_(uint64 instruction); - std::string LWC1_S9_(uint64 instruction); - std::string LWC1_U12_(uint64 instruction); - std::string LWC1X(uint64 instruction); - std::string LWC1XS(uint64 instruction); - std::string LWC2(uint64 instruction); - std::string LWE(uint64 instruction); - std::string LW_GP_(uint64 instruction); - std::string LW_GP16_(uint64 instruction); - std::string LWM(uint64 instruction); - std::string LWPC_48_(uint64 instruction); - std::string LW_S9_(uint64 instruction); - std::string LW_SP_(uint64 instruction); - std::string LW_U12_(uint64 instruction); - std::string LWU_GP_(uint64 instruction); - std::string LWU_S9_(uint64 instruction); - std::string LWU_U12_(uint64 instruction); - std::string LWUX(uint64 instruction); - std::string LWUXS(uint64 instruction); - std::string LWX(uint64 instruction); - std::string LWXS_16_(uint64 instruction); - std::string LWXS_32_(uint64 instruction); - std::string MADD_DSP_(uint64 instruction); - std::string MADDF_D(uint64 instruction); - std::string MADDF_S(uint64 instruction); - std::string MADDU_DSP_(uint64 instruction); - std::string MAQ_S_W_PHL(uint64 instruction); - std::string MAQ_S_W_PHR(uint64 instruction); - std::string MAQ_SA_W_PHL(uint64 instruction); - std::string MAQ_SA_W_PHR(uint64 instruction); - std::string MAX_D(uint64 instruction); - std::string MAX_S(uint64 instruction); - std::string MAXA_D(uint64 instruction); - std::string MAXA_S(uint64 instruction); - std::string MFC0(uint64 instruction); - std::string MFC1(uint64 instruction); - std::string MFC2(uint64 instruction); - std::string MFGC0(uint64 instruction); - std::string MFHC0(uint64 instruction); - std::string MFHC1(uint64 instruction); - std::string MFHC2(uint64 instruction); - std::string MFHGC0(uint64 instruction); - std::string MFHI_DSP_(uint64 instruction); - std::string MFHTR(uint64 instruction); - std::string MFLO_DSP_(uint64 instruction); - std::string MFTR(uint64 instruction); - std::string MIN_D(uint64 instruction); - std::string MIN_S(uint64 instruction); - std::string MINA_D(uint64 instruction); - std::string MINA_S(uint64 instruction); - std::string MOD(uint64 instruction); - std::string MODSUB(uint64 instruction); - std::string MODU(uint64 instruction); - std::string MOV_D(uint64 instruction); - std::string MOV_S(uint64 instruction); - std::string MOVE_BALC(uint64 instruction); - std::string MOVEP(uint64 instruction); - std::string MOVEP_REV_(uint64 instruction); - std::string MOVE(uint64 instruction); - std::string MOVN(uint64 instruction); - std::string MOVZ(uint64 instruction); - std::string MSUB_DSP_(uint64 instruction); - std::string MSUBF_D(uint64 instruction); - std::string MSUBF_S(uint64 instruction); - std::string MSUBU_DSP_(uint64 instruction); - std::string MTC0(uint64 instruction); - std::string MTC1(uint64 instruction); - std::string MTC2(uint64 instruction); - std::string MTGC0(uint64 instruction); - std::string MTHC0(uint64 instruction); - std::string MTHC1(uint64 instruction); - std::string MTHC2(uint64 instruction); - std::string MTHGC0(uint64 instruction); - std::string MTHI_DSP_(uint64 instruction); - std::string MTHLIP(uint64 instruction); - std::string MTHTR(uint64 instruction); - std::string MTLO_DSP_(uint64 instruction); - std::string MTTR(uint64 instruction); - std::string MUH(uint64 instruction); - std::string MUHU(uint64 instruction); - std::string MUL_32_(uint64 instruction); - std::string MUL_4X4_(uint64 instruction); - std::string MUL_D(uint64 instruction); - std::string MUL_PH(uint64 instruction); - std::string MUL_S(uint64 instruction); - std::string MUL_S_PH(uint64 instruction); - std::string MULEQ_S_W_PHL(uint64 instruction); - std::string MULEQ_S_W_PHR(uint64 instruction); - std::string MULEU_S_PH_QBL(uint64 instruction); - std::string MULEU_S_PH_QBR(uint64 instruction); - std::string MULQ_RS_PH(uint64 instruction); - std::string MULQ_RS_W(uint64 instruction); - std::string MULQ_S_PH(uint64 instruction); - std::string MULQ_S_W(uint64 instruction); - std::string MULSA_W_PH(uint64 instruction); - std::string MULSAQ_S_W_PH(uint64 instruction); - std::string MULT_DSP_(uint64 instruction); - std::string MULTU_DSP_(uint64 instruction); - std::string MULU(uint64 instruction); - std::string NEG_D(uint64 instruction); - std::string NEG_S(uint64 instruction); - std::string NOP_16_(uint64 instruction); - std::string NOP_32_(uint64 instruction); - std::string NOR(uint64 instruction); - std::string NOT_16_(uint64 instruction); - std::string OR_16_(uint64 instruction); - std::string OR_32_(uint64 instruction); - std::string ORI(uint64 instruction); - std::string PACKRL_PH(uint64 instruction); - std::string PAUSE(uint64 instruction); - std::string PICK_PH(uint64 instruction); - std::string PICK_QB(uint64 instruction); - std::string PRECEQ_W_PHL(uint64 instruction); - std::string PRECEQ_W_PHR(uint64 instruction); - std::string PRECEQU_PH_QBL(uint64 instruction); - std::string PRECEQU_PH_QBLA(uint64 instruction); - std::string PRECEQU_PH_QBR(uint64 instruction); - std::string PRECEQU_PH_QBRA(uint64 instruction); - std::string PRECEU_PH_QBL(uint64 instruction); - std::string PRECEU_PH_QBLA(uint64 instruction); - std::string PRECEU_PH_QBR(uint64 instruction); - std::string PRECEU_PH_QBRA(uint64 instruction); - std::string PRECR_QB_PH(uint64 instruction); - std::string PRECR_SRA_PH_W(uint64 instruction); - std::string PRECR_SRA_R_PH_W(uint64 instruction); - std::string PRECRQ_PH_W(uint64 instruction); - std::string PRECRQ_QB_PH(uint64 instruction); - std::string PRECRQ_RS_PH_W(uint64 instruction); - std::string PRECRQU_S_QB_PH(uint64 instruction); - std::string PREF_S9_(uint64 instruction); - std::string PREF_U12_(uint64 instruction); - std::string PREFE(uint64 instruction); - std::string PREPEND(uint64 instruction); - std::string RADDU_W_QB(uint64 instruction); - std::string RDDSP(uint64 instruction); - std::string RDHWR(uint64 instruction); - std::string RDPGPR(uint64 instruction); - std::string RECIP_D(uint64 instruction); - std::string RECIP_S(uint64 instruction); - std::string REPL_PH(uint64 instruction); - std::string REPL_QB(uint64 instruction); - std::string REPLV_PH(uint64 instruction); - std::string REPLV_QB(uint64 instruction); - std::string RESTORE_32_(uint64 instruction); - std::string RESTORE_JRC_16_(uint64 instruction); - std::string RESTORE_JRC_32_(uint64 instruction); - std::string RESTOREF(uint64 instruction); - std::string RINT_D(uint64 instruction); - std::string RINT_S(uint64 instruction); - std::string ROTR(uint64 instruction); - std::string ROTRV(uint64 instruction); - std::string ROTX(uint64 instruction); - std::string ROUND_L_D(uint64 instruction); - std::string ROUND_L_S(uint64 instruction); - std::string ROUND_W_D(uint64 instruction); - std::string ROUND_W_S(uint64 instruction); - std::string RSQRT_D(uint64 instruction); - std::string RSQRT_S(uint64 instruction); - std::string SAVE_16_(uint64 instruction); - std::string SAVE_32_(uint64 instruction); - std::string SAVEF(uint64 instruction); - std::string SB_16_(uint64 instruction); - std::string SB_GP_(uint64 instruction); - std::string SB_S9_(uint64 instruction); - std::string SB_U12_(uint64 instruction); - std::string SBE(uint64 instruction); - std::string SBX(uint64 instruction); - std::string SC(uint64 instruction); - std::string SCD(uint64 instruction); - std::string SCDP(uint64 instruction); - std::string SCE(uint64 instruction); - std::string SCWP(uint64 instruction); - std::string SCWPE(uint64 instruction); - std::string SD_GP_(uint64 instruction); - std::string SD_S9_(uint64 instruction); - std::string SD_U12_(uint64 instruction); - std::string SDBBP_16_(uint64 instruction); - std::string SDBBP_32_(uint64 instruction); - std::string SDC1_GP_(uint64 instruction); - std::string SDC1_S9_(uint64 instruction); - std::string SDC1_U12_(uint64 instruction); - std::string SDC1X(uint64 instruction); - std::string SDC1XS(uint64 instruction); - std::string SDC2(uint64 instruction); - std::string SDM(uint64 instruction); - std::string SDPC_48_(uint64 instruction); - std::string SDX(uint64 instruction); - std::string SDXS(uint64 instruction); - std::string SEB(uint64 instruction); - std::string SEH(uint64 instruction); - std::string SEL_D(uint64 instruction); - std::string SEL_S(uint64 instruction); - std::string SELEQZ_D(uint64 instruction); - std::string SELEQZ_S(uint64 instruction); - std::string SELNEZ_D(uint64 instruction); - std::string SELNEZ_S(uint64 instruction); - std::string SEQI(uint64 instruction); - std::string SH_16_(uint64 instruction); - std::string SH_GP_(uint64 instruction); - std::string SH_S9_(uint64 instruction); - std::string SH_U12_(uint64 instruction); - std::string SHE(uint64 instruction); - std::string SHILO(uint64 instruction); - std::string SHILOV(uint64 instruction); - std::string SHLL_PH(uint64 instruction); - std::string SHLL_QB(uint64 instruction); - std::string SHLL_S_PH(uint64 instruction); - std::string SHLL_S_W(uint64 instruction); - std::string SHLLV_PH(uint64 instruction); - std::string SHLLV_QB(uint64 instruction); - std::string SHLLV_S_PH(uint64 instruction); - std::string SHLLV_S_W(uint64 instruction); - std::string SHRA_PH(uint64 instruction); - std::string SHRA_QB(uint64 instruction); - std::string SHRA_R_PH(uint64 instruction); - std::string SHRA_R_QB(uint64 instruction); - std::string SHRA_R_W(uint64 instruction); - std::string SHRAV_PH(uint64 instruction); - std::string SHRAV_QB(uint64 instruction); - std::string SHRAV_R_PH(uint64 instruction); - std::string SHRAV_R_QB(uint64 instruction); - std::string SHRAV_R_W(uint64 instruction); - std::string SHRL_PH(uint64 instruction); - std::string SHRL_QB(uint64 instruction); - std::string SHRLV_PH(uint64 instruction); - std::string SHRLV_QB(uint64 instruction); - std::string SHX(uint64 instruction); - std::string SHXS(uint64 instruction); - std::string SIGRIE(uint64 instruction); - std::string SLL_16_(uint64 instruction); - std::string SLL_32_(uint64 instruction); - std::string SLLV(uint64 instruction); - std::string SLT(uint64 instruction); - std::string SLTI(uint64 instruction); - std::string SLTIU(uint64 instruction); - std::string SLTU(uint64 instruction); - std::string SOV(uint64 instruction); - std::string SPECIAL2(uint64 instruction); - std::string SQRT_D(uint64 instruction); - std::string SQRT_S(uint64 instruction); - std::string SRA(uint64 instruction); - std::string SRAV(uint64 instruction); - std::string SRL_16_(uint64 instruction); - std::string SRL_32_(uint64 instruction); - std::string SRLV(uint64 instruction); - std::string SUB(uint64 instruction); - std::string SUB_D(uint64 instruction); - std::string SUB_S(uint64 instruction); - std::string SUBQ_PH(uint64 instruction); - std::string SUBQ_S_PH(uint64 instruction); - std::string SUBQ_S_W(uint64 instruction); - std::string SUBQH_PH(uint64 instruction); - std::string SUBQH_R_PH(uint64 instruction); - std::string SUBQH_R_W(uint64 instruction); - std::string SUBQH_W(uint64 instruction); - std::string SUBU_16_(uint64 instruction); - std::string SUBU_32_(uint64 instruction); - std::string SUBU_PH(uint64 instruction); - std::string SUBU_QB(uint64 instruction); - std::string SUBU_S_PH(uint64 instruction); - std::string SUBU_S_QB(uint64 instruction); - std::string SUBUH_QB(uint64 instruction); - std::string SUBUH_R_QB(uint64 instruction); - std::string SW_16_(uint64 instruction); - std::string SW_4X4_(uint64 instruction); - std::string SW_GP16_(uint64 instruction); - std::string SW_GP_(uint64 instruction); - std::string SW_S9_(uint64 instruction); - std::string SW_SP_(uint64 instruction); - std::string SW_U12_(uint64 instruction); - std::string SWC1_GP_(uint64 instruction); - std::string SWC1_S9_(uint64 instruction); - std::string SWC1_U12_(uint64 instruction); - std::string SWC1X(uint64 instruction); - std::string SWC1XS(uint64 instruction); - std::string SWC2(uint64 instruction); - std::string SWE(uint64 instruction); - std::string SWM(uint64 instruction); - std::string SWPC_48_(uint64 instruction); - std::string SWX(uint64 instruction); - std::string SWXS(uint64 instruction); - std::string SYNC(uint64 instruction); - std::string SYNCI(uint64 instruction); - std::string SYNCIE(uint64 instruction); - std::string SYSCALL_16_(uint64 instruction); - std::string SYSCALL_32_(uint64 instruction); - std::string TEQ(uint64 instruction); - std::string TLBGINV(uint64 instruction); - std::string TLBGINVF(uint64 instruction); - std::string TLBGP(uint64 instruction); - std::string TLBGR(uint64 instruction); - std::string TLBGWI(uint64 instruction); - std::string TLBGWR(uint64 instruction); - std::string TLBINV(uint64 instruction); - std::string TLBINVF(uint64 instruction); - std::string TLBP(uint64 instruction); - std::string TLBR(uint64 instruction); - std::string TLBWI(uint64 instruction); - std::string TLBWR(uint64 instruction); - std::string TNE(uint64 instruction); - std::string TRUNC_L_D(uint64 instruction); - std::string TRUNC_L_S(uint64 instruction); - std::string TRUNC_W_D(uint64 instruction); - std::string TRUNC_W_S(uint64 instruction); - std::string UALDM(uint64 instruction); - std::string UALH(uint64 instruction); - std::string UALWM(uint64 instruction); - std::string UASDM(uint64 instruction); - std::string UASH(uint64 instruction); - std::string UASWM(uint64 instruction); - std::string UDI(uint64 instruction); - std::string WAIT(uint64 instruction); - std::string WRDSP(uint64 instruction); - std::string WRPGPR(uint64 instruction); - std::string XOR_16_(uint64 instruction); - std::string XOR_32_(uint64 instruction); - std::string XORI(uint64 instruction); - std::string YIELD(uint64 instruction); + std::string ABS_D(uint64 instruction, Dis_info *info); + std::string ABS_S(uint64 instruction, Dis_info *info); + std::string ABSQ_S_PH(uint64 instruction, Dis_info *info); + std::string ABSQ_S_QB(uint64 instruction, Dis_info *info); + std::string ABSQ_S_W(uint64 instruction, Dis_info *info); + std::string ACLR(uint64 instruction, Dis_info *info); + std::string ADD(uint64 instruction, Dis_info *info); + std::string ADD_D(uint64 instruction, Dis_info *info); + std::string ADD_S(uint64 instruction, Dis_info *info); + std::string ADDIU_32_(uint64 instruction, Dis_info *info); + std::string ADDIU_48_(uint64 instruction, Dis_info *info); + std::string ADDIU_GP48_(uint64 instruction, Dis_info *info); + std::string ADDIU_GP_B_(uint64 instruction, Dis_info *info); + std::string ADDIU_GP_W_(uint64 instruction, Dis_info *info); + std::string ADDIU_NEG_(uint64 instruction, Dis_info *info); + std::string ADDIU_R1_SP_(uint64 instruction, Dis_info *info); + std::string ADDIU_R2_(uint64 instruction, Dis_info *info); + std::string ADDIU_RS5_(uint64 instruction, Dis_info *info); + std::string ADDIUPC_32_(uint64 instruction, Dis_info *info); + std::string ADDIUPC_48_(uint64 instruction, Dis_info *info); + std::string ADDQ_PH(uint64 instruction, Dis_info *info); + std::string ADDQ_S_PH(uint64 instruction, Dis_info *info); + std::string ADDQ_S_W(uint64 instruction, Dis_info *info); + std::string ADDQH_PH(uint64 instruction, Dis_info *info); + std::string ADDQH_R_PH(uint64 instruction, Dis_info *info); + std::string ADDQH_R_W(uint64 instruction, Dis_info *info); + std::string ADDQH_W(uint64 instruction, Dis_info *info); + std::string ADDSC(uint64 instruction, Dis_info *info); + std::string ADDU_16_(uint64 instruction, Dis_info *info); + std::string ADDU_32_(uint64 instruction, Dis_info *info); + std::string ADDU_4X4_(uint64 instruction, Dis_info *info); + std::string ADDU_PH(uint64 instruction, Dis_info *info); + std::string ADDU_QB(uint64 instruction, Dis_info *info); + std::string ADDU_S_PH(uint64 instruction, Dis_info *info); + std::string ADDU_S_QB(uint64 instruction, Dis_info *info); + std::string ADDUH_QB(uint64 instruction, Dis_info *info); + std::string ADDUH_R_QB(uint64 instruction, Dis_info *info); + std::string ADDWC(uint64 instruction, Dis_info *info); + std::string ALUIPC(uint64 instruction, Dis_info *info); + std::string AND_16_(uint64 instruction, Dis_info *info); + std::string AND_32_(uint64 instruction, Dis_info *info); + std::string ANDI_16_(uint64 instruction, Dis_info *info); + std::string ANDI_32_(uint64 instruction, Dis_info *info); + std::string APPEND(uint64 instruction, Dis_info *info); + std::string ASET(uint64 instruction, Dis_info *info); + std::string BALC_16_(uint64 instruction, Dis_info *info); + std::string BALC_32_(uint64 instruction, Dis_info *info); + std::string BALRSC(uint64 instruction, Dis_info *info); + std::string BBEQZC(uint64 instruction, Dis_info *info); + std::string BBNEZC(uint64 instruction, Dis_info *info); + std::string BC_16_(uint64 instruction, Dis_info *info); + std::string BC_32_(uint64 instruction, Dis_info *info); + std::string BC1EQZC(uint64 instruction, Dis_info *info); + std::string BC1NEZC(uint64 instruction, Dis_info *info); + std::string BC2EQZC(uint64 instruction, Dis_info *info); + std::string BC2NEZC(uint64 instruction, Dis_info *info); + std::string BEQC_16_(uint64 instruction, Dis_info *info); + std::string BEQC_32_(uint64 instruction, Dis_info *info); + std::string BEQIC(uint64 instruction, Dis_info *info); + std::string BEQZC_16_(uint64 instruction, Dis_info *info); + std::string BGEC(uint64 instruction, Dis_info *info); + std::string BGEIC(uint64 instruction, Dis_info *info); + std::string BGEIUC(uint64 instruction, Dis_info *info); + std::string BGEUC(uint64 instruction, Dis_info *info); + std::string BLTC(uint64 instruction, Dis_info *info); + std::string BLTIC(uint64 instruction, Dis_info *info); + std::string BLTIUC(uint64 instruction, Dis_info *info); + std::string BLTUC(uint64 instruction, Dis_info *info); + std::string BNEC_16_(uint64 instruction, Dis_info *info); + std::string BNEC_32_(uint64 instruction, Dis_info *info); + std::string BNEIC(uint64 instruction, Dis_info *info); + std::string BNEZC_16_(uint64 instruction, Dis_info *info); + std::string BPOSGE32C(uint64 instruction, Dis_info *info); + std::string BREAK_16_(uint64 instruction, Dis_info *info); + std::string BREAK_32_(uint64 instruction, Dis_info *info); + std::string BRSC(uint64 instruction, Dis_info *info); + std::string CACHE(uint64 instruction, Dis_info *info); + std::string CACHEE(uint64 instruction, Dis_info *info); + std::string CEIL_L_D(uint64 instruction, Dis_info *info); + std::string CEIL_L_S(uint64 instruction, Dis_info *info); + std::string CEIL_W_D(uint64 instruction, Dis_info *info); + std::string CEIL_W_S(uint64 instruction, Dis_info *info); + std::string CFC1(uint64 instruction, Dis_info *info); + std::string CFC2(uint64 instruction, Dis_info *info); + std::string CLASS_D(uint64 instruction, Dis_info *info); + std::string CLASS_S(uint64 instruction, Dis_info *info); + std::string CLO(uint64 instruction, Dis_info *info); + std::string CLZ(uint64 instruction, Dis_info *info); + std::string CMP_AF_D(uint64 instruction, Dis_info *info); + std::string CMP_AF_S(uint64 instruction, Dis_info *info); + std::string CMP_EQ_D(uint64 instruction, Dis_info *info); + std::string CMP_EQ_PH(uint64 instruction, Dis_info *info); + std::string CMP_EQ_S(uint64 instruction, Dis_info *info); + std::string CMP_LE_D(uint64 instruction, Dis_info *info); + std::string CMP_LE_PH(uint64 instruction, Dis_info *info); + std::string CMP_LE_S(uint64 instruction, Dis_info *info); + std::string CMP_LT_D(uint64 instruction, Dis_info *info); + std::string CMP_LT_PH(uint64 instruction, Dis_info *info); + std::string CMP_LT_S(uint64 instruction, Dis_info *info); + std::string CMP_NE_D(uint64 instruction, Dis_info *info); + std::string CMP_NE_S(uint64 instruction, Dis_info *info); + std::string CMP_OR_D(uint64 instruction, Dis_info *info); + std::string CMP_OR_S(uint64 instruction, Dis_info *info); + std::string CMP_SAF_D(uint64 instruction, Dis_info *info); + std::string CMP_SAF_S(uint64 instruction, Dis_info *info); + std::string CMP_SEQ_D(uint64 instruction, Dis_info *info); + std::string CMP_SEQ_S(uint64 instruction, Dis_info *info); + std::string CMP_SLE_D(uint64 instruction, Dis_info *info); + std::string CMP_SLE_S(uint64 instruction, Dis_info *info); + std::string CMP_SLT_D(uint64 instruction, Dis_info *info); + std::string CMP_SLT_S(uint64 instruction, Dis_info *info); + std::string CMP_SNE_D(uint64 instruction, Dis_info *info); + std::string CMP_SNE_S(uint64 instruction, Dis_info *info); + std::string CMP_SOR_D(uint64 instruction, Dis_info *info); + std::string CMP_SOR_S(uint64 instruction, Dis_info *info); + std::string CMP_SUEQ_D(uint64 instruction, Dis_info *info); + std::string CMP_SUEQ_S(uint64 instruction, Dis_info *info); + std::string CMP_SULE_D(uint64 instruction, Dis_info *info); + std::string CMP_SULE_S(uint64 instruction, Dis_info *info); + std::string CMP_SULT_D(uint64 instruction, Dis_info *info); + std::string CMP_SULT_S(uint64 instruction, Dis_info *info); + std::string CMP_SUN_D(uint64 instruction, Dis_info *info); + std::string CMP_SUN_S(uint64 instruction, Dis_info *info); + std::string CMP_SUNE_D(uint64 instruction, Dis_info *info); + std::string CMP_SUNE_S(uint64 instruction, Dis_info *info); + std::string CMP_UEQ_D(uint64 instruction, Dis_info *info); + std::string CMP_UEQ_S(uint64 instruction, Dis_info *info); + std::string CMP_ULE_D(uint64 instruction, Dis_info *info); + std::string CMP_ULE_S(uint64 instruction, Dis_info *info); + std::string CMP_ULT_D(uint64 instruction, Dis_info *info); + std::string CMP_ULT_S(uint64 instruction, Dis_info *info); + std::string CMP_UN_D(uint64 instruction, Dis_info *info); + std::string CMP_UN_S(uint64 instruction, Dis_info *info); + std::string CMP_UNE_D(uint64 instruction, Dis_info *info); + std::string CMP_UNE_S(uint64 instruction, Dis_info *info); + std::string CMPGDU_EQ_QB(uint64 instruction, Dis_info *info); + std::string CMPGDU_LE_QB(uint64 instruction, Dis_info *info); + std::string CMPGDU_LT_QB(uint64 instruction, Dis_info *info); + std::string CMPGU_EQ_QB(uint64 instruction, Dis_info *info); + std::string CMPGU_LE_QB(uint64 instruction, Dis_info *info); + std::string CMPGU_LT_QB(uint64 instruction, Dis_info *info); + std::string CMPU_EQ_QB(uint64 instruction, Dis_info *info); + std::string CMPU_LE_QB(uint64 instruction, Dis_info *info); + std::string CMPU_LT_QB(uint64 instruction, Dis_info *info); + std::string COP2_1(uint64 instruction, Dis_info *info); + std::string CTC1(uint64 instruction, Dis_info *info); + std::string CTC2(uint64 instruction, Dis_info *info); + std::string CVT_D_L(uint64 instruction, Dis_info *info); + std::string CVT_D_S(uint64 instruction, Dis_info *info); + std::string CVT_D_W(uint64 instruction, Dis_info *info); + std::string CVT_L_D(uint64 instruction, Dis_info *info); + std::string CVT_L_S(uint64 instruction, Dis_info *info); + std::string CVT_S_D(uint64 instruction, Dis_info *info); + std::string CVT_S_L(uint64 instruction, Dis_info *info); + std::string CVT_S_PL(uint64 instruction, Dis_info *info); + std::string CVT_S_PU(uint64 instruction, Dis_info *info); + std::string CVT_S_W(uint64 instruction, Dis_info *info); + std::string CVT_W_D(uint64 instruction, Dis_info *info); + std::string CVT_W_S(uint64 instruction, Dis_info *info); + std::string DADDIU_48_(uint64 instruction, Dis_info *info); + std::string DADDIU_NEG_(uint64 instruction, Dis_info *info); + std::string DADDIU_U12_(uint64 instruction, Dis_info *info); + std::string DADD(uint64 instruction, Dis_info *info); + std::string DADDU(uint64 instruction, Dis_info *info); + std::string DCLO(uint64 instruction, Dis_info *info); + std::string DCLZ(uint64 instruction, Dis_info *info); + std::string DDIV(uint64 instruction, Dis_info *info); + std::string DDIVU(uint64 instruction, Dis_info *info); + std::string DERET(uint64 instruction, Dis_info *info); + std::string DEXTM(uint64 instruction, Dis_info *info); + std::string DEXT(uint64 instruction, Dis_info *info); + std::string DEXTU(uint64 instruction, Dis_info *info); + std::string DINSM(uint64 instruction, Dis_info *info); + std::string DINS(uint64 instruction, Dis_info *info); + std::string DINSU(uint64 instruction, Dis_info *info); + std::string DI(uint64 instruction, Dis_info *info); + std::string DIV(uint64 instruction, Dis_info *info); + std::string DIV_D(uint64 instruction, Dis_info *info); + std::string DIV_S(uint64 instruction, Dis_info *info); + std::string DIVU(uint64 instruction, Dis_info *info); + std::string DLSA(uint64 instruction, Dis_info *info); + std::string DLUI_48_(uint64 instruction, Dis_info *info); + std::string DMFC0(uint64 instruction, Dis_info *info); + std::string DMFC1(uint64 instruction, Dis_info *info); + std::string DMFC2(uint64 instruction, Dis_info *info); + std::string DMFGC0(uint64 instruction, Dis_info *info); + std::string DMOD(uint64 instruction, Dis_info *info); + std::string DMODU(uint64 instruction, Dis_info *info); + std::string DMTC0(uint64 instruction, Dis_info *info); + std::string DMTC1(uint64 instruction, Dis_info *info); + std::string DMTC2(uint64 instruction, Dis_info *info); + std::string DMTGC0(uint64 instruction, Dis_info *info); + std::string DMT(uint64 instruction, Dis_info *info); + std::string DMUH(uint64 instruction, Dis_info *info); + std::string DMUHU(uint64 instruction, Dis_info *info); + std::string DMUL(uint64 instruction, Dis_info *info); + std::string DMULU(uint64 instruction, Dis_info *info); + std::string DPAQ_S_W_PH(uint64 instruction, Dis_info *info); + std::string DPAQ_SA_L_W(uint64 instruction, Dis_info *info); + std::string DPAQX_S_W_PH(uint64 instruction, Dis_info *info); + std::string DPAQX_SA_W_PH(uint64 instruction, Dis_info *info); + std::string DPAU_H_QBL(uint64 instruction, Dis_info *info); + std::string DPAU_H_QBR(uint64 instruction, Dis_info *info); + std::string DPA_W_PH(uint64 instruction, Dis_info *info); + std::string DPAX_W_PH(uint64 instruction, Dis_info *info); + std::string DPS_W_PH(uint64 instruction, Dis_info *info); + std::string DPSQ_SA_L_W(uint64 instruction, Dis_info *info); + std::string DPSQ_S_W_PH(uint64 instruction, Dis_info *info); + std::string DPSQX_SA_W_PH(uint64 instruction, Dis_info *info); + std::string DPSQX_S_W_PH(uint64 instruction, Dis_info *info); + std::string DPSU_H_QBL(uint64 instruction, Dis_info *info); + std::string DPSU_H_QBR(uint64 instruction, Dis_info *info); + std::string DPSX_W_PH(uint64 instruction, Dis_info *info); + std::string DROTR(uint64 instruction, Dis_info *info); + std::string DROTR32(uint64 instruction, Dis_info *info); + std::string DROTRV(uint64 instruction, Dis_info *info); + std::string DROTX(uint64 instruction, Dis_info *info); + std::string DSLL(uint64 instruction, Dis_info *info); + std::string DSLL32(uint64 instruction, Dis_info *info); + std::string DSLLV(uint64 instruction, Dis_info *info); + std::string DSRA(uint64 instruction, Dis_info *info); + std::string DSRA32(uint64 instruction, Dis_info *info); + std::string DSRAV(uint64 instruction, Dis_info *info); + std::string DSRL32(uint64 instruction, Dis_info *info); + std::string DSRL(uint64 instruction, Dis_info *info); + std::string DSRLV(uint64 instruction, Dis_info *info); + std::string DSUB(uint64 instruction, Dis_info *info); + std::string DSUBU(uint64 instruction, Dis_info *info); + std::string DVP(uint64 instruction, Dis_info *info); + std::string DVPE(uint64 instruction, Dis_info *info); + std::string EHB(uint64 instruction, Dis_info *info); + std::string EI(uint64 instruction, Dis_info *info); + std::string EMT(uint64 instruction, Dis_info *info); + std::string ERET(uint64 instruction, Dis_info *info); + std::string ERETNC(uint64 instruction, Dis_info *info); + std::string EVP(uint64 instruction, Dis_info *info); + std::string EVPE(uint64 instruction, Dis_info *info); + std::string EXT(uint64 instruction, Dis_info *info); + std::string EXTD(uint64 instruction, Dis_info *info); + std::string EXTD32(uint64 instruction, Dis_info *info); + std::string EXTP(uint64 instruction, Dis_info *info); + std::string EXTPDP(uint64 instruction, Dis_info *info); + std::string EXTPDPV(uint64 instruction, Dis_info *info); + std::string EXTPV(uint64 instruction, Dis_info *info); + std::string EXTR_RS_W(uint64 instruction, Dis_info *info); + std::string EXTR_R_W(uint64 instruction, Dis_info *info); + std::string EXTR_S_H(uint64 instruction, Dis_info *info); + std::string EXTR_W(uint64 instruction, Dis_info *info); + std::string EXTRV_R_W(uint64 instruction, Dis_info *info); + std::string EXTRV_RS_W(uint64 instruction, Dis_info *info); + std::string EXTRV_S_H(uint64 instruction, Dis_info *info); + std::string EXTRV_W(uint64 instruction, Dis_info *info); + std::string EXTW(uint64 instruction, Dis_info *info); + std::string FLOOR_L_D(uint64 instruction, Dis_info *info); + std::string FLOOR_L_S(uint64 instruction, Dis_info *info); + std::string FLOOR_W_D(uint64 instruction, Dis_info *info); + std::string FLOOR_W_S(uint64 instruction, Dis_info *info); + std::string FORK(uint64 instruction, Dis_info *info); + std::string HYPCALL(uint64 instruction, Dis_info *info); + std::string HYPCALL_16_(uint64 instruction, Dis_info *info); + std::string INS(uint64 instruction, Dis_info *info); + std::string INSV(uint64 instruction, Dis_info *info); + std::string IRET(uint64 instruction, Dis_info *info); + std::string JALRC_16_(uint64 instruction, Dis_info *info); + std::string JALRC_32_(uint64 instruction, Dis_info *info); + std::string JALRC_HB(uint64 instruction, Dis_info *info); + std::string JRC(uint64 instruction, Dis_info *info); + std::string LB_16_(uint64 instruction, Dis_info *info); + std::string LB_GP_(uint64 instruction, Dis_info *info); + std::string LB_S9_(uint64 instruction, Dis_info *info); + std::string LB_U12_(uint64 instruction, Dis_info *info); + std::string LBE(uint64 instruction, Dis_info *info); + std::string LBU_16_(uint64 instruction, Dis_info *info); + std::string LBU_GP_(uint64 instruction, Dis_info *info); + std::string LBU_S9_(uint64 instruction, Dis_info *info); + std::string LBU_U12_(uint64 instruction, Dis_info *info); + std::string LBUE(uint64 instruction, Dis_info *info); + std::string LBUX(uint64 instruction, Dis_info *info); + std::string LBX(uint64 instruction, Dis_info *info); + std::string LD_GP_(uint64 instruction, Dis_info *info); + std::string LD_S9_(uint64 instruction, Dis_info *info); + std::string LD_U12_(uint64 instruction, Dis_info *info); + std::string LDC1_GP_(uint64 instruction, Dis_info *info); + std::string LDC1_S9_(uint64 instruction, Dis_info *info); + std::string LDC1_U12_(uint64 instruction, Dis_info *info); + std::string LDC1X(uint64 instruction, Dis_info *info); + std::string LDC1XS(uint64 instruction, Dis_info *info); + std::string LDC2(uint64 instruction, Dis_info *info); + std::string LDM(uint64 instruction, Dis_info *info); + std::string LDPC_48_(uint64 instruction, Dis_info *info); + std::string LDX(uint64 instruction, Dis_info *info); + std::string LDXS(uint64 instruction, Dis_info *info); + std::string LH_16_(uint64 instruction, Dis_info *info); + std::string LH_GP_(uint64 instruction, Dis_info *info); + std::string LH_S9_(uint64 instruction, Dis_info *info); + std::string LH_U12_(uint64 instruction, Dis_info *info); + std::string LHE(uint64 instruction, Dis_info *info); + std::string LHU_16_(uint64 instruction, Dis_info *info); + std::string LHU_GP_(uint64 instruction, Dis_info *info); + std::string LHU_S9_(uint64 instruction, Dis_info *info); + std::string LHU_U12_(uint64 instruction, Dis_info *info); + std::string LHUE(uint64 instruction, Dis_info *info); + std::string LHUX(uint64 instruction, Dis_info *info); + std::string LHUXS(uint64 instruction, Dis_info *info); + std::string LHX(uint64 instruction, Dis_info *info); + std::string LHXS(uint64 instruction, Dis_info *info); + std::string LI_16_(uint64 instruction, Dis_info *info); + std::string LI_48_(uint64 instruction, Dis_info *info); + std::string LL(uint64 instruction, Dis_info *info); + std::string LLD(uint64 instruction, Dis_info *info); + std::string LLDP(uint64 instruction, Dis_info *info); + std::string LLE(uint64 instruction, Dis_info *info); + std::string LLWP(uint64 instruction, Dis_info *info); + std::string LLWPE(uint64 instruction, Dis_info *info); + std::string LSA(uint64 instruction, Dis_info *info); + std::string LUI(uint64 instruction, Dis_info *info); + std::string LW_16_(uint64 instruction, Dis_info *info); + std::string LW_4X4_(uint64 instruction, Dis_info *info); + std::string LWC1_GP_(uint64 instruction, Dis_info *info); + std::string LWC1_S9_(uint64 instruction, Dis_info *info); + std::string LWC1_U12_(uint64 instruction, Dis_info *info); + std::string LWC1X(uint64 instruction, Dis_info *info); + std::string LWC1XS(uint64 instruction, Dis_info *info); + std::string LWC2(uint64 instruction, Dis_info *info); + std::string LWE(uint64 instruction, Dis_info *info); + std::string LW_GP_(uint64 instruction, Dis_info *info); + std::string LW_GP16_(uint64 instruction, Dis_info *info); + std::string LWM(uint64 instruction, Dis_info *info); + std::string LWPC_48_(uint64 instruction, Dis_info *info); + std::string LW_S9_(uint64 instruction, Dis_info *info); + std::string LW_SP_(uint64 instruction, Dis_info *info); + std::string LW_U12_(uint64 instruction, Dis_info *info); + std::string LWU_GP_(uint64 instruction, Dis_info *info); + std::string LWU_S9_(uint64 instruction, Dis_info *info); + std::string LWU_U12_(uint64 instruction, Dis_info *info); + std::string LWUX(uint64 instruction, Dis_info *info); + std::string LWUXS(uint64 instruction, Dis_info *info); + std::string LWX(uint64 instruction, Dis_info *info); + std::string LWXS_16_(uint64 instruction, Dis_info *info); + std::string LWXS_32_(uint64 instruction, Dis_info *info); + std::string MADD_DSP_(uint64 instruction, Dis_info *info); + std::string MADDF_D(uint64 instruction, Dis_info *info); + std::string MADDF_S(uint64 instruction, Dis_info *info); + std::string MADDU_DSP_(uint64 instruction, Dis_info *info); + std::string MAQ_S_W_PHL(uint64 instruction, Dis_info *info); + std::string MAQ_S_W_PHR(uint64 instruction, Dis_info *info); + std::string MAQ_SA_W_PHL(uint64 instruction, Dis_info *info); + std::string MAQ_SA_W_PHR(uint64 instruction, Dis_info *info); + std::string MAX_D(uint64 instruction, Dis_info *info); + std::string MAX_S(uint64 instruction, Dis_info *info); + std::string MAXA_D(uint64 instruction, Dis_info *info); + std::string MAXA_S(uint64 instruction, Dis_info *info); + std::string MFC0(uint64 instruction, Dis_info *info); + std::string MFC1(uint64 instruction, Dis_info *info); + std::string MFC2(uint64 instruction, Dis_info *info); + std::string MFGC0(uint64 instruction, Dis_info *info); + std::string MFHC0(uint64 instruction, Dis_info *info); + std::string MFHC1(uint64 instruction, Dis_info *info); + std::string MFHC2(uint64 instruction, Dis_info *info); + std::string MFHGC0(uint64 instruction, Dis_info *info); + std::string MFHI_DSP_(uint64 instruction, Dis_info *info); + std::string MFHTR(uint64 instruction, Dis_info *info); + std::string MFLO_DSP_(uint64 instruction, Dis_info *info); + std::string MFTR(uint64 instruction, Dis_info *info); + std::string MIN_D(uint64 instruction, Dis_info *info); + std::string MIN_S(uint64 instruction, Dis_info *info); + std::string MINA_D(uint64 instruction, Dis_info *info); + std::string MINA_S(uint64 instruction, Dis_info *info); + std::string MOD(uint64 instruction, Dis_info *info); + std::string MODSUB(uint64 instruction, Dis_info *info); + std::string MODU(uint64 instruction, Dis_info *info); + std::string MOV_D(uint64 instruction, Dis_info *info); + std::string MOV_S(uint64 instruction, Dis_info *info); + std::string MOVE_BALC(uint64 instruction, Dis_info *info); + std::string MOVEP(uint64 instruction, Dis_info *info); + std::string MOVEP_REV_(uint64 instruction, Dis_info *info); + std::string MOVE(uint64 instruction, Dis_info *info); + std::string MOVN(uint64 instruction, Dis_info *info); + std::string MOVZ(uint64 instruction, Dis_info *info); + std::string MSUB_DSP_(uint64 instruction, Dis_info *info); + std::string MSUBF_D(uint64 instruction, Dis_info *info); + std::string MSUBF_S(uint64 instruction, Dis_info *info); + std::string MSUBU_DSP_(uint64 instruction, Dis_info *info); + std::string MTC0(uint64 instruction, Dis_info *info); + std::string MTC1(uint64 instruction, Dis_info *info); + std::string MTC2(uint64 instruction, Dis_info *info); + std::string MTGC0(uint64 instruction, Dis_info *info); + std::string MTHC0(uint64 instruction, Dis_info *info); + std::string MTHC1(uint64 instruction, Dis_info *info); + std::string MTHC2(uint64 instruction, Dis_info *info); + std::string MTHGC0(uint64 instruction, Dis_info *info); + std::string MTHI_DSP_(uint64 instruction, Dis_info *info); + std::string MTHLIP(uint64 instruction, Dis_info *info); + std::string MTHTR(uint64 instruction, Dis_info *info); + std::string MTLO_DSP_(uint64 instruction, Dis_info *info); + std::string MTTR(uint64 instruction, Dis_info *info); + std::string MUH(uint64 instruction, Dis_info *info); + std::string MUHU(uint64 instruction, Dis_info *info); + std::string MUL_32_(uint64 instruction, Dis_info *info); + std::string MUL_4X4_(uint64 instruction, Dis_info *info); + std::string MUL_D(uint64 instruction, Dis_info *info); + std::string MUL_PH(uint64 instruction, Dis_info *info); + std::string MUL_S(uint64 instruction, Dis_info *info); + std::string MUL_S_PH(uint64 instruction, Dis_info *info); + std::string MULEQ_S_W_PHL(uint64 instruction, Dis_info *info); + std::string MULEQ_S_W_PHR(uint64 instruction, Dis_info *info); + std::string MULEU_S_PH_QBL(uint64 instruction, Dis_info *info); + std::string MULEU_S_PH_QBR(uint64 instruction, Dis_info *info); + std::string MULQ_RS_PH(uint64 instruction, Dis_info *info); + std::string MULQ_RS_W(uint64 instruction, Dis_info *info); + std::string MULQ_S_PH(uint64 instruction, Dis_info *info); + std::string MULQ_S_W(uint64 instruction, Dis_info *info); + std::string MULSA_W_PH(uint64 instruction, Dis_info *info); + std::string MULSAQ_S_W_PH(uint64 instruction, Dis_info *info); + std::string MULT_DSP_(uint64 instruction, Dis_info *info); + std::string MULTU_DSP_(uint64 instruction, Dis_info *info); + std::string MULU(uint64 instruction, Dis_info *info); + std::string NEG_D(uint64 instruction, Dis_info *info); + std::string NEG_S(uint64 instruction, Dis_info *info); + std::string NOP_16_(uint64 instruction, Dis_info *info); + std::string NOP_32_(uint64 instruction, Dis_info *info); + std::string NOR(uint64 instruction, Dis_info *info); + std::string NOT_16_(uint64 instruction, Dis_info *info); + std::string OR_16_(uint64 instruction, Dis_info *info); + std::string OR_32_(uint64 instruction, Dis_info *info); + std::string ORI(uint64 instruction, Dis_info *info); + std::string PACKRL_PH(uint64 instruction, Dis_info *info); + std::string PAUSE(uint64 instruction, Dis_info *info); + std::string PICK_PH(uint64 instruction, Dis_info *info); + std::string PICK_QB(uint64 instruction, Dis_info *info); + std::string PRECEQ_W_PHL(uint64 instruction, Dis_info *info); + std::string PRECEQ_W_PHR(uint64 instruction, Dis_info *info); + std::string PRECEQU_PH_QBL(uint64 instruction, Dis_info *info); + std::string PRECEQU_PH_QBLA(uint64 instruction, Dis_info *info); + std::string PRECEQU_PH_QBR(uint64 instruction, Dis_info *info); + std::string PRECEQU_PH_QBRA(uint64 instruction, Dis_info *info); + std::string PRECEU_PH_QBL(uint64 instruction, Dis_info *info); + std::string PRECEU_PH_QBLA(uint64 instruction, Dis_info *info); + std::string PRECEU_PH_QBR(uint64 instruction, Dis_info *info); + std::string PRECEU_PH_QBRA(uint64 instruction, Dis_info *info); + std::string PRECR_QB_PH(uint64 instruction, Dis_info *info); + std::string PRECR_SRA_PH_W(uint64 instruction, Dis_info *info); + std::string PRECR_SRA_R_PH_W(uint64 instruction, Dis_info *info); + std::string PRECRQ_PH_W(uint64 instruction, Dis_info *info); + std::string PRECRQ_QB_PH(uint64 instruction, Dis_info *info); + std::string PRECRQ_RS_PH_W(uint64 instruction, Dis_info *info); + std::string PRECRQU_S_QB_PH(uint64 instruction, Dis_info *info); + std::string PREF_S9_(uint64 instruction, Dis_info *info); + std::string PREF_U12_(uint64 instruction, Dis_info *info); + std::string PREFE(uint64 instruction, Dis_info *info); + std::string PREPEND(uint64 instruction, Dis_info *info); + std::string RADDU_W_QB(uint64 instruction, Dis_info *info); + std::string RDDSP(uint64 instruction, Dis_info *info); + std::string RDHWR(uint64 instruction, Dis_info *info); + std::string RDPGPR(uint64 instruction, Dis_info *info); + std::string RECIP_D(uint64 instruction, Dis_info *info); + std::string RECIP_S(uint64 instruction, Dis_info *info); + std::string REPL_PH(uint64 instruction, Dis_info *info); + std::string REPL_QB(uint64 instruction, Dis_info *info); + std::string REPLV_PH(uint64 instruction, Dis_info *info); + std::string REPLV_QB(uint64 instruction, Dis_info *info); + std::string RESTORE_32_(uint64 instruction, Dis_info *info); + std::string RESTORE_JRC_16_(uint64 instruction, Dis_info *info); + std::string RESTORE_JRC_32_(uint64 instruction, Dis_info *info); + std::string RESTOREF(uint64 instruction, Dis_info *info); + std::string RINT_D(uint64 instruction, Dis_info *info); + std::string RINT_S(uint64 instruction, Dis_info *info); + std::string ROTR(uint64 instruction, Dis_info *info); + std::string ROTRV(uint64 instruction, Dis_info *info); + std::string ROTX(uint64 instruction, Dis_info *info); + std::string ROUND_L_D(uint64 instruction, Dis_info *info); + std::string ROUND_L_S(uint64 instruction, Dis_info *info); + std::string ROUND_W_D(uint64 instruction, Dis_info *info); + std::string ROUND_W_S(uint64 instruction, Dis_info *info); + std::string RSQRT_D(uint64 instruction, Dis_info *info); + std::string RSQRT_S(uint64 instruction, Dis_info *info); + std::string SAVE_16_(uint64 instruction, Dis_info *info); + std::string SAVE_32_(uint64 instruction, Dis_info *info); + std::string SAVEF(uint64 instruction, Dis_info *info); + std::string SB_16_(uint64 instruction, Dis_info *info); + std::string SB_GP_(uint64 instruction, Dis_info *info); + std::string SB_S9_(uint64 instruction, Dis_info *info); + std::string SB_U12_(uint64 instruction, Dis_info *info); + std::string SBE(uint64 instruction, Dis_info *info); + std::string SBX(uint64 instruction, Dis_info *info); + std::string SC(uint64 instruction, Dis_info *info); + std::string SCD(uint64 instruction, Dis_info *info); + std::string SCDP(uint64 instruction, Dis_info *info); + std::string SCE(uint64 instruction, Dis_info *info); + std::string SCWP(uint64 instruction, Dis_info *info); + std::string SCWPE(uint64 instruction, Dis_info *info); + std::string SD_GP_(uint64 instruction, Dis_info *info); + std::string SD_S9_(uint64 instruction, Dis_info *info); + std::string SD_U12_(uint64 instruction, Dis_info *info); + std::string SDBBP_16_(uint64 instruction, Dis_info *info); + std::string SDBBP_32_(uint64 instruction, Dis_info *info); + std::string SDC1_GP_(uint64 instruction, Dis_info *info); + std::string SDC1_S9_(uint64 instruction, Dis_info *info); + std::string SDC1_U12_(uint64 instruction, Dis_info *info); + std::string SDC1X(uint64 instruction, Dis_info *info); + std::string SDC1XS(uint64 instruction, Dis_info *info); + std::string SDC2(uint64 instruction, Dis_info *info); + std::string SDM(uint64 instruction, Dis_info *info); + std::string SDPC_48_(uint64 instruction, Dis_info *info); + std::string SDX(uint64 instruction, Dis_info *info); + std::string SDXS(uint64 instruction, Dis_info *info); + std::string SEB(uint64 instruction, Dis_info *info); + std::string SEH(uint64 instruction, Dis_info *info); + std::string SEL_D(uint64 instruction, Dis_info *info); + std::string SEL_S(uint64 instruction, Dis_info *info); + std::string SELEQZ_D(uint64 instruction, Dis_info *info); + std::string SELEQZ_S(uint64 instruction, Dis_info *info); + std::string SELNEZ_D(uint64 instruction, Dis_info *info); + std::string SELNEZ_S(uint64 instruction, Dis_info *info); + std::string SEQI(uint64 instruction, Dis_info *info); + std::string SH_16_(uint64 instruction, Dis_info *info); + std::string SH_GP_(uint64 instruction, Dis_info *info); + std::string SH_S9_(uint64 instruction, Dis_info *info); + std::string SH_U12_(uint64 instruction, Dis_info *info); + std::string SHE(uint64 instruction, Dis_info *info); + std::string SHILO(uint64 instruction, Dis_info *info); + std::string SHILOV(uint64 instruction, Dis_info *info); + std::string SHLL_PH(uint64 instruction, Dis_info *info); + std::string SHLL_QB(uint64 instruction, Dis_info *info); + std::string SHLL_S_PH(uint64 instruction, Dis_info *info); + std::string SHLL_S_W(uint64 instruction, Dis_info *info); + std::string SHLLV_PH(uint64 instruction, Dis_info *info); + std::string SHLLV_QB(uint64 instruction, Dis_info *info); + std::string SHLLV_S_PH(uint64 instruction, Dis_info *info); + std::string SHLLV_S_W(uint64 instruction, Dis_info *info); + std::string SHRA_PH(uint64 instruction, Dis_info *info); + std::string SHRA_QB(uint64 instruction, Dis_info *info); + std::string SHRA_R_PH(uint64 instruction, Dis_info *info); + std::string SHRA_R_QB(uint64 instruction, Dis_info *info); + std::string SHRA_R_W(uint64 instruction, Dis_info *info); + std::string SHRAV_PH(uint64 instruction, Dis_info *info); + std::string SHRAV_QB(uint64 instruction, Dis_info *info); + std::string SHRAV_R_PH(uint64 instruction, Dis_info *info); + std::string SHRAV_R_QB(uint64 instruction, Dis_info *info); + std::string SHRAV_R_W(uint64 instruction, Dis_info *info); + std::string SHRL_PH(uint64 instruction, Dis_info *info); + std::string SHRL_QB(uint64 instruction, Dis_info *info); + std::string SHRLV_PH(uint64 instruction, Dis_info *info); + std::string SHRLV_QB(uint64 instruction, Dis_info *info); + std::string SHX(uint64 instruction, Dis_info *info); + std::string SHXS(uint64 instruction, Dis_info *info); + std::string SIGRIE(uint64 instruction, Dis_info *info); + std::string SLL_16_(uint64 instruction, Dis_info *info); + std::string SLL_32_(uint64 instruction, Dis_info *info); + std::string SLLV(uint64 instruction, Dis_info *info); + std::string SLT(uint64 instruction, Dis_info *info); + std::string SLTI(uint64 instruction, Dis_info *info); + std::string SLTIU(uint64 instruction, Dis_info *info); + std::string SLTU(uint64 instruction, Dis_info *info); + std::string SOV(uint64 instruction, Dis_info *info); + std::string SPECIAL2(uint64 instruction, Dis_info *info); + std::string SQRT_D(uint64 instruction, Dis_info *info); + std::string SQRT_S(uint64 instruction, Dis_info *info); + std::string SRA(uint64 instruction, Dis_info *info); + std::string SRAV(uint64 instruction, Dis_info *info); + std::string SRL_16_(uint64 instruction, Dis_info *info); + std::string SRL_32_(uint64 instruction, Dis_info *info); + std::string SRLV(uint64 instruction, Dis_info *info); + std::string SUB(uint64 instruction, Dis_info *info); + std::string SUB_D(uint64 instruction, Dis_info *info); + std::string SUB_S(uint64 instruction, Dis_info *info); + std::string SUBQ_PH(uint64 instruction, Dis_info *info); + std::string SUBQ_S_PH(uint64 instruction, Dis_info *info); + std::string SUBQ_S_W(uint64 instruction, Dis_info *info); + std::string SUBQH_PH(uint64 instruction, Dis_info *info); + std::string SUBQH_R_PH(uint64 instruction, Dis_info *info); + std::string SUBQH_R_W(uint64 instruction, Dis_info *info); + std::string SUBQH_W(uint64 instruction, Dis_info *info); + std::string SUBU_16_(uint64 instruction, Dis_info *info); + std::string SUBU_32_(uint64 instruction, Dis_info *info); + std::string SUBU_PH(uint64 instruction, Dis_info *info); + std::string SUBU_QB(uint64 instruction, Dis_info *info); + std::string SUBU_S_PH(uint64 instruction, Dis_info *info); + std::string SUBU_S_QB(uint64 instruction, Dis_info *info); + std::string SUBUH_QB(uint64 instruction, Dis_info *info); + std::string SUBUH_R_QB(uint64 instruction, Dis_info *info); + std::string SW_16_(uint64 instruction, Dis_info *info); + std::string SW_4X4_(uint64 instruction, Dis_info *info); + std::string SW_GP16_(uint64 instruction, Dis_info *info); + std::string SW_GP_(uint64 instruction, Dis_info *info); + std::string SW_S9_(uint64 instruction, Dis_info *info); + std::string SW_SP_(uint64 instruction, Dis_info *info); + std::string SW_U12_(uint64 instruction, Dis_info *info); + std::string SWC1_GP_(uint64 instruction, Dis_info *info); + std::string SWC1_S9_(uint64 instruction, Dis_info *info); + std::string SWC1_U12_(uint64 instruction, Dis_info *info); + std::string SWC1X(uint64 instruction, Dis_info *info); + std::string SWC1XS(uint64 instruction, Dis_info *info); + std::string SWC2(uint64 instruction, Dis_info *info); + std::string SWE(uint64 instruction, Dis_info *info); + std::string SWM(uint64 instruction, Dis_info *info); + std::string SWPC_48_(uint64 instruction, Dis_info *info); + std::string SWX(uint64 instruction, Dis_info *info); + std::string SWXS(uint64 instruction, Dis_info *info); + std::string SYNC(uint64 instruction, Dis_info *info); + std::string SYNCI(uint64 instruction, Dis_info *info); + std::string SYNCIE(uint64 instruction, Dis_info *info); + std::string SYSCALL_16_(uint64 instruction, Dis_info *info); + std::string SYSCALL_32_(uint64 instruction, Dis_info *info); + std::string TEQ(uint64 instruction, Dis_info *info); + std::string TLBGINV(uint64 instruction, Dis_info *info); + std::string TLBGINVF(uint64 instruction, Dis_info *info); + std::string TLBGP(uint64 instruction, Dis_info *info); + std::string TLBGR(uint64 instruction, Dis_info *info); + std::string TLBGWI(uint64 instruction, Dis_info *info); + std::string TLBGWR(uint64 instruction, Dis_info *info); + std::string TLBINV(uint64 instruction, Dis_info *info); + std::string TLBINVF(uint64 instruction, Dis_info *info); + std::string TLBP(uint64 instruction, Dis_info *info); + std::string TLBR(uint64 instruction, Dis_info *info); + std::string TLBWI(uint64 instruction, Dis_info *info); + std::string TLBWR(uint64 instruction, Dis_info *info); + std::string TNE(uint64 instruction, Dis_info *info); + std::string TRUNC_L_D(uint64 instruction, Dis_info *info); + std::string TRUNC_L_S(uint64 instruction, Dis_info *info); + std::string TRUNC_W_D(uint64 instruction, Dis_info *info); + std::string TRUNC_W_S(uint64 instruction, Dis_info *info); + std::string UALDM(uint64 instruction, Dis_info *info); + std::string UALH(uint64 instruction, Dis_info *info); + std::string UALWM(uint64 instruction, Dis_info *info); + std::string UASDM(uint64 instruction, Dis_info *info); + std::string UASH(uint64 instruction, Dis_info *info); + std::string UASWM(uint64 instruction, Dis_info *info); + std::string UDI(uint64 instruction, Dis_info *info); + std::string WAIT(uint64 instruction, Dis_info *info); + std::string WRDSP(uint64 instruction, Dis_info *info); + std::string WRPGPR(uint64 instruction, Dis_info *info); + std::string XOR_16_(uint64 instruction, Dis_info *info); + std::string XOR_32_(uint64 instruction, Dis_info *info); + std::string XORI(uint64 instruction, Dis_info *info); + std::string YIELD(uint64 instruction, Dis_info *info); static Pool P_SYSCALL[2]; static Pool P_RI[4]; From 2dc0c175df28cd9c9a5eeb12880219cb0f426951 Mon Sep 17 00:00:00 2001 From: Milica Lazarevic Date: Mon, 12 Sep 2022 14:26:16 +0200 Subject: [PATCH 426/705] disas/nanomips: Remove helper methods from class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Helper methods from NMD class like NMD::renumber_registers, NMD::decode_gpr_gpr4... etc. are removed from the class. They're now declared global static functions. Following helper methods have been deleted because they're not used by the nanomips disassembler: - NMD::encode_msbd_from_pos_and_size, - NMD::encode_s_from_s_hi, - NMD::neg_copy Global functions used by those methods: - nanomips_dis - sign_extend - extract_bits have also been defined as static global functions. Signed-off-by: Milica Lazarevic Reviewed-by: Richard Henderson Message-Id: <20220912122635.74032-6-milica.lazarevic@syrmia.com> Signed-off-by: Philippe Mathieu-Daudé --- disas/nanomips.cpp | 328 +++++++++++++++++++++------------------------ disas/nanomips.h | 144 -------------------- 2 files changed, 154 insertions(+), 318 deletions(-) diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp index 9005f26ee3..271afcde07 100644 --- a/disas/nanomips.cpp +++ b/disas/nanomips.cpp @@ -41,7 +41,7 @@ #define IMGASSERTONCE(test) -int nanomips_dis(char *buf, +static int nanomips_dis(char *buf, Dis_info *info, unsigned short one, unsigned short two, @@ -259,20 +259,20 @@ std::string to_string(img_address a) } -uint64 extract_bits(uint64 data, uint32 bit_offset, uint32 bit_size) +static uint64 extract_bits(uint64 data, uint32 bit_offset, uint32 bit_size) { return (data << (64 - (bit_size + bit_offset))) >> (64 - bit_size); } -int64 sign_extend(int64 data, int msb) +static int64 sign_extend(int64 data, int msb) { uint64 shift = 63 - msb; return (data << shift) >> shift; } -uint64 NMD::renumber_registers(uint64 index, uint64 *register_list, +static uint64 renumber_registers(uint64 index, uint64 *register_list, size_t register_list_size) { if (index < register_list_size) { @@ -287,7 +287,7 @@ uint64 NMD::renumber_registers(uint64 index, uint64 *register_list, /* - * NMD::decode_gpr_gpr4() - decoder for 'gpr4' gpr encoding type + * decode_gpr_gpr4() - decoder for 'gpr4' gpr encoding type * * Map a 4-bit code to the 5-bit register space according to this pattern: * @@ -312,7 +312,7 @@ uint64 NMD::renumber_registers(uint64 index, uint64 *register_list, * - MUL[4X4] * - SW[4X4] */ -uint64 NMD::decode_gpr_gpr4(uint64 d) +static uint64 decode_gpr_gpr4(uint64 d) { static uint64 register_list[] = { 8, 9, 10, 11, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23 }; @@ -322,7 +322,7 @@ uint64 NMD::decode_gpr_gpr4(uint64 d) /* - * NMD::decode_gpr_gpr4_zero() - decoder for 'gpr4.zero' gpr encoding type + * decode_gpr_gpr4_zero() - decoder for 'gpr4.zero' gpr encoding type * * Map a 4-bit code to the 5-bit register space according to this pattern: * @@ -348,7 +348,7 @@ uint64 NMD::decode_gpr_gpr4(uint64 d) * - MOVEP * - SW[4X4] */ -uint64 NMD::decode_gpr_gpr4_zero(uint64 d) +static uint64 decode_gpr_gpr4_zero(uint64 d) { static uint64 register_list[] = { 8, 9, 10, 0, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23 }; @@ -358,7 +358,7 @@ uint64 NMD::decode_gpr_gpr4_zero(uint64 d) /* - * NMD::decode_gpr_gpr3() - decoder for 'gpr3' gpr encoding type + * decode_gpr_gpr3() - decoder for 'gpr3' gpr encoding type * * Map a 3-bit code to the 5-bit register space according to this pattern: * @@ -407,7 +407,7 @@ uint64 NMD::decode_gpr_gpr4_zero(uint64 d) * - SW[16] * - XOR[16] */ -uint64 NMD::decode_gpr_gpr3(uint64 d) +static uint64 decode_gpr_gpr3(uint64 d) { static uint64 register_list[] = { 16, 17, 18, 19, 4, 5, 6, 7 }; return renumber_registers(d, register_list, @@ -416,7 +416,7 @@ uint64 NMD::decode_gpr_gpr3(uint64 d) /* - * NMD::decode_gpr_gpr3_src_store() - decoder for 'gpr3.src.store' gpr encoding + * decode_gpr_gpr3_src_store() - decoder for 'gpr3.src.store' gpr encoding * type * * Map a 3-bit code to the 5-bit register space according to this pattern: @@ -447,7 +447,7 @@ uint64 NMD::decode_gpr_gpr3(uint64 d) * - SW[16] * - SW[GP16] */ -uint64 NMD::decode_gpr_gpr3_src_store(uint64 d) +static uint64 decode_gpr_gpr3_src_store(uint64 d) { static uint64 register_list[] = { 0, 17, 18, 19, 4, 5, 6, 7 }; return renumber_registers(d, register_list, @@ -456,7 +456,7 @@ uint64 NMD::decode_gpr_gpr3_src_store(uint64 d) /* - * NMD::decode_gpr_gpr2_reg1() - decoder for 'gpr2.reg1' gpr encoding type + * decode_gpr_gpr2_reg1() - decoder for 'gpr2.reg1' gpr encoding type * * Map a 2-bit code to the 5-bit register space according to this pattern: * @@ -477,7 +477,7 @@ uint64 NMD::decode_gpr_gpr3_src_store(uint64 d) * - MOVEP * - MOVEP[REV] */ -uint64 NMD::decode_gpr_gpr2_reg1(uint64 d) +static uint64 decode_gpr_gpr2_reg1(uint64 d) { static uint64 register_list[] = { 4, 5, 6, 7 }; return renumber_registers(d, register_list, @@ -486,7 +486,7 @@ uint64 NMD::decode_gpr_gpr2_reg1(uint64 d) /* - * NMD::decode_gpr_gpr2_reg2() - decoder for 'gpr2.reg2' gpr encoding type + * decode_gpr_gpr2_reg2() - decoder for 'gpr2.reg2' gpr encoding type * * Map a 2-bit code to the 5-bit register space according to this pattern: * @@ -507,7 +507,7 @@ uint64 NMD::decode_gpr_gpr2_reg1(uint64 d) * - MOVEP * - MOVEP[REV] */ -uint64 NMD::decode_gpr_gpr2_reg2(uint64 d) +static uint64 decode_gpr_gpr2_reg2(uint64 d) { static uint64 register_list[] = { 5, 6, 7, 8 }; return renumber_registers(d, register_list, @@ -516,7 +516,7 @@ uint64 NMD::decode_gpr_gpr2_reg2(uint64 d) /* - * NMD::decode_gpr_gpr1() - decoder for 'gpr1' gpr encoding type + * decode_gpr_gpr1() - decoder for 'gpr1' gpr encoding type * * Map a 1-bit code to the 5-bit register space according to this pattern: * @@ -536,7 +536,7 @@ uint64 NMD::decode_gpr_gpr2_reg2(uint64 d) * * - MOVE.BALC */ -uint64 NMD::decode_gpr_gpr1(uint64 d) +static uint64 decode_gpr_gpr1(uint64 d) { static uint64 register_list[] = { 4, 5 }; return renumber_registers(d, register_list, @@ -544,73 +544,60 @@ uint64 NMD::decode_gpr_gpr1(uint64 d) } -uint64 NMD::copy(uint64 d) +static uint64 copy(uint64 d) { return d; } -int64 NMD::copy(int64 d) +static int64 copy(int64 d) { return d; } -int64 NMD::neg_copy(uint64 d) +static int64 neg_copy(uint64 d) { return 0ll - d; } -int64 NMD::neg_copy(int64 d) -{ - return -d; -} - - /* strange wrapper around gpr3 */ -uint64 NMD::encode_rs3_and_check_rs3_ge_rt3(uint64 d) +static uint64 encode_rs3_and_check_rs3_ge_rt3(uint64 d) { return decode_gpr_gpr3(d); } /* strange wrapper around gpr3 */ -uint64 NMD::encode_rs3_and_check_rs3_lt_rt3(uint64 d) +static uint64 encode_rs3_and_check_rs3_lt_rt3(uint64 d) { return decode_gpr_gpr3(d); } /* nop - done by extraction function */ -uint64 NMD::encode_s_from_address(uint64 d) +static uint64 encode_s_from_address(uint64 d) { return d; } /* nop - done by extraction function */ -uint64 NMD::encode_u_from_address(uint64 d) +static uint64 encode_u_from_address(uint64 d) { return d; } -/* nop - done by extraction function */ -uint64 NMD::encode_s_from_s_hi(uint64 d) -{ - return d; -} - - -uint64 NMD::encode_count3_from_count(uint64 d) +static uint64 encode_count3_from_count(uint64 d) { IMGASSERTONCE(d < 8); return d == 0ull ? 8ull : d; } -uint64 NMD::encode_shift3_from_shift(uint64 d) +static uint64 encode_shift3_from_shift(uint64 d) { IMGASSERTONCE(d < 8); return d == 0ull ? 8ull : d; @@ -618,21 +605,21 @@ uint64 NMD::encode_shift3_from_shift(uint64 d) /* special value for load literal */ -int64 NMD::encode_eu_from_s_li16(uint64 d) +static int64 encode_eu_from_s_li16(uint64 d) { IMGASSERTONCE(d < 128); return d == 127 ? -1 : (int64)d; } -uint64 NMD::encode_msbd_from_size(uint64 d) +static uint64 encode_msbd_from_size(uint64 d) { IMGASSERTONCE(d < 32); return d + 1; } -uint64 NMD::encode_eu_from_u_andi16(uint64 d) +static uint64 encode_eu_from_u_andi16(uint64 d) { IMGASSERTONCE(d < 16); if (d == 12) { @@ -645,42 +632,21 @@ uint64 NMD::encode_eu_from_u_andi16(uint64 d) } -uint64 NMD::encode_msbd_from_pos_and_size(uint64 d) -{ - IMGASSERTONCE(0); - return d; -} - - /* save16 / restore16 ???? */ -uint64 NMD::encode_rt1_from_rt(uint64 d) +static uint64 encode_rt1_from_rt(uint64 d) { return d ? 31 : 30; } /* ? */ -uint64 NMD::encode_lsb_from_pos_and_size(uint64 d) +static uint64 encode_lsb_from_pos_and_size(uint64 d) { return d; } -std::string NMD::save_restore_list(uint64 rt, uint64 count, uint64 gp) -{ - std::string str; - - for (uint64 counter = 0; counter != count; counter++) { - bool use_gp = gp && (counter == count - 1); - uint64 this_rt = use_gp ? 28 : ((rt & 0x10) | (rt + counter)) & 0x1f; - str += img_format(",%s", GPR(this_rt)); - } - - return str; -} - - -std::string NMD::GPR(uint64 reg) +static std::string GPR(uint64 reg) { static const char *gpr_reg[32] = { "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", @@ -698,7 +664,21 @@ std::string NMD::GPR(uint64 reg) } -std::string NMD::FPR(uint64 reg) +static std::string save_restore_list(uint64 rt, uint64 count, uint64 gp) +{ + std::string str; + + for (uint64 counter = 0; counter != count; counter++) { + bool use_gp = gp && (counter == count - 1); + uint64 this_rt = use_gp ? 28 : ((rt & 0x10) | (rt + counter)) & 0x1f; + str += img_format(",%s", GPR(this_rt)); + } + + return str; +} + + +static std::string FPR(uint64 reg) { static const char *fpr_reg[32] = { "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", @@ -716,7 +696,7 @@ std::string NMD::FPR(uint64 reg) } -std::string NMD::AC(uint64 reg) +static std::string AC(uint64 reg) { static const char *ac_reg[4] = { "ac0", "ac1", "ac2", "ac3" @@ -731,26 +711,26 @@ std::string NMD::AC(uint64 reg) } -std::string NMD::IMMEDIATE(uint64 value) +static std::string IMMEDIATE(uint64 value) { return img_format("0x%" PRIx64, value); } -std::string NMD::IMMEDIATE(int64 value) +static std::string IMMEDIATE(int64 value) { return img_format("%" PRId64, value); } -std::string NMD::CPR(uint64 reg) +static std::string CPR(uint64 reg) { /* needs more work */ return img_format("CP%" PRIu64, reg); } -std::string NMD::ADDRESS(uint64 value, int instruction_size, Dis_info *info) +static std::string ADDRESS(uint64 value, int instruction_size, Dis_info *info) { /* token for string replace */ img_address address = info->m_pc + value + instruction_size; @@ -849,7 +829,7 @@ int NMD::Disassemble(const uint16 * data, std::string & dis, } -uint64 NMD::extract_code_18_to_0(uint64 instruction) +static uint64 extract_code_18_to_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 19); @@ -857,7 +837,7 @@ uint64 NMD::extract_code_18_to_0(uint64 instruction) } -uint64 NMD::extract_shift3_2_1_0(uint64 instruction) +static uint64 extract_shift3_2_1_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 3); @@ -865,7 +845,7 @@ uint64 NMD::extract_shift3_2_1_0(uint64 instruction) } -uint64 NMD::extract_u_11_10_9_8_7_6_5_4_3__s3(uint64 instruction) +static uint64 extract_u_11_10_9_8_7_6_5_4_3__s3(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 3, 9) << 3; @@ -873,7 +853,7 @@ uint64 NMD::extract_u_11_10_9_8_7_6_5_4_3__s3(uint64 instruction) } -uint64 NMD::extract_count_3_2_1_0(uint64 instruction) +static uint64 extract_count_3_2_1_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 4); @@ -881,7 +861,7 @@ uint64 NMD::extract_count_3_2_1_0(uint64 instruction) } -uint64 NMD::extract_rtz3_9_8_7(uint64 instruction) +static uint64 extract_rtz3_9_8_7(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 7, 3); @@ -889,7 +869,7 @@ uint64 NMD::extract_rtz3_9_8_7(uint64 instruction) } -uint64 NMD::extract_u_17_to_1__s1(uint64 instruction) +static uint64 extract_u_17_to_1__s1(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 1, 17) << 1; @@ -897,7 +877,7 @@ uint64 NMD::extract_u_17_to_1__s1(uint64 instruction) } -int64 NMD::extract_s__se9_20_19_18_17_16_15_14_13_12_11(uint64 instruction) +static int64 extract_s__se9_20_19_18_17_16_15_14_13_12_11(uint64 instruction) { int64 value = 0; value |= extract_bits(instruction, 11, 10); @@ -906,7 +886,7 @@ int64 NMD::extract_s__se9_20_19_18_17_16_15_14_13_12_11(uint64 instruction) } -int64 NMD::extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(uint64 instruction) +static int64 extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(uint64 instruction) { int64 value = 0; value |= extract_bits(instruction, 0, 1) << 11; @@ -916,7 +896,7 @@ int64 NMD::extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(uint64 instruction) } -uint64 NMD::extract_u_10(uint64 instruction) +static uint64 extract_u_10(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 10, 1); @@ -924,7 +904,7 @@ uint64 NMD::extract_u_10(uint64 instruction) } -uint64 NMD::extract_rtz4_27_26_25_23_22_21(uint64 instruction) +static uint64 extract_rtz4_27_26_25_23_22_21(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 21, 3); @@ -933,7 +913,7 @@ uint64 NMD::extract_rtz4_27_26_25_23_22_21(uint64 instruction) } -uint64 NMD::extract_sa_15_14_13_12_11(uint64 instruction) +static uint64 extract_sa_15_14_13_12_11(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 11, 5); @@ -941,7 +921,7 @@ uint64 NMD::extract_sa_15_14_13_12_11(uint64 instruction) } -uint64 NMD::extract_shift_4_3_2_1_0(uint64 instruction) +static uint64 extract_shift_4_3_2_1_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 5); @@ -949,7 +929,7 @@ uint64 NMD::extract_shift_4_3_2_1_0(uint64 instruction) } -uint64 NMD::extract_shiftx_10_9_8_7__s1(uint64 instruction) +static uint64 extract_shiftx_10_9_8_7__s1(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 7, 4) << 1; @@ -957,7 +937,7 @@ uint64 NMD::extract_shiftx_10_9_8_7__s1(uint64 instruction) } -uint64 NMD::extract_hint_25_24_23_22_21(uint64 instruction) +static uint64 extract_hint_25_24_23_22_21(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 21, 5); @@ -965,7 +945,7 @@ uint64 NMD::extract_hint_25_24_23_22_21(uint64 instruction) } -uint64 NMD::extract_count3_14_13_12(uint64 instruction) +static uint64 extract_count3_14_13_12(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 12, 3); @@ -973,7 +953,7 @@ uint64 NMD::extract_count3_14_13_12(uint64 instruction) } -int64 NMD::extract_s__se31_0_11_to_2_20_to_12_s12(uint64 instruction) +static int64 extract_s__se31_0_11_to_2_20_to_12_s12(uint64 instruction) { int64 value = 0; value |= extract_bits(instruction, 0, 1) << 31; @@ -984,7 +964,7 @@ int64 NMD::extract_s__se31_0_11_to_2_20_to_12_s12(uint64 instruction) } -int64 NMD::extract_s__se7_0_6_5_4_3_2_1_s1(uint64 instruction) +static int64 extract_s__se7_0_6_5_4_3_2_1_s1(uint64 instruction) { int64 value = 0; value |= extract_bits(instruction, 0, 1) << 7; @@ -994,7 +974,7 @@ int64 NMD::extract_s__se7_0_6_5_4_3_2_1_s1(uint64 instruction) } -uint64 NMD::extract_u2_10_9(uint64 instruction) +static uint64 extract_u2_10_9(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 9, 2); @@ -1002,7 +982,7 @@ uint64 NMD::extract_u2_10_9(uint64 instruction) } -uint64 NMD::extract_code_25_24_23_22_21_20_19_18_17_16(uint64 instruction) +static uint64 extract_code_25_24_23_22_21_20_19_18_17_16(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 16, 10); @@ -1010,7 +990,7 @@ uint64 NMD::extract_code_25_24_23_22_21_20_19_18_17_16(uint64 instruction) } -uint64 NMD::extract_rs_20_19_18_17_16(uint64 instruction) +static uint64 extract_rs_20_19_18_17_16(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 16, 5); @@ -1018,7 +998,7 @@ uint64 NMD::extract_rs_20_19_18_17_16(uint64 instruction) } -uint64 NMD::extract_u_2_1__s1(uint64 instruction) +static uint64 extract_u_2_1__s1(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 1, 2) << 1; @@ -1026,7 +1006,7 @@ uint64 NMD::extract_u_2_1__s1(uint64 instruction) } -uint64 NMD::extract_stripe_6(uint64 instruction) +static uint64 extract_stripe_6(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 6, 1); @@ -1034,7 +1014,7 @@ uint64 NMD::extract_stripe_6(uint64 instruction) } -uint64 NMD::extract_ac_15_14(uint64 instruction) +static uint64 extract_ac_15_14(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 14, 2); @@ -1042,7 +1022,7 @@ uint64 NMD::extract_ac_15_14(uint64 instruction) } -uint64 NMD::extract_shift_20_19_18_17_16(uint64 instruction) +static uint64 extract_shift_20_19_18_17_16(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 16, 5); @@ -1050,7 +1030,7 @@ uint64 NMD::extract_shift_20_19_18_17_16(uint64 instruction) } -uint64 NMD::extract_rdl_25_24(uint64 instruction) +static uint64 extract_rdl_25_24(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 24, 1); @@ -1058,7 +1038,7 @@ uint64 NMD::extract_rdl_25_24(uint64 instruction) } -int64 NMD::extract_s__se10_0_9_8_7_6_5_4_3_2_1_s1(uint64 instruction) +static int64 extract_s__se10_0_9_8_7_6_5_4_3_2_1_s1(uint64 instruction) { int64 value = 0; value |= extract_bits(instruction, 0, 1) << 10; @@ -1068,7 +1048,7 @@ int64 NMD::extract_s__se10_0_9_8_7_6_5_4_3_2_1_s1(uint64 instruction) } -uint64 NMD::extract_eu_6_5_4_3_2_1_0(uint64 instruction) +static uint64 extract_eu_6_5_4_3_2_1_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 7); @@ -1076,7 +1056,7 @@ uint64 NMD::extract_eu_6_5_4_3_2_1_0(uint64 instruction) } -uint64 NMD::extract_shift_5_4_3_2_1_0(uint64 instruction) +static uint64 extract_shift_5_4_3_2_1_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 6); @@ -1084,7 +1064,7 @@ uint64 NMD::extract_shift_5_4_3_2_1_0(uint64 instruction) } -uint64 NMD::extract_count_19_18_17_16(uint64 instruction) +static uint64 extract_count_19_18_17_16(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 16, 4); @@ -1092,7 +1072,7 @@ uint64 NMD::extract_count_19_18_17_16(uint64 instruction) } -uint64 NMD::extract_code_2_1_0(uint64 instruction) +static uint64 extract_code_2_1_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 3); @@ -1100,7 +1080,7 @@ uint64 NMD::extract_code_2_1_0(uint64 instruction) } -uint64 NMD::extract_u_11_10_9_8_7_6_5_4_3_2_1_0(uint64 instruction) +static uint64 extract_u_11_10_9_8_7_6_5_4_3_2_1_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 12); @@ -1108,7 +1088,7 @@ uint64 NMD::extract_u_11_10_9_8_7_6_5_4_3_2_1_0(uint64 instruction) } -uint64 NMD::extract_rs_4_3_2_1_0(uint64 instruction) +static uint64 extract_rs_4_3_2_1_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 5); @@ -1116,7 +1096,7 @@ uint64 NMD::extract_rs_4_3_2_1_0(uint64 instruction) } -uint64 NMD::extract_u_20_to_3__s3(uint64 instruction) +static uint64 extract_u_20_to_3__s3(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 3, 18) << 3; @@ -1124,7 +1104,7 @@ uint64 NMD::extract_u_20_to_3__s3(uint64 instruction) } -uint64 NMD::extract_u_3_2_1_0__s2(uint64 instruction) +static uint64 extract_u_3_2_1_0__s2(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 4) << 2; @@ -1132,7 +1112,7 @@ uint64 NMD::extract_u_3_2_1_0__s2(uint64 instruction) } -uint64 NMD::extract_cofun_25_24_23(uint64 instruction) +static uint64 extract_cofun_25_24_23(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 3, 23); @@ -1140,7 +1120,7 @@ uint64 NMD::extract_cofun_25_24_23(uint64 instruction) } -uint64 NMD::extract_u_2_1_0__s2(uint64 instruction) +static uint64 extract_u_2_1_0__s2(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 3) << 2; @@ -1148,7 +1128,7 @@ uint64 NMD::extract_u_2_1_0__s2(uint64 instruction) } -uint64 NMD::extract_rd3_3_2_1(uint64 instruction) +static uint64 extract_rd3_3_2_1(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 1, 3); @@ -1156,7 +1136,7 @@ uint64 NMD::extract_rd3_3_2_1(uint64 instruction) } -uint64 NMD::extract_sa_15_14_13_12(uint64 instruction) +static uint64 extract_sa_15_14_13_12(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 12, 4); @@ -1164,7 +1144,7 @@ uint64 NMD::extract_sa_15_14_13_12(uint64 instruction) } -uint64 NMD::extract_rt_25_24_23_22_21(uint64 instruction) +static uint64 extract_rt_25_24_23_22_21(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 21, 5); @@ -1172,7 +1152,7 @@ uint64 NMD::extract_rt_25_24_23_22_21(uint64 instruction) } -uint64 NMD::extract_ru_7_6_5_4_3(uint64 instruction) +static uint64 extract_ru_7_6_5_4_3(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 3, 5); @@ -1180,7 +1160,7 @@ uint64 NMD::extract_ru_7_6_5_4_3(uint64 instruction) } -uint64 NMD::extract_u_17_to_0(uint64 instruction) +static uint64 extract_u_17_to_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 18); @@ -1188,7 +1168,7 @@ uint64 NMD::extract_u_17_to_0(uint64 instruction) } -uint64 NMD::extract_rsz4_4_2_1_0(uint64 instruction) +static uint64 extract_rsz4_4_2_1_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 3); @@ -1197,7 +1177,7 @@ uint64 NMD::extract_rsz4_4_2_1_0(uint64 instruction) } -int64 NMD::extract_s__se21_0_20_to_1_s1(uint64 instruction) +static int64 extract_s__se21_0_20_to_1_s1(uint64 instruction) { int64 value = 0; value |= extract_bits(instruction, 0, 1) << 21; @@ -1207,7 +1187,7 @@ int64 NMD::extract_s__se21_0_20_to_1_s1(uint64 instruction) } -uint64 NMD::extract_op_25_to_3(uint64 instruction) +static uint64 extract_op_25_to_3(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 3, 23); @@ -1215,7 +1195,7 @@ uint64 NMD::extract_op_25_to_3(uint64 instruction) } -uint64 NMD::extract_rs4_4_2_1_0(uint64 instruction) +static uint64 extract_rs4_4_2_1_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 3); @@ -1224,7 +1204,7 @@ uint64 NMD::extract_rs4_4_2_1_0(uint64 instruction) } -uint64 NMD::extract_bit_23_22_21(uint64 instruction) +static uint64 extract_bit_23_22_21(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 21, 3); @@ -1232,7 +1212,7 @@ uint64 NMD::extract_bit_23_22_21(uint64 instruction) } -uint64 NMD::extract_rt_41_40_39_38_37(uint64 instruction) +static uint64 extract_rt_41_40_39_38_37(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 37, 5); @@ -1240,7 +1220,7 @@ uint64 NMD::extract_rt_41_40_39_38_37(uint64 instruction) } -int64 NMD::extract_shift__se5_21_20_19_18_17_16(uint64 instruction) +static int64 extract_shift__se5_21_20_19_18_17_16(uint64 instruction) { int64 value = 0; value |= extract_bits(instruction, 16, 6); @@ -1249,7 +1229,7 @@ int64 NMD::extract_shift__se5_21_20_19_18_17_16(uint64 instruction) } -uint64 NMD::extract_rd2_3_8(uint64 instruction) +static uint64 extract_rd2_3_8(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 3, 1) << 1; @@ -1258,7 +1238,7 @@ uint64 NMD::extract_rd2_3_8(uint64 instruction) } -uint64 NMD::extract_code_17_to_0(uint64 instruction) +static uint64 extract_code_17_to_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 18); @@ -1266,7 +1246,7 @@ uint64 NMD::extract_code_17_to_0(uint64 instruction) } -uint64 NMD::extract_size_20_19_18_17_16(uint64 instruction) +static uint64 extract_size_20_19_18_17_16(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 16, 5); @@ -1274,7 +1254,7 @@ uint64 NMD::extract_size_20_19_18_17_16(uint64 instruction) } -int64 NMD::extract_s__se8_15_7_6_5_4_3_2_s2(uint64 instruction) +static int64 extract_s__se8_15_7_6_5_4_3_2_s2(uint64 instruction) { int64 value = 0; value |= extract_bits(instruction, 2, 6) << 2; @@ -1284,7 +1264,7 @@ int64 NMD::extract_s__se8_15_7_6_5_4_3_2_s2(uint64 instruction) } -uint64 NMD::extract_u_15_to_0(uint64 instruction) +static uint64 extract_u_15_to_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 16); @@ -1292,7 +1272,7 @@ uint64 NMD::extract_u_15_to_0(uint64 instruction) } -uint64 NMD::extract_fs_20_19_18_17_16(uint64 instruction) +static uint64 extract_fs_20_19_18_17_16(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 16, 5); @@ -1300,7 +1280,7 @@ uint64 NMD::extract_fs_20_19_18_17_16(uint64 instruction) } -int64 NMD::extract_s__se8_15_7_6_5_4_3_2_1_0(uint64 instruction) +static int64 extract_s__se8_15_7_6_5_4_3_2_1_0(uint64 instruction) { int64 value = 0; value |= extract_bits(instruction, 0, 8); @@ -1310,7 +1290,7 @@ int64 NMD::extract_s__se8_15_7_6_5_4_3_2_1_0(uint64 instruction) } -uint64 NMD::extract_stype_20_19_18_17_16(uint64 instruction) +static uint64 extract_stype_20_19_18_17_16(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 16, 5); @@ -1318,7 +1298,7 @@ uint64 NMD::extract_stype_20_19_18_17_16(uint64 instruction) } -uint64 NMD::extract_rtl_11(uint64 instruction) +static uint64 extract_rtl_11(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 9, 1); @@ -1326,7 +1306,7 @@ uint64 NMD::extract_rtl_11(uint64 instruction) } -uint64 NMD::extract_hs_20_19_18_17_16(uint64 instruction) +static uint64 extract_hs_20_19_18_17_16(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 16, 5); @@ -1334,7 +1314,7 @@ uint64 NMD::extract_hs_20_19_18_17_16(uint64 instruction) } -uint64 NMD::extract_sel_13_12_11(uint64 instruction) +static uint64 extract_sel_13_12_11(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 11, 3); @@ -1342,7 +1322,7 @@ uint64 NMD::extract_sel_13_12_11(uint64 instruction) } -uint64 NMD::extract_lsb_4_3_2_1_0(uint64 instruction) +static uint64 extract_lsb_4_3_2_1_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 5); @@ -1350,7 +1330,7 @@ uint64 NMD::extract_lsb_4_3_2_1_0(uint64 instruction) } -uint64 NMD::extract_gp_2(uint64 instruction) +static uint64 extract_gp_2(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 2, 1); @@ -1358,7 +1338,7 @@ uint64 NMD::extract_gp_2(uint64 instruction) } -uint64 NMD::extract_rt3_9_8_7(uint64 instruction) +static uint64 extract_rt3_9_8_7(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 7, 3); @@ -1366,7 +1346,7 @@ uint64 NMD::extract_rt3_9_8_7(uint64 instruction) } -uint64 NMD::extract_ft_25_24_23_22_21(uint64 instruction) +static uint64 extract_ft_25_24_23_22_21(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 21, 5); @@ -1374,7 +1354,7 @@ uint64 NMD::extract_ft_25_24_23_22_21(uint64 instruction) } -uint64 NMD::extract_u_17_16_15_14_13_12_11(uint64 instruction) +static uint64 extract_u_17_16_15_14_13_12_11(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 11, 7); @@ -1382,7 +1362,7 @@ uint64 NMD::extract_u_17_16_15_14_13_12_11(uint64 instruction) } -uint64 NMD::extract_cs_20_19_18_17_16(uint64 instruction) +static uint64 extract_cs_20_19_18_17_16(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 16, 5); @@ -1390,7 +1370,7 @@ uint64 NMD::extract_cs_20_19_18_17_16(uint64 instruction) } -uint64 NMD::extract_rt4_9_7_6_5(uint64 instruction) +static uint64 extract_rt4_9_7_6_5(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 5, 3); @@ -1399,7 +1379,7 @@ uint64 NMD::extract_rt4_9_7_6_5(uint64 instruction) } -uint64 NMD::extract_msbt_10_9_8_7_6(uint64 instruction) +static uint64 extract_msbt_10_9_8_7_6(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 6, 5); @@ -1407,7 +1387,7 @@ uint64 NMD::extract_msbt_10_9_8_7_6(uint64 instruction) } -uint64 NMD::extract_u_5_4_3_2_1_0__s2(uint64 instruction) +static uint64 extract_u_5_4_3_2_1_0__s2(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 6) << 2; @@ -1415,7 +1395,7 @@ uint64 NMD::extract_u_5_4_3_2_1_0__s2(uint64 instruction) } -uint64 NMD::extract_sa_15_14_13(uint64 instruction) +static uint64 extract_sa_15_14_13(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 13, 3); @@ -1423,7 +1403,7 @@ uint64 NMD::extract_sa_15_14_13(uint64 instruction) } -int64 NMD::extract_s__se14_0_13_to_1_s1(uint64 instruction) +static int64 extract_s__se14_0_13_to_1_s1(uint64 instruction) { int64 value = 0; value |= extract_bits(instruction, 0, 1) << 14; @@ -1433,7 +1413,7 @@ int64 NMD::extract_s__se14_0_13_to_1_s1(uint64 instruction) } -uint64 NMD::extract_rs3_6_5_4(uint64 instruction) +static uint64 extract_rs3_6_5_4(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 4, 3); @@ -1441,7 +1421,7 @@ uint64 NMD::extract_rs3_6_5_4(uint64 instruction) } -uint64 NMD::extract_u_31_to_0__s32(uint64 instruction) +static uint64 extract_u_31_to_0__s32(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 32) << 32; @@ -1449,7 +1429,7 @@ uint64 NMD::extract_u_31_to_0__s32(uint64 instruction) } -uint64 NMD::extract_shift_10_9_8_7_6(uint64 instruction) +static uint64 extract_shift_10_9_8_7_6(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 6, 5); @@ -1457,7 +1437,7 @@ uint64 NMD::extract_shift_10_9_8_7_6(uint64 instruction) } -uint64 NMD::extract_cs_25_24_23_22_21(uint64 instruction) +static uint64 extract_cs_25_24_23_22_21(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 21, 5); @@ -1465,7 +1445,7 @@ uint64 NMD::extract_cs_25_24_23_22_21(uint64 instruction) } -uint64 NMD::extract_shiftx_11_10_9_8_7_6(uint64 instruction) +static uint64 extract_shiftx_11_10_9_8_7_6(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 6, 6); @@ -1473,7 +1453,7 @@ uint64 NMD::extract_shiftx_11_10_9_8_7_6(uint64 instruction) } -uint64 NMD::extract_rt_9_8_7_6_5(uint64 instruction) +static uint64 extract_rt_9_8_7_6_5(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 5, 5); @@ -1481,7 +1461,7 @@ uint64 NMD::extract_rt_9_8_7_6_5(uint64 instruction) } -uint64 NMD::extract_op_25_24_23_22_21(uint64 instruction) +static uint64 extract_op_25_24_23_22_21(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 21, 5); @@ -1489,7 +1469,7 @@ uint64 NMD::extract_op_25_24_23_22_21(uint64 instruction) } -uint64 NMD::extract_u_6_5_4_3_2_1_0__s2(uint64 instruction) +static uint64 extract_u_6_5_4_3_2_1_0__s2(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 7) << 2; @@ -1497,7 +1477,7 @@ uint64 NMD::extract_u_6_5_4_3_2_1_0__s2(uint64 instruction) } -uint64 NMD::extract_bit_16_15_14_13_12_11(uint64 instruction) +static uint64 extract_bit_16_15_14_13_12_11(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 11, 6); @@ -1505,7 +1485,7 @@ uint64 NMD::extract_bit_16_15_14_13_12_11(uint64 instruction) } -uint64 NMD::extract_mask_20_19_18_17_16_15_14(uint64 instruction) +static uint64 extract_mask_20_19_18_17_16_15_14(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 14, 7); @@ -1513,7 +1493,7 @@ uint64 NMD::extract_mask_20_19_18_17_16_15_14(uint64 instruction) } -uint64 NMD::extract_eu_3_2_1_0(uint64 instruction) +static uint64 extract_eu_3_2_1_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 4); @@ -1521,7 +1501,7 @@ uint64 NMD::extract_eu_3_2_1_0(uint64 instruction) } -uint64 NMD::extract_u_7_6_5_4__s4(uint64 instruction) +static uint64 extract_u_7_6_5_4__s4(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 4, 4) << 4; @@ -1529,7 +1509,7 @@ uint64 NMD::extract_u_7_6_5_4__s4(uint64 instruction) } -int64 NMD::extract_s__se8_15_7_6_5_4_3_s3(uint64 instruction) +static int64 extract_s__se8_15_7_6_5_4_3_s3(uint64 instruction) { int64 value = 0; value |= extract_bits(instruction, 3, 5) << 3; @@ -1539,7 +1519,7 @@ int64 NMD::extract_s__se8_15_7_6_5_4_3_s3(uint64 instruction) } -uint64 NMD::extract_ft_15_14_13_12_11(uint64 instruction) +static uint64 extract_ft_15_14_13_12_11(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 11, 5); @@ -1547,7 +1527,7 @@ uint64 NMD::extract_ft_15_14_13_12_11(uint64 instruction) } -int64 NMD::extract_s__se31_15_to_0_31_to_16(uint64 instruction) +static int64 extract_s__se31_15_to_0_31_to_16(uint64 instruction) { int64 value = 0; value |= extract_bits(instruction, 0, 16) << 16; @@ -1557,7 +1537,7 @@ int64 NMD::extract_s__se31_15_to_0_31_to_16(uint64 instruction) } -uint64 NMD::extract_u_20_19_18_17_16_15_14_13(uint64 instruction) +static uint64 extract_u_20_19_18_17_16_15_14_13(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 13, 8); @@ -1565,7 +1545,7 @@ uint64 NMD::extract_u_20_19_18_17_16_15_14_13(uint64 instruction) } -uint64 NMD::extract_u_17_to_2__s2(uint64 instruction) +static uint64 extract_u_17_to_2__s2(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 2, 16) << 2; @@ -1573,7 +1553,7 @@ uint64 NMD::extract_u_17_to_2__s2(uint64 instruction) } -uint64 NMD::extract_rd_15_14_13_12_11(uint64 instruction) +static uint64 extract_rd_15_14_13_12_11(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 11, 5); @@ -1581,7 +1561,7 @@ uint64 NMD::extract_rd_15_14_13_12_11(uint64 instruction) } -uint64 NMD::extract_c0s_20_19_18_17_16(uint64 instruction) +static uint64 extract_c0s_20_19_18_17_16(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 16, 5); @@ -1589,7 +1569,7 @@ uint64 NMD::extract_c0s_20_19_18_17_16(uint64 instruction) } -uint64 NMD::extract_code_1_0(uint64 instruction) +static uint64 extract_code_1_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 2); @@ -1597,7 +1577,7 @@ uint64 NMD::extract_code_1_0(uint64 instruction) } -int64 NMD::extract_s__se25_0_24_to_1_s1(uint64 instruction) +static int64 extract_s__se25_0_24_to_1_s1(uint64 instruction) { int64 value = 0; value |= extract_bits(instruction, 0, 1) << 25; @@ -1607,7 +1587,7 @@ int64 NMD::extract_s__se25_0_24_to_1_s1(uint64 instruction) } -uint64 NMD::extract_u_1_0(uint64 instruction) +static uint64 extract_u_1_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 2); @@ -1615,7 +1595,7 @@ uint64 NMD::extract_u_1_0(uint64 instruction) } -uint64 NMD::extract_u_3_8__s2(uint64 instruction) +static uint64 extract_u_3_8__s2(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 3, 1) << 3; @@ -1624,7 +1604,7 @@ uint64 NMD::extract_u_3_8__s2(uint64 instruction) } -uint64 NMD::extract_fd_15_14_13_12_11(uint64 instruction) +static uint64 extract_fd_15_14_13_12_11(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 11, 5); @@ -1632,7 +1612,7 @@ uint64 NMD::extract_fd_15_14_13_12_11(uint64 instruction) } -uint64 NMD::extract_u_4_3_2_1_0__s2(uint64 instruction) +static uint64 extract_u_4_3_2_1_0__s2(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 5) << 2; @@ -1640,7 +1620,7 @@ uint64 NMD::extract_u_4_3_2_1_0__s2(uint64 instruction) } -uint64 NMD::extract_rtz4_9_7_6_5(uint64 instruction) +static uint64 extract_rtz4_9_7_6_5(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 5, 3); @@ -1649,7 +1629,7 @@ uint64 NMD::extract_rtz4_9_7_6_5(uint64 instruction) } -uint64 NMD::extract_sel_15_14_13_12_11(uint64 instruction) +static uint64 extract_sel_15_14_13_12_11(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 11, 5); @@ -1657,7 +1637,7 @@ uint64 NMD::extract_sel_15_14_13_12_11(uint64 instruction) } -uint64 NMD::extract_ct_25_24_23_22_21(uint64 instruction) +static uint64 extract_ct_25_24_23_22_21(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 21, 5); @@ -1665,7 +1645,7 @@ uint64 NMD::extract_ct_25_24_23_22_21(uint64 instruction) } -uint64 NMD::extract_u_20_to_2__s2(uint64 instruction) +static uint64 extract_u_20_to_2__s2(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 2, 19) << 2; @@ -1673,7 +1653,7 @@ uint64 NMD::extract_u_20_to_2__s2(uint64 instruction) } -int64 NMD::extract_s__se3_4_2_1_0(uint64 instruction) +static int64 extract_s__se3_4_2_1_0(uint64 instruction) { int64 value = 0; value |= extract_bits(instruction, 0, 3); @@ -1683,7 +1663,7 @@ int64 NMD::extract_s__se3_4_2_1_0(uint64 instruction) } -uint64 NMD::extract_u_3_2_1_0__s1(uint64 instruction) +static uint64 extract_u_3_2_1_0__s1(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 4) << 1; diff --git a/disas/nanomips.h b/disas/nanomips.h index fcd41c405c..8eca843ef0 100644 --- a/disas/nanomips.h +++ b/disas/nanomips.h @@ -94,150 +94,6 @@ private: TABLE_ENTRY_TYPE & type, const Pool *table, int table_size, Dis_info *info); - uint64 renumber_registers(uint64 index, uint64 *register_list, - size_t register_list_size); - - uint64 decode_gpr_gpr4(uint64 d); - uint64 decode_gpr_gpr4_zero(uint64 d); - uint64 decode_gpr_gpr3(uint64 d); - uint64 decode_gpr_gpr3_src_store(uint64 d); - uint64 decode_gpr_gpr2_reg1(uint64 d); - uint64 decode_gpr_gpr2_reg2(uint64 d); - uint64 decode_gpr_gpr1(uint64 d); - - uint64 copy(uint64 d); - int64 copy(int64 d); - int64 neg_copy(uint64 d); - int64 neg_copy(int64 d); - uint64 encode_rs3_and_check_rs3_ge_rt3(uint64 d); - uint64 encode_rs3_and_check_rs3_lt_rt3(uint64 d); - uint64 encode_s_from_address(uint64 d); - uint64 encode_u_from_address(uint64 d); - uint64 encode_s_from_s_hi(uint64 d); - uint64 encode_count3_from_count(uint64 d); - uint64 encode_shift3_from_shift(uint64 d); - int64 encode_eu_from_s_li16(uint64 d); - uint64 encode_msbd_from_size(uint64 d); - uint64 encode_eu_from_u_andi16(uint64 d); - - uint64 encode_msbd_from_pos_and_size(uint64 d); - - uint64 encode_rt1_from_rt(uint64 d); - uint64 encode_lsb_from_pos_and_size(uint64 d); - - std::string save_restore_list(uint64 rt, uint64 count, uint64 gp); - - std::string GPR(uint64 reg); - std::string FPR(uint64 reg); - std::string AC(uint64 reg); - std::string IMMEDIATE(uint64 value); - std::string IMMEDIATE(int64 value); - std::string CPR(uint64 reg); - std::string ADDRESS(uint64 value, int instruction_size, Dis_info *info); - - int64 extract_s__se3_4_2_1_0(uint64 instruction); - int64 extract_s__se7_0_6_5_4_3_2_1_s1(uint64 instruction); - int64 extract_s__se8_15_7_6_5_4_3_s3(uint64 instruction); - int64 extract_s__se8_15_7_6_5_4_3_2_s2(uint64 instruction); - int64 extract_s__se8_15_7_6_5_4_3_2_1_0(uint64 instruction); - int64 extract_s__se9_20_19_18_17_16_15_14_13_12_11(uint64 instruction); - int64 extract_s__se10_0_9_8_7_6_5_4_3_2_1_s1(uint64 instruction); - int64 extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(uint64 instruction); - int64 extract_s__se14_0_13_to_1_s1(uint64 instruction); - int64 extract_s__se21_0_20_to_1_s1(uint64 instruction); - int64 extract_s__se25_0_24_to_1_s1(uint64 instruction); - int64 extract_s__se31_15_to_0_31_to_16(uint64 instruction); - int64 extract_s__se31_0_11_to_2_20_to_12_s12(uint64 instruction); - int64 extract_shift__se5_21_20_19_18_17_16(uint64 instruction); - - uint64 extract_ac_15_14(uint64 instruction); - uint64 extract_bit_16_15_14_13_12_11(uint64 instruction); - uint64 extract_bit_23_22_21(uint64 instruction); - uint64 extract_c0s_20_19_18_17_16(uint64 instruction); - uint64 extract_code_17_to_0(uint64 instruction); - uint64 extract_code_18_to_0(uint64 instruction); - uint64 extract_code_1_0(uint64 instruction); - uint64 extract_code_2_1_0(uint64 instruction); - uint64 extract_code_25_24_23_22_21_20_19_18_17_16(uint64 instruction); - uint64 extract_cofun_25_24_23(uint64 instruction); - uint64 extract_count3_14_13_12(uint64 instruction); - uint64 extract_count_3_2_1_0(uint64 instruction); - uint64 extract_count_19_18_17_16(uint64 instruction); - uint64 extract_cs_20_19_18_17_16(uint64 instruction); - uint64 extract_cs_25_24_23_22_21(uint64 instruction); - uint64 extract_ct_25_24_23_22_21(uint64 instruction); - uint64 extract_eu_3_2_1_0(uint64 instruction); - uint64 extract_eu_6_5_4_3_2_1_0(uint64 instruction); - uint64 extract_fd_15_14_13_12_11(uint64 instruction); - uint64 extract_fs_20_19_18_17_16(uint64 instruction); - uint64 extract_ft_15_14_13_12_11(uint64 instruction); - uint64 extract_ft_25_24_23_22_21(uint64 instruction); - uint64 extract_gp_2(uint64 instruction); - uint64 extract_hint_25_24_23_22_21(uint64 instruction); - uint64 extract_hs_20_19_18_17_16(uint64 instruction); - uint64 extract_lsb_4_3_2_1_0(uint64 instruction); - uint64 extract_mask_20_19_18_17_16_15_14(uint64 instruction); - uint64 extract_msbt_10_9_8_7_6(uint64 instruction); - uint64 extract_op_25_24_23_22_21(uint64 instruction); - uint64 extract_op_25_to_3(uint64 instruction); - uint64 extract_rdl_25_24(uint64 instruction); - uint64 extract_rd2_3_8(uint64 instruction); - uint64 extract_rd3_3_2_1(uint64 instruction); - uint64 extract_rd_15_14_13_12_11(uint64 instruction); - uint64 extract_rs3_6_5_4(uint64 instruction); - uint64 extract_rs4_4_2_1_0(uint64 instruction); - uint64 extract_rs_4_3_2_1_0(uint64 instruction); - uint64 extract_rs_20_19_18_17_16(uint64 instruction); - uint64 extract_rsz4_4_2_1_0(uint64 instruction); - uint64 extract_rtl_11(uint64 instruction); - uint64 extract_rt3_9_8_7(uint64 instruction); - uint64 extract_rt4_9_7_6_5(uint64 instruction); - uint64 extract_rt_25_24_23_22_21(uint64 instruction); - uint64 extract_rt_41_40_39_38_37(uint64 instruction); - uint64 extract_rt_9_8_7_6_5(uint64 instruction); - uint64 extract_rtz3_9_8_7(uint64 instruction); - uint64 extract_rtz4_27_26_25_23_22_21(uint64 instruction); - uint64 extract_rtz4_9_7_6_5(uint64 instruction); - uint64 extract_ru_7_6_5_4_3(uint64 instruction); - uint64 extract_sa_15_14_13_12_11(uint64 instruction); - uint64 extract_sa_15_14_13_12(uint64 instruction); - uint64 extract_sa_15_14_13(uint64 instruction); - uint64 extract_sel_13_12_11(uint64 instruction); - uint64 extract_sel_15_14_13_12_11(uint64 instruction); - uint64 extract_shift3_2_1_0(uint64 instruction); - uint64 extract_shift_4_3_2_1_0(uint64 instruction); - uint64 extract_shift_5_4_3_2_1_0(uint64 instruction); - uint64 extract_shift_20_19_18_17_16(uint64 instruction); - uint64 extract_shift_10_9_8_7_6(uint64 instruction); - uint64 extract_shiftx_11_10_9_8_7_6(uint64 instruction); - uint64 extract_shiftx_10_9_8_7__s1(uint64 instruction); - uint64 extract_size_20_19_18_17_16(uint64 instruction); - uint64 extract_stripe_6(uint64 instruction); - uint64 extract_stype_20_19_18_17_16(uint64 instruction); - uint64 extract_u2_10_9(uint64 instruction); - uint64 extract_u_11_10_9_8_7_6_5_4_3_2_1_0(uint64 instruction); - uint64 extract_u_15_to_0(uint64 instruction); - uint64 extract_u_17_to_0(uint64 instruction); - uint64 extract_u_1_0(uint64 instruction); - uint64 extract_u_3_2_1_0__s1(uint64 instruction); - uint64 extract_u_2_1_0__s2(uint64 instruction); - uint64 extract_u_3_2_1_0__s2(uint64 instruction); - uint64 extract_u_4_3_2_1_0__s2(uint64 instruction); - uint64 extract_u_5_4_3_2_1_0__s2(uint64 instruction); - uint64 extract_u_6_5_4_3_2_1_0__s2(uint64 instruction); - uint64 extract_u_31_to_0__s32(uint64 instruction); - uint64 extract_u_10(uint64 instruction); - uint64 extract_u_17_16_15_14_13_12_11(uint64 instruction); - uint64 extract_u_20_19_18_17_16_15_14_13(uint64 instruction); - uint64 extract_u_17_to_1__s1(uint64 instruction); - uint64 extract_u_2_1__s1(uint64 instruction); - uint64 extract_u_17_to_2__s2(uint64 instruction); - uint64 extract_u_20_to_2__s2(uint64 instruction); - uint64 extract_u_20_to_3__s3(uint64 instruction); - uint64 extract_u_3_8__s2(uint64 instruction); - uint64 extract_u_11_10_9_8_7_6_5_4_3__s3(uint64 instruction); - uint64 extract_u_7_6_5_4__s4(uint64 instruction); - bool ADDIU_32__cond(uint64 instruction); bool ADDIU_RS5__cond(uint64 instruction); bool BALRSC_cond(uint64 instruction); From 655fc22f1bc7a16d9da6bd44c43e763bc27d0b8a Mon Sep 17 00:00:00 2001 From: Milica Lazarevic Date: Mon, 12 Sep 2022 14:26:17 +0200 Subject: [PATCH 427/705] disas/nanomips: Remove __cond methods from class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NMD class methods with the conditional_function type like NMD::ADDIU_32__cond, NMD::ADDIU_RS5__cond, etc. are removed from the NMD class. They're now declared global static functions. Therefore, typedef of the function pointer, conditional_function is defined outside of the class. Now that conditional_function type functions are not part of the NMD class we can't access them using the this pointer. Thus, the use of the this pointer has been deleted. Signed-off-by: Milica Lazarevic Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20220912122635.74032-7-milica.lazarevic@syrmia.com> Signed-off-by: Philippe Mathieu-Daudé --- disas/nanomips.cpp | 42 +++++++++++++++++++++--------------------- disas/nanomips.h | 14 ++------------ 2 files changed, 23 insertions(+), 33 deletions(-) diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp index 271afcde07..98a632a3fc 100644 --- a/disas/nanomips.cpp +++ b/disas/nanomips.cpp @@ -784,7 +784,7 @@ int NMD::Disassemble(const uint16 * data, std::string & dis, if ((op_code & table[i].mask) == table[i].value) { /* possible match */ conditional_function cond = table[i].condition; - if ((cond == 0) || (this->*cond)(op_code)) { + if ((cond == NULL) || cond(op_code)) { try { if (table[i].type == pool) { @@ -1672,28 +1672,28 @@ static uint64 extract_u_3_2_1_0__s1(uint64 instruction) -bool NMD::ADDIU_32__cond(uint64 instruction) +static bool ADDIU_32__cond(uint64 instruction) { uint64 rt = extract_rt_25_24_23_22_21(instruction); return rt != 0; } -bool NMD::ADDIU_RS5__cond(uint64 instruction) +static bool ADDIU_RS5__cond(uint64 instruction) { uint64 rt = extract_rt_9_8_7_6_5(instruction); return rt != 0; } -bool NMD::BALRSC_cond(uint64 instruction) +static bool BALRSC_cond(uint64 instruction) { uint64 rt = extract_rt_25_24_23_22_21(instruction); return rt != 0; } -bool NMD::BEQC_16__cond(uint64 instruction) +static bool BEQC_16__cond(uint64 instruction) { uint64 rs3 = extract_rs3_6_5_4(instruction); uint64 rt3 = extract_rt3_9_8_7(instruction); @@ -1702,7 +1702,7 @@ bool NMD::BEQC_16__cond(uint64 instruction) } -bool NMD::BNEC_16__cond(uint64 instruction) +static bool BNEC_16__cond(uint64 instruction) { uint64 rs3 = extract_rs3_6_5_4(instruction); uint64 rt3 = extract_rt3_9_8_7(instruction); @@ -1711,35 +1711,35 @@ bool NMD::BNEC_16__cond(uint64 instruction) } -bool NMD::MOVE_cond(uint64 instruction) +static bool MOVE_cond(uint64 instruction) { uint64 rt = extract_rt_9_8_7_6_5(instruction); return rt != 0; } -bool NMD::P16_BR1_cond(uint64 instruction) +static bool P16_BR1_cond(uint64 instruction) { uint64 u = extract_u_3_2_1_0__s1(instruction); return u != 0; } -bool NMD::PREF_S9__cond(uint64 instruction) +static bool PREF_S9__cond(uint64 instruction) { uint64 hint = extract_hint_25_24_23_22_21(instruction); return hint != 31; } -bool NMD::PREFE_cond(uint64 instruction) +static bool PREFE_cond(uint64 instruction) { uint64 hint = extract_hint_25_24_23_22_21(instruction); return hint != 31; } -bool NMD::SLTU_cond(uint64 instruction) +static bool SLTU_cond(uint64 instruction) { uint64 rd = extract_rd_15_14_13_12_11(instruction); return rd != 0; @@ -16692,7 +16692,7 @@ NMD::Pool NMD::P_ADDIU[2] = { 0xffe00000, 0x00000000, 0 , 0, 0x0 }, /* P.RI */ { instruction , 0 , 0 , 32, - 0xfc000000, 0x00000000, &NMD::ADDIU_32_ , &NMD::ADDIU_32__cond , + 0xfc000000, 0x00000000, &NMD::ADDIU_32_ , &ADDIU_32__cond , 0x0 }, /* ADDIU[32] */ }; @@ -16790,7 +16790,7 @@ NMD::Pool NMD::P_SLTU[2] = { 0xfc00fbff, 0x20000390, 0 , 0, 0x0 }, /* P.DVP */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000390, &NMD::SLTU , &NMD::SLTU_cond , + 0xfc0003ff, 0x20000390, &NMD::SLTU , &SLTU_cond , 0x0 }, /* SLTU */ }; @@ -21335,7 +21335,7 @@ NMD::Pool NMD::P_PREF_S9_[2] = { 0xffe07f00, 0xa7e01800, &NMD::SYNCI , 0, 0x0 }, /* SYNCI */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4001800, &NMD::PREF_S9_ , &NMD::PREF_S9__cond , + 0xfc007f00, 0xa4001800, &NMD::PREF_S9_ , &PREF_S9__cond , 0x0 }, /* PREF[S9] */ }; @@ -21547,7 +21547,7 @@ NMD::Pool NMD::P_PREFE[2] = { 0xffe07f00, 0xa7e01a00, &NMD::SYNCIE , 0, CP0_ | EVA_ }, /* SYNCIE */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4001a00, &NMD::PREFE , &NMD::PREFE_cond , + 0xfc007f00, 0xa4001a00, &NMD::PREFE , &PREFE_cond , CP0_ | EVA_ }, /* PREFE */ }; @@ -21719,7 +21719,7 @@ NMD::Pool NMD::P_BALRSC[2] = { 0xffe0f000, 0x48008000, &NMD::BRSC , 0, 0x0 }, /* BRSC */ { call_instruction , 0 , 0 , 32, - 0xfc00f000, 0x48008000, &NMD::BALRSC , &NMD::BALRSC_cond , + 0xfc00f000, 0x48008000, &NMD::BALRSC , &BALRSC_cond , 0x0 }, /* BALRSC */ }; @@ -22067,7 +22067,7 @@ NMD::Pool NMD::P16_MV[2] = { 0xffe0 , 0x1000 , 0 , 0, 0x0 }, /* P16.RI */ { instruction , 0 , 0 , 16, - 0xfc00 , 0x1000 , &NMD::MOVE , &NMD::MOVE_cond , + 0xfc00 , 0x1000 , &NMD::MOVE , &MOVE_cond , 0x0 }, /* MOVE */ }; @@ -22133,7 +22133,7 @@ NMD::Pool NMD::P_ADDIU_RS5_[2] = { 0xffe8 , 0x9008 , &NMD::NOP_16_ , 0, 0x0 }, /* NOP[16] */ { instruction , 0 , 0 , 16, - 0xfc08 , 0x9008 , &NMD::ADDIU_RS5_ , &NMD::ADDIU_RS5__cond , + 0xfc08 , 0x9008 , &NMD::ADDIU_RS5_ , &ADDIU_RS5__cond , 0x0 }, /* ADDIU[RS5] */ }; @@ -22170,10 +22170,10 @@ NMD::Pool NMD::P16_JRC[2] = { NMD::Pool NMD::P16_BR1[2] = { { branch_instruction , 0 , 0 , 16, - 0xfc00 , 0xd800 , &NMD::BEQC_16_ , &NMD::BEQC_16__cond , + 0xfc00 , 0xd800 , &NMD::BEQC_16_ , &BEQC_16__cond , XMMS_ }, /* BEQC[16] */ { branch_instruction , 0 , 0 , 16, - 0xfc00 , 0xd800 , &NMD::BNEC_16_ , &NMD::BNEC_16__cond , + 0xfc00 , 0xd800 , &NMD::BNEC_16_ , &BNEC_16__cond , XMMS_ }, /* BNEC[16] */ }; @@ -22183,7 +22183,7 @@ NMD::Pool NMD::P16_BR[2] = { 0xfc0f , 0xd800 , 0 , 0, 0x0 }, /* P16.JRC */ { pool , P16_BR1 , 2 , 16, - 0xfc00 , 0xd800 , 0 , &NMD::P16_BR1_cond , + 0xfc00 , 0xd800 , 0 , &P16_BR1_cond , 0x0 }, /* P16.BR1 */ }; diff --git a/disas/nanomips.h b/disas/nanomips.h index 8eca843ef0..af803f4cc0 100644 --- a/disas/nanomips.h +++ b/disas/nanomips.h @@ -64,6 +64,8 @@ typedef struct Dis_info { img_address m_pc; } Dis_info; +typedef bool (*conditional_function)(uint64 instruction); + class NMD { public: @@ -75,7 +77,6 @@ private: typedef std::string(NMD:: *disassembly_function)(uint64 instruction, Dis_info *info); - typedef bool(NMD:: *conditional_function)(uint64 instruction); struct Pool { TABLE_ENTRY_TYPE type; @@ -94,17 +95,6 @@ private: TABLE_ENTRY_TYPE & type, const Pool *table, int table_size, Dis_info *info); - bool ADDIU_32__cond(uint64 instruction); - bool ADDIU_RS5__cond(uint64 instruction); - bool BALRSC_cond(uint64 instruction); - bool BEQC_16__cond(uint64 instruction); - bool BNEC_16__cond(uint64 instruction); - bool MOVE_cond(uint64 instruction); - bool P16_BR1_cond(uint64 instruction); - bool PREF_S9__cond(uint64 instruction); - bool PREFE_cond(uint64 instruction); - bool SLTU_cond(uint64 instruction); - std::string ABS_D(uint64 instruction, Dis_info *info); std::string ABS_S(uint64 instruction, Dis_info *info); std::string ABSQ_S_PH(uint64 instruction, Dis_info *info); From 8d416f6b455d0c73667a2ffa9a0782aa07627d81 Mon Sep 17 00:00:00 2001 From: Milica Lazarevic Date: Mon, 12 Sep 2022 14:26:18 +0200 Subject: [PATCH 428/705] disas/nanomips: Remove disasm methods from class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NMD class methods with the disassembly_function type like NMD::ABS_D, NMD::ABS_S, etc. are removed from the class. They're now declared global static functions. Therefore, typedef of the function pointer, disassembly_function is defined outside of the class. Now that disassembly_function type functions are not part of the NMD class we can't access them using the this pointer. Thus, the use of the this pointer has been deleted. Signed-off-by: Milica Lazarevic Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20220912122635.74032-8-milica.lazarevic@syrmia.com> Signed-off-by: Philippe Mathieu-Daudé --- disas/nanomips.cpp | 2546 ++++++++++++++++++++++---------------------- disas/nanomips.h | 642 +---------- 2 files changed, 1275 insertions(+), 1913 deletions(-) diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp index 98a632a3fc..5482284206 100644 --- a/disas/nanomips.cpp +++ b/disas/nanomips.cpp @@ -802,7 +802,7 @@ int NMD::Disassemble(const uint16 * data, std::string & dis, return -6; } type = table[i].type; - dis = (this->*dis_fn)(op_code, info); + dis = dis_fn(op_code, info); return table[i].instructions_size; } else { dis = "reserved instruction"; @@ -1757,7 +1757,7 @@ static bool SLTU_cond(uint64 instruction) * fs ----- * fd ----- */ -std::string NMD::ABS_D(uint64 instruction, Dis_info *info) +static std::string ABS_D(uint64 instruction, Dis_info *info) { uint64 fd_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -1779,7 +1779,7 @@ std::string NMD::ABS_D(uint64 instruction, Dis_info *info) * fd ----- * fs ----- */ -std::string NMD::ABS_S(uint64 instruction, Dis_info *info) +static std::string ABS_S(uint64 instruction, Dis_info *info) { uint64 fd_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -1801,7 +1801,7 @@ std::string NMD::ABS_S(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -std::string NMD::ABSQ_S_PH(uint64 instruction, Dis_info *info) +static std::string ABSQ_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -1823,7 +1823,7 @@ std::string NMD::ABSQ_S_PH(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -std::string NMD::ABSQ_S_QB(uint64 instruction, Dis_info *info) +static std::string ABSQ_S_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -1845,7 +1845,7 @@ std::string NMD::ABSQ_S_QB(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -std::string NMD::ABSQ_S_W(uint64 instruction, Dis_info *info) +static std::string ABSQ_S_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -1866,7 +1866,7 @@ std::string NMD::ABSQ_S_W(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -std::string NMD::ACLR(uint64 instruction, Dis_info *info) +static std::string ACLR(uint64 instruction, Dis_info *info) { uint64 bit_value = extract_bit_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -1889,7 +1889,7 @@ std::string NMD::ACLR(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -std::string NMD::ADD(uint64 instruction, Dis_info *info) +static std::string ADD(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -1914,7 +1914,7 @@ std::string NMD::ADD(uint64 instruction, Dis_info *info) * fs ----- * fd ----- */ -std::string NMD::ADD_D(uint64 instruction, Dis_info *info) +static std::string ADD_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -1939,7 +1939,7 @@ std::string NMD::ADD_D(uint64 instruction, Dis_info *info) * fs ----- * fd ----- */ -std::string NMD::ADD_S(uint64 instruction, Dis_info *info) +static std::string ADD_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -1962,7 +1962,7 @@ std::string NMD::ADD_S(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -std::string NMD::ADDIU_32_(uint64 instruction, Dis_info *info) +static std::string ADDIU_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -1985,7 +1985,7 @@ std::string NMD::ADDIU_32_(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -std::string NMD::ADDIU_48_(uint64 instruction, Dis_info *info) +static std::string ADDIU_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); @@ -2006,7 +2006,7 @@ std::string NMD::ADDIU_48_(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -std::string NMD::ADDIU_GP48_(uint64 instruction, Dis_info *info) +static std::string ADDIU_GP48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); @@ -2027,7 +2027,7 @@ std::string NMD::ADDIU_GP48_(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -std::string NMD::ADDIU_GP_B_(uint64 instruction, Dis_info *info) +static std::string ADDIU_GP_B_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_0(instruction); @@ -2048,7 +2048,7 @@ std::string NMD::ADDIU_GP_B_(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -std::string NMD::ADDIU_GP_W_(uint64 instruction, Dis_info *info) +static std::string ADDIU_GP_W_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_to_2__s2(instruction); @@ -2069,7 +2069,7 @@ std::string NMD::ADDIU_GP_W_(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -std::string NMD::ADDIU_NEG_(uint64 instruction, Dis_info *info) +static std::string ADDIU_NEG_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2092,7 +2092,7 @@ std::string NMD::ADDIU_NEG_(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -std::string NMD::ADDIU_R1_SP_(uint64 instruction, Dis_info *info) +static std::string ADDIU_R1_SP_(uint64 instruction, Dis_info *info) { uint64 u_value = extract_u_5_4_3_2_1_0__s2(instruction); uint64 rt3_value = extract_rt3_9_8_7(instruction); @@ -2113,7 +2113,7 @@ std::string NMD::ADDIU_R1_SP_(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -std::string NMD::ADDIU_R2_(uint64 instruction, Dis_info *info) +static std::string ADDIU_R2_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -2135,7 +2135,7 @@ std::string NMD::ADDIU_R2_(uint64 instruction, Dis_info *info) * rt ----- * s - --- */ -std::string NMD::ADDIU_RS5_(uint64 instruction, Dis_info *info) +static std::string ADDIU_RS5_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_9_8_7_6_5(instruction); int64 s_value = extract_s__se3_4_2_1_0(instruction); @@ -2157,7 +2157,7 @@ std::string NMD::ADDIU_RS5_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::ADDIUPC_32_(uint64 instruction, Dis_info *info) +static std::string ADDIUPC_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); int64 s_value = extract_s__se21_0_20_to_1_s1(instruction); @@ -2179,7 +2179,7 @@ std::string NMD::ADDIUPC_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::ADDIUPC_48_(uint64 instruction, Dis_info *info) +static std::string ADDIUPC_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); @@ -2201,7 +2201,7 @@ std::string NMD::ADDIUPC_48_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::ADDQ_PH(uint64 instruction, Dis_info *info) +static std::string ADDQ_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2226,7 +2226,7 @@ std::string NMD::ADDQ_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::ADDQ_S_PH(uint64 instruction, Dis_info *info) +static std::string ADDQ_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2250,7 +2250,7 @@ std::string NMD::ADDQ_S_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::ADDQ_S_W(uint64 instruction, Dis_info *info) +static std::string ADDQ_S_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2275,7 +2275,7 @@ std::string NMD::ADDQ_S_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::ADDQH_PH(uint64 instruction, Dis_info *info) +static std::string ADDQH_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2300,7 +2300,7 @@ std::string NMD::ADDQH_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::ADDQH_R_PH(uint64 instruction, Dis_info *info) +static std::string ADDQH_R_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2325,7 +2325,7 @@ std::string NMD::ADDQH_R_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::ADDQH_R_W(uint64 instruction, Dis_info *info) +static std::string ADDQH_R_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2350,7 +2350,7 @@ std::string NMD::ADDQH_R_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::ADDQH_W(uint64 instruction, Dis_info *info) +static std::string ADDQH_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2374,7 +2374,7 @@ std::string NMD::ADDQH_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::ADDSC(uint64 instruction, Dis_info *info) +static std::string ADDSC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2397,7 +2397,7 @@ std::string NMD::ADDSC(uint64 instruction, Dis_info *info) * rs3 --- * rd3 --- */ -std::string NMD::ADDU_16_(uint64 instruction, Dis_info *info) +static std::string ADDU_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -2421,7 +2421,7 @@ std::string NMD::ADDU_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::ADDU_32_(uint64 instruction, Dis_info *info) +static std::string ADDU_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2445,7 +2445,7 @@ std::string NMD::ADDU_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::ADDU_4X4_(uint64 instruction, Dis_info *info) +static std::string ADDU_4X4_(uint64 instruction, Dis_info *info) { uint64 rt4_value = extract_rt4_9_7_6_5(instruction); uint64 rs4_value = extract_rs4_4_2_1_0(instruction); @@ -2467,7 +2467,7 @@ std::string NMD::ADDU_4X4_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::ADDU_PH(uint64 instruction, Dis_info *info) +static std::string ADDU_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2491,7 +2491,7 @@ std::string NMD::ADDU_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::ADDU_QB(uint64 instruction, Dis_info *info) +static std::string ADDU_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2516,7 +2516,7 @@ std::string NMD::ADDU_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::ADDU_S_PH(uint64 instruction, Dis_info *info) +static std::string ADDU_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2540,7 +2540,7 @@ std::string NMD::ADDU_S_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::ADDU_S_QB(uint64 instruction, Dis_info *info) +static std::string ADDU_S_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2565,7 +2565,7 @@ std::string NMD::ADDU_S_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::ADDUH_QB(uint64 instruction, Dis_info *info) +static std::string ADDUH_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2590,7 +2590,7 @@ std::string NMD::ADDUH_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::ADDUH_R_QB(uint64 instruction, Dis_info *info) +static std::string ADDUH_R_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2613,7 +2613,7 @@ std::string NMD::ADDUH_R_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::ADDWC(uint64 instruction, Dis_info *info) +static std::string ADDWC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2637,7 +2637,7 @@ std::string NMD::ADDWC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::ALUIPC(uint64 instruction, Dis_info *info) +static std::string ALUIPC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); int64 s_value = extract_s__se31_0_11_to_2_20_to_12_s12(instruction); @@ -2658,7 +2658,7 @@ std::string NMD::ALUIPC(uint64 instruction, Dis_info *info) * rs3 --- * eu ---- */ -std::string NMD::AND_16_(uint64 instruction, Dis_info *info) +static std::string AND_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -2680,7 +2680,7 @@ std::string NMD::AND_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::AND_32_(uint64 instruction, Dis_info *info) +static std::string AND_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2703,7 +2703,7 @@ std::string NMD::AND_32_(uint64 instruction, Dis_info *info) * rs3 --- * eu ---- */ -std::string NMD::ANDI_16_(uint64 instruction, Dis_info *info) +static std::string ANDI_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -2727,7 +2727,7 @@ std::string NMD::ANDI_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::ANDI_32_(uint64 instruction, Dis_info *info) +static std::string ANDI_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2751,7 +2751,7 @@ std::string NMD::ANDI_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::APPEND(uint64 instruction, Dis_info *info) +static std::string APPEND(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2775,7 +2775,7 @@ std::string NMD::APPEND(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::ASET(uint64 instruction, Dis_info *info) +static std::string ASET(uint64 instruction, Dis_info *info) { uint64 bit_value = extract_bit_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2799,7 +2799,7 @@ std::string NMD::ASET(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::BALC_16_(uint64 instruction, Dis_info *info) +static std::string BALC_16_(uint64 instruction, Dis_info *info) { int64 s_value = extract_s__se10_0_9_8_7_6_5_4_3_2_1_s1(instruction); @@ -2819,7 +2819,7 @@ std::string NMD::BALC_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::BALC_32_(uint64 instruction, Dis_info *info) +static std::string BALC_32_(uint64 instruction, Dis_info *info) { int64 s_value = extract_s__se25_0_24_to_1_s1(instruction); @@ -2839,7 +2839,7 @@ std::string NMD::BALC_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::BALRSC(uint64 instruction, Dis_info *info) +static std::string BALRSC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -2861,7 +2861,7 @@ std::string NMD::BALRSC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::BBEQZC(uint64 instruction, Dis_info *info) +static std::string BBEQZC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 bit_value = extract_bit_16_15_14_13_12_11(instruction); @@ -2885,7 +2885,7 @@ std::string NMD::BBEQZC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::BBNEZC(uint64 instruction, Dis_info *info) +static std::string BBNEZC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 bit_value = extract_bit_16_15_14_13_12_11(instruction); @@ -2909,7 +2909,7 @@ std::string NMD::BBNEZC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::BC_16_(uint64 instruction, Dis_info *info) +static std::string BC_16_(uint64 instruction, Dis_info *info) { int64 s_value = extract_s__se10_0_9_8_7_6_5_4_3_2_1_s1(instruction); @@ -2929,7 +2929,7 @@ std::string NMD::BC_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::BC_32_(uint64 instruction, Dis_info *info) +static std::string BC_32_(uint64 instruction, Dis_info *info) { int64 s_value = extract_s__se25_0_24_to_1_s1(instruction); @@ -2949,7 +2949,7 @@ std::string NMD::BC_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::BC1EQZC(uint64 instruction, Dis_info *info) +static std::string BC1EQZC(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); @@ -2971,7 +2971,7 @@ std::string NMD::BC1EQZC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::BC1NEZC(uint64 instruction, Dis_info *info) +static std::string BC1NEZC(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); @@ -2993,7 +2993,7 @@ std::string NMD::BC1NEZC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::BC2EQZC(uint64 instruction, Dis_info *info) +static std::string BC2EQZC(uint64 instruction, Dis_info *info) { uint64 ct_value = extract_ct_25_24_23_22_21(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); @@ -3015,7 +3015,7 @@ std::string NMD::BC2EQZC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::BC2NEZC(uint64 instruction, Dis_info *info) +static std::string BC2NEZC(uint64 instruction, Dis_info *info) { uint64 ct_value = extract_ct_25_24_23_22_21(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); @@ -3037,7 +3037,7 @@ std::string NMD::BC2NEZC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::BEQC_16_(uint64 instruction, Dis_info *info) +static std::string BEQC_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -3061,7 +3061,7 @@ std::string NMD::BEQC_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::BEQC_32_(uint64 instruction, Dis_info *info) +static std::string BEQC_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -3085,7 +3085,7 @@ std::string NMD::BEQC_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::BEQIC(uint64 instruction, Dis_info *info) +static std::string BEQIC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); @@ -3109,7 +3109,7 @@ std::string NMD::BEQIC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::BEQZC_16_(uint64 instruction, Dis_info *info) +static std::string BEQZC_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); int64 s_value = extract_s__se7_0_6_5_4_3_2_1_s1(instruction); @@ -3131,7 +3131,7 @@ std::string NMD::BEQZC_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::BGEC(uint64 instruction, Dis_info *info) +static std::string BGEC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -3155,7 +3155,7 @@ std::string NMD::BGEC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::BGEIC(uint64 instruction, Dis_info *info) +static std::string BGEIC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); @@ -3179,7 +3179,7 @@ std::string NMD::BGEIC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::BGEIUC(uint64 instruction, Dis_info *info) +static std::string BGEIUC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); @@ -3203,7 +3203,7 @@ std::string NMD::BGEIUC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::BGEUC(uint64 instruction, Dis_info *info) +static std::string BGEUC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -3227,7 +3227,7 @@ std::string NMD::BGEUC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::BLTC(uint64 instruction, Dis_info *info) +static std::string BLTC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -3251,7 +3251,7 @@ std::string NMD::BLTC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::BLTIC(uint64 instruction, Dis_info *info) +static std::string BLTIC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); @@ -3275,7 +3275,7 @@ std::string NMD::BLTIC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::BLTIUC(uint64 instruction, Dis_info *info) +static std::string BLTIUC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); @@ -3299,7 +3299,7 @@ std::string NMD::BLTIUC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::BLTUC(uint64 instruction, Dis_info *info) +static std::string BLTUC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -3323,7 +3323,7 @@ std::string NMD::BLTUC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::BNEC_16_(uint64 instruction, Dis_info *info) +static std::string BNEC_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -3347,7 +3347,7 @@ std::string NMD::BNEC_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::BNEC_32_(uint64 instruction, Dis_info *info) +static std::string BNEC_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -3371,7 +3371,7 @@ std::string NMD::BNEC_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::BNEIC(uint64 instruction, Dis_info *info) +static std::string BNEIC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); @@ -3395,7 +3395,7 @@ std::string NMD::BNEIC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::BNEZC_16_(uint64 instruction, Dis_info *info) +static std::string BNEZC_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); int64 s_value = extract_s__se7_0_6_5_4_3_2_1_s1(instruction); @@ -3417,7 +3417,7 @@ std::string NMD::BNEZC_16_(uint64 instruction, Dis_info *info) * s[13:1] ------------- * s[14] - */ -std::string NMD::BPOSGE32C(uint64 instruction, Dis_info *info) +static std::string BPOSGE32C(uint64 instruction, Dis_info *info) { int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); @@ -3437,7 +3437,7 @@ std::string NMD::BPOSGE32C(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::BREAK_16_(uint64 instruction, Dis_info *info) +static std::string BREAK_16_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_2_1_0(instruction); @@ -3457,7 +3457,7 @@ std::string NMD::BREAK_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::BREAK_32_(uint64 instruction, Dis_info *info) +static std::string BREAK_32_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_18_to_0(instruction); @@ -3477,7 +3477,7 @@ std::string NMD::BREAK_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::BRSC(uint64 instruction, Dis_info *info) +static std::string BRSC(uint64 instruction, Dis_info *info) { uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -3497,7 +3497,7 @@ std::string NMD::BRSC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CACHE(uint64 instruction, Dis_info *info) +static std::string CACHE(uint64 instruction, Dis_info *info) { uint64 op_value = extract_op_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -3521,7 +3521,7 @@ std::string NMD::CACHE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CACHEE(uint64 instruction, Dis_info *info) +static std::string CACHEE(uint64 instruction, Dis_info *info) { uint64 op_value = extract_op_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -3545,7 +3545,7 @@ std::string NMD::CACHEE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CEIL_L_D(uint64 instruction, Dis_info *info) +static std::string CEIL_L_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -3567,7 +3567,7 @@ std::string NMD::CEIL_L_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CEIL_L_S(uint64 instruction, Dis_info *info) +static std::string CEIL_L_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -3589,7 +3589,7 @@ std::string NMD::CEIL_L_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CEIL_W_D(uint64 instruction, Dis_info *info) +static std::string CEIL_W_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -3611,7 +3611,7 @@ std::string NMD::CEIL_W_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CEIL_W_S(uint64 instruction, Dis_info *info) +static std::string CEIL_W_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -3633,7 +3633,7 @@ std::string NMD::CEIL_W_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CFC1(uint64 instruction, Dis_info *info) +static std::string CFC1(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); @@ -3655,7 +3655,7 @@ std::string NMD::CFC1(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CFC2(uint64 instruction, Dis_info *info) +static std::string CFC2(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); @@ -3677,7 +3677,7 @@ std::string NMD::CFC2(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CLASS_D(uint64 instruction, Dis_info *info) +static std::string CLASS_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -3699,7 +3699,7 @@ std::string NMD::CLASS_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CLASS_S(uint64 instruction, Dis_info *info) +static std::string CLASS_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -3721,7 +3721,7 @@ std::string NMD::CLASS_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CLO(uint64 instruction, Dis_info *info) +static std::string CLO(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -3743,7 +3743,7 @@ std::string NMD::CLO(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CLZ(uint64 instruction, Dis_info *info) +static std::string CLZ(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -3765,7 +3765,7 @@ std::string NMD::CLZ(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_AF_D(uint64 instruction, Dis_info *info) +static std::string CMP_AF_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -3789,7 +3789,7 @@ std::string NMD::CMP_AF_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_AF_S(uint64 instruction, Dis_info *info) +static std::string CMP_AF_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -3813,7 +3813,7 @@ std::string NMD::CMP_AF_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_EQ_D(uint64 instruction, Dis_info *info) +static std::string CMP_EQ_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -3836,7 +3836,7 @@ std::string NMD::CMP_EQ_D(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -std::string NMD::CMP_EQ_PH(uint64 instruction, Dis_info *info) +static std::string CMP_EQ_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -3858,7 +3858,7 @@ std::string NMD::CMP_EQ_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_EQ_S(uint64 instruction, Dis_info *info) +static std::string CMP_EQ_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -3882,7 +3882,7 @@ std::string NMD::CMP_EQ_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_LE_D(uint64 instruction, Dis_info *info) +static std::string CMP_LE_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -3905,7 +3905,7 @@ std::string NMD::CMP_LE_D(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -std::string NMD::CMP_LE_PH(uint64 instruction, Dis_info *info) +static std::string CMP_LE_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -3927,7 +3927,7 @@ std::string NMD::CMP_LE_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_LE_S(uint64 instruction, Dis_info *info) +static std::string CMP_LE_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -3951,7 +3951,7 @@ std::string NMD::CMP_LE_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_LT_D(uint64 instruction, Dis_info *info) +static std::string CMP_LT_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -3974,7 +3974,7 @@ std::string NMD::CMP_LT_D(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -std::string NMD::CMP_LT_PH(uint64 instruction, Dis_info *info) +static std::string CMP_LT_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -3996,7 +3996,7 @@ std::string NMD::CMP_LT_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_LT_S(uint64 instruction, Dis_info *info) +static std::string CMP_LT_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4020,7 +4020,7 @@ std::string NMD::CMP_LT_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_NE_D(uint64 instruction, Dis_info *info) +static std::string CMP_NE_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4044,7 +4044,7 @@ std::string NMD::CMP_NE_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_NE_S(uint64 instruction, Dis_info *info) +static std::string CMP_NE_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4068,7 +4068,7 @@ std::string NMD::CMP_NE_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_OR_D(uint64 instruction, Dis_info *info) +static std::string CMP_OR_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4092,7 +4092,7 @@ std::string NMD::CMP_OR_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_OR_S(uint64 instruction, Dis_info *info) +static std::string CMP_OR_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4116,7 +4116,7 @@ std::string NMD::CMP_OR_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_SAF_D(uint64 instruction, Dis_info *info) +static std::string CMP_SAF_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4140,7 +4140,7 @@ std::string NMD::CMP_SAF_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_SAF_S(uint64 instruction, Dis_info *info) +static std::string CMP_SAF_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4164,7 +4164,7 @@ std::string NMD::CMP_SAF_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_SEQ_D(uint64 instruction, Dis_info *info) +static std::string CMP_SEQ_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4188,7 +4188,7 @@ std::string NMD::CMP_SEQ_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_SEQ_S(uint64 instruction, Dis_info *info) +static std::string CMP_SEQ_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4212,7 +4212,7 @@ std::string NMD::CMP_SEQ_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_SLE_D(uint64 instruction, Dis_info *info) +static std::string CMP_SLE_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4236,7 +4236,7 @@ std::string NMD::CMP_SLE_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_SLE_S(uint64 instruction, Dis_info *info) +static std::string CMP_SLE_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4260,7 +4260,7 @@ std::string NMD::CMP_SLE_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_SLT_D(uint64 instruction, Dis_info *info) +static std::string CMP_SLT_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4284,7 +4284,7 @@ std::string NMD::CMP_SLT_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_SLT_S(uint64 instruction, Dis_info *info) +static std::string CMP_SLT_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4308,7 +4308,7 @@ std::string NMD::CMP_SLT_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_SNE_D(uint64 instruction, Dis_info *info) +static std::string CMP_SNE_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4332,7 +4332,7 @@ std::string NMD::CMP_SNE_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_SNE_S(uint64 instruction, Dis_info *info) +static std::string CMP_SNE_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4356,7 +4356,7 @@ std::string NMD::CMP_SNE_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_SOR_D(uint64 instruction, Dis_info *info) +static std::string CMP_SOR_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4380,7 +4380,7 @@ std::string NMD::CMP_SOR_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_SOR_S(uint64 instruction, Dis_info *info) +static std::string CMP_SOR_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4404,7 +4404,7 @@ std::string NMD::CMP_SOR_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_SUEQ_D(uint64 instruction, Dis_info *info) +static std::string CMP_SUEQ_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4428,7 +4428,7 @@ std::string NMD::CMP_SUEQ_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_SUEQ_S(uint64 instruction, Dis_info *info) +static std::string CMP_SUEQ_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4452,7 +4452,7 @@ std::string NMD::CMP_SUEQ_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_SULE_D(uint64 instruction, Dis_info *info) +static std::string CMP_SULE_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4476,7 +4476,7 @@ std::string NMD::CMP_SULE_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_SULE_S(uint64 instruction, Dis_info *info) +static std::string CMP_SULE_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4500,7 +4500,7 @@ std::string NMD::CMP_SULE_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_SULT_D(uint64 instruction, Dis_info *info) +static std::string CMP_SULT_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4524,7 +4524,7 @@ std::string NMD::CMP_SULT_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_SULT_S(uint64 instruction, Dis_info *info) +static std::string CMP_SULT_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4548,7 +4548,7 @@ std::string NMD::CMP_SULT_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_SUN_D(uint64 instruction, Dis_info *info) +static std::string CMP_SUN_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4572,7 +4572,7 @@ std::string NMD::CMP_SUN_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_SUNE_D(uint64 instruction, Dis_info *info) +static std::string CMP_SUNE_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4596,7 +4596,7 @@ std::string NMD::CMP_SUNE_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_SUNE_S(uint64 instruction, Dis_info *info) +static std::string CMP_SUNE_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4620,7 +4620,7 @@ std::string NMD::CMP_SUNE_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_SUN_S(uint64 instruction, Dis_info *info) +static std::string CMP_SUN_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4644,7 +4644,7 @@ std::string NMD::CMP_SUN_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_UEQ_D(uint64 instruction, Dis_info *info) +static std::string CMP_UEQ_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4668,7 +4668,7 @@ std::string NMD::CMP_UEQ_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_UEQ_S(uint64 instruction, Dis_info *info) +static std::string CMP_UEQ_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4692,7 +4692,7 @@ std::string NMD::CMP_UEQ_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_ULE_D(uint64 instruction, Dis_info *info) +static std::string CMP_ULE_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4716,7 +4716,7 @@ std::string NMD::CMP_ULE_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_ULE_S(uint64 instruction, Dis_info *info) +static std::string CMP_ULE_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4740,7 +4740,7 @@ std::string NMD::CMP_ULE_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_ULT_D(uint64 instruction, Dis_info *info) +static std::string CMP_ULT_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4764,7 +4764,7 @@ std::string NMD::CMP_ULT_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_ULT_S(uint64 instruction, Dis_info *info) +static std::string CMP_ULT_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4788,7 +4788,7 @@ std::string NMD::CMP_ULT_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_UN_D(uint64 instruction, Dis_info *info) +static std::string CMP_UN_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4812,7 +4812,7 @@ std::string NMD::CMP_UN_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_UNE_D(uint64 instruction, Dis_info *info) +static std::string CMP_UNE_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4836,7 +4836,7 @@ std::string NMD::CMP_UNE_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_UNE_S(uint64 instruction, Dis_info *info) +static std::string CMP_UNE_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4860,7 +4860,7 @@ std::string NMD::CMP_UNE_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMP_UN_S(uint64 instruction, Dis_info *info) +static std::string CMP_UN_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -4885,7 +4885,7 @@ std::string NMD::CMP_UN_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMPGDU_EQ_QB(uint64 instruction, Dis_info *info) +static std::string CMPGDU_EQ_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -4910,7 +4910,7 @@ std::string NMD::CMPGDU_EQ_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMPGDU_LE_QB(uint64 instruction, Dis_info *info) +static std::string CMPGDU_LE_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -4935,7 +4935,7 @@ std::string NMD::CMPGDU_LE_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMPGDU_LT_QB(uint64 instruction, Dis_info *info) +static std::string CMPGDU_LT_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -4960,7 +4960,7 @@ std::string NMD::CMPGDU_LT_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMPGU_EQ_QB(uint64 instruction, Dis_info *info) +static std::string CMPGU_EQ_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -4985,7 +4985,7 @@ std::string NMD::CMPGU_EQ_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMPGU_LE_QB(uint64 instruction, Dis_info *info) +static std::string CMPGU_LE_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5010,7 +5010,7 @@ std::string NMD::CMPGU_LE_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CMPGU_LT_QB(uint64 instruction, Dis_info *info) +static std::string CMPGU_LT_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5034,7 +5034,7 @@ std::string NMD::CMPGU_LT_QB(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -std::string NMD::CMPU_EQ_QB(uint64 instruction, Dis_info *info) +static std::string CMPU_EQ_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5056,7 +5056,7 @@ std::string NMD::CMPU_EQ_QB(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -std::string NMD::CMPU_LE_QB(uint64 instruction, Dis_info *info) +static std::string CMPU_LE_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5078,7 +5078,7 @@ std::string NMD::CMPU_LE_QB(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -std::string NMD::CMPU_LT_QB(uint64 instruction, Dis_info *info) +static std::string CMPU_LT_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5100,7 +5100,7 @@ std::string NMD::CMPU_LT_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::COP2_1(uint64 instruction, Dis_info *info) +static std::string COP2_1(uint64 instruction, Dis_info *info) { uint64 cofun_value = extract_cofun_25_24_23(instruction); @@ -5120,7 +5120,7 @@ std::string NMD::COP2_1(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CTC1(uint64 instruction, Dis_info *info) +static std::string CTC1(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); @@ -5142,7 +5142,7 @@ std::string NMD::CTC1(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CTC2(uint64 instruction, Dis_info *info) +static std::string CTC2(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); @@ -5164,7 +5164,7 @@ std::string NMD::CTC2(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CVT_D_L(uint64 instruction, Dis_info *info) +static std::string CVT_D_L(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -5186,7 +5186,7 @@ std::string NMD::CVT_D_L(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CVT_D_S(uint64 instruction, Dis_info *info) +static std::string CVT_D_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -5208,7 +5208,7 @@ std::string NMD::CVT_D_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CVT_D_W(uint64 instruction, Dis_info *info) +static std::string CVT_D_W(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -5230,7 +5230,7 @@ std::string NMD::CVT_D_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CVT_L_D(uint64 instruction, Dis_info *info) +static std::string CVT_L_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -5252,7 +5252,7 @@ std::string NMD::CVT_L_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CVT_L_S(uint64 instruction, Dis_info *info) +static std::string CVT_L_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -5274,7 +5274,7 @@ std::string NMD::CVT_L_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CVT_S_D(uint64 instruction, Dis_info *info) +static std::string CVT_S_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -5296,7 +5296,7 @@ std::string NMD::CVT_S_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CVT_S_L(uint64 instruction, Dis_info *info) +static std::string CVT_S_L(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -5318,7 +5318,7 @@ std::string NMD::CVT_S_L(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CVT_S_PL(uint64 instruction, Dis_info *info) +static std::string CVT_S_PL(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -5340,7 +5340,7 @@ std::string NMD::CVT_S_PL(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CVT_S_PU(uint64 instruction, Dis_info *info) +static std::string CVT_S_PU(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -5362,7 +5362,7 @@ std::string NMD::CVT_S_PU(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CVT_S_W(uint64 instruction, Dis_info *info) +static std::string CVT_S_W(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -5384,7 +5384,7 @@ std::string NMD::CVT_S_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CVT_W_D(uint64 instruction, Dis_info *info) +static std::string CVT_W_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -5406,7 +5406,7 @@ std::string NMD::CVT_W_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::CVT_W_S(uint64 instruction, Dis_info *info) +static std::string CVT_W_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -5428,7 +5428,7 @@ std::string NMD::CVT_W_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DADDIU_48_(uint64 instruction, Dis_info *info) +static std::string DADDIU_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); @@ -5450,7 +5450,7 @@ std::string NMD::DADDIU_48_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DADDIU_NEG_(uint64 instruction, Dis_info *info) +static std::string DADDIU_NEG_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5474,7 +5474,7 @@ std::string NMD::DADDIU_NEG_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DADDIU_U12_(uint64 instruction, Dis_info *info) +static std::string DADDIU_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5498,7 +5498,7 @@ std::string NMD::DADDIU_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DADD(uint64 instruction, Dis_info *info) +static std::string DADD(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5522,7 +5522,7 @@ std::string NMD::DADD(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DADDU(uint64 instruction, Dis_info *info) +static std::string DADDU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5546,7 +5546,7 @@ std::string NMD::DADDU(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DCLO(uint64 instruction, Dis_info *info) +static std::string DCLO(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5568,7 +5568,7 @@ std::string NMD::DCLO(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DCLZ(uint64 instruction, Dis_info *info) +static std::string DCLZ(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5590,7 +5590,7 @@ std::string NMD::DCLZ(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DDIV(uint64 instruction, Dis_info *info) +static std::string DDIV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5614,7 +5614,7 @@ std::string NMD::DDIV(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DDIVU(uint64 instruction, Dis_info *info) +static std::string DDIVU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5638,7 +5638,7 @@ std::string NMD::DDIVU(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DERET(uint64 instruction, Dis_info *info) +static std::string DERET(uint64 instruction, Dis_info *info) { (void)instruction; @@ -5656,7 +5656,7 @@ std::string NMD::DERET(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DEXTM(uint64 instruction, Dis_info *info) +static std::string DEXTM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5682,7 +5682,7 @@ std::string NMD::DEXTM(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DEXT(uint64 instruction, Dis_info *info) +static std::string DEXT(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5708,7 +5708,7 @@ std::string NMD::DEXT(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DEXTU(uint64 instruction, Dis_info *info) +static std::string DEXTU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5734,7 +5734,7 @@ std::string NMD::DEXTU(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DINSM(uint64 instruction, Dis_info *info) +static std::string DINSM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5762,7 +5762,7 @@ std::string NMD::DINSM(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DINS(uint64 instruction, Dis_info *info) +static std::string DINS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5790,7 +5790,7 @@ std::string NMD::DINS(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DINSU(uint64 instruction, Dis_info *info) +static std::string DINSU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5818,7 +5818,7 @@ std::string NMD::DINSU(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DI(uint64 instruction, Dis_info *info) +static std::string DI(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); @@ -5838,7 +5838,7 @@ std::string NMD::DI(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DIV(uint64 instruction, Dis_info *info) +static std::string DIV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5862,7 +5862,7 @@ std::string NMD::DIV(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DIV_D(uint64 instruction, Dis_info *info) +static std::string DIV_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -5886,7 +5886,7 @@ std::string NMD::DIV_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DIV_S(uint64 instruction, Dis_info *info) +static std::string DIV_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -5910,7 +5910,7 @@ std::string NMD::DIV_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DIVU(uint64 instruction, Dis_info *info) +static std::string DIVU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5934,7 +5934,7 @@ std::string NMD::DIVU(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DLSA(uint64 instruction, Dis_info *info) +static std::string DLSA(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -5960,7 +5960,7 @@ std::string NMD::DLSA(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DLUI_48_(uint64 instruction, Dis_info *info) +static std::string DLUI_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); uint64 u_value = extract_u_31_to_0__s32(instruction); @@ -5982,7 +5982,7 @@ std::string NMD::DLUI_48_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DMFC0(uint64 instruction, Dis_info *info) +static std::string DMFC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); @@ -6006,7 +6006,7 @@ std::string NMD::DMFC0(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DMFC1(uint64 instruction, Dis_info *info) +static std::string DMFC1(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -6028,7 +6028,7 @@ std::string NMD::DMFC1(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DMFC2(uint64 instruction, Dis_info *info) +static std::string DMFC2(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); @@ -6050,7 +6050,7 @@ std::string NMD::DMFC2(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DMFGC0(uint64 instruction, Dis_info *info) +static std::string DMFGC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); @@ -6074,7 +6074,7 @@ std::string NMD::DMFGC0(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DMOD(uint64 instruction, Dis_info *info) +static std::string DMOD(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6098,7 +6098,7 @@ std::string NMD::DMOD(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DMODU(uint64 instruction, Dis_info *info) +static std::string DMODU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6122,7 +6122,7 @@ std::string NMD::DMODU(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DMTC0(uint64 instruction, Dis_info *info) +static std::string DMTC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); @@ -6146,7 +6146,7 @@ std::string NMD::DMTC0(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DMTC1(uint64 instruction, Dis_info *info) +static std::string DMTC1(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -6168,7 +6168,7 @@ std::string NMD::DMTC1(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DMTC2(uint64 instruction, Dis_info *info) +static std::string DMTC2(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); @@ -6190,7 +6190,7 @@ std::string NMD::DMTC2(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DMTGC0(uint64 instruction, Dis_info *info) +static std::string DMTGC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); @@ -6214,7 +6214,7 @@ std::string NMD::DMTGC0(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DMT(uint64 instruction, Dis_info *info) +static std::string DMT(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); @@ -6234,7 +6234,7 @@ std::string NMD::DMT(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DMUH(uint64 instruction, Dis_info *info) +static std::string DMUH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6258,7 +6258,7 @@ std::string NMD::DMUH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DMUHU(uint64 instruction, Dis_info *info) +static std::string DMUHU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6282,7 +6282,7 @@ std::string NMD::DMUHU(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DMUL(uint64 instruction, Dis_info *info) +static std::string DMUL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6306,7 +6306,7 @@ std::string NMD::DMUL(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DMULU(uint64 instruction, Dis_info *info) +static std::string DMULU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6331,7 +6331,7 @@ std::string NMD::DMULU(uint64 instruction, Dis_info *info) * rs ----- * ac -- */ -std::string NMD::DPA_W_PH(uint64 instruction, Dis_info *info) +static std::string DPA_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6355,7 +6355,7 @@ std::string NMD::DPA_W_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DPAQ_SA_L_W(uint64 instruction, Dis_info *info) +static std::string DPAQ_SA_L_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6379,7 +6379,7 @@ std::string NMD::DPAQ_SA_L_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DPAQ_S_W_PH(uint64 instruction, Dis_info *info) +static std::string DPAQ_S_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6403,7 +6403,7 @@ std::string NMD::DPAQ_S_W_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DPAQX_SA_W_PH(uint64 instruction, Dis_info *info) +static std::string DPAQX_SA_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6427,7 +6427,7 @@ std::string NMD::DPAQX_SA_W_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DPAQX_S_W_PH(uint64 instruction, Dis_info *info) +static std::string DPAQX_S_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6451,7 +6451,7 @@ std::string NMD::DPAQX_S_W_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DPAU_H_QBL(uint64 instruction, Dis_info *info) +static std::string DPAU_H_QBL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6475,7 +6475,7 @@ std::string NMD::DPAU_H_QBL(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DPAU_H_QBR(uint64 instruction, Dis_info *info) +static std::string DPAU_H_QBR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6499,7 +6499,7 @@ std::string NMD::DPAU_H_QBR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DPAX_W_PH(uint64 instruction, Dis_info *info) +static std::string DPAX_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6523,7 +6523,7 @@ std::string NMD::DPAX_W_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DPS_W_PH(uint64 instruction, Dis_info *info) +static std::string DPS_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6547,7 +6547,7 @@ std::string NMD::DPS_W_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DPSQ_SA_L_W(uint64 instruction, Dis_info *info) +static std::string DPSQ_SA_L_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6571,7 +6571,7 @@ std::string NMD::DPSQ_SA_L_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DPSQ_S_W_PH(uint64 instruction, Dis_info *info) +static std::string DPSQ_S_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6595,7 +6595,7 @@ std::string NMD::DPSQ_S_W_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DPSQX_SA_W_PH(uint64 instruction, Dis_info *info) +static std::string DPSQX_SA_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6619,7 +6619,7 @@ std::string NMD::DPSQX_SA_W_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DPSQX_S_W_PH(uint64 instruction, Dis_info *info) +static std::string DPSQX_S_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6643,7 +6643,7 @@ std::string NMD::DPSQX_S_W_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DPSU_H_QBL(uint64 instruction, Dis_info *info) +static std::string DPSU_H_QBL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6667,7 +6667,7 @@ std::string NMD::DPSU_H_QBL(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DPSU_H_QBR(uint64 instruction, Dis_info *info) +static std::string DPSU_H_QBR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6691,7 +6691,7 @@ std::string NMD::DPSU_H_QBR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DPSX_W_PH(uint64 instruction, Dis_info *info) +static std::string DPSX_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6715,7 +6715,7 @@ std::string NMD::DPSX_W_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DROTR(uint64 instruction, Dis_info *info) +static std::string DROTR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6739,7 +6739,7 @@ std::string NMD::DROTR(uint64 instruction, Dis_info *info) * rs ----- * shift ----- */ -std::string NMD::DROTR32(uint64 instruction, Dis_info *info) +static std::string DROTR32(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6763,7 +6763,7 @@ std::string NMD::DROTR32(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DROTRV(uint64 instruction, Dis_info *info) +static std::string DROTRV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6787,7 +6787,7 @@ std::string NMD::DROTRV(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DROTX(uint64 instruction, Dis_info *info) +static std::string DROTX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6813,7 +6813,7 @@ std::string NMD::DROTX(uint64 instruction, Dis_info *info) * rs ----- * shift ----- */ -std::string NMD::DSLL(uint64 instruction, Dis_info *info) +static std::string DSLL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6837,7 +6837,7 @@ std::string NMD::DSLL(uint64 instruction, Dis_info *info) * rs ----- * shift ----- */ -std::string NMD::DSLL32(uint64 instruction, Dis_info *info) +static std::string DSLL32(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6861,7 +6861,7 @@ std::string NMD::DSLL32(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DSLLV(uint64 instruction, Dis_info *info) +static std::string DSLLV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6885,7 +6885,7 @@ std::string NMD::DSLLV(uint64 instruction, Dis_info *info) * rs ----- * shift ----- */ -std::string NMD::DSRA(uint64 instruction, Dis_info *info) +static std::string DSRA(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6909,7 +6909,7 @@ std::string NMD::DSRA(uint64 instruction, Dis_info *info) * rs ----- * shift ----- */ -std::string NMD::DSRA32(uint64 instruction, Dis_info *info) +static std::string DSRA32(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6933,7 +6933,7 @@ std::string NMD::DSRA32(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DSRAV(uint64 instruction, Dis_info *info) +static std::string DSRAV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6957,7 +6957,7 @@ std::string NMD::DSRAV(uint64 instruction, Dis_info *info) * rs ----- * shift ----- */ -std::string NMD::DSRL(uint64 instruction, Dis_info *info) +static std::string DSRL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -6981,7 +6981,7 @@ std::string NMD::DSRL(uint64 instruction, Dis_info *info) * rs ----- * shift ----- */ -std::string NMD::DSRL32(uint64 instruction, Dis_info *info) +static std::string DSRL32(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7005,7 +7005,7 @@ std::string NMD::DSRL32(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DSRLV(uint64 instruction, Dis_info *info) +static std::string DSRLV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7029,7 +7029,7 @@ std::string NMD::DSRLV(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DSUB(uint64 instruction, Dis_info *info) +static std::string DSUB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7053,7 +7053,7 @@ std::string NMD::DSUB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DSUBU(uint64 instruction, Dis_info *info) +static std::string DSUBU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7077,7 +7077,7 @@ std::string NMD::DSUBU(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DVPE(uint64 instruction, Dis_info *info) +static std::string DVPE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); @@ -7097,7 +7097,7 @@ std::string NMD::DVPE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::DVP(uint64 instruction, Dis_info *info) +static std::string DVP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); @@ -7117,7 +7117,7 @@ std::string NMD::DVP(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::EHB(uint64 instruction, Dis_info *info) +static std::string EHB(uint64 instruction, Dis_info *info) { (void)instruction; @@ -7135,7 +7135,7 @@ std::string NMD::EHB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::EI(uint64 instruction, Dis_info *info) +static std::string EI(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); @@ -7155,7 +7155,7 @@ std::string NMD::EI(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::EMT(uint64 instruction, Dis_info *info) +static std::string EMT(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); @@ -7175,7 +7175,7 @@ std::string NMD::EMT(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::ERET(uint64 instruction, Dis_info *info) +static std::string ERET(uint64 instruction, Dis_info *info) { (void)instruction; @@ -7193,7 +7193,7 @@ std::string NMD::ERET(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::ERETNC(uint64 instruction, Dis_info *info) +static std::string ERETNC(uint64 instruction, Dis_info *info) { (void)instruction; @@ -7211,7 +7211,7 @@ std::string NMD::ERETNC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::EVP(uint64 instruction, Dis_info *info) +static std::string EVP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); @@ -7231,7 +7231,7 @@ std::string NMD::EVP(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::EVPE(uint64 instruction, Dis_info *info) +static std::string EVPE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); @@ -7251,7 +7251,7 @@ std::string NMD::EVPE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::EXT(uint64 instruction, Dis_info *info) +static std::string EXT(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7277,7 +7277,7 @@ std::string NMD::EXT(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::EXTD(uint64 instruction, Dis_info *info) +static std::string EXTD(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7303,7 +7303,7 @@ std::string NMD::EXTD(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::EXTD32(uint64 instruction, Dis_info *info) +static std::string EXTD32(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7329,7 +7329,7 @@ std::string NMD::EXTD32(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::EXTPDP(uint64 instruction, Dis_info *info) +static std::string EXTPDP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 size_value = extract_size_20_19_18_17_16(instruction); @@ -7353,7 +7353,7 @@ std::string NMD::EXTPDP(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::EXTPDPV(uint64 instruction, Dis_info *info) +static std::string EXTPDPV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7377,7 +7377,7 @@ std::string NMD::EXTPDPV(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::EXTP(uint64 instruction, Dis_info *info) +static std::string EXTP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 size_value = extract_size_20_19_18_17_16(instruction); @@ -7401,7 +7401,7 @@ std::string NMD::EXTP(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::EXTPV(uint64 instruction, Dis_info *info) +static std::string EXTPV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7426,7 +7426,7 @@ std::string NMD::EXTPV(uint64 instruction, Dis_info *info) * shift ----- * ac -- */ -std::string NMD::EXTR_RS_W(uint64 instruction, Dis_info *info) +static std::string EXTR_RS_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 shift_value = extract_shift_20_19_18_17_16(instruction); @@ -7451,7 +7451,7 @@ std::string NMD::EXTR_RS_W(uint64 instruction, Dis_info *info) * shift ----- * ac -- */ -std::string NMD::EXTR_R_W(uint64 instruction, Dis_info *info) +static std::string EXTR_R_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 shift_value = extract_shift_20_19_18_17_16(instruction); @@ -7476,7 +7476,7 @@ std::string NMD::EXTR_R_W(uint64 instruction, Dis_info *info) * shift ----- * ac -- */ -std::string NMD::EXTR_S_H(uint64 instruction, Dis_info *info) +static std::string EXTR_S_H(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 shift_value = extract_shift_20_19_18_17_16(instruction); @@ -7501,7 +7501,7 @@ std::string NMD::EXTR_S_H(uint64 instruction, Dis_info *info) * shift ----- * ac -- */ -std::string NMD::EXTR_W(uint64 instruction, Dis_info *info) +static std::string EXTR_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 shift_value = extract_shift_20_19_18_17_16(instruction); @@ -7526,7 +7526,7 @@ std::string NMD::EXTR_W(uint64 instruction, Dis_info *info) * rs ----- * ac -- */ -std::string NMD::EXTRV_RS_W(uint64 instruction, Dis_info *info) +static std::string EXTRV_RS_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7551,7 +7551,7 @@ std::string NMD::EXTRV_RS_W(uint64 instruction, Dis_info *info) * rs ----- * ac -- */ -std::string NMD::EXTRV_R_W(uint64 instruction, Dis_info *info) +static std::string EXTRV_R_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7576,7 +7576,7 @@ std::string NMD::EXTRV_R_W(uint64 instruction, Dis_info *info) * rs ----- * ac -- */ -std::string NMD::EXTRV_S_H(uint64 instruction, Dis_info *info) +static std::string EXTRV_S_H(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7601,7 +7601,7 @@ std::string NMD::EXTRV_S_H(uint64 instruction, Dis_info *info) * rs ----- * ac -- */ -std::string NMD::EXTRV_W(uint64 instruction, Dis_info *info) +static std::string EXTRV_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7626,7 +7626,7 @@ std::string NMD::EXTRV_W(uint64 instruction, Dis_info *info) * rd ----- * shift ----- */ -std::string NMD::EXTW(uint64 instruction, Dis_info *info) +static std::string EXTW(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7652,7 +7652,7 @@ std::string NMD::EXTW(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::FLOOR_L_D(uint64 instruction, Dis_info *info) +static std::string FLOOR_L_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -7674,7 +7674,7 @@ std::string NMD::FLOOR_L_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::FLOOR_L_S(uint64 instruction, Dis_info *info) +static std::string FLOOR_L_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -7696,7 +7696,7 @@ std::string NMD::FLOOR_L_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::FLOOR_W_D(uint64 instruction, Dis_info *info) +static std::string FLOOR_W_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -7718,7 +7718,7 @@ std::string NMD::FLOOR_W_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::FLOOR_W_S(uint64 instruction, Dis_info *info) +static std::string FLOOR_W_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -7740,7 +7740,7 @@ std::string NMD::FLOOR_W_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::FORK(uint64 instruction, Dis_info *info) +static std::string FORK(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7764,7 +7764,7 @@ std::string NMD::FORK(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::HYPCALL(uint64 instruction, Dis_info *info) +static std::string HYPCALL(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_17_to_0(instruction); @@ -7784,7 +7784,7 @@ std::string NMD::HYPCALL(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::HYPCALL_16_(uint64 instruction, Dis_info *info) +static std::string HYPCALL_16_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_1_0(instruction); @@ -7804,7 +7804,7 @@ std::string NMD::HYPCALL_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::INS(uint64 instruction, Dis_info *info) +static std::string INS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7831,7 +7831,7 @@ std::string NMD::INS(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -std::string NMD::INSV(uint64 instruction, Dis_info *info) +static std::string INSV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7853,7 +7853,7 @@ std::string NMD::INSV(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::IRET(uint64 instruction, Dis_info *info) +static std::string IRET(uint64 instruction, Dis_info *info) { (void)instruction; @@ -7871,7 +7871,7 @@ std::string NMD::IRET(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::JALRC_16_(uint64 instruction, Dis_info *info) +static std::string JALRC_16_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_9_8_7_6_5(instruction); @@ -7891,7 +7891,7 @@ std::string NMD::JALRC_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::JALRC_32_(uint64 instruction, Dis_info *info) +static std::string JALRC_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7913,7 +7913,7 @@ std::string NMD::JALRC_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::JALRC_HB(uint64 instruction, Dis_info *info) +static std::string JALRC_HB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -7935,7 +7935,7 @@ std::string NMD::JALRC_HB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::JRC(uint64 instruction, Dis_info *info) +static std::string JRC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_9_8_7_6_5(instruction); @@ -7955,7 +7955,7 @@ std::string NMD::JRC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LB_16_(uint64 instruction, Dis_info *info) +static std::string LB_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -7979,7 +7979,7 @@ std::string NMD::LB_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LB_GP_(uint64 instruction, Dis_info *info) +static std::string LB_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_0(instruction); @@ -8001,7 +8001,7 @@ std::string NMD::LB_GP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LB_S9_(uint64 instruction, Dis_info *info) +static std::string LB_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8025,7 +8025,7 @@ std::string NMD::LB_S9_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LB_U12_(uint64 instruction, Dis_info *info) +static std::string LB_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8049,7 +8049,7 @@ std::string NMD::LB_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LBE(uint64 instruction, Dis_info *info) +static std::string LBE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8073,7 +8073,7 @@ std::string NMD::LBE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LBU_16_(uint64 instruction, Dis_info *info) +static std::string LBU_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -8097,7 +8097,7 @@ std::string NMD::LBU_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LBU_GP_(uint64 instruction, Dis_info *info) +static std::string LBU_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_0(instruction); @@ -8119,7 +8119,7 @@ std::string NMD::LBU_GP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LBU_S9_(uint64 instruction, Dis_info *info) +static std::string LBU_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8143,7 +8143,7 @@ std::string NMD::LBU_S9_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LBU_U12_(uint64 instruction, Dis_info *info) +static std::string LBU_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8167,7 +8167,7 @@ std::string NMD::LBU_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LBUE(uint64 instruction, Dis_info *info) +static std::string LBUE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8191,7 +8191,7 @@ std::string NMD::LBUE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LBUX(uint64 instruction, Dis_info *info) +static std::string LBUX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8215,7 +8215,7 @@ std::string NMD::LBUX(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LBX(uint64 instruction, Dis_info *info) +static std::string LBX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8239,7 +8239,7 @@ std::string NMD::LBX(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LD_GP_(uint64 instruction, Dis_info *info) +static std::string LD_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_to_3__s3(instruction); @@ -8261,7 +8261,7 @@ std::string NMD::LD_GP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LD_S9_(uint64 instruction, Dis_info *info) +static std::string LD_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8285,7 +8285,7 @@ std::string NMD::LD_S9_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LD_U12_(uint64 instruction, Dis_info *info) +static std::string LD_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8309,7 +8309,7 @@ std::string NMD::LD_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LDC1_GP_(uint64 instruction, Dis_info *info) +static std::string LDC1_GP_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_2__s2(instruction); @@ -8331,7 +8331,7 @@ std::string NMD::LDC1_GP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LDC1_S9_(uint64 instruction, Dis_info *info) +static std::string LDC1_S9_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8355,7 +8355,7 @@ std::string NMD::LDC1_S9_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LDC1_U12_(uint64 instruction, Dis_info *info) +static std::string LDC1_U12_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8379,7 +8379,7 @@ std::string NMD::LDC1_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LDC1XS(uint64 instruction, Dis_info *info) +static std::string LDC1XS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8403,7 +8403,7 @@ std::string NMD::LDC1XS(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LDC1X(uint64 instruction, Dis_info *info) +static std::string LDC1X(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8427,7 +8427,7 @@ std::string NMD::LDC1X(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LDC2(uint64 instruction, Dis_info *info) +static std::string LDC2(uint64 instruction, Dis_info *info) { uint64 ct_value = extract_ct_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8451,7 +8451,7 @@ std::string NMD::LDC2(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LDM(uint64 instruction, Dis_info *info) +static std::string LDM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8477,7 +8477,7 @@ std::string NMD::LDM(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LDPC_48_(uint64 instruction, Dis_info *info) +static std::string LDPC_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); @@ -8499,7 +8499,7 @@ std::string NMD::LDPC_48_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LDX(uint64 instruction, Dis_info *info) +static std::string LDX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8523,7 +8523,7 @@ std::string NMD::LDX(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LDXS(uint64 instruction, Dis_info *info) +static std::string LDXS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8547,7 +8547,7 @@ std::string NMD::LDXS(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LH_16_(uint64 instruction, Dis_info *info) +static std::string LH_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -8571,7 +8571,7 @@ std::string NMD::LH_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LH_GP_(uint64 instruction, Dis_info *info) +static std::string LH_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_1__s1(instruction); @@ -8593,7 +8593,7 @@ std::string NMD::LH_GP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LH_S9_(uint64 instruction, Dis_info *info) +static std::string LH_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8617,7 +8617,7 @@ std::string NMD::LH_S9_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LH_U12_(uint64 instruction, Dis_info *info) +static std::string LH_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8641,7 +8641,7 @@ std::string NMD::LH_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LHE(uint64 instruction, Dis_info *info) +static std::string LHE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8665,7 +8665,7 @@ std::string NMD::LHE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LHU_16_(uint64 instruction, Dis_info *info) +static std::string LHU_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -8689,7 +8689,7 @@ std::string NMD::LHU_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LHU_GP_(uint64 instruction, Dis_info *info) +static std::string LHU_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_1__s1(instruction); @@ -8711,7 +8711,7 @@ std::string NMD::LHU_GP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LHU_S9_(uint64 instruction, Dis_info *info) +static std::string LHU_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8735,7 +8735,7 @@ std::string NMD::LHU_S9_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LHU_U12_(uint64 instruction, Dis_info *info) +static std::string LHU_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8759,7 +8759,7 @@ std::string NMD::LHU_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LHUE(uint64 instruction, Dis_info *info) +static std::string LHUE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8783,7 +8783,7 @@ std::string NMD::LHUE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LHUX(uint64 instruction, Dis_info *info) +static std::string LHUX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8807,7 +8807,7 @@ std::string NMD::LHUX(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LHUXS(uint64 instruction, Dis_info *info) +static std::string LHUXS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8831,7 +8831,7 @@ std::string NMD::LHUXS(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LHXS(uint64 instruction, Dis_info *info) +static std::string LHXS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8855,7 +8855,7 @@ std::string NMD::LHXS(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LHX(uint64 instruction, Dis_info *info) +static std::string LHX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8879,7 +8879,7 @@ std::string NMD::LHX(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LI_16_(uint64 instruction, Dis_info *info) +static std::string LI_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 eu_value = extract_eu_6_5_4_3_2_1_0(instruction); @@ -8901,7 +8901,7 @@ std::string NMD::LI_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LI_48_(uint64 instruction, Dis_info *info) +static std::string LI_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); @@ -8923,7 +8923,7 @@ std::string NMD::LI_48_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LL(uint64 instruction, Dis_info *info) +static std::string LL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8947,7 +8947,7 @@ std::string NMD::LL(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LLD(uint64 instruction, Dis_info *info) +static std::string LLD(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8971,7 +8971,7 @@ std::string NMD::LLD(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LLDP(uint64 instruction, Dis_info *info) +static std::string LLDP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -8995,7 +8995,7 @@ std::string NMD::LLDP(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LLE(uint64 instruction, Dis_info *info) +static std::string LLE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9019,7 +9019,7 @@ std::string NMD::LLE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LLWP(uint64 instruction, Dis_info *info) +static std::string LLWP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9043,7 +9043,7 @@ std::string NMD::LLWP(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LLWPE(uint64 instruction, Dis_info *info) +static std::string LLWPE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9067,7 +9067,7 @@ std::string NMD::LLWPE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LSA(uint64 instruction, Dis_info *info) +static std::string LSA(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9093,7 +9093,7 @@ std::string NMD::LSA(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LUI(uint64 instruction, Dis_info *info) +static std::string LUI(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); int64 s_value = extract_s__se31_0_11_to_2_20_to_12_s12(instruction); @@ -9115,7 +9115,7 @@ std::string NMD::LUI(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LW_16_(uint64 instruction, Dis_info *info) +static std::string LW_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -9139,7 +9139,7 @@ std::string NMD::LW_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LW_4X4_(uint64 instruction, Dis_info *info) +static std::string LW_4X4_(uint64 instruction, Dis_info *info) { uint64 rt4_value = extract_rt4_9_7_6_5(instruction); uint64 rs4_value = extract_rs4_4_2_1_0(instruction); @@ -9163,7 +9163,7 @@ std::string NMD::LW_4X4_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LW_GP_(uint64 instruction, Dis_info *info) +static std::string LW_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_to_2__s2(instruction); @@ -9185,7 +9185,7 @@ std::string NMD::LW_GP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LW_GP16_(uint64 instruction, Dis_info *info) +static std::string LW_GP16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 u_value = extract_u_6_5_4_3_2_1_0__s2(instruction); @@ -9207,7 +9207,7 @@ std::string NMD::LW_GP16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LW_S9_(uint64 instruction, Dis_info *info) +static std::string LW_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9231,7 +9231,7 @@ std::string NMD::LW_S9_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LW_SP_(uint64 instruction, Dis_info *info) +static std::string LW_SP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_9_8_7_6_5(instruction); uint64 u_value = extract_u_4_3_2_1_0__s2(instruction); @@ -9253,7 +9253,7 @@ std::string NMD::LW_SP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LW_U12_(uint64 instruction, Dis_info *info) +static std::string LW_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9277,7 +9277,7 @@ std::string NMD::LW_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LWC1_GP_(uint64 instruction, Dis_info *info) +static std::string LWC1_GP_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_2__s2(instruction); @@ -9299,7 +9299,7 @@ std::string NMD::LWC1_GP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LWC1_S9_(uint64 instruction, Dis_info *info) +static std::string LWC1_S9_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9323,7 +9323,7 @@ std::string NMD::LWC1_S9_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LWC1_U12_(uint64 instruction, Dis_info *info) +static std::string LWC1_U12_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9347,7 +9347,7 @@ std::string NMD::LWC1_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LWC1X(uint64 instruction, Dis_info *info) +static std::string LWC1X(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9371,7 +9371,7 @@ std::string NMD::LWC1X(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LWC1XS(uint64 instruction, Dis_info *info) +static std::string LWC1XS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9395,7 +9395,7 @@ std::string NMD::LWC1XS(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LWC2(uint64 instruction, Dis_info *info) +static std::string LWC2(uint64 instruction, Dis_info *info) { uint64 ct_value = extract_ct_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9419,7 +9419,7 @@ std::string NMD::LWC2(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LWE(uint64 instruction, Dis_info *info) +static std::string LWE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9443,7 +9443,7 @@ std::string NMD::LWE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LWM(uint64 instruction, Dis_info *info) +static std::string LWM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9469,7 +9469,7 @@ std::string NMD::LWM(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LWPC_48_(uint64 instruction, Dis_info *info) +static std::string LWPC_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); @@ -9491,7 +9491,7 @@ std::string NMD::LWPC_48_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LWU_GP_(uint64 instruction, Dis_info *info) +static std::string LWU_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_2__s2(instruction); @@ -9513,7 +9513,7 @@ std::string NMD::LWU_GP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LWU_S9_(uint64 instruction, Dis_info *info) +static std::string LWU_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9537,7 +9537,7 @@ std::string NMD::LWU_S9_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LWU_U12_(uint64 instruction, Dis_info *info) +static std::string LWU_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9561,7 +9561,7 @@ std::string NMD::LWU_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LWUX(uint64 instruction, Dis_info *info) +static std::string LWUX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9585,7 +9585,7 @@ std::string NMD::LWUX(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LWUXS(uint64 instruction, Dis_info *info) +static std::string LWUXS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9609,7 +9609,7 @@ std::string NMD::LWUXS(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LWX(uint64 instruction, Dis_info *info) +static std::string LWX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9633,7 +9633,7 @@ std::string NMD::LWX(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LWXS_16_(uint64 instruction, Dis_info *info) +static std::string LWXS_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -9657,7 +9657,7 @@ std::string NMD::LWXS_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::LWXS_32_(uint64 instruction, Dis_info *info) +static std::string LWXS_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9682,7 +9682,7 @@ std::string NMD::LWXS_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MADD_DSP_(uint64 instruction, Dis_info *info) +static std::string MADD_DSP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9706,7 +9706,7 @@ std::string NMD::MADD_DSP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MADDF_D(uint64 instruction, Dis_info *info) +static std::string MADDF_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -9730,7 +9730,7 @@ std::string NMD::MADDF_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MADDF_S(uint64 instruction, Dis_info *info) +static std::string MADDF_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -9755,7 +9755,7 @@ std::string NMD::MADDF_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MADDU_DSP_(uint64 instruction, Dis_info *info) +static std::string MADDU_DSP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9780,7 +9780,7 @@ std::string NMD::MADDU_DSP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MAQ_S_W_PHL(uint64 instruction, Dis_info *info) +static std::string MAQ_S_W_PHL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9805,7 +9805,7 @@ std::string NMD::MAQ_S_W_PHL(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MAQ_S_W_PHR(uint64 instruction, Dis_info *info) +static std::string MAQ_S_W_PHR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9830,7 +9830,7 @@ std::string NMD::MAQ_S_W_PHR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MAQ_SA_W_PHL(uint64 instruction, Dis_info *info) +static std::string MAQ_SA_W_PHL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9855,7 +9855,7 @@ std::string NMD::MAQ_SA_W_PHL(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MAQ_SA_W_PHR(uint64 instruction, Dis_info *info) +static std::string MAQ_SA_W_PHR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -9879,7 +9879,7 @@ std::string NMD::MAQ_SA_W_PHR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MAX_D(uint64 instruction, Dis_info *info) +static std::string MAX_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -9903,7 +9903,7 @@ std::string NMD::MAX_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MAX_S(uint64 instruction, Dis_info *info) +static std::string MAX_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -9927,7 +9927,7 @@ std::string NMD::MAX_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MAXA_D(uint64 instruction, Dis_info *info) +static std::string MAXA_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -9951,7 +9951,7 @@ std::string NMD::MAXA_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MAXA_S(uint64 instruction, Dis_info *info) +static std::string MAXA_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -9975,7 +9975,7 @@ std::string NMD::MAXA_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MFC0(uint64 instruction, Dis_info *info) +static std::string MFC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); @@ -9999,7 +9999,7 @@ std::string NMD::MFC0(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MFC1(uint64 instruction, Dis_info *info) +static std::string MFC1(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -10021,7 +10021,7 @@ std::string NMD::MFC1(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MFC2(uint64 instruction, Dis_info *info) +static std::string MFC2(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); @@ -10043,7 +10043,7 @@ std::string NMD::MFC2(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MFGC0(uint64 instruction, Dis_info *info) +static std::string MFGC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); @@ -10067,7 +10067,7 @@ std::string NMD::MFGC0(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MFHC0(uint64 instruction, Dis_info *info) +static std::string MFHC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); @@ -10091,7 +10091,7 @@ std::string NMD::MFHC0(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MFHC1(uint64 instruction, Dis_info *info) +static std::string MFHC1(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -10113,7 +10113,7 @@ std::string NMD::MFHC1(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MFHC2(uint64 instruction, Dis_info *info) +static std::string MFHC2(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); @@ -10135,7 +10135,7 @@ std::string NMD::MFHC2(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MFHGC0(uint64 instruction, Dis_info *info) +static std::string MFHGC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); @@ -10158,7 +10158,7 @@ std::string NMD::MFHGC0(uint64 instruction, Dis_info *info) * rt ----- * ac -- */ -std::string NMD::MFHI_DSP_(uint64 instruction, Dis_info *info) +static std::string MFHI_DSP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 ac_value = extract_ac_15_14(instruction); @@ -10180,7 +10180,7 @@ std::string NMD::MFHI_DSP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MFHTR(uint64 instruction, Dis_info *info) +static std::string MFHTR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); @@ -10205,7 +10205,7 @@ std::string NMD::MFHTR(uint64 instruction, Dis_info *info) * rt ----- * ac -- */ -std::string NMD::MFLO_DSP_(uint64 instruction, Dis_info *info) +static std::string MFLO_DSP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 ac_value = extract_ac_15_14(instruction); @@ -10227,7 +10227,7 @@ std::string NMD::MFLO_DSP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MFTR(uint64 instruction, Dis_info *info) +static std::string MFTR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); @@ -10253,7 +10253,7 @@ std::string NMD::MFTR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MIN_D(uint64 instruction, Dis_info *info) +static std::string MIN_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -10277,7 +10277,7 @@ std::string NMD::MIN_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MIN_S(uint64 instruction, Dis_info *info) +static std::string MIN_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -10301,7 +10301,7 @@ std::string NMD::MIN_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MINA_D(uint64 instruction, Dis_info *info) +static std::string MINA_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -10325,7 +10325,7 @@ std::string NMD::MINA_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MINA_S(uint64 instruction, Dis_info *info) +static std::string MINA_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -10349,7 +10349,7 @@ std::string NMD::MINA_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MOD(uint64 instruction, Dis_info *info) +static std::string MOD(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -10373,7 +10373,7 @@ std::string NMD::MOD(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MODSUB(uint64 instruction, Dis_info *info) +static std::string MODSUB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -10397,7 +10397,7 @@ std::string NMD::MODSUB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MODU(uint64 instruction, Dis_info *info) +static std::string MODU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -10421,7 +10421,7 @@ std::string NMD::MODU(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MOV_D(uint64 instruction, Dis_info *info) +static std::string MOV_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -10443,7 +10443,7 @@ std::string NMD::MOV_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MOV_S(uint64 instruction, Dis_info *info) +static std::string MOV_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -10465,7 +10465,7 @@ std::string NMD::MOV_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MOVE_BALC(uint64 instruction, Dis_info *info) +static std::string MOVE_BALC(uint64 instruction, Dis_info *info) { uint64 rtz4_value = extract_rtz4_27_26_25_23_22_21(instruction); uint64 rd1_value = extract_rdl_25_24(instruction); @@ -10489,7 +10489,7 @@ std::string NMD::MOVE_BALC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MOVEP(uint64 instruction, Dis_info *info) +static std::string MOVEP(uint64 instruction, Dis_info *info) { uint64 rtz4_value = extract_rtz4_9_7_6_5(instruction); uint64 rd2_value = extract_rd2_3_8(instruction); @@ -10516,7 +10516,7 @@ std::string NMD::MOVEP(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MOVEP_REV_(uint64 instruction, Dis_info *info) +static std::string MOVEP_REV_(uint64 instruction, Dis_info *info) { uint64 rt4_value = extract_rt4_9_7_6_5(instruction); uint64 rd2_value = extract_rd2_3_8(instruction); @@ -10543,7 +10543,7 @@ std::string NMD::MOVEP_REV_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MOVE(uint64 instruction, Dis_info *info) +static std::string MOVE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_9_8_7_6_5(instruction); uint64 rs_value = extract_rs_4_3_2_1_0(instruction); @@ -10565,7 +10565,7 @@ std::string NMD::MOVE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MOVN(uint64 instruction, Dis_info *info) +static std::string MOVN(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -10589,7 +10589,7 @@ std::string NMD::MOVN(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MOVZ(uint64 instruction, Dis_info *info) +static std::string MOVZ(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -10613,7 +10613,7 @@ std::string NMD::MOVZ(uint64 instruction, Dis_info *info) * rs ----- * ac -- */ -std::string NMD::MSUB_DSP_(uint64 instruction, Dis_info *info) +static std::string MSUB_DSP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -10637,7 +10637,7 @@ std::string NMD::MSUB_DSP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MSUBF_D(uint64 instruction, Dis_info *info) +static std::string MSUBF_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -10661,7 +10661,7 @@ std::string NMD::MSUBF_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MSUBF_S(uint64 instruction, Dis_info *info) +static std::string MSUBF_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -10685,7 +10685,7 @@ std::string NMD::MSUBF_S(uint64 instruction, Dis_info *info) * rs ----- * ac -- */ -std::string NMD::MSUBU_DSP_(uint64 instruction, Dis_info *info) +static std::string MSUBU_DSP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -10709,7 +10709,7 @@ std::string NMD::MSUBU_DSP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MTC0(uint64 instruction, Dis_info *info) +static std::string MTC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); @@ -10733,7 +10733,7 @@ std::string NMD::MTC0(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MTC1(uint64 instruction, Dis_info *info) +static std::string MTC1(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -10755,7 +10755,7 @@ std::string NMD::MTC1(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MTC2(uint64 instruction, Dis_info *info) +static std::string MTC2(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); @@ -10777,7 +10777,7 @@ std::string NMD::MTC2(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MTGC0(uint64 instruction, Dis_info *info) +static std::string MTGC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); @@ -10801,7 +10801,7 @@ std::string NMD::MTGC0(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MTHC0(uint64 instruction, Dis_info *info) +static std::string MTHC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); @@ -10825,7 +10825,7 @@ std::string NMD::MTHC0(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MTHC1(uint64 instruction, Dis_info *info) +static std::string MTHC1(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -10847,7 +10847,7 @@ std::string NMD::MTHC1(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MTHC2(uint64 instruction, Dis_info *info) +static std::string MTHC2(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); @@ -10869,7 +10869,7 @@ std::string NMD::MTHC2(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MTHGC0(uint64 instruction, Dis_info *info) +static std::string MTHGC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); @@ -10892,7 +10892,7 @@ std::string NMD::MTHGC0(uint64 instruction, Dis_info *info) * rs ----- * ac -- */ -std::string NMD::MTHI_DSP_(uint64 instruction, Dis_info *info) +static std::string MTHI_DSP_(uint64 instruction, Dis_info *info) { uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); @@ -10913,7 +10913,7 @@ std::string NMD::MTHI_DSP_(uint64 instruction, Dis_info *info) * rs ----- * ac -- */ -std::string NMD::MTHLIP(uint64 instruction, Dis_info *info) +static std::string MTHLIP(uint64 instruction, Dis_info *info) { uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); @@ -10935,7 +10935,7 @@ std::string NMD::MTHLIP(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MTHTR(uint64 instruction, Dis_info *info) +static std::string MTHTR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); @@ -10960,7 +10960,7 @@ std::string NMD::MTHTR(uint64 instruction, Dis_info *info) * rs ----- * ac -- */ -std::string NMD::MTLO_DSP_(uint64 instruction, Dis_info *info) +static std::string MTLO_DSP_(uint64 instruction, Dis_info *info) { uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); @@ -10982,7 +10982,7 @@ std::string NMD::MTLO_DSP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MTTR(uint64 instruction, Dis_info *info) +static std::string MTTR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); @@ -11008,7 +11008,7 @@ std::string NMD::MTTR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MUH(uint64 instruction, Dis_info *info) +static std::string MUH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11032,7 +11032,7 @@ std::string NMD::MUH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MUHU(uint64 instruction, Dis_info *info) +static std::string MUHU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11056,7 +11056,7 @@ std::string NMD::MUHU(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MUL_32_(uint64 instruction, Dis_info *info) +static std::string MUL_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11080,7 +11080,7 @@ std::string NMD::MUL_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MUL_4X4_(uint64 instruction, Dis_info *info) +static std::string MUL_4X4_(uint64 instruction, Dis_info *info) { uint64 rt4_value = extract_rt4_9_7_6_5(instruction); uint64 rs4_value = extract_rs4_4_2_1_0(instruction); @@ -11102,7 +11102,7 @@ std::string NMD::MUL_4X4_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MUL_D(uint64 instruction, Dis_info *info) +static std::string MUL_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -11127,7 +11127,7 @@ std::string NMD::MUL_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MUL_PH(uint64 instruction, Dis_info *info) +static std::string MUL_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11152,7 +11152,7 @@ std::string NMD::MUL_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MUL_S_PH(uint64 instruction, Dis_info *info) +static std::string MUL_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11176,7 +11176,7 @@ std::string NMD::MUL_S_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MUL_S(uint64 instruction, Dis_info *info) +static std::string MUL_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -11201,7 +11201,7 @@ std::string NMD::MUL_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MULEQ_S_W_PHL(uint64 instruction, Dis_info *info) +static std::string MULEQ_S_W_PHL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11226,7 +11226,7 @@ std::string NMD::MULEQ_S_W_PHL(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MULEQ_S_W_PHR(uint64 instruction, Dis_info *info) +static std::string MULEQ_S_W_PHR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11251,7 +11251,7 @@ std::string NMD::MULEQ_S_W_PHR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MULEU_S_PH_QBL(uint64 instruction, Dis_info *info) +static std::string MULEU_S_PH_QBL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11276,7 +11276,7 @@ std::string NMD::MULEU_S_PH_QBL(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MULEU_S_PH_QBR(uint64 instruction, Dis_info *info) +static std::string MULEU_S_PH_QBR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11301,7 +11301,7 @@ std::string NMD::MULEU_S_PH_QBR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MULQ_RS_PH(uint64 instruction, Dis_info *info) +static std::string MULQ_RS_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11326,7 +11326,7 @@ std::string NMD::MULQ_RS_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MULQ_RS_W(uint64 instruction, Dis_info *info) +static std::string MULQ_RS_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11351,7 +11351,7 @@ std::string NMD::MULQ_RS_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MULQ_S_PH(uint64 instruction, Dis_info *info) +static std::string MULQ_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11376,7 +11376,7 @@ std::string NMD::MULQ_S_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MULQ_S_W(uint64 instruction, Dis_info *info) +static std::string MULQ_S_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11401,7 +11401,7 @@ std::string NMD::MULQ_S_W(uint64 instruction, Dis_info *info) * rs ----- * ac -- */ -std::string NMD::MULSA_W_PH(uint64 instruction, Dis_info *info) +static std::string MULSA_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11426,7 +11426,7 @@ std::string NMD::MULSA_W_PH(uint64 instruction, Dis_info *info) * rs ----- * ac -- */ -std::string NMD::MULSAQ_S_W_PH(uint64 instruction, Dis_info *info) +static std::string MULSAQ_S_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11450,7 +11450,7 @@ std::string NMD::MULSAQ_S_W_PH(uint64 instruction, Dis_info *info) * rs ----- * ac -- */ -std::string NMD::MULT_DSP_(uint64 instruction, Dis_info *info) +static std::string MULT_DSP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11474,7 +11474,7 @@ std::string NMD::MULT_DSP_(uint64 instruction, Dis_info *info) * rs ----- * ac -- */ -std::string NMD::MULTU_DSP_(uint64 instruction, Dis_info *info) +static std::string MULTU_DSP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11498,7 +11498,7 @@ std::string NMD::MULTU_DSP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::MULU(uint64 instruction, Dis_info *info) +static std::string MULU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11522,7 +11522,7 @@ std::string NMD::MULU(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::NEG_D(uint64 instruction, Dis_info *info) +static std::string NEG_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -11544,7 +11544,7 @@ std::string NMD::NEG_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::NEG_S(uint64 instruction, Dis_info *info) +static std::string NEG_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -11566,7 +11566,7 @@ std::string NMD::NEG_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::NOP_16_(uint64 instruction, Dis_info *info) +static std::string NOP_16_(uint64 instruction, Dis_info *info) { (void)instruction; @@ -11584,7 +11584,7 @@ std::string NMD::NOP_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::NOP_32_(uint64 instruction, Dis_info *info) +static std::string NOP_32_(uint64 instruction, Dis_info *info) { (void)instruction; @@ -11602,7 +11602,7 @@ std::string NMD::NOP_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::NOR(uint64 instruction, Dis_info *info) +static std::string NOR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11626,7 +11626,7 @@ std::string NMD::NOR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::NOT_16_(uint64 instruction, Dis_info *info) +static std::string NOT_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -11648,7 +11648,7 @@ std::string NMD::NOT_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::OR_16_(uint64 instruction, Dis_info *info) +static std::string OR_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -11670,7 +11670,7 @@ std::string NMD::OR_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::OR_32_(uint64 instruction, Dis_info *info) +static std::string OR_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11694,7 +11694,7 @@ std::string NMD::OR_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::ORI(uint64 instruction, Dis_info *info) +static std::string ORI(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11719,7 +11719,7 @@ std::string NMD::ORI(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::PACKRL_PH(uint64 instruction, Dis_info *info) +static std::string PACKRL_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11743,7 +11743,7 @@ std::string NMD::PACKRL_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::PAUSE(uint64 instruction, Dis_info *info) +static std::string PAUSE(uint64 instruction, Dis_info *info) { (void)instruction; @@ -11762,7 +11762,7 @@ std::string NMD::PAUSE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::PICK_PH(uint64 instruction, Dis_info *info) +static std::string PICK_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11787,7 +11787,7 @@ std::string NMD::PICK_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::PICK_QB(uint64 instruction, Dis_info *info) +static std::string PICK_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11812,7 +11812,7 @@ std::string NMD::PICK_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::PRECEQ_W_PHL(uint64 instruction, Dis_info *info) +static std::string PRECEQ_W_PHL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11835,7 +11835,7 @@ std::string NMD::PRECEQ_W_PHL(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::PRECEQ_W_PHR(uint64 instruction, Dis_info *info) +static std::string PRECEQ_W_PHR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11858,7 +11858,7 @@ std::string NMD::PRECEQ_W_PHR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::PRECEQU_PH_QBLA(uint64 instruction, Dis_info *info) +static std::string PRECEQU_PH_QBLA(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11881,7 +11881,7 @@ std::string NMD::PRECEQU_PH_QBLA(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::PRECEQU_PH_QBL(uint64 instruction, Dis_info *info) +static std::string PRECEQU_PH_QBL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11904,7 +11904,7 @@ std::string NMD::PRECEQU_PH_QBL(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::PRECEQU_PH_QBRA(uint64 instruction, Dis_info *info) +static std::string PRECEQU_PH_QBRA(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11927,7 +11927,7 @@ std::string NMD::PRECEQU_PH_QBRA(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::PRECEQU_PH_QBR(uint64 instruction, Dis_info *info) +static std::string PRECEQU_PH_QBR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11951,7 +11951,7 @@ std::string NMD::PRECEQU_PH_QBR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::PRECEU_PH_QBLA(uint64 instruction, Dis_info *info) +static std::string PRECEU_PH_QBLA(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11974,7 +11974,7 @@ std::string NMD::PRECEU_PH_QBLA(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::PRECEU_PH_QBL(uint64 instruction, Dis_info *info) +static std::string PRECEU_PH_QBL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -11998,7 +11998,7 @@ std::string NMD::PRECEU_PH_QBL(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::PRECEU_PH_QBRA(uint64 instruction, Dis_info *info) +static std::string PRECEU_PH_QBRA(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12021,7 +12021,7 @@ std::string NMD::PRECEU_PH_QBRA(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::PRECEU_PH_QBR(uint64 instruction, Dis_info *info) +static std::string PRECEU_PH_QBR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12044,7 +12044,7 @@ std::string NMD::PRECEU_PH_QBR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::PRECR_QB_PH(uint64 instruction, Dis_info *info) +static std::string PRECR_QB_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12069,7 +12069,7 @@ std::string NMD::PRECR_QB_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::PRECR_SRA_PH_W(uint64 instruction, Dis_info *info) +static std::string PRECR_SRA_PH_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12094,7 +12094,7 @@ std::string NMD::PRECR_SRA_PH_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::PRECR_SRA_R_PH_W(uint64 instruction, Dis_info *info) +static std::string PRECR_SRA_R_PH_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12119,7 +12119,7 @@ std::string NMD::PRECR_SRA_R_PH_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::PRECRQ_PH_W(uint64 instruction, Dis_info *info) +static std::string PRECRQ_PH_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12144,7 +12144,7 @@ std::string NMD::PRECRQ_PH_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::PRECRQ_QB_PH(uint64 instruction, Dis_info *info) +static std::string PRECRQ_QB_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12169,7 +12169,7 @@ std::string NMD::PRECRQ_QB_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::PRECRQ_RS_PH_W(uint64 instruction, Dis_info *info) +static std::string PRECRQ_RS_PH_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12194,7 +12194,7 @@ std::string NMD::PRECRQ_RS_PH_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::PRECRQU_S_QB_PH(uint64 instruction, Dis_info *info) +static std::string PRECRQU_S_QB_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12218,7 +12218,7 @@ std::string NMD::PRECRQU_S_QB_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::PREF_S9_(uint64 instruction, Dis_info *info) +static std::string PREF_S9_(uint64 instruction, Dis_info *info) { uint64 hint_value = extract_hint_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12242,7 +12242,7 @@ std::string NMD::PREF_S9_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::PREF_U12_(uint64 instruction, Dis_info *info) +static std::string PREF_U12_(uint64 instruction, Dis_info *info) { uint64 hint_value = extract_hint_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12266,7 +12266,7 @@ std::string NMD::PREF_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::PREFE(uint64 instruction, Dis_info *info) +static std::string PREFE(uint64 instruction, Dis_info *info) { uint64 hint_value = extract_hint_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12290,7 +12290,7 @@ std::string NMD::PREFE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::PREPEND(uint64 instruction, Dis_info *info) +static std::string PREPEND(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12313,7 +12313,7 @@ std::string NMD::PREPEND(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -std::string NMD::RADDU_W_QB(uint64 instruction, Dis_info *info) +static std::string RADDU_W_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12334,7 +12334,7 @@ std::string NMD::RADDU_W_QB(uint64 instruction, Dis_info *info) * rt ----- * mask ------- */ -std::string NMD::RDDSP(uint64 instruction, Dis_info *info) +static std::string RDDSP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 mask_value = extract_mask_20_19_18_17_16_15_14(instruction); @@ -12356,7 +12356,7 @@ std::string NMD::RDDSP(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::RDHWR(uint64 instruction, Dis_info *info) +static std::string RDHWR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 hs_value = extract_hs_20_19_18_17_16(instruction); @@ -12380,7 +12380,7 @@ std::string NMD::RDHWR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::RDPGPR(uint64 instruction, Dis_info *info) +static std::string RDPGPR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12402,7 +12402,7 @@ std::string NMD::RDPGPR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::RECIP_D(uint64 instruction, Dis_info *info) +static std::string RECIP_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -12424,7 +12424,7 @@ std::string NMD::RECIP_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::RECIP_S(uint64 instruction, Dis_info *info) +static std::string RECIP_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -12446,7 +12446,7 @@ std::string NMD::RECIP_S(uint64 instruction, Dis_info *info) * rt ----- * s ---------- */ -std::string NMD::REPL_PH(uint64 instruction, Dis_info *info) +static std::string REPL_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); int64 s_value = extract_s__se9_20_19_18_17_16_15_14_13_12_11(instruction); @@ -12468,7 +12468,7 @@ std::string NMD::REPL_PH(uint64 instruction, Dis_info *info) * rt ----- * u -------- */ -std::string NMD::REPL_QB(uint64 instruction, Dis_info *info) +static std::string REPL_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_19_18_17_16_15_14_13(instruction); @@ -12490,7 +12490,7 @@ std::string NMD::REPL_QB(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -std::string NMD::REPLV_PH(uint64 instruction, Dis_info *info) +static std::string REPLV_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12511,7 +12511,7 @@ std::string NMD::REPLV_PH(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -std::string NMD::REPLV_QB(uint64 instruction, Dis_info *info) +static std::string REPLV_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12533,7 +12533,7 @@ std::string NMD::REPLV_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::RESTORE_32_(uint64 instruction, Dis_info *info) +static std::string RESTORE_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 count_value = extract_count_19_18_17_16(instruction); @@ -12556,7 +12556,7 @@ std::string NMD::RESTORE_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::RESTORE_JRC_16_(uint64 instruction, Dis_info *info) +static std::string RESTORE_JRC_16_(uint64 instruction, Dis_info *info) { uint64 rt1_value = extract_rtl_11(instruction); uint64 u_value = extract_u_7_6_5_4__s4(instruction); @@ -12578,7 +12578,7 @@ std::string NMD::RESTORE_JRC_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::RESTORE_JRC_32_(uint64 instruction, Dis_info *info) +static std::string RESTORE_JRC_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 count_value = extract_count_19_18_17_16(instruction); @@ -12601,7 +12601,7 @@ std::string NMD::RESTORE_JRC_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::RESTOREF(uint64 instruction, Dis_info *info) +static std::string RESTOREF(uint64 instruction, Dis_info *info) { uint64 count_value = extract_count_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3__s3(instruction); @@ -12623,7 +12623,7 @@ std::string NMD::RESTOREF(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::RINT_D(uint64 instruction, Dis_info *info) +static std::string RINT_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -12645,7 +12645,7 @@ std::string NMD::RINT_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::RINT_S(uint64 instruction, Dis_info *info) +static std::string RINT_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -12667,7 +12667,7 @@ std::string NMD::RINT_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::ROTR(uint64 instruction, Dis_info *info) +static std::string ROTR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12691,7 +12691,7 @@ std::string NMD::ROTR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::ROTRV(uint64 instruction, Dis_info *info) +static std::string ROTRV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12715,7 +12715,7 @@ std::string NMD::ROTRV(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::ROTX(uint64 instruction, Dis_info *info) +static std::string ROTX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12744,7 +12744,7 @@ std::string NMD::ROTX(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::ROUND_L_D(uint64 instruction, Dis_info *info) +static std::string ROUND_L_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -12766,7 +12766,7 @@ std::string NMD::ROUND_L_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::ROUND_L_S(uint64 instruction, Dis_info *info) +static std::string ROUND_L_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -12788,7 +12788,7 @@ std::string NMD::ROUND_L_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::ROUND_W_D(uint64 instruction, Dis_info *info) +static std::string ROUND_W_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -12810,7 +12810,7 @@ std::string NMD::ROUND_W_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::ROUND_W_S(uint64 instruction, Dis_info *info) +static std::string ROUND_W_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -12832,7 +12832,7 @@ std::string NMD::ROUND_W_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::RSQRT_D(uint64 instruction, Dis_info *info) +static std::string RSQRT_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -12854,7 +12854,7 @@ std::string NMD::RSQRT_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::RSQRT_S(uint64 instruction, Dis_info *info) +static std::string RSQRT_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -12876,7 +12876,7 @@ std::string NMD::RSQRT_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SAVE_16_(uint64 instruction, Dis_info *info) +static std::string SAVE_16_(uint64 instruction, Dis_info *info) { uint64 rt1_value = extract_rtl_11(instruction); uint64 u_value = extract_u_7_6_5_4__s4(instruction); @@ -12898,7 +12898,7 @@ std::string NMD::SAVE_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SAVE_32_(uint64 instruction, Dis_info *info) +static std::string SAVE_32_(uint64 instruction, Dis_info *info) { uint64 count_value = extract_count_19_18_17_16(instruction); uint64 rt_value = extract_rt_25_24_23_22_21(instruction); @@ -12921,7 +12921,7 @@ std::string NMD::SAVE_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SAVEF(uint64 instruction, Dis_info *info) +static std::string SAVEF(uint64 instruction, Dis_info *info) { uint64 count_value = extract_count_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3__s3(instruction); @@ -12943,7 +12943,7 @@ std::string NMD::SAVEF(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SB_16_(uint64 instruction, Dis_info *info) +static std::string SB_16_(uint64 instruction, Dis_info *info) { uint64 rtz3_value = extract_rtz3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -12967,7 +12967,7 @@ std::string NMD::SB_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SB_GP_(uint64 instruction, Dis_info *info) +static std::string SB_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_0(instruction); @@ -12989,7 +12989,7 @@ std::string NMD::SB_GP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SB_S9_(uint64 instruction, Dis_info *info) +static std::string SB_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13013,7 +13013,7 @@ std::string NMD::SB_S9_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SB_U12_(uint64 instruction, Dis_info *info) +static std::string SB_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13037,7 +13037,7 @@ std::string NMD::SB_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SBE(uint64 instruction, Dis_info *info) +static std::string SBE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13061,7 +13061,7 @@ std::string NMD::SBE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SBX(uint64 instruction, Dis_info *info) +static std::string SBX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13085,7 +13085,7 @@ std::string NMD::SBX(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SC(uint64 instruction, Dis_info *info) +static std::string SC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13109,7 +13109,7 @@ std::string NMD::SC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SCD(uint64 instruction, Dis_info *info) +static std::string SCD(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13133,7 +13133,7 @@ std::string NMD::SCD(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SCDP(uint64 instruction, Dis_info *info) +static std::string SCDP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13157,7 +13157,7 @@ std::string NMD::SCDP(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SCE(uint64 instruction, Dis_info *info) +static std::string SCE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13181,7 +13181,7 @@ std::string NMD::SCE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SCWP(uint64 instruction, Dis_info *info) +static std::string SCWP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13205,7 +13205,7 @@ std::string NMD::SCWP(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SCWPE(uint64 instruction, Dis_info *info) +static std::string SCWPE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13229,7 +13229,7 @@ std::string NMD::SCWPE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SD_GP_(uint64 instruction, Dis_info *info) +static std::string SD_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_to_3__s3(instruction); @@ -13251,7 +13251,7 @@ std::string NMD::SD_GP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SD_S9_(uint64 instruction, Dis_info *info) +static std::string SD_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13275,7 +13275,7 @@ std::string NMD::SD_S9_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SD_U12_(uint64 instruction, Dis_info *info) +static std::string SD_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13299,7 +13299,7 @@ std::string NMD::SD_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SDBBP_16_(uint64 instruction, Dis_info *info) +static std::string SDBBP_16_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_2_1_0(instruction); @@ -13319,7 +13319,7 @@ std::string NMD::SDBBP_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SDBBP_32_(uint64 instruction, Dis_info *info) +static std::string SDBBP_32_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_18_to_0(instruction); @@ -13339,7 +13339,7 @@ std::string NMD::SDBBP_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SDC1_GP_(uint64 instruction, Dis_info *info) +static std::string SDC1_GP_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_2__s2(instruction); @@ -13361,7 +13361,7 @@ std::string NMD::SDC1_GP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SDC1_S9_(uint64 instruction, Dis_info *info) +static std::string SDC1_S9_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13385,7 +13385,7 @@ std::string NMD::SDC1_S9_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SDC1_U12_(uint64 instruction, Dis_info *info) +static std::string SDC1_U12_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13409,7 +13409,7 @@ std::string NMD::SDC1_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SDC1X(uint64 instruction, Dis_info *info) +static std::string SDC1X(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13433,7 +13433,7 @@ std::string NMD::SDC1X(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SDC1XS(uint64 instruction, Dis_info *info) +static std::string SDC1XS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13457,7 +13457,7 @@ std::string NMD::SDC1XS(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SDC2(uint64 instruction, Dis_info *info) +static std::string SDC2(uint64 instruction, Dis_info *info) { uint64 cs_value = extract_cs_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13481,7 +13481,7 @@ std::string NMD::SDC2(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SDM(uint64 instruction, Dis_info *info) +static std::string SDM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13507,7 +13507,7 @@ std::string NMD::SDM(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SDPC_48_(uint64 instruction, Dis_info *info) +static std::string SDPC_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); @@ -13529,7 +13529,7 @@ std::string NMD::SDPC_48_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SDXS(uint64 instruction, Dis_info *info) +static std::string SDXS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13553,7 +13553,7 @@ std::string NMD::SDXS(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SDX(uint64 instruction, Dis_info *info) +static std::string SDX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13577,7 +13577,7 @@ std::string NMD::SDX(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SEB(uint64 instruction, Dis_info *info) +static std::string SEB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13599,7 +13599,7 @@ std::string NMD::SEB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SEH(uint64 instruction, Dis_info *info) +static std::string SEH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13621,7 +13621,7 @@ std::string NMD::SEH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SEL_D(uint64 instruction, Dis_info *info) +static std::string SEL_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -13645,7 +13645,7 @@ std::string NMD::SEL_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SEL_S(uint64 instruction, Dis_info *info) +static std::string SEL_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -13669,7 +13669,7 @@ std::string NMD::SEL_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SELEQZ_D(uint64 instruction, Dis_info *info) +static std::string SELEQZ_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -13693,7 +13693,7 @@ std::string NMD::SELEQZ_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SELEQZ_S(uint64 instruction, Dis_info *info) +static std::string SELEQZ_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -13717,7 +13717,7 @@ std::string NMD::SELEQZ_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SELNEZ_D(uint64 instruction, Dis_info *info) +static std::string SELNEZ_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -13741,7 +13741,7 @@ std::string NMD::SELNEZ_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SELNEZ_S(uint64 instruction, Dis_info *info) +static std::string SELNEZ_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -13765,7 +13765,7 @@ std::string NMD::SELNEZ_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SEQI(uint64 instruction, Dis_info *info) +static std::string SEQI(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13789,7 +13789,7 @@ std::string NMD::SEQI(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SH_16_(uint64 instruction, Dis_info *info) +static std::string SH_16_(uint64 instruction, Dis_info *info) { uint64 rtz3_value = extract_rtz3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -13813,7 +13813,7 @@ std::string NMD::SH_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SH_GP_(uint64 instruction, Dis_info *info) +static std::string SH_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_1__s1(instruction); @@ -13835,7 +13835,7 @@ std::string NMD::SH_GP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SH_S9_(uint64 instruction, Dis_info *info) +static std::string SH_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13859,7 +13859,7 @@ std::string NMD::SH_S9_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SH_U12_(uint64 instruction, Dis_info *info) +static std::string SH_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13883,7 +13883,7 @@ std::string NMD::SH_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SHE(uint64 instruction, Dis_info *info) +static std::string SHE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13907,7 +13907,7 @@ std::string NMD::SHE(uint64 instruction, Dis_info *info) * shift ------ * ac -- */ -std::string NMD::SHILO(uint64 instruction, Dis_info *info) +static std::string SHILO(uint64 instruction, Dis_info *info) { int64 shift_value = extract_shift__se5_21_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); @@ -13929,7 +13929,7 @@ std::string NMD::SHILO(uint64 instruction, Dis_info *info) * rs ----- * ac -- */ -std::string NMD::SHILOV(uint64 instruction, Dis_info *info) +static std::string SHILOV(uint64 instruction, Dis_info *info) { uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); @@ -13951,7 +13951,7 @@ std::string NMD::SHILOV(uint64 instruction, Dis_info *info) * rs ----- * sa ---- */ -std::string NMD::SHLL_PH(uint64 instruction, Dis_info *info) +static std::string SHLL_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -13975,7 +13975,7 @@ std::string NMD::SHLL_PH(uint64 instruction, Dis_info *info) * rs ----- * sa --- */ -std::string NMD::SHLL_QB(uint64 instruction, Dis_info *info) +static std::string SHLL_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14000,7 +14000,7 @@ std::string NMD::SHLL_QB(uint64 instruction, Dis_info *info) * rs ----- * sa ---- */ -std::string NMD::SHLL_S_PH(uint64 instruction, Dis_info *info) +static std::string SHLL_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14024,7 +14024,7 @@ std::string NMD::SHLL_S_PH(uint64 instruction, Dis_info *info) * rs ----- * sa ----- */ -std::string NMD::SHLL_S_W(uint64 instruction, Dis_info *info) +static std::string SHLL_S_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14049,7 +14049,7 @@ std::string NMD::SHLL_S_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SHLLV_PH(uint64 instruction, Dis_info *info) +static std::string SHLLV_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14073,7 +14073,7 @@ std::string NMD::SHLLV_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SHLLV_QB(uint64 instruction, Dis_info *info) +static std::string SHLLV_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14098,7 +14098,7 @@ std::string NMD::SHLLV_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SHLLV_S_PH(uint64 instruction, Dis_info *info) +static std::string SHLLV_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14122,7 +14122,7 @@ std::string NMD::SHLLV_S_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SHLLV_S_W(uint64 instruction, Dis_info *info) +static std::string SHLLV_S_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14146,7 +14146,7 @@ std::string NMD::SHLLV_S_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SHRA_PH(uint64 instruction, Dis_info *info) +static std::string SHRA_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14170,7 +14170,7 @@ std::string NMD::SHRA_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SHRA_QB(uint64 instruction, Dis_info *info) +static std::string SHRA_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14194,7 +14194,7 @@ std::string NMD::SHRA_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SHRA_R_PH(uint64 instruction, Dis_info *info) +static std::string SHRA_R_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14218,7 +14218,7 @@ std::string NMD::SHRA_R_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SHRA_R_QB(uint64 instruction, Dis_info *info) +static std::string SHRA_R_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14242,7 +14242,7 @@ std::string NMD::SHRA_R_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SHRA_R_W(uint64 instruction, Dis_info *info) +static std::string SHRA_R_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14266,7 +14266,7 @@ std::string NMD::SHRA_R_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SHRAV_PH(uint64 instruction, Dis_info *info) +static std::string SHRAV_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14290,7 +14290,7 @@ std::string NMD::SHRAV_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SHRAV_QB(uint64 instruction, Dis_info *info) +static std::string SHRAV_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14314,7 +14314,7 @@ std::string NMD::SHRAV_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SHRAV_R_PH(uint64 instruction, Dis_info *info) +static std::string SHRAV_R_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14338,7 +14338,7 @@ std::string NMD::SHRAV_R_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SHRAV_R_QB(uint64 instruction, Dis_info *info) +static std::string SHRAV_R_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14362,7 +14362,7 @@ std::string NMD::SHRAV_R_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SHRAV_R_W(uint64 instruction, Dis_info *info) +static std::string SHRAV_R_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14386,7 +14386,7 @@ std::string NMD::SHRAV_R_W(uint64 instruction, Dis_info *info) * rs ----- * sa ---- */ -std::string NMD::SHRL_PH(uint64 instruction, Dis_info *info) +static std::string SHRL_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14410,7 +14410,7 @@ std::string NMD::SHRL_PH(uint64 instruction, Dis_info *info) * rs ----- * sa --- */ -std::string NMD::SHRL_QB(uint64 instruction, Dis_info *info) +static std::string SHRL_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14435,7 +14435,7 @@ std::string NMD::SHRL_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SHRLV_PH(uint64 instruction, Dis_info *info) +static std::string SHRLV_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14459,7 +14459,7 @@ std::string NMD::SHRLV_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SHRLV_QB(uint64 instruction, Dis_info *info) +static std::string SHRLV_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14483,7 +14483,7 @@ std::string NMD::SHRLV_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SHX(uint64 instruction, Dis_info *info) +static std::string SHX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14507,7 +14507,7 @@ std::string NMD::SHX(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SHXS(uint64 instruction, Dis_info *info) +static std::string SHXS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14531,7 +14531,7 @@ std::string NMD::SHXS(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SIGRIE(uint64 instruction, Dis_info *info) +static std::string SIGRIE(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_18_to_0(instruction); @@ -14551,7 +14551,7 @@ std::string NMD::SIGRIE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SLL_16_(uint64 instruction, Dis_info *info) +static std::string SLL_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -14575,7 +14575,7 @@ std::string NMD::SLL_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SLL_32_(uint64 instruction, Dis_info *info) +static std::string SLL_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14599,7 +14599,7 @@ std::string NMD::SLL_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SLLV(uint64 instruction, Dis_info *info) +static std::string SLLV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14623,7 +14623,7 @@ std::string NMD::SLLV(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SLT(uint64 instruction, Dis_info *info) +static std::string SLT(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14647,7 +14647,7 @@ std::string NMD::SLT(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SLTI(uint64 instruction, Dis_info *info) +static std::string SLTI(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14671,7 +14671,7 @@ std::string NMD::SLTI(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SLTIU(uint64 instruction, Dis_info *info) +static std::string SLTIU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14695,7 +14695,7 @@ std::string NMD::SLTIU(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SLTU(uint64 instruction, Dis_info *info) +static std::string SLTU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14719,7 +14719,7 @@ std::string NMD::SLTU(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SOV(uint64 instruction, Dis_info *info) +static std::string SOV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14743,7 +14743,7 @@ std::string NMD::SOV(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SPECIAL2(uint64 instruction, Dis_info *info) +static std::string SPECIAL2(uint64 instruction, Dis_info *info) { uint64 op_value = extract_op_25_to_3(instruction); @@ -14763,7 +14763,7 @@ std::string NMD::SPECIAL2(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SQRT_D(uint64 instruction, Dis_info *info) +static std::string SQRT_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -14785,7 +14785,7 @@ std::string NMD::SQRT_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SQRT_S(uint64 instruction, Dis_info *info) +static std::string SQRT_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -14807,7 +14807,7 @@ std::string NMD::SQRT_S(uint64 instruction, Dis_info *info) * rd ----- * sa ----- */ -std::string NMD::SRA(uint64 instruction, Dis_info *info) +static std::string SRA(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14831,7 +14831,7 @@ std::string NMD::SRA(uint64 instruction, Dis_info *info) * rt ----- * rd ----- */ -std::string NMD::SRAV(uint64 instruction, Dis_info *info) +static std::string SRAV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14855,7 +14855,7 @@ std::string NMD::SRAV(uint64 instruction, Dis_info *info) * rt ----- * rd ----- */ -std::string NMD::SRL_16_(uint64 instruction, Dis_info *info) +static std::string SRL_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -14879,7 +14879,7 @@ std::string NMD::SRL_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SRL_32_(uint64 instruction, Dis_info *info) +static std::string SRL_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14903,7 +14903,7 @@ std::string NMD::SRL_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SRLV(uint64 instruction, Dis_info *info) +static std::string SRLV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14927,7 +14927,7 @@ std::string NMD::SRLV(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SUB(uint64 instruction, Dis_info *info) +static std::string SUB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -14951,7 +14951,7 @@ std::string NMD::SUB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SUB_D(uint64 instruction, Dis_info *info) +static std::string SUB_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -14975,7 +14975,7 @@ std::string NMD::SUB_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SUB_S(uint64 instruction, Dis_info *info) +static std::string SUB_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -14999,7 +14999,7 @@ std::string NMD::SUB_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SUBQ_PH(uint64 instruction, Dis_info *info) +static std::string SUBQ_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15024,7 +15024,7 @@ std::string NMD::SUBQ_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SUBQ_S_PH(uint64 instruction, Dis_info *info) +static std::string SUBQ_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15049,7 +15049,7 @@ std::string NMD::SUBQ_S_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SUBQ_S_W(uint64 instruction, Dis_info *info) +static std::string SUBQ_S_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15074,7 +15074,7 @@ std::string NMD::SUBQ_S_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SUBQH_PH(uint64 instruction, Dis_info *info) +static std::string SUBQH_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15099,7 +15099,7 @@ std::string NMD::SUBQH_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SUBQH_R_PH(uint64 instruction, Dis_info *info) +static std::string SUBQH_R_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15124,7 +15124,7 @@ std::string NMD::SUBQH_R_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SUBQH_R_W(uint64 instruction, Dis_info *info) +static std::string SUBQH_R_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15149,7 +15149,7 @@ std::string NMD::SUBQH_R_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SUBQH_W(uint64 instruction, Dis_info *info) +static std::string SUBQH_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15173,7 +15173,7 @@ std::string NMD::SUBQH_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SUBU_16_(uint64 instruction, Dis_info *info) +static std::string SUBU_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -15197,7 +15197,7 @@ std::string NMD::SUBU_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SUBU_32_(uint64 instruction, Dis_info *info) +static std::string SUBU_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15221,7 +15221,7 @@ std::string NMD::SUBU_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SUBU_PH(uint64 instruction, Dis_info *info) +static std::string SUBU_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15245,7 +15245,7 @@ std::string NMD::SUBU_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SUBU_QB(uint64 instruction, Dis_info *info) +static std::string SUBU_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15270,7 +15270,7 @@ std::string NMD::SUBU_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SUBU_S_PH(uint64 instruction, Dis_info *info) +static std::string SUBU_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15295,7 +15295,7 @@ std::string NMD::SUBU_S_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SUBU_S_QB(uint64 instruction, Dis_info *info) +static std::string SUBU_S_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15320,7 +15320,7 @@ std::string NMD::SUBU_S_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SUBUH_QB(uint64 instruction, Dis_info *info) +static std::string SUBUH_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15345,7 +15345,7 @@ std::string NMD::SUBUH_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SUBUH_R_QB(uint64 instruction, Dis_info *info) +static std::string SUBUH_R_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15369,7 +15369,7 @@ std::string NMD::SUBUH_R_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SW_16_(uint64 instruction, Dis_info *info) +static std::string SW_16_(uint64 instruction, Dis_info *info) { uint64 rtz3_value = extract_rtz3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -15393,7 +15393,7 @@ std::string NMD::SW_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SW_4X4_(uint64 instruction, Dis_info *info) +static std::string SW_4X4_(uint64 instruction, Dis_info *info) { uint64 rtz4_value = extract_rtz4_9_7_6_5(instruction); uint64 rs4_value = extract_rs4_4_2_1_0(instruction); @@ -15417,7 +15417,7 @@ std::string NMD::SW_4X4_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SW_GP16_(uint64 instruction, Dis_info *info) +static std::string SW_GP16_(uint64 instruction, Dis_info *info) { uint64 u_value = extract_u_6_5_4_3_2_1_0__s2(instruction); uint64 rtz3_value = extract_rtz3_9_8_7(instruction); @@ -15439,7 +15439,7 @@ std::string NMD::SW_GP16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SW_GP_(uint64 instruction, Dis_info *info) +static std::string SW_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_to_2__s2(instruction); @@ -15461,7 +15461,7 @@ std::string NMD::SW_GP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SW_S9_(uint64 instruction, Dis_info *info) +static std::string SW_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); @@ -15485,7 +15485,7 @@ std::string NMD::SW_S9_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SW_SP_(uint64 instruction, Dis_info *info) +static std::string SW_SP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_9_8_7_6_5(instruction); uint64 u_value = extract_u_4_3_2_1_0__s2(instruction); @@ -15507,7 +15507,7 @@ std::string NMD::SW_SP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SW_U12_(uint64 instruction, Dis_info *info) +static std::string SW_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15531,7 +15531,7 @@ std::string NMD::SW_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SWC1_GP_(uint64 instruction, Dis_info *info) +static std::string SWC1_GP_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_2__s2(instruction); @@ -15553,7 +15553,7 @@ std::string NMD::SWC1_GP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SWC1_S9_(uint64 instruction, Dis_info *info) +static std::string SWC1_S9_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15577,7 +15577,7 @@ std::string NMD::SWC1_S9_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SWC1_U12_(uint64 instruction, Dis_info *info) +static std::string SWC1_U12_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15601,7 +15601,7 @@ std::string NMD::SWC1_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SWC1X(uint64 instruction, Dis_info *info) +static std::string SWC1X(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15625,7 +15625,7 @@ std::string NMD::SWC1X(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SWC1XS(uint64 instruction, Dis_info *info) +static std::string SWC1XS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15649,7 +15649,7 @@ std::string NMD::SWC1XS(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SWC2(uint64 instruction, Dis_info *info) +static std::string SWC2(uint64 instruction, Dis_info *info) { uint64 cs_value = extract_cs_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15673,7 +15673,7 @@ std::string NMD::SWC2(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SWE(uint64 instruction, Dis_info *info) +static std::string SWE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15697,7 +15697,7 @@ std::string NMD::SWE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SWM(uint64 instruction, Dis_info *info) +static std::string SWM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15723,7 +15723,7 @@ std::string NMD::SWM(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SWPC_48_(uint64 instruction, Dis_info *info) +static std::string SWPC_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); @@ -15745,7 +15745,7 @@ std::string NMD::SWPC_48_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SWX(uint64 instruction, Dis_info *info) +static std::string SWX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15769,7 +15769,7 @@ std::string NMD::SWX(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SWXS(uint64 instruction, Dis_info *info) +static std::string SWXS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15793,7 +15793,7 @@ std::string NMD::SWXS(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SYNC(uint64 instruction, Dis_info *info) +static std::string SYNC(uint64 instruction, Dis_info *info) { uint64 stype_value = extract_stype_20_19_18_17_16(instruction); @@ -15813,7 +15813,7 @@ std::string NMD::SYNC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SYNCI(uint64 instruction, Dis_info *info) +static std::string SYNCI(uint64 instruction, Dis_info *info) { uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); @@ -15835,7 +15835,7 @@ std::string NMD::SYNCI(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SYNCIE(uint64 instruction, Dis_info *info) +static std::string SYNCIE(uint64 instruction, Dis_info *info) { uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); @@ -15857,7 +15857,7 @@ std::string NMD::SYNCIE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::SYSCALL_16_(uint64 instruction, Dis_info *info) +static std::string SYSCALL_16_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_1_0(instruction); @@ -15875,7 +15875,7 @@ std::string NMD::SYSCALL_16_(uint64 instruction, Dis_info *info) * 00000000000010 * code ------------------ */ -std::string NMD::SYSCALL_32_(uint64 instruction, Dis_info *info) +static std::string SYSCALL_32_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_17_to_0(instruction); @@ -15895,7 +15895,7 @@ std::string NMD::SYSCALL_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::TEQ(uint64 instruction, Dis_info *info) +static std::string TEQ(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -15917,7 +15917,7 @@ std::string NMD::TEQ(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::TLBGINV(uint64 instruction, Dis_info *info) +static std::string TLBGINV(uint64 instruction, Dis_info *info) { (void)instruction; @@ -15935,7 +15935,7 @@ std::string NMD::TLBGINV(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::TLBGINVF(uint64 instruction, Dis_info *info) +static std::string TLBGINVF(uint64 instruction, Dis_info *info) { (void)instruction; @@ -15953,7 +15953,7 @@ std::string NMD::TLBGINVF(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::TLBGP(uint64 instruction, Dis_info *info) +static std::string TLBGP(uint64 instruction, Dis_info *info) { (void)instruction; @@ -15971,7 +15971,7 @@ std::string NMD::TLBGP(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::TLBGR(uint64 instruction, Dis_info *info) +static std::string TLBGR(uint64 instruction, Dis_info *info) { (void)instruction; @@ -15989,7 +15989,7 @@ std::string NMD::TLBGR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::TLBGWI(uint64 instruction, Dis_info *info) +static std::string TLBGWI(uint64 instruction, Dis_info *info) { (void)instruction; @@ -16007,7 +16007,7 @@ std::string NMD::TLBGWI(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::TLBGWR(uint64 instruction, Dis_info *info) +static std::string TLBGWR(uint64 instruction, Dis_info *info) { (void)instruction; @@ -16025,7 +16025,7 @@ std::string NMD::TLBGWR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::TLBINV(uint64 instruction, Dis_info *info) +static std::string TLBINV(uint64 instruction, Dis_info *info) { (void)instruction; @@ -16043,7 +16043,7 @@ std::string NMD::TLBINV(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::TLBINVF(uint64 instruction, Dis_info *info) +static std::string TLBINVF(uint64 instruction, Dis_info *info) { (void)instruction; @@ -16061,7 +16061,7 @@ std::string NMD::TLBINVF(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::TLBP(uint64 instruction, Dis_info *info) +static std::string TLBP(uint64 instruction, Dis_info *info) { (void)instruction; @@ -16079,7 +16079,7 @@ std::string NMD::TLBP(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::TLBR(uint64 instruction, Dis_info *info) +static std::string TLBR(uint64 instruction, Dis_info *info) { (void)instruction; @@ -16097,7 +16097,7 @@ std::string NMD::TLBR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::TLBWI(uint64 instruction, Dis_info *info) +static std::string TLBWI(uint64 instruction, Dis_info *info) { (void)instruction; @@ -16115,7 +16115,7 @@ std::string NMD::TLBWI(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::TLBWR(uint64 instruction, Dis_info *info) +static std::string TLBWR(uint64 instruction, Dis_info *info) { (void)instruction; @@ -16133,7 +16133,7 @@ std::string NMD::TLBWR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::TNE(uint64 instruction, Dis_info *info) +static std::string TNE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -16155,7 +16155,7 @@ std::string NMD::TNE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::TRUNC_L_D(uint64 instruction, Dis_info *info) +static std::string TRUNC_L_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -16177,7 +16177,7 @@ std::string NMD::TRUNC_L_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::TRUNC_L_S(uint64 instruction, Dis_info *info) +static std::string TRUNC_L_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -16199,7 +16199,7 @@ std::string NMD::TRUNC_L_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::TRUNC_W_D(uint64 instruction, Dis_info *info) +static std::string TRUNC_W_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -16221,7 +16221,7 @@ std::string NMD::TRUNC_W_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::TRUNC_W_S(uint64 instruction, Dis_info *info) +static std::string TRUNC_W_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); @@ -16243,7 +16243,7 @@ std::string NMD::TRUNC_W_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::UALDM(uint64 instruction, Dis_info *info) +static std::string UALDM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -16269,7 +16269,7 @@ std::string NMD::UALDM(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::UALH(uint64 instruction, Dis_info *info) +static std::string UALH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -16293,7 +16293,7 @@ std::string NMD::UALH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::UALWM(uint64 instruction, Dis_info *info) +static std::string UALWM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -16319,7 +16319,7 @@ std::string NMD::UALWM(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::UASDM(uint64 instruction, Dis_info *info) +static std::string UASDM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -16345,7 +16345,7 @@ std::string NMD::UASDM(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::UASH(uint64 instruction, Dis_info *info) +static std::string UASH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -16369,7 +16369,7 @@ std::string NMD::UASH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::UASWM(uint64 instruction, Dis_info *info) +static std::string UASWM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -16395,7 +16395,7 @@ std::string NMD::UASWM(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::UDI(uint64 instruction, Dis_info *info) +static std::string UDI(uint64 instruction, Dis_info *info) { uint64 op_value = extract_op_25_to_3(instruction); @@ -16413,7 +16413,7 @@ std::string NMD::UDI(uint64 instruction, Dis_info *info) * 001000 1100001101111111 * code ---------- */ -std::string NMD::WAIT(uint64 instruction, Dis_info *info) +static std::string WAIT(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_25_24_23_22_21_20_19_18_17_16(instruction); @@ -16433,7 +16433,7 @@ std::string NMD::WAIT(uint64 instruction, Dis_info *info) * rt ----- * mask ------- */ -std::string NMD::WRDSP(uint64 instruction, Dis_info *info) +static std::string WRDSP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 mask_value = extract_mask_20_19_18_17_16_15_14(instruction); @@ -16455,7 +16455,7 @@ std::string NMD::WRDSP(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::WRPGPR(uint64 instruction, Dis_info *info) +static std::string WRPGPR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -16477,7 +16477,7 @@ std::string NMD::WRPGPR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::XOR_16_(uint64 instruction, Dis_info *info) +static std::string XOR_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); @@ -16499,7 +16499,7 @@ std::string NMD::XOR_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::XOR_32_(uint64 instruction, Dis_info *info) +static std::string XOR_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -16523,7 +16523,7 @@ std::string NMD::XOR_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -std::string NMD::XORI(uint64 instruction, Dis_info *info) +static std::string XORI(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -16546,7 +16546,7 @@ std::string NMD::XORI(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -std::string NMD::YIELD(uint64 instruction, Dis_info *info) +static std::string YIELD(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -16663,26 +16663,26 @@ std::string NMD::YIELD(uint64 instruction, Dis_info *info) NMD::Pool NMD::P_SYSCALL[2] = { { instruction , 0 , 0 , 32, - 0xfffc0000, 0x00080000, &NMD::SYSCALL_32_ , 0, + 0xfffc0000, 0x00080000, &SYSCALL_32_ , 0, 0x0 }, /* SYSCALL[32] */ { instruction , 0 , 0 , 32, - 0xfffc0000, 0x000c0000, &NMD::HYPCALL , 0, + 0xfffc0000, 0x000c0000, &HYPCALL , 0, CP0_ | VZ_ }, /* HYPCALL */ }; NMD::Pool NMD::P_RI[4] = { { instruction , 0 , 0 , 32, - 0xfff80000, 0x00000000, &NMD::SIGRIE , 0, + 0xfff80000, 0x00000000, &SIGRIE , 0, 0x0 }, /* SIGRIE */ { pool , P_SYSCALL , 2 , 32, 0xfff80000, 0x00080000, 0 , 0, 0x0 }, /* P.SYSCALL */ { instruction , 0 , 0 , 32, - 0xfff80000, 0x00100000, &NMD::BREAK_32_ , 0, + 0xfff80000, 0x00100000, &BREAK_32_ , 0, 0x0 }, /* BREAK[32] */ { instruction , 0 , 0 , 32, - 0xfff80000, 0x00180000, &NMD::SDBBP_32_ , 0, + 0xfff80000, 0x00180000, &SDBBP_32_ , 0, EJTAG_ }, /* SDBBP[32] */ }; @@ -16692,47 +16692,47 @@ NMD::Pool NMD::P_ADDIU[2] = { 0xffe00000, 0x00000000, 0 , 0, 0x0 }, /* P.RI */ { instruction , 0 , 0 , 32, - 0xfc000000, 0x00000000, &NMD::ADDIU_32_ , &ADDIU_32__cond , + 0xfc000000, 0x00000000, &ADDIU_32_ , &ADDIU_32__cond , 0x0 }, /* ADDIU[32] */ }; NMD::Pool NMD::P_TRAP[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000000, &NMD::TEQ , 0, + 0xfc0007ff, 0x20000000, &TEQ , 0, XMMS_ }, /* TEQ */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000400, &NMD::TNE , 0, + 0xfc0007ff, 0x20000400, &TNE , 0, XMMS_ }, /* TNE */ }; NMD::Pool NMD::P_CMOVE[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000210, &NMD::MOVZ , 0, + 0xfc0007ff, 0x20000210, &MOVZ , 0, 0x0 }, /* MOVZ */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000610, &NMD::MOVN , 0, + 0xfc0007ff, 0x20000610, &MOVN , 0, 0x0 }, /* MOVN */ }; NMD::Pool NMD::P_D_MT_VPE[2] = { { instruction , 0 , 0 , 32, - 0xfc1f3fff, 0x20010ab0, &NMD::DMT , 0, + 0xfc1f3fff, 0x20010ab0, &DMT , 0, MT_ }, /* DMT */ { instruction , 0 , 0 , 32, - 0xfc1f3fff, 0x20000ab0, &NMD::DVPE , 0, + 0xfc1f3fff, 0x20000ab0, &DVPE , 0, MT_ }, /* DVPE */ }; NMD::Pool NMD::P_E_MT_VPE[2] = { { instruction , 0 , 0 , 32, - 0xfc1f3fff, 0x20010eb0, &NMD::EMT , 0, + 0xfc1f3fff, 0x20010eb0, &EMT , 0, MT_ }, /* EMT */ { instruction , 0 , 0 , 32, - 0xfc1f3fff, 0x20000eb0, &NMD::EVPE , 0, + 0xfc1f3fff, 0x20000eb0, &EVPE , 0, MT_ }, /* EVPE */ }; @@ -16777,10 +16777,10 @@ NMD::Pool NMD::P_MT_VPE[8] = { NMD::Pool NMD::P_DVP[2] = { { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x20000390, &NMD::DVP , 0, + 0xfc00ffff, 0x20000390, &DVP , 0, 0x0 }, /* DVP */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x20000790, &NMD::EVP , 0, + 0xfc00ffff, 0x20000790, &EVP , 0, 0x0 }, /* EVP */ }; @@ -16790,7 +16790,7 @@ NMD::Pool NMD::P_SLTU[2] = { 0xfc00fbff, 0x20000390, 0 , 0, 0x0 }, /* P.DVP */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000390, &NMD::SLTU , &SLTU_cond , + 0xfc0003ff, 0x20000390, &SLTU , &SLTU_cond , 0x0 }, /* SLTU */ }; @@ -16800,13 +16800,13 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x20000000, 0 , 0, 0x0 }, /* P.TRAP */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000008, &NMD::SEB , 0, + 0xfc0003ff, 0x20000008, &SEB , 0, XMMS_ }, /* SEB */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000010, &NMD::SLLV , 0, + 0xfc0003ff, 0x20000010, &SLLV , 0, 0x0 }, /* SLLV */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000018, &NMD::MUL_32_ , 0, + 0xfc0003ff, 0x20000018, &MUL_32_ , 0, 0x0 }, /* MUL[32] */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000020, 0 , 0, @@ -16815,22 +16815,22 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x20000028, 0 , 0, 0x0 }, /* _POOL32A0~*(5) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000030, &NMD::MFC0 , 0, + 0xfc0003ff, 0x20000030, &MFC0 , 0, 0x0 }, /* MFC0 */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000038, &NMD::MFHC0 , 0, + 0xfc0003ff, 0x20000038, &MFHC0 , 0, CP0_ | MVH_ }, /* MFHC0 */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000040, 0 , 0, 0x0 }, /* _POOL32A0~*(8) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000048, &NMD::SEH , 0, + 0xfc0003ff, 0x20000048, &SEH , 0, 0x0 }, /* SEH */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000050, &NMD::SRLV , 0, + 0xfc0003ff, 0x20000050, &SRLV , 0, 0x0 }, /* SRLV */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000058, &NMD::MUH , 0, + 0xfc0003ff, 0x20000058, &MUH , 0, 0x0 }, /* MUH */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000060, 0 , 0, @@ -16839,10 +16839,10 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x20000068, 0 , 0, 0x0 }, /* _POOL32A0~*(13) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000070, &NMD::MTC0 , 0, + 0xfc0003ff, 0x20000070, &MTC0 , 0, CP0_ }, /* MTC0 */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000078, &NMD::MTHC0 , 0, + 0xfc0003ff, 0x20000078, &MTHC0 , 0, CP0_ | MVH_ }, /* MTHC0 */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000080, 0 , 0, @@ -16851,10 +16851,10 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x20000088, 0 , 0, 0x0 }, /* _POOL32A0~*(17) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000090, &NMD::SRAV , 0, + 0xfc0003ff, 0x20000090, &SRAV , 0, 0x0 }, /* SRAV */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000098, &NMD::MULU , 0, + 0xfc0003ff, 0x20000098, &MULU , 0, 0x0 }, /* MULU */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200000a0, 0 , 0, @@ -16863,10 +16863,10 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x200000a8, 0 , 0, 0x0 }, /* _POOL32A0~*(21) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200000b0, &NMD::MFGC0 , 0, + 0xfc0003ff, 0x200000b0, &MFGC0 , 0, CP0_ | VZ_ }, /* MFGC0 */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200000b8, &NMD::MFHGC0 , 0, + 0xfc0003ff, 0x200000b8, &MFHGC0 , 0, CP0_ | VZ_ | MVH_ }, /* MFHGC0 */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200000c0, 0 , 0, @@ -16875,10 +16875,10 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x200000c8, 0 , 0, 0x0 }, /* _POOL32A0~*(25) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200000d0, &NMD::ROTRV , 0, + 0xfc0003ff, 0x200000d0, &ROTRV , 0, 0x0 }, /* ROTRV */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200000d8, &NMD::MUHU , 0, + 0xfc0003ff, 0x200000d8, &MUHU , 0, 0x0 }, /* MUHU */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200000e0, 0 , 0, @@ -16887,10 +16887,10 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x200000e8, 0 , 0, 0x0 }, /* _POOL32A0~*(29) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200000f0, &NMD::MTGC0 , 0, + 0xfc0003ff, 0x200000f0, &MTGC0 , 0, CP0_ | VZ_ }, /* MTGC0 */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200000f8, &NMD::MTHGC0 , 0, + 0xfc0003ff, 0x200000f8, &MTHGC0 , 0, CP0_ | VZ_ | MVH_ }, /* MTHGC0 */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000100, 0 , 0, @@ -16899,10 +16899,10 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x20000108, 0 , 0, 0x0 }, /* _POOL32A0~*(33) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000110, &NMD::ADD , 0, + 0xfc0003ff, 0x20000110, &ADD , 0, XMMS_ }, /* ADD */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000118, &NMD::DIV , 0, + 0xfc0003ff, 0x20000118, &DIV , 0, 0x0 }, /* DIV */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000120, 0 , 0, @@ -16911,7 +16911,7 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x20000128, 0 , 0, 0x0 }, /* _POOL32A0~*(37) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000130, &NMD::DMFC0 , 0, + 0xfc0003ff, 0x20000130, &DMFC0 , 0, CP0_ | MIPS64_ }, /* DMFC0 */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000138, 0 , 0, @@ -16923,10 +16923,10 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x20000148, 0 , 0, 0x0 }, /* _POOL32A0~*(41) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000150, &NMD::ADDU_32_ , 0, + 0xfc0003ff, 0x20000150, &ADDU_32_ , 0, 0x0 }, /* ADDU[32] */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000158, &NMD::MOD , 0, + 0xfc0003ff, 0x20000158, &MOD , 0, 0x0 }, /* MOD */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000160, 0 , 0, @@ -16935,7 +16935,7 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x20000168, 0 , 0, 0x0 }, /* _POOL32A0~*(45) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000170, &NMD::DMTC0 , 0, + 0xfc0003ff, 0x20000170, &DMTC0 , 0, CP0_ | MIPS64_ }, /* DMTC0 */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000178, 0 , 0, @@ -16947,10 +16947,10 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x20000188, 0 , 0, 0x0 }, /* _POOL32A0~*(49) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000190, &NMD::SUB , 0, + 0xfc0003ff, 0x20000190, &SUB , 0, XMMS_ }, /* SUB */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000198, &NMD::DIVU , 0, + 0xfc0003ff, 0x20000198, &DIVU , 0, 0x0 }, /* DIVU */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200001a0, 0 , 0, @@ -16959,22 +16959,22 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x200001a8, 0 , 0, 0x0 }, /* _POOL32A0~*(53) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200001b0, &NMD::DMFGC0 , 0, + 0xfc0003ff, 0x200001b0, &DMFGC0 , 0, CP0_ | MIPS64_ | VZ_}, /* DMFGC0 */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200001b8, 0 , 0, 0x0 }, /* _POOL32A0~*(55) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200001c0, &NMD::RDHWR , 0, + 0xfc0003ff, 0x200001c0, &RDHWR , 0, XMMS_ }, /* RDHWR */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200001c8, 0 , 0, 0x0 }, /* _POOL32A0~*(57) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200001d0, &NMD::SUBU_32_ , 0, + 0xfc0003ff, 0x200001d0, &SUBU_32_ , 0, 0x0 }, /* SUBU[32] */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200001d8, &NMD::MODU , 0, + 0xfc0003ff, 0x200001d8, &MODU , 0, 0x0 }, /* MODU */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200001e0, 0 , 0, @@ -16983,7 +16983,7 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x200001e8, 0 , 0, 0x0 }, /* _POOL32A0~*(61) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200001f0, &NMD::DMTGC0 , 0, + 0xfc0003ff, 0x200001f0, &DMTGC0 , 0, CP0_ | MIPS64_ | VZ_}, /* DMTGC0 */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200001f8, 0 , 0, @@ -17004,13 +17004,13 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x20000220, 0 , 0, 0x0 }, /* _POOL32A0~*(68) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000228, &NMD::FORK , 0, + 0xfc0003ff, 0x20000228, &FORK , 0, MT_ }, /* FORK */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000230, &NMD::MFTR , 0, + 0xfc0003ff, 0x20000230, &MFTR , 0, MT_ }, /* MFTR */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000238, &NMD::MFHTR , 0, + 0xfc0003ff, 0x20000238, &MFHTR , 0, MT_ }, /* MFHTR */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000240, 0 , 0, @@ -17019,7 +17019,7 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x20000248, 0 , 0, 0x0 }, /* _POOL32A0~*(73) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000250, &NMD::AND_32_ , 0, + 0xfc0003ff, 0x20000250, &AND_32_ , 0, 0x0 }, /* AND[32] */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000258, 0 , 0, @@ -17028,13 +17028,13 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x20000260, 0 , 0, 0x0 }, /* _POOL32A0~*(76) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000268, &NMD::YIELD , 0, + 0xfc0003ff, 0x20000268, &YIELD , 0, MT_ }, /* YIELD */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000270, &NMD::MTTR , 0, + 0xfc0003ff, 0x20000270, &MTTR , 0, MT_ }, /* MTTR */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000278, &NMD::MTHTR , 0, + 0xfc0003ff, 0x20000278, &MTHTR , 0, MT_ }, /* MTHTR */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000280, 0 , 0, @@ -17043,7 +17043,7 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x20000288, 0 , 0, 0x0 }, /* _POOL32A0~*(81) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000290, &NMD::OR_32_ , 0, + 0xfc0003ff, 0x20000290, &OR_32_ , 0, 0x0 }, /* OR[32] */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000298, 0 , 0, @@ -17067,7 +17067,7 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x200002c8, 0 , 0, 0x0 }, /* _POOL32A0~*(89) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200002d0, &NMD::NOR , 0, + 0xfc0003ff, 0x200002d0, &NOR , 0, 0x0 }, /* NOR */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200002d8, 0 , 0, @@ -17091,7 +17091,7 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x20000308, 0 , 0, 0x0 }, /* _POOL32A0~*(97) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000310, &NMD::XOR_32_ , 0, + 0xfc0003ff, 0x20000310, &XOR_32_ , 0, 0x0 }, /* XOR[32] */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000318, 0 , 0, @@ -17115,7 +17115,7 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x20000348, 0 , 0, 0x0 }, /* _POOL32A0~*(105) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000350, &NMD::SLT , 0, + 0xfc0003ff, 0x20000350, &SLT , 0, 0x0 }, /* SLT */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000358, 0 , 0, @@ -17163,7 +17163,7 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x200003c8, 0 , 0, 0x0 }, /* _POOL32A0~*(121) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200003d0, &NMD::SOV , 0, + 0xfc0003ff, 0x200003d0, &SOV , 0, 0x0 }, /* SOV */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200003d8, 0 , 0, @@ -17185,183 +17185,183 @@ NMD::Pool NMD::_POOL32A0[128] = { NMD::Pool NMD::ADDQ__S__PH[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000000d, &NMD::ADDQ_PH , 0, + 0xfc0007ff, 0x2000000d, &ADDQ_PH , 0, DSP_ }, /* ADDQ.PH */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000040d, &NMD::ADDQ_S_PH , 0, + 0xfc0007ff, 0x2000040d, &ADDQ_S_PH , 0, DSP_ }, /* ADDQ_S.PH */ }; NMD::Pool NMD::MUL__S__PH[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000002d, &NMD::MUL_PH , 0, + 0xfc0007ff, 0x2000002d, &MUL_PH , 0, DSP_ }, /* MUL.PH */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000042d, &NMD::MUL_S_PH , 0, + 0xfc0007ff, 0x2000042d, &MUL_S_PH , 0, DSP_ }, /* MUL_S.PH */ }; NMD::Pool NMD::ADDQH__R__PH[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000004d, &NMD::ADDQH_PH , 0, + 0xfc0007ff, 0x2000004d, &ADDQH_PH , 0, DSP_ }, /* ADDQH.PH */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000044d, &NMD::ADDQH_R_PH , 0, + 0xfc0007ff, 0x2000044d, &ADDQH_R_PH , 0, DSP_ }, /* ADDQH_R.PH */ }; NMD::Pool NMD::ADDQH__R__W[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000008d, &NMD::ADDQH_W , 0, + 0xfc0007ff, 0x2000008d, &ADDQH_W , 0, DSP_ }, /* ADDQH.W */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000048d, &NMD::ADDQH_R_W , 0, + 0xfc0007ff, 0x2000048d, &ADDQH_R_W , 0, DSP_ }, /* ADDQH_R.W */ }; NMD::Pool NMD::ADDU__S__QB[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x200000cd, &NMD::ADDU_QB , 0, + 0xfc0007ff, 0x200000cd, &ADDU_QB , 0, DSP_ }, /* ADDU.QB */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x200004cd, &NMD::ADDU_S_QB , 0, + 0xfc0007ff, 0x200004cd, &ADDU_S_QB , 0, DSP_ }, /* ADDU_S.QB */ }; NMD::Pool NMD::ADDU__S__PH[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000010d, &NMD::ADDU_PH , 0, + 0xfc0007ff, 0x2000010d, &ADDU_PH , 0, DSP_ }, /* ADDU.PH */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000050d, &NMD::ADDU_S_PH , 0, + 0xfc0007ff, 0x2000050d, &ADDU_S_PH , 0, DSP_ }, /* ADDU_S.PH */ }; NMD::Pool NMD::ADDUH__R__QB[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000014d, &NMD::ADDUH_QB , 0, + 0xfc0007ff, 0x2000014d, &ADDUH_QB , 0, DSP_ }, /* ADDUH.QB */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000054d, &NMD::ADDUH_R_QB , 0, + 0xfc0007ff, 0x2000054d, &ADDUH_R_QB , 0, DSP_ }, /* ADDUH_R.QB */ }; NMD::Pool NMD::SHRAV__R__PH[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000018d, &NMD::SHRAV_PH , 0, + 0xfc0007ff, 0x2000018d, &SHRAV_PH , 0, DSP_ }, /* SHRAV.PH */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000058d, &NMD::SHRAV_R_PH , 0, + 0xfc0007ff, 0x2000058d, &SHRAV_R_PH , 0, DSP_ }, /* SHRAV_R.PH */ }; NMD::Pool NMD::SHRAV__R__QB[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x200001cd, &NMD::SHRAV_QB , 0, + 0xfc0007ff, 0x200001cd, &SHRAV_QB , 0, DSP_ }, /* SHRAV.QB */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x200005cd, &NMD::SHRAV_R_QB , 0, + 0xfc0007ff, 0x200005cd, &SHRAV_R_QB , 0, DSP_ }, /* SHRAV_R.QB */ }; NMD::Pool NMD::SUBQ__S__PH[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000020d, &NMD::SUBQ_PH , 0, + 0xfc0007ff, 0x2000020d, &SUBQ_PH , 0, DSP_ }, /* SUBQ.PH */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000060d, &NMD::SUBQ_S_PH , 0, + 0xfc0007ff, 0x2000060d, &SUBQ_S_PH , 0, DSP_ }, /* SUBQ_S.PH */ }; NMD::Pool NMD::SUBQH__R__PH[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000024d, &NMD::SUBQH_PH , 0, + 0xfc0007ff, 0x2000024d, &SUBQH_PH , 0, DSP_ }, /* SUBQH.PH */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000064d, &NMD::SUBQH_R_PH , 0, + 0xfc0007ff, 0x2000064d, &SUBQH_R_PH , 0, DSP_ }, /* SUBQH_R.PH */ }; NMD::Pool NMD::SUBQH__R__W[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000028d, &NMD::SUBQH_W , 0, + 0xfc0007ff, 0x2000028d, &SUBQH_W , 0, DSP_ }, /* SUBQH.W */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000068d, &NMD::SUBQH_R_W , 0, + 0xfc0007ff, 0x2000068d, &SUBQH_R_W , 0, DSP_ }, /* SUBQH_R.W */ }; NMD::Pool NMD::SUBU__S__QB[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x200002cd, &NMD::SUBU_QB , 0, + 0xfc0007ff, 0x200002cd, &SUBU_QB , 0, DSP_ }, /* SUBU.QB */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x200006cd, &NMD::SUBU_S_QB , 0, + 0xfc0007ff, 0x200006cd, &SUBU_S_QB , 0, DSP_ }, /* SUBU_S.QB */ }; NMD::Pool NMD::SUBU__S__PH[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000030d, &NMD::SUBU_PH , 0, + 0xfc0007ff, 0x2000030d, &SUBU_PH , 0, DSP_ }, /* SUBU.PH */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000070d, &NMD::SUBU_S_PH , 0, + 0xfc0007ff, 0x2000070d, &SUBU_S_PH , 0, DSP_ }, /* SUBU_S.PH */ }; NMD::Pool NMD::SHRA__R__PH[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000335, &NMD::SHRA_PH , 0, + 0xfc0007ff, 0x20000335, &SHRA_PH , 0, DSP_ }, /* SHRA.PH */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000735, &NMD::SHRA_R_PH , 0, + 0xfc0007ff, 0x20000735, &SHRA_R_PH , 0, DSP_ }, /* SHRA_R.PH */ }; NMD::Pool NMD::SUBUH__R__QB[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000034d, &NMD::SUBUH_QB , 0, + 0xfc0007ff, 0x2000034d, &SUBUH_QB , 0, DSP_ }, /* SUBUH.QB */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000074d, &NMD::SUBUH_R_QB , 0, + 0xfc0007ff, 0x2000074d, &SUBUH_R_QB , 0, DSP_ }, /* SUBUH_R.QB */ }; NMD::Pool NMD::SHLLV__S__PH[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000038d, &NMD::SHLLV_PH , 0, + 0xfc0007ff, 0x2000038d, &SHLLV_PH , 0, DSP_ }, /* SHLLV.PH */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000078d, &NMD::SHLLV_S_PH , 0, + 0xfc0007ff, 0x2000078d, &SHLLV_S_PH , 0, DSP_ }, /* SHLLV_S.PH */ }; NMD::Pool NMD::SHLL__S__PH[4] = { { instruction , 0 , 0 , 32, - 0xfc000fff, 0x200003b5, &NMD::SHLL_PH , 0, + 0xfc000fff, 0x200003b5, &SHLL_PH , 0, DSP_ }, /* SHLL.PH */ { reserved_block , 0 , 0 , 32, 0xfc000fff, 0x200007b5, 0 , 0, 0x0 }, /* SHLL[_S].PH~*(1) */ { instruction , 0 , 0 , 32, - 0xfc000fff, 0x20000bb5, &NMD::SHLL_S_PH , 0, + 0xfc000fff, 0x20000bb5, &SHLL_S_PH , 0, DSP_ }, /* SHLL_S.PH */ { reserved_block , 0 , 0 , 32, 0xfc000fff, 0x20000fb5, 0 , 0, @@ -17371,17 +17371,17 @@ NMD::Pool NMD::SHLL__S__PH[4] = { NMD::Pool NMD::PRECR_SRA__R__PH_W[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x200003cd, &NMD::PRECR_SRA_PH_W , 0, + 0xfc0007ff, 0x200003cd, &PRECR_SRA_PH_W , 0, DSP_ }, /* PRECR_SRA.PH.W */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x200007cd, &NMD::PRECR_SRA_R_PH_W , 0, + 0xfc0007ff, 0x200007cd, &PRECR_SRA_R_PH_W , 0, DSP_ }, /* PRECR_SRA_R.PH.W */ }; NMD::Pool NMD::_POOL32A5[128] = { { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000005, &NMD::CMP_EQ_PH , 0, + 0xfc0003ff, 0x20000005, &CMP_EQ_PH , 0, DSP_ }, /* CMP.EQ.PH */ { pool , ADDQ__S__PH , 2 , 32, 0xfc0003ff, 0x2000000d, 0 , 0, @@ -17390,10 +17390,10 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x20000015, 0 , 0, 0x0 }, /* _POOL32A5~*(2) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x2000001d, &NMD::SHILO , 0, + 0xfc0003ff, 0x2000001d, &SHILO , 0, DSP_ }, /* SHILO */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000025, &NMD::MULEQ_S_W_PHL , 0, + 0xfc0003ff, 0x20000025, &MULEQ_S_W_PHL , 0, DSP_ }, /* MULEQ_S.W.PHL */ { pool , MUL__S__PH , 2 , 32, 0xfc0003ff, 0x2000002d, 0 , 0, @@ -17402,10 +17402,10 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x20000035, 0 , 0, 0x0 }, /* _POOL32A5~*(6) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x2000003d, &NMD::REPL_PH , 0, + 0xfc0003ff, 0x2000003d, &REPL_PH , 0, DSP_ }, /* REPL.PH */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000045, &NMD::CMP_LT_PH , 0, + 0xfc0003ff, 0x20000045, &CMP_LT_PH , 0, DSP_ }, /* CMP.LT.PH */ { pool , ADDQH__R__PH , 2 , 32, 0xfc0003ff, 0x2000004d, 0 , 0, @@ -17417,10 +17417,10 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x2000005d, 0 , 0, 0x0 }, /* _POOL32A5~*(11) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000065, &NMD::MULEQ_S_W_PHR , 0, + 0xfc0003ff, 0x20000065, &MULEQ_S_W_PHR , 0, DSP_ }, /* MULEQ_S.W.PHR */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x2000006d, &NMD::PRECR_QB_PH , 0, + 0xfc0003ff, 0x2000006d, &PRECR_QB_PH , 0, DSP_ }, /* PRECR.QB.PH */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000075, 0 , 0, @@ -17429,13 +17429,13 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x2000007d, 0 , 0, 0x0 }, /* _POOL32A5~*(15) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000085, &NMD::CMP_LE_PH , 0, + 0xfc0003ff, 0x20000085, &CMP_LE_PH , 0, DSP_ }, /* CMP.LE.PH */ { pool , ADDQH__R__W , 2 , 32, 0xfc0003ff, 0x2000008d, 0 , 0, 0x0 }, /* ADDQH[_R].W */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000095, &NMD::MULEU_S_PH_QBL , 0, + 0xfc0003ff, 0x20000095, &MULEU_S_PH_QBL , 0, DSP_ }, /* MULEU_S.PH.QBL */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x2000009d, 0 , 0, @@ -17444,7 +17444,7 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x200000a5, 0 , 0, 0x0 }, /* _POOL32A5~*(20) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200000ad, &NMD::PRECRQ_QB_PH , 0, + 0xfc0003ff, 0x200000ad, &PRECRQ_QB_PH , 0, DSP_ }, /* PRECRQ.QB.PH */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200000b5, 0 , 0, @@ -17453,13 +17453,13 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x200000bd, 0 , 0, 0x0 }, /* _POOL32A5~*(23) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200000c5, &NMD::CMPGU_EQ_QB , 0, + 0xfc0003ff, 0x200000c5, &CMPGU_EQ_QB , 0, DSP_ }, /* CMPGU.EQ.QB */ { pool , ADDU__S__QB , 2 , 32, 0xfc0003ff, 0x200000cd, 0 , 0, 0x0 }, /* ADDU[_S].QB */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200000d5, &NMD::MULEU_S_PH_QBR , 0, + 0xfc0003ff, 0x200000d5, &MULEU_S_PH_QBR , 0, DSP_ }, /* MULEU_S.PH.QBR */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200000dd, 0 , 0, @@ -17468,7 +17468,7 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x200000e5, 0 , 0, 0x0 }, /* _POOL32A5~*(28) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200000ed, &NMD::PRECRQ_PH_W , 0, + 0xfc0003ff, 0x200000ed, &PRECRQ_PH_W , 0, DSP_ }, /* PRECRQ.PH.W */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200000f5, 0 , 0, @@ -17477,13 +17477,13 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x200000fd, 0 , 0, 0x0 }, /* _POOL32A5~*(31) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000105, &NMD::CMPGU_LT_QB , 0, + 0xfc0003ff, 0x20000105, &CMPGU_LT_QB , 0, DSP_ }, /* CMPGU.LT.QB */ { pool , ADDU__S__PH , 2 , 32, 0xfc0003ff, 0x2000010d, 0 , 0, 0x0 }, /* ADDU[_S].PH */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000115, &NMD::MULQ_RS_PH , 0, + 0xfc0003ff, 0x20000115, &MULQ_RS_PH , 0, DSP_ }, /* MULQ_RS.PH */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x2000011d, 0 , 0, @@ -17492,7 +17492,7 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x20000125, 0 , 0, 0x0 }, /* _POOL32A5~*(36) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x2000012d, &NMD::PRECRQ_RS_PH_W , 0, + 0xfc0003ff, 0x2000012d, &PRECRQ_RS_PH_W , 0, DSP_ }, /* PRECRQ_RS.PH.W */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000135, 0 , 0, @@ -17501,13 +17501,13 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x2000013d, 0 , 0, 0x0 }, /* _POOL32A5~*(39) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000145, &NMD::CMPGU_LE_QB , 0, + 0xfc0003ff, 0x20000145, &CMPGU_LE_QB , 0, DSP_ }, /* CMPGU.LE.QB */ { pool , ADDUH__R__QB , 2 , 32, 0xfc0003ff, 0x2000014d, 0 , 0, 0x0 }, /* ADDUH[_R].QB */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000155, &NMD::MULQ_S_PH , 0, + 0xfc0003ff, 0x20000155, &MULQ_S_PH , 0, DSP_ }, /* MULQ_S.PH */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x2000015d, 0 , 0, @@ -17516,7 +17516,7 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x20000165, 0 , 0, 0x0 }, /* _POOL32A5~*(44) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x2000016d, &NMD::PRECRQU_S_QB_PH , 0, + 0xfc0003ff, 0x2000016d, &PRECRQU_S_QB_PH , 0, DSP_ }, /* PRECRQU_S.QB.PH */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000175, 0 , 0, @@ -17525,13 +17525,13 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x2000017d, 0 , 0, 0x0 }, /* _POOL32A5~*(47) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000185, &NMD::CMPGDU_EQ_QB , 0, + 0xfc0003ff, 0x20000185, &CMPGDU_EQ_QB , 0, DSP_ }, /* CMPGDU.EQ.QB */ { pool , SHRAV__R__PH , 2 , 32, 0xfc0003ff, 0x2000018d, 0 , 0, 0x0 }, /* SHRAV[_R].PH */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000195, &NMD::MULQ_RS_W , 0, + 0xfc0003ff, 0x20000195, &MULQ_RS_W , 0, DSP_ }, /* MULQ_RS.W */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x2000019d, 0 , 0, @@ -17540,7 +17540,7 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x200001a5, 0 , 0, 0x0 }, /* _POOL32A5~*(52) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200001ad, &NMD::PACKRL_PH , 0, + 0xfc0003ff, 0x200001ad, &PACKRL_PH , 0, DSP_ }, /* PACKRL.PH */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200001b5, 0 , 0, @@ -17549,13 +17549,13 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x200001bd, 0 , 0, 0x0 }, /* _POOL32A5~*(55) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200001c5, &NMD::CMPGDU_LT_QB , 0, + 0xfc0003ff, 0x200001c5, &CMPGDU_LT_QB , 0, DSP_ }, /* CMPGDU.LT.QB */ { pool , SHRAV__R__QB , 2 , 32, 0xfc0003ff, 0x200001cd, 0 , 0, 0x0 }, /* SHRAV[_R].QB */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200001d5, &NMD::MULQ_S_W , 0, + 0xfc0003ff, 0x200001d5, &MULQ_S_W , 0, DSP_ }, /* MULQ_S.W */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200001dd, 0 , 0, @@ -17564,7 +17564,7 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x200001e5, 0 , 0, 0x0 }, /* _POOL32A5~*(60) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200001ed, &NMD::PICK_QB , 0, + 0xfc0003ff, 0x200001ed, &PICK_QB , 0, DSP_ }, /* PICK.QB */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200001f5, 0 , 0, @@ -17573,13 +17573,13 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x200001fd, 0 , 0, 0x0 }, /* _POOL32A5~*(63) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000205, &NMD::CMPGDU_LE_QB , 0, + 0xfc0003ff, 0x20000205, &CMPGDU_LE_QB , 0, DSP_ }, /* CMPGDU.LE.QB */ { pool , SUBQ__S__PH , 2 , 32, 0xfc0003ff, 0x2000020d, 0 , 0, 0x0 }, /* SUBQ[_S].PH */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000215, &NMD::APPEND , 0, + 0xfc0003ff, 0x20000215, &APPEND , 0, DSP_ }, /* APPEND */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x2000021d, 0 , 0, @@ -17588,7 +17588,7 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x20000225, 0 , 0, 0x0 }, /* _POOL32A5~*(68) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x2000022d, &NMD::PICK_PH , 0, + 0xfc0003ff, 0x2000022d, &PICK_PH , 0, DSP_ }, /* PICK.PH */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000235, 0 , 0, @@ -17597,13 +17597,13 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x2000023d, 0 , 0, 0x0 }, /* _POOL32A5~*(71) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000245, &NMD::CMPU_EQ_QB , 0, + 0xfc0003ff, 0x20000245, &CMPU_EQ_QB , 0, DSP_ }, /* CMPU.EQ.QB */ { pool , SUBQH__R__PH , 2 , 32, 0xfc0003ff, 0x2000024d, 0 , 0, 0x0 }, /* SUBQH[_R].PH */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000255, &NMD::PREPEND , 0, + 0xfc0003ff, 0x20000255, &PREPEND , 0, DSP_ }, /* PREPEND */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x2000025d, 0 , 0, @@ -17621,13 +17621,13 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x2000027d, 0 , 0, 0x0 }, /* _POOL32A5~*(79) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000285, &NMD::CMPU_LT_QB , 0, + 0xfc0003ff, 0x20000285, &CMPU_LT_QB , 0, DSP_ }, /* CMPU.LT.QB */ { pool , SUBQH__R__W , 2 , 32, 0xfc0003ff, 0x2000028d, 0 , 0, 0x0 }, /* SUBQH[_R].W */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000295, &NMD::MODSUB , 0, + 0xfc0003ff, 0x20000295, &MODSUB , 0, DSP_ }, /* MODSUB */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x2000029d, 0 , 0, @@ -17645,13 +17645,13 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x200002bd, 0 , 0, 0x0 }, /* _POOL32A5~*(87) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200002c5, &NMD::CMPU_LE_QB , 0, + 0xfc0003ff, 0x200002c5, &CMPU_LE_QB , 0, DSP_ }, /* CMPU.LE.QB */ { pool , SUBU__S__QB , 2 , 32, 0xfc0003ff, 0x200002cd, 0 , 0, 0x0 }, /* SUBU[_S].QB */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200002d5, &NMD::SHRAV_R_W , 0, + 0xfc0003ff, 0x200002d5, &SHRAV_R_W , 0, DSP_ }, /* SHRAV_R.W */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200002dd, 0 , 0, @@ -17663,19 +17663,19 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x200002ed, 0 , 0, 0x0 }, /* _POOL32A5~*(93) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200002f5, &NMD::SHRA_R_W , 0, + 0xfc0003ff, 0x200002f5, &SHRA_R_W , 0, DSP_ }, /* SHRA_R.W */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200002fd, 0 , 0, 0x0 }, /* _POOL32A5~*(95) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000305, &NMD::ADDQ_S_W , 0, + 0xfc0003ff, 0x20000305, &ADDQ_S_W , 0, DSP_ }, /* ADDQ_S.W */ { pool , SUBU__S__PH , 2 , 32, 0xfc0003ff, 0x2000030d, 0 , 0, 0x0 }, /* SUBU[_S].PH */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000315, &NMD::SHRLV_PH , 0, + 0xfc0003ff, 0x20000315, &SHRLV_PH , 0, DSP_ }, /* SHRLV.PH */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x2000031d, 0 , 0, @@ -17693,13 +17693,13 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x2000033d, 0 , 0, 0x0 }, /* _POOL32A5~*(103) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000345, &NMD::SUBQ_S_W , 0, + 0xfc0003ff, 0x20000345, &SUBQ_S_W , 0, DSP_ }, /* SUBQ_S.W */ { pool , SUBUH__R__QB , 2 , 32, 0xfc0003ff, 0x2000034d, 0 , 0, 0x0 }, /* SUBUH[_R].QB */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000355, &NMD::SHRLV_QB , 0, + 0xfc0003ff, 0x20000355, &SHRLV_QB , 0, DSP_ }, /* SHRLV.QB */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x2000035d, 0 , 0, @@ -17717,13 +17717,13 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x2000037d, 0 , 0, 0x0 }, /* _POOL32A5~*(111) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000385, &NMD::ADDSC , 0, + 0xfc0003ff, 0x20000385, &ADDSC , 0, DSP_ }, /* ADDSC */ { pool , SHLLV__S__PH , 2 , 32, 0xfc0003ff, 0x2000038d, 0 , 0, 0x0 }, /* SHLLV[_S].PH */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000395, &NMD::SHLLV_QB , 0, + 0xfc0003ff, 0x20000395, &SHLLV_QB , 0, DSP_ }, /* SHLLV.QB */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x2000039d, 0 , 0, @@ -17741,13 +17741,13 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x200003bd, 0 , 0, 0x0 }, /* _POOL32A5~*(119) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200003c5, &NMD::ADDWC , 0, + 0xfc0003ff, 0x200003c5, &ADDWC , 0, DSP_ }, /* ADDWC */ { pool , PRECR_SRA__R__PH_W , 2 , 32, 0xfc0003ff, 0x200003cd, 0 , 0, 0x0 }, /* PRECR_SRA[_R].PH.W */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200003d5, &NMD::SHLLV_S_W , 0, + 0xfc0003ff, 0x200003d5, &SHLLV_S_W , 0, DSP_ }, /* SHLLV_S.W */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200003dd, 0 , 0, @@ -17759,7 +17759,7 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x200003ed, 0 , 0, 0x0 }, /* _POOL32A5~*(125) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200003f5, &NMD::SHLL_S_W , 0, + 0xfc0003ff, 0x200003f5, &SHLL_S_W , 0, DSP_ }, /* SHLL_S.W */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200003fd, 0 , 0, @@ -17769,52 +17769,52 @@ NMD::Pool NMD::_POOL32A5[128] = { NMD::Pool NMD::PP_LSX[16] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000007, &NMD::LBX , 0, + 0xfc0007ff, 0x20000007, &LBX , 0, 0x0 }, /* LBX */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000087, &NMD::SBX , 0, + 0xfc0007ff, 0x20000087, &SBX , 0, XMMS_ }, /* SBX */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000107, &NMD::LBUX , 0, + 0xfc0007ff, 0x20000107, &LBUX , 0, 0x0 }, /* LBUX */ { reserved_block , 0 , 0 , 32, 0xfc0007ff, 0x20000187, 0 , 0, 0x0 }, /* PP.LSX~*(3) */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000207, &NMD::LHX , 0, + 0xfc0007ff, 0x20000207, &LHX , 0, 0x0 }, /* LHX */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000287, &NMD::SHX , 0, + 0xfc0007ff, 0x20000287, &SHX , 0, XMMS_ }, /* SHX */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000307, &NMD::LHUX , 0, + 0xfc0007ff, 0x20000307, &LHUX , 0, 0x0 }, /* LHUX */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000387, &NMD::LWUX , 0, + 0xfc0007ff, 0x20000387, &LWUX , 0, MIPS64_ }, /* LWUX */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000407, &NMD::LWX , 0, + 0xfc0007ff, 0x20000407, &LWX , 0, 0x0 }, /* LWX */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000487, &NMD::SWX , 0, + 0xfc0007ff, 0x20000487, &SWX , 0, XMMS_ }, /* SWX */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000507, &NMD::LWC1X , 0, + 0xfc0007ff, 0x20000507, &LWC1X , 0, CP1_ }, /* LWC1X */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000587, &NMD::SWC1X , 0, + 0xfc0007ff, 0x20000587, &SWC1X , 0, CP1_ }, /* SWC1X */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000607, &NMD::LDX , 0, + 0xfc0007ff, 0x20000607, &LDX , 0, MIPS64_ }, /* LDX */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000687, &NMD::SDX , 0, + 0xfc0007ff, 0x20000687, &SDX , 0, MIPS64_ }, /* SDX */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000707, &NMD::LDC1X , 0, + 0xfc0007ff, 0x20000707, &LDC1X , 0, CP1_ }, /* LDC1X */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000787, &NMD::SDC1X , 0, + 0xfc0007ff, 0x20000787, &SDC1X , 0, CP1_ }, /* SDC1X */ }; @@ -17833,40 +17833,40 @@ NMD::Pool NMD::PP_LSXS[16] = { 0xfc0007ff, 0x200001c7, 0 , 0, 0x0 }, /* PP.LSXS~*(3) */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000247, &NMD::LHXS , 0, + 0xfc0007ff, 0x20000247, &LHXS , 0, 0x0 }, /* LHXS */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x200002c7, &NMD::SHXS , 0, + 0xfc0007ff, 0x200002c7, &SHXS , 0, XMMS_ }, /* SHXS */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000347, &NMD::LHUXS , 0, + 0xfc0007ff, 0x20000347, &LHUXS , 0, 0x0 }, /* LHUXS */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x200003c7, &NMD::LWUXS , 0, + 0xfc0007ff, 0x200003c7, &LWUXS , 0, MIPS64_ }, /* LWUXS */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000447, &NMD::LWXS_32_ , 0, + 0xfc0007ff, 0x20000447, &LWXS_32_ , 0, 0x0 }, /* LWXS[32] */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x200004c7, &NMD::SWXS , 0, + 0xfc0007ff, 0x200004c7, &SWXS , 0, XMMS_ }, /* SWXS */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000547, &NMD::LWC1XS , 0, + 0xfc0007ff, 0x20000547, &LWC1XS , 0, CP1_ }, /* LWC1XS */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x200005c7, &NMD::SWC1XS , 0, + 0xfc0007ff, 0x200005c7, &SWC1XS , 0, CP1_ }, /* SWC1XS */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000647, &NMD::LDXS , 0, + 0xfc0007ff, 0x20000647, &LDXS , 0, MIPS64_ }, /* LDXS */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x200006c7, &NMD::SDXS , 0, + 0xfc0007ff, 0x200006c7, &SDXS , 0, MIPS64_ }, /* SDXS */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000747, &NMD::LDC1XS , 0, + 0xfc0007ff, 0x20000747, &LDC1XS , 0, CP1_ }, /* LDC1XS */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x200007c7, &NMD::SDC1XS , 0, + 0xfc0007ff, 0x200007c7, &SDC1XS , 0, CP1_ }, /* SDC1XS */ }; @@ -17883,26 +17883,26 @@ NMD::Pool NMD::P_LSX[2] = { NMD::Pool NMD::POOL32Axf_1_0[4] = { { instruction , 0 , 0 , 32, - 0xfc003fff, 0x2000007f, &NMD::MFHI_DSP_ , 0, + 0xfc003fff, 0x2000007f, &MFHI_DSP_ , 0, DSP_ }, /* MFHI[DSP] */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x2000107f, &NMD::MFLO_DSP_ , 0, + 0xfc003fff, 0x2000107f, &MFLO_DSP_ , 0, DSP_ }, /* MFLO[DSP] */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x2000207f, &NMD::MTHI_DSP_ , 0, + 0xfc003fff, 0x2000207f, &MTHI_DSP_ , 0, DSP_ }, /* MTHI[DSP] */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x2000307f, &NMD::MTLO_DSP_ , 0, + 0xfc003fff, 0x2000307f, &MTLO_DSP_ , 0, DSP_ }, /* MTLO[DSP] */ }; NMD::Pool NMD::POOL32Axf_1_1[4] = { { instruction , 0 , 0 , 32, - 0xfc003fff, 0x2000027f, &NMD::MTHLIP , 0, + 0xfc003fff, 0x2000027f, &MTHLIP , 0, DSP_ }, /* MTHLIP */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x2000127f, &NMD::SHILOV , 0, + 0xfc003fff, 0x2000127f, &SHILOV , 0, DSP_ }, /* SHILOV */ { reserved_block , 0 , 0 , 32, 0xfc003fff, 0x2000227f, 0 , 0, @@ -17915,46 +17915,46 @@ NMD::Pool NMD::POOL32Axf_1_1[4] = { NMD::Pool NMD::POOL32Axf_1_3[4] = { { instruction , 0 , 0 , 32, - 0xfc003fff, 0x2000067f, &NMD::RDDSP , 0, + 0xfc003fff, 0x2000067f, &RDDSP , 0, DSP_ }, /* RDDSP */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x2000167f, &NMD::WRDSP , 0, + 0xfc003fff, 0x2000167f, &WRDSP , 0, DSP_ }, /* WRDSP */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x2000267f, &NMD::EXTP , 0, + 0xfc003fff, 0x2000267f, &EXTP , 0, DSP_ }, /* EXTP */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x2000367f, &NMD::EXTPDP , 0, + 0xfc003fff, 0x2000367f, &EXTPDP , 0, DSP_ }, /* EXTPDP */ }; NMD::Pool NMD::POOL32Axf_1_4[2] = { { instruction , 0 , 0 , 32, - 0xfc001fff, 0x2000087f, &NMD::SHLL_QB , 0, + 0xfc001fff, 0x2000087f, &SHLL_QB , 0, DSP_ }, /* SHLL.QB */ { instruction , 0 , 0 , 32, - 0xfc001fff, 0x2000187f, &NMD::SHRL_QB , 0, + 0xfc001fff, 0x2000187f, &SHRL_QB , 0, DSP_ }, /* SHRL.QB */ }; NMD::Pool NMD::MAQ_S_A__W_PHR[2] = { { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20000a7f, &NMD::MAQ_S_W_PHR , 0, + 0xfc003fff, 0x20000a7f, &MAQ_S_W_PHR , 0, DSP_ }, /* MAQ_S.W.PHR */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20002a7f, &NMD::MAQ_SA_W_PHR , 0, + 0xfc003fff, 0x20002a7f, &MAQ_SA_W_PHR , 0, DSP_ }, /* MAQ_SA.W.PHR */ }; NMD::Pool NMD::MAQ_S_A__W_PHL[2] = { { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20001a7f, &NMD::MAQ_S_W_PHL , 0, + 0xfc003fff, 0x20001a7f, &MAQ_S_W_PHL , 0, DSP_ }, /* MAQ_S.W.PHL */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20003a7f, &NMD::MAQ_SA_W_PHL , 0, + 0xfc003fff, 0x20003a7f, &MAQ_SA_W_PHL , 0, DSP_ }, /* MAQ_SA.W.PHL */ }; @@ -17971,16 +17971,16 @@ NMD::Pool NMD::POOL32Axf_1_5[2] = { NMD::Pool NMD::POOL32Axf_1_7[4] = { { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20000e7f, &NMD::EXTR_W , 0, + 0xfc003fff, 0x20000e7f, &EXTR_W , 0, DSP_ }, /* EXTR.W */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20001e7f, &NMD::EXTR_R_W , 0, + 0xfc003fff, 0x20001e7f, &EXTR_R_W , 0, DSP_ }, /* EXTR_R.W */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20002e7f, &NMD::EXTR_RS_W , 0, + 0xfc003fff, 0x20002e7f, &EXTR_RS_W , 0, DSP_ }, /* EXTR_RS.W */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20003e7f, &NMD::EXTR_S_H , 0, + 0xfc003fff, 0x20003e7f, &EXTR_S_H , 0, DSP_ }, /* EXTR_S.H */ }; @@ -18015,112 +18015,112 @@ NMD::Pool NMD::POOL32Axf_1[8] = { NMD::Pool NMD::POOL32Axf_2_DSP__0_7[8] = { { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200000bf, &NMD::DPA_W_PH , 0, + 0xfc003fff, 0x200000bf, &DPA_W_PH , 0, DSP_ }, /* DPA.W.PH */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200002bf, &NMD::DPAQ_S_W_PH , 0, + 0xfc003fff, 0x200002bf, &DPAQ_S_W_PH , 0, DSP_ }, /* DPAQ_S.W.PH */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200004bf, &NMD::DPS_W_PH , 0, + 0xfc003fff, 0x200004bf, &DPS_W_PH , 0, DSP_ }, /* DPS.W.PH */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200006bf, &NMD::DPSQ_S_W_PH , 0, + 0xfc003fff, 0x200006bf, &DPSQ_S_W_PH , 0, DSP_ }, /* DPSQ_S.W.PH */ { reserved_block , 0 , 0 , 32, 0xfc003fff, 0x200008bf, 0 , 0, 0x0 }, /* POOL32Axf_2(DSP)_0_7~*(4) */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20000abf, &NMD::MADD_DSP_ , 0, + 0xfc003fff, 0x20000abf, &MADD_DSP_ , 0, DSP_ }, /* MADD[DSP] */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20000cbf, &NMD::MULT_DSP_ , 0, + 0xfc003fff, 0x20000cbf, &MULT_DSP_ , 0, DSP_ }, /* MULT[DSP] */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20000ebf, &NMD::EXTRV_W , 0, + 0xfc003fff, 0x20000ebf, &EXTRV_W , 0, DSP_ }, /* EXTRV.W */ }; NMD::Pool NMD::POOL32Axf_2_DSP__8_15[8] = { { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200010bf, &NMD::DPAX_W_PH , 0, + 0xfc003fff, 0x200010bf, &DPAX_W_PH , 0, DSP_ }, /* DPAX.W.PH */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200012bf, &NMD::DPAQ_SA_L_W , 0, + 0xfc003fff, 0x200012bf, &DPAQ_SA_L_W , 0, DSP_ }, /* DPAQ_SA.L.W */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200014bf, &NMD::DPSX_W_PH , 0, + 0xfc003fff, 0x200014bf, &DPSX_W_PH , 0, DSP_ }, /* DPSX.W.PH */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200016bf, &NMD::DPSQ_SA_L_W , 0, + 0xfc003fff, 0x200016bf, &DPSQ_SA_L_W , 0, DSP_ }, /* DPSQ_SA.L.W */ { reserved_block , 0 , 0 , 32, 0xfc003fff, 0x200018bf, 0 , 0, 0x0 }, /* POOL32Axf_2(DSP)_8_15~*(4) */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20001abf, &NMD::MADDU_DSP_ , 0, + 0xfc003fff, 0x20001abf, &MADDU_DSP_ , 0, DSP_ }, /* MADDU[DSP] */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20001cbf, &NMD::MULTU_DSP_ , 0, + 0xfc003fff, 0x20001cbf, &MULTU_DSP_ , 0, DSP_ }, /* MULTU[DSP] */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20001ebf, &NMD::EXTRV_R_W , 0, + 0xfc003fff, 0x20001ebf, &EXTRV_R_W , 0, DSP_ }, /* EXTRV_R.W */ }; NMD::Pool NMD::POOL32Axf_2_DSP__16_23[8] = { { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200020bf, &NMD::DPAU_H_QBL , 0, + 0xfc003fff, 0x200020bf, &DPAU_H_QBL , 0, DSP_ }, /* DPAU.H.QBL */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200022bf, &NMD::DPAQX_S_W_PH , 0, + 0xfc003fff, 0x200022bf, &DPAQX_S_W_PH , 0, DSP_ }, /* DPAQX_S.W.PH */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200024bf, &NMD::DPSU_H_QBL , 0, + 0xfc003fff, 0x200024bf, &DPSU_H_QBL , 0, DSP_ }, /* DPSU.H.QBL */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200026bf, &NMD::DPSQX_S_W_PH , 0, + 0xfc003fff, 0x200026bf, &DPSQX_S_W_PH , 0, DSP_ }, /* DPSQX_S.W.PH */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200028bf, &NMD::EXTPV , 0, + 0xfc003fff, 0x200028bf, &EXTPV , 0, DSP_ }, /* EXTPV */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20002abf, &NMD::MSUB_DSP_ , 0, + 0xfc003fff, 0x20002abf, &MSUB_DSP_ , 0, DSP_ }, /* MSUB[DSP] */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20002cbf, &NMD::MULSA_W_PH , 0, + 0xfc003fff, 0x20002cbf, &MULSA_W_PH , 0, DSP_ }, /* MULSA.W.PH */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20002ebf, &NMD::EXTRV_RS_W , 0, + 0xfc003fff, 0x20002ebf, &EXTRV_RS_W , 0, DSP_ }, /* EXTRV_RS.W */ }; NMD::Pool NMD::POOL32Axf_2_DSP__24_31[8] = { { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200030bf, &NMD::DPAU_H_QBR , 0, + 0xfc003fff, 0x200030bf, &DPAU_H_QBR , 0, DSP_ }, /* DPAU.H.QBR */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200032bf, &NMD::DPAQX_SA_W_PH , 0, + 0xfc003fff, 0x200032bf, &DPAQX_SA_W_PH , 0, DSP_ }, /* DPAQX_SA.W.PH */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200034bf, &NMD::DPSU_H_QBR , 0, + 0xfc003fff, 0x200034bf, &DPSU_H_QBR , 0, DSP_ }, /* DPSU.H.QBR */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200036bf, &NMD::DPSQX_SA_W_PH , 0, + 0xfc003fff, 0x200036bf, &DPSQX_SA_W_PH , 0, DSP_ }, /* DPSQX_SA.W.PH */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200038bf, &NMD::EXTPDPV , 0, + 0xfc003fff, 0x200038bf, &EXTPDPV , 0, DSP_ }, /* EXTPDPV */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20003abf, &NMD::MSUBU_DSP_ , 0, + 0xfc003fff, 0x20003abf, &MSUBU_DSP_ , 0, DSP_ }, /* MSUBU[DSP] */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20003cbf, &NMD::MULSAQ_S_W_PH , 0, + 0xfc003fff, 0x20003cbf, &MULSAQ_S_W_PH , 0, DSP_ }, /* MULSAQ_S.W.PH */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20003ebf, &NMD::EXTRV_S_H , 0, + 0xfc003fff, 0x20003ebf, &EXTRV_S_H , 0, DSP_ }, /* EXTRV_S.H */ }; @@ -18143,10 +18143,10 @@ NMD::Pool NMD::POOL32Axf_2[4] = { NMD::Pool NMD::POOL32Axf_4[128] = { { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000013f, &NMD::ABSQ_S_QB , 0, + 0xfc00ffff, 0x2000013f, &ABSQ_S_QB , 0, DSP_ }, /* ABSQ_S.QB */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000033f, &NMD::REPLV_PH , 0, + 0xfc00ffff, 0x2000033f, &REPLV_PH , 0, DSP_ }, /* REPLV.PH */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000053f, 0 , 0, @@ -18167,10 +18167,10 @@ NMD::Pool NMD::POOL32Axf_4[128] = { 0xfc00ffff, 0x20000f3f, 0 , 0, 0x0 }, /* POOL32Axf_4~*(7) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000113f, &NMD::ABSQ_S_PH , 0, + 0xfc00ffff, 0x2000113f, &ABSQ_S_PH , 0, DSP_ }, /* ABSQ_S.PH */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000133f, &NMD::REPLV_QB , 0, + 0xfc00ffff, 0x2000133f, &REPLV_QB , 0, DSP_ }, /* REPLV.QB */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000153f, 0 , 0, @@ -18191,7 +18191,7 @@ NMD::Pool NMD::POOL32Axf_4[128] = { 0xfc00ffff, 0x20001f3f, 0 , 0, 0x0 }, /* POOL32Axf_4~*(15) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000213f, &NMD::ABSQ_S_W , 0, + 0xfc00ffff, 0x2000213f, &ABSQ_S_W , 0, DSP_ }, /* ABSQ_S.W */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000233f, 0 , 0, @@ -18239,7 +18239,7 @@ NMD::Pool NMD::POOL32Axf_4[128] = { 0xfc00ffff, 0x20003f3f, 0 , 0, 0x0 }, /* POOL32Axf_4~*(31) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000413f, &NMD::INSV , 0, + 0xfc00ffff, 0x2000413f, &INSV , 0, DSP_ }, /* INSV */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000433f, 0 , 0, @@ -18254,16 +18254,16 @@ NMD::Pool NMD::POOL32Axf_4[128] = { 0xfc00ffff, 0x2000493f, 0 , 0, 0x0 }, /* POOL32Axf_4~*(36) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x20004b3f, &NMD::CLO , 0, + 0xfc00ffff, 0x20004b3f, &CLO , 0, XMMS_ }, /* CLO */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x20004d3f, &NMD::MFC2 , 0, + 0xfc00ffff, 0x20004d3f, &MFC2 , 0, CP2_ }, /* MFC2 */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x20004f3f, 0 , 0, 0x0 }, /* POOL32Axf_4~*(39) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000513f, &NMD::PRECEQ_W_PHL , 0, + 0xfc00ffff, 0x2000513f, &PRECEQ_W_PHL , 0, DSP_ }, /* PRECEQ.W.PHL */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000533f, 0 , 0, @@ -18278,16 +18278,16 @@ NMD::Pool NMD::POOL32Axf_4[128] = { 0xfc00ffff, 0x2000593f, 0 , 0, 0x0 }, /* POOL32Axf_4~*(44) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x20005b3f, &NMD::CLZ , 0, + 0xfc00ffff, 0x20005b3f, &CLZ , 0, XMMS_ }, /* CLZ */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x20005d3f, &NMD::MTC2 , 0, + 0xfc00ffff, 0x20005d3f, &MTC2 , 0, CP2_ }, /* MTC2 */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x20005f3f, 0 , 0, 0x0 }, /* POOL32Axf_4~*(47) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000613f, &NMD::PRECEQ_W_PHR , 0, + 0xfc00ffff, 0x2000613f, &PRECEQ_W_PHR , 0, DSP_ }, /* PRECEQ.W.PHR */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000633f, 0 , 0, @@ -18305,16 +18305,16 @@ NMD::Pool NMD::POOL32Axf_4[128] = { 0xfc00ffff, 0x20006b3f, 0 , 0, 0x0 }, /* POOL32Axf_4~*(53) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x20006d3f, &NMD::DMFC2 , 0, + 0xfc00ffff, 0x20006d3f, &DMFC2 , 0, CP2_ }, /* DMFC2 */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x20006f3f, 0 , 0, 0x0 }, /* POOL32Axf_4~*(55) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000713f, &NMD::PRECEQU_PH_QBL , 0, + 0xfc00ffff, 0x2000713f, &PRECEQU_PH_QBL , 0, DSP_ }, /* PRECEQU.PH.QBL */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000733f, &NMD::PRECEQU_PH_QBLA , 0, + 0xfc00ffff, 0x2000733f, &PRECEQU_PH_QBLA , 0, DSP_ }, /* PRECEQU.PH.QBLA */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000753f, 0 , 0, @@ -18329,7 +18329,7 @@ NMD::Pool NMD::POOL32Axf_4[128] = { 0xfc00ffff, 0x20007b3f, 0 , 0, 0x0 }, /* POOL32Axf_4~*(61) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x20007d3f, &NMD::DMTC2 , 0, + 0xfc00ffff, 0x20007d3f, &DMTC2 , 0, CP2_ }, /* DMTC2 */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x20007f3f, 0 , 0, @@ -18353,16 +18353,16 @@ NMD::Pool NMD::POOL32Axf_4[128] = { 0xfc00ffff, 0x20008b3f, 0 , 0, 0x0 }, /* POOL32Axf_4~*(69) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x20008d3f, &NMD::MFHC2 , 0, + 0xfc00ffff, 0x20008d3f, &MFHC2 , 0, CP2_ }, /* MFHC2 */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x20008f3f, 0 , 0, 0x0 }, /* POOL32Axf_4~*(71) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000913f, &NMD::PRECEQU_PH_QBR , 0, + 0xfc00ffff, 0x2000913f, &PRECEQU_PH_QBR , 0, DSP_ }, /* PRECEQU.PH.QBR */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000933f, &NMD::PRECEQU_PH_QBRA , 0, + 0xfc00ffff, 0x2000933f, &PRECEQU_PH_QBRA , 0, DSP_ }, /* PRECEQU.PH.QBRA */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000953f, 0 , 0, @@ -18377,7 +18377,7 @@ NMD::Pool NMD::POOL32Axf_4[128] = { 0xfc00ffff, 0x20009b3f, 0 , 0, 0x0 }, /* POOL32Axf_4~*(77) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x20009d3f, &NMD::MTHC2 , 0, + 0xfc00ffff, 0x20009d3f, &MTHC2 , 0, CP2_ }, /* MTHC2 */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x20009f3f, 0 , 0, @@ -18407,10 +18407,10 @@ NMD::Pool NMD::POOL32Axf_4[128] = { 0xfc00ffff, 0x2000af3f, 0 , 0, 0x0 }, /* POOL32Axf_4~*(87) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000b13f, &NMD::PRECEU_PH_QBL , 0, + 0xfc00ffff, 0x2000b13f, &PRECEU_PH_QBL , 0, DSP_ }, /* PRECEU.PH.QBL */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000b33f, &NMD::PRECEU_PH_QBLA , 0, + 0xfc00ffff, 0x2000b33f, &PRECEU_PH_QBLA , 0, DSP_ }, /* PRECEU.PH.QBLA */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000b53f, 0 , 0, @@ -18449,16 +18449,16 @@ NMD::Pool NMD::POOL32Axf_4[128] = { 0xfc00ffff, 0x2000cb3f, 0 , 0, 0x0 }, /* POOL32Axf_4~*(101) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000cd3f, &NMD::CFC2 , 0, + 0xfc00ffff, 0x2000cd3f, &CFC2 , 0, CP2_ }, /* CFC2 */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000cf3f, 0 , 0, 0x0 }, /* POOL32Axf_4~*(103) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000d13f, &NMD::PRECEU_PH_QBR , 0, + 0xfc00ffff, 0x2000d13f, &PRECEU_PH_QBR , 0, DSP_ }, /* PRECEU.PH.QBR */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000d33f, &NMD::PRECEU_PH_QBRA , 0, + 0xfc00ffff, 0x2000d33f, &PRECEU_PH_QBRA , 0, DSP_ }, /* PRECEU.PH.QBRA */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000d53f, 0 , 0, @@ -18473,7 +18473,7 @@ NMD::Pool NMD::POOL32Axf_4[128] = { 0xfc00ffff, 0x2000db3f, 0 , 0, 0x0 }, /* POOL32Axf_4~*(109) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000dd3f, &NMD::CTC2 , 0, + 0xfc00ffff, 0x2000dd3f, &CTC2 , 0, CP2_ }, /* CTC2 */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000df3f, 0 , 0, @@ -18503,7 +18503,7 @@ NMD::Pool NMD::POOL32Axf_4[128] = { 0xfc00ffff, 0x2000ef3f, 0 , 0, 0x0 }, /* POOL32Axf_4~*(119) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000f13f, &NMD::RADDU_W_QB , 0, + 0xfc00ffff, 0x2000f13f, &RADDU_W_QB , 0, DSP_ }, /* RADDU.W.QB */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000f33f, 0 , 0, @@ -18531,16 +18531,16 @@ NMD::Pool NMD::POOL32Axf_4[128] = { NMD::Pool NMD::POOL32Axf_5_group0[32] = { { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000017f, &NMD::TLBGP , 0, + 0xfc00ffff, 0x2000017f, &TLBGP , 0, CP0_ | VZ_ | TLB_ }, /* TLBGP */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000037f, &NMD::TLBP , 0, + 0xfc00ffff, 0x2000037f, &TLBP , 0, CP0_ | TLB_ }, /* TLBP */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000057f, &NMD::TLBGINV , 0, + 0xfc00ffff, 0x2000057f, &TLBGINV , 0, CP0_ | VZ_ | TLB_ | TLBINV_}, /* TLBGINV */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000077f, &NMD::TLBINV , 0, + 0xfc00ffff, 0x2000077f, &TLBINV , 0, CP0_ | TLB_ | TLBINV_}, /* TLBINV */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000097f, 0 , 0, @@ -18555,16 +18555,16 @@ NMD::Pool NMD::POOL32Axf_5_group0[32] = { 0xfc00ffff, 0x20000f7f, 0 , 0, 0x0 }, /* POOL32Axf_5_group0~*(7) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000117f, &NMD::TLBGR , 0, + 0xfc00ffff, 0x2000117f, &TLBGR , 0, CP0_ | VZ_ | TLB_ }, /* TLBGR */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000137f, &NMD::TLBR , 0, + 0xfc00ffff, 0x2000137f, &TLBR , 0, CP0_ | TLB_ }, /* TLBR */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000157f, &NMD::TLBGINVF , 0, + 0xfc00ffff, 0x2000157f, &TLBGINVF , 0, CP0_ | VZ_ | TLB_ | TLBINV_}, /* TLBGINVF */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000177f, &NMD::TLBINVF , 0, + 0xfc00ffff, 0x2000177f, &TLBINVF , 0, CP0_ | TLB_ | TLBINV_}, /* TLBINVF */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000197f, 0 , 0, @@ -18579,10 +18579,10 @@ NMD::Pool NMD::POOL32Axf_5_group0[32] = { 0xfc00ffff, 0x20001f7f, 0 , 0, 0x0 }, /* POOL32Axf_5_group0~*(15) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000217f, &NMD::TLBGWI , 0, + 0xfc00ffff, 0x2000217f, &TLBGWI , 0, CP0_ | VZ_ | TLB_ }, /* TLBGWI */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000237f, &NMD::TLBWI , 0, + 0xfc00ffff, 0x2000237f, &TLBWI , 0, CP0_ | TLB_ }, /* TLBWI */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000257f, 0 , 0, @@ -18603,10 +18603,10 @@ NMD::Pool NMD::POOL32Axf_5_group0[32] = { 0xfc00ffff, 0x20002f7f, 0 , 0, 0x0 }, /* POOL32Axf_5_group0~*(23) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000317f, &NMD::TLBGWR , 0, + 0xfc00ffff, 0x2000317f, &TLBGWR , 0, CP0_ | VZ_ | TLB_ }, /* TLBGWR */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000337f, &NMD::TLBWR , 0, + 0xfc00ffff, 0x2000337f, &TLBWR , 0, CP0_ | TLB_ }, /* TLBWR */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000357f, 0 , 0, @@ -18640,7 +18640,7 @@ NMD::Pool NMD::POOL32Axf_5_group1[32] = { 0xfc00ffff, 0x2000457f, 0 , 0, 0x0 }, /* POOL32Axf_5_group1~*(2) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000477f, &NMD::DI , 0, + 0xfc00ffff, 0x2000477f, &DI , 0, 0x0 }, /* DI */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000497f, 0 , 0, @@ -18664,7 +18664,7 @@ NMD::Pool NMD::POOL32Axf_5_group1[32] = { 0xfc00ffff, 0x2000557f, 0 , 0, 0x0 }, /* POOL32Axf_5_group1~*(10) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000577f, &NMD::EI , 0, + 0xfc00ffff, 0x2000577f, &EI , 0, 0x0 }, /* EI */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000597f, 0 , 0, @@ -18731,10 +18731,10 @@ NMD::Pool NMD::POOL32Axf_5_group1[32] = { NMD::Pool NMD::ERETx[2] = { { instruction , 0 , 0 , 32, - 0xfc01ffff, 0x2000f37f, &NMD::ERET , 0, + 0xfc01ffff, 0x2000f37f, &ERET , 0, 0x0 }, /* ERET */ { instruction , 0 , 0 , 32, - 0xfc01ffff, 0x2001f37f, &NMD::ERETNC , 0, + 0xfc01ffff, 0x2001f37f, &ERETNC , 0, 0x0 }, /* ERETNC */ }; @@ -18744,7 +18744,7 @@ NMD::Pool NMD::POOL32Axf_5_group3[32] = { 0xfc00ffff, 0x2000c17f, 0 , 0, 0x0 }, /* POOL32Axf_5_group3~*(0) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000c37f, &NMD::WAIT , 0, + 0xfc00ffff, 0x2000c37f, &WAIT , 0, 0x0 }, /* WAIT */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000c57f, 0 , 0, @@ -18768,7 +18768,7 @@ NMD::Pool NMD::POOL32Axf_5_group3[32] = { 0xfc00ffff, 0x2000d17f, 0 , 0, 0x0 }, /* POOL32Axf_5_group3~*(8) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000d37f, &NMD::IRET , 0, + 0xfc00ffff, 0x2000d37f, &IRET , 0, MCU_ }, /* IRET */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000d57f, 0 , 0, @@ -18789,10 +18789,10 @@ NMD::Pool NMD::POOL32Axf_5_group3[32] = { 0xfc00ffff, 0x2000df7f, 0 , 0, 0x0 }, /* POOL32Axf_5_group3~*(15) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000e17f, &NMD::RDPGPR , 0, + 0xfc00ffff, 0x2000e17f, &RDPGPR , 0, CP0_ }, /* RDPGPR */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000e37f, &NMD::DERET , 0, + 0xfc00ffff, 0x2000e37f, &DERET , 0, EJTAG_ }, /* DERET */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000e57f, 0 , 0, @@ -18813,7 +18813,7 @@ NMD::Pool NMD::POOL32Axf_5_group3[32] = { 0xfc00ffff, 0x2000ef7f, 0 , 0, 0x0 }, /* POOL32Axf_5_group3~*(23) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000f17f, &NMD::WRPGPR , 0, + 0xfc00ffff, 0x2000f17f, &WRPGPR , 0, CP0_ }, /* WRPGPR */ { pool , ERETx , 2 , 32, 0xfc00ffff, 0x2000f37f, 0 , 0, @@ -18857,10 +18857,10 @@ NMD::Pool NMD::POOL32Axf_5[4] = { NMD::Pool NMD::SHRA__R__QB[2] = { { instruction , 0 , 0 , 32, - 0xfc001fff, 0x200001ff, &NMD::SHRA_QB , 0, + 0xfc001fff, 0x200001ff, &SHRA_QB , 0, DSP_ }, /* SHRA.QB */ { instruction , 0 , 0 , 32, - 0xfc001fff, 0x200011ff, &NMD::SHRA_R_QB , 0, + 0xfc001fff, 0x200011ff, &SHRA_R_QB , 0, DSP_ }, /* SHRA_R.QB */ }; @@ -18870,10 +18870,10 @@ NMD::Pool NMD::POOL32Axf_7[8] = { 0xfc000fff, 0x200001ff, 0 , 0, 0x0 }, /* SHRA[_R].QB */ { instruction , 0 , 0 , 32, - 0xfc000fff, 0x200003ff, &NMD::SHRL_PH , 0, + 0xfc000fff, 0x200003ff, &SHRL_PH , 0, DSP_ }, /* SHRL.PH */ { instruction , 0 , 0 , 32, - 0xfc000fff, 0x200005ff, &NMD::REPL_QB , 0, + 0xfc000fff, 0x200005ff, &REPL_QB , 0, DSP_ }, /* REPL.QB */ { reserved_block , 0 , 0 , 32, 0xfc000fff, 0x200007ff, 0 , 0, @@ -18926,13 +18926,13 @@ NMD::Pool NMD::_POOL32A7[8] = { 0xfc00003f, 0x20000007, 0 , 0, 0x0 }, /* P.LSX */ { instruction , 0 , 0 , 32, - 0xfc00003f, 0x2000000f, &NMD::LSA , 0, + 0xfc00003f, 0x2000000f, &LSA , 0, 0x0 }, /* LSA */ { reserved_block , 0 , 0 , 32, 0xfc00003f, 0x20000017, 0 , 0, 0x0 }, /* _POOL32A7~*(2) */ { instruction , 0 , 0 , 32, - 0xfc00003f, 0x2000001f, &NMD::EXTW , 0, + 0xfc00003f, 0x2000001f, &EXTW , 0, 0x0 }, /* EXTW */ { reserved_block , 0 , 0 , 32, 0xfc00003f, 0x20000027, 0 , 0, @@ -18954,13 +18954,13 @@ NMD::Pool NMD::P32A[8] = { 0xfc000007, 0x20000000, 0 , 0, 0x0 }, /* _POOL32A0 */ { instruction , 0 , 0 , 32, - 0xfc000007, 0x20000001, &NMD::SPECIAL2 , 0, + 0xfc000007, 0x20000001, &SPECIAL2 , 0, UDI_ }, /* SPECIAL2 */ { instruction , 0 , 0 , 32, - 0xfc000007, 0x20000002, &NMD::COP2_1 , 0, + 0xfc000007, 0x20000002, &COP2_1 , 0, CP2_ }, /* COP2_1 */ { instruction , 0 , 0 , 32, - 0xfc000007, 0x20000003, &NMD::UDI , 0, + 0xfc000007, 0x20000003, &UDI , 0, UDI_ }, /* UDI */ { reserved_block , 0 , 0 , 32, 0xfc000007, 0x20000004, 0 , 0, @@ -18979,42 +18979,42 @@ NMD::Pool NMD::P32A[8] = { NMD::Pool NMD::P_GP_D[2] = { { instruction , 0 , 0 , 32, - 0xfc000007, 0x40000001, &NMD::LD_GP_ , 0, + 0xfc000007, 0x40000001, &LD_GP_ , 0, MIPS64_ }, /* LD[GP] */ { instruction , 0 , 0 , 32, - 0xfc000007, 0x40000005, &NMD::SD_GP_ , 0, + 0xfc000007, 0x40000005, &SD_GP_ , 0, MIPS64_ }, /* SD[GP] */ }; NMD::Pool NMD::P_GP_W[4] = { { instruction , 0 , 0 , 32, - 0xfc000003, 0x40000000, &NMD::ADDIU_GP_W_ , 0, + 0xfc000003, 0x40000000, &ADDIU_GP_W_ , 0, 0x0 }, /* ADDIU[GP.W] */ { pool , P_GP_D , 2 , 32, 0xfc000003, 0x40000001, 0 , 0, 0x0 }, /* P.GP.D */ { instruction , 0 , 0 , 32, - 0xfc000003, 0x40000002, &NMD::LW_GP_ , 0, + 0xfc000003, 0x40000002, &LW_GP_ , 0, 0x0 }, /* LW[GP] */ { instruction , 0 , 0 , 32, - 0xfc000003, 0x40000003, &NMD::SW_GP_ , 0, + 0xfc000003, 0x40000003, &SW_GP_ , 0, 0x0 }, /* SW[GP] */ }; NMD::Pool NMD::POOL48I[32] = { { instruction , 0 , 0 , 48, - 0xfc1f00000000ull, 0x600000000000ull, &NMD::LI_48_ , 0, + 0xfc1f00000000ull, 0x600000000000ull, &LI_48_ , 0, XMMS_ }, /* LI[48] */ { instruction , 0 , 0 , 48, - 0xfc1f00000000ull, 0x600100000000ull, &NMD::ADDIU_48_ , 0, + 0xfc1f00000000ull, 0x600100000000ull, &ADDIU_48_ , 0, XMMS_ }, /* ADDIU[48] */ { instruction , 0 , 0 , 48, - 0xfc1f00000000ull, 0x600200000000ull, &NMD::ADDIU_GP48_ , 0, + 0xfc1f00000000ull, 0x600200000000ull, &ADDIU_GP48_ , 0, XMMS_ }, /* ADDIU[GP48] */ { instruction , 0 , 0 , 48, - 0xfc1f00000000ull, 0x600300000000ull, &NMD::ADDIUPC_48_ , 0, + 0xfc1f00000000ull, 0x600300000000ull, &ADDIUPC_48_ , 0, XMMS_ }, /* ADDIUPC[48] */ { reserved_block , 0 , 0 , 48, 0xfc1f00000000ull, 0x600400000000ull, 0 , 0, @@ -19038,7 +19038,7 @@ NMD::Pool NMD::POOL48I[32] = { 0xfc1f00000000ull, 0x600a00000000ull, 0 , 0, 0x0 }, /* POOL48I~*(10) */ { instruction , 0 , 0 , 48, - 0xfc1f00000000ull, 0x600b00000000ull, &NMD::LWPC_48_ , 0, + 0xfc1f00000000ull, 0x600b00000000ull, &LWPC_48_ , 0, XMMS_ }, /* LWPC[48] */ { reserved_block , 0 , 0 , 48, 0xfc1f00000000ull, 0x600c00000000ull, 0 , 0, @@ -19050,13 +19050,13 @@ NMD::Pool NMD::POOL48I[32] = { 0xfc1f00000000ull, 0x600e00000000ull, 0 , 0, 0x0 }, /* POOL48I~*(14) */ { instruction , 0 , 0 , 48, - 0xfc1f00000000ull, 0x600f00000000ull, &NMD::SWPC_48_ , 0, + 0xfc1f00000000ull, 0x600f00000000ull, &SWPC_48_ , 0, XMMS_ }, /* SWPC[48] */ { reserved_block , 0 , 0 , 48, 0xfc1f00000000ull, 0x601000000000ull, 0 , 0, 0x0 }, /* POOL48I~*(16) */ { instruction , 0 , 0 , 48, - 0xfc1f00000000ull, 0x601100000000ull, &NMD::DADDIU_48_ , 0, + 0xfc1f00000000ull, 0x601100000000ull, &DADDIU_48_ , 0, MIPS64_ }, /* DADDIU[48] */ { reserved_block , 0 , 0 , 48, 0xfc1f00000000ull, 0x601200000000ull, 0 , 0, @@ -19065,7 +19065,7 @@ NMD::Pool NMD::POOL48I[32] = { 0xfc1f00000000ull, 0x601300000000ull, 0 , 0, 0x0 }, /* POOL48I~*(19) */ { instruction , 0 , 0 , 48, - 0xfc1f00000000ull, 0x601400000000ull, &NMD::DLUI_48_ , 0, + 0xfc1f00000000ull, 0x601400000000ull, &DLUI_48_ , 0, MIPS64_ }, /* DLUI[48] */ { reserved_block , 0 , 0 , 48, 0xfc1f00000000ull, 0x601500000000ull, 0 , 0, @@ -19086,7 +19086,7 @@ NMD::Pool NMD::POOL48I[32] = { 0xfc1f00000000ull, 0x601a00000000ull, 0 , 0, 0x0 }, /* POOL48I~*(26) */ { instruction , 0 , 0 , 48, - 0xfc1f00000000ull, 0x601b00000000ull, &NMD::LDPC_48_ , 0, + 0xfc1f00000000ull, 0x601b00000000ull, &LDPC_48_ , 0, MIPS64_ }, /* LDPC[48] */ { reserved_block , 0 , 0 , 48, 0xfc1f00000000ull, 0x601c00000000ull, 0 , 0, @@ -19098,33 +19098,33 @@ NMD::Pool NMD::POOL48I[32] = { 0xfc1f00000000ull, 0x601e00000000ull, 0 , 0, 0x0 }, /* POOL48I~*(30) */ { instruction , 0 , 0 , 48, - 0xfc1f00000000ull, 0x601f00000000ull, &NMD::SDPC_48_ , 0, + 0xfc1f00000000ull, 0x601f00000000ull, &SDPC_48_ , 0, MIPS64_ }, /* SDPC[48] */ }; NMD::Pool NMD::PP_SR[4] = { { instruction , 0 , 0 , 32, - 0xfc10f003, 0x80003000, &NMD::SAVE_32_ , 0, + 0xfc10f003, 0x80003000, &SAVE_32_ , 0, 0x0 }, /* SAVE[32] */ { reserved_block , 0 , 0 , 32, 0xfc10f003, 0x80003001, 0 , 0, 0x0 }, /* PP.SR~*(1) */ { instruction , 0 , 0 , 32, - 0xfc10f003, 0x80003002, &NMD::RESTORE_32_ , 0, + 0xfc10f003, 0x80003002, &RESTORE_32_ , 0, 0x0 }, /* RESTORE[32] */ { return_instruction , 0 , 0 , 32, - 0xfc10f003, 0x80003003, &NMD::RESTORE_JRC_32_ , 0, + 0xfc10f003, 0x80003003, &RESTORE_JRC_32_ , 0, 0x0 }, /* RESTORE.JRC[32] */ }; NMD::Pool NMD::P_SR_F[8] = { { instruction , 0 , 0 , 32, - 0xfc10f007, 0x80103000, &NMD::SAVEF , 0, + 0xfc10f007, 0x80103000, &SAVEF , 0, CP1_ }, /* SAVEF */ { instruction , 0 , 0 , 32, - 0xfc10f007, 0x80103001, &NMD::RESTOREF , 0, + 0xfc10f007, 0x80103001, &RESTOREF , 0, CP1_ }, /* RESTOREF */ { reserved_block , 0 , 0 , 32, 0xfc10f007, 0x80103002, 0 , 0, @@ -19159,19 +19159,19 @@ NMD::Pool NMD::P_SR[2] = { NMD::Pool NMD::P_SLL[5] = { { instruction , 0 , 0 , 32, - 0xffe0f1ff, 0x8000c000, &NMD::NOP_32_ , 0, + 0xffe0f1ff, 0x8000c000, &NOP_32_ , 0, 0x0 }, /* NOP[32] */ { instruction , 0 , 0 , 32, - 0xffe0f1ff, 0x8000c003, &NMD::EHB , 0, + 0xffe0f1ff, 0x8000c003, &EHB , 0, 0x0 }, /* EHB */ { instruction , 0 , 0 , 32, - 0xffe0f1ff, 0x8000c005, &NMD::PAUSE , 0, + 0xffe0f1ff, 0x8000c005, &PAUSE , 0, 0x0 }, /* PAUSE */ { instruction , 0 , 0 , 32, - 0xffe0f1ff, 0x8000c006, &NMD::SYNC , 0, + 0xffe0f1ff, 0x8000c006, &SYNC , 0, 0x0 }, /* SYNC */ { instruction , 0 , 0 , 32, - 0xfc00f1e0, 0x8000c000, &NMD::SLL_32_ , 0, + 0xfc00f1e0, 0x8000c000, &SLL_32_ , 0, 0x0 }, /* SLL[32] */ }; @@ -19184,53 +19184,53 @@ NMD::Pool NMD::P_SHIFT[16] = { 0xfc00f1e0, 0x8000c020, 0 , 0, 0x0 }, /* P.SHIFT~*(1) */ { instruction , 0 , 0 , 32, - 0xfc00f1e0, 0x8000c040, &NMD::SRL_32_ , 0, + 0xfc00f1e0, 0x8000c040, &SRL_32_ , 0, 0x0 }, /* SRL[32] */ { reserved_block , 0 , 0 , 32, 0xfc00f1e0, 0x8000c060, 0 , 0, 0x0 }, /* P.SHIFT~*(3) */ { instruction , 0 , 0 , 32, - 0xfc00f1e0, 0x8000c080, &NMD::SRA , 0, + 0xfc00f1e0, 0x8000c080, &SRA , 0, 0x0 }, /* SRA */ { reserved_block , 0 , 0 , 32, 0xfc00f1e0, 0x8000c0a0, 0 , 0, 0x0 }, /* P.SHIFT~*(5) */ { instruction , 0 , 0 , 32, - 0xfc00f1e0, 0x8000c0c0, &NMD::ROTR , 0, + 0xfc00f1e0, 0x8000c0c0, &ROTR , 0, 0x0 }, /* ROTR */ { reserved_block , 0 , 0 , 32, 0xfc00f1e0, 0x8000c0e0, 0 , 0, 0x0 }, /* P.SHIFT~*(7) */ { instruction , 0 , 0 , 32, - 0xfc00f1e0, 0x8000c100, &NMD::DSLL , 0, + 0xfc00f1e0, 0x8000c100, &DSLL , 0, MIPS64_ }, /* DSLL */ { instruction , 0 , 0 , 32, - 0xfc00f1e0, 0x8000c120, &NMD::DSLL32 , 0, + 0xfc00f1e0, 0x8000c120, &DSLL32 , 0, MIPS64_ }, /* DSLL32 */ { instruction , 0 , 0 , 32, - 0xfc00f1e0, 0x8000c140, &NMD::DSRL , 0, + 0xfc00f1e0, 0x8000c140, &DSRL , 0, MIPS64_ }, /* DSRL */ { instruction , 0 , 0 , 32, - 0xfc00f1e0, 0x8000c160, &NMD::DSRL32 , 0, + 0xfc00f1e0, 0x8000c160, &DSRL32 , 0, MIPS64_ }, /* DSRL32 */ { instruction , 0 , 0 , 32, - 0xfc00f1e0, 0x8000c180, &NMD::DSRA , 0, + 0xfc00f1e0, 0x8000c180, &DSRA , 0, MIPS64_ }, /* DSRA */ { instruction , 0 , 0 , 32, - 0xfc00f1e0, 0x8000c1a0, &NMD::DSRA32 , 0, + 0xfc00f1e0, 0x8000c1a0, &DSRA32 , 0, MIPS64_ }, /* DSRA32 */ { instruction , 0 , 0 , 32, - 0xfc00f1e0, 0x8000c1c0, &NMD::DROTR , 0, + 0xfc00f1e0, 0x8000c1c0, &DROTR , 0, MIPS64_ }, /* DROTR */ { instruction , 0 , 0 , 32, - 0xfc00f1e0, 0x8000c1e0, &NMD::DROTR32 , 0, + 0xfc00f1e0, 0x8000c1e0, &DROTR32 , 0, MIPS64_ }, /* DROTR32 */ }; NMD::Pool NMD::P_ROTX[4] = { { instruction , 0 , 0 , 32, - 0xfc00f820, 0x8000d000, &NMD::ROTX , 0, + 0xfc00f820, 0x8000d000, &ROTX , 0, XMMS_ }, /* ROTX */ { reserved_block , 0 , 0 , 32, 0xfc00f820, 0x8000d020, 0 , 0, @@ -19246,72 +19246,72 @@ NMD::Pool NMD::P_ROTX[4] = { NMD::Pool NMD::P_INS[4] = { { instruction , 0 , 0 , 32, - 0xfc00f820, 0x8000e000, &NMD::INS , 0, + 0xfc00f820, 0x8000e000, &INS , 0, XMMS_ }, /* INS */ { instruction , 0 , 0 , 32, - 0xfc00f820, 0x8000e020, &NMD::DINSU , 0, + 0xfc00f820, 0x8000e020, &DINSU , 0, MIPS64_ }, /* DINSU */ { instruction , 0 , 0 , 32, - 0xfc00f820, 0x8000e800, &NMD::DINSM , 0, + 0xfc00f820, 0x8000e800, &DINSM , 0, MIPS64_ }, /* DINSM */ { instruction , 0 , 0 , 32, - 0xfc00f820, 0x8000e820, &NMD::DINS , 0, + 0xfc00f820, 0x8000e820, &DINS , 0, MIPS64_ }, /* DINS */ }; NMD::Pool NMD::P_EXT[4] = { { instruction , 0 , 0 , 32, - 0xfc00f820, 0x8000f000, &NMD::EXT , 0, + 0xfc00f820, 0x8000f000, &EXT , 0, XMMS_ }, /* EXT */ { instruction , 0 , 0 , 32, - 0xfc00f820, 0x8000f020, &NMD::DEXTU , 0, + 0xfc00f820, 0x8000f020, &DEXTU , 0, MIPS64_ }, /* DEXTU */ { instruction , 0 , 0 , 32, - 0xfc00f820, 0x8000f800, &NMD::DEXTM , 0, + 0xfc00f820, 0x8000f800, &DEXTM , 0, MIPS64_ }, /* DEXTM */ { instruction , 0 , 0 , 32, - 0xfc00f820, 0x8000f820, &NMD::DEXT , 0, + 0xfc00f820, 0x8000f820, &DEXT , 0, MIPS64_ }, /* DEXT */ }; NMD::Pool NMD::P_U12[16] = { { instruction , 0 , 0 , 32, - 0xfc00f000, 0x80000000, &NMD::ORI , 0, + 0xfc00f000, 0x80000000, &ORI , 0, 0x0 }, /* ORI */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x80001000, &NMD::XORI , 0, + 0xfc00f000, 0x80001000, &XORI , 0, 0x0 }, /* XORI */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x80002000, &NMD::ANDI_32_ , 0, + 0xfc00f000, 0x80002000, &ANDI_32_ , 0, 0x0 }, /* ANDI[32] */ { pool , P_SR , 2 , 32, 0xfc00f000, 0x80003000, 0 , 0, 0x0 }, /* P.SR */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x80004000, &NMD::SLTI , 0, + 0xfc00f000, 0x80004000, &SLTI , 0, 0x0 }, /* SLTI */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x80005000, &NMD::SLTIU , 0, + 0xfc00f000, 0x80005000, &SLTIU , 0, 0x0 }, /* SLTIU */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x80006000, &NMD::SEQI , 0, + 0xfc00f000, 0x80006000, &SEQI , 0, 0x0 }, /* SEQI */ { reserved_block , 0 , 0 , 32, 0xfc00f000, 0x80007000, 0 , 0, 0x0 }, /* P.U12~*(7) */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x80008000, &NMD::ADDIU_NEG_ , 0, + 0xfc00f000, 0x80008000, &ADDIU_NEG_ , 0, 0x0 }, /* ADDIU[NEG] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x80009000, &NMD::DADDIU_U12_ , 0, + 0xfc00f000, 0x80009000, &DADDIU_U12_ , 0, MIPS64_ }, /* DADDIU[U12] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x8000a000, &NMD::DADDIU_NEG_ , 0, + 0xfc00f000, 0x8000a000, &DADDIU_NEG_ , 0, MIPS64_ }, /* DADDIU[NEG] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x8000b000, &NMD::DROTX , 0, + 0xfc00f000, 0x8000b000, &DROTX , 0, MIPS64_ }, /* DROTX */ { pool , P_SHIFT , 16 , 32, 0xfc00f000, 0x8000c000, 0 , 0, @@ -19330,17 +19330,17 @@ NMD::Pool NMD::P_U12[16] = { NMD::Pool NMD::RINT_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa0000020, &NMD::RINT_S , 0, + 0xfc0003ff, 0xa0000020, &RINT_S , 0, CP1_ }, /* RINT.S */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa0000220, &NMD::RINT_D , 0, + 0xfc0003ff, 0xa0000220, &RINT_D , 0, CP1_ }, /* RINT.D */ }; NMD::Pool NMD::ADD_fmt0[2] = { { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa0000030, &NMD::ADD_S , 0, + 0xfc0003ff, 0xa0000030, &ADD_S , 0, CP1_ }, /* ADD.S */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0xa0000230, 0 , 0, @@ -19350,27 +19350,27 @@ NMD::Pool NMD::ADD_fmt0[2] = { NMD::Pool NMD::SELEQZ_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa0000038, &NMD::SELEQZ_S , 0, + 0xfc0003ff, 0xa0000038, &SELEQZ_S , 0, CP1_ }, /* SELEQZ.S */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa0000238, &NMD::SELEQZ_D , 0, + 0xfc0003ff, 0xa0000238, &SELEQZ_D , 0, CP1_ }, /* SELEQZ.D */ }; NMD::Pool NMD::CLASS_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa0000060, &NMD::CLASS_S , 0, + 0xfc0003ff, 0xa0000060, &CLASS_S , 0, CP1_ }, /* CLASS.S */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa0000260, &NMD::CLASS_D , 0, + 0xfc0003ff, 0xa0000260, &CLASS_D , 0, CP1_ }, /* CLASS.D */ }; NMD::Pool NMD::SUB_fmt0[2] = { { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa0000070, &NMD::SUB_S , 0, + 0xfc0003ff, 0xa0000070, &SUB_S , 0, CP1_ }, /* SUB.S */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0xa0000270, 0 , 0, @@ -19380,17 +19380,17 @@ NMD::Pool NMD::SUB_fmt0[2] = { NMD::Pool NMD::SELNEZ_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa0000078, &NMD::SELNEZ_S , 0, + 0xfc0003ff, 0xa0000078, &SELNEZ_S , 0, CP1_ }, /* SELNEZ.S */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa0000278, &NMD::SELNEZ_D , 0, + 0xfc0003ff, 0xa0000278, &SELNEZ_D , 0, CP1_ }, /* SELNEZ.D */ }; NMD::Pool NMD::MUL_fmt0[2] = { { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa00000b0, &NMD::MUL_S , 0, + 0xfc0003ff, 0xa00000b0, &MUL_S , 0, CP1_ }, /* MUL.S */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0xa00002b0, 0 , 0, @@ -19400,17 +19400,17 @@ NMD::Pool NMD::MUL_fmt0[2] = { NMD::Pool NMD::SEL_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa00000b8, &NMD::SEL_S , 0, + 0xfc0003ff, 0xa00000b8, &SEL_S , 0, CP1_ }, /* SEL.S */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa00002b8, &NMD::SEL_D , 0, + 0xfc0003ff, 0xa00002b8, &SEL_D , 0, CP1_ }, /* SEL.D */ }; NMD::Pool NMD::DIV_fmt0[2] = { { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa00000f0, &NMD::DIV_S , 0, + 0xfc0003ff, 0xa00000f0, &DIV_S , 0, CP1_ }, /* DIV.S */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0xa00002f0, 0 , 0, @@ -19420,7 +19420,7 @@ NMD::Pool NMD::DIV_fmt0[2] = { NMD::Pool NMD::ADD_fmt1[2] = { { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa0000130, &NMD::ADD_D , 0, + 0xfc0003ff, 0xa0000130, &ADD_D , 0, CP1_ }, /* ADD.D */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0xa0000330, 0 , 0, @@ -19430,7 +19430,7 @@ NMD::Pool NMD::ADD_fmt1[2] = { NMD::Pool NMD::SUB_fmt1[2] = { { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa0000170, &NMD::SUB_D , 0, + 0xfc0003ff, 0xa0000170, &SUB_D , 0, CP1_ }, /* SUB.D */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0xa0000370, 0 , 0, @@ -19440,7 +19440,7 @@ NMD::Pool NMD::SUB_fmt1[2] = { NMD::Pool NMD::MUL_fmt1[2] = { { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa00001b0, &NMD::MUL_D , 0, + 0xfc0003ff, 0xa00001b0, &MUL_D , 0, CP1_ }, /* MUL.D */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0xa00003b0, 0 , 0, @@ -19450,17 +19450,17 @@ NMD::Pool NMD::MUL_fmt1[2] = { NMD::Pool NMD::MADDF_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa00001b8, &NMD::MADDF_S , 0, + 0xfc0003ff, 0xa00001b8, &MADDF_S , 0, CP1_ }, /* MADDF.S */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa00003b8, &NMD::MADDF_D , 0, + 0xfc0003ff, 0xa00003b8, &MADDF_D , 0, CP1_ }, /* MADDF.D */ }; NMD::Pool NMD::DIV_fmt1[2] = { { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa00001f0, &NMD::DIV_D , 0, + 0xfc0003ff, 0xa00001f0, &DIV_D , 0, CP1_ }, /* DIV.D */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0xa00003f0, 0 , 0, @@ -19470,10 +19470,10 @@ NMD::Pool NMD::DIV_fmt1[2] = { NMD::Pool NMD::MSUBF_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa00001f8, &NMD::MSUBF_S , 0, + 0xfc0003ff, 0xa00001f8, &MSUBF_S , 0, CP1_ }, /* MSUBF.S */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa00003f8, &NMD::MSUBF_D , 0, + 0xfc0003ff, 0xa00003f8, &MSUBF_D , 0, CP1_ }, /* MSUBF.D */ }; @@ -19676,170 +19676,170 @@ NMD::Pool NMD::POOL32F_0[64] = { NMD::Pool NMD::MIN_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc00023f, 0xa0000003, &NMD::MIN_S , 0, + 0xfc00023f, 0xa0000003, &MIN_S , 0, CP1_ }, /* MIN.S */ { instruction , 0 , 0 , 32, - 0xfc00023f, 0xa0000203, &NMD::MIN_D , 0, + 0xfc00023f, 0xa0000203, &MIN_D , 0, CP1_ }, /* MIN.D */ }; NMD::Pool NMD::MAX_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc00023f, 0xa000000b, &NMD::MAX_S , 0, + 0xfc00023f, 0xa000000b, &MAX_S , 0, CP1_ }, /* MAX.S */ { instruction , 0 , 0 , 32, - 0xfc00023f, 0xa000020b, &NMD::MAX_D , 0, + 0xfc00023f, 0xa000020b, &MAX_D , 0, CP1_ }, /* MAX.D */ }; NMD::Pool NMD::MINA_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc00023f, 0xa0000023, &NMD::MINA_S , 0, + 0xfc00023f, 0xa0000023, &MINA_S , 0, CP1_ }, /* MINA.S */ { instruction , 0 , 0 , 32, - 0xfc00023f, 0xa0000223, &NMD::MINA_D , 0, + 0xfc00023f, 0xa0000223, &MINA_D , 0, CP1_ }, /* MINA.D */ }; NMD::Pool NMD::MAXA_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc00023f, 0xa000002b, &NMD::MAXA_S , 0, + 0xfc00023f, 0xa000002b, &MAXA_S , 0, CP1_ }, /* MAXA.S */ { instruction , 0 , 0 , 32, - 0xfc00023f, 0xa000022b, &NMD::MAXA_D , 0, + 0xfc00023f, 0xa000022b, &MAXA_D , 0, CP1_ }, /* MAXA.D */ }; NMD::Pool NMD::CVT_L_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000013b, &NMD::CVT_L_S , 0, + 0xfc007fff, 0xa000013b, &CVT_L_S , 0, CP1_ }, /* CVT.L.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000413b, &NMD::CVT_L_D , 0, + 0xfc007fff, 0xa000413b, &CVT_L_D , 0, CP1_ }, /* CVT.L.D */ }; NMD::Pool NMD::RSQRT_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000023b, &NMD::RSQRT_S , 0, + 0xfc007fff, 0xa000023b, &RSQRT_S , 0, CP1_ }, /* RSQRT.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000423b, &NMD::RSQRT_D , 0, + 0xfc007fff, 0xa000423b, &RSQRT_D , 0, CP1_ }, /* RSQRT.D */ }; NMD::Pool NMD::FLOOR_L_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000033b, &NMD::FLOOR_L_S , 0, + 0xfc007fff, 0xa000033b, &FLOOR_L_S , 0, CP1_ }, /* FLOOR.L.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000433b, &NMD::FLOOR_L_D , 0, + 0xfc007fff, 0xa000433b, &FLOOR_L_D , 0, CP1_ }, /* FLOOR.L.D */ }; NMD::Pool NMD::CVT_W_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000093b, &NMD::CVT_W_S , 0, + 0xfc007fff, 0xa000093b, &CVT_W_S , 0, CP1_ }, /* CVT.W.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000493b, &NMD::CVT_W_D , 0, + 0xfc007fff, 0xa000493b, &CVT_W_D , 0, CP1_ }, /* CVT.W.D */ }; NMD::Pool NMD::SQRT_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa0000a3b, &NMD::SQRT_S , 0, + 0xfc007fff, 0xa0000a3b, &SQRT_S , 0, CP1_ }, /* SQRT.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa0004a3b, &NMD::SQRT_D , 0, + 0xfc007fff, 0xa0004a3b, &SQRT_D , 0, CP1_ }, /* SQRT.D */ }; NMD::Pool NMD::FLOOR_W_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa0000b3b, &NMD::FLOOR_W_S , 0, + 0xfc007fff, 0xa0000b3b, &FLOOR_W_S , 0, CP1_ }, /* FLOOR.W.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa0004b3b, &NMD::FLOOR_W_D , 0, + 0xfc007fff, 0xa0004b3b, &FLOOR_W_D , 0, CP1_ }, /* FLOOR.W.D */ }; NMD::Pool NMD::RECIP_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000123b, &NMD::RECIP_S , 0, + 0xfc007fff, 0xa000123b, &RECIP_S , 0, CP1_ }, /* RECIP.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000523b, &NMD::RECIP_D , 0, + 0xfc007fff, 0xa000523b, &RECIP_D , 0, CP1_ }, /* RECIP.D */ }; NMD::Pool NMD::CEIL_L_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000133b, &NMD::CEIL_L_S , 0, + 0xfc007fff, 0xa000133b, &CEIL_L_S , 0, CP1_ }, /* CEIL.L.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000533b, &NMD::CEIL_L_D , 0, + 0xfc007fff, 0xa000533b, &CEIL_L_D , 0, CP1_ }, /* CEIL.L.D */ }; NMD::Pool NMD::CEIL_W_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa0001b3b, &NMD::CEIL_W_S , 0, + 0xfc007fff, 0xa0001b3b, &CEIL_W_S , 0, CP1_ }, /* CEIL.W.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa0005b3b, &NMD::CEIL_W_D , 0, + 0xfc007fff, 0xa0005b3b, &CEIL_W_D , 0, CP1_ }, /* CEIL.W.D */ }; NMD::Pool NMD::TRUNC_L_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000233b, &NMD::TRUNC_L_S , 0, + 0xfc007fff, 0xa000233b, &TRUNC_L_S , 0, CP1_ }, /* TRUNC.L.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000633b, &NMD::TRUNC_L_D , 0, + 0xfc007fff, 0xa000633b, &TRUNC_L_D , 0, CP1_ }, /* TRUNC.L.D */ }; NMD::Pool NMD::TRUNC_W_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa0002b3b, &NMD::TRUNC_W_S , 0, + 0xfc007fff, 0xa0002b3b, &TRUNC_W_S , 0, CP1_ }, /* TRUNC.W.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa0006b3b, &NMD::TRUNC_W_D , 0, + 0xfc007fff, 0xa0006b3b, &TRUNC_W_D , 0, CP1_ }, /* TRUNC.W.D */ }; NMD::Pool NMD::ROUND_L_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000333b, &NMD::ROUND_L_S , 0, + 0xfc007fff, 0xa000333b, &ROUND_L_S , 0, CP1_ }, /* ROUND.L.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000733b, &NMD::ROUND_L_D , 0, + 0xfc007fff, 0xa000733b, &ROUND_L_D , 0, CP1_ }, /* ROUND.L.D */ }; NMD::Pool NMD::ROUND_W_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa0003b3b, &NMD::ROUND_W_S , 0, + 0xfc007fff, 0xa0003b3b, &ROUND_W_S , 0, CP1_ }, /* ROUND.W.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa0007b3b, &NMD::ROUND_W_D , 0, + 0xfc007fff, 0xa0007b3b, &ROUND_W_D , 0, CP1_ }, /* ROUND.W.D */ }; @@ -19894,7 +19894,7 @@ NMD::Pool NMD::POOL32Fxf_0[64] = { 0xfc003fff, 0xa0000f3b, 0 , 0, CP1_ }, /* POOL32Fxf_0~*(15) */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0xa000103b, &NMD::CFC1 , 0, + 0xfc003fff, 0xa000103b, &CFC1 , 0, CP1_ }, /* CFC1 */ { reserved_block , 0 , 0 , 32, 0xfc003fff, 0xa000113b, 0 , 0, @@ -19918,7 +19918,7 @@ NMD::Pool NMD::POOL32Fxf_0[64] = { 0xfc003fff, 0xa000173b, 0 , 0, CP1_ }, /* POOL32Fxf_0~*(23) */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0xa000183b, &NMD::CTC1 , 0, + 0xfc003fff, 0xa000183b, &CTC1 , 0, CP1_ }, /* CTC1 */ { reserved_block , 0 , 0 , 32, 0xfc003fff, 0xa000193b, 0 , 0, @@ -19942,10 +19942,10 @@ NMD::Pool NMD::POOL32Fxf_0[64] = { 0xfc003fff, 0xa0001f3b, 0 , 0, CP1_ }, /* POOL32Fxf_0~*(31) */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0xa000203b, &NMD::MFC1 , 0, + 0xfc003fff, 0xa000203b, &MFC1 , 0, CP1_ }, /* MFC1 */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0xa000213b, &NMD::CVT_S_PL , 0, + 0xfc003fff, 0xa000213b, &CVT_S_PL , 0, CP1_ }, /* CVT.S.PL */ { reserved_block , 0 , 0 , 32, 0xfc003fff, 0xa000223b, 0 , 0, @@ -19954,7 +19954,7 @@ NMD::Pool NMD::POOL32Fxf_0[64] = { 0xfc003fff, 0xa000233b, 0 , 0, CP1_ }, /* TRUNC.L.fmt */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0xa000243b, &NMD::DMFC1 , 0, + 0xfc003fff, 0xa000243b, &DMFC1 , 0, CP1_ | MIPS64_ }, /* DMFC1 */ { reserved_block , 0 , 0 , 32, 0xfc003fff, 0xa000253b, 0 , 0, @@ -19966,10 +19966,10 @@ NMD::Pool NMD::POOL32Fxf_0[64] = { 0xfc003fff, 0xa000273b, 0 , 0, CP1_ }, /* POOL32Fxf_0~*(39) */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0xa000283b, &NMD::MTC1 , 0, + 0xfc003fff, 0xa000283b, &MTC1 , 0, CP1_ }, /* MTC1 */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0xa000293b, &NMD::CVT_S_PU , 0, + 0xfc003fff, 0xa000293b, &CVT_S_PU , 0, CP1_ }, /* CVT.S.PU */ { reserved_block , 0 , 0 , 32, 0xfc003fff, 0xa0002a3b, 0 , 0, @@ -19978,7 +19978,7 @@ NMD::Pool NMD::POOL32Fxf_0[64] = { 0xfc003fff, 0xa0002b3b, 0 , 0, CP1_ }, /* TRUNC.W.fmt */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0xa0002c3b, &NMD::DMTC1 , 0, + 0xfc003fff, 0xa0002c3b, &DMTC1 , 0, CP1_ | MIPS64_ }, /* DMTC1 */ { reserved_block , 0 , 0 , 32, 0xfc003fff, 0xa0002d3b, 0 , 0, @@ -19990,7 +19990,7 @@ NMD::Pool NMD::POOL32Fxf_0[64] = { 0xfc003fff, 0xa0002f3b, 0 , 0, CP1_ }, /* POOL32Fxf_0~*(47) */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0xa000303b, &NMD::MFHC1 , 0, + 0xfc003fff, 0xa000303b, &MFHC1 , 0, CP1_ }, /* MFHC1 */ { reserved_block , 0 , 0 , 32, 0xfc003fff, 0xa000313b, 0 , 0, @@ -20014,7 +20014,7 @@ NMD::Pool NMD::POOL32Fxf_0[64] = { 0xfc003fff, 0xa000373b, 0 , 0, CP1_ }, /* POOL32Fxf_0~*(55) */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0xa000383b, &NMD::MTHC1 , 0, + 0xfc003fff, 0xa000383b, &MTHC1 , 0, CP1_ }, /* MTHC1 */ { reserved_block , 0 , 0 , 32, 0xfc003fff, 0xa000393b, 0 , 0, @@ -20042,10 +20042,10 @@ NMD::Pool NMD::POOL32Fxf_0[64] = { NMD::Pool NMD::MOV_fmt[4] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000007b, &NMD::MOV_S , 0, + 0xfc007fff, 0xa000007b, &MOV_S , 0, CP1_ }, /* MOV.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000207b, &NMD::MOV_D , 0, + 0xfc007fff, 0xa000207b, &MOV_D , 0, CP1_ }, /* MOV.D */ { reserved_block , 0 , 0 , 32, 0xfc007fff, 0xa000407b, 0 , 0, @@ -20058,10 +20058,10 @@ NMD::Pool NMD::MOV_fmt[4] = { NMD::Pool NMD::ABS_fmt[4] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000037b, &NMD::ABS_S , 0, + 0xfc007fff, 0xa000037b, &ABS_S , 0, CP1_ }, /* ABS.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000237b, &NMD::ABS_D , 0, + 0xfc007fff, 0xa000237b, &ABS_D , 0, CP1_ }, /* ABS.D */ { reserved_block , 0 , 0 , 32, 0xfc007fff, 0xa000437b, 0 , 0, @@ -20074,10 +20074,10 @@ NMD::Pool NMD::ABS_fmt[4] = { NMD::Pool NMD::NEG_fmt[4] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa0000b7b, &NMD::NEG_S , 0, + 0xfc007fff, 0xa0000b7b, &NEG_S , 0, CP1_ }, /* NEG.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa0002b7b, &NMD::NEG_D , 0, + 0xfc007fff, 0xa0002b7b, &NEG_D , 0, CP1_ }, /* NEG.D */ { reserved_block , 0 , 0 , 32, 0xfc007fff, 0xa0004b7b, 0 , 0, @@ -20090,13 +20090,13 @@ NMD::Pool NMD::NEG_fmt[4] = { NMD::Pool NMD::CVT_D_fmt[4] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000137b, &NMD::CVT_D_S , 0, + 0xfc007fff, 0xa000137b, &CVT_D_S , 0, CP1_ }, /* CVT.D.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000337b, &NMD::CVT_D_W , 0, + 0xfc007fff, 0xa000337b, &CVT_D_W , 0, CP1_ }, /* CVT.D.W */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000537b, &NMD::CVT_D_L , 0, + 0xfc007fff, 0xa000537b, &CVT_D_L , 0, CP1_ }, /* CVT.D.L */ { reserved_block , 0 , 0 , 32, 0xfc007fff, 0xa000737b, 0 , 0, @@ -20106,13 +20106,13 @@ NMD::Pool NMD::CVT_D_fmt[4] = { NMD::Pool NMD::CVT_S_fmt[4] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa0001b7b, &NMD::CVT_S_D , 0, + 0xfc007fff, 0xa0001b7b, &CVT_S_D , 0, CP1_ }, /* CVT.S.D */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa0003b7b, &NMD::CVT_S_W , 0, + 0xfc007fff, 0xa0003b7b, &CVT_S_W , 0, CP1_ }, /* CVT.S.W */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa0005b7b, &NMD::CVT_S_L , 0, + 0xfc007fff, 0xa0005b7b, &CVT_S_L , 0, CP1_ }, /* CVT.S.L */ { reserved_block , 0 , 0 , 32, 0xfc007fff, 0xa0007b7b, 0 , 0, @@ -20266,64 +20266,64 @@ NMD::Pool NMD::POOL32F_3[8] = { NMD::Pool NMD::CMP_condn_S[32] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000005, &NMD::CMP_AF_S , 0, + 0xfc0007ff, 0xa0000005, &CMP_AF_S , 0, CP1_ }, /* CMP.AF.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000045, &NMD::CMP_UN_S , 0, + 0xfc0007ff, 0xa0000045, &CMP_UN_S , 0, CP1_ }, /* CMP.UN.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000085, &NMD::CMP_EQ_S , 0, + 0xfc0007ff, 0xa0000085, &CMP_EQ_S , 0, CP1_ }, /* CMP.EQ.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa00000c5, &NMD::CMP_UEQ_S , 0, + 0xfc0007ff, 0xa00000c5, &CMP_UEQ_S , 0, CP1_ }, /* CMP.UEQ.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000105, &NMD::CMP_LT_S , 0, + 0xfc0007ff, 0xa0000105, &CMP_LT_S , 0, CP1_ }, /* CMP.LT.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000145, &NMD::CMP_ULT_S , 0, + 0xfc0007ff, 0xa0000145, &CMP_ULT_S , 0, CP1_ }, /* CMP.ULT.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000185, &NMD::CMP_LE_S , 0, + 0xfc0007ff, 0xa0000185, &CMP_LE_S , 0, CP1_ }, /* CMP.LE.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa00001c5, &NMD::CMP_ULE_S , 0, + 0xfc0007ff, 0xa00001c5, &CMP_ULE_S , 0, CP1_ }, /* CMP.ULE.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000205, &NMD::CMP_SAF_S , 0, + 0xfc0007ff, 0xa0000205, &CMP_SAF_S , 0, CP1_ }, /* CMP.SAF.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000245, &NMD::CMP_SUN_S , 0, + 0xfc0007ff, 0xa0000245, &CMP_SUN_S , 0, CP1_ }, /* CMP.SUN.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000285, &NMD::CMP_SEQ_S , 0, + 0xfc0007ff, 0xa0000285, &CMP_SEQ_S , 0, CP1_ }, /* CMP.SEQ.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa00002c5, &NMD::CMP_SUEQ_S , 0, + 0xfc0007ff, 0xa00002c5, &CMP_SUEQ_S , 0, CP1_ }, /* CMP.SUEQ.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000305, &NMD::CMP_SLT_S , 0, + 0xfc0007ff, 0xa0000305, &CMP_SLT_S , 0, CP1_ }, /* CMP.SLT.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000345, &NMD::CMP_SULT_S , 0, + 0xfc0007ff, 0xa0000345, &CMP_SULT_S , 0, CP1_ }, /* CMP.SULT.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000385, &NMD::CMP_SLE_S , 0, + 0xfc0007ff, 0xa0000385, &CMP_SLE_S , 0, CP1_ }, /* CMP.SLE.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa00003c5, &NMD::CMP_SULE_S , 0, + 0xfc0007ff, 0xa00003c5, &CMP_SULE_S , 0, CP1_ }, /* CMP.SULE.S */ { reserved_block , 0 , 0 , 32, 0xfc0007ff, 0xa0000405, 0 , 0, CP1_ }, /* CMP.condn.S~*(16) */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000445, &NMD::CMP_OR_S , 0, + 0xfc0007ff, 0xa0000445, &CMP_OR_S , 0, CP1_ }, /* CMP.OR.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000485, &NMD::CMP_UNE_S , 0, + 0xfc0007ff, 0xa0000485, &CMP_UNE_S , 0, CP1_ }, /* CMP.UNE.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa00004c5, &NMD::CMP_NE_S , 0, + 0xfc0007ff, 0xa00004c5, &CMP_NE_S , 0, CP1_ }, /* CMP.NE.S */ { reserved_block , 0 , 0 , 32, 0xfc0007ff, 0xa0000505, 0 , 0, @@ -20341,13 +20341,13 @@ NMD::Pool NMD::CMP_condn_S[32] = { 0xfc0007ff, 0xa0000605, 0 , 0, CP1_ }, /* CMP.condn.S~*(24) */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000645, &NMD::CMP_SOR_S , 0, + 0xfc0007ff, 0xa0000645, &CMP_SOR_S , 0, CP1_ }, /* CMP.SOR.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000685, &NMD::CMP_SUNE_S , 0, + 0xfc0007ff, 0xa0000685, &CMP_SUNE_S , 0, CP1_ }, /* CMP.SUNE.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa00006c5, &NMD::CMP_SNE_S , 0, + 0xfc0007ff, 0xa00006c5, &CMP_SNE_S , 0, CP1_ }, /* CMP.SNE.S */ { reserved_block , 0 , 0 , 32, 0xfc0007ff, 0xa0000705, 0 , 0, @@ -20366,64 +20366,64 @@ NMD::Pool NMD::CMP_condn_S[32] = { NMD::Pool NMD::CMP_condn_D[32] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000015, &NMD::CMP_AF_D , 0, + 0xfc0007ff, 0xa0000015, &CMP_AF_D , 0, CP1_ }, /* CMP.AF.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000055, &NMD::CMP_UN_D , 0, + 0xfc0007ff, 0xa0000055, &CMP_UN_D , 0, CP1_ }, /* CMP.UN.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000095, &NMD::CMP_EQ_D , 0, + 0xfc0007ff, 0xa0000095, &CMP_EQ_D , 0, CP1_ }, /* CMP.EQ.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa00000d5, &NMD::CMP_UEQ_D , 0, + 0xfc0007ff, 0xa00000d5, &CMP_UEQ_D , 0, CP1_ }, /* CMP.UEQ.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000115, &NMD::CMP_LT_D , 0, + 0xfc0007ff, 0xa0000115, &CMP_LT_D , 0, CP1_ }, /* CMP.LT.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000155, &NMD::CMP_ULT_D , 0, + 0xfc0007ff, 0xa0000155, &CMP_ULT_D , 0, CP1_ }, /* CMP.ULT.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000195, &NMD::CMP_LE_D , 0, + 0xfc0007ff, 0xa0000195, &CMP_LE_D , 0, CP1_ }, /* CMP.LE.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa00001d5, &NMD::CMP_ULE_D , 0, + 0xfc0007ff, 0xa00001d5, &CMP_ULE_D , 0, CP1_ }, /* CMP.ULE.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000215, &NMD::CMP_SAF_D , 0, + 0xfc0007ff, 0xa0000215, &CMP_SAF_D , 0, CP1_ }, /* CMP.SAF.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000255, &NMD::CMP_SUN_D , 0, + 0xfc0007ff, 0xa0000255, &CMP_SUN_D , 0, CP1_ }, /* CMP.SUN.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000295, &NMD::CMP_SEQ_D , 0, + 0xfc0007ff, 0xa0000295, &CMP_SEQ_D , 0, CP1_ }, /* CMP.SEQ.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa00002d5, &NMD::CMP_SUEQ_D , 0, + 0xfc0007ff, 0xa00002d5, &CMP_SUEQ_D , 0, CP1_ }, /* CMP.SUEQ.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000315, &NMD::CMP_SLT_D , 0, + 0xfc0007ff, 0xa0000315, &CMP_SLT_D , 0, CP1_ }, /* CMP.SLT.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000355, &NMD::CMP_SULT_D , 0, + 0xfc0007ff, 0xa0000355, &CMP_SULT_D , 0, CP1_ }, /* CMP.SULT.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000395, &NMD::CMP_SLE_D , 0, + 0xfc0007ff, 0xa0000395, &CMP_SLE_D , 0, CP1_ }, /* CMP.SLE.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa00003d5, &NMD::CMP_SULE_D , 0, + 0xfc0007ff, 0xa00003d5, &CMP_SULE_D , 0, CP1_ }, /* CMP.SULE.D */ { reserved_block , 0 , 0 , 32, 0xfc0007ff, 0xa0000415, 0 , 0, CP1_ }, /* CMP.condn.D~*(16) */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000455, &NMD::CMP_OR_D , 0, + 0xfc0007ff, 0xa0000455, &CMP_OR_D , 0, CP1_ }, /* CMP.OR.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000495, &NMD::CMP_UNE_D , 0, + 0xfc0007ff, 0xa0000495, &CMP_UNE_D , 0, CP1_ }, /* CMP.UNE.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa00004d5, &NMD::CMP_NE_D , 0, + 0xfc0007ff, 0xa00004d5, &CMP_NE_D , 0, CP1_ }, /* CMP.NE.D */ { reserved_block , 0 , 0 , 32, 0xfc0007ff, 0xa0000515, 0 , 0, @@ -20441,13 +20441,13 @@ NMD::Pool NMD::CMP_condn_D[32] = { 0xfc0007ff, 0xa0000615, 0 , 0, CP1_ }, /* CMP.condn.D~*(24) */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000655, &NMD::CMP_SOR_D , 0, + 0xfc0007ff, 0xa0000655, &CMP_SOR_D , 0, CP1_ }, /* CMP.SOR.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000695, &NMD::CMP_SUNE_D , 0, + 0xfc0007ff, 0xa0000695, &CMP_SUNE_D , 0, CP1_ }, /* CMP.SUNE.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa00006d5, &NMD::CMP_SNE_D , 0, + 0xfc0007ff, 0xa00006d5, &CMP_SNE_D , 0, CP1_ }, /* CMP.SNE.D */ { reserved_block , 0 , 0 , 32, 0xfc0007ff, 0xa0000715, 0 , 0, @@ -20525,13 +20525,13 @@ NMD::Pool NMD::POOL32S_0[64] = { 0xfc0001ff, 0xc0000000, 0 , 0, 0x0 }, /* POOL32S_0~*(0) */ { instruction , 0 , 0 , 32, - 0xfc0001ff, 0xc0000008, &NMD::DLSA , 0, + 0xfc0001ff, 0xc0000008, &DLSA , 0, MIPS64_ }, /* DLSA */ { instruction , 0 , 0 , 32, - 0xfc0001ff, 0xc0000010, &NMD::DSLLV , 0, + 0xfc0001ff, 0xc0000010, &DSLLV , 0, MIPS64_ }, /* DSLLV */ { instruction , 0 , 0 , 32, - 0xfc0001ff, 0xc0000018, &NMD::DMUL , 0, + 0xfc0001ff, 0xc0000018, &DMUL , 0, MIPS64_ }, /* DMUL */ { reserved_block , 0 , 0 , 32, 0xfc0001ff, 0xc0000020, 0 , 0, @@ -20552,10 +20552,10 @@ NMD::Pool NMD::POOL32S_0[64] = { 0xfc0001ff, 0xc0000048, 0 , 0, 0x0 }, /* POOL32S_0~*(9) */ { instruction , 0 , 0 , 32, - 0xfc0001ff, 0xc0000050, &NMD::DSRLV , 0, + 0xfc0001ff, 0xc0000050, &DSRLV , 0, MIPS64_ }, /* DSRLV */ { instruction , 0 , 0 , 32, - 0xfc0001ff, 0xc0000058, &NMD::DMUH , 0, + 0xfc0001ff, 0xc0000058, &DMUH , 0, MIPS64_ }, /* DMUH */ { reserved_block , 0 , 0 , 32, 0xfc0001ff, 0xc0000060, 0 , 0, @@ -20576,10 +20576,10 @@ NMD::Pool NMD::POOL32S_0[64] = { 0xfc0001ff, 0xc0000088, 0 , 0, 0x0 }, /* POOL32S_0~*(17) */ { instruction , 0 , 0 , 32, - 0xfc0001ff, 0xc0000090, &NMD::DSRAV , 0, + 0xfc0001ff, 0xc0000090, &DSRAV , 0, MIPS64_ }, /* DSRAV */ { instruction , 0 , 0 , 32, - 0xfc0001ff, 0xc0000098, &NMD::DMULU , 0, + 0xfc0001ff, 0xc0000098, &DMULU , 0, MIPS64_ }, /* DMULU */ { reserved_block , 0 , 0 , 32, 0xfc0001ff, 0xc00000a0, 0 , 0, @@ -20600,10 +20600,10 @@ NMD::Pool NMD::POOL32S_0[64] = { 0xfc0001ff, 0xc00000c8, 0 , 0, 0x0 }, /* POOL32S_0~*(25) */ { instruction , 0 , 0 , 32, - 0xfc0001ff, 0xc00000d0, &NMD::DROTRV , 0, + 0xfc0001ff, 0xc00000d0, &DROTRV , 0, MIPS64_ }, /* DROTRV */ { instruction , 0 , 0 , 32, - 0xfc0001ff, 0xc00000d8, &NMD::DMUHU , 0, + 0xfc0001ff, 0xc00000d8, &DMUHU , 0, MIPS64_ }, /* DMUHU */ { reserved_block , 0 , 0 , 32, 0xfc0001ff, 0xc00000e0, 0 , 0, @@ -20624,10 +20624,10 @@ NMD::Pool NMD::POOL32S_0[64] = { 0xfc0001ff, 0xc0000108, 0 , 0, 0x0 }, /* POOL32S_0~*(33) */ { instruction , 0 , 0 , 32, - 0xfc0001ff, 0xc0000110, &NMD::DADD , 0, + 0xfc0001ff, 0xc0000110, &DADD , 0, MIPS64_ }, /* DADD */ { instruction , 0 , 0 , 32, - 0xfc0001ff, 0xc0000118, &NMD::DDIV , 0, + 0xfc0001ff, 0xc0000118, &DDIV , 0, MIPS64_ }, /* DDIV */ { reserved_block , 0 , 0 , 32, 0xfc0001ff, 0xc0000120, 0 , 0, @@ -20648,10 +20648,10 @@ NMD::Pool NMD::POOL32S_0[64] = { 0xfc0001ff, 0xc0000148, 0 , 0, 0x0 }, /* POOL32S_0~*(41) */ { instruction , 0 , 0 , 32, - 0xfc0001ff, 0xc0000150, &NMD::DADDU , 0, + 0xfc0001ff, 0xc0000150, &DADDU , 0, MIPS64_ }, /* DADDU */ { instruction , 0 , 0 , 32, - 0xfc0001ff, 0xc0000158, &NMD::DMOD , 0, + 0xfc0001ff, 0xc0000158, &DMOD , 0, MIPS64_ }, /* DMOD */ { reserved_block , 0 , 0 , 32, 0xfc0001ff, 0xc0000160, 0 , 0, @@ -20672,10 +20672,10 @@ NMD::Pool NMD::POOL32S_0[64] = { 0xfc0001ff, 0xc0000188, 0 , 0, 0x0 }, /* POOL32S_0~*(49) */ { instruction , 0 , 0 , 32, - 0xfc0001ff, 0xc0000190, &NMD::DSUB , 0, + 0xfc0001ff, 0xc0000190, &DSUB , 0, MIPS64_ }, /* DSUB */ { instruction , 0 , 0 , 32, - 0xfc0001ff, 0xc0000198, &NMD::DDIVU , 0, + 0xfc0001ff, 0xc0000198, &DDIVU , 0, MIPS64_ }, /* DDIVU */ { reserved_block , 0 , 0 , 32, 0xfc0001ff, 0xc00001a0, 0 , 0, @@ -20696,10 +20696,10 @@ NMD::Pool NMD::POOL32S_0[64] = { 0xfc0001ff, 0xc00001c8, 0 , 0, 0x0 }, /* POOL32S_0~*(57) */ { instruction , 0 , 0 , 32, - 0xfc0001ff, 0xc00001d0, &NMD::DSUBU , 0, + 0xfc0001ff, 0xc00001d0, &DSUBU , 0, MIPS64_ }, /* DSUBU */ { instruction , 0 , 0 , 32, - 0xfc0001ff, 0xc00001d8, &NMD::DMODU , 0, + 0xfc0001ff, 0xc00001d8, &DMODU , 0, MIPS64_ }, /* DMODU */ { reserved_block , 0 , 0 , 32, 0xfc0001ff, 0xc00001e0, 0 , 0, @@ -20829,7 +20829,7 @@ NMD::Pool NMD::POOL32Sxf_4[128] = { 0xfc00ffff, 0xc000493c, 0 , 0, 0x0 }, /* POOL32Sxf_4~*(36) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0xc0004b3c, &NMD::DCLO , 0, + 0xfc00ffff, 0xc0004b3c, &DCLO , 0, MIPS64_ }, /* DCLO */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0xc0004d3c, 0 , 0, @@ -20853,7 +20853,7 @@ NMD::Pool NMD::POOL32Sxf_4[128] = { 0xfc00ffff, 0xc000593c, 0 , 0, 0x0 }, /* POOL32Sxf_4~*(44) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0xc0005b3c, &NMD::DCLZ , 0, + 0xfc00ffff, 0xc0005b3c, &DCLZ , 0, MIPS64_ }, /* DCLZ */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0xc0005d3c, 0 , 0, @@ -21134,10 +21134,10 @@ NMD::Pool NMD::POOL32Sxf[8] = { NMD::Pool NMD::POOL32S_4[8] = { { instruction , 0 , 0 , 32, - 0xfc00003f, 0xc0000004, &NMD::EXTD , 0, + 0xfc00003f, 0xc0000004, &EXTD , 0, MIPS64_ }, /* EXTD */ { instruction , 0 , 0 , 32, - 0xfc00003f, 0xc000000c, &NMD::EXTD32 , 0, + 0xfc00003f, 0xc000000c, &EXTD32 , 0, MIPS64_ }, /* EXTD32 */ { reserved_block , 0 , 0 , 32, 0xfc00003f, 0xc0000014, 0 , 0, @@ -21190,27 +21190,27 @@ NMD::Pool NMD::POOL32S[8] = { NMD::Pool NMD::P_LUI[2] = { { instruction , 0 , 0 , 32, - 0xfc000002, 0xe0000000, &NMD::LUI , 0, + 0xfc000002, 0xe0000000, &LUI , 0, 0x0 }, /* LUI */ { instruction , 0 , 0 , 32, - 0xfc000002, 0xe0000002, &NMD::ALUIPC , 0, + 0xfc000002, 0xe0000002, &ALUIPC , 0, 0x0 }, /* ALUIPC */ }; NMD::Pool NMD::P_GP_LH[2] = { { instruction , 0 , 0 , 32, - 0xfc1c0001, 0x44100000, &NMD::LH_GP_ , 0, + 0xfc1c0001, 0x44100000, &LH_GP_ , 0, 0x0 }, /* LH[GP] */ { instruction , 0 , 0 , 32, - 0xfc1c0001, 0x44100001, &NMD::LHU_GP_ , 0, + 0xfc1c0001, 0x44100001, &LHU_GP_ , 0, 0x0 }, /* LHU[GP] */ }; NMD::Pool NMD::P_GP_SH[2] = { { instruction , 0 , 0 , 32, - 0xfc1c0001, 0x44140000, &NMD::SH_GP_ , 0, + 0xfc1c0001, 0x44140000, &SH_GP_ , 0, 0x0 }, /* SH[GP] */ { reserved_block , 0 , 0 , 32, 0xfc1c0001, 0x44140001, 0 , 0, @@ -21220,23 +21220,23 @@ NMD::Pool NMD::P_GP_SH[2] = { NMD::Pool NMD::P_GP_CP1[4] = { { instruction , 0 , 0 , 32, - 0xfc1c0003, 0x44180000, &NMD::LWC1_GP_ , 0, + 0xfc1c0003, 0x44180000, &LWC1_GP_ , 0, CP1_ }, /* LWC1[GP] */ { instruction , 0 , 0 , 32, - 0xfc1c0003, 0x44180001, &NMD::SWC1_GP_ , 0, + 0xfc1c0003, 0x44180001, &SWC1_GP_ , 0, CP1_ }, /* SWC1[GP] */ { instruction , 0 , 0 , 32, - 0xfc1c0003, 0x44180002, &NMD::LDC1_GP_ , 0, + 0xfc1c0003, 0x44180002, &LDC1_GP_ , 0, CP1_ }, /* LDC1[GP] */ { instruction , 0 , 0 , 32, - 0xfc1c0003, 0x44180003, &NMD::SDC1_GP_ , 0, + 0xfc1c0003, 0x44180003, &SDC1_GP_ , 0, CP1_ }, /* SDC1[GP] */ }; NMD::Pool NMD::P_GP_M64[4] = { { instruction , 0 , 0 , 32, - 0xfc1c0003, 0x441c0000, &NMD::LWU_GP_ , 0, + 0xfc1c0003, 0x441c0000, &LWU_GP_ , 0, MIPS64_ }, /* LWU[GP] */ { reserved_block , 0 , 0 , 32, 0xfc1c0003, 0x441c0001, 0 , 0, @@ -21252,16 +21252,16 @@ NMD::Pool NMD::P_GP_M64[4] = { NMD::Pool NMD::P_GP_BH[8] = { { instruction , 0 , 0 , 32, - 0xfc1c0000, 0x44000000, &NMD::LB_GP_ , 0, + 0xfc1c0000, 0x44000000, &LB_GP_ , 0, 0x0 }, /* LB[GP] */ { instruction , 0 , 0 , 32, - 0xfc1c0000, 0x44040000, &NMD::SB_GP_ , 0, + 0xfc1c0000, 0x44040000, &SB_GP_ , 0, 0x0 }, /* SB[GP] */ { instruction , 0 , 0 , 32, - 0xfc1c0000, 0x44080000, &NMD::LBU_GP_ , 0, + 0xfc1c0000, 0x44080000, &LBU_GP_ , 0, 0x0 }, /* LBU[GP] */ { instruction , 0 , 0 , 32, - 0xfc1c0000, 0x440c0000, &NMD::ADDIU_GP_B_ , 0, + 0xfc1c0000, 0x440c0000, &ADDIU_GP_B_ , 0, 0x0 }, /* ADDIU[GP.B] */ { pool , P_GP_LH , 2 , 32, 0xfc1c0000, 0x44100000, 0 , 0, @@ -21280,134 +21280,134 @@ NMD::Pool NMD::P_GP_BH[8] = { NMD::Pool NMD::P_LS_U12[16] = { { instruction , 0 , 0 , 32, - 0xfc00f000, 0x84000000, &NMD::LB_U12_ , 0, + 0xfc00f000, 0x84000000, &LB_U12_ , 0, 0x0 }, /* LB[U12] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x84001000, &NMD::SB_U12_ , 0, + 0xfc00f000, 0x84001000, &SB_U12_ , 0, 0x0 }, /* SB[U12] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x84002000, &NMD::LBU_U12_ , 0, + 0xfc00f000, 0x84002000, &LBU_U12_ , 0, 0x0 }, /* LBU[U12] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x84003000, &NMD::PREF_U12_ , 0, + 0xfc00f000, 0x84003000, &PREF_U12_ , 0, 0x0 }, /* PREF[U12] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x84004000, &NMD::LH_U12_ , 0, + 0xfc00f000, 0x84004000, &LH_U12_ , 0, 0x0 }, /* LH[U12] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x84005000, &NMD::SH_U12_ , 0, + 0xfc00f000, 0x84005000, &SH_U12_ , 0, 0x0 }, /* SH[U12] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x84006000, &NMD::LHU_U12_ , 0, + 0xfc00f000, 0x84006000, &LHU_U12_ , 0, 0x0 }, /* LHU[U12] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x84007000, &NMD::LWU_U12_ , 0, + 0xfc00f000, 0x84007000, &LWU_U12_ , 0, MIPS64_ }, /* LWU[U12] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x84008000, &NMD::LW_U12_ , 0, + 0xfc00f000, 0x84008000, &LW_U12_ , 0, 0x0 }, /* LW[U12] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x84009000, &NMD::SW_U12_ , 0, + 0xfc00f000, 0x84009000, &SW_U12_ , 0, 0x0 }, /* SW[U12] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x8400a000, &NMD::LWC1_U12_ , 0, + 0xfc00f000, 0x8400a000, &LWC1_U12_ , 0, CP1_ }, /* LWC1[U12] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x8400b000, &NMD::SWC1_U12_ , 0, + 0xfc00f000, 0x8400b000, &SWC1_U12_ , 0, CP1_ }, /* SWC1[U12] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x8400c000, &NMD::LD_U12_ , 0, + 0xfc00f000, 0x8400c000, &LD_U12_ , 0, MIPS64_ }, /* LD[U12] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x8400d000, &NMD::SD_U12_ , 0, + 0xfc00f000, 0x8400d000, &SD_U12_ , 0, MIPS64_ }, /* SD[U12] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x8400e000, &NMD::LDC1_U12_ , 0, + 0xfc00f000, 0x8400e000, &LDC1_U12_ , 0, CP1_ }, /* LDC1[U12] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x8400f000, &NMD::SDC1_U12_ , 0, + 0xfc00f000, 0x8400f000, &SDC1_U12_ , 0, CP1_ }, /* SDC1[U12] */ }; NMD::Pool NMD::P_PREF_S9_[2] = { { instruction , 0 , 0 , 32, - 0xffe07f00, 0xa7e01800, &NMD::SYNCI , 0, + 0xffe07f00, 0xa7e01800, &SYNCI , 0, 0x0 }, /* SYNCI */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4001800, &NMD::PREF_S9_ , &PREF_S9__cond , + 0xfc007f00, 0xa4001800, &PREF_S9_ , &PREF_S9__cond , 0x0 }, /* PREF[S9] */ }; NMD::Pool NMD::P_LS_S0[16] = { { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4000000, &NMD::LB_S9_ , 0, + 0xfc007f00, 0xa4000000, &LB_S9_ , 0, 0x0 }, /* LB[S9] */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4000800, &NMD::SB_S9_ , 0, + 0xfc007f00, 0xa4000800, &SB_S9_ , 0, 0x0 }, /* SB[S9] */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4001000, &NMD::LBU_S9_ , 0, + 0xfc007f00, 0xa4001000, &LBU_S9_ , 0, 0x0 }, /* LBU[S9] */ { pool , P_PREF_S9_ , 2 , 32, 0xfc007f00, 0xa4001800, 0 , 0, 0x0 }, /* P.PREF[S9] */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4002000, &NMD::LH_S9_ , 0, + 0xfc007f00, 0xa4002000, &LH_S9_ , 0, 0x0 }, /* LH[S9] */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4002800, &NMD::SH_S9_ , 0, + 0xfc007f00, 0xa4002800, &SH_S9_ , 0, 0x0 }, /* SH[S9] */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4003000, &NMD::LHU_S9_ , 0, + 0xfc007f00, 0xa4003000, &LHU_S9_ , 0, 0x0 }, /* LHU[S9] */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4003800, &NMD::LWU_S9_ , 0, + 0xfc007f00, 0xa4003800, &LWU_S9_ , 0, MIPS64_ }, /* LWU[S9] */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4004000, &NMD::LW_S9_ , 0, + 0xfc007f00, 0xa4004000, &LW_S9_ , 0, 0x0 }, /* LW[S9] */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4004800, &NMD::SW_S9_ , 0, + 0xfc007f00, 0xa4004800, &SW_S9_ , 0, 0x0 }, /* SW[S9] */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4005000, &NMD::LWC1_S9_ , 0, + 0xfc007f00, 0xa4005000, &LWC1_S9_ , 0, CP1_ }, /* LWC1[S9] */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4005800, &NMD::SWC1_S9_ , 0, + 0xfc007f00, 0xa4005800, &SWC1_S9_ , 0, CP1_ }, /* SWC1[S9] */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4006000, &NMD::LD_S9_ , 0, + 0xfc007f00, 0xa4006000, &LD_S9_ , 0, MIPS64_ }, /* LD[S9] */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4006800, &NMD::SD_S9_ , 0, + 0xfc007f00, 0xa4006800, &SD_S9_ , 0, MIPS64_ }, /* SD[S9] */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4007000, &NMD::LDC1_S9_ , 0, + 0xfc007f00, 0xa4007000, &LDC1_S9_ , 0, CP1_ }, /* LDC1[S9] */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4007800, &NMD::SDC1_S9_ , 0, + 0xfc007f00, 0xa4007800, &SDC1_S9_ , 0, CP1_ }, /* SDC1[S9] */ }; NMD::Pool NMD::ASET_ACLR[2] = { { instruction , 0 , 0 , 32, - 0xfe007f00, 0xa4001100, &NMD::ASET , 0, + 0xfe007f00, 0xa4001100, &ASET , 0, MCU_ }, /* ASET */ { instruction , 0 , 0 , 32, - 0xfe007f00, 0xa6001100, &NMD::ACLR , 0, + 0xfe007f00, 0xa6001100, &ACLR , 0, MCU_ }, /* ACLR */ }; NMD::Pool NMD::P_LL[4] = { { instruction , 0 , 0 , 32, - 0xfc007f03, 0xa4005100, &NMD::LL , 0, + 0xfc007f03, 0xa4005100, &LL , 0, 0x0 }, /* LL */ { instruction , 0 , 0 , 32, - 0xfc007f03, 0xa4005101, &NMD::LLWP , 0, + 0xfc007f03, 0xa4005101, &LLWP , 0, XNP_ }, /* LLWP */ { reserved_block , 0 , 0 , 32, 0xfc007f03, 0xa4005102, 0 , 0, @@ -21420,10 +21420,10 @@ NMD::Pool NMD::P_LL[4] = { NMD::Pool NMD::P_SC[4] = { { instruction , 0 , 0 , 32, - 0xfc007f03, 0xa4005900, &NMD::SC , 0, + 0xfc007f03, 0xa4005900, &SC , 0, 0x0 }, /* SC */ { instruction , 0 , 0 , 32, - 0xfc007f03, 0xa4005901, &NMD::SCWP , 0, + 0xfc007f03, 0xa4005901, &SCWP , 0, XNP_ }, /* SCWP */ { reserved_block , 0 , 0 , 32, 0xfc007f03, 0xa4005902, 0 , 0, @@ -21436,10 +21436,10 @@ NMD::Pool NMD::P_SC[4] = { NMD::Pool NMD::P_LLD[8] = { { instruction , 0 , 0 , 32, - 0xfc007f07, 0xa4007100, &NMD::LLD , 0, + 0xfc007f07, 0xa4007100, &LLD , 0, MIPS64_ }, /* LLD */ { instruction , 0 , 0 , 32, - 0xfc007f07, 0xa4007101, &NMD::LLDP , 0, + 0xfc007f07, 0xa4007101, &LLDP , 0, MIPS64_ }, /* LLDP */ { reserved_block , 0 , 0 , 32, 0xfc007f07, 0xa4007102, 0 , 0, @@ -21464,10 +21464,10 @@ NMD::Pool NMD::P_LLD[8] = { NMD::Pool NMD::P_SCD[8] = { { instruction , 0 , 0 , 32, - 0xfc007f07, 0xa4007900, &NMD::SCD , 0, + 0xfc007f07, 0xa4007900, &SCD , 0, MIPS64_ }, /* SCD */ { instruction , 0 , 0 , 32, - 0xfc007f07, 0xa4007901, &NMD::SCDP , 0, + 0xfc007f07, 0xa4007901, &SCDP , 0, MIPS64_ }, /* SCDP */ { reserved_block , 0 , 0 , 32, 0xfc007f07, 0xa4007902, 0 , 0, @@ -21504,22 +21504,22 @@ NMD::Pool NMD::P_LS_S1[16] = { 0xfc007f00, 0xa4001900, 0 , 0, 0x0 }, /* P.LS.S1~*(3) */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4002100, &NMD::UALH , 0, + 0xfc007f00, 0xa4002100, &UALH , 0, XMMS_ }, /* UALH */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4002900, &NMD::UASH , 0, + 0xfc007f00, 0xa4002900, &UASH , 0, XMMS_ }, /* UASH */ { reserved_block , 0 , 0 , 32, 0xfc007f00, 0xa4003100, 0 , 0, 0x0 }, /* P.LS.S1~*(6) */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4003900, &NMD::CACHE , 0, + 0xfc007f00, 0xa4003900, &CACHE , 0, CP0_ }, /* CACHE */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4004100, &NMD::LWC2 , 0, + 0xfc007f00, 0xa4004100, &LWC2 , 0, CP2_ }, /* LWC2 */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4004900, &NMD::SWC2 , 0, + 0xfc007f00, 0xa4004900, &SWC2 , 0, CP2_ }, /* SWC2 */ { pool , P_LL , 4 , 32, 0xfc007f00, 0xa4005100, 0 , 0, @@ -21528,10 +21528,10 @@ NMD::Pool NMD::P_LS_S1[16] = { 0xfc007f00, 0xa4005900, 0 , 0, 0x0 }, /* P.SC */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4006100, &NMD::LDC2 , 0, + 0xfc007f00, 0xa4006100, &LDC2 , 0, CP2_ }, /* LDC2 */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4006900, &NMD::SDC2 , 0, + 0xfc007f00, 0xa4006900, &SDC2 , 0, CP2_ }, /* SDC2 */ { pool , P_LLD , 8 , 32, 0xfc007f00, 0xa4007100, 0 , 0, @@ -21544,20 +21544,20 @@ NMD::Pool NMD::P_LS_S1[16] = { NMD::Pool NMD::P_PREFE[2] = { { instruction , 0 , 0 , 32, - 0xffe07f00, 0xa7e01a00, &NMD::SYNCIE , 0, + 0xffe07f00, 0xa7e01a00, &SYNCIE , 0, CP0_ | EVA_ }, /* SYNCIE */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4001a00, &NMD::PREFE , &PREFE_cond , + 0xfc007f00, 0xa4001a00, &PREFE , &PREFE_cond , CP0_ | EVA_ }, /* PREFE */ }; NMD::Pool NMD::P_LLE[4] = { { instruction , 0 , 0 , 32, - 0xfc007f03, 0xa4005200, &NMD::LLE , 0, + 0xfc007f03, 0xa4005200, &LLE , 0, CP0_ | EVA_ }, /* LLE */ { instruction , 0 , 0 , 32, - 0xfc007f03, 0xa4005201, &NMD::LLWPE , 0, + 0xfc007f03, 0xa4005201, &LLWPE , 0, CP0_ | EVA_ }, /* LLWPE */ { reserved_block , 0 , 0 , 32, 0xfc007f03, 0xa4005202, 0 , 0, @@ -21570,10 +21570,10 @@ NMD::Pool NMD::P_LLE[4] = { NMD::Pool NMD::P_SCE[4] = { { instruction , 0 , 0 , 32, - 0xfc007f03, 0xa4005a00, &NMD::SCE , 0, + 0xfc007f03, 0xa4005a00, &SCE , 0, CP0_ | EVA_ }, /* SCE */ { instruction , 0 , 0 , 32, - 0xfc007f03, 0xa4005a01, &NMD::SCWPE , 0, + 0xfc007f03, 0xa4005a01, &SCWPE , 0, CP0_ | EVA_ }, /* SCWPE */ { reserved_block , 0 , 0 , 32, 0xfc007f03, 0xa4005a02, 0 , 0, @@ -21586,34 +21586,34 @@ NMD::Pool NMD::P_SCE[4] = { NMD::Pool NMD::P_LS_E0[16] = { { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4000200, &NMD::LBE , 0, + 0xfc007f00, 0xa4000200, &LBE , 0, CP0_ | EVA_ }, /* LBE */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4000a00, &NMD::SBE , 0, + 0xfc007f00, 0xa4000a00, &SBE , 0, CP0_ | EVA_ }, /* SBE */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4001200, &NMD::LBUE , 0, + 0xfc007f00, 0xa4001200, &LBUE , 0, CP0_ | EVA_ }, /* LBUE */ { pool , P_PREFE , 2 , 32, 0xfc007f00, 0xa4001a00, 0 , 0, 0x0 }, /* P.PREFE */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4002200, &NMD::LHE , 0, + 0xfc007f00, 0xa4002200, &LHE , 0, CP0_ | EVA_ }, /* LHE */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4002a00, &NMD::SHE , 0, + 0xfc007f00, 0xa4002a00, &SHE , 0, CP0_ | EVA_ }, /* SHE */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4003200, &NMD::LHUE , 0, + 0xfc007f00, 0xa4003200, &LHUE , 0, CP0_ | EVA_ }, /* LHUE */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4003a00, &NMD::CACHEE , 0, + 0xfc007f00, 0xa4003a00, &CACHEE , 0, CP0_ | EVA_ }, /* CACHEE */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4004200, &NMD::LWE , 0, + 0xfc007f00, 0xa4004200, &LWE , 0, CP0_ | EVA_ }, /* LWE */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4004a00, &NMD::SWE , 0, + 0xfc007f00, 0xa4004a00, &SWE , 0, CP0_ | EVA_ }, /* SWE */ { pool , P_LLE , 4 , 32, 0xfc007f00, 0xa4005200, 0 , 0, @@ -21638,40 +21638,40 @@ NMD::Pool NMD::P_LS_E0[16] = { NMD::Pool NMD::P_LS_WM[2] = { { instruction , 0 , 0 , 32, - 0xfc000f00, 0xa4000400, &NMD::LWM , 0, + 0xfc000f00, 0xa4000400, &LWM , 0, XMMS_ }, /* LWM */ { instruction , 0 , 0 , 32, - 0xfc000f00, 0xa4000c00, &NMD::SWM , 0, + 0xfc000f00, 0xa4000c00, &SWM , 0, XMMS_ }, /* SWM */ }; NMD::Pool NMD::P_LS_UAWM[2] = { { instruction , 0 , 0 , 32, - 0xfc000f00, 0xa4000500, &NMD::UALWM , 0, + 0xfc000f00, 0xa4000500, &UALWM , 0, XMMS_ }, /* UALWM */ { instruction , 0 , 0 , 32, - 0xfc000f00, 0xa4000d00, &NMD::UASWM , 0, + 0xfc000f00, 0xa4000d00, &UASWM , 0, XMMS_ }, /* UASWM */ }; NMD::Pool NMD::P_LS_DM[2] = { { instruction , 0 , 0 , 32, - 0xfc000f00, 0xa4000600, &NMD::LDM , 0, + 0xfc000f00, 0xa4000600, &LDM , 0, MIPS64_ }, /* LDM */ { instruction , 0 , 0 , 32, - 0xfc000f00, 0xa4000e00, &NMD::SDM , 0, + 0xfc000f00, 0xa4000e00, &SDM , 0, MIPS64_ }, /* SDM */ }; NMD::Pool NMD::P_LS_UADM[2] = { { instruction , 0 , 0 , 32, - 0xfc000f00, 0xa4000700, &NMD::UALDM , 0, + 0xfc000f00, 0xa4000700, &UALDM , 0, MIPS64_ }, /* UALDM */ { instruction , 0 , 0 , 32, - 0xfc000f00, 0xa4000f00, &NMD::UASDM , 0, + 0xfc000f00, 0xa4000f00, &UASDM , 0, MIPS64_ }, /* UASDM */ }; @@ -21706,30 +21706,30 @@ NMD::Pool NMD::P_LS_S9[8] = { NMD::Pool NMD::P_BAL[2] = { { branch_instruction , 0 , 0 , 32, - 0xfe000000, 0x28000000, &NMD::BC_32_ , 0, + 0xfe000000, 0x28000000, &BC_32_ , 0, 0x0 }, /* BC[32] */ { call_instruction , 0 , 0 , 32, - 0xfe000000, 0x2a000000, &NMD::BALC_32_ , 0, + 0xfe000000, 0x2a000000, &BALC_32_ , 0, 0x0 }, /* BALC[32] */ }; NMD::Pool NMD::P_BALRSC[2] = { { branch_instruction , 0 , 0 , 32, - 0xffe0f000, 0x48008000, &NMD::BRSC , 0, + 0xffe0f000, 0x48008000, &BRSC , 0, 0x0 }, /* BRSC */ { call_instruction , 0 , 0 , 32, - 0xfc00f000, 0x48008000, &NMD::BALRSC , &BALRSC_cond , + 0xfc00f000, 0x48008000, &BALRSC , &BALRSC_cond , 0x0 }, /* BALRSC */ }; NMD::Pool NMD::P_J[16] = { { call_instruction , 0 , 0 , 32, - 0xfc00f000, 0x48000000, &NMD::JALRC_32_ , 0, + 0xfc00f000, 0x48000000, &JALRC_32_ , 0, 0x0 }, /* JALRC[32] */ { call_instruction , 0 , 0 , 32, - 0xfc00f000, 0x48001000, &NMD::JALRC_HB , 0, + 0xfc00f000, 0x48001000, &JALRC_HB , 0, 0x0 }, /* JALRC.HB */ { reserved_block , 0 , 0 , 32, 0xfc00f000, 0x48002000, 0 , 0, @@ -21778,19 +21778,19 @@ NMD::Pool NMD::P_J[16] = { NMD::Pool NMD::P_BR3A[32] = { { branch_instruction , 0 , 0 , 32, - 0xfc1fc000, 0x88004000, &NMD::BC1EQZC , 0, + 0xfc1fc000, 0x88004000, &BC1EQZC , 0, CP1_ }, /* BC1EQZC */ { branch_instruction , 0 , 0 , 32, - 0xfc1fc000, 0x88014000, &NMD::BC1NEZC , 0, + 0xfc1fc000, 0x88014000, &BC1NEZC , 0, CP1_ }, /* BC1NEZC */ { branch_instruction , 0 , 0 , 32, - 0xfc1fc000, 0x88024000, &NMD::BC2EQZC , 0, + 0xfc1fc000, 0x88024000, &BC2EQZC , 0, CP2_ }, /* BC2EQZC */ { branch_instruction , 0 , 0 , 32, - 0xfc1fc000, 0x88034000, &NMD::BC2NEZC , 0, + 0xfc1fc000, 0x88034000, &BC2NEZC , 0, CP2_ }, /* BC2NEZC */ { branch_instruction , 0 , 0 , 32, - 0xfc1fc000, 0x88044000, &NMD::BPOSGE32C , 0, + 0xfc1fc000, 0x88044000, &BPOSGE32C , 0, DSP_ }, /* BPOSGE32C */ { reserved_block , 0 , 0 , 32, 0xfc1fc000, 0x88054000, 0 , 0, @@ -21878,60 +21878,60 @@ NMD::Pool NMD::P_BR3A[32] = { NMD::Pool NMD::P_BR1[4] = { { branch_instruction , 0 , 0 , 32, - 0xfc00c000, 0x88000000, &NMD::BEQC_32_ , 0, + 0xfc00c000, 0x88000000, &BEQC_32_ , 0, 0x0 }, /* BEQC[32] */ { pool , P_BR3A , 32 , 32, 0xfc00c000, 0x88004000, 0 , 0, 0x0 }, /* P.BR3A */ { branch_instruction , 0 , 0 , 32, - 0xfc00c000, 0x88008000, &NMD::BGEC , 0, + 0xfc00c000, 0x88008000, &BGEC , 0, 0x0 }, /* BGEC */ { branch_instruction , 0 , 0 , 32, - 0xfc00c000, 0x8800c000, &NMD::BGEUC , 0, + 0xfc00c000, 0x8800c000, &BGEUC , 0, 0x0 }, /* BGEUC */ }; NMD::Pool NMD::P_BR2[4] = { { branch_instruction , 0 , 0 , 32, - 0xfc00c000, 0xa8000000, &NMD::BNEC_32_ , 0, + 0xfc00c000, 0xa8000000, &BNEC_32_ , 0, 0x0 }, /* BNEC[32] */ { reserved_block , 0 , 0 , 32, 0xfc00c000, 0xa8004000, 0 , 0, 0x0 }, /* P.BR2~*(1) */ { branch_instruction , 0 , 0 , 32, - 0xfc00c000, 0xa8008000, &NMD::BLTC , 0, + 0xfc00c000, 0xa8008000, &BLTC , 0, 0x0 }, /* BLTC */ { branch_instruction , 0 , 0 , 32, - 0xfc00c000, 0xa800c000, &NMD::BLTUC , 0, + 0xfc00c000, 0xa800c000, &BLTUC , 0, 0x0 }, /* BLTUC */ }; NMD::Pool NMD::P_BRI[8] = { { branch_instruction , 0 , 0 , 32, - 0xfc1c0000, 0xc8000000, &NMD::BEQIC , 0, + 0xfc1c0000, 0xc8000000, &BEQIC , 0, 0x0 }, /* BEQIC */ { branch_instruction , 0 , 0 , 32, - 0xfc1c0000, 0xc8040000, &NMD::BBEQZC , 0, + 0xfc1c0000, 0xc8040000, &BBEQZC , 0, XMMS_ }, /* BBEQZC */ { branch_instruction , 0 , 0 , 32, - 0xfc1c0000, 0xc8080000, &NMD::BGEIC , 0, + 0xfc1c0000, 0xc8080000, &BGEIC , 0, 0x0 }, /* BGEIC */ { branch_instruction , 0 , 0 , 32, - 0xfc1c0000, 0xc80c0000, &NMD::BGEIUC , 0, + 0xfc1c0000, 0xc80c0000, &BGEIUC , 0, 0x0 }, /* BGEIUC */ { branch_instruction , 0 , 0 , 32, - 0xfc1c0000, 0xc8100000, &NMD::BNEIC , 0, + 0xfc1c0000, 0xc8100000, &BNEIC , 0, 0x0 }, /* BNEIC */ { branch_instruction , 0 , 0 , 32, - 0xfc1c0000, 0xc8140000, &NMD::BBNEZC , 0, + 0xfc1c0000, 0xc8140000, &BBNEZC , 0, XMMS_ }, /* BBNEZC */ { branch_instruction , 0 , 0 , 32, - 0xfc1c0000, 0xc8180000, &NMD::BLTIC , 0, + 0xfc1c0000, 0xc8180000, &BLTIC , 0, 0x0 }, /* BLTIC */ { branch_instruction , 0 , 0 , 32, - 0xfc1c0000, 0xc81c0000, &NMD::BLTIUC , 0, + 0xfc1c0000, 0xc81c0000, &BLTIUC , 0, 0x0 }, /* BLTIUC */ }; @@ -21962,7 +21962,7 @@ NMD::Pool NMD::P32[32] = { 0xfc000000, 0xe0000000, 0 , 0, 0x0 }, /* P.LUI */ { instruction , 0 , 0 , 32, - 0xfc000000, 0x04000000, &NMD::ADDIUPC_32_ , 0, + 0xfc000000, 0x04000000, &ADDIUPC_32_ , 0, 0x0 }, /* ADDIUPC[32] */ { reserved_block , 0 , 0 , 32, 0xfc000000, 0x24000000, 0 , 0, @@ -21986,7 +21986,7 @@ NMD::Pool NMD::P32[32] = { 0xfc000000, 0xe4000000, 0 , 0, 0x0 }, /* P32~*(29) */ { call_instruction , 0 , 0 , 32, - 0xfc000000, 0x08000000, &NMD::MOVE_BALC , 0, + 0xfc000000, 0x08000000, &MOVE_BALC , 0, XMMS_ }, /* MOVE.BALC */ { pool , P_BAL , 2 , 32, 0xfc000000, 0x28000000, 0 , 0, @@ -22038,10 +22038,10 @@ NMD::Pool NMD::P32[32] = { NMD::Pool NMD::P16_SYSCALL[2] = { { instruction , 0 , 0 , 16, - 0xfffc , 0x1008 , &NMD::SYSCALL_16_ , 0, + 0xfffc , 0x1008 , &SYSCALL_16_ , 0, 0x0 }, /* SYSCALL[16] */ { instruction , 0 , 0 , 16, - 0xfffc , 0x100c , &NMD::HYPCALL_16_ , 0, + 0xfffc , 0x100c , &HYPCALL_16_ , 0, CP0_ | VZ_ }, /* HYPCALL[16] */ }; @@ -22054,10 +22054,10 @@ NMD::Pool NMD::P16_RI[4] = { 0xfff8 , 0x1008 , 0 , 0, 0x0 }, /* P16.SYSCALL */ { instruction , 0 , 0 , 16, - 0xfff8 , 0x1010 , &NMD::BREAK_16_ , 0, + 0xfff8 , 0x1010 , &BREAK_16_ , 0, 0x0 }, /* BREAK[16] */ { instruction , 0 , 0 , 16, - 0xfff8 , 0x1018 , &NMD::SDBBP_16_ , 0, + 0xfff8 , 0x1018 , &SDBBP_16_ , 0, EJTAG_ }, /* SDBBP[16] */ }; @@ -22067,33 +22067,33 @@ NMD::Pool NMD::P16_MV[2] = { 0xffe0 , 0x1000 , 0 , 0, 0x0 }, /* P16.RI */ { instruction , 0 , 0 , 16, - 0xfc00 , 0x1000 , &NMD::MOVE , &MOVE_cond , + 0xfc00 , 0x1000 , &MOVE , &MOVE_cond , 0x0 }, /* MOVE */ }; NMD::Pool NMD::P16_SHIFT[2] = { { instruction , 0 , 0 , 16, - 0xfc08 , 0x3000 , &NMD::SLL_16_ , 0, + 0xfc08 , 0x3000 , &SLL_16_ , 0, 0x0 }, /* SLL[16] */ { instruction , 0 , 0 , 16, - 0xfc08 , 0x3008 , &NMD::SRL_16_ , 0, + 0xfc08 , 0x3008 , &SRL_16_ , 0, 0x0 }, /* SRL[16] */ }; NMD::Pool NMD::POOL16C_00[4] = { { instruction , 0 , 0 , 16, - 0xfc0f , 0x5000 , &NMD::NOT_16_ , 0, + 0xfc0f , 0x5000 , &NOT_16_ , 0, 0x0 }, /* NOT[16] */ { instruction , 0 , 0 , 16, - 0xfc0f , 0x5004 , &NMD::XOR_16_ , 0, + 0xfc0f , 0x5004 , &XOR_16_ , 0, 0x0 }, /* XOR[16] */ { instruction , 0 , 0 , 16, - 0xfc0f , 0x5008 , &NMD::AND_16_ , 0, + 0xfc0f , 0x5008 , &AND_16_ , 0, 0x0 }, /* AND[16] */ { instruction , 0 , 0 , 16, - 0xfc0f , 0x500c , &NMD::OR_16_ , 0, + 0xfc0f , 0x500c , &OR_16_ , 0, 0x0 }, /* OR[16] */ }; @@ -22113,7 +22113,7 @@ NMD::Pool NMD::P16C[2] = { 0xfc01 , 0x5000 , 0 , 0, 0x0 }, /* POOL16C_0 */ { instruction , 0 , 0 , 16, - 0xfc01 , 0x5001 , &NMD::LWXS_16_ , 0, + 0xfc01 , 0x5001 , &LWXS_16_ , 0, 0x0 }, /* LWXS[16] */ }; @@ -22123,24 +22123,24 @@ NMD::Pool NMD::P16_A1[2] = { 0xfc40 , 0x7000 , 0 , 0, 0x0 }, /* P16.A1~*(0) */ { instruction , 0 , 0 , 16, - 0xfc40 , 0x7040 , &NMD::ADDIU_R1_SP_ , 0, + 0xfc40 , 0x7040 , &ADDIU_R1_SP_ , 0, 0x0 }, /* ADDIU[R1.SP] */ }; NMD::Pool NMD::P_ADDIU_RS5_[2] = { { instruction , 0 , 0 , 16, - 0xffe8 , 0x9008 , &NMD::NOP_16_ , 0, + 0xffe8 , 0x9008 , &NOP_16_ , 0, 0x0 }, /* NOP[16] */ { instruction , 0 , 0 , 16, - 0xfc08 , 0x9008 , &NMD::ADDIU_RS5_ , &ADDIU_RS5__cond , + 0xfc08 , 0x9008 , &ADDIU_RS5_ , &ADDIU_RS5__cond , 0x0 }, /* ADDIU[RS5] */ }; NMD::Pool NMD::P16_A2[2] = { { instruction , 0 , 0 , 16, - 0xfc08 , 0x9000 , &NMD::ADDIU_R2_ , 0, + 0xfc08 , 0x9000 , &ADDIU_R2_ , 0, 0x0 }, /* ADDIU[R2] */ { pool , P_ADDIU_RS5_ , 2 , 16, 0xfc08 , 0x9008 , 0 , 0, @@ -22150,30 +22150,30 @@ NMD::Pool NMD::P16_A2[2] = { NMD::Pool NMD::P16_ADDU[2] = { { instruction , 0 , 0 , 16, - 0xfc01 , 0xb000 , &NMD::ADDU_16_ , 0, + 0xfc01 , 0xb000 , &ADDU_16_ , 0, 0x0 }, /* ADDU[16] */ { instruction , 0 , 0 , 16, - 0xfc01 , 0xb001 , &NMD::SUBU_16_ , 0, + 0xfc01 , 0xb001 , &SUBU_16_ , 0, 0x0 }, /* SUBU[16] */ }; NMD::Pool NMD::P16_JRC[2] = { { branch_instruction , 0 , 0 , 16, - 0xfc1f , 0xd800 , &NMD::JRC , 0, + 0xfc1f , 0xd800 , &JRC , 0, 0x0 }, /* JRC */ { call_instruction , 0 , 0 , 16, - 0xfc1f , 0xd810 , &NMD::JALRC_16_ , 0, + 0xfc1f , 0xd810 , &JALRC_16_ , 0, 0x0 }, /* JALRC[16] */ }; NMD::Pool NMD::P16_BR1[2] = { { branch_instruction , 0 , 0 , 16, - 0xfc00 , 0xd800 , &NMD::BEQC_16_ , &BEQC_16__cond , + 0xfc00 , 0xd800 , &BEQC_16_ , &BEQC_16__cond , XMMS_ }, /* BEQC[16] */ { branch_instruction , 0 , 0 , 16, - 0xfc00 , 0xd800 , &NMD::BNEC_16_ , &BNEC_16__cond , + 0xfc00 , 0xd800 , &BNEC_16_ , &BNEC_16__cond , XMMS_ }, /* BNEC[16] */ }; @@ -22190,20 +22190,20 @@ NMD::Pool NMD::P16_BR[2] = { NMD::Pool NMD::P16_SR[2] = { { instruction , 0 , 0 , 16, - 0xfd00 , 0x1c00 , &NMD::SAVE_16_ , 0, + 0xfd00 , 0x1c00 , &SAVE_16_ , 0, 0x0 }, /* SAVE[16] */ { return_instruction , 0 , 0 , 16, - 0xfd00 , 0x1d00 , &NMD::RESTORE_JRC_16_ , 0, + 0xfd00 , 0x1d00 , &RESTORE_JRC_16_ , 0, 0x0 }, /* RESTORE.JRC[16] */ }; NMD::Pool NMD::P16_4X4[4] = { { instruction , 0 , 0 , 16, - 0xfd08 , 0x3c00 , &NMD::ADDU_4X4_ , 0, + 0xfd08 , 0x3c00 , &ADDU_4X4_ , 0, XMMS_ }, /* ADDU[4X4] */ { instruction , 0 , 0 , 16, - 0xfd08 , 0x3c08 , &NMD::MUL_4X4_ , 0, + 0xfd08 , 0x3c08 , &MUL_4X4_ , 0, XMMS_ }, /* MUL[4X4] */ { reserved_block , 0 , 0 , 16, 0xfd08 , 0x3d00 , 0 , 0, @@ -22216,13 +22216,13 @@ NMD::Pool NMD::P16_4X4[4] = { NMD::Pool NMD::P16_LB[4] = { { instruction , 0 , 0 , 16, - 0xfc0c , 0x5c00 , &NMD::LB_16_ , 0, + 0xfc0c , 0x5c00 , &LB_16_ , 0, 0x0 }, /* LB[16] */ { instruction , 0 , 0 , 16, - 0xfc0c , 0x5c04 , &NMD::SB_16_ , 0, + 0xfc0c , 0x5c04 , &SB_16_ , 0, 0x0 }, /* SB[16] */ { instruction , 0 , 0 , 16, - 0xfc0c , 0x5c08 , &NMD::LBU_16_ , 0, + 0xfc0c , 0x5c08 , &LBU_16_ , 0, 0x0 }, /* LBU[16] */ { reserved_block , 0 , 0 , 16, 0xfc0c , 0x5c0c , 0 , 0, @@ -22232,13 +22232,13 @@ NMD::Pool NMD::P16_LB[4] = { NMD::Pool NMD::P16_LH[4] = { { instruction , 0 , 0 , 16, - 0xfc09 , 0x7c00 , &NMD::LH_16_ , 0, + 0xfc09 , 0x7c00 , &LH_16_ , 0, 0x0 }, /* LH[16] */ { instruction , 0 , 0 , 16, - 0xfc09 , 0x7c01 , &NMD::SH_16_ , 0, + 0xfc09 , 0x7c01 , &SH_16_ , 0, 0x0 }, /* SH[16] */ { instruction , 0 , 0 , 16, - 0xfc09 , 0x7c08 , &NMD::LHU_16_ , 0, + 0xfc09 , 0x7c08 , &LHU_16_ , 0, 0x0 }, /* LHU[16] */ { reserved_block , 0 , 0 , 16, 0xfc09 , 0x7c09 , 0 , 0, @@ -22266,40 +22266,40 @@ NMD::Pool NMD::P16[32] = { 0xfc00 , 0xb000 , 0 , 0, 0x0 }, /* P16.ADDU */ { instruction , 0 , 0 , 16, - 0xfc00 , 0xd000 , &NMD::LI_16_ , 0, + 0xfc00 , 0xd000 , &LI_16_ , 0, 0x0 }, /* LI[16] */ { instruction , 0 , 0 , 16, - 0xfc00 , 0xf000 , &NMD::ANDI_16_ , 0, + 0xfc00 , 0xf000 , &ANDI_16_ , 0, 0x0 }, /* ANDI[16] */ { instruction , 0 , 0 , 16, - 0xfc00 , 0x1400 , &NMD::LW_16_ , 0, + 0xfc00 , 0x1400 , &LW_16_ , 0, 0x0 }, /* LW[16] */ { instruction , 0 , 0 , 16, - 0xfc00 , 0x3400 , &NMD::LW_SP_ , 0, + 0xfc00 , 0x3400 , &LW_SP_ , 0, 0x0 }, /* LW[SP] */ { instruction , 0 , 0 , 16, - 0xfc00 , 0x5400 , &NMD::LW_GP16_ , 0, + 0xfc00 , 0x5400 , &LW_GP16_ , 0, 0x0 }, /* LW[GP16] */ { instruction , 0 , 0 , 16, - 0xfc00 , 0x7400 , &NMD::LW_4X4_ , 0, + 0xfc00 , 0x7400 , &LW_4X4_ , 0, XMMS_ }, /* LW[4X4] */ { instruction , 0 , 0 , 16, - 0xfc00 , 0x9400 , &NMD::SW_16_ , 0, + 0xfc00 , 0x9400 , &SW_16_ , 0, 0x0 }, /* SW[16] */ { instruction , 0 , 0 , 16, - 0xfc00 , 0xb400 , &NMD::SW_SP_ , 0, + 0xfc00 , 0xb400 , &SW_SP_ , 0, 0x0 }, /* SW[SP] */ { instruction , 0 , 0 , 16, - 0xfc00 , 0xd400 , &NMD::SW_GP16_ , 0, + 0xfc00 , 0xd400 , &SW_GP16_ , 0, 0x0 }, /* SW[GP16] */ { instruction , 0 , 0 , 16, - 0xfc00 , 0xf400 , &NMD::SW_4X4_ , 0, + 0xfc00 , 0xf400 , &SW_4X4_ , 0, XMMS_ }, /* SW[4X4] */ { branch_instruction , 0 , 0 , 16, - 0xfc00 , 0x1800 , &NMD::BC_16_ , 0, + 0xfc00 , 0x1800 , &BC_16_ , 0, 0x0 }, /* BC[16] */ { call_instruction , 0 , 0 , 16, - 0xfc00 , 0x3800 , &NMD::BALC_16_ , 0, + 0xfc00 , 0x3800 , &BALC_16_ , 0, 0x0 }, /* BALC[16] */ { reserved_block , 0 , 0 , 16, 0xfc00 , 0x5800 , 0 , 0, @@ -22308,10 +22308,10 @@ NMD::Pool NMD::P16[32] = { 0xfc00 , 0x7800 , 0 , 0, 0x0 }, /* P16~*(14) */ { branch_instruction , 0 , 0 , 16, - 0xfc00 , 0x9800 , &NMD::BEQZC_16_ , 0, + 0xfc00 , 0x9800 , &BEQZC_16_ , 0, 0x0 }, /* BEQZC[16] */ { branch_instruction , 0 , 0 , 16, - 0xfc00 , 0xb800 , &NMD::BNEZC_16_ , 0, + 0xfc00 , 0xb800 , &BNEZC_16_ , 0, 0x0 }, /* BNEZC[16] */ { pool , P16_BR , 2 , 16, 0xfc00 , 0xd800 , 0 , 0, @@ -22335,13 +22335,13 @@ NMD::Pool NMD::P16[32] = { 0xfc00 , 0x9c00 , 0 , 0, 0x0 }, /* P16~*(19) */ { instruction , 0 , 0 , 16, - 0xfc00 , 0xbc00 , &NMD::MOVEP , 0, + 0xfc00 , 0xbc00 , &MOVEP , 0, XMMS_ }, /* MOVEP */ { reserved_block , 0 , 0 , 16, 0xfc00 , 0xdc00 , 0 , 0, 0x0 }, /* P16~*(27) */ { instruction , 0 , 0 , 16, - 0xfc00 , 0xfc00 , &NMD::MOVEP_REV_ , 0, + 0xfc00 , 0xfc00 , &MOVEP_REV_ , 0, XMMS_ }, /* MOVEP[REV] */ }; diff --git a/disas/nanomips.h b/disas/nanomips.h index af803f4cc0..7036e589f4 100644 --- a/disas/nanomips.h +++ b/disas/nanomips.h @@ -65,6 +65,8 @@ typedef struct Dis_info { } Dis_info; typedef bool (*conditional_function)(uint64 instruction); +typedef std::string (*disassembly_function)(uint64 instruction, + Dis_info *info); class NMD { @@ -75,9 +77,6 @@ public: private: - typedef std::string(NMD:: *disassembly_function)(uint64 instruction, - Dis_info *info); - struct Pool { TABLE_ENTRY_TYPE type; struct Pool *next_table; @@ -95,643 +94,6 @@ private: TABLE_ENTRY_TYPE & type, const Pool *table, int table_size, Dis_info *info); - std::string ABS_D(uint64 instruction, Dis_info *info); - std::string ABS_S(uint64 instruction, Dis_info *info); - std::string ABSQ_S_PH(uint64 instruction, Dis_info *info); - std::string ABSQ_S_QB(uint64 instruction, Dis_info *info); - std::string ABSQ_S_W(uint64 instruction, Dis_info *info); - std::string ACLR(uint64 instruction, Dis_info *info); - std::string ADD(uint64 instruction, Dis_info *info); - std::string ADD_D(uint64 instruction, Dis_info *info); - std::string ADD_S(uint64 instruction, Dis_info *info); - std::string ADDIU_32_(uint64 instruction, Dis_info *info); - std::string ADDIU_48_(uint64 instruction, Dis_info *info); - std::string ADDIU_GP48_(uint64 instruction, Dis_info *info); - std::string ADDIU_GP_B_(uint64 instruction, Dis_info *info); - std::string ADDIU_GP_W_(uint64 instruction, Dis_info *info); - std::string ADDIU_NEG_(uint64 instruction, Dis_info *info); - std::string ADDIU_R1_SP_(uint64 instruction, Dis_info *info); - std::string ADDIU_R2_(uint64 instruction, Dis_info *info); - std::string ADDIU_RS5_(uint64 instruction, Dis_info *info); - std::string ADDIUPC_32_(uint64 instruction, Dis_info *info); - std::string ADDIUPC_48_(uint64 instruction, Dis_info *info); - std::string ADDQ_PH(uint64 instruction, Dis_info *info); - std::string ADDQ_S_PH(uint64 instruction, Dis_info *info); - std::string ADDQ_S_W(uint64 instruction, Dis_info *info); - std::string ADDQH_PH(uint64 instruction, Dis_info *info); - std::string ADDQH_R_PH(uint64 instruction, Dis_info *info); - std::string ADDQH_R_W(uint64 instruction, Dis_info *info); - std::string ADDQH_W(uint64 instruction, Dis_info *info); - std::string ADDSC(uint64 instruction, Dis_info *info); - std::string ADDU_16_(uint64 instruction, Dis_info *info); - std::string ADDU_32_(uint64 instruction, Dis_info *info); - std::string ADDU_4X4_(uint64 instruction, Dis_info *info); - std::string ADDU_PH(uint64 instruction, Dis_info *info); - std::string ADDU_QB(uint64 instruction, Dis_info *info); - std::string ADDU_S_PH(uint64 instruction, Dis_info *info); - std::string ADDU_S_QB(uint64 instruction, Dis_info *info); - std::string ADDUH_QB(uint64 instruction, Dis_info *info); - std::string ADDUH_R_QB(uint64 instruction, Dis_info *info); - std::string ADDWC(uint64 instruction, Dis_info *info); - std::string ALUIPC(uint64 instruction, Dis_info *info); - std::string AND_16_(uint64 instruction, Dis_info *info); - std::string AND_32_(uint64 instruction, Dis_info *info); - std::string ANDI_16_(uint64 instruction, Dis_info *info); - std::string ANDI_32_(uint64 instruction, Dis_info *info); - std::string APPEND(uint64 instruction, Dis_info *info); - std::string ASET(uint64 instruction, Dis_info *info); - std::string BALC_16_(uint64 instruction, Dis_info *info); - std::string BALC_32_(uint64 instruction, Dis_info *info); - std::string BALRSC(uint64 instruction, Dis_info *info); - std::string BBEQZC(uint64 instruction, Dis_info *info); - std::string BBNEZC(uint64 instruction, Dis_info *info); - std::string BC_16_(uint64 instruction, Dis_info *info); - std::string BC_32_(uint64 instruction, Dis_info *info); - std::string BC1EQZC(uint64 instruction, Dis_info *info); - std::string BC1NEZC(uint64 instruction, Dis_info *info); - std::string BC2EQZC(uint64 instruction, Dis_info *info); - std::string BC2NEZC(uint64 instruction, Dis_info *info); - std::string BEQC_16_(uint64 instruction, Dis_info *info); - std::string BEQC_32_(uint64 instruction, Dis_info *info); - std::string BEQIC(uint64 instruction, Dis_info *info); - std::string BEQZC_16_(uint64 instruction, Dis_info *info); - std::string BGEC(uint64 instruction, Dis_info *info); - std::string BGEIC(uint64 instruction, Dis_info *info); - std::string BGEIUC(uint64 instruction, Dis_info *info); - std::string BGEUC(uint64 instruction, Dis_info *info); - std::string BLTC(uint64 instruction, Dis_info *info); - std::string BLTIC(uint64 instruction, Dis_info *info); - std::string BLTIUC(uint64 instruction, Dis_info *info); - std::string BLTUC(uint64 instruction, Dis_info *info); - std::string BNEC_16_(uint64 instruction, Dis_info *info); - std::string BNEC_32_(uint64 instruction, Dis_info *info); - std::string BNEIC(uint64 instruction, Dis_info *info); - std::string BNEZC_16_(uint64 instruction, Dis_info *info); - std::string BPOSGE32C(uint64 instruction, Dis_info *info); - std::string BREAK_16_(uint64 instruction, Dis_info *info); - std::string BREAK_32_(uint64 instruction, Dis_info *info); - std::string BRSC(uint64 instruction, Dis_info *info); - std::string CACHE(uint64 instruction, Dis_info *info); - std::string CACHEE(uint64 instruction, Dis_info *info); - std::string CEIL_L_D(uint64 instruction, Dis_info *info); - std::string CEIL_L_S(uint64 instruction, Dis_info *info); - std::string CEIL_W_D(uint64 instruction, Dis_info *info); - std::string CEIL_W_S(uint64 instruction, Dis_info *info); - std::string CFC1(uint64 instruction, Dis_info *info); - std::string CFC2(uint64 instruction, Dis_info *info); - std::string CLASS_D(uint64 instruction, Dis_info *info); - std::string CLASS_S(uint64 instruction, Dis_info *info); - std::string CLO(uint64 instruction, Dis_info *info); - std::string CLZ(uint64 instruction, Dis_info *info); - std::string CMP_AF_D(uint64 instruction, Dis_info *info); - std::string CMP_AF_S(uint64 instruction, Dis_info *info); - std::string CMP_EQ_D(uint64 instruction, Dis_info *info); - std::string CMP_EQ_PH(uint64 instruction, Dis_info *info); - std::string CMP_EQ_S(uint64 instruction, Dis_info *info); - std::string CMP_LE_D(uint64 instruction, Dis_info *info); - std::string CMP_LE_PH(uint64 instruction, Dis_info *info); - std::string CMP_LE_S(uint64 instruction, Dis_info *info); - std::string CMP_LT_D(uint64 instruction, Dis_info *info); - std::string CMP_LT_PH(uint64 instruction, Dis_info *info); - std::string CMP_LT_S(uint64 instruction, Dis_info *info); - std::string CMP_NE_D(uint64 instruction, Dis_info *info); - std::string CMP_NE_S(uint64 instruction, Dis_info *info); - std::string CMP_OR_D(uint64 instruction, Dis_info *info); - std::string CMP_OR_S(uint64 instruction, Dis_info *info); - std::string CMP_SAF_D(uint64 instruction, Dis_info *info); - std::string CMP_SAF_S(uint64 instruction, Dis_info *info); - std::string CMP_SEQ_D(uint64 instruction, Dis_info *info); - std::string CMP_SEQ_S(uint64 instruction, Dis_info *info); - std::string CMP_SLE_D(uint64 instruction, Dis_info *info); - std::string CMP_SLE_S(uint64 instruction, Dis_info *info); - std::string CMP_SLT_D(uint64 instruction, Dis_info *info); - std::string CMP_SLT_S(uint64 instruction, Dis_info *info); - std::string CMP_SNE_D(uint64 instruction, Dis_info *info); - std::string CMP_SNE_S(uint64 instruction, Dis_info *info); - std::string CMP_SOR_D(uint64 instruction, Dis_info *info); - std::string CMP_SOR_S(uint64 instruction, Dis_info *info); - std::string CMP_SUEQ_D(uint64 instruction, Dis_info *info); - std::string CMP_SUEQ_S(uint64 instruction, Dis_info *info); - std::string CMP_SULE_D(uint64 instruction, Dis_info *info); - std::string CMP_SULE_S(uint64 instruction, Dis_info *info); - std::string CMP_SULT_D(uint64 instruction, Dis_info *info); - std::string CMP_SULT_S(uint64 instruction, Dis_info *info); - std::string CMP_SUN_D(uint64 instruction, Dis_info *info); - std::string CMP_SUN_S(uint64 instruction, Dis_info *info); - std::string CMP_SUNE_D(uint64 instruction, Dis_info *info); - std::string CMP_SUNE_S(uint64 instruction, Dis_info *info); - std::string CMP_UEQ_D(uint64 instruction, Dis_info *info); - std::string CMP_UEQ_S(uint64 instruction, Dis_info *info); - std::string CMP_ULE_D(uint64 instruction, Dis_info *info); - std::string CMP_ULE_S(uint64 instruction, Dis_info *info); - std::string CMP_ULT_D(uint64 instruction, Dis_info *info); - std::string CMP_ULT_S(uint64 instruction, Dis_info *info); - std::string CMP_UN_D(uint64 instruction, Dis_info *info); - std::string CMP_UN_S(uint64 instruction, Dis_info *info); - std::string CMP_UNE_D(uint64 instruction, Dis_info *info); - std::string CMP_UNE_S(uint64 instruction, Dis_info *info); - std::string CMPGDU_EQ_QB(uint64 instruction, Dis_info *info); - std::string CMPGDU_LE_QB(uint64 instruction, Dis_info *info); - std::string CMPGDU_LT_QB(uint64 instruction, Dis_info *info); - std::string CMPGU_EQ_QB(uint64 instruction, Dis_info *info); - std::string CMPGU_LE_QB(uint64 instruction, Dis_info *info); - std::string CMPGU_LT_QB(uint64 instruction, Dis_info *info); - std::string CMPU_EQ_QB(uint64 instruction, Dis_info *info); - std::string CMPU_LE_QB(uint64 instruction, Dis_info *info); - std::string CMPU_LT_QB(uint64 instruction, Dis_info *info); - std::string COP2_1(uint64 instruction, Dis_info *info); - std::string CTC1(uint64 instruction, Dis_info *info); - std::string CTC2(uint64 instruction, Dis_info *info); - std::string CVT_D_L(uint64 instruction, Dis_info *info); - std::string CVT_D_S(uint64 instruction, Dis_info *info); - std::string CVT_D_W(uint64 instruction, Dis_info *info); - std::string CVT_L_D(uint64 instruction, Dis_info *info); - std::string CVT_L_S(uint64 instruction, Dis_info *info); - std::string CVT_S_D(uint64 instruction, Dis_info *info); - std::string CVT_S_L(uint64 instruction, Dis_info *info); - std::string CVT_S_PL(uint64 instruction, Dis_info *info); - std::string CVT_S_PU(uint64 instruction, Dis_info *info); - std::string CVT_S_W(uint64 instruction, Dis_info *info); - std::string CVT_W_D(uint64 instruction, Dis_info *info); - std::string CVT_W_S(uint64 instruction, Dis_info *info); - std::string DADDIU_48_(uint64 instruction, Dis_info *info); - std::string DADDIU_NEG_(uint64 instruction, Dis_info *info); - std::string DADDIU_U12_(uint64 instruction, Dis_info *info); - std::string DADD(uint64 instruction, Dis_info *info); - std::string DADDU(uint64 instruction, Dis_info *info); - std::string DCLO(uint64 instruction, Dis_info *info); - std::string DCLZ(uint64 instruction, Dis_info *info); - std::string DDIV(uint64 instruction, Dis_info *info); - std::string DDIVU(uint64 instruction, Dis_info *info); - std::string DERET(uint64 instruction, Dis_info *info); - std::string DEXTM(uint64 instruction, Dis_info *info); - std::string DEXT(uint64 instruction, Dis_info *info); - std::string DEXTU(uint64 instruction, Dis_info *info); - std::string DINSM(uint64 instruction, Dis_info *info); - std::string DINS(uint64 instruction, Dis_info *info); - std::string DINSU(uint64 instruction, Dis_info *info); - std::string DI(uint64 instruction, Dis_info *info); - std::string DIV(uint64 instruction, Dis_info *info); - std::string DIV_D(uint64 instruction, Dis_info *info); - std::string DIV_S(uint64 instruction, Dis_info *info); - std::string DIVU(uint64 instruction, Dis_info *info); - std::string DLSA(uint64 instruction, Dis_info *info); - std::string DLUI_48_(uint64 instruction, Dis_info *info); - std::string DMFC0(uint64 instruction, Dis_info *info); - std::string DMFC1(uint64 instruction, Dis_info *info); - std::string DMFC2(uint64 instruction, Dis_info *info); - std::string DMFGC0(uint64 instruction, Dis_info *info); - std::string DMOD(uint64 instruction, Dis_info *info); - std::string DMODU(uint64 instruction, Dis_info *info); - std::string DMTC0(uint64 instruction, Dis_info *info); - std::string DMTC1(uint64 instruction, Dis_info *info); - std::string DMTC2(uint64 instruction, Dis_info *info); - std::string DMTGC0(uint64 instruction, Dis_info *info); - std::string DMT(uint64 instruction, Dis_info *info); - std::string DMUH(uint64 instruction, Dis_info *info); - std::string DMUHU(uint64 instruction, Dis_info *info); - std::string DMUL(uint64 instruction, Dis_info *info); - std::string DMULU(uint64 instruction, Dis_info *info); - std::string DPAQ_S_W_PH(uint64 instruction, Dis_info *info); - std::string DPAQ_SA_L_W(uint64 instruction, Dis_info *info); - std::string DPAQX_S_W_PH(uint64 instruction, Dis_info *info); - std::string DPAQX_SA_W_PH(uint64 instruction, Dis_info *info); - std::string DPAU_H_QBL(uint64 instruction, Dis_info *info); - std::string DPAU_H_QBR(uint64 instruction, Dis_info *info); - std::string DPA_W_PH(uint64 instruction, Dis_info *info); - std::string DPAX_W_PH(uint64 instruction, Dis_info *info); - std::string DPS_W_PH(uint64 instruction, Dis_info *info); - std::string DPSQ_SA_L_W(uint64 instruction, Dis_info *info); - std::string DPSQ_S_W_PH(uint64 instruction, Dis_info *info); - std::string DPSQX_SA_W_PH(uint64 instruction, Dis_info *info); - std::string DPSQX_S_W_PH(uint64 instruction, Dis_info *info); - std::string DPSU_H_QBL(uint64 instruction, Dis_info *info); - std::string DPSU_H_QBR(uint64 instruction, Dis_info *info); - std::string DPSX_W_PH(uint64 instruction, Dis_info *info); - std::string DROTR(uint64 instruction, Dis_info *info); - std::string DROTR32(uint64 instruction, Dis_info *info); - std::string DROTRV(uint64 instruction, Dis_info *info); - std::string DROTX(uint64 instruction, Dis_info *info); - std::string DSLL(uint64 instruction, Dis_info *info); - std::string DSLL32(uint64 instruction, Dis_info *info); - std::string DSLLV(uint64 instruction, Dis_info *info); - std::string DSRA(uint64 instruction, Dis_info *info); - std::string DSRA32(uint64 instruction, Dis_info *info); - std::string DSRAV(uint64 instruction, Dis_info *info); - std::string DSRL32(uint64 instruction, Dis_info *info); - std::string DSRL(uint64 instruction, Dis_info *info); - std::string DSRLV(uint64 instruction, Dis_info *info); - std::string DSUB(uint64 instruction, Dis_info *info); - std::string DSUBU(uint64 instruction, Dis_info *info); - std::string DVP(uint64 instruction, Dis_info *info); - std::string DVPE(uint64 instruction, Dis_info *info); - std::string EHB(uint64 instruction, Dis_info *info); - std::string EI(uint64 instruction, Dis_info *info); - std::string EMT(uint64 instruction, Dis_info *info); - std::string ERET(uint64 instruction, Dis_info *info); - std::string ERETNC(uint64 instruction, Dis_info *info); - std::string EVP(uint64 instruction, Dis_info *info); - std::string EVPE(uint64 instruction, Dis_info *info); - std::string EXT(uint64 instruction, Dis_info *info); - std::string EXTD(uint64 instruction, Dis_info *info); - std::string EXTD32(uint64 instruction, Dis_info *info); - std::string EXTP(uint64 instruction, Dis_info *info); - std::string EXTPDP(uint64 instruction, Dis_info *info); - std::string EXTPDPV(uint64 instruction, Dis_info *info); - std::string EXTPV(uint64 instruction, Dis_info *info); - std::string EXTR_RS_W(uint64 instruction, Dis_info *info); - std::string EXTR_R_W(uint64 instruction, Dis_info *info); - std::string EXTR_S_H(uint64 instruction, Dis_info *info); - std::string EXTR_W(uint64 instruction, Dis_info *info); - std::string EXTRV_R_W(uint64 instruction, Dis_info *info); - std::string EXTRV_RS_W(uint64 instruction, Dis_info *info); - std::string EXTRV_S_H(uint64 instruction, Dis_info *info); - std::string EXTRV_W(uint64 instruction, Dis_info *info); - std::string EXTW(uint64 instruction, Dis_info *info); - std::string FLOOR_L_D(uint64 instruction, Dis_info *info); - std::string FLOOR_L_S(uint64 instruction, Dis_info *info); - std::string FLOOR_W_D(uint64 instruction, Dis_info *info); - std::string FLOOR_W_S(uint64 instruction, Dis_info *info); - std::string FORK(uint64 instruction, Dis_info *info); - std::string HYPCALL(uint64 instruction, Dis_info *info); - std::string HYPCALL_16_(uint64 instruction, Dis_info *info); - std::string INS(uint64 instruction, Dis_info *info); - std::string INSV(uint64 instruction, Dis_info *info); - std::string IRET(uint64 instruction, Dis_info *info); - std::string JALRC_16_(uint64 instruction, Dis_info *info); - std::string JALRC_32_(uint64 instruction, Dis_info *info); - std::string JALRC_HB(uint64 instruction, Dis_info *info); - std::string JRC(uint64 instruction, Dis_info *info); - std::string LB_16_(uint64 instruction, Dis_info *info); - std::string LB_GP_(uint64 instruction, Dis_info *info); - std::string LB_S9_(uint64 instruction, Dis_info *info); - std::string LB_U12_(uint64 instruction, Dis_info *info); - std::string LBE(uint64 instruction, Dis_info *info); - std::string LBU_16_(uint64 instruction, Dis_info *info); - std::string LBU_GP_(uint64 instruction, Dis_info *info); - std::string LBU_S9_(uint64 instruction, Dis_info *info); - std::string LBU_U12_(uint64 instruction, Dis_info *info); - std::string LBUE(uint64 instruction, Dis_info *info); - std::string LBUX(uint64 instruction, Dis_info *info); - std::string LBX(uint64 instruction, Dis_info *info); - std::string LD_GP_(uint64 instruction, Dis_info *info); - std::string LD_S9_(uint64 instruction, Dis_info *info); - std::string LD_U12_(uint64 instruction, Dis_info *info); - std::string LDC1_GP_(uint64 instruction, Dis_info *info); - std::string LDC1_S9_(uint64 instruction, Dis_info *info); - std::string LDC1_U12_(uint64 instruction, Dis_info *info); - std::string LDC1X(uint64 instruction, Dis_info *info); - std::string LDC1XS(uint64 instruction, Dis_info *info); - std::string LDC2(uint64 instruction, Dis_info *info); - std::string LDM(uint64 instruction, Dis_info *info); - std::string LDPC_48_(uint64 instruction, Dis_info *info); - std::string LDX(uint64 instruction, Dis_info *info); - std::string LDXS(uint64 instruction, Dis_info *info); - std::string LH_16_(uint64 instruction, Dis_info *info); - std::string LH_GP_(uint64 instruction, Dis_info *info); - std::string LH_S9_(uint64 instruction, Dis_info *info); - std::string LH_U12_(uint64 instruction, Dis_info *info); - std::string LHE(uint64 instruction, Dis_info *info); - std::string LHU_16_(uint64 instruction, Dis_info *info); - std::string LHU_GP_(uint64 instruction, Dis_info *info); - std::string LHU_S9_(uint64 instruction, Dis_info *info); - std::string LHU_U12_(uint64 instruction, Dis_info *info); - std::string LHUE(uint64 instruction, Dis_info *info); - std::string LHUX(uint64 instruction, Dis_info *info); - std::string LHUXS(uint64 instruction, Dis_info *info); - std::string LHX(uint64 instruction, Dis_info *info); - std::string LHXS(uint64 instruction, Dis_info *info); - std::string LI_16_(uint64 instruction, Dis_info *info); - std::string LI_48_(uint64 instruction, Dis_info *info); - std::string LL(uint64 instruction, Dis_info *info); - std::string LLD(uint64 instruction, Dis_info *info); - std::string LLDP(uint64 instruction, Dis_info *info); - std::string LLE(uint64 instruction, Dis_info *info); - std::string LLWP(uint64 instruction, Dis_info *info); - std::string LLWPE(uint64 instruction, Dis_info *info); - std::string LSA(uint64 instruction, Dis_info *info); - std::string LUI(uint64 instruction, Dis_info *info); - std::string LW_16_(uint64 instruction, Dis_info *info); - std::string LW_4X4_(uint64 instruction, Dis_info *info); - std::string LWC1_GP_(uint64 instruction, Dis_info *info); - std::string LWC1_S9_(uint64 instruction, Dis_info *info); - std::string LWC1_U12_(uint64 instruction, Dis_info *info); - std::string LWC1X(uint64 instruction, Dis_info *info); - std::string LWC1XS(uint64 instruction, Dis_info *info); - std::string LWC2(uint64 instruction, Dis_info *info); - std::string LWE(uint64 instruction, Dis_info *info); - std::string LW_GP_(uint64 instruction, Dis_info *info); - std::string LW_GP16_(uint64 instruction, Dis_info *info); - std::string LWM(uint64 instruction, Dis_info *info); - std::string LWPC_48_(uint64 instruction, Dis_info *info); - std::string LW_S9_(uint64 instruction, Dis_info *info); - std::string LW_SP_(uint64 instruction, Dis_info *info); - std::string LW_U12_(uint64 instruction, Dis_info *info); - std::string LWU_GP_(uint64 instruction, Dis_info *info); - std::string LWU_S9_(uint64 instruction, Dis_info *info); - std::string LWU_U12_(uint64 instruction, Dis_info *info); - std::string LWUX(uint64 instruction, Dis_info *info); - std::string LWUXS(uint64 instruction, Dis_info *info); - std::string LWX(uint64 instruction, Dis_info *info); - std::string LWXS_16_(uint64 instruction, Dis_info *info); - std::string LWXS_32_(uint64 instruction, Dis_info *info); - std::string MADD_DSP_(uint64 instruction, Dis_info *info); - std::string MADDF_D(uint64 instruction, Dis_info *info); - std::string MADDF_S(uint64 instruction, Dis_info *info); - std::string MADDU_DSP_(uint64 instruction, Dis_info *info); - std::string MAQ_S_W_PHL(uint64 instruction, Dis_info *info); - std::string MAQ_S_W_PHR(uint64 instruction, Dis_info *info); - std::string MAQ_SA_W_PHL(uint64 instruction, Dis_info *info); - std::string MAQ_SA_W_PHR(uint64 instruction, Dis_info *info); - std::string MAX_D(uint64 instruction, Dis_info *info); - std::string MAX_S(uint64 instruction, Dis_info *info); - std::string MAXA_D(uint64 instruction, Dis_info *info); - std::string MAXA_S(uint64 instruction, Dis_info *info); - std::string MFC0(uint64 instruction, Dis_info *info); - std::string MFC1(uint64 instruction, Dis_info *info); - std::string MFC2(uint64 instruction, Dis_info *info); - std::string MFGC0(uint64 instruction, Dis_info *info); - std::string MFHC0(uint64 instruction, Dis_info *info); - std::string MFHC1(uint64 instruction, Dis_info *info); - std::string MFHC2(uint64 instruction, Dis_info *info); - std::string MFHGC0(uint64 instruction, Dis_info *info); - std::string MFHI_DSP_(uint64 instruction, Dis_info *info); - std::string MFHTR(uint64 instruction, Dis_info *info); - std::string MFLO_DSP_(uint64 instruction, Dis_info *info); - std::string MFTR(uint64 instruction, Dis_info *info); - std::string MIN_D(uint64 instruction, Dis_info *info); - std::string MIN_S(uint64 instruction, Dis_info *info); - std::string MINA_D(uint64 instruction, Dis_info *info); - std::string MINA_S(uint64 instruction, Dis_info *info); - std::string MOD(uint64 instruction, Dis_info *info); - std::string MODSUB(uint64 instruction, Dis_info *info); - std::string MODU(uint64 instruction, Dis_info *info); - std::string MOV_D(uint64 instruction, Dis_info *info); - std::string MOV_S(uint64 instruction, Dis_info *info); - std::string MOVE_BALC(uint64 instruction, Dis_info *info); - std::string MOVEP(uint64 instruction, Dis_info *info); - std::string MOVEP_REV_(uint64 instruction, Dis_info *info); - std::string MOVE(uint64 instruction, Dis_info *info); - std::string MOVN(uint64 instruction, Dis_info *info); - std::string MOVZ(uint64 instruction, Dis_info *info); - std::string MSUB_DSP_(uint64 instruction, Dis_info *info); - std::string MSUBF_D(uint64 instruction, Dis_info *info); - std::string MSUBF_S(uint64 instruction, Dis_info *info); - std::string MSUBU_DSP_(uint64 instruction, Dis_info *info); - std::string MTC0(uint64 instruction, Dis_info *info); - std::string MTC1(uint64 instruction, Dis_info *info); - std::string MTC2(uint64 instruction, Dis_info *info); - std::string MTGC0(uint64 instruction, Dis_info *info); - std::string MTHC0(uint64 instruction, Dis_info *info); - std::string MTHC1(uint64 instruction, Dis_info *info); - std::string MTHC2(uint64 instruction, Dis_info *info); - std::string MTHGC0(uint64 instruction, Dis_info *info); - std::string MTHI_DSP_(uint64 instruction, Dis_info *info); - std::string MTHLIP(uint64 instruction, Dis_info *info); - std::string MTHTR(uint64 instruction, Dis_info *info); - std::string MTLO_DSP_(uint64 instruction, Dis_info *info); - std::string MTTR(uint64 instruction, Dis_info *info); - std::string MUH(uint64 instruction, Dis_info *info); - std::string MUHU(uint64 instruction, Dis_info *info); - std::string MUL_32_(uint64 instruction, Dis_info *info); - std::string MUL_4X4_(uint64 instruction, Dis_info *info); - std::string MUL_D(uint64 instruction, Dis_info *info); - std::string MUL_PH(uint64 instruction, Dis_info *info); - std::string MUL_S(uint64 instruction, Dis_info *info); - std::string MUL_S_PH(uint64 instruction, Dis_info *info); - std::string MULEQ_S_W_PHL(uint64 instruction, Dis_info *info); - std::string MULEQ_S_W_PHR(uint64 instruction, Dis_info *info); - std::string MULEU_S_PH_QBL(uint64 instruction, Dis_info *info); - std::string MULEU_S_PH_QBR(uint64 instruction, Dis_info *info); - std::string MULQ_RS_PH(uint64 instruction, Dis_info *info); - std::string MULQ_RS_W(uint64 instruction, Dis_info *info); - std::string MULQ_S_PH(uint64 instruction, Dis_info *info); - std::string MULQ_S_W(uint64 instruction, Dis_info *info); - std::string MULSA_W_PH(uint64 instruction, Dis_info *info); - std::string MULSAQ_S_W_PH(uint64 instruction, Dis_info *info); - std::string MULT_DSP_(uint64 instruction, Dis_info *info); - std::string MULTU_DSP_(uint64 instruction, Dis_info *info); - std::string MULU(uint64 instruction, Dis_info *info); - std::string NEG_D(uint64 instruction, Dis_info *info); - std::string NEG_S(uint64 instruction, Dis_info *info); - std::string NOP_16_(uint64 instruction, Dis_info *info); - std::string NOP_32_(uint64 instruction, Dis_info *info); - std::string NOR(uint64 instruction, Dis_info *info); - std::string NOT_16_(uint64 instruction, Dis_info *info); - std::string OR_16_(uint64 instruction, Dis_info *info); - std::string OR_32_(uint64 instruction, Dis_info *info); - std::string ORI(uint64 instruction, Dis_info *info); - std::string PACKRL_PH(uint64 instruction, Dis_info *info); - std::string PAUSE(uint64 instruction, Dis_info *info); - std::string PICK_PH(uint64 instruction, Dis_info *info); - std::string PICK_QB(uint64 instruction, Dis_info *info); - std::string PRECEQ_W_PHL(uint64 instruction, Dis_info *info); - std::string PRECEQ_W_PHR(uint64 instruction, Dis_info *info); - std::string PRECEQU_PH_QBL(uint64 instruction, Dis_info *info); - std::string PRECEQU_PH_QBLA(uint64 instruction, Dis_info *info); - std::string PRECEQU_PH_QBR(uint64 instruction, Dis_info *info); - std::string PRECEQU_PH_QBRA(uint64 instruction, Dis_info *info); - std::string PRECEU_PH_QBL(uint64 instruction, Dis_info *info); - std::string PRECEU_PH_QBLA(uint64 instruction, Dis_info *info); - std::string PRECEU_PH_QBR(uint64 instruction, Dis_info *info); - std::string PRECEU_PH_QBRA(uint64 instruction, Dis_info *info); - std::string PRECR_QB_PH(uint64 instruction, Dis_info *info); - std::string PRECR_SRA_PH_W(uint64 instruction, Dis_info *info); - std::string PRECR_SRA_R_PH_W(uint64 instruction, Dis_info *info); - std::string PRECRQ_PH_W(uint64 instruction, Dis_info *info); - std::string PRECRQ_QB_PH(uint64 instruction, Dis_info *info); - std::string PRECRQ_RS_PH_W(uint64 instruction, Dis_info *info); - std::string PRECRQU_S_QB_PH(uint64 instruction, Dis_info *info); - std::string PREF_S9_(uint64 instruction, Dis_info *info); - std::string PREF_U12_(uint64 instruction, Dis_info *info); - std::string PREFE(uint64 instruction, Dis_info *info); - std::string PREPEND(uint64 instruction, Dis_info *info); - std::string RADDU_W_QB(uint64 instruction, Dis_info *info); - std::string RDDSP(uint64 instruction, Dis_info *info); - std::string RDHWR(uint64 instruction, Dis_info *info); - std::string RDPGPR(uint64 instruction, Dis_info *info); - std::string RECIP_D(uint64 instruction, Dis_info *info); - std::string RECIP_S(uint64 instruction, Dis_info *info); - std::string REPL_PH(uint64 instruction, Dis_info *info); - std::string REPL_QB(uint64 instruction, Dis_info *info); - std::string REPLV_PH(uint64 instruction, Dis_info *info); - std::string REPLV_QB(uint64 instruction, Dis_info *info); - std::string RESTORE_32_(uint64 instruction, Dis_info *info); - std::string RESTORE_JRC_16_(uint64 instruction, Dis_info *info); - std::string RESTORE_JRC_32_(uint64 instruction, Dis_info *info); - std::string RESTOREF(uint64 instruction, Dis_info *info); - std::string RINT_D(uint64 instruction, Dis_info *info); - std::string RINT_S(uint64 instruction, Dis_info *info); - std::string ROTR(uint64 instruction, Dis_info *info); - std::string ROTRV(uint64 instruction, Dis_info *info); - std::string ROTX(uint64 instruction, Dis_info *info); - std::string ROUND_L_D(uint64 instruction, Dis_info *info); - std::string ROUND_L_S(uint64 instruction, Dis_info *info); - std::string ROUND_W_D(uint64 instruction, Dis_info *info); - std::string ROUND_W_S(uint64 instruction, Dis_info *info); - std::string RSQRT_D(uint64 instruction, Dis_info *info); - std::string RSQRT_S(uint64 instruction, Dis_info *info); - std::string SAVE_16_(uint64 instruction, Dis_info *info); - std::string SAVE_32_(uint64 instruction, Dis_info *info); - std::string SAVEF(uint64 instruction, Dis_info *info); - std::string SB_16_(uint64 instruction, Dis_info *info); - std::string SB_GP_(uint64 instruction, Dis_info *info); - std::string SB_S9_(uint64 instruction, Dis_info *info); - std::string SB_U12_(uint64 instruction, Dis_info *info); - std::string SBE(uint64 instruction, Dis_info *info); - std::string SBX(uint64 instruction, Dis_info *info); - std::string SC(uint64 instruction, Dis_info *info); - std::string SCD(uint64 instruction, Dis_info *info); - std::string SCDP(uint64 instruction, Dis_info *info); - std::string SCE(uint64 instruction, Dis_info *info); - std::string SCWP(uint64 instruction, Dis_info *info); - std::string SCWPE(uint64 instruction, Dis_info *info); - std::string SD_GP_(uint64 instruction, Dis_info *info); - std::string SD_S9_(uint64 instruction, Dis_info *info); - std::string SD_U12_(uint64 instruction, Dis_info *info); - std::string SDBBP_16_(uint64 instruction, Dis_info *info); - std::string SDBBP_32_(uint64 instruction, Dis_info *info); - std::string SDC1_GP_(uint64 instruction, Dis_info *info); - std::string SDC1_S9_(uint64 instruction, Dis_info *info); - std::string SDC1_U12_(uint64 instruction, Dis_info *info); - std::string SDC1X(uint64 instruction, Dis_info *info); - std::string SDC1XS(uint64 instruction, Dis_info *info); - std::string SDC2(uint64 instruction, Dis_info *info); - std::string SDM(uint64 instruction, Dis_info *info); - std::string SDPC_48_(uint64 instruction, Dis_info *info); - std::string SDX(uint64 instruction, Dis_info *info); - std::string SDXS(uint64 instruction, Dis_info *info); - std::string SEB(uint64 instruction, Dis_info *info); - std::string SEH(uint64 instruction, Dis_info *info); - std::string SEL_D(uint64 instruction, Dis_info *info); - std::string SEL_S(uint64 instruction, Dis_info *info); - std::string SELEQZ_D(uint64 instruction, Dis_info *info); - std::string SELEQZ_S(uint64 instruction, Dis_info *info); - std::string SELNEZ_D(uint64 instruction, Dis_info *info); - std::string SELNEZ_S(uint64 instruction, Dis_info *info); - std::string SEQI(uint64 instruction, Dis_info *info); - std::string SH_16_(uint64 instruction, Dis_info *info); - std::string SH_GP_(uint64 instruction, Dis_info *info); - std::string SH_S9_(uint64 instruction, Dis_info *info); - std::string SH_U12_(uint64 instruction, Dis_info *info); - std::string SHE(uint64 instruction, Dis_info *info); - std::string SHILO(uint64 instruction, Dis_info *info); - std::string SHILOV(uint64 instruction, Dis_info *info); - std::string SHLL_PH(uint64 instruction, Dis_info *info); - std::string SHLL_QB(uint64 instruction, Dis_info *info); - std::string SHLL_S_PH(uint64 instruction, Dis_info *info); - std::string SHLL_S_W(uint64 instruction, Dis_info *info); - std::string SHLLV_PH(uint64 instruction, Dis_info *info); - std::string SHLLV_QB(uint64 instruction, Dis_info *info); - std::string SHLLV_S_PH(uint64 instruction, Dis_info *info); - std::string SHLLV_S_W(uint64 instruction, Dis_info *info); - std::string SHRA_PH(uint64 instruction, Dis_info *info); - std::string SHRA_QB(uint64 instruction, Dis_info *info); - std::string SHRA_R_PH(uint64 instruction, Dis_info *info); - std::string SHRA_R_QB(uint64 instruction, Dis_info *info); - std::string SHRA_R_W(uint64 instruction, Dis_info *info); - std::string SHRAV_PH(uint64 instruction, Dis_info *info); - std::string SHRAV_QB(uint64 instruction, Dis_info *info); - std::string SHRAV_R_PH(uint64 instruction, Dis_info *info); - std::string SHRAV_R_QB(uint64 instruction, Dis_info *info); - std::string SHRAV_R_W(uint64 instruction, Dis_info *info); - std::string SHRL_PH(uint64 instruction, Dis_info *info); - std::string SHRL_QB(uint64 instruction, Dis_info *info); - std::string SHRLV_PH(uint64 instruction, Dis_info *info); - std::string SHRLV_QB(uint64 instruction, Dis_info *info); - std::string SHX(uint64 instruction, Dis_info *info); - std::string SHXS(uint64 instruction, Dis_info *info); - std::string SIGRIE(uint64 instruction, Dis_info *info); - std::string SLL_16_(uint64 instruction, Dis_info *info); - std::string SLL_32_(uint64 instruction, Dis_info *info); - std::string SLLV(uint64 instruction, Dis_info *info); - std::string SLT(uint64 instruction, Dis_info *info); - std::string SLTI(uint64 instruction, Dis_info *info); - std::string SLTIU(uint64 instruction, Dis_info *info); - std::string SLTU(uint64 instruction, Dis_info *info); - std::string SOV(uint64 instruction, Dis_info *info); - std::string SPECIAL2(uint64 instruction, Dis_info *info); - std::string SQRT_D(uint64 instruction, Dis_info *info); - std::string SQRT_S(uint64 instruction, Dis_info *info); - std::string SRA(uint64 instruction, Dis_info *info); - std::string SRAV(uint64 instruction, Dis_info *info); - std::string SRL_16_(uint64 instruction, Dis_info *info); - std::string SRL_32_(uint64 instruction, Dis_info *info); - std::string SRLV(uint64 instruction, Dis_info *info); - std::string SUB(uint64 instruction, Dis_info *info); - std::string SUB_D(uint64 instruction, Dis_info *info); - std::string SUB_S(uint64 instruction, Dis_info *info); - std::string SUBQ_PH(uint64 instruction, Dis_info *info); - std::string SUBQ_S_PH(uint64 instruction, Dis_info *info); - std::string SUBQ_S_W(uint64 instruction, Dis_info *info); - std::string SUBQH_PH(uint64 instruction, Dis_info *info); - std::string SUBQH_R_PH(uint64 instruction, Dis_info *info); - std::string SUBQH_R_W(uint64 instruction, Dis_info *info); - std::string SUBQH_W(uint64 instruction, Dis_info *info); - std::string SUBU_16_(uint64 instruction, Dis_info *info); - std::string SUBU_32_(uint64 instruction, Dis_info *info); - std::string SUBU_PH(uint64 instruction, Dis_info *info); - std::string SUBU_QB(uint64 instruction, Dis_info *info); - std::string SUBU_S_PH(uint64 instruction, Dis_info *info); - std::string SUBU_S_QB(uint64 instruction, Dis_info *info); - std::string SUBUH_QB(uint64 instruction, Dis_info *info); - std::string SUBUH_R_QB(uint64 instruction, Dis_info *info); - std::string SW_16_(uint64 instruction, Dis_info *info); - std::string SW_4X4_(uint64 instruction, Dis_info *info); - std::string SW_GP16_(uint64 instruction, Dis_info *info); - std::string SW_GP_(uint64 instruction, Dis_info *info); - std::string SW_S9_(uint64 instruction, Dis_info *info); - std::string SW_SP_(uint64 instruction, Dis_info *info); - std::string SW_U12_(uint64 instruction, Dis_info *info); - std::string SWC1_GP_(uint64 instruction, Dis_info *info); - std::string SWC1_S9_(uint64 instruction, Dis_info *info); - std::string SWC1_U12_(uint64 instruction, Dis_info *info); - std::string SWC1X(uint64 instruction, Dis_info *info); - std::string SWC1XS(uint64 instruction, Dis_info *info); - std::string SWC2(uint64 instruction, Dis_info *info); - std::string SWE(uint64 instruction, Dis_info *info); - std::string SWM(uint64 instruction, Dis_info *info); - std::string SWPC_48_(uint64 instruction, Dis_info *info); - std::string SWX(uint64 instruction, Dis_info *info); - std::string SWXS(uint64 instruction, Dis_info *info); - std::string SYNC(uint64 instruction, Dis_info *info); - std::string SYNCI(uint64 instruction, Dis_info *info); - std::string SYNCIE(uint64 instruction, Dis_info *info); - std::string SYSCALL_16_(uint64 instruction, Dis_info *info); - std::string SYSCALL_32_(uint64 instruction, Dis_info *info); - std::string TEQ(uint64 instruction, Dis_info *info); - std::string TLBGINV(uint64 instruction, Dis_info *info); - std::string TLBGINVF(uint64 instruction, Dis_info *info); - std::string TLBGP(uint64 instruction, Dis_info *info); - std::string TLBGR(uint64 instruction, Dis_info *info); - std::string TLBGWI(uint64 instruction, Dis_info *info); - std::string TLBGWR(uint64 instruction, Dis_info *info); - std::string TLBINV(uint64 instruction, Dis_info *info); - std::string TLBINVF(uint64 instruction, Dis_info *info); - std::string TLBP(uint64 instruction, Dis_info *info); - std::string TLBR(uint64 instruction, Dis_info *info); - std::string TLBWI(uint64 instruction, Dis_info *info); - std::string TLBWR(uint64 instruction, Dis_info *info); - std::string TNE(uint64 instruction, Dis_info *info); - std::string TRUNC_L_D(uint64 instruction, Dis_info *info); - std::string TRUNC_L_S(uint64 instruction, Dis_info *info); - std::string TRUNC_W_D(uint64 instruction, Dis_info *info); - std::string TRUNC_W_S(uint64 instruction, Dis_info *info); - std::string UALDM(uint64 instruction, Dis_info *info); - std::string UALH(uint64 instruction, Dis_info *info); - std::string UALWM(uint64 instruction, Dis_info *info); - std::string UASDM(uint64 instruction, Dis_info *info); - std::string UASH(uint64 instruction, Dis_info *info); - std::string UASWM(uint64 instruction, Dis_info *info); - std::string UDI(uint64 instruction, Dis_info *info); - std::string WAIT(uint64 instruction, Dis_info *info); - std::string WRDSP(uint64 instruction, Dis_info *info); - std::string WRPGPR(uint64 instruction, Dis_info *info); - std::string XOR_16_(uint64 instruction, Dis_info *info); - std::string XOR_32_(uint64 instruction, Dis_info *info); - std::string XORI(uint64 instruction, Dis_info *info); - std::string YIELD(uint64 instruction, Dis_info *info); - static Pool P_SYSCALL[2]; static Pool P_RI[4]; static Pool P_ADDIU[2]; From a146549034a67234d7b8c5aa66cc2552989c630a Mon Sep 17 00:00:00 2001 From: Milica Lazarevic Date: Mon, 12 Sep 2022 14:26:19 +0200 Subject: [PATCH 429/705] disas/nanomips: Remove Pool tables from the class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pool tables are no longer declared as static fields of the NMD class but as global static const variables. Pool struct is defined outside of the class. The NMD::Disassemble method is using the MAJOR Pool table variable, so its implementation is moved to the end of the nanomips.cpp file, right after the initialization of the MAJOR Pool table. Signed-off-by: Milica Lazarevic Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20220912122635.74032-9-milica.lazarevic@syrmia.com> Signed-off-by: Philippe Mathieu-Daudé --- disas/nanomips.cpp | 363 ++++++++++++++++++++++----------------------- disas/nanomips.h | 201 ++----------------------- 2 files changed, 193 insertions(+), 371 deletions(-) diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp index 5482284206..a73eae5b33 100644 --- a/disas/nanomips.cpp +++ b/disas/nanomips.cpp @@ -754,13 +754,6 @@ uint64 NMD::extract_op_code_value(const uint16 * data, int size) } -int NMD::Disassemble(const uint16 * data, std::string & dis, - TABLE_ENTRY_TYPE & type, Dis_info *info) -{ - return Disassemble(data, dis, type, MAJOR, 2, info); -} - - /* * Recurse through tables until the instruction is found then return * the string and size @@ -16661,7 +16654,7 @@ static std::string YIELD(uint64 instruction, Dis_info *info) * */ -NMD::Pool NMD::P_SYSCALL[2] = { +static const Pool P_SYSCALL[2] = { { instruction , 0 , 0 , 32, 0xfffc0000, 0x00080000, &SYSCALL_32_ , 0, 0x0 }, /* SYSCALL[32] */ @@ -16671,7 +16664,7 @@ NMD::Pool NMD::P_SYSCALL[2] = { }; -NMD::Pool NMD::P_RI[4] = { +static const Pool P_RI[4] = { { instruction , 0 , 0 , 32, 0xfff80000, 0x00000000, &SIGRIE , 0, 0x0 }, /* SIGRIE */ @@ -16687,7 +16680,7 @@ NMD::Pool NMD::P_RI[4] = { }; -NMD::Pool NMD::P_ADDIU[2] = { +static const Pool P_ADDIU[2] = { { pool , P_RI , 4 , 32, 0xffe00000, 0x00000000, 0 , 0, 0x0 }, /* P.RI */ @@ -16697,7 +16690,7 @@ NMD::Pool NMD::P_ADDIU[2] = { }; -NMD::Pool NMD::P_TRAP[2] = { +static const Pool P_TRAP[2] = { { instruction , 0 , 0 , 32, 0xfc0007ff, 0x20000000, &TEQ , 0, XMMS_ }, /* TEQ */ @@ -16707,7 +16700,7 @@ NMD::Pool NMD::P_TRAP[2] = { }; -NMD::Pool NMD::P_CMOVE[2] = { +static const Pool P_CMOVE[2] = { { instruction , 0 , 0 , 32, 0xfc0007ff, 0x20000210, &MOVZ , 0, 0x0 }, /* MOVZ */ @@ -16717,7 +16710,7 @@ NMD::Pool NMD::P_CMOVE[2] = { }; -NMD::Pool NMD::P_D_MT_VPE[2] = { +static const Pool P_D_MT_VPE[2] = { { instruction , 0 , 0 , 32, 0xfc1f3fff, 0x20010ab0, &DMT , 0, MT_ }, /* DMT */ @@ -16727,7 +16720,7 @@ NMD::Pool NMD::P_D_MT_VPE[2] = { }; -NMD::Pool NMD::P_E_MT_VPE[2] = { +static const Pool P_E_MT_VPE[2] = { { instruction , 0 , 0 , 32, 0xfc1f3fff, 0x20010eb0, &EMT , 0, MT_ }, /* EMT */ @@ -16737,7 +16730,7 @@ NMD::Pool NMD::P_E_MT_VPE[2] = { }; -NMD::Pool NMD::_P_MT_VPE[2] = { +static const Pool _P_MT_VPE[2] = { { pool , P_D_MT_VPE , 2 , 32, 0xfc003fff, 0x20000ab0, 0 , 0, 0x0 }, /* P.D_MT_VPE */ @@ -16747,7 +16740,7 @@ NMD::Pool NMD::_P_MT_VPE[2] = { }; -NMD::Pool NMD::P_MT_VPE[8] = { +static const Pool P_MT_VPE[8] = { { reserved_block , 0 , 0 , 32, 0xfc003bff, 0x200002b0, 0 , 0, 0x0 }, /* P.MT_VPE~*(0) */ @@ -16775,7 +16768,7 @@ NMD::Pool NMD::P_MT_VPE[8] = { }; -NMD::Pool NMD::P_DVP[2] = { +static const Pool P_DVP[2] = { { instruction , 0 , 0 , 32, 0xfc00ffff, 0x20000390, &DVP , 0, 0x0 }, /* DVP */ @@ -16785,7 +16778,7 @@ NMD::Pool NMD::P_DVP[2] = { }; -NMD::Pool NMD::P_SLTU[2] = { +static const Pool P_SLTU[2] = { { pool , P_DVP , 2 , 32, 0xfc00fbff, 0x20000390, 0 , 0, 0x0 }, /* P.DVP */ @@ -16795,7 +16788,7 @@ NMD::Pool NMD::P_SLTU[2] = { }; -NMD::Pool NMD::_POOL32A0[128] = { +static const Pool _POOL32A0[128] = { { pool , P_TRAP , 2 , 32, 0xfc0003ff, 0x20000000, 0 , 0, 0x0 }, /* P.TRAP */ @@ -17183,7 +17176,7 @@ NMD::Pool NMD::_POOL32A0[128] = { }; -NMD::Pool NMD::ADDQ__S__PH[2] = { +static const Pool ADDQ__S__PH[2] = { { instruction , 0 , 0 , 32, 0xfc0007ff, 0x2000000d, &ADDQ_PH , 0, DSP_ }, /* ADDQ.PH */ @@ -17193,7 +17186,7 @@ NMD::Pool NMD::ADDQ__S__PH[2] = { }; -NMD::Pool NMD::MUL__S__PH[2] = { +static const Pool MUL__S__PH[2] = { { instruction , 0 , 0 , 32, 0xfc0007ff, 0x2000002d, &MUL_PH , 0, DSP_ }, /* MUL.PH */ @@ -17203,7 +17196,7 @@ NMD::Pool NMD::MUL__S__PH[2] = { }; -NMD::Pool NMD::ADDQH__R__PH[2] = { +static const Pool ADDQH__R__PH[2] = { { instruction , 0 , 0 , 32, 0xfc0007ff, 0x2000004d, &ADDQH_PH , 0, DSP_ }, /* ADDQH.PH */ @@ -17213,7 +17206,7 @@ NMD::Pool NMD::ADDQH__R__PH[2] = { }; -NMD::Pool NMD::ADDQH__R__W[2] = { +static const Pool ADDQH__R__W[2] = { { instruction , 0 , 0 , 32, 0xfc0007ff, 0x2000008d, &ADDQH_W , 0, DSP_ }, /* ADDQH.W */ @@ -17223,7 +17216,7 @@ NMD::Pool NMD::ADDQH__R__W[2] = { }; -NMD::Pool NMD::ADDU__S__QB[2] = { +static const Pool ADDU__S__QB[2] = { { instruction , 0 , 0 , 32, 0xfc0007ff, 0x200000cd, &ADDU_QB , 0, DSP_ }, /* ADDU.QB */ @@ -17233,7 +17226,7 @@ NMD::Pool NMD::ADDU__S__QB[2] = { }; -NMD::Pool NMD::ADDU__S__PH[2] = { +static const Pool ADDU__S__PH[2] = { { instruction , 0 , 0 , 32, 0xfc0007ff, 0x2000010d, &ADDU_PH , 0, DSP_ }, /* ADDU.PH */ @@ -17243,7 +17236,7 @@ NMD::Pool NMD::ADDU__S__PH[2] = { }; -NMD::Pool NMD::ADDUH__R__QB[2] = { +static const Pool ADDUH__R__QB[2] = { { instruction , 0 , 0 , 32, 0xfc0007ff, 0x2000014d, &ADDUH_QB , 0, DSP_ }, /* ADDUH.QB */ @@ -17253,7 +17246,7 @@ NMD::Pool NMD::ADDUH__R__QB[2] = { }; -NMD::Pool NMD::SHRAV__R__PH[2] = { +static const Pool SHRAV__R__PH[2] = { { instruction , 0 , 0 , 32, 0xfc0007ff, 0x2000018d, &SHRAV_PH , 0, DSP_ }, /* SHRAV.PH */ @@ -17263,7 +17256,7 @@ NMD::Pool NMD::SHRAV__R__PH[2] = { }; -NMD::Pool NMD::SHRAV__R__QB[2] = { +static const Pool SHRAV__R__QB[2] = { { instruction , 0 , 0 , 32, 0xfc0007ff, 0x200001cd, &SHRAV_QB , 0, DSP_ }, /* SHRAV.QB */ @@ -17273,7 +17266,7 @@ NMD::Pool NMD::SHRAV__R__QB[2] = { }; -NMD::Pool NMD::SUBQ__S__PH[2] = { +static const Pool SUBQ__S__PH[2] = { { instruction , 0 , 0 , 32, 0xfc0007ff, 0x2000020d, &SUBQ_PH , 0, DSP_ }, /* SUBQ.PH */ @@ -17283,7 +17276,7 @@ NMD::Pool NMD::SUBQ__S__PH[2] = { }; -NMD::Pool NMD::SUBQH__R__PH[2] = { +static const Pool SUBQH__R__PH[2] = { { instruction , 0 , 0 , 32, 0xfc0007ff, 0x2000024d, &SUBQH_PH , 0, DSP_ }, /* SUBQH.PH */ @@ -17293,7 +17286,7 @@ NMD::Pool NMD::SUBQH__R__PH[2] = { }; -NMD::Pool NMD::SUBQH__R__W[2] = { +static const Pool SUBQH__R__W[2] = { { instruction , 0 , 0 , 32, 0xfc0007ff, 0x2000028d, &SUBQH_W , 0, DSP_ }, /* SUBQH.W */ @@ -17303,7 +17296,7 @@ NMD::Pool NMD::SUBQH__R__W[2] = { }; -NMD::Pool NMD::SUBU__S__QB[2] = { +static const Pool SUBU__S__QB[2] = { { instruction , 0 , 0 , 32, 0xfc0007ff, 0x200002cd, &SUBU_QB , 0, DSP_ }, /* SUBU.QB */ @@ -17313,7 +17306,7 @@ NMD::Pool NMD::SUBU__S__QB[2] = { }; -NMD::Pool NMD::SUBU__S__PH[2] = { +static const Pool SUBU__S__PH[2] = { { instruction , 0 , 0 , 32, 0xfc0007ff, 0x2000030d, &SUBU_PH , 0, DSP_ }, /* SUBU.PH */ @@ -17323,7 +17316,7 @@ NMD::Pool NMD::SUBU__S__PH[2] = { }; -NMD::Pool NMD::SHRA__R__PH[2] = { +static const Pool SHRA__R__PH[2] = { { instruction , 0 , 0 , 32, 0xfc0007ff, 0x20000335, &SHRA_PH , 0, DSP_ }, /* SHRA.PH */ @@ -17333,7 +17326,7 @@ NMD::Pool NMD::SHRA__R__PH[2] = { }; -NMD::Pool NMD::SUBUH__R__QB[2] = { +static const Pool SUBUH__R__QB[2] = { { instruction , 0 , 0 , 32, 0xfc0007ff, 0x2000034d, &SUBUH_QB , 0, DSP_ }, /* SUBUH.QB */ @@ -17343,7 +17336,7 @@ NMD::Pool NMD::SUBUH__R__QB[2] = { }; -NMD::Pool NMD::SHLLV__S__PH[2] = { +static const Pool SHLLV__S__PH[2] = { { instruction , 0 , 0 , 32, 0xfc0007ff, 0x2000038d, &SHLLV_PH , 0, DSP_ }, /* SHLLV.PH */ @@ -17353,7 +17346,7 @@ NMD::Pool NMD::SHLLV__S__PH[2] = { }; -NMD::Pool NMD::SHLL__S__PH[4] = { +static const Pool SHLL__S__PH[4] = { { instruction , 0 , 0 , 32, 0xfc000fff, 0x200003b5, &SHLL_PH , 0, DSP_ }, /* SHLL.PH */ @@ -17369,7 +17362,7 @@ NMD::Pool NMD::SHLL__S__PH[4] = { }; -NMD::Pool NMD::PRECR_SRA__R__PH_W[2] = { +static const Pool PRECR_SRA__R__PH_W[2] = { { instruction , 0 , 0 , 32, 0xfc0007ff, 0x200003cd, &PRECR_SRA_PH_W , 0, DSP_ }, /* PRECR_SRA.PH.W */ @@ -17379,7 +17372,7 @@ NMD::Pool NMD::PRECR_SRA__R__PH_W[2] = { }; -NMD::Pool NMD::_POOL32A5[128] = { +static const Pool _POOL32A5[128] = { { instruction , 0 , 0 , 32, 0xfc0003ff, 0x20000005, &CMP_EQ_PH , 0, DSP_ }, /* CMP.EQ.PH */ @@ -17767,7 +17760,7 @@ NMD::Pool NMD::_POOL32A5[128] = { }; -NMD::Pool NMD::PP_LSX[16] = { +static const Pool PP_LSX[16] = { { instruction , 0 , 0 , 32, 0xfc0007ff, 0x20000007, &LBX , 0, 0x0 }, /* LBX */ @@ -17819,7 +17812,7 @@ NMD::Pool NMD::PP_LSX[16] = { }; -NMD::Pool NMD::PP_LSXS[16] = { +static const Pool PP_LSXS[16] = { { reserved_block , 0 , 0 , 32, 0xfc0007ff, 0x20000047, 0 , 0, 0x0 }, /* PP.LSXS~*(0) */ @@ -17871,7 +17864,7 @@ NMD::Pool NMD::PP_LSXS[16] = { }; -NMD::Pool NMD::P_LSX[2] = { +static const Pool P_LSX[2] = { { pool , PP_LSX , 16 , 32, 0xfc00007f, 0x20000007, 0 , 0, 0x0 }, /* PP.LSX */ @@ -17881,7 +17874,7 @@ NMD::Pool NMD::P_LSX[2] = { }; -NMD::Pool NMD::POOL32Axf_1_0[4] = { +static const Pool POOL32Axf_1_0[4] = { { instruction , 0 , 0 , 32, 0xfc003fff, 0x2000007f, &MFHI_DSP_ , 0, DSP_ }, /* MFHI[DSP] */ @@ -17897,7 +17890,7 @@ NMD::Pool NMD::POOL32Axf_1_0[4] = { }; -NMD::Pool NMD::POOL32Axf_1_1[4] = { +static const Pool POOL32Axf_1_1[4] = { { instruction , 0 , 0 , 32, 0xfc003fff, 0x2000027f, &MTHLIP , 0, DSP_ }, /* MTHLIP */ @@ -17913,7 +17906,7 @@ NMD::Pool NMD::POOL32Axf_1_1[4] = { }; -NMD::Pool NMD::POOL32Axf_1_3[4] = { +static const Pool POOL32Axf_1_3[4] = { { instruction , 0 , 0 , 32, 0xfc003fff, 0x2000067f, &RDDSP , 0, DSP_ }, /* RDDSP */ @@ -17929,7 +17922,7 @@ NMD::Pool NMD::POOL32Axf_1_3[4] = { }; -NMD::Pool NMD::POOL32Axf_1_4[2] = { +static const Pool POOL32Axf_1_4[2] = { { instruction , 0 , 0 , 32, 0xfc001fff, 0x2000087f, &SHLL_QB , 0, DSP_ }, /* SHLL.QB */ @@ -17939,7 +17932,7 @@ NMD::Pool NMD::POOL32Axf_1_4[2] = { }; -NMD::Pool NMD::MAQ_S_A__W_PHR[2] = { +static const Pool MAQ_S_A__W_PHR[2] = { { instruction , 0 , 0 , 32, 0xfc003fff, 0x20000a7f, &MAQ_S_W_PHR , 0, DSP_ }, /* MAQ_S.W.PHR */ @@ -17949,7 +17942,7 @@ NMD::Pool NMD::MAQ_S_A__W_PHR[2] = { }; -NMD::Pool NMD::MAQ_S_A__W_PHL[2] = { +static const Pool MAQ_S_A__W_PHL[2] = { { instruction , 0 , 0 , 32, 0xfc003fff, 0x20001a7f, &MAQ_S_W_PHL , 0, DSP_ }, /* MAQ_S.W.PHL */ @@ -17959,7 +17952,7 @@ NMD::Pool NMD::MAQ_S_A__W_PHL[2] = { }; -NMD::Pool NMD::POOL32Axf_1_5[2] = { +static const Pool POOL32Axf_1_5[2] = { { pool , MAQ_S_A__W_PHR , 2 , 32, 0xfc001fff, 0x20000a7f, 0 , 0, 0x0 }, /* MAQ_S[A].W.PHR */ @@ -17969,7 +17962,7 @@ NMD::Pool NMD::POOL32Axf_1_5[2] = { }; -NMD::Pool NMD::POOL32Axf_1_7[4] = { +static const Pool POOL32Axf_1_7[4] = { { instruction , 0 , 0 , 32, 0xfc003fff, 0x20000e7f, &EXTR_W , 0, DSP_ }, /* EXTR.W */ @@ -17985,7 +17978,7 @@ NMD::Pool NMD::POOL32Axf_1_7[4] = { }; -NMD::Pool NMD::POOL32Axf_1[8] = { +static const Pool POOL32Axf_1[8] = { { pool , POOL32Axf_1_0 , 4 , 32, 0xfc000fff, 0x2000007f, 0 , 0, 0x0 }, /* POOL32Axf_1_0 */ @@ -18013,7 +18006,7 @@ NMD::Pool NMD::POOL32Axf_1[8] = { }; -NMD::Pool NMD::POOL32Axf_2_DSP__0_7[8] = { +static const Pool POOL32Axf_2_DSP__0_7[8] = { { instruction , 0 , 0 , 32, 0xfc003fff, 0x200000bf, &DPA_W_PH , 0, DSP_ }, /* DPA.W.PH */ @@ -18041,7 +18034,7 @@ NMD::Pool NMD::POOL32Axf_2_DSP__0_7[8] = { }; -NMD::Pool NMD::POOL32Axf_2_DSP__8_15[8] = { +static const Pool POOL32Axf_2_DSP__8_15[8] = { { instruction , 0 , 0 , 32, 0xfc003fff, 0x200010bf, &DPAX_W_PH , 0, DSP_ }, /* DPAX.W.PH */ @@ -18069,7 +18062,7 @@ NMD::Pool NMD::POOL32Axf_2_DSP__8_15[8] = { }; -NMD::Pool NMD::POOL32Axf_2_DSP__16_23[8] = { +static const Pool POOL32Axf_2_DSP__16_23[8] = { { instruction , 0 , 0 , 32, 0xfc003fff, 0x200020bf, &DPAU_H_QBL , 0, DSP_ }, /* DPAU.H.QBL */ @@ -18097,7 +18090,7 @@ NMD::Pool NMD::POOL32Axf_2_DSP__16_23[8] = { }; -NMD::Pool NMD::POOL32Axf_2_DSP__24_31[8] = { +static const Pool POOL32Axf_2_DSP__24_31[8] = { { instruction , 0 , 0 , 32, 0xfc003fff, 0x200030bf, &DPAU_H_QBR , 0, DSP_ }, /* DPAU.H.QBR */ @@ -18125,7 +18118,7 @@ NMD::Pool NMD::POOL32Axf_2_DSP__24_31[8] = { }; -NMD::Pool NMD::POOL32Axf_2[4] = { +static const Pool POOL32Axf_2[4] = { { pool , POOL32Axf_2_DSP__0_7, 8 , 32, 0xfc0031ff, 0x200000bf, 0 , 0, 0x0 }, /* POOL32Axf_2(DSP)_0_7 */ @@ -18141,7 +18134,7 @@ NMD::Pool NMD::POOL32Axf_2[4] = { }; -NMD::Pool NMD::POOL32Axf_4[128] = { +static const Pool POOL32Axf_4[128] = { { instruction , 0 , 0 , 32, 0xfc00ffff, 0x2000013f, &ABSQ_S_QB , 0, DSP_ }, /* ABSQ_S.QB */ @@ -18529,7 +18522,7 @@ NMD::Pool NMD::POOL32Axf_4[128] = { }; -NMD::Pool NMD::POOL32Axf_5_group0[32] = { +static const Pool POOL32Axf_5_group0[32] = { { instruction , 0 , 0 , 32, 0xfc00ffff, 0x2000017f, &TLBGP , 0, CP0_ | VZ_ | TLB_ }, /* TLBGP */ @@ -18629,7 +18622,7 @@ NMD::Pool NMD::POOL32Axf_5_group0[32] = { }; -NMD::Pool NMD::POOL32Axf_5_group1[32] = { +static const Pool POOL32Axf_5_group1[32] = { { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000417f, 0 , 0, 0x0 }, /* POOL32Axf_5_group1~*(0) */ @@ -18729,7 +18722,7 @@ NMD::Pool NMD::POOL32Axf_5_group1[32] = { }; -NMD::Pool NMD::ERETx[2] = { +static const Pool ERETx[2] = { { instruction , 0 , 0 , 32, 0xfc01ffff, 0x2000f37f, &ERET , 0, 0x0 }, /* ERET */ @@ -18739,7 +18732,7 @@ NMD::Pool NMD::ERETx[2] = { }; -NMD::Pool NMD::POOL32Axf_5_group3[32] = { +static const Pool POOL32Axf_5_group3[32] = { { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000c17f, 0 , 0, 0x0 }, /* POOL32Axf_5_group3~*(0) */ @@ -18839,7 +18832,7 @@ NMD::Pool NMD::POOL32Axf_5_group3[32] = { }; -NMD::Pool NMD::POOL32Axf_5[4] = { +static const Pool POOL32Axf_5[4] = { { pool , POOL32Axf_5_group0 , 32 , 32, 0xfc00c1ff, 0x2000017f, 0 , 0, 0x0 }, /* POOL32Axf_5_group0 */ @@ -18855,7 +18848,7 @@ NMD::Pool NMD::POOL32Axf_5[4] = { }; -NMD::Pool NMD::SHRA__R__QB[2] = { +static const Pool SHRA__R__QB[2] = { { instruction , 0 , 0 , 32, 0xfc001fff, 0x200001ff, &SHRA_QB , 0, DSP_ }, /* SHRA.QB */ @@ -18865,7 +18858,7 @@ NMD::Pool NMD::SHRA__R__QB[2] = { }; -NMD::Pool NMD::POOL32Axf_7[8] = { +static const Pool POOL32Axf_7[8] = { { pool , SHRA__R__QB , 2 , 32, 0xfc000fff, 0x200001ff, 0 , 0, 0x0 }, /* SHRA[_R].QB */ @@ -18893,7 +18886,7 @@ NMD::Pool NMD::POOL32Axf_7[8] = { }; -NMD::Pool NMD::POOL32Axf[8] = { +static const Pool POOL32Axf[8] = { { reserved_block , 0 , 0 , 32, 0xfc0001ff, 0x2000003f, 0 , 0, 0x0 }, /* POOL32Axf~*(0) */ @@ -18921,7 +18914,7 @@ NMD::Pool NMD::POOL32Axf[8] = { }; -NMD::Pool NMD::_POOL32A7[8] = { +static const Pool _POOL32A7[8] = { { pool , P_LSX , 2 , 32, 0xfc00003f, 0x20000007, 0 , 0, 0x0 }, /* P.LSX */ @@ -18949,7 +18942,7 @@ NMD::Pool NMD::_POOL32A7[8] = { }; -NMD::Pool NMD::P32A[8] = { +static const Pool P32A[8] = { { pool , _POOL32A0 , 128 , 32, 0xfc000007, 0x20000000, 0 , 0, 0x0 }, /* _POOL32A0 */ @@ -18977,7 +18970,7 @@ NMD::Pool NMD::P32A[8] = { }; -NMD::Pool NMD::P_GP_D[2] = { +static const Pool P_GP_D[2] = { { instruction , 0 , 0 , 32, 0xfc000007, 0x40000001, &LD_GP_ , 0, MIPS64_ }, /* LD[GP] */ @@ -18987,7 +18980,7 @@ NMD::Pool NMD::P_GP_D[2] = { }; -NMD::Pool NMD::P_GP_W[4] = { +static const Pool P_GP_W[4] = { { instruction , 0 , 0 , 32, 0xfc000003, 0x40000000, &ADDIU_GP_W_ , 0, 0x0 }, /* ADDIU[GP.W] */ @@ -19003,7 +18996,7 @@ NMD::Pool NMD::P_GP_W[4] = { }; -NMD::Pool NMD::POOL48I[32] = { +static const Pool POOL48I[32] = { { instruction , 0 , 0 , 48, 0xfc1f00000000ull, 0x600000000000ull, &LI_48_ , 0, XMMS_ }, /* LI[48] */ @@ -19103,7 +19096,7 @@ NMD::Pool NMD::POOL48I[32] = { }; -NMD::Pool NMD::PP_SR[4] = { +static const Pool PP_SR[4] = { { instruction , 0 , 0 , 32, 0xfc10f003, 0x80003000, &SAVE_32_ , 0, 0x0 }, /* SAVE[32] */ @@ -19119,7 +19112,7 @@ NMD::Pool NMD::PP_SR[4] = { }; -NMD::Pool NMD::P_SR_F[8] = { +static const Pool P_SR_F[8] = { { instruction , 0 , 0 , 32, 0xfc10f007, 0x80103000, &SAVEF , 0, CP1_ }, /* SAVEF */ @@ -19147,7 +19140,7 @@ NMD::Pool NMD::P_SR_F[8] = { }; -NMD::Pool NMD::P_SR[2] = { +static const Pool P_SR[2] = { { pool , PP_SR , 4 , 32, 0xfc10f000, 0x80003000, 0 , 0, 0x0 }, /* PP.SR */ @@ -19157,7 +19150,7 @@ NMD::Pool NMD::P_SR[2] = { }; -NMD::Pool NMD::P_SLL[5] = { +static const Pool P_SLL[5] = { { instruction , 0 , 0 , 32, 0xffe0f1ff, 0x8000c000, &NOP_32_ , 0, 0x0 }, /* NOP[32] */ @@ -19176,7 +19169,7 @@ NMD::Pool NMD::P_SLL[5] = { }; -NMD::Pool NMD::P_SHIFT[16] = { +static const Pool P_SHIFT[16] = { { pool , P_SLL , 5 , 32, 0xfc00f1e0, 0x8000c000, 0 , 0, 0x0 }, /* P.SLL */ @@ -19228,7 +19221,7 @@ NMD::Pool NMD::P_SHIFT[16] = { }; -NMD::Pool NMD::P_ROTX[4] = { +static const Pool P_ROTX[4] = { { instruction , 0 , 0 , 32, 0xfc00f820, 0x8000d000, &ROTX , 0, XMMS_ }, /* ROTX */ @@ -19244,7 +19237,7 @@ NMD::Pool NMD::P_ROTX[4] = { }; -NMD::Pool NMD::P_INS[4] = { +static const Pool P_INS[4] = { { instruction , 0 , 0 , 32, 0xfc00f820, 0x8000e000, &INS , 0, XMMS_ }, /* INS */ @@ -19260,7 +19253,7 @@ NMD::Pool NMD::P_INS[4] = { }; -NMD::Pool NMD::P_EXT[4] = { +static const Pool P_EXT[4] = { { instruction , 0 , 0 , 32, 0xfc00f820, 0x8000f000, &EXT , 0, XMMS_ }, /* EXT */ @@ -19276,7 +19269,7 @@ NMD::Pool NMD::P_EXT[4] = { }; -NMD::Pool NMD::P_U12[16] = { +static const Pool P_U12[16] = { { instruction , 0 , 0 , 32, 0xfc00f000, 0x80000000, &ORI , 0, 0x0 }, /* ORI */ @@ -19328,7 +19321,7 @@ NMD::Pool NMD::P_U12[16] = { }; -NMD::Pool NMD::RINT_fmt[2] = { +static const Pool RINT_fmt[2] = { { instruction , 0 , 0 , 32, 0xfc0003ff, 0xa0000020, &RINT_S , 0, CP1_ }, /* RINT.S */ @@ -19338,7 +19331,7 @@ NMD::Pool NMD::RINT_fmt[2] = { }; -NMD::Pool NMD::ADD_fmt0[2] = { +static const Pool ADD_fmt0[2] = { { instruction , 0 , 0 , 32, 0xfc0003ff, 0xa0000030, &ADD_S , 0, CP1_ }, /* ADD.S */ @@ -19348,7 +19341,7 @@ NMD::Pool NMD::ADD_fmt0[2] = { }; -NMD::Pool NMD::SELEQZ_fmt[2] = { +static const Pool SELEQZ_fmt[2] = { { instruction , 0 , 0 , 32, 0xfc0003ff, 0xa0000038, &SELEQZ_S , 0, CP1_ }, /* SELEQZ.S */ @@ -19358,7 +19351,7 @@ NMD::Pool NMD::SELEQZ_fmt[2] = { }; -NMD::Pool NMD::CLASS_fmt[2] = { +static const Pool CLASS_fmt[2] = { { instruction , 0 , 0 , 32, 0xfc0003ff, 0xa0000060, &CLASS_S , 0, CP1_ }, /* CLASS.S */ @@ -19368,7 +19361,7 @@ NMD::Pool NMD::CLASS_fmt[2] = { }; -NMD::Pool NMD::SUB_fmt0[2] = { +static const Pool SUB_fmt0[2] = { { instruction , 0 , 0 , 32, 0xfc0003ff, 0xa0000070, &SUB_S , 0, CP1_ }, /* SUB.S */ @@ -19378,7 +19371,7 @@ NMD::Pool NMD::SUB_fmt0[2] = { }; -NMD::Pool NMD::SELNEZ_fmt[2] = { +static const Pool SELNEZ_fmt[2] = { { instruction , 0 , 0 , 32, 0xfc0003ff, 0xa0000078, &SELNEZ_S , 0, CP1_ }, /* SELNEZ.S */ @@ -19388,7 +19381,7 @@ NMD::Pool NMD::SELNEZ_fmt[2] = { }; -NMD::Pool NMD::MUL_fmt0[2] = { +static const Pool MUL_fmt0[2] = { { instruction , 0 , 0 , 32, 0xfc0003ff, 0xa00000b0, &MUL_S , 0, CP1_ }, /* MUL.S */ @@ -19398,7 +19391,7 @@ NMD::Pool NMD::MUL_fmt0[2] = { }; -NMD::Pool NMD::SEL_fmt[2] = { +static const Pool SEL_fmt[2] = { { instruction , 0 , 0 , 32, 0xfc0003ff, 0xa00000b8, &SEL_S , 0, CP1_ }, /* SEL.S */ @@ -19408,7 +19401,7 @@ NMD::Pool NMD::SEL_fmt[2] = { }; -NMD::Pool NMD::DIV_fmt0[2] = { +static const Pool DIV_fmt0[2] = { { instruction , 0 , 0 , 32, 0xfc0003ff, 0xa00000f0, &DIV_S , 0, CP1_ }, /* DIV.S */ @@ -19418,7 +19411,7 @@ NMD::Pool NMD::DIV_fmt0[2] = { }; -NMD::Pool NMD::ADD_fmt1[2] = { +static const Pool ADD_fmt1[2] = { { instruction , 0 , 0 , 32, 0xfc0003ff, 0xa0000130, &ADD_D , 0, CP1_ }, /* ADD.D */ @@ -19428,7 +19421,7 @@ NMD::Pool NMD::ADD_fmt1[2] = { }; -NMD::Pool NMD::SUB_fmt1[2] = { +static const Pool SUB_fmt1[2] = { { instruction , 0 , 0 , 32, 0xfc0003ff, 0xa0000170, &SUB_D , 0, CP1_ }, /* SUB.D */ @@ -19438,7 +19431,7 @@ NMD::Pool NMD::SUB_fmt1[2] = { }; -NMD::Pool NMD::MUL_fmt1[2] = { +static const Pool MUL_fmt1[2] = { { instruction , 0 , 0 , 32, 0xfc0003ff, 0xa00001b0, &MUL_D , 0, CP1_ }, /* MUL.D */ @@ -19448,7 +19441,7 @@ NMD::Pool NMD::MUL_fmt1[2] = { }; -NMD::Pool NMD::MADDF_fmt[2] = { +static const Pool MADDF_fmt[2] = { { instruction , 0 , 0 , 32, 0xfc0003ff, 0xa00001b8, &MADDF_S , 0, CP1_ }, /* MADDF.S */ @@ -19458,7 +19451,7 @@ NMD::Pool NMD::MADDF_fmt[2] = { }; -NMD::Pool NMD::DIV_fmt1[2] = { +static const Pool DIV_fmt1[2] = { { instruction , 0 , 0 , 32, 0xfc0003ff, 0xa00001f0, &DIV_D , 0, CP1_ }, /* DIV.D */ @@ -19468,7 +19461,7 @@ NMD::Pool NMD::DIV_fmt1[2] = { }; -NMD::Pool NMD::MSUBF_fmt[2] = { +static const Pool MSUBF_fmt[2] = { { instruction , 0 , 0 , 32, 0xfc0003ff, 0xa00001f8, &MSUBF_S , 0, CP1_ }, /* MSUBF.S */ @@ -19478,7 +19471,7 @@ NMD::Pool NMD::MSUBF_fmt[2] = { }; -NMD::Pool NMD::POOL32F_0[64] = { +static const Pool POOL32F_0[64] = { { reserved_block , 0 , 0 , 32, 0xfc0001ff, 0xa0000000, 0 , 0, CP1_ }, /* POOL32F_0~*(0) */ @@ -19674,7 +19667,7 @@ NMD::Pool NMD::POOL32F_0[64] = { }; -NMD::Pool NMD::MIN_fmt[2] = { +static const Pool MIN_fmt[2] = { { instruction , 0 , 0 , 32, 0xfc00023f, 0xa0000003, &MIN_S , 0, CP1_ }, /* MIN.S */ @@ -19684,7 +19677,7 @@ NMD::Pool NMD::MIN_fmt[2] = { }; -NMD::Pool NMD::MAX_fmt[2] = { +static const Pool MAX_fmt[2] = { { instruction , 0 , 0 , 32, 0xfc00023f, 0xa000000b, &MAX_S , 0, CP1_ }, /* MAX.S */ @@ -19694,7 +19687,7 @@ NMD::Pool NMD::MAX_fmt[2] = { }; -NMD::Pool NMD::MINA_fmt[2] = { +static const Pool MINA_fmt[2] = { { instruction , 0 , 0 , 32, 0xfc00023f, 0xa0000023, &MINA_S , 0, CP1_ }, /* MINA.S */ @@ -19704,7 +19697,7 @@ NMD::Pool NMD::MINA_fmt[2] = { }; -NMD::Pool NMD::MAXA_fmt[2] = { +static const Pool MAXA_fmt[2] = { { instruction , 0 , 0 , 32, 0xfc00023f, 0xa000002b, &MAXA_S , 0, CP1_ }, /* MAXA.S */ @@ -19714,7 +19707,7 @@ NMD::Pool NMD::MAXA_fmt[2] = { }; -NMD::Pool NMD::CVT_L_fmt[2] = { +static const Pool CVT_L_fmt[2] = { { instruction , 0 , 0 , 32, 0xfc007fff, 0xa000013b, &CVT_L_S , 0, CP1_ }, /* CVT.L.S */ @@ -19724,7 +19717,7 @@ NMD::Pool NMD::CVT_L_fmt[2] = { }; -NMD::Pool NMD::RSQRT_fmt[2] = { +static const Pool RSQRT_fmt[2] = { { instruction , 0 , 0 , 32, 0xfc007fff, 0xa000023b, &RSQRT_S , 0, CP1_ }, /* RSQRT.S */ @@ -19734,7 +19727,7 @@ NMD::Pool NMD::RSQRT_fmt[2] = { }; -NMD::Pool NMD::FLOOR_L_fmt[2] = { +static const Pool FLOOR_L_fmt[2] = { { instruction , 0 , 0 , 32, 0xfc007fff, 0xa000033b, &FLOOR_L_S , 0, CP1_ }, /* FLOOR.L.S */ @@ -19744,7 +19737,7 @@ NMD::Pool NMD::FLOOR_L_fmt[2] = { }; -NMD::Pool NMD::CVT_W_fmt[2] = { +static const Pool CVT_W_fmt[2] = { { instruction , 0 , 0 , 32, 0xfc007fff, 0xa000093b, &CVT_W_S , 0, CP1_ }, /* CVT.W.S */ @@ -19754,7 +19747,7 @@ NMD::Pool NMD::CVT_W_fmt[2] = { }; -NMD::Pool NMD::SQRT_fmt[2] = { +static const Pool SQRT_fmt[2] = { { instruction , 0 , 0 , 32, 0xfc007fff, 0xa0000a3b, &SQRT_S , 0, CP1_ }, /* SQRT.S */ @@ -19764,7 +19757,7 @@ NMD::Pool NMD::SQRT_fmt[2] = { }; -NMD::Pool NMD::FLOOR_W_fmt[2] = { +static const Pool FLOOR_W_fmt[2] = { { instruction , 0 , 0 , 32, 0xfc007fff, 0xa0000b3b, &FLOOR_W_S , 0, CP1_ }, /* FLOOR.W.S */ @@ -19774,7 +19767,7 @@ NMD::Pool NMD::FLOOR_W_fmt[2] = { }; -NMD::Pool NMD::RECIP_fmt[2] = { +static const Pool RECIP_fmt[2] = { { instruction , 0 , 0 , 32, 0xfc007fff, 0xa000123b, &RECIP_S , 0, CP1_ }, /* RECIP.S */ @@ -19784,7 +19777,7 @@ NMD::Pool NMD::RECIP_fmt[2] = { }; -NMD::Pool NMD::CEIL_L_fmt[2] = { +static const Pool CEIL_L_fmt[2] = { { instruction , 0 , 0 , 32, 0xfc007fff, 0xa000133b, &CEIL_L_S , 0, CP1_ }, /* CEIL.L.S */ @@ -19794,7 +19787,7 @@ NMD::Pool NMD::CEIL_L_fmt[2] = { }; -NMD::Pool NMD::CEIL_W_fmt[2] = { +static const Pool CEIL_W_fmt[2] = { { instruction , 0 , 0 , 32, 0xfc007fff, 0xa0001b3b, &CEIL_W_S , 0, CP1_ }, /* CEIL.W.S */ @@ -19804,7 +19797,7 @@ NMD::Pool NMD::CEIL_W_fmt[2] = { }; -NMD::Pool NMD::TRUNC_L_fmt[2] = { +static const Pool TRUNC_L_fmt[2] = { { instruction , 0 , 0 , 32, 0xfc007fff, 0xa000233b, &TRUNC_L_S , 0, CP1_ }, /* TRUNC.L.S */ @@ -19814,7 +19807,7 @@ NMD::Pool NMD::TRUNC_L_fmt[2] = { }; -NMD::Pool NMD::TRUNC_W_fmt[2] = { +static const Pool TRUNC_W_fmt[2] = { { instruction , 0 , 0 , 32, 0xfc007fff, 0xa0002b3b, &TRUNC_W_S , 0, CP1_ }, /* TRUNC.W.S */ @@ -19824,7 +19817,7 @@ NMD::Pool NMD::TRUNC_W_fmt[2] = { }; -NMD::Pool NMD::ROUND_L_fmt[2] = { +static const Pool ROUND_L_fmt[2] = { { instruction , 0 , 0 , 32, 0xfc007fff, 0xa000333b, &ROUND_L_S , 0, CP1_ }, /* ROUND.L.S */ @@ -19834,7 +19827,7 @@ NMD::Pool NMD::ROUND_L_fmt[2] = { }; -NMD::Pool NMD::ROUND_W_fmt[2] = { +static const Pool ROUND_W_fmt[2] = { { instruction , 0 , 0 , 32, 0xfc007fff, 0xa0003b3b, &ROUND_W_S , 0, CP1_ }, /* ROUND.W.S */ @@ -19844,7 +19837,7 @@ NMD::Pool NMD::ROUND_W_fmt[2] = { }; -NMD::Pool NMD::POOL32Fxf_0[64] = { +static const Pool POOL32Fxf_0[64] = { { reserved_block , 0 , 0 , 32, 0xfc003fff, 0xa000003b, 0 , 0, CP1_ }, /* POOL32Fxf_0~*(0) */ @@ -20040,7 +20033,7 @@ NMD::Pool NMD::POOL32Fxf_0[64] = { }; -NMD::Pool NMD::MOV_fmt[4] = { +static const Pool MOV_fmt[4] = { { instruction , 0 , 0 , 32, 0xfc007fff, 0xa000007b, &MOV_S , 0, CP1_ }, /* MOV.S */ @@ -20056,7 +20049,7 @@ NMD::Pool NMD::MOV_fmt[4] = { }; -NMD::Pool NMD::ABS_fmt[4] = { +static const Pool ABS_fmt[4] = { { instruction , 0 , 0 , 32, 0xfc007fff, 0xa000037b, &ABS_S , 0, CP1_ }, /* ABS.S */ @@ -20072,7 +20065,7 @@ NMD::Pool NMD::ABS_fmt[4] = { }; -NMD::Pool NMD::NEG_fmt[4] = { +static const Pool NEG_fmt[4] = { { instruction , 0 , 0 , 32, 0xfc007fff, 0xa0000b7b, &NEG_S , 0, CP1_ }, /* NEG.S */ @@ -20088,7 +20081,7 @@ NMD::Pool NMD::NEG_fmt[4] = { }; -NMD::Pool NMD::CVT_D_fmt[4] = { +static const Pool CVT_D_fmt[4] = { { instruction , 0 , 0 , 32, 0xfc007fff, 0xa000137b, &CVT_D_S , 0, CP1_ }, /* CVT.D.S */ @@ -20104,7 +20097,7 @@ NMD::Pool NMD::CVT_D_fmt[4] = { }; -NMD::Pool NMD::CVT_S_fmt[4] = { +static const Pool CVT_S_fmt[4] = { { instruction , 0 , 0 , 32, 0xfc007fff, 0xa0001b7b, &CVT_S_D , 0, CP1_ }, /* CVT.S.D */ @@ -20120,7 +20113,7 @@ NMD::Pool NMD::CVT_S_fmt[4] = { }; -NMD::Pool NMD::POOL32Fxf_1[32] = { +static const Pool POOL32Fxf_1[32] = { { pool , MOV_fmt , 4 , 32, 0xfc001fff, 0xa000007b, 0 , 0, CP1_ }, /* MOV.fmt */ @@ -20220,7 +20213,7 @@ NMD::Pool NMD::POOL32Fxf_1[32] = { }; -NMD::Pool NMD::POOL32Fxf[4] = { +static const Pool POOL32Fxf[4] = { { pool , POOL32Fxf_0 , 64 , 32, 0xfc0000ff, 0xa000003b, 0 , 0, CP1_ }, /* POOL32Fxf_0 */ @@ -20236,7 +20229,7 @@ NMD::Pool NMD::POOL32Fxf[4] = { }; -NMD::Pool NMD::POOL32F_3[8] = { +static const Pool POOL32F_3[8] = { { pool , MIN_fmt , 2 , 32, 0xfc00003f, 0xa0000003, 0 , 0, CP1_ }, /* MIN.fmt */ @@ -20264,7 +20257,7 @@ NMD::Pool NMD::POOL32F_3[8] = { }; -NMD::Pool NMD::CMP_condn_S[32] = { +static const Pool CMP_condn_S[32] = { { instruction , 0 , 0 , 32, 0xfc0007ff, 0xa0000005, &CMP_AF_S , 0, CP1_ }, /* CMP.AF.S */ @@ -20364,7 +20357,7 @@ NMD::Pool NMD::CMP_condn_S[32] = { }; -NMD::Pool NMD::CMP_condn_D[32] = { +static const Pool CMP_condn_D[32] = { { instruction , 0 , 0 , 32, 0xfc0007ff, 0xa0000015, &CMP_AF_D , 0, CP1_ }, /* CMP.AF.D */ @@ -20464,7 +20457,7 @@ NMD::Pool NMD::CMP_condn_D[32] = { }; -NMD::Pool NMD::POOL32F_5[8] = { +static const Pool POOL32F_5[8] = { { pool , CMP_condn_S , 32 , 32, 0xfc00003f, 0xa0000005, 0 , 0, CP1_ }, /* CMP.condn.S */ @@ -20492,7 +20485,7 @@ NMD::Pool NMD::POOL32F_5[8] = { }; -NMD::Pool NMD::POOL32F[8] = { +static const Pool POOL32F[8] = { { pool , POOL32F_0 , 64 , 32, 0xfc000007, 0xa0000000, 0 , 0, CP1_ }, /* POOL32F_0 */ @@ -20520,7 +20513,7 @@ NMD::Pool NMD::POOL32F[8] = { }; -NMD::Pool NMD::POOL32S_0[64] = { +static const Pool POOL32S_0[64] = { { reserved_block , 0 , 0 , 32, 0xfc0001ff, 0xc0000000, 0 , 0, 0x0 }, /* POOL32S_0~*(0) */ @@ -20716,7 +20709,7 @@ NMD::Pool NMD::POOL32S_0[64] = { }; -NMD::Pool NMD::POOL32Sxf_4[128] = { +static const Pool POOL32Sxf_4[128] = { { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0xc000013c, 0 , 0, 0x0 }, /* POOL32Sxf_4~*(0) */ @@ -21104,7 +21097,7 @@ NMD::Pool NMD::POOL32Sxf_4[128] = { }; -NMD::Pool NMD::POOL32Sxf[8] = { +static const Pool POOL32Sxf[8] = { { reserved_block , 0 , 0 , 32, 0xfc0001ff, 0xc000003c, 0 , 0, 0x0 }, /* POOL32Sxf~*(0) */ @@ -21132,7 +21125,7 @@ NMD::Pool NMD::POOL32Sxf[8] = { }; -NMD::Pool NMD::POOL32S_4[8] = { +static const Pool POOL32S_4[8] = { { instruction , 0 , 0 , 32, 0xfc00003f, 0xc0000004, &EXTD , 0, MIPS64_ }, /* EXTD */ @@ -21160,7 +21153,7 @@ NMD::Pool NMD::POOL32S_4[8] = { }; -NMD::Pool NMD::POOL32S[8] = { +static const Pool POOL32S[8] = { { pool , POOL32S_0 , 64 , 32, 0xfc000007, 0xc0000000, 0 , 0, 0x0 }, /* POOL32S_0 */ @@ -21188,7 +21181,7 @@ NMD::Pool NMD::POOL32S[8] = { }; -NMD::Pool NMD::P_LUI[2] = { +static const Pool P_LUI[2] = { { instruction , 0 , 0 , 32, 0xfc000002, 0xe0000000, &LUI , 0, 0x0 }, /* LUI */ @@ -21198,7 +21191,7 @@ NMD::Pool NMD::P_LUI[2] = { }; -NMD::Pool NMD::P_GP_LH[2] = { +static const Pool P_GP_LH[2] = { { instruction , 0 , 0 , 32, 0xfc1c0001, 0x44100000, &LH_GP_ , 0, 0x0 }, /* LH[GP] */ @@ -21208,7 +21201,7 @@ NMD::Pool NMD::P_GP_LH[2] = { }; -NMD::Pool NMD::P_GP_SH[2] = { +static const Pool P_GP_SH[2] = { { instruction , 0 , 0 , 32, 0xfc1c0001, 0x44140000, &SH_GP_ , 0, 0x0 }, /* SH[GP] */ @@ -21218,7 +21211,7 @@ NMD::Pool NMD::P_GP_SH[2] = { }; -NMD::Pool NMD::P_GP_CP1[4] = { +static const Pool P_GP_CP1[4] = { { instruction , 0 , 0 , 32, 0xfc1c0003, 0x44180000, &LWC1_GP_ , 0, CP1_ }, /* LWC1[GP] */ @@ -21234,7 +21227,7 @@ NMD::Pool NMD::P_GP_CP1[4] = { }; -NMD::Pool NMD::P_GP_M64[4] = { +static const Pool P_GP_M64[4] = { { instruction , 0 , 0 , 32, 0xfc1c0003, 0x441c0000, &LWU_GP_ , 0, MIPS64_ }, /* LWU[GP] */ @@ -21250,7 +21243,7 @@ NMD::Pool NMD::P_GP_M64[4] = { }; -NMD::Pool NMD::P_GP_BH[8] = { +static const Pool P_GP_BH[8] = { { instruction , 0 , 0 , 32, 0xfc1c0000, 0x44000000, &LB_GP_ , 0, 0x0 }, /* LB[GP] */ @@ -21278,7 +21271,7 @@ NMD::Pool NMD::P_GP_BH[8] = { }; -NMD::Pool NMD::P_LS_U12[16] = { +static const Pool P_LS_U12[16] = { { instruction , 0 , 0 , 32, 0xfc00f000, 0x84000000, &LB_U12_ , 0, 0x0 }, /* LB[U12] */ @@ -21330,7 +21323,7 @@ NMD::Pool NMD::P_LS_U12[16] = { }; -NMD::Pool NMD::P_PREF_S9_[2] = { +static const Pool P_PREF_S9_[2] = { { instruction , 0 , 0 , 32, 0xffe07f00, 0xa7e01800, &SYNCI , 0, 0x0 }, /* SYNCI */ @@ -21340,7 +21333,7 @@ NMD::Pool NMD::P_PREF_S9_[2] = { }; -NMD::Pool NMD::P_LS_S0[16] = { +static const Pool P_LS_S0[16] = { { instruction , 0 , 0 , 32, 0xfc007f00, 0xa4000000, &LB_S9_ , 0, 0x0 }, /* LB[S9] */ @@ -21392,7 +21385,7 @@ NMD::Pool NMD::P_LS_S0[16] = { }; -NMD::Pool NMD::ASET_ACLR[2] = { +static const Pool ASET_ACLR[2] = { { instruction , 0 , 0 , 32, 0xfe007f00, 0xa4001100, &ASET , 0, MCU_ }, /* ASET */ @@ -21402,7 +21395,7 @@ NMD::Pool NMD::ASET_ACLR[2] = { }; -NMD::Pool NMD::P_LL[4] = { +static const Pool P_LL[4] = { { instruction , 0 , 0 , 32, 0xfc007f03, 0xa4005100, &LL , 0, 0x0 }, /* LL */ @@ -21418,7 +21411,7 @@ NMD::Pool NMD::P_LL[4] = { }; -NMD::Pool NMD::P_SC[4] = { +static const Pool P_SC[4] = { { instruction , 0 , 0 , 32, 0xfc007f03, 0xa4005900, &SC , 0, 0x0 }, /* SC */ @@ -21434,7 +21427,7 @@ NMD::Pool NMD::P_SC[4] = { }; -NMD::Pool NMD::P_LLD[8] = { +static const Pool P_LLD[8] = { { instruction , 0 , 0 , 32, 0xfc007f07, 0xa4007100, &LLD , 0, MIPS64_ }, /* LLD */ @@ -21462,7 +21455,7 @@ NMD::Pool NMD::P_LLD[8] = { }; -NMD::Pool NMD::P_SCD[8] = { +static const Pool P_SCD[8] = { { instruction , 0 , 0 , 32, 0xfc007f07, 0xa4007900, &SCD , 0, MIPS64_ }, /* SCD */ @@ -21490,7 +21483,7 @@ NMD::Pool NMD::P_SCD[8] = { }; -NMD::Pool NMD::P_LS_S1[16] = { +static const Pool P_LS_S1[16] = { { reserved_block , 0 , 0 , 32, 0xfc007f00, 0xa4000100, 0 , 0, 0x0 }, /* P.LS.S1~*(0) */ @@ -21542,7 +21535,7 @@ NMD::Pool NMD::P_LS_S1[16] = { }; -NMD::Pool NMD::P_PREFE[2] = { +static const Pool P_PREFE[2] = { { instruction , 0 , 0 , 32, 0xffe07f00, 0xa7e01a00, &SYNCIE , 0, CP0_ | EVA_ }, /* SYNCIE */ @@ -21552,7 +21545,7 @@ NMD::Pool NMD::P_PREFE[2] = { }; -NMD::Pool NMD::P_LLE[4] = { +static const Pool P_LLE[4] = { { instruction , 0 , 0 , 32, 0xfc007f03, 0xa4005200, &LLE , 0, CP0_ | EVA_ }, /* LLE */ @@ -21568,7 +21561,7 @@ NMD::Pool NMD::P_LLE[4] = { }; -NMD::Pool NMD::P_SCE[4] = { +static const Pool P_SCE[4] = { { instruction , 0 , 0 , 32, 0xfc007f03, 0xa4005a00, &SCE , 0, CP0_ | EVA_ }, /* SCE */ @@ -21584,7 +21577,7 @@ NMD::Pool NMD::P_SCE[4] = { }; -NMD::Pool NMD::P_LS_E0[16] = { +static const Pool P_LS_E0[16] = { { instruction , 0 , 0 , 32, 0xfc007f00, 0xa4000200, &LBE , 0, CP0_ | EVA_ }, /* LBE */ @@ -21636,7 +21629,7 @@ NMD::Pool NMD::P_LS_E0[16] = { }; -NMD::Pool NMD::P_LS_WM[2] = { +static const Pool P_LS_WM[2] = { { instruction , 0 , 0 , 32, 0xfc000f00, 0xa4000400, &LWM , 0, XMMS_ }, /* LWM */ @@ -21646,7 +21639,7 @@ NMD::Pool NMD::P_LS_WM[2] = { }; -NMD::Pool NMD::P_LS_UAWM[2] = { +static const Pool P_LS_UAWM[2] = { { instruction , 0 , 0 , 32, 0xfc000f00, 0xa4000500, &UALWM , 0, XMMS_ }, /* UALWM */ @@ -21656,7 +21649,7 @@ NMD::Pool NMD::P_LS_UAWM[2] = { }; -NMD::Pool NMD::P_LS_DM[2] = { +static const Pool P_LS_DM[2] = { { instruction , 0 , 0 , 32, 0xfc000f00, 0xa4000600, &LDM , 0, MIPS64_ }, /* LDM */ @@ -21666,7 +21659,7 @@ NMD::Pool NMD::P_LS_DM[2] = { }; -NMD::Pool NMD::P_LS_UADM[2] = { +static const Pool P_LS_UADM[2] = { { instruction , 0 , 0 , 32, 0xfc000f00, 0xa4000700, &UALDM , 0, MIPS64_ }, /* UALDM */ @@ -21676,7 +21669,7 @@ NMD::Pool NMD::P_LS_UADM[2] = { }; -NMD::Pool NMD::P_LS_S9[8] = { +static const Pool P_LS_S9[8] = { { pool , P_LS_S0 , 16 , 32, 0xfc000700, 0xa4000000, 0 , 0, 0x0 }, /* P.LS.S0 */ @@ -21704,7 +21697,7 @@ NMD::Pool NMD::P_LS_S9[8] = { }; -NMD::Pool NMD::P_BAL[2] = { +static const Pool P_BAL[2] = { { branch_instruction , 0 , 0 , 32, 0xfe000000, 0x28000000, &BC_32_ , 0, 0x0 }, /* BC[32] */ @@ -21714,7 +21707,7 @@ NMD::Pool NMD::P_BAL[2] = { }; -NMD::Pool NMD::P_BALRSC[2] = { +static const Pool P_BALRSC[2] = { { branch_instruction , 0 , 0 , 32, 0xffe0f000, 0x48008000, &BRSC , 0, 0x0 }, /* BRSC */ @@ -21724,7 +21717,7 @@ NMD::Pool NMD::P_BALRSC[2] = { }; -NMD::Pool NMD::P_J[16] = { +static const Pool P_J[16] = { { call_instruction , 0 , 0 , 32, 0xfc00f000, 0x48000000, &JALRC_32_ , 0, 0x0 }, /* JALRC[32] */ @@ -21776,7 +21769,7 @@ NMD::Pool NMD::P_J[16] = { }; -NMD::Pool NMD::P_BR3A[32] = { +static const Pool P_BR3A[32] = { { branch_instruction , 0 , 0 , 32, 0xfc1fc000, 0x88004000, &BC1EQZC , 0, CP1_ }, /* BC1EQZC */ @@ -21876,7 +21869,7 @@ NMD::Pool NMD::P_BR3A[32] = { }; -NMD::Pool NMD::P_BR1[4] = { +static const Pool P_BR1[4] = { { branch_instruction , 0 , 0 , 32, 0xfc00c000, 0x88000000, &BEQC_32_ , 0, 0x0 }, /* BEQC[32] */ @@ -21892,7 +21885,7 @@ NMD::Pool NMD::P_BR1[4] = { }; -NMD::Pool NMD::P_BR2[4] = { +static const Pool P_BR2[4] = { { branch_instruction , 0 , 0 , 32, 0xfc00c000, 0xa8000000, &BNEC_32_ , 0, 0x0 }, /* BNEC[32] */ @@ -21908,7 +21901,7 @@ NMD::Pool NMD::P_BR2[4] = { }; -NMD::Pool NMD::P_BRI[8] = { +static const Pool P_BRI[8] = { { branch_instruction , 0 , 0 , 32, 0xfc1c0000, 0xc8000000, &BEQIC , 0, 0x0 }, /* BEQIC */ @@ -21936,7 +21929,7 @@ NMD::Pool NMD::P_BRI[8] = { }; -NMD::Pool NMD::P32[32] = { +static const Pool P32[32] = { { pool , P_ADDIU , 2 , 32, 0xfc000000, 0x00000000, 0 , 0, 0x0 }, /* P.ADDIU */ @@ -22036,7 +22029,7 @@ NMD::Pool NMD::P32[32] = { }; -NMD::Pool NMD::P16_SYSCALL[2] = { +static const Pool P16_SYSCALL[2] = { { instruction , 0 , 0 , 16, 0xfffc , 0x1008 , &SYSCALL_16_ , 0, 0x0 }, /* SYSCALL[16] */ @@ -22046,7 +22039,7 @@ NMD::Pool NMD::P16_SYSCALL[2] = { }; -NMD::Pool NMD::P16_RI[4] = { +static const Pool P16_RI[4] = { { reserved_block , 0 , 0 , 16, 0xfff8 , 0x1000 , 0 , 0, 0x0 }, /* P16.RI~*(0) */ @@ -22062,7 +22055,7 @@ NMD::Pool NMD::P16_RI[4] = { }; -NMD::Pool NMD::P16_MV[2] = { +static const Pool P16_MV[2] = { { pool , P16_RI , 4 , 16, 0xffe0 , 0x1000 , 0 , 0, 0x0 }, /* P16.RI */ @@ -22072,7 +22065,7 @@ NMD::Pool NMD::P16_MV[2] = { }; -NMD::Pool NMD::P16_SHIFT[2] = { +static const Pool P16_SHIFT[2] = { { instruction , 0 , 0 , 16, 0xfc08 , 0x3000 , &SLL_16_ , 0, 0x0 }, /* SLL[16] */ @@ -22082,7 +22075,7 @@ NMD::Pool NMD::P16_SHIFT[2] = { }; -NMD::Pool NMD::POOL16C_00[4] = { +static const Pool POOL16C_00[4] = { { instruction , 0 , 0 , 16, 0xfc0f , 0x5000 , &NOT_16_ , 0, 0x0 }, /* NOT[16] */ @@ -22098,7 +22091,7 @@ NMD::Pool NMD::POOL16C_00[4] = { }; -NMD::Pool NMD::POOL16C_0[2] = { +static const Pool POOL16C_0[2] = { { pool , POOL16C_00 , 4 , 16, 0xfc03 , 0x5000 , 0 , 0, 0x0 }, /* POOL16C_00 */ @@ -22108,7 +22101,7 @@ NMD::Pool NMD::POOL16C_0[2] = { }; -NMD::Pool NMD::P16C[2] = { +static const Pool P16C[2] = { { pool , POOL16C_0 , 2 , 16, 0xfc01 , 0x5000 , 0 , 0, 0x0 }, /* POOL16C_0 */ @@ -22118,7 +22111,7 @@ NMD::Pool NMD::P16C[2] = { }; -NMD::Pool NMD::P16_A1[2] = { +static const Pool P16_A1[2] = { { reserved_block , 0 , 0 , 16, 0xfc40 , 0x7000 , 0 , 0, 0x0 }, /* P16.A1~*(0) */ @@ -22128,7 +22121,7 @@ NMD::Pool NMD::P16_A1[2] = { }; -NMD::Pool NMD::P_ADDIU_RS5_[2] = { +static const Pool P_ADDIU_RS5_[2] = { { instruction , 0 , 0 , 16, 0xffe8 , 0x9008 , &NOP_16_ , 0, 0x0 }, /* NOP[16] */ @@ -22138,7 +22131,7 @@ NMD::Pool NMD::P_ADDIU_RS5_[2] = { }; -NMD::Pool NMD::P16_A2[2] = { +static const Pool P16_A2[2] = { { instruction , 0 , 0 , 16, 0xfc08 , 0x9000 , &ADDIU_R2_ , 0, 0x0 }, /* ADDIU[R2] */ @@ -22148,7 +22141,7 @@ NMD::Pool NMD::P16_A2[2] = { }; -NMD::Pool NMD::P16_ADDU[2] = { +static const Pool P16_ADDU[2] = { { instruction , 0 , 0 , 16, 0xfc01 , 0xb000 , &ADDU_16_ , 0, 0x0 }, /* ADDU[16] */ @@ -22158,7 +22151,7 @@ NMD::Pool NMD::P16_ADDU[2] = { }; -NMD::Pool NMD::P16_JRC[2] = { +static const Pool P16_JRC[2] = { { branch_instruction , 0 , 0 , 16, 0xfc1f , 0xd800 , &JRC , 0, 0x0 }, /* JRC */ @@ -22168,7 +22161,7 @@ NMD::Pool NMD::P16_JRC[2] = { }; -NMD::Pool NMD::P16_BR1[2] = { +static const Pool P16_BR1[2] = { { branch_instruction , 0 , 0 , 16, 0xfc00 , 0xd800 , &BEQC_16_ , &BEQC_16__cond , XMMS_ }, /* BEQC[16] */ @@ -22178,7 +22171,7 @@ NMD::Pool NMD::P16_BR1[2] = { }; -NMD::Pool NMD::P16_BR[2] = { +static const Pool P16_BR[2] = { { pool , P16_JRC , 2 , 16, 0xfc0f , 0xd800 , 0 , 0, 0x0 }, /* P16.JRC */ @@ -22188,7 +22181,7 @@ NMD::Pool NMD::P16_BR[2] = { }; -NMD::Pool NMD::P16_SR[2] = { +static const Pool P16_SR[2] = { { instruction , 0 , 0 , 16, 0xfd00 , 0x1c00 , &SAVE_16_ , 0, 0x0 }, /* SAVE[16] */ @@ -22198,7 +22191,7 @@ NMD::Pool NMD::P16_SR[2] = { }; -NMD::Pool NMD::P16_4X4[4] = { +static const Pool P16_4X4[4] = { { instruction , 0 , 0 , 16, 0xfd08 , 0x3c00 , &ADDU_4X4_ , 0, XMMS_ }, /* ADDU[4X4] */ @@ -22214,7 +22207,7 @@ NMD::Pool NMD::P16_4X4[4] = { }; -NMD::Pool NMD::P16_LB[4] = { +static const Pool P16_LB[4] = { { instruction , 0 , 0 , 16, 0xfc0c , 0x5c00 , &LB_16_ , 0, 0x0 }, /* LB[16] */ @@ -22230,7 +22223,7 @@ NMD::Pool NMD::P16_LB[4] = { }; -NMD::Pool NMD::P16_LH[4] = { +static const Pool P16_LH[4] = { { instruction , 0 , 0 , 16, 0xfc09 , 0x7c00 , &LH_16_ , 0, 0x0 }, /* LH[16] */ @@ -22246,7 +22239,7 @@ NMD::Pool NMD::P16_LH[4] = { }; -NMD::Pool NMD::P16[32] = { +static const Pool P16[32] = { { pool , P16_MV , 2 , 16, 0xfc00 , 0x1000 , 0 , 0, 0x0 }, /* P16.MV */ @@ -22346,7 +22339,7 @@ NMD::Pool NMD::P16[32] = { }; -NMD::Pool NMD::MAJOR[2] = { +static const Pool MAJOR[2] = { { pool , P32 , 32 , 32, 0x10000000, 0x00000000, 0 , 0, 0x0 }, /* P32 */ @@ -22354,3 +22347,9 @@ NMD::Pool NMD::MAJOR[2] = { 0x1000 , 0x1000 , 0 , 0, 0x0 }, /* P16 */ }; + +int NMD::Disassemble(const uint16 *data, std::string & dis, + TABLE_ENTRY_TYPE & type, Dis_info *info) +{ + return Disassemble(data, dis, type, MAJOR, 2, info); +} diff --git a/disas/nanomips.h b/disas/nanomips.h index 7036e589f4..c56fc32b1e 100644 --- a/disas/nanomips.h +++ b/disas/nanomips.h @@ -68,6 +68,18 @@ typedef bool (*conditional_function)(uint64 instruction); typedef std::string (*disassembly_function)(uint64 instruction, Dis_info *info); +typedef struct Pool { + TABLE_ENTRY_TYPE type; + const struct Pool *next_table; + int next_table_size; + int instructions_size; + uint64 mask; + uint64 value; + disassembly_function disassembly; + conditional_function condition; + uint64 attributes; +} Pool; + class NMD { public: @@ -77,199 +89,10 @@ public: private: - struct Pool { - TABLE_ENTRY_TYPE type; - struct Pool *next_table; - int next_table_size; - int instructions_size; - uint64 mask; - uint64 value; - disassembly_function disassembly; - conditional_function condition; - uint64 attributes; - }; - uint64 extract_op_code_value(const uint16 *data, int size); int Disassemble(const uint16 *data, std::string & dis, TABLE_ENTRY_TYPE & type, const Pool *table, int table_size, Dis_info *info); - - static Pool P_SYSCALL[2]; - static Pool P_RI[4]; - static Pool P_ADDIU[2]; - static Pool P_TRAP[2]; - static Pool P_CMOVE[2]; - static Pool P_D_MT_VPE[2]; - static Pool P_E_MT_VPE[2]; - static Pool _P_MT_VPE[2]; - static Pool P_MT_VPE[8]; - static Pool P_DVP[2]; - static Pool P_SLTU[2]; - static Pool _POOL32A0[128]; - static Pool ADDQ__S__PH[2]; - static Pool MUL__S__PH[2]; - static Pool ADDQH__R__PH[2]; - static Pool ADDQH__R__W[2]; - static Pool ADDU__S__QB[2]; - static Pool ADDU__S__PH[2]; - static Pool ADDUH__R__QB[2]; - static Pool SHRAV__R__PH[2]; - static Pool SHRAV__R__QB[2]; - static Pool SUBQ__S__PH[2]; - static Pool SUBQH__R__PH[2]; - static Pool SUBQH__R__W[2]; - static Pool SUBU__S__QB[2]; - static Pool SUBU__S__PH[2]; - static Pool SHRA__R__PH[2]; - static Pool SUBUH__R__QB[2]; - static Pool SHLLV__S__PH[2]; - static Pool SHLL__S__PH[4]; - static Pool PRECR_SRA__R__PH_W[2]; - static Pool _POOL32A5[128]; - static Pool PP_LSX[16]; - static Pool PP_LSXS[16]; - static Pool P_LSX[2]; - static Pool POOL32Axf_1_0[4]; - static Pool POOL32Axf_1_1[4]; - static Pool POOL32Axf_1_3[4]; - static Pool POOL32Axf_1_4[2]; - static Pool MAQ_S_A__W_PHR[2]; - static Pool MAQ_S_A__W_PHL[2]; - static Pool POOL32Axf_1_5[2]; - static Pool POOL32Axf_1_7[4]; - static Pool POOL32Axf_1[8]; - static Pool POOL32Axf_2_DSP__0_7[8]; - static Pool POOL32Axf_2_DSP__8_15[8]; - static Pool POOL32Axf_2_DSP__16_23[8]; - static Pool POOL32Axf_2_DSP__24_31[8]; - static Pool POOL32Axf_2[4]; - static Pool POOL32Axf_4[128]; - static Pool POOL32Axf_5_group0[32]; - static Pool POOL32Axf_5_group1[32]; - static Pool ERETx[2]; - static Pool POOL32Axf_5_group3[32]; - static Pool POOL32Axf_5[4]; - static Pool SHRA__R__QB[2]; - static Pool POOL32Axf_7[8]; - static Pool POOL32Axf[8]; - static Pool _POOL32A7[8]; - static Pool P32A[8]; - static Pool P_GP_D[2]; - static Pool P_GP_W[4]; - static Pool POOL48I[32]; - static Pool PP_SR[4]; - static Pool P_SR_F[8]; - static Pool P_SR[2]; - static Pool P_SLL[5]; - static Pool P_SHIFT[16]; - static Pool P_ROTX[4]; - static Pool P_INS[4]; - static Pool P_EXT[4]; - static Pool P_U12[16]; - static Pool RINT_fmt[2]; - static Pool ADD_fmt0[2]; - static Pool SELEQZ_fmt[2]; - static Pool CLASS_fmt[2]; - static Pool SUB_fmt0[2]; - static Pool SELNEZ_fmt[2]; - static Pool MUL_fmt0[2]; - static Pool SEL_fmt[2]; - static Pool DIV_fmt0[2]; - static Pool ADD_fmt1[2]; - static Pool SUB_fmt1[2]; - static Pool MUL_fmt1[2]; - static Pool MADDF_fmt[2]; - static Pool DIV_fmt1[2]; - static Pool MSUBF_fmt[2]; - static Pool POOL32F_0[64]; - static Pool MIN_fmt[2]; - static Pool MAX_fmt[2]; - static Pool MINA_fmt[2]; - static Pool MAXA_fmt[2]; - static Pool CVT_L_fmt[2]; - static Pool RSQRT_fmt[2]; - static Pool FLOOR_L_fmt[2]; - static Pool CVT_W_fmt[2]; - static Pool SQRT_fmt[2]; - static Pool FLOOR_W_fmt[2]; - static Pool RECIP_fmt[2]; - static Pool CEIL_L_fmt[2]; - static Pool CEIL_W_fmt[2]; - static Pool TRUNC_L_fmt[2]; - static Pool TRUNC_W_fmt[2]; - static Pool ROUND_L_fmt[2]; - static Pool ROUND_W_fmt[2]; - static Pool POOL32Fxf_0[64]; - static Pool MOV_fmt[4]; - static Pool ABS_fmt[4]; - static Pool NEG_fmt[4]; - static Pool CVT_D_fmt[4]; - static Pool CVT_S_fmt[4]; - static Pool POOL32Fxf_1[32]; - static Pool POOL32Fxf[4]; - static Pool POOL32F_3[8]; - static Pool CMP_condn_S[32]; - static Pool CMP_condn_D[32]; - static Pool POOL32F_5[8]; - static Pool POOL32F[8]; - static Pool POOL32S_0[64]; - static Pool POOL32Sxf_4[128]; - static Pool POOL32Sxf[8]; - static Pool POOL32S_4[8]; - static Pool POOL32S[8]; - static Pool P_LUI[2]; - static Pool P_GP_LH[2]; - static Pool P_GP_SH[2]; - static Pool P_GP_CP1[4]; - static Pool P_GP_M64[4]; - static Pool P_GP_BH[8]; - static Pool P_LS_U12[16]; - static Pool P_PREF_S9_[2]; - static Pool P_LS_S0[16]; - static Pool ASET_ACLR[2]; - static Pool P_LL[4]; - static Pool P_SC[4]; - static Pool P_LLD[8]; - static Pool P_SCD[8]; - static Pool P_LS_S1[16]; - static Pool P_PREFE[2]; - static Pool P_LLE[4]; - static Pool P_SCE[4]; - static Pool P_LS_E0[16]; - static Pool P_LS_WM[2]; - static Pool P_LS_UAWM[2]; - static Pool P_LS_DM[2]; - static Pool P_LS_UADM[2]; - static Pool P_LS_S9[8]; - static Pool P_BAL[2]; - static Pool P_BALRSC[2]; - static Pool P_J[16]; - static Pool P_BR3A[32]; - static Pool P_BR1[4]; - static Pool P_BR2[4]; - static Pool P_BRI[8]; - static Pool P32[32]; - static Pool P16_SYSCALL[2]; - static Pool P16_RI[4]; - static Pool P16_MV[2]; - static Pool P16_SHIFT[2]; - static Pool POOL16C_00[4]; - static Pool POOL16C_0[2]; - static Pool P16C[2]; - static Pool P16_A1[2]; - static Pool P_ADDIU_RS5_[2]; - static Pool P16_A2[2]; - static Pool P16_ADDU[2]; - static Pool P16_JRC[2]; - static Pool P16_BR1[2]; - static Pool P16_BR[2]; - static Pool P16_SR[2]; - static Pool P16_4X4[4]; - static Pool P16_LB[4]; - static Pool P16_LH[4]; - static Pool P16[32]; - static Pool MAJOR[2]; - }; #endif From beebf65bec528bcd73f704b2c93ac9c9494431c1 Mon Sep 17 00:00:00 2001 From: Milica Lazarevic Date: Mon, 12 Sep 2022 14:26:20 +0200 Subject: [PATCH 430/705] disas/nanomips: Remove NMD class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NMD class has been deleted. The following methods are now declared as static functions: - public NMD::Disassemble method - private NMD::Disassemble method - private NMD::extract_op_code_value helper method Also, the implementation of the print_insn_nanomips function and nanomips_dis function is moved to the end of the nanomips.cpp file, right after the implementation of the Disassemble function. Signed-off-by: Milica Lazarevic Reviewed-by: Richard Henderson Message-Id: <20220912122635.74032-10-milica.lazarevic@syrmia.com> Signed-off-by: Philippe Mathieu-Daudé --- disas/nanomips.cpp | 204 ++++++++++++++++++++++----------------------- disas/nanomips.h | 15 ---- 2 files changed, 101 insertions(+), 118 deletions(-) diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp index a73eae5b33..0d67462e5d 100644 --- a/disas/nanomips.cpp +++ b/disas/nanomips.cpp @@ -41,105 +41,6 @@ #define IMGASSERTONCE(test) -static int nanomips_dis(char *buf, - Dis_info *info, - unsigned short one, - unsigned short two, - unsigned short three) -{ - std::string disasm; - uint16 bits[3] = {one, two, three}; - - TABLE_ENTRY_TYPE type; - NMD d; - int size = d.Disassemble(bits, disasm, type, info); - - strcpy(buf, disasm.c_str()); - return size; -} - -int print_insn_nanomips(bfd_vma memaddr, struct disassemble_info *info) -{ - int status; - bfd_byte buffer[2]; - uint16_t insn1 = 0, insn2 = 0, insn3 = 0; - char buf[200]; - - info->bytes_per_chunk = 2; - info->display_endian = info->endian; - info->insn_info_valid = 1; - info->branch_delay_insns = 0; - info->data_size = 0; - info->insn_type = dis_nonbranch; - info->target = 0; - info->target2 = 0; - - Dis_info disassm_info; - disassm_info.m_pc = memaddr; - - status = (*info->read_memory_func)(memaddr, buffer, 2, info); - if (status != 0) { - (*info->memory_error_func)(status, memaddr, info); - return -1; - } - - if (info->endian == BFD_ENDIAN_BIG) { - insn1 = bfd_getb16(buffer); - } else { - insn1 = bfd_getl16(buffer); - } - (*info->fprintf_func)(info->stream, "%04x ", insn1); - - /* Handle 32-bit opcodes. */ - if ((insn1 & 0x1000) == 0) { - status = (*info->read_memory_func)(memaddr + 2, buffer, 2, info); - if (status != 0) { - (*info->memory_error_func)(status, memaddr + 2, info); - return -1; - } - - if (info->endian == BFD_ENDIAN_BIG) { - insn2 = bfd_getb16(buffer); - } else { - insn2 = bfd_getl16(buffer); - } - (*info->fprintf_func)(info->stream, "%04x ", insn2); - } else { - (*info->fprintf_func)(info->stream, " "); - } - /* Handle 48-bit opcodes. */ - if ((insn1 >> 10) == 0x18) { - status = (*info->read_memory_func)(memaddr + 4, buffer, 2, info); - if (status != 0) { - (*info->memory_error_func)(status, memaddr + 4, info); - return -1; - } - - if (info->endian == BFD_ENDIAN_BIG) { - insn3 = bfd_getb16(buffer); - } else { - insn3 = bfd_getl16(buffer); - } - (*info->fprintf_func)(info->stream, "%04x ", insn3); - } else { - (*info->fprintf_func)(info->stream, " "); - } - - int length = nanomips_dis(buf, &disassm_info, insn1, insn2, insn3); - - /* FIXME: Should probably use a hash table on the major opcode here. */ - - (*info->fprintf_func) (info->stream, "%s", buf); - if (length > 0) { - return length / 8; - } - - info->insn_type = dis_noninsn; - - return insn3 ? 6 : insn2 ? 4 : 2; -} - - std::string img_format(const char *format, ...) { char buffer[256]; @@ -739,7 +640,7 @@ static std::string ADDRESS(uint64 value, int instruction_size, Dis_info *info) } -uint64 NMD::extract_op_code_value(const uint16 * data, int size) +static uint64 extract_op_code_value(const uint16 *data, int size) { switch (size) { case 16: @@ -765,7 +666,7 @@ uint64 NMD::extract_op_code_value(const uint16 * data, int size) * instruction size - negative is error * disassembly string - on error will constain error string */ -int NMD::Disassemble(const uint16 * data, std::string & dis, +static int Disassemble(const uint16 *data, std::string & dis, TABLE_ENTRY_TYPE & type, const Pool *table, int table_size, Dis_info *info) { @@ -22348,8 +22249,105 @@ static const Pool MAJOR[2] = { 0x0 }, /* P16 */ }; -int NMD::Disassemble(const uint16 *data, std::string & dis, - TABLE_ENTRY_TYPE & type, Dis_info *info) +static int Disassemble(const uint16 *data, std::string & dis, + TABLE_ENTRY_TYPE & type, Dis_info *info) { return Disassemble(data, dis, type, MAJOR, 2, info); } + +static int nanomips_dis(char *buf, + Dis_info *info, + unsigned short one, + unsigned short two, + unsigned short three) +{ + std::string disasm; + uint16 bits[3] = {one, two, three}; + + TABLE_ENTRY_TYPE type; + int size = Disassemble(bits, disasm, type, info); + + strcpy(buf, disasm.c_str()); + return size; +} + +int print_insn_nanomips(bfd_vma memaddr, struct disassemble_info *info) +{ + int status; + bfd_byte buffer[2]; + uint16_t insn1 = 0, insn2 = 0, insn3 = 0; + char buf[200]; + + info->bytes_per_chunk = 2; + info->display_endian = info->endian; + info->insn_info_valid = 1; + info->branch_delay_insns = 0; + info->data_size = 0; + info->insn_type = dis_nonbranch; + info->target = 0; + info->target2 = 0; + + Dis_info disassm_info; + disassm_info.m_pc = memaddr; + + status = (*info->read_memory_func)(memaddr, buffer, 2, info); + if (status != 0) { + (*info->memory_error_func)(status, memaddr, info); + return -1; + } + + if (info->endian == BFD_ENDIAN_BIG) { + insn1 = bfd_getb16(buffer); + } else { + insn1 = bfd_getl16(buffer); + } + (*info->fprintf_func)(info->stream, "%04x ", insn1); + + /* Handle 32-bit opcodes. */ + if ((insn1 & 0x1000) == 0) { + status = (*info->read_memory_func)(memaddr + 2, buffer, 2, info); + if (status != 0) { + (*info->memory_error_func)(status, memaddr + 2, info); + return -1; + } + + if (info->endian == BFD_ENDIAN_BIG) { + insn2 = bfd_getb16(buffer); + } else { + insn2 = bfd_getl16(buffer); + } + (*info->fprintf_func)(info->stream, "%04x ", insn2); + } else { + (*info->fprintf_func)(info->stream, " "); + } + /* Handle 48-bit opcodes. */ + if ((insn1 >> 10) == 0x18) { + status = (*info->read_memory_func)(memaddr + 4, buffer, 2, info); + if (status != 0) { + (*info->memory_error_func)(status, memaddr + 4, info); + return -1; + } + + if (info->endian == BFD_ENDIAN_BIG) { + insn3 = bfd_getb16(buffer); + } else { + insn3 = bfd_getl16(buffer); + } + (*info->fprintf_func)(info->stream, "%04x ", insn3); + } else { + (*info->fprintf_func)(info->stream, " "); + } + + int length = nanomips_dis(buf, &disassm_info, insn1, insn2, insn3); + + /* FIXME: Should probably use a hash table on the major opcode here. */ + + (*info->fprintf_func) (info->stream, "%s", buf); + if (length > 0) { + return length / 8; + } + + info->insn_type = dis_noninsn; + + return insn3 ? 6 : insn2 ? 4 : 2; +} diff --git a/disas/nanomips.h b/disas/nanomips.h index c56fc32b1e..47b44af751 100644 --- a/disas/nanomips.h +++ b/disas/nanomips.h @@ -80,19 +80,4 @@ typedef struct Pool { uint64 attributes; } Pool; -class NMD -{ -public: - - int Disassemble(const uint16 *data, std::string & dis, - TABLE_ENTRY_TYPE & type, Dis_info *info); - -private: - - uint64 extract_op_code_value(const uint16 *data, int size); - int Disassemble(const uint16 *data, std::string & dis, - TABLE_ENTRY_TYPE & type, const Pool *table, int table_size, - Dis_info *info); -}; - #endif From f1cb3bdbc77aa719a3ea7434e3e89dd64d95508f Mon Sep 17 00:00:00 2001 From: Milica Lazarevic Date: Mon, 12 Sep 2022 14:26:21 +0200 Subject: [PATCH 431/705] disas/nanomips: Move typedefs etc to nanomips.cpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The following is moved from the nanomips.h to nanomips.cpp file: - #include line - typedefs - enums - definition of the Pool struct. Header file nanomips.h will be deleted to be consistent with the rest of the disas/ code. Signed-off-by: Milica Lazarevic Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20220912122635.74032-11-milica.lazarevic@syrmia.com> Signed-off-by: Philippe Mathieu-Daudé --- disas/nanomips.cpp | 57 +++++++++++++++++++++++++++++++++++++++++++++- disas/nanomips.h | 57 ---------------------------------------------- 2 files changed, 56 insertions(+), 58 deletions(-) diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp index 0d67462e5d..7d09fd1a69 100644 --- a/disas/nanomips.cpp +++ b/disas/nanomips.cpp @@ -36,7 +36,62 @@ #include #include -#include "nanomips.h" +#include + +typedef int64_t int64; +typedef uint64_t uint64; +typedef uint32_t uint32; +typedef uint16_t uint16; +typedef uint64_t img_address; + +enum TABLE_ENTRY_TYPE { + instruction, + call_instruction, + branch_instruction, + return_instruction, + reserved_block, + pool, +}; + +enum TABLE_ATTRIBUTE_TYPE { + MIPS64_ = 0x00000001, + XNP_ = 0x00000002, + XMMS_ = 0x00000004, + EVA_ = 0x00000008, + DSP_ = 0x00000010, + MT_ = 0x00000020, + EJTAG_ = 0x00000040, + TLBINV_ = 0x00000080, + CP0_ = 0x00000100, + CP1_ = 0x00000200, + CP2_ = 0x00000400, + UDI_ = 0x00000800, + MCU_ = 0x00001000, + VZ_ = 0x00002000, + TLB_ = 0x00004000, + MVH_ = 0x00008000, + ALL_ATTRIBUTES = 0xffffffffull, +}; + +typedef struct Dis_info { + img_address m_pc; +} Dis_info; + +typedef bool (*conditional_function)(uint64 instruction); +typedef std::string (*disassembly_function)(uint64 instruction, + Dis_info *info); + +typedef struct Pool { + TABLE_ENTRY_TYPE type; + const struct Pool *next_table; + int next_table_size; + int instructions_size; + uint64 mask; + uint64 value; + disassembly_function disassembly; + conditional_function condition; + uint64 attributes; +} Pool; #define IMGASSERTONCE(test) diff --git a/disas/nanomips.h b/disas/nanomips.h index 47b44af751..0fd7299900 100644 --- a/disas/nanomips.h +++ b/disas/nanomips.h @@ -23,61 +23,4 @@ #ifndef DISAS_NANOMIPS_H #define DISAS_NANOMIPS_H -#include - -typedef int64_t int64; -typedef uint64_t uint64; -typedef uint32_t uint32; -typedef uint16_t uint16; -typedef uint64_t img_address; - -enum TABLE_ENTRY_TYPE { - instruction, - call_instruction, - branch_instruction, - return_instruction, - reserved_block, - pool, -}; - -enum TABLE_ATTRIBUTE_TYPE { - MIPS64_ = 0x00000001, - XNP_ = 0x00000002, - XMMS_ = 0x00000004, - EVA_ = 0x00000008, - DSP_ = 0x00000010, - MT_ = 0x00000020, - EJTAG_ = 0x00000040, - TLBINV_ = 0x00000080, - CP0_ = 0x00000100, - CP1_ = 0x00000200, - CP2_ = 0x00000400, - UDI_ = 0x00000800, - MCU_ = 0x00001000, - VZ_ = 0x00002000, - TLB_ = 0x00004000, - MVH_ = 0x00008000, - ALL_ATTRIBUTES = 0xffffffffull, -}; - -typedef struct Dis_info { - img_address m_pc; -} Dis_info; - -typedef bool (*conditional_function)(uint64 instruction); -typedef std::string (*disassembly_function)(uint64 instruction, - Dis_info *info); - -typedef struct Pool { - TABLE_ENTRY_TYPE type; - const struct Pool *next_table; - int next_table_size; - int instructions_size; - uint64 mask; - uint64 value; - disassembly_function disassembly; - conditional_function condition; - uint64 attributes; -} Pool; - #endif From 1a1cc52a88eed130cc99f4912844cddb14a0c8af Mon Sep 17 00:00:00 2001 From: Milica Lazarevic Date: Mon, 12 Sep 2022 14:26:22 +0200 Subject: [PATCH 432/705] disas/nanomips: Delete nanomips.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Header file nanomips.h has been deleted for the nanomips disassembler to stay consistent with the rest of the disassemblers which don't include extra header files. Signed-off-by: Milica Lazarevic Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20220912122635.74032-12-milica.lazarevic@syrmia.com> Signed-off-by: Philippe Mathieu-Daudé --- disas/nanomips.h | 26 -------------------------- 1 file changed, 26 deletions(-) delete mode 100644 disas/nanomips.h diff --git a/disas/nanomips.h b/disas/nanomips.h deleted file mode 100644 index 0fd7299900..0000000000 --- a/disas/nanomips.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Header file for nanoMIPS disassembler component of QEMU - * - * Copyright (C) 2018 Wave Computing, Inc. - * Copyright (C) 2018 Matthew Fortune - * Copyright (C) 2018 Aleksandar Markovic - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#ifndef DISAS_NANOMIPS_H -#define DISAS_NANOMIPS_H - -#endif From 912c95b4fae34a8fc62d383bd3f757ceda8cd20f Mon Sep 17 00:00:00 2001 From: Milica Lazarevic Date: Mon, 12 Sep 2022 14:26:23 +0200 Subject: [PATCH 433/705] disas/nanomips: Remove #include MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit is a C++ library and it's not used by disassembler. Signed-off-by: Milica Lazarevic Reviewed-by: Thomas Huth Reviewed-by: Richard Henderson Message-Id: <20220912122635.74032-13-milica.lazarevic@syrmia.com> Signed-off-by: Philippe Mathieu-Daudé --- disas/nanomips.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp index 7d09fd1a69..4b49630b8b 100644 --- a/disas/nanomips.cpp +++ b/disas/nanomips.cpp @@ -32,7 +32,6 @@ #include #include -#include #include #include From b5cc052894b809cb0e6e7e70b389264b59e06072 Mon Sep 17 00:00:00 2001 From: Milica Lazarevic Date: Mon, 12 Sep 2022 14:26:24 +0200 Subject: [PATCH 434/705] disas/nanomips: Delete copy functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Functions that have just one parameter and simply return it have been deleted. Calls to these functions have been replaced with the argument itself. We're deleting following functions: - both versions of copy() - encode_s_from_address() - encode_u_from_address() - encode_lsb_from_pos_and_size() Signed-off-by: Milica Lazarevic Reviewed-by: Richard Henderson Message-Id: <20220912122635.74032-14-milica.lazarevic@syrmia.com> Signed-off-by: Philippe Mathieu-Daudé --- disas/nanomips.cpp | 3151 ++++++++++++++++++++++---------------------- 1 file changed, 1559 insertions(+), 1592 deletions(-) diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp index 4b49630b8b..b90be5744e 100644 --- a/disas/nanomips.cpp +++ b/disas/nanomips.cpp @@ -499,18 +499,6 @@ static uint64 decode_gpr_gpr1(uint64 d) } -static uint64 copy(uint64 d) -{ - return d; -} - - -static int64 copy(int64 d) -{ - return d; -} - - static int64 neg_copy(uint64 d) { return 0ll - d; @@ -531,20 +519,6 @@ static uint64 encode_rs3_and_check_rs3_lt_rt3(uint64 d) } -/* nop - done by extraction function */ -static uint64 encode_s_from_address(uint64 d) -{ - return d; -} - - -/* nop - done by extraction function */ -static uint64 encode_u_from_address(uint64 d) -{ - return d; -} - - static uint64 encode_count3_from_count(uint64 d) { IMGASSERTONCE(d < 8); @@ -594,13 +568,6 @@ static uint64 encode_rt1_from_rt(uint64 d) } -/* ? */ -static uint64 encode_lsb_from_pos_and_size(uint64 d) -{ - return d; -} - - static std::string GPR(uint64 reg) { static const char *gpr_reg[32] = { @@ -1710,8 +1677,8 @@ static std::string ABS_D(uint64 instruction, Dis_info *info) uint64 fd_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string fs = FPR(copy(fs_value)); - std::string fd = FPR(copy(fd_value)); + std::string fs = FPR(fs_value); + std::string fd = FPR(fd_value); return img_format("ABS.D %s, %s", fd, fs); } @@ -1732,8 +1699,8 @@ static std::string ABS_S(uint64 instruction, Dis_info *info) uint64 fd_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string fs = FPR(copy(fs_value)); - std::string fd = FPR(copy(fd_value)); + std::string fs = FPR(fs_value); + std::string fd = FPR(fd_value); return img_format("ABS.S %s, %s", fd, fs); } @@ -1754,8 +1721,8 @@ static std::string ABSQ_S_PH(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("ABSQ_S.PH %s, %s", rt, rs); } @@ -1776,8 +1743,8 @@ static std::string ABSQ_S_QB(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("ABSQ_S.QB %s, %s", rt, rs); } @@ -1798,8 +1765,8 @@ static std::string ABSQ_S_W(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("ABSQ_S.W %s, %s", rt, rs); } @@ -1820,9 +1787,9 @@ static std::string ACLR(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string bit = IMMEDIATE(copy(bit_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string bit = IMMEDIATE(bit_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("ACLR %s, %s(%s)", bit, s, rs); } @@ -1843,9 +1810,9 @@ static std::string ADD(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("ADD %s, %s, %s", rd, rs, rt); } @@ -1868,9 +1835,9 @@ static std::string ADD_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); - std::string fd = FPR(copy(fd_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); + std::string fd = FPR(fd_value); return img_format("ADD.D %s, %s, %s", fd, fs, ft); } @@ -1893,9 +1860,9 @@ static std::string ADD_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); - std::string fd = FPR(copy(fd_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); + std::string fd = FPR(fd_value); return img_format("ADD.S %s, %s, %s", fd, fs, ft); } @@ -1916,9 +1883,9 @@ static std::string ADDIU_32_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_15_to_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string u = IMMEDIATE(u_value); return img_format("ADDIU %s, %s, %s", rt, rs, u); } @@ -1938,8 +1905,8 @@ static std::string ADDIU_48_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); return img_format("ADDIU %s, %s", rt, s); } @@ -1959,8 +1926,8 @@ static std::string ADDIU_GP48_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); return img_format("ADDIU %s, $%d, %s", rt, 28, s); } @@ -1980,8 +1947,8 @@ static std::string ADDIU_GP_B_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); return img_format("ADDIU %s, $%d, %s", rt, 28, u); } @@ -2001,8 +1968,8 @@ static std::string ADDIU_GP_W_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_to_2__s2(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); return img_format("ADDIU %s, $%d, %s", rt, 28, u); } @@ -2023,8 +1990,8 @@ static std::string ADDIU_NEG_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); std::string u = IMMEDIATE(neg_copy(u_value)); return img_format("ADDIU %s, %s, %s", rt, rs, u); @@ -2046,7 +2013,7 @@ static std::string ADDIU_R1_SP_(uint64 instruction, Dis_info *info) uint64 rt3_value = extract_rt3_9_8_7(instruction); std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string u = IMMEDIATE(u_value); return img_format("ADDIU %s, $%d, %s", rt3, 29, u); } @@ -2069,7 +2036,7 @@ static std::string ADDIU_R2_(uint64 instruction, Dis_info *info) std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string u = IMMEDIATE(u_value); return img_format("ADDIU %s, %s, %s", rt3, rs3, u); } @@ -2088,8 +2055,8 @@ static std::string ADDIU_RS5_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_9_8_7_6_5(instruction); int64 s_value = extract_s__se3_4_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); return img_format("ADDIU %s, %s", rt, s); } @@ -2110,8 +2077,8 @@ static std::string ADDIUPC_32_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); int64 s_value = extract_s__se21_0_20_to_1_s1(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); + std::string rt = GPR(rt_value); + std::string s = ADDRESS(s_value, 4, info); return img_format("ADDIUPC %s, %s", rt, s); } @@ -2132,8 +2099,8 @@ static std::string ADDIUPC_48_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 6, info); + std::string rt = GPR(rt_value); + std::string s = ADDRESS(s_value, 6, info); return img_format("ADDIUPC %s, %s", rt, s); } @@ -2155,9 +2122,9 @@ static std::string ADDQ_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("ADDQ.PH %s, %s, %s", rd, rs, rt); } @@ -2180,9 +2147,9 @@ static std::string ADDQ_S_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("ADDQ_S.PH %s, %s, %s", rd, rs, rt); } @@ -2204,9 +2171,9 @@ static std::string ADDQ_S_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("ADDQ_S.W %s, %s, %s", rd, rs, rt); } @@ -2229,9 +2196,9 @@ static std::string ADDQH_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("ADDQH.PH %s, %s, %s", rd, rs, rt); } @@ -2254,9 +2221,9 @@ static std::string ADDQH_R_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("ADDQH_R.PH %s, %s, %s", rd, rs, rt); } @@ -2279,9 +2246,9 @@ static std::string ADDQH_R_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("ADDQH_R.W %s, %s, %s", rd, rs, rt); } @@ -2304,9 +2271,9 @@ static std::string ADDQH_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("ADDQH.W %s, %s, %s", rd, rs, rt); } @@ -2328,9 +2295,9 @@ static std::string ADDSC(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("ADDSC %s, %s, %s", rd, rs, rt); } @@ -2375,9 +2342,9 @@ static std::string ADDU_32_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("ADDU %s, %s, %s", rd, rs, rt); } @@ -2421,9 +2388,9 @@ static std::string ADDU_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("ADDU.PH %s, %s, %s", rd, rs, rt); } @@ -2445,9 +2412,9 @@ static std::string ADDU_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("ADDU.QB %s, %s, %s", rd, rs, rt); } @@ -2470,9 +2437,9 @@ static std::string ADDU_S_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("ADDU_S.PH %s, %s, %s", rd, rs, rt); } @@ -2494,9 +2461,9 @@ static std::string ADDU_S_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("ADDU_S.QB %s, %s, %s", rd, rs, rt); } @@ -2519,9 +2486,9 @@ static std::string ADDUH_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("ADDUH.QB %s, %s, %s", rd, rs, rt); } @@ -2544,9 +2511,9 @@ static std::string ADDUH_R_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("ADDUH_R.QB %s, %s, %s", rd, rs, rt); } @@ -2567,9 +2534,9 @@ static std::string ADDWC(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("ADDWC %s, %s, %s", rd, rs, rt); } @@ -2590,8 +2557,8 @@ static std::string ALUIPC(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); int64 s_value = extract_s__se31_0_11_to_2_20_to_12_s12(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); + std::string rt = GPR(rt_value); + std::string s = ADDRESS(s_value, 4, info); return img_format("ALUIPC %s, %%pcrel_hi(%s)", rt, s); } @@ -2634,9 +2601,9 @@ static std::string AND_32_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("AND %s, %s, %s", rd, rs, rt); } @@ -2681,9 +2648,9 @@ static std::string ANDI_32_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string u = IMMEDIATE(u_value); return img_format("ANDI %s, %s, %s", rt, rs, u); } @@ -2705,9 +2672,9 @@ static std::string APPEND(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13_12_11(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string sa = IMMEDIATE(copy(sa_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string sa = IMMEDIATE(sa_value); return img_format("APPEND %s, %s, %s", rt, rs, sa); } @@ -2729,9 +2696,9 @@ static std::string ASET(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string bit = IMMEDIATE(copy(bit_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string bit = IMMEDIATE(bit_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("ASET %s, %s(%s)", bit, s, rs); } @@ -2751,7 +2718,7 @@ static std::string BALC_16_(uint64 instruction, Dis_info *info) { int64 s_value = extract_s__se10_0_9_8_7_6_5_4_3_2_1_s1(instruction); - std::string s = ADDRESS(encode_s_from_address(s_value), 2, info); + std::string s = ADDRESS(s_value, 2, info); return img_format("BALC %s", s); } @@ -2771,7 +2738,7 @@ static std::string BALC_32_(uint64 instruction, Dis_info *info) { int64 s_value = extract_s__se25_0_24_to_1_s1(instruction); - std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); + std::string s = ADDRESS(s_value, 4, info); return img_format("BALC %s", s); } @@ -2792,8 +2759,8 @@ static std::string BALRSC(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("BALRSC %s, %s", rt, rs); } @@ -2815,9 +2782,9 @@ static std::string BBEQZC(uint64 instruction, Dis_info *info) uint64 bit_value = extract_bit_16_15_14_13_12_11(instruction); int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); - std::string rt = GPR(copy(rt_value)); - std::string bit = IMMEDIATE(copy(bit_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); + std::string rt = GPR(rt_value); + std::string bit = IMMEDIATE(bit_value); + std::string s = ADDRESS(s_value, 4, info); return img_format("BBEQZC %s, %s, %s", rt, bit, s); } @@ -2839,9 +2806,9 @@ static std::string BBNEZC(uint64 instruction, Dis_info *info) uint64 bit_value = extract_bit_16_15_14_13_12_11(instruction); int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); - std::string rt = GPR(copy(rt_value)); - std::string bit = IMMEDIATE(copy(bit_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); + std::string rt = GPR(rt_value); + std::string bit = IMMEDIATE(bit_value); + std::string s = ADDRESS(s_value, 4, info); return img_format("BBNEZC %s, %s, %s", rt, bit, s); } @@ -2861,7 +2828,7 @@ static std::string BC_16_(uint64 instruction, Dis_info *info) { int64 s_value = extract_s__se10_0_9_8_7_6_5_4_3_2_1_s1(instruction); - std::string s = ADDRESS(encode_s_from_address(s_value), 2, info); + std::string s = ADDRESS(s_value, 2, info); return img_format("BC %s", s); } @@ -2881,7 +2848,7 @@ static std::string BC_32_(uint64 instruction, Dis_info *info) { int64 s_value = extract_s__se25_0_24_to_1_s1(instruction); - std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); + std::string s = ADDRESS(s_value, 4, info); return img_format("BC %s", s); } @@ -2902,8 +2869,8 @@ static std::string BC1EQZC(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - std::string ft = FPR(copy(ft_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); + std::string ft = FPR(ft_value); + std::string s = ADDRESS(s_value, 4, info); return img_format("BC1EQZC %s, %s", ft, s); } @@ -2924,8 +2891,8 @@ static std::string BC1NEZC(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - std::string ft = FPR(copy(ft_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); + std::string ft = FPR(ft_value); + std::string s = ADDRESS(s_value, 4, info); return img_format("BC1NEZC %s, %s", ft, s); } @@ -2946,8 +2913,8 @@ static std::string BC2EQZC(uint64 instruction, Dis_info *info) uint64 ct_value = extract_ct_25_24_23_22_21(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - std::string ct = CPR(copy(ct_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); + std::string ct = CPR(ct_value); + std::string s = ADDRESS(s_value, 4, info); return img_format("BC2EQZC %s, %s", ct, s); } @@ -2968,8 +2935,8 @@ static std::string BC2NEZC(uint64 instruction, Dis_info *info) uint64 ct_value = extract_ct_25_24_23_22_21(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - std::string ct = CPR(copy(ct_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); + std::string ct = CPR(ct_value); + std::string s = ADDRESS(s_value, 4, info); return img_format("BC2NEZC %s, %s", ct, s); } @@ -2993,7 +2960,7 @@ static std::string BEQC_16_(uint64 instruction, Dis_info *info) std::string rs3 = GPR(encode_rs3_and_check_rs3_lt_rt3(rs3_value)); std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string u = ADDRESS(encode_u_from_address(u_value), 2, info); + std::string u = ADDRESS(u_value, 2, info); return img_format("BEQC %s, %s, %s", rs3, rt3, u); } @@ -3015,9 +2982,9 @@ static std::string BEQC_32_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); + std::string s = ADDRESS(s_value, 4, info); return img_format("BEQC %s, %s, %s", rs, rt, s); } @@ -3039,9 +3006,9 @@ static std::string BEQIC(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); + std::string s = ADDRESS(s_value, 4, info); return img_format("BEQIC %s, %s, %s", rt, u, s); } @@ -3063,7 +3030,7 @@ static std::string BEQZC_16_(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se7_0_6_5_4_3_2_1_s1(instruction); std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 2, info); + std::string s = ADDRESS(s_value, 2, info); return img_format("BEQZC %s, %s", rt3, s); } @@ -3085,9 +3052,9 @@ static std::string BGEC(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); + std::string s = ADDRESS(s_value, 4, info); return img_format("BGEC %s, %s, %s", rs, rt, s); } @@ -3109,9 +3076,9 @@ static std::string BGEIC(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); + std::string s = ADDRESS(s_value, 4, info); return img_format("BGEIC %s, %s, %s", rt, u, s); } @@ -3133,9 +3100,9 @@ static std::string BGEIUC(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); + std::string s = ADDRESS(s_value, 4, info); return img_format("BGEIUC %s, %s, %s", rt, u, s); } @@ -3157,9 +3124,9 @@ static std::string BGEUC(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); + std::string s = ADDRESS(s_value, 4, info); return img_format("BGEUC %s, %s, %s", rs, rt, s); } @@ -3181,9 +3148,9 @@ static std::string BLTC(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); + std::string s = ADDRESS(s_value, 4, info); return img_format("BLTC %s, %s, %s", rs, rt, s); } @@ -3205,9 +3172,9 @@ static std::string BLTIC(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); + std::string s = ADDRESS(s_value, 4, info); return img_format("BLTIC %s, %s, %s", rt, u, s); } @@ -3229,9 +3196,9 @@ static std::string BLTIUC(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); + std::string s = ADDRESS(s_value, 4, info); return img_format("BLTIUC %s, %s, %s", rt, u, s); } @@ -3253,9 +3220,9 @@ static std::string BLTUC(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); + std::string s = ADDRESS(s_value, 4, info); return img_format("BLTUC %s, %s, %s", rs, rt, s); } @@ -3279,7 +3246,7 @@ static std::string BNEC_16_(uint64 instruction, Dis_info *info) std::string rs3 = GPR(encode_rs3_and_check_rs3_ge_rt3(rs3_value)); std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string u = ADDRESS(encode_u_from_address(u_value), 2, info); + std::string u = ADDRESS(u_value, 2, info); return img_format("BNEC %s, %s, %s", rs3, rt3, u); } @@ -3301,9 +3268,9 @@ static std::string BNEC_32_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); + std::string s = ADDRESS(s_value, 4, info); return img_format("BNEC %s, %s, %s", rs, rt, s); } @@ -3325,9 +3292,9 @@ static std::string BNEIC(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); + std::string s = ADDRESS(s_value, 4, info); return img_format("BNEIC %s, %s, %s", rt, u, s); } @@ -3349,7 +3316,7 @@ static std::string BNEZC_16_(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se7_0_6_5_4_3_2_1_s1(instruction); std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 2, info); + std::string s = ADDRESS(s_value, 2, info); return img_format("BNEZC %s, %s", rt3, s); } @@ -3369,7 +3336,7 @@ static std::string BPOSGE32C(uint64 instruction, Dis_info *info) { int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); + std::string s = ADDRESS(s_value, 4, info); return img_format("BPOSGE32C %s", s); } @@ -3389,7 +3356,7 @@ static std::string BREAK_16_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_2_1_0(instruction); - std::string code = IMMEDIATE(copy(code_value)); + std::string code = IMMEDIATE(code_value); return img_format("BREAK %s", code); } @@ -3409,7 +3376,7 @@ static std::string BREAK_32_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_18_to_0(instruction); - std::string code = IMMEDIATE(copy(code_value)); + std::string code = IMMEDIATE(code_value); return img_format("BREAK %s", code); } @@ -3429,7 +3396,7 @@ static std::string BRSC(uint64 instruction, Dis_info *info) { uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rs = GPR(copy(rs_value)); + std::string rs = GPR(rs_value); return img_format("BRSC %s", rs); } @@ -3451,9 +3418,9 @@ static std::string CACHE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string op = IMMEDIATE(copy(op_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string op = IMMEDIATE(op_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("CACHE %s, %s(%s)", op, s, rs); } @@ -3475,9 +3442,9 @@ static std::string CACHEE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string op = IMMEDIATE(copy(op_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string op = IMMEDIATE(op_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("CACHEE %s, %s(%s)", op, s, rs); } @@ -3498,8 +3465,8 @@ static std::string CEIL_L_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("CEIL.L.D %s, %s", ft, fs); } @@ -3520,8 +3487,8 @@ static std::string CEIL_L_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("CEIL.L.S %s, %s", ft, fs); } @@ -3542,8 +3509,8 @@ static std::string CEIL_W_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("CEIL.W.D %s, %s", ft, fs); } @@ -3564,8 +3531,8 @@ static std::string CEIL_W_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("CEIL.W.S %s, %s", ft, fs); } @@ -3586,8 +3553,8 @@ static std::string CFC1(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string cs = CPR(copy(cs_value)); + std::string rt = GPR(rt_value); + std::string cs = CPR(cs_value); return img_format("CFC1 %s, %s", rt, cs); } @@ -3608,8 +3575,8 @@ static std::string CFC2(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string cs = CPR(copy(cs_value)); + std::string rt = GPR(rt_value); + std::string cs = CPR(cs_value); return img_format("CFC2 %s, %s", rt, cs); } @@ -3630,8 +3597,8 @@ static std::string CLASS_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("CLASS.D %s, %s", ft, fs); } @@ -3652,8 +3619,8 @@ static std::string CLASS_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("CLASS.S %s, %s", ft, fs); } @@ -3674,8 +3641,8 @@ static std::string CLO(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("CLO %s, %s", rt, rs); } @@ -3696,8 +3663,8 @@ static std::string CLZ(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("CLZ %s, %s", rt, rs); } @@ -3719,9 +3686,9 @@ static std::string CMP_AF_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.AF.D %s, %s, %s", fd, fs, ft); } @@ -3743,9 +3710,9 @@ static std::string CMP_AF_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.AF.S %s, %s, %s", fd, fs, ft); } @@ -3767,9 +3734,9 @@ static std::string CMP_EQ_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.EQ.D %s, %s, %s", fd, fs, ft); } @@ -3789,8 +3756,8 @@ static std::string CMP_EQ_PH(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("CMP.EQ.PH %s, %s", rs, rt); } @@ -3812,9 +3779,9 @@ static std::string CMP_EQ_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.EQ.S %s, %s, %s", fd, fs, ft); } @@ -3836,9 +3803,9 @@ static std::string CMP_LE_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.LE.D %s, %s, %s", fd, fs, ft); } @@ -3858,8 +3825,8 @@ static std::string CMP_LE_PH(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("CMP.LE.PH %s, %s", rs, rt); } @@ -3881,9 +3848,9 @@ static std::string CMP_LE_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.LE.S %s, %s, %s", fd, fs, ft); } @@ -3905,9 +3872,9 @@ static std::string CMP_LT_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.LT.D %s, %s, %s", fd, fs, ft); } @@ -3927,8 +3894,8 @@ static std::string CMP_LT_PH(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("CMP.LT.PH %s, %s", rs, rt); } @@ -3950,9 +3917,9 @@ static std::string CMP_LT_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.LT.S %s, %s, %s", fd, fs, ft); } @@ -3974,9 +3941,9 @@ static std::string CMP_NE_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.NE.D %s, %s, %s", fd, fs, ft); } @@ -3998,9 +3965,9 @@ static std::string CMP_NE_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.NE.S %s, %s, %s", fd, fs, ft); } @@ -4022,9 +3989,9 @@ static std::string CMP_OR_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.OR.D %s, %s, %s", fd, fs, ft); } @@ -4046,9 +4013,9 @@ static std::string CMP_OR_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.OR.S %s, %s, %s", fd, fs, ft); } @@ -4070,9 +4037,9 @@ static std::string CMP_SAF_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.SAF.D %s, %s, %s", fd, fs, ft); } @@ -4094,9 +4061,9 @@ static std::string CMP_SAF_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.SAF.S %s, %s, %s", fd, fs, ft); } @@ -4118,9 +4085,9 @@ static std::string CMP_SEQ_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.SEQ.D %s, %s, %s", fd, fs, ft); } @@ -4142,9 +4109,9 @@ static std::string CMP_SEQ_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.SEQ.S %s, %s, %s", fd, fs, ft); } @@ -4166,9 +4133,9 @@ static std::string CMP_SLE_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.SLE.D %s, %s, %s", fd, fs, ft); } @@ -4190,9 +4157,9 @@ static std::string CMP_SLE_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.SLE.S %s, %s, %s", fd, fs, ft); } @@ -4214,9 +4181,9 @@ static std::string CMP_SLT_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.SLT.D %s, %s, %s", fd, fs, ft); } @@ -4238,9 +4205,9 @@ static std::string CMP_SLT_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.SLT.S %s, %s, %s", fd, fs, ft); } @@ -4262,9 +4229,9 @@ static std::string CMP_SNE_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.SNE.D %s, %s, %s", fd, fs, ft); } @@ -4286,9 +4253,9 @@ static std::string CMP_SNE_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.SNE.S %s, %s, %s", fd, fs, ft); } @@ -4310,9 +4277,9 @@ static std::string CMP_SOR_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.SOR.D %s, %s, %s", fd, fs, ft); } @@ -4334,9 +4301,9 @@ static std::string CMP_SOR_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.SOR.S %s, %s, %s", fd, fs, ft); } @@ -4358,9 +4325,9 @@ static std::string CMP_SUEQ_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.SUEQ.D %s, %s, %s", fd, fs, ft); } @@ -4382,9 +4349,9 @@ static std::string CMP_SUEQ_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.SUEQ.S %s, %s, %s", fd, fs, ft); } @@ -4406,9 +4373,9 @@ static std::string CMP_SULE_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.SULE.D %s, %s, %s", fd, fs, ft); } @@ -4430,9 +4397,9 @@ static std::string CMP_SULE_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.SULE.S %s, %s, %s", fd, fs, ft); } @@ -4454,9 +4421,9 @@ static std::string CMP_SULT_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.SULT.D %s, %s, %s", fd, fs, ft); } @@ -4478,9 +4445,9 @@ static std::string CMP_SULT_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.SULT.S %s, %s, %s", fd, fs, ft); } @@ -4502,9 +4469,9 @@ static std::string CMP_SUN_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.SUN.D %s, %s, %s", fd, fs, ft); } @@ -4526,9 +4493,9 @@ static std::string CMP_SUNE_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.SUNE.D %s, %s, %s", fd, fs, ft); } @@ -4550,9 +4517,9 @@ static std::string CMP_SUNE_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.SUNE.S %s, %s, %s", fd, fs, ft); } @@ -4574,9 +4541,9 @@ static std::string CMP_SUN_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.SUN.S %s, %s, %s", fd, fs, ft); } @@ -4598,9 +4565,9 @@ static std::string CMP_UEQ_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.UEQ.D %s, %s, %s", fd, fs, ft); } @@ -4622,9 +4589,9 @@ static std::string CMP_UEQ_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.UEQ.S %s, %s, %s", fd, fs, ft); } @@ -4646,9 +4613,9 @@ static std::string CMP_ULE_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.ULE.D %s, %s, %s", fd, fs, ft); } @@ -4670,9 +4637,9 @@ static std::string CMP_ULE_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.ULE.S %s, %s, %s", fd, fs, ft); } @@ -4694,9 +4661,9 @@ static std::string CMP_ULT_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.ULT.D %s, %s, %s", fd, fs, ft); } @@ -4718,9 +4685,9 @@ static std::string CMP_ULT_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.ULT.S %s, %s, %s", fd, fs, ft); } @@ -4742,9 +4709,9 @@ static std::string CMP_UN_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.UN.D %s, %s, %s", fd, fs, ft); } @@ -4766,9 +4733,9 @@ static std::string CMP_UNE_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.UNE.D %s, %s, %s", fd, fs, ft); } @@ -4790,9 +4757,9 @@ static std::string CMP_UNE_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.UNE.S %s, %s, %s", fd, fs, ft); } @@ -4814,9 +4781,9 @@ static std::string CMP_UN_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("CMP.UN.S %s, %s, %s", fd, fs, ft); } @@ -4839,9 +4806,9 @@ static std::string CMPGDU_EQ_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("CMPGDU.EQ.QB %s, %s, %s", rd, rs, rt); } @@ -4864,9 +4831,9 @@ static std::string CMPGDU_LE_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("CMPGDU.LE.QB %s, %s, %s", rd, rs, rt); } @@ -4889,9 +4856,9 @@ static std::string CMPGDU_LT_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("CMPGDU.LT.QB %s, %s, %s", rd, rs, rt); } @@ -4914,9 +4881,9 @@ static std::string CMPGU_EQ_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("CMPGU.EQ.QB %s, %s, %s", rd, rs, rt); } @@ -4939,9 +4906,9 @@ static std::string CMPGU_LE_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("CMPGU.LE.QB %s, %s, %s", rd, rs, rt); } @@ -4964,9 +4931,9 @@ static std::string CMPGU_LT_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("CMPGU.LT.QB %s, %s, %s", rd, rs, rt); } @@ -4987,8 +4954,8 @@ static std::string CMPU_EQ_QB(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("CMPU.EQ.QB %s, %s", rs, rt); } @@ -5009,8 +4976,8 @@ static std::string CMPU_LE_QB(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("CMPU.LE.QB %s, %s", rs, rt); } @@ -5031,8 +4998,8 @@ static std::string CMPU_LT_QB(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("CMPU.LT.QB %s, %s", rs, rt); } @@ -5052,7 +5019,7 @@ static std::string COP2_1(uint64 instruction, Dis_info *info) { uint64 cofun_value = extract_cofun_25_24_23(instruction); - std::string cofun = IMMEDIATE(copy(cofun_value)); + std::string cofun = IMMEDIATE(cofun_value); return img_format("COP2_1 %s", cofun); } @@ -5073,8 +5040,8 @@ static std::string CTC1(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string cs = CPR(copy(cs_value)); + std::string rt = GPR(rt_value); + std::string cs = CPR(cs_value); return img_format("CTC1 %s, %s", rt, cs); } @@ -5095,8 +5062,8 @@ static std::string CTC2(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string cs = CPR(copy(cs_value)); + std::string rt = GPR(rt_value); + std::string cs = CPR(cs_value); return img_format("CTC2 %s, %s", rt, cs); } @@ -5117,8 +5084,8 @@ static std::string CVT_D_L(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("CVT.D.L %s, %s", ft, fs); } @@ -5139,8 +5106,8 @@ static std::string CVT_D_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("CVT.D.S %s, %s", ft, fs); } @@ -5161,8 +5128,8 @@ static std::string CVT_D_W(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("CVT.D.W %s, %s", ft, fs); } @@ -5183,8 +5150,8 @@ static std::string CVT_L_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("CVT.L.D %s, %s", ft, fs); } @@ -5205,8 +5172,8 @@ static std::string CVT_L_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("CVT.L.S %s, %s", ft, fs); } @@ -5227,8 +5194,8 @@ static std::string CVT_S_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("CVT.S.D %s, %s", ft, fs); } @@ -5249,8 +5216,8 @@ static std::string CVT_S_L(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("CVT.S.L %s, %s", ft, fs); } @@ -5271,8 +5238,8 @@ static std::string CVT_S_PL(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("CVT.S.PL %s, %s", ft, fs); } @@ -5293,8 +5260,8 @@ static std::string CVT_S_PU(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("CVT.S.PU %s, %s", ft, fs); } @@ -5315,8 +5282,8 @@ static std::string CVT_S_W(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("CVT.S.W %s, %s", ft, fs); } @@ -5337,8 +5304,8 @@ static std::string CVT_W_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("CVT.W.D %s, %s", ft, fs); } @@ -5359,8 +5326,8 @@ static std::string CVT_W_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("CVT.W.S %s, %s", ft, fs); } @@ -5381,8 +5348,8 @@ static std::string DADDIU_48_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); return img_format("DADDIU %s, %s", rt, s); } @@ -5404,8 +5371,8 @@ static std::string DADDIU_NEG_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); std::string u = IMMEDIATE(neg_copy(u_value)); return img_format("DADDIU %s, %s, %s", rt, rs, u); @@ -5428,9 +5395,9 @@ static std::string DADDIU_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string u = IMMEDIATE(u_value); return img_format("DADDIU %s, %s, %s", rt, rs, u); } @@ -5452,9 +5419,9 @@ static std::string DADD(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DADD %s, %s, %s", rd, rs, rt); } @@ -5476,9 +5443,9 @@ static std::string DADDU(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DADDU %s, %s, %s", rd, rs, rt); } @@ -5499,8 +5466,8 @@ static std::string DCLO(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("DCLO %s, %s", rt, rs); } @@ -5521,8 +5488,8 @@ static std::string DCLZ(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("DCLZ %s, %s", rt, rs); } @@ -5544,9 +5511,9 @@ static std::string DDIV(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DDIV %s, %s, %s", rd, rs, rt); } @@ -5568,9 +5535,9 @@ static std::string DDIVU(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DDIVU %s, %s, %s", rd, rs, rt); } @@ -5611,9 +5578,9 @@ static std::string DEXTM(uint64 instruction, Dis_info *info) uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction); uint64 lsb_value = extract_lsb_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string lsb = IMMEDIATE(copy(lsb_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string lsb = IMMEDIATE(lsb_value); std::string msbd = IMMEDIATE(encode_msbd_from_size(msbd_value)); return img_format("DEXTM %s, %s, %s, %s", rt, rs, lsb, msbd); @@ -5637,9 +5604,9 @@ static std::string DEXT(uint64 instruction, Dis_info *info) uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction); uint64 lsb_value = extract_lsb_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string lsb = IMMEDIATE(copy(lsb_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string lsb = IMMEDIATE(lsb_value); std::string msbd = IMMEDIATE(encode_msbd_from_size(msbd_value)); return img_format("DEXT %s, %s, %s, %s", rt, rs, lsb, msbd); @@ -5663,9 +5630,9 @@ static std::string DEXTU(uint64 instruction, Dis_info *info) uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction); uint64 lsb_value = extract_lsb_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string lsb = IMMEDIATE(copy(lsb_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string lsb = IMMEDIATE(lsb_value); std::string msbd = IMMEDIATE(encode_msbd_from_size(msbd_value)); return img_format("DEXTU %s, %s, %s, %s", rt, rs, lsb, msbd); @@ -5689,10 +5656,10 @@ static std::string DINSM(uint64 instruction, Dis_info *info) uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction); uint64 lsb_value = extract_lsb_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string pos = IMMEDIATE(encode_lsb_from_pos_and_size(lsb_value)); - std::string size = IMMEDIATE(encode_lsb_from_pos_and_size(msbd_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string pos = IMMEDIATE(lsb_value); + std::string size = IMMEDIATE(msbd_value); /* !!!!!!!!!! - no conversion function */ return img_format("DINSM %s, %s, %s, %s", rt, rs, pos, size); @@ -5717,10 +5684,10 @@ static std::string DINS(uint64 instruction, Dis_info *info) uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction); uint64 lsb_value = extract_lsb_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string pos = IMMEDIATE(encode_lsb_from_pos_and_size(lsb_value)); - std::string size = IMMEDIATE(encode_lsb_from_pos_and_size(msbd_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string pos = IMMEDIATE(lsb_value); + std::string size = IMMEDIATE(msbd_value); /* !!!!!!!!!! - no conversion function */ return img_format("DINS %s, %s, %s, %s", rt, rs, pos, size); @@ -5745,10 +5712,10 @@ static std::string DINSU(uint64 instruction, Dis_info *info) uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction); uint64 lsb_value = extract_lsb_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string pos = IMMEDIATE(encode_lsb_from_pos_and_size(lsb_value)); - std::string size = IMMEDIATE(encode_lsb_from_pos_and_size(msbd_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string pos = IMMEDIATE(lsb_value); + std::string size = IMMEDIATE(msbd_value); /* !!!!!!!!!! - no conversion function */ return img_format("DINSU %s, %s, %s, %s", rt, rs, pos, size); @@ -5770,7 +5737,7 @@ static std::string DI(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); - std::string rt = GPR(copy(rt_value)); + std::string rt = GPR(rt_value); return img_format("DI %s", rt); } @@ -5792,9 +5759,9 @@ static std::string DIV(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DIV %s, %s, %s", rd, rs, rt); } @@ -5816,9 +5783,9 @@ static std::string DIV_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("DIV.D %s, %s, %s", fd, fs, ft); } @@ -5840,9 +5807,9 @@ static std::string DIV_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("DIV.S %s, %s, %s", fd, fs, ft); } @@ -5864,9 +5831,9 @@ static std::string DIVU(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DIVU %s, %s, %s", rd, rs, rt); } @@ -5889,10 +5856,10 @@ static std::string DLSA(uint64 instruction, Dis_info *info) uint64 rd_value = extract_rd_15_14_13_12_11(instruction); uint64 u2_value = extract_u2_10_9(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); - std::string u2 = IMMEDIATE(copy(u2_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); + std::string u2 = IMMEDIATE(u2_value); return img_format("DLSA %s, %s, %s, %s", rd, rs, rt, u2); } @@ -5913,8 +5880,8 @@ static std::string DLUI_48_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_41_40_39_38_37(instruction); uint64 u_value = extract_u_31_to_0__s32(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); return img_format("DLUI %s, %s", rt, u); } @@ -5936,9 +5903,9 @@ static std::string DMFC0(uint64 instruction, Dis_info *info) uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - std::string rt = GPR(copy(rt_value)); - std::string c0s = CPR(copy(c0s_value)); - std::string sel = IMMEDIATE(copy(sel_value)); + std::string rt = GPR(rt_value); + std::string c0s = CPR(c0s_value); + std::string sel = IMMEDIATE(sel_value); return img_format("DMFC0 %s, %s, %s", rt, c0s, sel); } @@ -5959,8 +5926,8 @@ static std::string DMFC1(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string fs = FPR(copy(fs_value)); + std::string rt = GPR(rt_value); + std::string fs = FPR(fs_value); return img_format("DMFC1 %s, %s", rt, fs); } @@ -5981,8 +5948,8 @@ static std::string DMFC2(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string cs = CPR(copy(cs_value)); + std::string rt = GPR(rt_value); + std::string cs = CPR(cs_value); return img_format("DMFC2 %s, %s", rt, cs); } @@ -6004,9 +5971,9 @@ static std::string DMFGC0(uint64 instruction, Dis_info *info) uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - std::string rt = GPR(copy(rt_value)); - std::string c0s = CPR(copy(c0s_value)); - std::string sel = IMMEDIATE(copy(sel_value)); + std::string rt = GPR(rt_value); + std::string c0s = CPR(c0s_value); + std::string sel = IMMEDIATE(sel_value); return img_format("DMFGC0 %s, %s, %s", rt, c0s, sel); } @@ -6028,9 +5995,9 @@ static std::string DMOD(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DMOD %s, %s, %s", rd, rs, rt); } @@ -6052,9 +6019,9 @@ static std::string DMODU(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DMODU %s, %s, %s", rd, rs, rt); } @@ -6076,9 +6043,9 @@ static std::string DMTC0(uint64 instruction, Dis_info *info) uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - std::string rt = GPR(copy(rt_value)); - std::string c0s = CPR(copy(c0s_value)); - std::string sel = IMMEDIATE(copy(sel_value)); + std::string rt = GPR(rt_value); + std::string c0s = CPR(c0s_value); + std::string sel = IMMEDIATE(sel_value); return img_format("DMTC0 %s, %s, %s", rt, c0s, sel); } @@ -6099,8 +6066,8 @@ static std::string DMTC1(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string fs = FPR(copy(fs_value)); + std::string rt = GPR(rt_value); + std::string fs = FPR(fs_value); return img_format("DMTC1 %s, %s", rt, fs); } @@ -6121,8 +6088,8 @@ static std::string DMTC2(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string cs = CPR(copy(cs_value)); + std::string rt = GPR(rt_value); + std::string cs = CPR(cs_value); return img_format("DMTC2 %s, %s", rt, cs); } @@ -6144,9 +6111,9 @@ static std::string DMTGC0(uint64 instruction, Dis_info *info) uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - std::string rt = GPR(copy(rt_value)); - std::string c0s = CPR(copy(c0s_value)); - std::string sel = IMMEDIATE(copy(sel_value)); + std::string rt = GPR(rt_value); + std::string c0s = CPR(c0s_value); + std::string sel = IMMEDIATE(sel_value); return img_format("DMTGC0 %s, %s, %s", rt, c0s, sel); } @@ -6166,7 +6133,7 @@ static std::string DMT(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); - std::string rt = GPR(copy(rt_value)); + std::string rt = GPR(rt_value); return img_format("DMT %s", rt); } @@ -6188,9 +6155,9 @@ static std::string DMUH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DMUH %s, %s, %s", rd, rs, rt); } @@ -6212,9 +6179,9 @@ static std::string DMUHU(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DMUHU %s, %s, %s", rd, rs, rt); } @@ -6236,9 +6203,9 @@ static std::string DMUL(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DMUL %s, %s, %s", rd, rs, rt); } @@ -6260,9 +6227,9 @@ static std::string DMULU(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DMULU %s, %s, %s", rd, rs, rt); } @@ -6285,9 +6252,9 @@ static std::string DPA_W_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DPA.W.PH %s, %s, %s", ac, rs, rt); } @@ -6309,9 +6276,9 @@ static std::string DPAQ_SA_L_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DPAQ_SA.L.W %s, %s, %s", ac, rs, rt); } @@ -6333,9 +6300,9 @@ static std::string DPAQ_S_W_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DPAQ_S.W.PH %s, %s, %s", ac, rs, rt); } @@ -6357,9 +6324,9 @@ static std::string DPAQX_SA_W_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DPAQX_SA.W.PH %s, %s, %s", ac, rs, rt); } @@ -6381,9 +6348,9 @@ static std::string DPAQX_S_W_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DPAQX_S.W.PH %s, %s, %s", ac, rs, rt); } @@ -6405,9 +6372,9 @@ static std::string DPAU_H_QBL(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DPAU.H.QBL %s, %s, %s", ac, rs, rt); } @@ -6429,9 +6396,9 @@ static std::string DPAU_H_QBR(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DPAU.H.QBR %s, %s, %s", ac, rs, rt); } @@ -6453,9 +6420,9 @@ static std::string DPAX_W_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DPAX.W.PH %s, %s, %s", ac, rs, rt); } @@ -6477,9 +6444,9 @@ static std::string DPS_W_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DPS.W.PH %s, %s, %s", ac, rs, rt); } @@ -6501,9 +6468,9 @@ static std::string DPSQ_SA_L_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DPSQ_SA.L.W %s, %s, %s", ac, rs, rt); } @@ -6525,9 +6492,9 @@ static std::string DPSQ_S_W_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DPSQ_S.W.PH %s, %s, %s", ac, rs, rt); } @@ -6549,9 +6516,9 @@ static std::string DPSQX_SA_W_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DPSQX_SA.W.PH %s, %s, %s", ac, rs, rt); } @@ -6573,9 +6540,9 @@ static std::string DPSQX_S_W_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DPSQX_S.W.PH %s, %s, %s", ac, rs, rt); } @@ -6597,9 +6564,9 @@ static std::string DPSU_H_QBL(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DPSU.H.QBL %s, %s, %s", ac, rs, rt); } @@ -6621,9 +6588,9 @@ static std::string DPSU_H_QBR(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DPSU.H.QBR %s, %s, %s", ac, rs, rt); } @@ -6645,9 +6612,9 @@ static std::string DPSX_W_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DPSX.W.PH %s, %s, %s", ac, rs, rt); } @@ -6669,9 +6636,9 @@ static std::string DROTR(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string shift = IMMEDIATE(copy(shift_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string shift = IMMEDIATE(shift_value); return img_format("DROTR %s, %s, %s", rt, rs, shift); } @@ -6693,9 +6660,9 @@ static std::string DROTR32(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string shift = IMMEDIATE(copy(shift_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string shift = IMMEDIATE(shift_value); return img_format("DROTR32 %s, %s, %s", rt, rs, shift); } @@ -6717,9 +6684,9 @@ static std::string DROTRV(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DROTRV %s, %s, %s", rd, rs, rt); } @@ -6742,10 +6709,10 @@ static std::string DROTX(uint64 instruction, Dis_info *info) uint64 shiftx_value = extract_shiftx_11_10_9_8_7_6(instruction); uint64 shift_value = extract_shift_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string shift = IMMEDIATE(copy(shift_value)); - std::string shiftx = IMMEDIATE(copy(shiftx_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string shift = IMMEDIATE(shift_value); + std::string shiftx = IMMEDIATE(shiftx_value); return img_format("DROTX %s, %s, %s, %s", rt, rs, shift, shiftx); } @@ -6767,9 +6734,9 @@ static std::string DSLL(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string shift = IMMEDIATE(copy(shift_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string shift = IMMEDIATE(shift_value); return img_format("DSLL %s, %s, %s", rt, rs, shift); } @@ -6791,9 +6758,9 @@ static std::string DSLL32(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string shift = IMMEDIATE(copy(shift_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string shift = IMMEDIATE(shift_value); return img_format("DSLL32 %s, %s, %s", rt, rs, shift); } @@ -6815,9 +6782,9 @@ static std::string DSLLV(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DSLLV %s, %s, %s", rd, rs, rt); } @@ -6839,9 +6806,9 @@ static std::string DSRA(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string shift = IMMEDIATE(copy(shift_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string shift = IMMEDIATE(shift_value); return img_format("DSRA %s, %s, %s", rt, rs, shift); } @@ -6863,9 +6830,9 @@ static std::string DSRA32(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string shift = IMMEDIATE(copy(shift_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string shift = IMMEDIATE(shift_value); return img_format("DSRA32 %s, %s, %s", rt, rs, shift); } @@ -6887,9 +6854,9 @@ static std::string DSRAV(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DSRAV %s, %s, %s", rd, rs, rt); } @@ -6911,9 +6878,9 @@ static std::string DSRL(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string shift = IMMEDIATE(copy(shift_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string shift = IMMEDIATE(shift_value); return img_format("DSRL %s, %s, %s", rt, rs, shift); } @@ -6935,9 +6902,9 @@ static std::string DSRL32(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string shift = IMMEDIATE(copy(shift_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string shift = IMMEDIATE(shift_value); return img_format("DSRL32 %s, %s, %s", rt, rs, shift); } @@ -6959,9 +6926,9 @@ static std::string DSRLV(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DSRLV %s, %s, %s", rd, rs, rt); } @@ -6983,9 +6950,9 @@ static std::string DSUB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DSUB %s, %s, %s", rd, rs, rt); } @@ -7007,9 +6974,9 @@ static std::string DSUBU(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("DSUBU %s, %s, %s", rd, rs, rt); } @@ -7029,7 +6996,7 @@ static std::string DVPE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); - std::string rt = GPR(copy(rt_value)); + std::string rt = GPR(rt_value); return img_format("DVPE %s", rt); } @@ -7049,7 +7016,7 @@ static std::string DVP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); - std::string rt = GPR(copy(rt_value)); + std::string rt = GPR(rt_value); return img_format("DVP %s", rt); } @@ -7087,7 +7054,7 @@ static std::string EI(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); - std::string rt = GPR(copy(rt_value)); + std::string rt = GPR(rt_value); return img_format("EI %s", rt); } @@ -7107,7 +7074,7 @@ static std::string EMT(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); - std::string rt = GPR(copy(rt_value)); + std::string rt = GPR(rt_value); return img_format("EMT %s", rt); } @@ -7163,7 +7130,7 @@ static std::string EVP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); - std::string rt = GPR(copy(rt_value)); + std::string rt = GPR(rt_value); return img_format("EVP %s", rt); } @@ -7183,7 +7150,7 @@ static std::string EVPE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); - std::string rt = GPR(copy(rt_value)); + std::string rt = GPR(rt_value); return img_format("EVPE %s", rt); } @@ -7206,9 +7173,9 @@ static std::string EXT(uint64 instruction, Dis_info *info) uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction); uint64 lsb_value = extract_lsb_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string lsb = IMMEDIATE(copy(lsb_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string lsb = IMMEDIATE(lsb_value); std::string msbd = IMMEDIATE(encode_msbd_from_size(msbd_value)); return img_format("EXT %s, %s, %s, %s", rt, rs, lsb, msbd); @@ -7232,10 +7199,10 @@ static std::string EXTD(uint64 instruction, Dis_info *info) uint64 rd_value = extract_rd_15_14_13_12_11(instruction); uint64 shift_value = extract_shift_10_9_8_7_6(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); - std::string shift = IMMEDIATE(copy(shift_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); + std::string shift = IMMEDIATE(shift_value); return img_format("EXTD %s, %s, %s, %s", rd, rs, rt, shift); } @@ -7258,10 +7225,10 @@ static std::string EXTD32(uint64 instruction, Dis_info *info) uint64 rd_value = extract_rd_15_14_13_12_11(instruction); uint64 shift_value = extract_shift_10_9_8_7_6(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); - std::string shift = IMMEDIATE(copy(shift_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); + std::string shift = IMMEDIATE(shift_value); return img_format("EXTD32 %s, %s, %s, %s", rd, rs, rt, shift); } @@ -7283,9 +7250,9 @@ static std::string EXTPDP(uint64 instruction, Dis_info *info) uint64 size_value = extract_size_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ac = AC(copy(ac_value)); - std::string size = IMMEDIATE(copy(size_value)); + std::string rt = GPR(rt_value); + std::string ac = AC(ac_value); + std::string size = IMMEDIATE(size_value); return img_format("EXTPDP %s, %s, %s", rt, ac, size); } @@ -7307,9 +7274,9 @@ static std::string EXTPDPV(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); return img_format("EXTPDPV %s, %s, %s", rt, ac, rs); } @@ -7331,9 +7298,9 @@ static std::string EXTP(uint64 instruction, Dis_info *info) uint64 size_value = extract_size_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ac = AC(copy(ac_value)); - std::string size = IMMEDIATE(copy(size_value)); + std::string rt = GPR(rt_value); + std::string ac = AC(ac_value); + std::string size = IMMEDIATE(size_value); return img_format("EXTP %s, %s, %s", rt, ac, size); } @@ -7355,9 +7322,9 @@ static std::string EXTPV(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); return img_format("EXTPV %s, %s, %s", rt, ac, rs); } @@ -7380,9 +7347,9 @@ static std::string EXTR_RS_W(uint64 instruction, Dis_info *info) uint64 shift_value = extract_shift_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ac = AC(copy(ac_value)); - std::string shift = IMMEDIATE(copy(shift_value)); + std::string rt = GPR(rt_value); + std::string ac = AC(ac_value); + std::string shift = IMMEDIATE(shift_value); return img_format("EXTR_RS.W %s, %s, %s", rt, ac, shift); } @@ -7405,9 +7372,9 @@ static std::string EXTR_R_W(uint64 instruction, Dis_info *info) uint64 shift_value = extract_shift_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ac = AC(copy(ac_value)); - std::string shift = IMMEDIATE(copy(shift_value)); + std::string rt = GPR(rt_value); + std::string ac = AC(ac_value); + std::string shift = IMMEDIATE(shift_value); return img_format("EXTR_R.W %s, %s, %s", rt, ac, shift); } @@ -7430,9 +7397,9 @@ static std::string EXTR_S_H(uint64 instruction, Dis_info *info) uint64 shift_value = extract_shift_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ac = AC(copy(ac_value)); - std::string shift = IMMEDIATE(copy(shift_value)); + std::string rt = GPR(rt_value); + std::string ac = AC(ac_value); + std::string shift = IMMEDIATE(shift_value); return img_format("EXTR_S.H %s, %s, %s", rt, ac, shift); } @@ -7455,9 +7422,9 @@ static std::string EXTR_W(uint64 instruction, Dis_info *info) uint64 shift_value = extract_shift_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ac = AC(copy(ac_value)); - std::string shift = IMMEDIATE(copy(shift_value)); + std::string rt = GPR(rt_value); + std::string ac = AC(ac_value); + std::string shift = IMMEDIATE(shift_value); return img_format("EXTR.W %s, %s, %s", rt, ac, shift); } @@ -7480,9 +7447,9 @@ static std::string EXTRV_RS_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); return img_format("EXTRV_RS.W %s, %s, %s", rt, ac, rs); } @@ -7505,9 +7472,9 @@ static std::string EXTRV_R_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); return img_format("EXTRV_R.W %s, %s, %s", rt, ac, rs); } @@ -7530,9 +7497,9 @@ static std::string EXTRV_S_H(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); return img_format("EXTRV_S.H %s, %s, %s", rt, ac, rs); } @@ -7555,9 +7522,9 @@ static std::string EXTRV_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); return img_format("EXTRV.W %s, %s, %s", rt, ac, rs); } @@ -7581,10 +7548,10 @@ static std::string EXTW(uint64 instruction, Dis_info *info) uint64 rd_value = extract_rd_15_14_13_12_11(instruction); uint64 shift_value = extract_shift_10_9_8_7_6(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); - std::string shift = IMMEDIATE(copy(shift_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); + std::string shift = IMMEDIATE(shift_value); return img_format("EXTW %s, %s, %s, %s", rd, rs, rt, shift); } @@ -7605,8 +7572,8 @@ static std::string FLOOR_L_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("FLOOR.L.D %s, %s", ft, fs); } @@ -7627,8 +7594,8 @@ static std::string FLOOR_L_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("FLOOR.L.S %s, %s", ft, fs); } @@ -7649,8 +7616,8 @@ static std::string FLOOR_W_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("FLOOR.W.D %s, %s", ft, fs); } @@ -7671,8 +7638,8 @@ static std::string FLOOR_W_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("FLOOR.W.S %s, %s", ft, fs); } @@ -7694,9 +7661,9 @@ static std::string FORK(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("FORK %s, %s, %s", rd, rs, rt); } @@ -7716,7 +7683,7 @@ static std::string HYPCALL(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_17_to_0(instruction); - std::string code = IMMEDIATE(copy(code_value)); + std::string code = IMMEDIATE(code_value); return img_format("HYPCALL %s", code); } @@ -7736,7 +7703,7 @@ static std::string HYPCALL_16_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_1_0(instruction); - std::string code = IMMEDIATE(copy(code_value)); + std::string code = IMMEDIATE(code_value); return img_format("HYPCALL %s", code); } @@ -7759,10 +7726,10 @@ static std::string INS(uint64 instruction, Dis_info *info) uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction); uint64 lsb_value = extract_lsb_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string pos = IMMEDIATE(encode_lsb_from_pos_and_size(lsb_value)); - std::string size = IMMEDIATE(encode_lsb_from_pos_and_size(msbd_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string pos = IMMEDIATE(lsb_value); + std::string size = IMMEDIATE(msbd_value); /* !!!!!!!!!! - no conversion function */ return img_format("INS %s, %s, %s, %s", rt, rs, pos, size); @@ -7784,8 +7751,8 @@ static std::string INSV(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("INSV %s, %s", rt, rs); } @@ -7823,7 +7790,7 @@ static std::string JALRC_16_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_9_8_7_6_5(instruction); - std::string rt = GPR(copy(rt_value)); + std::string rt = GPR(rt_value); return img_format("JALRC $%d, %s", 31, rt); } @@ -7844,8 +7811,8 @@ static std::string JALRC_32_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("JALRC %s, %s", rt, rs); } @@ -7866,8 +7833,8 @@ static std::string JALRC_HB(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("JALRC.HB %s, %s", rt, rs); } @@ -7887,7 +7854,7 @@ static std::string JRC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_9_8_7_6_5(instruction); - std::string rt = GPR(copy(rt_value)); + std::string rt = GPR(rt_value); return img_format("JRC %s", rt); } @@ -7910,7 +7877,7 @@ static std::string LB_16_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_1_0(instruction); std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string u = IMMEDIATE(u_value); std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); return img_format("LB %s, %s(%s)", rt3, u, rs3); @@ -7932,8 +7899,8 @@ static std::string LB_GP_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); return img_format("LB %s, %s($%d)", rt, u, 28); } @@ -7955,9 +7922,9 @@ static std::string LB_S9_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("LB %s, %s(%s)", rt, s, rs); } @@ -7979,9 +7946,9 @@ static std::string LB_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); + std::string rs = GPR(rs_value); return img_format("LB %s, %s(%s)", rt, u, rs); } @@ -8003,9 +7970,9 @@ static std::string LBE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("LBE %s, %s(%s)", rt, s, rs); } @@ -8028,7 +7995,7 @@ static std::string LBU_16_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_1_0(instruction); std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string u = IMMEDIATE(u_value); std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); return img_format("LBU %s, %s(%s)", rt3, u, rs3); @@ -8050,8 +8017,8 @@ static std::string LBU_GP_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); return img_format("LBU %s, %s($%d)", rt, u, 28); } @@ -8073,9 +8040,9 @@ static std::string LBU_S9_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("LBU %s, %s(%s)", rt, s, rs); } @@ -8097,9 +8064,9 @@ static std::string LBU_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); + std::string rs = GPR(rs_value); return img_format("LBU %s, %s(%s)", rt, u, rs); } @@ -8121,9 +8088,9 @@ static std::string LBUE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("LBUE %s, %s(%s)", rt, s, rs); } @@ -8145,9 +8112,9 @@ static std::string LBUX(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("LBUX %s, %s(%s)", rd, rs, rt); } @@ -8169,9 +8136,9 @@ static std::string LBX(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("LBX %s, %s(%s)", rd, rs, rt); } @@ -8192,8 +8159,8 @@ static std::string LD_GP_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_to_3__s3(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); return img_format("LD %s, %s($%d)", rt, u, 28); } @@ -8215,9 +8182,9 @@ static std::string LD_S9_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("LD %s, %s(%s)", rt, s, rs); } @@ -8239,9 +8206,9 @@ static std::string LD_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); + std::string rs = GPR(rs_value); return img_format("LD %s, %s(%s)", rt, u, rs); } @@ -8262,8 +8229,8 @@ static std::string LDC1_GP_(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_2__s2(instruction); - std::string ft = FPR(copy(ft_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string ft = FPR(ft_value); + std::string u = IMMEDIATE(u_value); return img_format("LDC1 %s, %s($%d)", ft, u, 28); } @@ -8285,9 +8252,9 @@ static std::string LDC1_S9_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string ft = FPR(copy(ft_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string ft = FPR(ft_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("LDC1 %s, %s(%s)", ft, s, rs); } @@ -8309,9 +8276,9 @@ static std::string LDC1_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string ft = FPR(copy(ft_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs = GPR(copy(rs_value)); + std::string ft = FPR(ft_value); + std::string u = IMMEDIATE(u_value); + std::string rs = GPR(rs_value); return img_format("LDC1 %s, %s(%s)", ft, u, rs); } @@ -8333,9 +8300,9 @@ static std::string LDC1XS(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ft_value = extract_ft_15_14_13_12_11(instruction); - std::string ft = FPR(copy(ft_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ft = FPR(ft_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("LDC1XS %s, %s(%s)", ft, rs, rt); } @@ -8357,9 +8324,9 @@ static std::string LDC1X(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ft_value = extract_ft_15_14_13_12_11(instruction); - std::string ft = FPR(copy(ft_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ft = FPR(ft_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("LDC1X %s, %s(%s)", ft, rs, rt); } @@ -8381,9 +8348,9 @@ static std::string LDC2(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string ct = CPR(copy(ct_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string ct = CPR(ct_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("LDC2 %s, %s(%s)", ct, s, rs); } @@ -8406,9 +8373,9 @@ static std::string LDM(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 count3_value = extract_count3_14_13_12(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); std::string count3 = IMMEDIATE(encode_count3_from_count(count3_value)); return img_format("LDM %s, %s(%s), %s", rt, s, rs, count3); @@ -8430,8 +8397,8 @@ static std::string LDPC_48_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 6, info); + std::string rt = GPR(rt_value); + std::string s = ADDRESS(s_value, 6, info); return img_format("LDPC %s, %s", rt, s); } @@ -8453,9 +8420,9 @@ static std::string LDX(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("LDX %s, %s(%s)", rd, rs, rt); } @@ -8477,9 +8444,9 @@ static std::string LDXS(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("LDXS %s, %s(%s)", rd, rs, rt); } @@ -8502,7 +8469,7 @@ static std::string LH_16_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_2_1__s1(instruction); std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string u = IMMEDIATE(u_value); std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); return img_format("LH %s, %s(%s)", rt3, u, rs3); @@ -8524,8 +8491,8 @@ static std::string LH_GP_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_1__s1(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); return img_format("LH %s, %s($%d)", rt, u, 28); } @@ -8547,9 +8514,9 @@ static std::string LH_S9_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("LH %s, %s(%s)", rt, s, rs); } @@ -8571,9 +8538,9 @@ static std::string LH_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); + std::string rs = GPR(rs_value); return img_format("LH %s, %s(%s)", rt, u, rs); } @@ -8595,9 +8562,9 @@ static std::string LHE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("LHE %s, %s(%s)", rt, s, rs); } @@ -8620,7 +8587,7 @@ static std::string LHU_16_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_2_1__s1(instruction); std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string u = IMMEDIATE(u_value); std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); return img_format("LHU %s, %s(%s)", rt3, u, rs3); @@ -8642,8 +8609,8 @@ static std::string LHU_GP_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_1__s1(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); return img_format("LHU %s, %s($%d)", rt, u, 28); } @@ -8665,9 +8632,9 @@ static std::string LHU_S9_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("LHU %s, %s(%s)", rt, s, rs); } @@ -8689,9 +8656,9 @@ static std::string LHU_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); + std::string rs = GPR(rs_value); return img_format("LHU %s, %s(%s)", rt, u, rs); } @@ -8713,9 +8680,9 @@ static std::string LHUE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("LHUE %s, %s(%s)", rt, s, rs); } @@ -8737,9 +8704,9 @@ static std::string LHUX(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("LHUX %s, %s(%s)", rd, rs, rt); } @@ -8761,9 +8728,9 @@ static std::string LHUXS(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("LHUXS %s, %s(%s)", rd, rs, rt); } @@ -8785,9 +8752,9 @@ static std::string LHXS(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("LHXS %s, %s(%s)", rd, rs, rt); } @@ -8809,9 +8776,9 @@ static std::string LHX(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("LHX %s, %s(%s)", rd, rs, rt); } @@ -8854,8 +8821,8 @@ static std::string LI_48_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); return img_format("LI %s, %s", rt, s); } @@ -8877,9 +8844,9 @@ static std::string LL(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_s2(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("LL %s, %s(%s)", rt, s, rs); } @@ -8901,9 +8868,9 @@ static std::string LLD(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_s3(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("LLD %s, %s(%s)", rt, s, rs); } @@ -8925,9 +8892,9 @@ static std::string LLDP(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ru_value = extract_ru_7_6_5_4_3(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ru = GPR(copy(ru_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string ru = GPR(ru_value); + std::string rs = GPR(rs_value); return img_format("LLDP %s, %s, (%s)", rt, ru, rs); } @@ -8949,9 +8916,9 @@ static std::string LLE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_s2(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("LLE %s, %s(%s)", rt, s, rs); } @@ -8973,9 +8940,9 @@ static std::string LLWP(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ru_value = extract_ru_7_6_5_4_3(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ru = GPR(copy(ru_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string ru = GPR(ru_value); + std::string rs = GPR(rs_value); return img_format("LLWP %s, %s, (%s)", rt, ru, rs); } @@ -8997,9 +8964,9 @@ static std::string LLWPE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ru_value = extract_ru_7_6_5_4_3(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ru = GPR(copy(ru_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string ru = GPR(ru_value); + std::string rs = GPR(rs_value); return img_format("LLWPE %s, %s, (%s)", rt, ru, rs); } @@ -9022,10 +8989,10 @@ static std::string LSA(uint64 instruction, Dis_info *info) uint64 rd_value = extract_rd_15_14_13_12_11(instruction); uint64 u2_value = extract_u2_10_9(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); - std::string u2 = IMMEDIATE(copy(u2_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); + std::string u2 = IMMEDIATE(u2_value); return img_format("LSA %s, %s, %s, %s", rd, rs, rt, u2); } @@ -9046,8 +9013,8 @@ static std::string LUI(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); int64 s_value = extract_s__se31_0_11_to_2_20_to_12_s12(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); return img_format("LUI %s, %%hi(%s)", rt, s); } @@ -9070,7 +9037,7 @@ static std::string LW_16_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_3_2_1_0__s2(instruction); std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string u = IMMEDIATE(u_value); std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); return img_format("LW %s, %s(%s)", rt3, u, rs3); @@ -9094,7 +9061,7 @@ static std::string LW_4X4_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_3_8__s2(instruction); std::string rt4 = GPR(decode_gpr_gpr4(rt4_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string u = IMMEDIATE(u_value); std::string rs4 = GPR(decode_gpr_gpr4(rs4_value)); return img_format("LW %s, %s(%s)", rt4, u, rs4); @@ -9116,8 +9083,8 @@ static std::string LW_GP_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_to_2__s2(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); return img_format("LW %s, %s($%d)", rt, u, 28); } @@ -9139,7 +9106,7 @@ static std::string LW_GP16_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_6_5_4_3_2_1_0__s2(instruction); std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string u = IMMEDIATE(u_value); return img_format("LW %s, %s($%d)", rt3, u, 28); } @@ -9161,9 +9128,9 @@ static std::string LW_S9_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("LW %s, %s(%s)", rt, s, rs); } @@ -9184,8 +9151,8 @@ static std::string LW_SP_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_9_8_7_6_5(instruction); uint64 u_value = extract_u_4_3_2_1_0__s2(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); return img_format("LW %s, %s($%d)", rt, u, 29); } @@ -9207,9 +9174,9 @@ static std::string LW_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); + std::string rs = GPR(rs_value); return img_format("LW %s, %s(%s)", rt, u, rs); } @@ -9230,8 +9197,8 @@ static std::string LWC1_GP_(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_2__s2(instruction); - std::string ft = FPR(copy(ft_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string ft = FPR(ft_value); + std::string u = IMMEDIATE(u_value); return img_format("LWC1 %s, %s($%d)", ft, u, 28); } @@ -9253,9 +9220,9 @@ static std::string LWC1_S9_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string ft = FPR(copy(ft_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string ft = FPR(ft_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("LWC1 %s, %s(%s)", ft, s, rs); } @@ -9277,9 +9244,9 @@ static std::string LWC1_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string ft = FPR(copy(ft_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs = GPR(copy(rs_value)); + std::string ft = FPR(ft_value); + std::string u = IMMEDIATE(u_value); + std::string rs = GPR(rs_value); return img_format("LWC1 %s, %s(%s)", ft, u, rs); } @@ -9301,9 +9268,9 @@ static std::string LWC1X(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ft_value = extract_ft_15_14_13_12_11(instruction); - std::string ft = FPR(copy(ft_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ft = FPR(ft_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("LWC1X %s, %s(%s)", ft, rs, rt); } @@ -9325,9 +9292,9 @@ static std::string LWC1XS(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ft_value = extract_ft_15_14_13_12_11(instruction); - std::string ft = FPR(copy(ft_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ft = FPR(ft_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("LWC1XS %s, %s(%s)", ft, rs, rt); } @@ -9349,9 +9316,9 @@ static std::string LWC2(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string ct = CPR(copy(ct_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string ct = CPR(ct_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("LWC2 %s, %s(%s)", ct, s, rs); } @@ -9373,9 +9340,9 @@ static std::string LWE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("LWE %s, %s(%s)", rt, s, rs); } @@ -9398,9 +9365,9 @@ static std::string LWM(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 count3_value = extract_count3_14_13_12(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); std::string count3 = IMMEDIATE(encode_count3_from_count(count3_value)); return img_format("LWM %s, %s(%s), %s", rt, s, rs, count3); @@ -9422,8 +9389,8 @@ static std::string LWPC_48_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 6, info); + std::string rt = GPR(rt_value); + std::string s = ADDRESS(s_value, 6, info); return img_format("LWPC %s, %s", rt, s); } @@ -9444,8 +9411,8 @@ static std::string LWU_GP_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_2__s2(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); return img_format("LWU %s, %s($%d)", rt, u, 28); } @@ -9467,9 +9434,9 @@ static std::string LWU_S9_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("LWU %s, %s(%s)", rt, s, rs); } @@ -9491,9 +9458,9 @@ static std::string LWU_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); + std::string rs = GPR(rs_value); return img_format("LWU %s, %s(%s)", rt, u, rs); } @@ -9515,9 +9482,9 @@ static std::string LWUX(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("LWUX %s, %s(%s)", rd, rs, rt); } @@ -9539,9 +9506,9 @@ static std::string LWUXS(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("LWUXS %s, %s(%s)", rd, rs, rt); } @@ -9563,9 +9530,9 @@ static std::string LWX(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("LWX %s, %s(%s)", rd, rs, rt); } @@ -9611,9 +9578,9 @@ static std::string LWXS_32_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("LWXS %s, %s(%s)", rd, rs, rt); } @@ -9636,9 +9603,9 @@ static std::string MADD_DSP_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("MADD %s, %s, %s", ac, rs, rt); } @@ -9660,9 +9627,9 @@ static std::string MADDF_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("MADDF.D %s, %s, %s", fd, fs, ft); } @@ -9684,9 +9651,9 @@ static std::string MADDF_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("MADDF.S %s, %s, %s", fd, fs, ft); } @@ -9709,9 +9676,9 @@ static std::string MADDU_DSP_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("MADDU %s, %s, %s", ac, rs, rt); } @@ -9734,9 +9701,9 @@ static std::string MAQ_S_W_PHL(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("MAQ_S.W.PHL %s, %s, %s", ac, rs, rt); } @@ -9759,9 +9726,9 @@ static std::string MAQ_S_W_PHR(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("MAQ_S.W.PHR %s, %s, %s", ac, rs, rt); } @@ -9784,9 +9751,9 @@ static std::string MAQ_SA_W_PHL(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("MAQ_SA.W.PHL %s, %s, %s", ac, rs, rt); } @@ -9809,9 +9776,9 @@ static std::string MAQ_SA_W_PHR(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("MAQ_SA.W.PHR %s, %s, %s", ac, rs, rt); } @@ -9833,9 +9800,9 @@ static std::string MAX_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("MAX.D %s, %s, %s", fd, fs, ft); } @@ -9857,9 +9824,9 @@ static std::string MAX_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("MAX.S %s, %s, %s", fd, fs, ft); } @@ -9881,9 +9848,9 @@ static std::string MAXA_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("MAXA.D %s, %s, %s", fd, fs, ft); } @@ -9905,9 +9872,9 @@ static std::string MAXA_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("MAXA.S %s, %s, %s", fd, fs, ft); } @@ -9929,9 +9896,9 @@ static std::string MFC0(uint64 instruction, Dis_info *info) uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - std::string rt = GPR(copy(rt_value)); - std::string c0s = CPR(copy(c0s_value)); - std::string sel = IMMEDIATE(copy(sel_value)); + std::string rt = GPR(rt_value); + std::string c0s = CPR(c0s_value); + std::string sel = IMMEDIATE(sel_value); return img_format("MFC0 %s, %s, %s", rt, c0s, sel); } @@ -9952,8 +9919,8 @@ static std::string MFC1(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string fs = FPR(copy(fs_value)); + std::string rt = GPR(rt_value); + std::string fs = FPR(fs_value); return img_format("MFC1 %s, %s", rt, fs); } @@ -9974,8 +9941,8 @@ static std::string MFC2(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string cs = CPR(copy(cs_value)); + std::string rt = GPR(rt_value); + std::string cs = CPR(cs_value); return img_format("MFC2 %s, %s", rt, cs); } @@ -9997,9 +9964,9 @@ static std::string MFGC0(uint64 instruction, Dis_info *info) uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - std::string rt = GPR(copy(rt_value)); - std::string c0s = CPR(copy(c0s_value)); - std::string sel = IMMEDIATE(copy(sel_value)); + std::string rt = GPR(rt_value); + std::string c0s = CPR(c0s_value); + std::string sel = IMMEDIATE(sel_value); return img_format("MFGC0 %s, %s, %s", rt, c0s, sel); } @@ -10021,9 +9988,9 @@ static std::string MFHC0(uint64 instruction, Dis_info *info) uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - std::string rt = GPR(copy(rt_value)); - std::string c0s = CPR(copy(c0s_value)); - std::string sel = IMMEDIATE(copy(sel_value)); + std::string rt = GPR(rt_value); + std::string c0s = CPR(c0s_value); + std::string sel = IMMEDIATE(sel_value); return img_format("MFHC0 %s, %s, %s", rt, c0s, sel); } @@ -10044,8 +10011,8 @@ static std::string MFHC1(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string fs = FPR(copy(fs_value)); + std::string rt = GPR(rt_value); + std::string fs = FPR(fs_value); return img_format("MFHC1 %s, %s", rt, fs); } @@ -10066,8 +10033,8 @@ static std::string MFHC2(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string cs = CPR(copy(cs_value)); + std::string rt = GPR(rt_value); + std::string cs = CPR(cs_value); return img_format("MFHC2 %s, %s", rt, cs); } @@ -10089,9 +10056,9 @@ static std::string MFHGC0(uint64 instruction, Dis_info *info) uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - std::string rt = GPR(copy(rt_value)); - std::string c0s = CPR(copy(c0s_value)); - std::string sel = IMMEDIATE(copy(sel_value)); + std::string rt = GPR(rt_value); + std::string c0s = CPR(c0s_value); + std::string sel = IMMEDIATE(sel_value); return img_format("MFHGC0 %s, %s, %s", rt, c0s, sel); } @@ -10111,8 +10078,8 @@ static std::string MFHI_DSP_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ac = AC(copy(ac_value)); + std::string rt = GPR(rt_value); + std::string ac = AC(ac_value); return img_format("MFHI %s, %s", rt, ac); } @@ -10135,10 +10102,10 @@ static std::string MFHTR(uint64 instruction, Dis_info *info) uint64 sel_value = extract_sel_15_14_13_12_11(instruction); uint64 u_value = extract_u_10(instruction); - std::string rt = GPR(copy(rt_value)); - std::string c0s = IMMEDIATE(copy(c0s_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string sel = IMMEDIATE(copy(sel_value)); + std::string rt = GPR(rt_value); + std::string c0s = IMMEDIATE(c0s_value); + std::string u = IMMEDIATE(u_value); + std::string sel = IMMEDIATE(sel_value); return img_format("MFHTR %s, %s, %s, %s", rt, c0s, u, sel); } @@ -10158,8 +10125,8 @@ static std::string MFLO_DSP_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ac = AC(copy(ac_value)); + std::string rt = GPR(rt_value); + std::string ac = AC(ac_value); return img_format("MFLO %s, %s", rt, ac); } @@ -10182,10 +10149,10 @@ static std::string MFTR(uint64 instruction, Dis_info *info) uint64 sel_value = extract_sel_15_14_13_12_11(instruction); uint64 u_value = extract_u_10(instruction); - std::string rt = GPR(copy(rt_value)); - std::string c0s = IMMEDIATE(copy(c0s_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string sel = IMMEDIATE(copy(sel_value)); + std::string rt = GPR(rt_value); + std::string c0s = IMMEDIATE(c0s_value); + std::string u = IMMEDIATE(u_value); + std::string sel = IMMEDIATE(sel_value); return img_format("MFTR %s, %s, %s, %s", rt, c0s, u, sel); } @@ -10207,9 +10174,9 @@ static std::string MIN_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("MIN.D %s, %s, %s", fd, fs, ft); } @@ -10231,9 +10198,9 @@ static std::string MIN_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("MIN.S %s, %s, %s", fd, fs, ft); } @@ -10255,9 +10222,9 @@ static std::string MINA_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("MINA.D %s, %s, %s", fd, fs, ft); } @@ -10279,9 +10246,9 @@ static std::string MINA_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("MINA.S %s, %s, %s", fd, fs, ft); } @@ -10303,9 +10270,9 @@ static std::string MOD(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("MOD %s, %s, %s", rd, rs, rt); } @@ -10327,9 +10294,9 @@ static std::string MODSUB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("MODSUB %s, %s, %s", rd, rs, rt); } @@ -10351,9 +10318,9 @@ static std::string MODU(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("MODU %s, %s, %s", rd, rs, rt); } @@ -10374,8 +10341,8 @@ static std::string MOV_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("MOV.D %s, %s", ft, fs); } @@ -10396,8 +10363,8 @@ static std::string MOV_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("MOV.S %s, %s", ft, fs); } @@ -10421,7 +10388,7 @@ static std::string MOVE_BALC(uint64 instruction, Dis_info *info) std::string rd1 = GPR(decode_gpr_gpr1(rd1_value)); std::string rtz4 = GPR(decode_gpr_gpr4_zero(rtz4_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4, info); + std::string s = ADDRESS(s_value, 4, info); return img_format("MOVE.BALC %s, %s, %s", rd1, rtz4, s); } @@ -10496,8 +10463,8 @@ static std::string MOVE(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_9_8_7_6_5(instruction); uint64 rs_value = extract_rs_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("MOVE %s, %s", rt, rs); } @@ -10519,9 +10486,9 @@ static std::string MOVN(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("MOVN %s, %s, %s", rd, rs, rt); } @@ -10543,9 +10510,9 @@ static std::string MOVZ(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("MOVZ %s, %s, %s", rd, rs, rt); } @@ -10567,9 +10534,9 @@ static std::string MSUB_DSP_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("MSUB %s, %s, %s", ac, rs, rt); } @@ -10591,9 +10558,9 @@ static std::string MSUBF_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("MSUBF.D %s, %s, %s", fd, fs, ft); } @@ -10615,9 +10582,9 @@ static std::string MSUBF_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("MSUBF.S %s, %s, %s", fd, fs, ft); } @@ -10639,9 +10606,9 @@ static std::string MSUBU_DSP_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("MSUBU %s, %s, %s", ac, rs, rt); } @@ -10663,9 +10630,9 @@ static std::string MTC0(uint64 instruction, Dis_info *info) uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - std::string rt = GPR(copy(rt_value)); - std::string c0s = CPR(copy(c0s_value)); - std::string sel = IMMEDIATE(copy(sel_value)); + std::string rt = GPR(rt_value); + std::string c0s = CPR(c0s_value); + std::string sel = IMMEDIATE(sel_value); return img_format("MTC0 %s, %s, %s", rt, c0s, sel); } @@ -10686,8 +10653,8 @@ static std::string MTC1(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string fs = FPR(copy(fs_value)); + std::string rt = GPR(rt_value); + std::string fs = FPR(fs_value); return img_format("MTC1 %s, %s", rt, fs); } @@ -10708,8 +10675,8 @@ static std::string MTC2(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string cs = CPR(copy(cs_value)); + std::string rt = GPR(rt_value); + std::string cs = CPR(cs_value); return img_format("MTC2 %s, %s", rt, cs); } @@ -10731,9 +10698,9 @@ static std::string MTGC0(uint64 instruction, Dis_info *info) uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - std::string rt = GPR(copy(rt_value)); - std::string c0s = CPR(copy(c0s_value)); - std::string sel = IMMEDIATE(copy(sel_value)); + std::string rt = GPR(rt_value); + std::string c0s = CPR(c0s_value); + std::string sel = IMMEDIATE(sel_value); return img_format("MTGC0 %s, %s, %s", rt, c0s, sel); } @@ -10755,9 +10722,9 @@ static std::string MTHC0(uint64 instruction, Dis_info *info) uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - std::string rt = GPR(copy(rt_value)); - std::string c0s = CPR(copy(c0s_value)); - std::string sel = IMMEDIATE(copy(sel_value)); + std::string rt = GPR(rt_value); + std::string c0s = CPR(c0s_value); + std::string sel = IMMEDIATE(sel_value); return img_format("MTHC0 %s, %s, %s", rt, c0s, sel); } @@ -10778,8 +10745,8 @@ static std::string MTHC1(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string fs = FPR(copy(fs_value)); + std::string rt = GPR(rt_value); + std::string fs = FPR(fs_value); return img_format("MTHC1 %s, %s", rt, fs); } @@ -10800,8 +10767,8 @@ static std::string MTHC2(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string cs = CPR(copy(cs_value)); + std::string rt = GPR(rt_value); + std::string cs = CPR(cs_value); return img_format("MTHC2 %s, %s", rt, cs); } @@ -10823,9 +10790,9 @@ static std::string MTHGC0(uint64 instruction, Dis_info *info) uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - std::string rt = GPR(copy(rt_value)); - std::string c0s = CPR(copy(c0s_value)); - std::string sel = IMMEDIATE(copy(sel_value)); + std::string rt = GPR(rt_value); + std::string c0s = CPR(c0s_value); + std::string sel = IMMEDIATE(sel_value); return img_format("MTHGC0 %s, %s, %s", rt, c0s, sel); } @@ -10845,8 +10812,8 @@ static std::string MTHI_DSP_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rs = GPR(copy(rs_value)); - std::string ac = AC(copy(ac_value)); + std::string rs = GPR(rs_value); + std::string ac = AC(ac_value); return img_format("MTHI %s, %s", rs, ac); } @@ -10866,8 +10833,8 @@ static std::string MTHLIP(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rs = GPR(copy(rs_value)); - std::string ac = AC(copy(ac_value)); + std::string rs = GPR(rs_value); + std::string ac = AC(ac_value); return img_format("MTHLIP %s, %s", rs, ac); } @@ -10890,10 +10857,10 @@ static std::string MTHTR(uint64 instruction, Dis_info *info) uint64 sel_value = extract_sel_15_14_13_12_11(instruction); uint64 u_value = extract_u_10(instruction); - std::string rt = GPR(copy(rt_value)); - std::string c0s = IMMEDIATE(copy(c0s_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string sel = IMMEDIATE(copy(sel_value)); + std::string rt = GPR(rt_value); + std::string c0s = IMMEDIATE(c0s_value); + std::string u = IMMEDIATE(u_value); + std::string sel = IMMEDIATE(sel_value); return img_format("MTHTR %s, %s, %s, %s", rt, c0s, u, sel); } @@ -10913,8 +10880,8 @@ static std::string MTLO_DSP_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rs = GPR(copy(rs_value)); - std::string ac = AC(copy(ac_value)); + std::string rs = GPR(rs_value); + std::string ac = AC(ac_value); return img_format("MTLO %s, %s", rs, ac); } @@ -10937,10 +10904,10 @@ static std::string MTTR(uint64 instruction, Dis_info *info) uint64 sel_value = extract_sel_15_14_13_12_11(instruction); uint64 u_value = extract_u_10(instruction); - std::string rt = GPR(copy(rt_value)); - std::string c0s = IMMEDIATE(copy(c0s_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string sel = IMMEDIATE(copy(sel_value)); + std::string rt = GPR(rt_value); + std::string c0s = IMMEDIATE(c0s_value); + std::string u = IMMEDIATE(u_value); + std::string sel = IMMEDIATE(sel_value); return img_format("MTTR %s, %s, %s, %s", rt, c0s, u, sel); } @@ -10962,9 +10929,9 @@ static std::string MUH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("MUH %s, %s, %s", rd, rs, rt); } @@ -10986,9 +10953,9 @@ static std::string MUHU(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("MUHU %s, %s, %s", rd, rs, rt); } @@ -11010,9 +10977,9 @@ static std::string MUL_32_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("MUL %s, %s, %s", rd, rs, rt); } @@ -11056,9 +11023,9 @@ static std::string MUL_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("MUL.D %s, %s, %s", fd, fs, ft); } @@ -11081,9 +11048,9 @@ static std::string MUL_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("MUL.PH %s, %s, %s", rd, rs, rt); } @@ -11106,9 +11073,9 @@ static std::string MUL_S_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("MUL_S.PH %s, %s, %s", rd, rs, rt); } @@ -11130,9 +11097,9 @@ static std::string MUL_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("MUL.S %s, %s, %s", fd, fs, ft); } @@ -11155,9 +11122,9 @@ static std::string MULEQ_S_W_PHL(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("MULEQ_S.W.PHL %s, %s, %s", rd, rs, rt); } @@ -11180,9 +11147,9 @@ static std::string MULEQ_S_W_PHR(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("MULEQ_S.W.PHR %s, %s, %s", rd, rs, rt); } @@ -11205,9 +11172,9 @@ static std::string MULEU_S_PH_QBL(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("MULEU_S.PH.QBL %s, %s, %s", rd, rs, rt); } @@ -11230,9 +11197,9 @@ static std::string MULEU_S_PH_QBR(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("MULEU_S.PH.QBR %s, %s, %s", rd, rs, rt); } @@ -11255,9 +11222,9 @@ static std::string MULQ_RS_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("MULQ_RS.PH %s, %s, %s", rd, rs, rt); } @@ -11280,9 +11247,9 @@ static std::string MULQ_RS_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("MULQ_RS.W %s, %s, %s", rd, rs, rt); } @@ -11305,9 +11272,9 @@ static std::string MULQ_S_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("MULQ_S.PH %s, %s, %s", rd, rs, rt); } @@ -11330,9 +11297,9 @@ static std::string MULQ_S_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("MULQ_S.W %s, %s, %s", rd, rs, rt); } @@ -11355,9 +11322,9 @@ static std::string MULSA_W_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("MULSA.W.PH %s, %s, %s", ac, rs, rt); } @@ -11380,9 +11347,9 @@ static std::string MULSAQ_S_W_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("MULSAQ_S.W.PH %s, %s, %s", ac, rs, rt); } @@ -11404,9 +11371,9 @@ static std::string MULT_DSP_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("MULT %s, %s, %s", ac, rs, rt); } @@ -11428,9 +11395,9 @@ static std::string MULTU_DSP_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ac = AC(ac_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("MULTU %s, %s, %s", ac, rs, rt); } @@ -11452,9 +11419,9 @@ static std::string MULU(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("MULU %s, %s, %s", rd, rs, rt); } @@ -11475,8 +11442,8 @@ static std::string NEG_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("NEG.D %s, %s", ft, fs); } @@ -11497,8 +11464,8 @@ static std::string NEG_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("NEG.S %s, %s", ft, fs); } @@ -11556,9 +11523,9 @@ static std::string NOR(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("NOR %s, %s, %s", rd, rs, rt); } @@ -11624,9 +11591,9 @@ static std::string OR_32_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("OR %s, %s, %s", rd, rs, rt); } @@ -11648,9 +11615,9 @@ static std::string ORI(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string u = IMMEDIATE(u_value); return img_format("ORI %s, %s, %s", rt, rs, u); } @@ -11673,9 +11640,9 @@ static std::string PACKRL_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("PACKRL.PH %s, %s, %s", rd, rs, rt); } @@ -11716,9 +11683,9 @@ static std::string PICK_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("PICK.PH %s, %s, %s", rd, rs, rt); } @@ -11741,9 +11708,9 @@ static std::string PICK_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("PICK.QB %s, %s, %s", rd, rs, rt); } @@ -11765,8 +11732,8 @@ static std::string PRECEQ_W_PHL(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("PRECEQ.W.PHL %s, %s", rt, rs); } @@ -11788,8 +11755,8 @@ static std::string PRECEQ_W_PHR(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("PRECEQ.W.PHR %s, %s", rt, rs); } @@ -11811,8 +11778,8 @@ static std::string PRECEQU_PH_QBLA(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("PRECEQU.PH.QBLA %s, %s", rt, rs); } @@ -11834,8 +11801,8 @@ static std::string PRECEQU_PH_QBL(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("PRECEQU.PH.QBL %s, %s", rt, rs); } @@ -11857,8 +11824,8 @@ static std::string PRECEQU_PH_QBRA(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("PRECEQU.PH.QBRA %s, %s", rt, rs); } @@ -11880,8 +11847,8 @@ static std::string PRECEQU_PH_QBR(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("PRECEQU.PH.QBR %s, %s", rt, rs); } @@ -11904,8 +11871,8 @@ static std::string PRECEU_PH_QBLA(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("PRECEU.PH.QBLA %s, %s", rt, rs); } @@ -11927,8 +11894,8 @@ static std::string PRECEU_PH_QBL(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("PRECEU.PH.QBL %s, %s", rt, rs); } @@ -11951,8 +11918,8 @@ static std::string PRECEU_PH_QBRA(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("PRECEU.PH.QBRA %s, %s", rt, rs); } @@ -11974,8 +11941,8 @@ static std::string PRECEU_PH_QBR(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("PRECEU.PH.QBR %s, %s", rt, rs); } @@ -11998,9 +11965,9 @@ static std::string PRECR_QB_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("PRECR.QB.PH %s, %s, %s", rd, rs, rt); } @@ -12023,9 +11990,9 @@ static std::string PRECR_SRA_PH_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13_12_11(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string sa = IMMEDIATE(copy(sa_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string sa = IMMEDIATE(sa_value); return img_format("PRECR_SRA.PH.W %s, %s, %s", rt, rs, sa); } @@ -12048,9 +12015,9 @@ static std::string PRECR_SRA_R_PH_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13_12_11(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string sa = IMMEDIATE(copy(sa_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string sa = IMMEDIATE(sa_value); return img_format("PRECR_SRA_R.PH.W %s, %s, %s", rt, rs, sa); } @@ -12073,9 +12040,9 @@ static std::string PRECRQ_PH_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("PRECRQ.PH.W %s, %s, %s", rd, rs, rt); } @@ -12098,9 +12065,9 @@ static std::string PRECRQ_QB_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("PRECRQ.QB.PH %s, %s, %s", rd, rs, rt); } @@ -12123,9 +12090,9 @@ static std::string PRECRQ_RS_PH_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("PRECRQ_RS.PH.W %s, %s, %s", rd, rs, rt); } @@ -12148,9 +12115,9 @@ static std::string PRECRQU_S_QB_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("PRECRQU_S.QB.PH %s, %s, %s", rd, rs, rt); } @@ -12172,9 +12139,9 @@ static std::string PREF_S9_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string hint = IMMEDIATE(copy(hint_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string hint = IMMEDIATE(hint_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("PREF %s, %s(%s)", hint, s, rs); } @@ -12196,9 +12163,9 @@ static std::string PREF_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string hint = IMMEDIATE(copy(hint_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs = GPR(copy(rs_value)); + std::string hint = IMMEDIATE(hint_value); + std::string u = IMMEDIATE(u_value); + std::string rs = GPR(rs_value); return img_format("PREF %s, %s(%s)", hint, u, rs); } @@ -12220,9 +12187,9 @@ static std::string PREFE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string hint = IMMEDIATE(copy(hint_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string hint = IMMEDIATE(hint_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("PREFE %s, %s(%s)", hint, s, rs); } @@ -12244,9 +12211,9 @@ static std::string PREPEND(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13_12_11(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string sa = IMMEDIATE(copy(sa_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string sa = IMMEDIATE(sa_value); return img_format("PREPEND %s, %s, %s", rt, rs, sa); } @@ -12266,8 +12233,8 @@ static std::string RADDU_W_QB(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("RADDU.W.QB %s, %s", rt, rs); } @@ -12287,8 +12254,8 @@ static std::string RDDSP(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 mask_value = extract_mask_20_19_18_17_16_15_14(instruction); - std::string rt = GPR(copy(rt_value)); - std::string mask = IMMEDIATE(copy(mask_value)); + std::string rt = GPR(rt_value); + std::string mask = IMMEDIATE(mask_value); return img_format("RDDSP %s, %s", rt, mask); } @@ -12310,9 +12277,9 @@ static std::string RDHWR(uint64 instruction, Dis_info *info) uint64 hs_value = extract_hs_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_13_12_11(instruction); - std::string rt = GPR(copy(rt_value)); - std::string hs = CPR(copy(hs_value)); - std::string sel = IMMEDIATE(copy(sel_value)); + std::string rt = GPR(rt_value); + std::string hs = CPR(hs_value); + std::string sel = IMMEDIATE(sel_value); return img_format("RDHWR %s, %s, %s", rt, hs, sel); } @@ -12333,8 +12300,8 @@ static std::string RDPGPR(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("RDPGPR %s, %s", rt, rs); } @@ -12355,8 +12322,8 @@ static std::string RECIP_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("RECIP.D %s, %s", ft, fs); } @@ -12377,8 +12344,8 @@ static std::string RECIP_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("RECIP.S %s, %s", ft, fs); } @@ -12399,8 +12366,8 @@ static std::string REPL_PH(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); int64 s_value = extract_s__se9_20_19_18_17_16_15_14_13_12_11(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); return img_format("REPL.PH %s, %s", rt, s); } @@ -12421,8 +12388,8 @@ static std::string REPL_QB(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_19_18_17_16_15_14_13(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); return img_format("REPL.QB %s, %s", rt, u); } @@ -12443,8 +12410,8 @@ static std::string REPLV_PH(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("REPLV.PH %s, %s", rt, rs); } @@ -12464,8 +12431,8 @@ static std::string REPLV_QB(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("REPLV.QB %s, %s", rt, rs); } @@ -12488,7 +12455,7 @@ static std::string RESTORE_32_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3__s3(instruction); uint64 gp_value = extract_gp_2(instruction); - std::string u = IMMEDIATE(copy(u_value)); + std::string u = IMMEDIATE(u_value); return img_format("RESTORE %s%s", u, save_restore_list(rt_value, count_value, gp_value)); } @@ -12510,7 +12477,7 @@ static std::string RESTORE_JRC_16_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_7_6_5_4__s4(instruction); uint64 count_value = extract_count_3_2_1_0(instruction); - std::string u = IMMEDIATE(copy(u_value)); + std::string u = IMMEDIATE(u_value); return img_format("RESTORE.JRC %s%s", u, save_restore_list(encode_rt1_from_rt(rt1_value), count_value, 0)); } @@ -12533,7 +12500,7 @@ static std::string RESTORE_JRC_32_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3__s3(instruction); uint64 gp_value = extract_gp_2(instruction); - std::string u = IMMEDIATE(copy(u_value)); + std::string u = IMMEDIATE(u_value); return img_format("RESTORE.JRC %s%s", u, save_restore_list(rt_value, count_value, gp_value)); } @@ -12554,8 +12521,8 @@ static std::string RESTOREF(uint64 instruction, Dis_info *info) uint64 count_value = extract_count_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3__s3(instruction); - std::string u = IMMEDIATE(copy(u_value)); - std::string count = IMMEDIATE(copy(count_value)); + std::string u = IMMEDIATE(u_value); + std::string count = IMMEDIATE(count_value); return img_format("RESTOREF %s, %s", u, count); } @@ -12576,8 +12543,8 @@ static std::string RINT_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("RINT.D %s, %s", ft, fs); } @@ -12598,8 +12565,8 @@ static std::string RINT_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("RINT.S %s, %s", ft, fs); } @@ -12621,9 +12588,9 @@ static std::string ROTR(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string shift = IMMEDIATE(copy(shift_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string shift = IMMEDIATE(shift_value); return img_format("ROTR %s, %s, %s", rt, rs, shift); } @@ -12645,9 +12612,9 @@ static std::string ROTRV(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("ROTRV %s, %s, %s", rd, rs, rt); } @@ -12671,11 +12638,11 @@ static std::string ROTX(uint64 instruction, Dis_info *info) uint64 stripe_value = extract_stripe_6(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string shift = IMMEDIATE(copy(shift_value)); - std::string shiftx = IMMEDIATE(copy(shiftx_value)); - std::string stripe = IMMEDIATE(copy(stripe_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string shift = IMMEDIATE(shift_value); + std::string shiftx = IMMEDIATE(shiftx_value); + std::string stripe = IMMEDIATE(stripe_value); return img_format("ROTX %s, %s, %s, %s, %s", rt, rs, shift, shiftx, stripe); @@ -12697,8 +12664,8 @@ static std::string ROUND_L_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("ROUND.L.D %s, %s", ft, fs); } @@ -12719,8 +12686,8 @@ static std::string ROUND_L_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("ROUND.L.S %s, %s", ft, fs); } @@ -12741,8 +12708,8 @@ static std::string ROUND_W_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("ROUND.W.D %s, %s", ft, fs); } @@ -12763,8 +12730,8 @@ static std::string ROUND_W_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("ROUND.W.S %s, %s", ft, fs); } @@ -12785,8 +12752,8 @@ static std::string RSQRT_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("RSQRT.D %s, %s", ft, fs); } @@ -12807,8 +12774,8 @@ static std::string RSQRT_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("RSQRT.S %s, %s", ft, fs); } @@ -12830,7 +12797,7 @@ static std::string SAVE_16_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_7_6_5_4__s4(instruction); uint64 count_value = extract_count_3_2_1_0(instruction); - std::string u = IMMEDIATE(copy(u_value)); + std::string u = IMMEDIATE(u_value); return img_format("SAVE %s%s", u, save_restore_list(encode_rt1_from_rt(rt1_value), count_value, 0)); } @@ -12853,7 +12820,7 @@ static std::string SAVE_32_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3__s3(instruction); uint64 gp_value = extract_gp_2(instruction); - std::string u = IMMEDIATE(copy(u_value)); + std::string u = IMMEDIATE(u_value); return img_format("SAVE %s%s", u, save_restore_list(rt_value, count_value, gp_value)); } @@ -12874,8 +12841,8 @@ static std::string SAVEF(uint64 instruction, Dis_info *info) uint64 count_value = extract_count_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3__s3(instruction); - std::string u = IMMEDIATE(copy(u_value)); - std::string count = IMMEDIATE(copy(count_value)); + std::string u = IMMEDIATE(u_value); + std::string count = IMMEDIATE(count_value); return img_format("SAVEF %s, %s", u, count); } @@ -12898,7 +12865,7 @@ static std::string SB_16_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_1_0(instruction); std::string rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string u = IMMEDIATE(u_value); std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); return img_format("SB %s, %s(%s)", rtz3, u, rs3); @@ -12920,8 +12887,8 @@ static std::string SB_GP_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); return img_format("SB %s, %s($%d)", rt, u, 28); } @@ -12943,9 +12910,9 @@ static std::string SB_S9_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("SB %s, %s(%s)", rt, s, rs); } @@ -12967,9 +12934,9 @@ static std::string SB_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); + std::string rs = GPR(rs_value); return img_format("SB %s, %s(%s)", rt, u, rs); } @@ -12991,9 +12958,9 @@ static std::string SBE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("SBE %s, %s(%s)", rt, s, rs); } @@ -13015,9 +12982,9 @@ static std::string SBX(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("SBX %s, %s(%s)", rd, rs, rt); } @@ -13039,9 +13006,9 @@ static std::string SC(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_s2(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("SC %s, %s(%s)", rt, s, rs); } @@ -13063,9 +13030,9 @@ static std::string SCD(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_s3(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("SCD %s, %s(%s)", rt, s, rs); } @@ -13087,9 +13054,9 @@ static std::string SCDP(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ru_value = extract_ru_7_6_5_4_3(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ru = GPR(copy(ru_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string ru = GPR(ru_value); + std::string rs = GPR(rs_value); return img_format("SCDP %s, %s, (%s)", rt, ru, rs); } @@ -13111,9 +13078,9 @@ static std::string SCE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_s2(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("SCE %s, %s(%s)", rt, s, rs); } @@ -13135,9 +13102,9 @@ static std::string SCWP(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ru_value = extract_ru_7_6_5_4_3(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ru = GPR(copy(ru_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string ru = GPR(ru_value); + std::string rs = GPR(rs_value); return img_format("SCWP %s, %s, (%s)", rt, ru, rs); } @@ -13159,9 +13126,9 @@ static std::string SCWPE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ru_value = extract_ru_7_6_5_4_3(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ru = GPR(copy(ru_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string ru = GPR(ru_value); + std::string rs = GPR(rs_value); return img_format("SCWPE %s, %s, (%s)", rt, ru, rs); } @@ -13182,8 +13149,8 @@ static std::string SD_GP_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_to_3__s3(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); return img_format("SD %s, %s($%d)", rt, u, 28); } @@ -13205,9 +13172,9 @@ static std::string SD_S9_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("SD %s, %s(%s)", rt, s, rs); } @@ -13229,9 +13196,9 @@ static std::string SD_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); + std::string rs = GPR(rs_value); return img_format("SD %s, %s(%s)", rt, u, rs); } @@ -13251,7 +13218,7 @@ static std::string SDBBP_16_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_2_1_0(instruction); - std::string code = IMMEDIATE(copy(code_value)); + std::string code = IMMEDIATE(code_value); return img_format("SDBBP %s", code); } @@ -13271,7 +13238,7 @@ static std::string SDBBP_32_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_18_to_0(instruction); - std::string code = IMMEDIATE(copy(code_value)); + std::string code = IMMEDIATE(code_value); return img_format("SDBBP %s", code); } @@ -13292,8 +13259,8 @@ static std::string SDC1_GP_(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_2__s2(instruction); - std::string ft = FPR(copy(ft_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string ft = FPR(ft_value); + std::string u = IMMEDIATE(u_value); return img_format("SDC1 %s, %s($%d)", ft, u, 28); } @@ -13315,9 +13282,9 @@ static std::string SDC1_S9_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string ft = FPR(copy(ft_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string ft = FPR(ft_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("SDC1 %s, %s(%s)", ft, s, rs); } @@ -13339,9 +13306,9 @@ static std::string SDC1_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string ft = FPR(copy(ft_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs = GPR(copy(rs_value)); + std::string ft = FPR(ft_value); + std::string u = IMMEDIATE(u_value); + std::string rs = GPR(rs_value); return img_format("SDC1 %s, %s(%s)", ft, u, rs); } @@ -13363,9 +13330,9 @@ static std::string SDC1X(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ft_value = extract_ft_15_14_13_12_11(instruction); - std::string ft = FPR(copy(ft_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ft = FPR(ft_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("SDC1X %s, %s(%s)", ft, rs, rt); } @@ -13387,9 +13354,9 @@ static std::string SDC1XS(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ft_value = extract_ft_15_14_13_12_11(instruction); - std::string ft = FPR(copy(ft_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ft = FPR(ft_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("SDC1XS %s, %s(%s)", ft, rs, rt); } @@ -13411,9 +13378,9 @@ static std::string SDC2(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string cs = CPR(copy(cs_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string cs = CPR(cs_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("SDC2 %s, %s(%s)", cs, s, rs); } @@ -13436,9 +13403,9 @@ static std::string SDM(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 count3_value = extract_count3_14_13_12(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); std::string count3 = IMMEDIATE(encode_count3_from_count(count3_value)); return img_format("SDM %s, %s(%s), %s", rt, s, rs, count3); @@ -13460,8 +13427,8 @@ static std::string SDPC_48_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 6, info); + std::string rt = GPR(rt_value); + std::string s = ADDRESS(s_value, 6, info); return img_format("SDPC %s, %s", rt, s); } @@ -13483,9 +13450,9 @@ static std::string SDXS(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("SDXS %s, %s(%s)", rd, rs, rt); } @@ -13507,9 +13474,9 @@ static std::string SDX(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("SDX %s, %s(%s)", rd, rs, rt); } @@ -13530,8 +13497,8 @@ static std::string SEB(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("SEB %s, %s", rt, rs); } @@ -13552,8 +13519,8 @@ static std::string SEH(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("SEH %s, %s", rt, rs); } @@ -13575,9 +13542,9 @@ static std::string SEL_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("SEL.D %s, %s, %s", fd, fs, ft); } @@ -13599,9 +13566,9 @@ static std::string SEL_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("SEL.S %s, %s, %s", fd, fs, ft); } @@ -13623,9 +13590,9 @@ static std::string SELEQZ_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("SELEQZ.D %s, %s, %s", fd, fs, ft); } @@ -13647,9 +13614,9 @@ static std::string SELEQZ_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("SELEQZ.S %s, %s, %s", fd, fs, ft); } @@ -13671,9 +13638,9 @@ static std::string SELNEZ_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("SELNEZ.D %s, %s, %s", fd, fs, ft); } @@ -13695,9 +13662,9 @@ static std::string SELNEZ_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("SELNEZ.S %s, %s, %s", fd, fs, ft); } @@ -13719,9 +13686,9 @@ static std::string SEQI(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string u = IMMEDIATE(u_value); return img_format("SEQI %s, %s, %s", rt, rs, u); } @@ -13744,7 +13711,7 @@ static std::string SH_16_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_2_1__s1(instruction); std::string rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string u = IMMEDIATE(u_value); std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); return img_format("SH %s, %s(%s)", rtz3, u, rs3); @@ -13766,8 +13733,8 @@ static std::string SH_GP_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_1__s1(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); return img_format("SH %s, %s($%d)", rt, u, 28); } @@ -13789,9 +13756,9 @@ static std::string SH_S9_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("SH %s, %s(%s)", rt, s, rs); } @@ -13813,9 +13780,9 @@ static std::string SH_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); + std::string rs = GPR(rs_value); return img_format("SH %s, %s(%s)", rt, u, rs); } @@ -13837,9 +13804,9 @@ static std::string SHE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("SHE %s, %s(%s)", rt, s, rs); } @@ -13860,8 +13827,8 @@ static std::string SHILO(uint64 instruction, Dis_info *info) int64 shift_value = extract_shift__se5_21_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string shift = IMMEDIATE(copy(shift_value)); - std::string ac = AC(copy(ac_value)); + std::string shift = IMMEDIATE(shift_value); + std::string ac = AC(ac_value); return img_format("SHILO %s, %s", ac, shift); } @@ -13882,8 +13849,8 @@ static std::string SHILOV(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rs = GPR(copy(rs_value)); - std::string ac = AC(copy(ac_value)); + std::string rs = GPR(rs_value); + std::string ac = AC(ac_value); return img_format("SHILOV %s, %s", ac, rs); } @@ -13905,9 +13872,9 @@ static std::string SHLL_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13_12(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string sa = IMMEDIATE(copy(sa_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string sa = IMMEDIATE(sa_value); return img_format("SHLL.PH %s, %s, %s", rt, rs, sa); } @@ -13929,9 +13896,9 @@ static std::string SHLL_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string sa = IMMEDIATE(copy(sa_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string sa = IMMEDIATE(sa_value); return img_format("SHLL.QB %s, %s, %s", rt, rs, sa); } @@ -13954,9 +13921,9 @@ static std::string SHLL_S_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13_12(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string sa = IMMEDIATE(copy(sa_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string sa = IMMEDIATE(sa_value); return img_format("SHLL_S.PH %s, %s, %s", rt, rs, sa); } @@ -13978,9 +13945,9 @@ static std::string SHLL_S_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13_12_11(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string sa = IMMEDIATE(copy(sa_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string sa = IMMEDIATE(sa_value); return img_format("SHLL_S.W %s, %s, %s", rt, rs, sa); } @@ -14003,9 +13970,9 @@ static std::string SHLLV_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rd = GPR(rd_value); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("SHLLV.PH %s, %s, %s", rd, rt, rs); } @@ -14027,9 +13994,9 @@ static std::string SHLLV_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rd = GPR(rd_value); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("SHLLV.QB %s, %s, %s", rd, rt, rs); } @@ -14052,9 +14019,9 @@ static std::string SHLLV_S_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rd = GPR(rd_value); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("SHLLV_S.PH %s, %s, %s", rd, rt, rs); } @@ -14076,9 +14043,9 @@ static std::string SHLLV_S_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rd = GPR(rd_value); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("SHLLV_S.W %s, %s, %s", rd, rt, rs); } @@ -14100,9 +14067,9 @@ static std::string SHRA_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13_12(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string sa = IMMEDIATE(copy(sa_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string sa = IMMEDIATE(sa_value); return img_format("SHRA.PH %s, %s, %s", rt, rs, sa); } @@ -14124,9 +14091,9 @@ static std::string SHRA_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string sa = IMMEDIATE(copy(sa_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string sa = IMMEDIATE(sa_value); return img_format("SHRA.QB %s, %s, %s", rt, rs, sa); } @@ -14148,9 +14115,9 @@ static std::string SHRA_R_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13_12(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string sa = IMMEDIATE(copy(sa_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string sa = IMMEDIATE(sa_value); return img_format("SHRA_R.PH %s, %s, %s", rt, rs, sa); } @@ -14172,9 +14139,9 @@ static std::string SHRA_R_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string sa = IMMEDIATE(copy(sa_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string sa = IMMEDIATE(sa_value); return img_format("SHRA_R.QB %s, %s, %s", rt, rs, sa); } @@ -14196,9 +14163,9 @@ static std::string SHRA_R_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13_12_11(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string sa = IMMEDIATE(copy(sa_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string sa = IMMEDIATE(sa_value); return img_format("SHRA_R.W %s, %s, %s", rt, rs, sa); } @@ -14220,9 +14187,9 @@ static std::string SHRAV_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rd = GPR(rd_value); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("SHRAV.PH %s, %s, %s", rd, rt, rs); } @@ -14244,9 +14211,9 @@ static std::string SHRAV_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rd = GPR(rd_value); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("SHRAV.QB %s, %s, %s", rd, rt, rs); } @@ -14268,9 +14235,9 @@ static std::string SHRAV_R_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rd = GPR(rd_value); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("SHRAV_R.PH %s, %s, %s", rd, rt, rs); } @@ -14292,9 +14259,9 @@ static std::string SHRAV_R_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rd = GPR(rd_value); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("SHRAV_R.QB %s, %s, %s", rd, rt, rs); } @@ -14316,9 +14283,9 @@ static std::string SHRAV_R_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rd = GPR(rd_value); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("SHRAV_R.W %s, %s, %s", rd, rt, rs); } @@ -14340,9 +14307,9 @@ static std::string SHRL_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13_12(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string sa = IMMEDIATE(copy(sa_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string sa = IMMEDIATE(sa_value); return img_format("SHRL.PH %s, %s, %s", rt, rs, sa); } @@ -14364,9 +14331,9 @@ static std::string SHRL_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string sa = IMMEDIATE(copy(sa_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string sa = IMMEDIATE(sa_value); return img_format("SHRL.QB %s, %s, %s", rt, rs, sa); } @@ -14389,9 +14356,9 @@ static std::string SHRLV_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rd = GPR(rd_value); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("SHRLV.PH %s, %s, %s", rd, rt, rs); } @@ -14413,9 +14380,9 @@ static std::string SHRLV_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rd = GPR(rd_value); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("SHRLV.QB %s, %s, %s", rd, rt, rs); } @@ -14437,9 +14404,9 @@ static std::string SHX(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("SHX %s, %s(%s)", rd, rs, rt); } @@ -14461,9 +14428,9 @@ static std::string SHXS(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("SHXS %s, %s(%s)", rd, rs, rt); } @@ -14483,7 +14450,7 @@ static std::string SIGRIE(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_18_to_0(instruction); - std::string code = IMMEDIATE(copy(code_value)); + std::string code = IMMEDIATE(code_value); return img_format("SIGRIE %s", code); } @@ -14529,9 +14496,9 @@ static std::string SLL_32_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string shift = IMMEDIATE(copy(shift_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string shift = IMMEDIATE(shift_value); return img_format("SLL %s, %s, %s", rt, rs, shift); } @@ -14553,9 +14520,9 @@ static std::string SLLV(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("SLLV %s, %s, %s", rd, rs, rt); } @@ -14577,9 +14544,9 @@ static std::string SLT(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("SLT %s, %s, %s", rd, rs, rt); } @@ -14601,9 +14568,9 @@ static std::string SLTI(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string u = IMMEDIATE(u_value); return img_format("SLTI %s, %s, %s", rt, rs, u); } @@ -14625,9 +14592,9 @@ static std::string SLTIU(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string u = IMMEDIATE(u_value); return img_format("SLTIU %s, %s, %s", rt, rs, u); } @@ -14649,9 +14616,9 @@ static std::string SLTU(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("SLTU %s, %s, %s", rd, rs, rt); } @@ -14673,9 +14640,9 @@ static std::string SOV(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("SOV %s, %s, %s", rd, rs, rt); } @@ -14695,7 +14662,7 @@ static std::string SPECIAL2(uint64 instruction, Dis_info *info) { uint64 op_value = extract_op_25_to_3(instruction); - std::string op = IMMEDIATE(copy(op_value)); + std::string op = IMMEDIATE(op_value); return img_format("SPECIAL2 %s", op); } @@ -14716,8 +14683,8 @@ static std::string SQRT_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("SQRT.D %s, %s", ft, fs); } @@ -14738,8 +14705,8 @@ static std::string SQRT_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("SQRT.S %s, %s", ft, fs); } @@ -14761,9 +14728,9 @@ static std::string SRA(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string shift = IMMEDIATE(copy(shift_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string shift = IMMEDIATE(shift_value); return img_format("SRA %s, %s, %s", rt, rs, shift); } @@ -14785,9 +14752,9 @@ static std::string SRAV(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("SRAV %s, %s, %s", rd, rs, rt); } @@ -14833,9 +14800,9 @@ static std::string SRL_32_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string shift = IMMEDIATE(copy(shift_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string shift = IMMEDIATE(shift_value); return img_format("SRL %s, %s, %s", rt, rs, shift); } @@ -14857,9 +14824,9 @@ static std::string SRLV(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("SRLV %s, %s, %s", rd, rs, rt); } @@ -14881,9 +14848,9 @@ static std::string SUB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("SUB %s, %s, %s", rd, rs, rt); } @@ -14905,9 +14872,9 @@ static std::string SUB_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("SUB.D %s, %s, %s", fd, fs, ft); } @@ -14929,9 +14896,9 @@ static std::string SUB_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + std::string fd = FPR(fd_value); + std::string fs = FPR(fs_value); + std::string ft = FPR(ft_value); return img_format("SUB.S %s, %s, %s", fd, fs, ft); } @@ -14953,9 +14920,9 @@ static std::string SUBQ_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("SUBQ.PH %s, %s, %s", rd, rs, rt); } @@ -14978,9 +14945,9 @@ static std::string SUBQ_S_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("SUBQ_S.PH %s, %s, %s", rd, rs, rt); } @@ -15003,9 +14970,9 @@ static std::string SUBQ_S_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("SUBQ_S.W %s, %s, %s", rd, rs, rt); } @@ -15028,9 +14995,9 @@ static std::string SUBQH_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("SUBQH.PH %s, %s, %s", rd, rs, rt); } @@ -15053,9 +15020,9 @@ static std::string SUBQH_R_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("SUBQH_R.PH %s, %s, %s", rd, rs, rt); } @@ -15078,9 +15045,9 @@ static std::string SUBQH_R_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("SUBQH_R.W %s, %s, %s", rd, rs, rt); } @@ -15103,9 +15070,9 @@ static std::string SUBQH_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("SUBQH.W %s, %s, %s", rd, rs, rt); } @@ -15151,9 +15118,9 @@ static std::string SUBU_32_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("SUBU %s, %s, %s", rd, rs, rt); } @@ -15175,9 +15142,9 @@ static std::string SUBU_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("SUBU.PH %s, %s, %s", rd, rs, rt); } @@ -15199,9 +15166,9 @@ static std::string SUBU_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("SUBU.QB %s, %s, %s", rd, rs, rt); } @@ -15224,9 +15191,9 @@ static std::string SUBU_S_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("SUBU_S.PH %s, %s, %s", rd, rs, rt); } @@ -15249,9 +15216,9 @@ static std::string SUBU_S_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("SUBU_S.QB %s, %s, %s", rd, rs, rt); } @@ -15274,9 +15241,9 @@ static std::string SUBUH_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("SUBUH.QB %s, %s, %s", rd, rs, rt); } @@ -15299,9 +15266,9 @@ static std::string SUBUH_R_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("SUBUH_R.QB %s, %s, %s", rd, rs, rt); } @@ -15324,7 +15291,7 @@ static std::string SW_16_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_3_2_1_0__s2(instruction); std::string rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string u = IMMEDIATE(u_value); std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); return img_format("SW %s, %s(%s)", rtz3, u, rs3); @@ -15348,7 +15315,7 @@ static std::string SW_4X4_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_3_8__s2(instruction); std::string rtz4 = GPR(decode_gpr_gpr4_zero(rtz4_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string u = IMMEDIATE(u_value); std::string rs4 = GPR(decode_gpr_gpr4(rs4_value)); return img_format("SW %s, %s(%s)", rtz4, u, rs4); @@ -15371,7 +15338,7 @@ static std::string SW_GP16_(uint64 instruction, Dis_info *info) uint64 rtz3_value = extract_rtz3_9_8_7(instruction); std::string rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string u = IMMEDIATE(u_value); return img_format("SW %s, %s($%d)", rtz3, u, 28); } @@ -15392,8 +15359,8 @@ static std::string SW_GP_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_to_2__s2(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); return img_format("SW %s, %s($%d)", rt, u, 28); } @@ -15415,9 +15382,9 @@ static std::string SW_S9_(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("SW %s, %s(%s)", rt, s, rs); } @@ -15438,8 +15405,8 @@ static std::string SW_SP_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_9_8_7_6_5(instruction); uint64 u_value = extract_u_4_3_2_1_0__s2(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); return img_format("SW %s, %s($%d)", rt, u, 29); } @@ -15461,9 +15428,9 @@ static std::string SW_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string u = IMMEDIATE(u_value); + std::string rs = GPR(rs_value); return img_format("SW %s, %s(%s)", rt, u, rs); } @@ -15484,8 +15451,8 @@ static std::string SWC1_GP_(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_2__s2(instruction); - std::string ft = FPR(copy(ft_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string ft = FPR(ft_value); + std::string u = IMMEDIATE(u_value); return img_format("SWC1 %s, %s($%d)", ft, u, 28); } @@ -15507,9 +15474,9 @@ static std::string SWC1_S9_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string ft = FPR(copy(ft_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string ft = FPR(ft_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("SWC1 %s, %s(%s)", ft, s, rs); } @@ -15531,9 +15498,9 @@ static std::string SWC1_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string ft = FPR(copy(ft_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs = GPR(copy(rs_value)); + std::string ft = FPR(ft_value); + std::string u = IMMEDIATE(u_value); + std::string rs = GPR(rs_value); return img_format("SWC1 %s, %s(%s)", ft, u, rs); } @@ -15555,9 +15522,9 @@ static std::string SWC1X(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ft_value = extract_ft_15_14_13_12_11(instruction); - std::string ft = FPR(copy(ft_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ft = FPR(ft_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("SWC1X %s, %s(%s)", ft, rs, rt); } @@ -15579,9 +15546,9 @@ static std::string SWC1XS(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ft_value = extract_ft_15_14_13_12_11(instruction); - std::string ft = FPR(copy(ft_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string ft = FPR(ft_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("SWC1XS %s, %s(%s)", ft, rs, rt); } @@ -15603,9 +15570,9 @@ static std::string SWC2(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string cs = CPR(copy(cs_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string cs = CPR(cs_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("SWC2 %s, %s(%s)", cs, s, rs); } @@ -15627,9 +15594,9 @@ static std::string SWE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("SWE %s, %s(%s)", rt, s, rs); } @@ -15652,9 +15619,9 @@ static std::string SWM(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 count3_value = extract_count3_14_13_12(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); std::string count3 = IMMEDIATE(encode_count3_from_count(count3_value)); return img_format("SWM %s, %s(%s), %s", rt, s, rs, count3); @@ -15676,8 +15643,8 @@ static std::string SWPC_48_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 6, info); + std::string rt = GPR(rt_value); + std::string s = ADDRESS(s_value, 6, info); return img_format("SWPC %s, %s", rt, s); } @@ -15699,9 +15666,9 @@ static std::string SWX(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("SWX %s, %s(%s)", rd, rs, rt); } @@ -15723,9 +15690,9 @@ static std::string SWXS(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("SWXS %s, %s(%s)", rd, rs, rt); } @@ -15745,7 +15712,7 @@ static std::string SYNC(uint64 instruction, Dis_info *info) { uint64 stype_value = extract_stype_20_19_18_17_16(instruction); - std::string stype = IMMEDIATE(copy(stype_value)); + std::string stype = IMMEDIATE(stype_value); return img_format("SYNC %s", stype); } @@ -15766,8 +15733,8 @@ static std::string SYNCI(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("SYNCI %s(%s)", s, rs); } @@ -15788,8 +15755,8 @@ static std::string SYNCIE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("SYNCIE %s(%s)", s, rs); } @@ -15809,7 +15776,7 @@ static std::string SYSCALL_16_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_1_0(instruction); - std::string code = IMMEDIATE(copy(code_value)); + std::string code = IMMEDIATE(code_value); return img_format("SYSCALL %s", code); } @@ -15827,7 +15794,7 @@ static std::string SYSCALL_32_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_17_to_0(instruction); - std::string code = IMMEDIATE(copy(code_value)); + std::string code = IMMEDIATE(code_value); return img_format("SYSCALL %s", code); } @@ -15848,8 +15815,8 @@ static std::string TEQ(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("TEQ %s, %s", rs, rt); } @@ -16086,8 +16053,8 @@ static std::string TNE(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("TNE %s, %s", rs, rt); } @@ -16108,8 +16075,8 @@ static std::string TRUNC_L_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("TRUNC.L.D %s, %s", ft, fs); } @@ -16130,8 +16097,8 @@ static std::string TRUNC_L_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("TRUNC.L.S %s, %s", ft, fs); } @@ -16152,8 +16119,8 @@ static std::string TRUNC_W_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("TRUNC.W.D %s, %s", ft, fs); } @@ -16174,8 +16141,8 @@ static std::string TRUNC_W_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + std::string ft = FPR(ft_value); + std::string fs = FPR(fs_value); return img_format("TRUNC.W.S %s, %s", ft, fs); } @@ -16198,9 +16165,9 @@ static std::string UALDM(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 count3_value = extract_count3_14_13_12(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); std::string count3 = IMMEDIATE(encode_count3_from_count(count3_value)); return img_format("UALDM %s, %s(%s), %s", rt, s, rs, count3); @@ -16223,9 +16190,9 @@ static std::string UALH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("UALH %s, %s(%s)", rt, s, rs); } @@ -16248,9 +16215,9 @@ static std::string UALWM(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 count3_value = extract_count3_14_13_12(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); std::string count3 = IMMEDIATE(encode_count3_from_count(count3_value)); return img_format("UALWM %s, %s(%s), %s", rt, s, rs, count3); @@ -16274,9 +16241,9 @@ static std::string UASDM(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 count3_value = extract_count3_14_13_12(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); std::string count3 = IMMEDIATE(encode_count3_from_count(count3_value)); return img_format("UASDM %s, %s(%s), %s", rt, s, rs, count3); @@ -16299,9 +16266,9 @@ static std::string UASH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); return img_format("UASH %s, %s(%s)", rt, s, rs); } @@ -16324,9 +16291,9 @@ static std::string UASWM(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 count3_value = extract_count3_14_13_12(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string s = IMMEDIATE(s_value); + std::string rs = GPR(rs_value); std::string count3 = IMMEDIATE(encode_count3_from_count(count3_value)); return img_format("UASWM %s, %s(%s), %s", rt, s, rs, count3); @@ -16347,7 +16314,7 @@ static std::string UDI(uint64 instruction, Dis_info *info) { uint64 op_value = extract_op_25_to_3(instruction); - std::string op = IMMEDIATE(copy(op_value)); + std::string op = IMMEDIATE(op_value); return img_format("UDI %s", op); } @@ -16365,7 +16332,7 @@ static std::string WAIT(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_25_24_23_22_21_20_19_18_17_16(instruction); - std::string code = IMMEDIATE(copy(code_value)); + std::string code = IMMEDIATE(code_value); return img_format("WAIT %s", code); } @@ -16386,8 +16353,8 @@ static std::string WRDSP(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 mask_value = extract_mask_20_19_18_17_16_15_14(instruction); - std::string rt = GPR(copy(rt_value)); - std::string mask = IMMEDIATE(copy(mask_value)); + std::string rt = GPR(rt_value); + std::string mask = IMMEDIATE(mask_value); return img_format("WRDSP %s, %s", rt, mask); } @@ -16408,8 +16375,8 @@ static std::string WRPGPR(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("WRPGPR %s, %s", rt, rs); } @@ -16453,9 +16420,9 @@ static std::string XOR_32_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + std::string rd = GPR(rd_value); + std::string rs = GPR(rs_value); + std::string rt = GPR(rt_value); return img_format("XOR %s, %s, %s", rd, rs, rt); } @@ -16477,9 +16444,9 @@ static std::string XORI(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string u = IMMEDIATE(copy(u_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); + std::string u = IMMEDIATE(u_value); return img_format("XORI %s, %s, %s", rt, rs, u); } @@ -16499,8 +16466,8 @@ static std::string YIELD(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + std::string rt = GPR(rt_value); + std::string rs = GPR(rs_value); return img_format("YIELD %s, %s", rt, rs); } From afc47e07e57e9f39a9dfdf240d67b65a284b15d8 Mon Sep 17 00:00:00 2001 From: Milica Lazarevic Date: Mon, 12 Sep 2022 14:26:25 +0200 Subject: [PATCH 435/705] disas/nanomips: Delete wrapper functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Following functions just wrap the decode_gpr_gpr3() function: - encode_rs3_and_check_rs3_ge_rt3() - encode_rs3_and_check_rs3_lt_rt3() Therefore those have been deleted. Calls to these two functions have been replaced with calls to decode_gpr_gpr3. Signed-off-by: Milica Lazarevic Reviewed-by: Richard Henderson Message-Id: <20220912122635.74032-15-milica.lazarevic@syrmia.com> Signed-off-by: Philippe Mathieu-Daudé --- disas/nanomips.cpp | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp index b90be5744e..170f5c5c17 100644 --- a/disas/nanomips.cpp +++ b/disas/nanomips.cpp @@ -505,20 +505,6 @@ static int64 neg_copy(uint64 d) } -/* strange wrapper around gpr3 */ -static uint64 encode_rs3_and_check_rs3_ge_rt3(uint64 d) -{ -return decode_gpr_gpr3(d); -} - - -/* strange wrapper around gpr3 */ -static uint64 encode_rs3_and_check_rs3_lt_rt3(uint64 d) -{ - return decode_gpr_gpr3(d); -} - - static uint64 encode_count3_from_count(uint64 d) { IMGASSERTONCE(d < 8); @@ -2958,7 +2944,7 @@ static std::string BEQC_16_(uint64 instruction, Dis_info *info) uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_3_2_1_0__s1(instruction); - std::string rs3 = GPR(encode_rs3_and_check_rs3_lt_rt3(rs3_value)); + std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); std::string u = ADDRESS(u_value, 2, info); @@ -3244,7 +3230,7 @@ static std::string BNEC_16_(uint64 instruction, Dis_info *info) uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_3_2_1_0__s1(instruction); - std::string rs3 = GPR(encode_rs3_and_check_rs3_ge_rt3(rs3_value)); + std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); std::string u = ADDRESS(u_value, 2, info); From 7def8a4b937262c2710d2cd5fdb21e7af4b0529a Mon Sep 17 00:00:00 2001 From: Milica Lazarevic Date: Mon, 12 Sep 2022 14:26:26 +0200 Subject: [PATCH 436/705] disas/nanomips: Replace std::string type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The return type of typedef disassembly_function is changed to char * instead of std::string. Therefore, for every particular disassembly_function function signature is changed. For example: - static std::string ABS_D(uint64 instruction, img_address m_pc) {...} is replaced with - static char *ABS_D(uint64 instruction, img_address m_pc) {...} Every helper function used to return std::string is changed to return const char * or char *. Where the return value points to a static string that the caller must not free, the return type is const char *. If a function allocates memory and the caller is required to free it, the return type is a char *. This applies to the following functions: img_format, to_string, GPR, save_restore_list, FPR, etc. Now that we replaced every std::string for const char * or char *, it is possible to delete multiple versions of the img_format function. The general version: - static char *img_format(const char *format, ...) {...} can handle all string formatting, so others have been deleted. Where necessary, strings are dynamically allocated with g_strjoinv, g_strdup, g_strdup_vprintf, and g_strdup_printf. Memory leaking will be prevented later. String concatenation in the save_restore_list() function is handled using g_strjoinv() function instead of += operator. The type of the "dis" parameter in the Disassemble function is changed - from std::string & - to char ** Without applying all of these changes, the nanomips disassembler may be buildable but can't produce the appropriate output, so all of them are made together. Signed-off-by: Milica Lazarevic Reviewed-by: Richard Henderson Message-Id: <20220912122635.74032-16-milica.lazarevic@syrmia.com> Signed-off-by: Philippe Mathieu-Daudé --- disas/nanomips.cpp | 4778 ++++++++++++++++++++++---------------------- 1 file changed, 2338 insertions(+), 2440 deletions(-) diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp index 170f5c5c17..e4e122f3cf 100644 --- a/disas/nanomips.cpp +++ b/disas/nanomips.cpp @@ -30,13 +30,11 @@ #include "qemu/osdep.h" #include "disas/dis-asm.h" -#include +#include #include #include #include -#include - typedef int64_t int64; typedef uint64_t uint64; typedef uint32_t uint32; @@ -77,7 +75,7 @@ typedef struct Dis_info { } Dis_info; typedef bool (*conditional_function)(uint64 instruction); -typedef std::string (*disassembly_function)(uint64 instruction, +typedef char * (*disassembly_function)(uint64 instruction, Dis_info *info); typedef struct Pool { @@ -95,122 +93,20 @@ typedef struct Pool { #define IMGASSERTONCE(test) -std::string img_format(const char *format, ...) +static char *img_format(const char *format, ...) { - char buffer[256]; + char *buffer; va_list args; va_start(args, format); - int err = vsprintf(buffer, format, args); - if (err < 0) { - perror(buffer); - } + buffer = g_strdup_vprintf(format, args); va_end(args); return buffer; } -std::string img_format(const char *format, - std::string s) + +static char *to_string(img_address a) { - char buffer[256]; - - sprintf(buffer, format, s.c_str()); - - return buffer; -} - -std::string img_format(const char *format, - std::string s1, - std::string s2) -{ - char buffer[256]; - - sprintf(buffer, format, s1.c_str(), s2.c_str()); - - return buffer; -} - -std::string img_format(const char *format, - std::string s1, - std::string s2, - std::string s3) -{ - char buffer[256]; - - sprintf(buffer, format, s1.c_str(), s2.c_str(), s3.c_str()); - - return buffer; -} - -std::string img_format(const char *format, - std::string s1, - std::string s2, - std::string s3, - std::string s4) -{ - char buffer[256]; - - sprintf(buffer, format, s1.c_str(), s2.c_str(), s3.c_str(), - s4.c_str()); - - return buffer; -} - -std::string img_format(const char *format, - std::string s1, - std::string s2, - std::string s3, - std::string s4, - std::string s5) -{ - char buffer[256]; - - sprintf(buffer, format, s1.c_str(), s2.c_str(), s3.c_str(), - s4.c_str(), s5.c_str()); - - return buffer; -} - -std::string img_format(const char *format, - uint64 d, - std::string s2) -{ - char buffer[256]; - - sprintf(buffer, format, d, s2.c_str()); - - return buffer; -} - -std::string img_format(const char *format, - std::string s1, - uint64 d, - std::string s2) -{ - char buffer[256]; - - sprintf(buffer, format, s1.c_str(), d, s2.c_str()); - - return buffer; -} - -std::string img_format(const char *format, - std::string s1, - std::string s2, - uint64 d) -{ - char buffer[256]; - - sprintf(buffer, format, s1.c_str(), s2.c_str(), d); - - return buffer; -} - - -std::string to_string(img_address a) -{ - char buffer[256]; - sprintf(buffer, "0x%" PRIx64, a); - return buffer; + return g_strdup_printf("0x%" PRIx64, a); } @@ -554,7 +450,7 @@ static uint64 encode_rt1_from_rt(uint64 d) } -static std::string GPR(uint64 reg) +static const char *GPR(uint64 reg) { static const char *gpr_reg[32] = { "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", @@ -572,21 +468,25 @@ static std::string GPR(uint64 reg) } -static std::string save_restore_list(uint64 rt, uint64 count, uint64 gp) +static char *save_restore_list(uint64 rt, uint64 count, uint64 gp) { - std::string str; + char *reg_list[34]; + reg_list[0] = (char *)""; + assert(count <= 32); for (uint64 counter = 0; counter != count; counter++) { bool use_gp = gp && (counter == count - 1); uint64 this_rt = use_gp ? 28 : ((rt & 0x10) | (rt + counter)) & 0x1f; - str += img_format(",%s", GPR(this_rt)); + /* glib usage below requires casting away const */ + reg_list[counter + 1] = (char *)GPR(this_rt); } + reg_list[count + 1] = NULL; - return str; + return g_strjoinv(",", reg_list); } -static std::string FPR(uint64 reg) +static const char *FPR(uint64 reg) { static const char *fpr_reg[32] = { "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", @@ -604,7 +504,7 @@ static std::string FPR(uint64 reg) } -static std::string AC(uint64 reg) +static const char *AC(uint64 reg) { static const char *ac_reg[4] = { "ac0", "ac1", "ac2", "ac3" @@ -619,26 +519,26 @@ static std::string AC(uint64 reg) } -static std::string IMMEDIATE(uint64 value) +static char *IMMEDIATE(uint64 value) { return img_format("0x%" PRIx64, value); } -static std::string IMMEDIATE(int64 value) +static char *IMMEDIATE(int64 value) { return img_format("%" PRId64, value); } -static std::string CPR(uint64 reg) +static char *CPR(uint64 reg) { /* needs more work */ return img_format("CP%" PRIu64, reg); } -static std::string ADDRESS(uint64 value, int instruction_size, Dis_info *info) +static char *ADDRESS(uint64 value, int instruction_size, Dis_info *info) { /* token for string replace */ img_address address = info->m_pc + value + instruction_size; @@ -673,7 +573,7 @@ static uint64 extract_op_code_value(const uint16 *data, int size) * instruction size - negative is error * disassembly string - on error will constain error string */ -static int Disassemble(const uint16 *data, std::string & dis, +static int Disassemble(const uint16 *data, char **dis, TABLE_ENTRY_TYPE & type, const Pool *table, int table_size, Dis_info *info) { @@ -699,20 +599,21 @@ static int Disassemble(const uint16 *data, std::string & dis, (table[i].type == return_instruction)) { disassembly_function dis_fn = table[i].disassembly; if (dis_fn == 0) { - dis = "disassembler failure - bad table entry"; + *dis = g_strdup( + "disassembler failure - bad table entry"); return -6; } type = table[i].type; - dis = dis_fn(op_code, info); + *dis = dis_fn(op_code, info); return table[i].instructions_size; } else { - dis = "reserved instruction"; + *dis = g_strdup("reserved instruction"); return -2; } } catch (std::runtime_error & e) { - dis = e.what(); + *dis = g_strdup(e.what()); return -3; /* runtime error */ } } @@ -721,11 +622,11 @@ static int Disassemble(const uint16 *data, std::string & dis, } catch (std::exception & e) { - dis = e.what(); + *dis = g_strdup(e.what()); return -4; /* runtime error */ } - dis = "failed to disassemble"; + *dis = g_strdup("failed to disassemble"); return -1; /* failed to disassemble */ } @@ -1658,13 +1559,13 @@ static bool SLTU_cond(uint64 instruction) * fs ----- * fd ----- */ -static std::string ABS_D(uint64 instruction, Dis_info *info) +static char *ABS_D(uint64 instruction, Dis_info *info) { uint64 fd_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string fs = FPR(fs_value); - std::string fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *fd = FPR(fd_value); return img_format("ABS.D %s, %s", fd, fs); } @@ -1680,13 +1581,13 @@ static std::string ABS_D(uint64 instruction, Dis_info *info) * fd ----- * fs ----- */ -static std::string ABS_S(uint64 instruction, Dis_info *info) +static char *ABS_S(uint64 instruction, Dis_info *info) { uint64 fd_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string fs = FPR(fs_value); - std::string fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *fd = FPR(fd_value); return img_format("ABS.S %s, %s", fd, fs); } @@ -1702,13 +1603,13 @@ static std::string ABS_S(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -static std::string ABSQ_S_PH(uint64 instruction, Dis_info *info) +static char *ABSQ_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("ABSQ_S.PH %s, %s", rt, rs); } @@ -1724,13 +1625,13 @@ static std::string ABSQ_S_PH(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -static std::string ABSQ_S_QB(uint64 instruction, Dis_info *info) +static char *ABSQ_S_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("ABSQ_S.QB %s, %s", rt, rs); } @@ -1746,13 +1647,13 @@ static std::string ABSQ_S_QB(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -static std::string ABSQ_S_W(uint64 instruction, Dis_info *info) +static char *ABSQ_S_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("ABSQ_S.W %s, %s", rt, rs); } @@ -1767,15 +1668,15 @@ static std::string ABSQ_S_W(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -static std::string ACLR(uint64 instruction, Dis_info *info) +static char *ACLR(uint64 instruction, Dis_info *info) { uint64 bit_value = extract_bit_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string bit = IMMEDIATE(bit_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + char *bit = IMMEDIATE(bit_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("ACLR %s, %s(%s)", bit, s, rs); } @@ -1790,15 +1691,15 @@ static std::string ACLR(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -static std::string ADD(uint64 instruction, Dis_info *info) +static char *ADD(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("ADD %s, %s, %s", rd, rs, rt); } @@ -1815,15 +1716,15 @@ static std::string ADD(uint64 instruction, Dis_info *info) * fs ----- * fd ----- */ -static std::string ADD_D(uint64 instruction, Dis_info *info) +static char *ADD_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); - std::string fd = FPR(fd_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); + const char *fd = FPR(fd_value); return img_format("ADD.D %s, %s, %s", fd, fs, ft); } @@ -1840,15 +1741,15 @@ static std::string ADD_D(uint64 instruction, Dis_info *info) * fs ----- * fd ----- */ -static std::string ADD_S(uint64 instruction, Dis_info *info) +static char *ADD_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); - std::string fd = FPR(fd_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); + const char *fd = FPR(fd_value); return img_format("ADD.S %s, %s, %s", fd, fs, ft); } @@ -1863,15 +1764,15 @@ static std::string ADD_S(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -static std::string ADDIU_32_(uint64 instruction, Dis_info *info) +static char *ADDIU_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_15_to_0(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string u = IMMEDIATE(u_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *u = IMMEDIATE(u_value); return img_format("ADDIU %s, %s, %s", rt, rs, u); } @@ -1886,13 +1787,13 @@ static std::string ADDIU_32_(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -static std::string ADDIU_48_(uint64 instruction, Dis_info *info) +static char *ADDIU_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); return img_format("ADDIU %s, %s", rt, s); } @@ -1907,13 +1808,13 @@ static std::string ADDIU_48_(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -static std::string ADDIU_GP48_(uint64 instruction, Dis_info *info) +static char *ADDIU_GP48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); return img_format("ADDIU %s, $%d, %s", rt, 28, s); } @@ -1928,13 +1829,13 @@ static std::string ADDIU_GP48_(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -static std::string ADDIU_GP_B_(uint64 instruction, Dis_info *info) +static char *ADDIU_GP_B_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_0(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); return img_format("ADDIU %s, $%d, %s", rt, 28, u); } @@ -1949,13 +1850,13 @@ static std::string ADDIU_GP_B_(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -static std::string ADDIU_GP_W_(uint64 instruction, Dis_info *info) +static char *ADDIU_GP_W_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_to_2__s2(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); return img_format("ADDIU %s, $%d, %s", rt, 28, u); } @@ -1970,15 +1871,15 @@ static std::string ADDIU_GP_W_(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -static std::string ADDIU_NEG_(uint64 instruction, Dis_info *info) +static char *ADDIU_NEG_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string u = IMMEDIATE(neg_copy(u_value)); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *u = IMMEDIATE(neg_copy(u_value)); return img_format("ADDIU %s, %s, %s", rt, rs, u); } @@ -1993,13 +1894,13 @@ static std::string ADDIU_NEG_(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -static std::string ADDIU_R1_SP_(uint64 instruction, Dis_info *info) +static char *ADDIU_R1_SP_(uint64 instruction, Dis_info *info) { uint64 u_value = extract_u_5_4_3_2_1_0__s2(instruction); uint64 rt3_value = extract_rt3_9_8_7(instruction); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string u = IMMEDIATE(u_value); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); + char *u = IMMEDIATE(u_value); return img_format("ADDIU %s, $%d, %s", rt3, 29, u); } @@ -2014,15 +1915,15 @@ static std::string ADDIU_R1_SP_(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -static std::string ADDIU_R2_(uint64 instruction, Dis_info *info) +static char *ADDIU_R2_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_2_1_0__s2(instruction); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); - std::string u = IMMEDIATE(u_value); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); + char *u = IMMEDIATE(u_value); return img_format("ADDIU %s, %s, %s", rt3, rs3, u); } @@ -2036,13 +1937,13 @@ static std::string ADDIU_R2_(uint64 instruction, Dis_info *info) * rt ----- * s - --- */ -static std::string ADDIU_RS5_(uint64 instruction, Dis_info *info) +static char *ADDIU_RS5_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_9_8_7_6_5(instruction); int64 s_value = extract_s__se3_4_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); return img_format("ADDIU %s, %s", rt, s); } @@ -2058,13 +1959,13 @@ static std::string ADDIU_RS5_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string ADDIUPC_32_(uint64 instruction, Dis_info *info) +static char *ADDIUPC_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); int64 s_value = extract_s__se21_0_20_to_1_s1(instruction); - std::string rt = GPR(rt_value); - std::string s = ADDRESS(s_value, 4, info); + const char *rt = GPR(rt_value); + char *s = ADDRESS(s_value, 4, info); return img_format("ADDIUPC %s, %s", rt, s); } @@ -2080,13 +1981,13 @@ static std::string ADDIUPC_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string ADDIUPC_48_(uint64 instruction, Dis_info *info) +static char *ADDIUPC_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - std::string rt = GPR(rt_value); - std::string s = ADDRESS(s_value, 6, info); + const char *rt = GPR(rt_value); + char *s = ADDRESS(s_value, 6, info); return img_format("ADDIUPC %s, %s", rt, s); } @@ -2102,15 +2003,15 @@ static std::string ADDIUPC_48_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string ADDQ_PH(uint64 instruction, Dis_info *info) +static char *ADDQ_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("ADDQ.PH %s, %s, %s", rd, rs, rt); } @@ -2127,15 +2028,15 @@ static std::string ADDQ_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string ADDQ_S_PH(uint64 instruction, Dis_info *info) +static char *ADDQ_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("ADDQ_S.PH %s, %s, %s", rd, rs, rt); } @@ -2151,15 +2052,15 @@ static std::string ADDQ_S_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string ADDQ_S_W(uint64 instruction, Dis_info *info) +static char *ADDQ_S_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("ADDQ_S.W %s, %s, %s", rd, rs, rt); } @@ -2176,15 +2077,15 @@ static std::string ADDQ_S_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string ADDQH_PH(uint64 instruction, Dis_info *info) +static char *ADDQH_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("ADDQH.PH %s, %s, %s", rd, rs, rt); } @@ -2201,15 +2102,15 @@ static std::string ADDQH_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string ADDQH_R_PH(uint64 instruction, Dis_info *info) +static char *ADDQH_R_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("ADDQH_R.PH %s, %s, %s", rd, rs, rt); } @@ -2226,15 +2127,15 @@ static std::string ADDQH_R_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string ADDQH_R_W(uint64 instruction, Dis_info *info) +static char *ADDQH_R_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("ADDQH_R.W %s, %s, %s", rd, rs, rt); } @@ -2251,15 +2152,15 @@ static std::string ADDQH_R_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string ADDQH_W(uint64 instruction, Dis_info *info) +static char *ADDQH_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("ADDQH.W %s, %s, %s", rd, rs, rt); } @@ -2275,15 +2176,15 @@ static std::string ADDQH_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string ADDSC(uint64 instruction, Dis_info *info) +static char *ADDSC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("ADDSC %s, %s, %s", rd, rs, rt); } @@ -2298,15 +2199,15 @@ static std::string ADDSC(uint64 instruction, Dis_info *info) * rs3 --- * rd3 --- */ -static std::string ADDU_16_(uint64 instruction, Dis_info *info) +static char *ADDU_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 rd3_value = extract_rd3_3_2_1(instruction); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); - std::string rd3 = GPR(decode_gpr_gpr3(rd3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rd3 = GPR(decode_gpr_gpr3(rd3_value)); return img_format("ADDU %s, %s, %s", rd3, rs3, rt3); } @@ -2322,15 +2223,15 @@ static std::string ADDU_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string ADDU_32_(uint64 instruction, Dis_info *info) +static char *ADDU_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("ADDU %s, %s, %s", rd, rs, rt); } @@ -2346,13 +2247,13 @@ static std::string ADDU_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string ADDU_4X4_(uint64 instruction, Dis_info *info) +static char *ADDU_4X4_(uint64 instruction, Dis_info *info) { uint64 rt4_value = extract_rt4_9_7_6_5(instruction); uint64 rs4_value = extract_rs4_4_2_1_0(instruction); - std::string rs4 = GPR(decode_gpr_gpr4(rs4_value)); - std::string rt4 = GPR(decode_gpr_gpr4(rt4_value)); + const char *rs4 = GPR(decode_gpr_gpr4(rs4_value)); + const char *rt4 = GPR(decode_gpr_gpr4(rt4_value)); return img_format("ADDU %s, %s", rs4, rt4); } @@ -2368,15 +2269,15 @@ static std::string ADDU_4X4_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string ADDU_PH(uint64 instruction, Dis_info *info) +static char *ADDU_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("ADDU.PH %s, %s, %s", rd, rs, rt); } @@ -2392,15 +2293,15 @@ static std::string ADDU_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string ADDU_QB(uint64 instruction, Dis_info *info) +static char *ADDU_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("ADDU.QB %s, %s, %s", rd, rs, rt); } @@ -2417,15 +2318,15 @@ static std::string ADDU_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string ADDU_S_PH(uint64 instruction, Dis_info *info) +static char *ADDU_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("ADDU_S.PH %s, %s, %s", rd, rs, rt); } @@ -2441,15 +2342,15 @@ static std::string ADDU_S_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string ADDU_S_QB(uint64 instruction, Dis_info *info) +static char *ADDU_S_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("ADDU_S.QB %s, %s, %s", rd, rs, rt); } @@ -2466,15 +2367,15 @@ static std::string ADDU_S_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string ADDUH_QB(uint64 instruction, Dis_info *info) +static char *ADDUH_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("ADDUH.QB %s, %s, %s", rd, rs, rt); } @@ -2491,15 +2392,15 @@ static std::string ADDUH_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string ADDUH_R_QB(uint64 instruction, Dis_info *info) +static char *ADDUH_R_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("ADDUH_R.QB %s, %s, %s", rd, rs, rt); } @@ -2514,15 +2415,15 @@ static std::string ADDUH_R_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string ADDWC(uint64 instruction, Dis_info *info) +static char *ADDWC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("ADDWC %s, %s, %s", rd, rs, rt); } @@ -2538,13 +2439,13 @@ static std::string ADDWC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string ALUIPC(uint64 instruction, Dis_info *info) +static char *ALUIPC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); int64 s_value = extract_s__se31_0_11_to_2_20_to_12_s12(instruction); - std::string rt = GPR(rt_value); - std::string s = ADDRESS(s_value, 4, info); + const char *rt = GPR(rt_value); + char *s = ADDRESS(s_value, 4, info); return img_format("ALUIPC %s, %%pcrel_hi(%s)", rt, s); } @@ -2559,13 +2460,13 @@ static std::string ALUIPC(uint64 instruction, Dis_info *info) * rs3 --- * eu ---- */ -static std::string AND_16_(uint64 instruction, Dis_info *info) +static char *AND_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); return img_format("AND %s, %s", rs3, rt3); } @@ -2581,15 +2482,15 @@ static std::string AND_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string AND_32_(uint64 instruction, Dis_info *info) +static char *AND_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("AND %s, %s, %s", rd, rs, rt); } @@ -2604,15 +2505,15 @@ static std::string AND_32_(uint64 instruction, Dis_info *info) * rs3 --- * eu ---- */ -static std::string ANDI_16_(uint64 instruction, Dis_info *info) +static char *ANDI_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 eu_value = extract_eu_3_2_1_0(instruction); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); - std::string eu = IMMEDIATE(encode_eu_from_u_andi16(eu_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); + char *eu = IMMEDIATE(encode_eu_from_u_andi16(eu_value)); return img_format("ANDI %s, %s, %s", rt3, rs3, eu); } @@ -2628,15 +2529,15 @@ static std::string ANDI_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string ANDI_32_(uint64 instruction, Dis_info *info) +static char *ANDI_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string u = IMMEDIATE(u_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *u = IMMEDIATE(u_value); return img_format("ANDI %s, %s, %s", rt, rs, u); } @@ -2652,15 +2553,15 @@ static std::string ANDI_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string APPEND(uint64 instruction, Dis_info *info) +static char *APPEND(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13_12_11(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string sa = IMMEDIATE(sa_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *sa = IMMEDIATE(sa_value); return img_format("APPEND %s, %s, %s", rt, rs, sa); } @@ -2676,15 +2577,15 @@ static std::string APPEND(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string ASET(uint64 instruction, Dis_info *info) +static char *ASET(uint64 instruction, Dis_info *info) { uint64 bit_value = extract_bit_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string bit = IMMEDIATE(bit_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + char *bit = IMMEDIATE(bit_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("ASET %s, %s(%s)", bit, s, rs); } @@ -2700,11 +2601,11 @@ static std::string ASET(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string BALC_16_(uint64 instruction, Dis_info *info) +static char *BALC_16_(uint64 instruction, Dis_info *info) { int64 s_value = extract_s__se10_0_9_8_7_6_5_4_3_2_1_s1(instruction); - std::string s = ADDRESS(s_value, 2, info); + char *s = ADDRESS(s_value, 2, info); return img_format("BALC %s", s); } @@ -2720,11 +2621,11 @@ static std::string BALC_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string BALC_32_(uint64 instruction, Dis_info *info) +static char *BALC_32_(uint64 instruction, Dis_info *info) { int64 s_value = extract_s__se25_0_24_to_1_s1(instruction); - std::string s = ADDRESS(s_value, 4, info); + char *s = ADDRESS(s_value, 4, info); return img_format("BALC %s", s); } @@ -2740,13 +2641,13 @@ static std::string BALC_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string BALRSC(uint64 instruction, Dis_info *info) +static char *BALRSC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("BALRSC %s, %s", rt, rs); } @@ -2762,15 +2663,15 @@ static std::string BALRSC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string BBEQZC(uint64 instruction, Dis_info *info) +static char *BBEQZC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 bit_value = extract_bit_16_15_14_13_12_11(instruction); int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); - std::string rt = GPR(rt_value); - std::string bit = IMMEDIATE(bit_value); - std::string s = ADDRESS(s_value, 4, info); + const char *rt = GPR(rt_value); + char *bit = IMMEDIATE(bit_value); + char *s = ADDRESS(s_value, 4, info); return img_format("BBEQZC %s, %s, %s", rt, bit, s); } @@ -2786,15 +2687,15 @@ static std::string BBEQZC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string BBNEZC(uint64 instruction, Dis_info *info) +static char *BBNEZC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 bit_value = extract_bit_16_15_14_13_12_11(instruction); int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); - std::string rt = GPR(rt_value); - std::string bit = IMMEDIATE(bit_value); - std::string s = ADDRESS(s_value, 4, info); + const char *rt = GPR(rt_value); + char *bit = IMMEDIATE(bit_value); + char *s = ADDRESS(s_value, 4, info); return img_format("BBNEZC %s, %s, %s", rt, bit, s); } @@ -2810,11 +2711,11 @@ static std::string BBNEZC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string BC_16_(uint64 instruction, Dis_info *info) +static char *BC_16_(uint64 instruction, Dis_info *info) { int64 s_value = extract_s__se10_0_9_8_7_6_5_4_3_2_1_s1(instruction); - std::string s = ADDRESS(s_value, 2, info); + char *s = ADDRESS(s_value, 2, info); return img_format("BC %s", s); } @@ -2830,11 +2731,11 @@ static std::string BC_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string BC_32_(uint64 instruction, Dis_info *info) +static char *BC_32_(uint64 instruction, Dis_info *info) { int64 s_value = extract_s__se25_0_24_to_1_s1(instruction); - std::string s = ADDRESS(s_value, 4, info); + char *s = ADDRESS(s_value, 4, info); return img_format("BC %s", s); } @@ -2850,13 +2751,13 @@ static std::string BC_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string BC1EQZC(uint64 instruction, Dis_info *info) +static char *BC1EQZC(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - std::string ft = FPR(ft_value); - std::string s = ADDRESS(s_value, 4, info); + const char *ft = FPR(ft_value); + char *s = ADDRESS(s_value, 4, info); return img_format("BC1EQZC %s, %s", ft, s); } @@ -2872,13 +2773,13 @@ static std::string BC1EQZC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string BC1NEZC(uint64 instruction, Dis_info *info) +static char *BC1NEZC(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - std::string ft = FPR(ft_value); - std::string s = ADDRESS(s_value, 4, info); + const char *ft = FPR(ft_value); + char *s = ADDRESS(s_value, 4, info); return img_format("BC1NEZC %s, %s", ft, s); } @@ -2894,13 +2795,13 @@ static std::string BC1NEZC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string BC2EQZC(uint64 instruction, Dis_info *info) +static char *BC2EQZC(uint64 instruction, Dis_info *info) { uint64 ct_value = extract_ct_25_24_23_22_21(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - std::string ct = CPR(ct_value); - std::string s = ADDRESS(s_value, 4, info); + char *ct = CPR(ct_value); + char *s = ADDRESS(s_value, 4, info); return img_format("BC2EQZC %s, %s", ct, s); } @@ -2916,13 +2817,13 @@ static std::string BC2EQZC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string BC2NEZC(uint64 instruction, Dis_info *info) +static char *BC2NEZC(uint64 instruction, Dis_info *info) { uint64 ct_value = extract_ct_25_24_23_22_21(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - std::string ct = CPR(ct_value); - std::string s = ADDRESS(s_value, 4, info); + char *ct = CPR(ct_value); + char *s = ADDRESS(s_value, 4, info); return img_format("BC2NEZC %s, %s", ct, s); } @@ -2938,15 +2839,15 @@ static std::string BC2NEZC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string BEQC_16_(uint64 instruction, Dis_info *info) +static char *BEQC_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_3_2_1_0__s1(instruction); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string u = ADDRESS(u_value, 2, info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); + char *u = ADDRESS(u_value, 2, info); return img_format("BEQC %s, %s, %s", rs3, rt3, u); } @@ -2962,15 +2863,15 @@ static std::string BEQC_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string BEQC_32_(uint64 instruction, Dis_info *info) +static char *BEQC_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); - std::string s = ADDRESS(s_value, 4, info); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *s = ADDRESS(s_value, 4, info); return img_format("BEQC %s, %s, %s", rs, rt, s); } @@ -2986,15 +2887,15 @@ static std::string BEQC_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string BEQIC(uint64 instruction, Dis_info *info) +static char *BEQIC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); - std::string s = ADDRESS(s_value, 4, info); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); + char *s = ADDRESS(s_value, 4, info); return img_format("BEQIC %s, %s, %s", rt, u, s); } @@ -3010,13 +2911,13 @@ static std::string BEQIC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string BEQZC_16_(uint64 instruction, Dis_info *info) +static char *BEQZC_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); int64 s_value = extract_s__se7_0_6_5_4_3_2_1_s1(instruction); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string s = ADDRESS(s_value, 2, info); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); + char *s = ADDRESS(s_value, 2, info); return img_format("BEQZC %s, %s", rt3, s); } @@ -3032,15 +2933,15 @@ static std::string BEQZC_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string BGEC(uint64 instruction, Dis_info *info) +static char *BGEC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); - std::string s = ADDRESS(s_value, 4, info); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *s = ADDRESS(s_value, 4, info); return img_format("BGEC %s, %s, %s", rs, rt, s); } @@ -3056,15 +2957,15 @@ static std::string BGEC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string BGEIC(uint64 instruction, Dis_info *info) +static char *BGEIC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); - std::string s = ADDRESS(s_value, 4, info); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); + char *s = ADDRESS(s_value, 4, info); return img_format("BGEIC %s, %s, %s", rt, u, s); } @@ -3080,15 +2981,15 @@ static std::string BGEIC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string BGEIUC(uint64 instruction, Dis_info *info) +static char *BGEIUC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); - std::string s = ADDRESS(s_value, 4, info); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); + char *s = ADDRESS(s_value, 4, info); return img_format("BGEIUC %s, %s, %s", rt, u, s); } @@ -3104,15 +3005,15 @@ static std::string BGEIUC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string BGEUC(uint64 instruction, Dis_info *info) +static char *BGEUC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); - std::string s = ADDRESS(s_value, 4, info); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *s = ADDRESS(s_value, 4, info); return img_format("BGEUC %s, %s, %s", rs, rt, s); } @@ -3128,15 +3029,15 @@ static std::string BGEUC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string BLTC(uint64 instruction, Dis_info *info) +static char *BLTC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); - std::string s = ADDRESS(s_value, 4, info); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *s = ADDRESS(s_value, 4, info); return img_format("BLTC %s, %s, %s", rs, rt, s); } @@ -3152,15 +3053,15 @@ static std::string BLTC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string BLTIC(uint64 instruction, Dis_info *info) +static char *BLTIC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); - std::string s = ADDRESS(s_value, 4, info); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); + char *s = ADDRESS(s_value, 4, info); return img_format("BLTIC %s, %s, %s", rt, u, s); } @@ -3176,15 +3077,15 @@ static std::string BLTIC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string BLTIUC(uint64 instruction, Dis_info *info) +static char *BLTIUC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); - std::string s = ADDRESS(s_value, 4, info); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); + char *s = ADDRESS(s_value, 4, info); return img_format("BLTIUC %s, %s, %s", rt, u, s); } @@ -3200,15 +3101,15 @@ static std::string BLTIUC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string BLTUC(uint64 instruction, Dis_info *info) +static char *BLTUC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); - std::string s = ADDRESS(s_value, 4, info); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *s = ADDRESS(s_value, 4, info); return img_format("BLTUC %s, %s, %s", rs, rt, s); } @@ -3224,15 +3125,15 @@ static std::string BLTUC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string BNEC_16_(uint64 instruction, Dis_info *info) +static char *BNEC_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_3_2_1_0__s1(instruction); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string u = ADDRESS(u_value, 2, info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); + char *u = ADDRESS(u_value, 2, info); return img_format("BNEC %s, %s, %s", rs3, rt3, u); } @@ -3248,15 +3149,15 @@ static std::string BNEC_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string BNEC_32_(uint64 instruction, Dis_info *info) +static char *BNEC_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); - std::string s = ADDRESS(s_value, 4, info); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *s = ADDRESS(s_value, 4, info); return img_format("BNEC %s, %s, %s", rs, rt, s); } @@ -3272,15 +3173,15 @@ static std::string BNEC_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string BNEIC(uint64 instruction, Dis_info *info) +static char *BNEIC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); - std::string s = ADDRESS(s_value, 4, info); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); + char *s = ADDRESS(s_value, 4, info); return img_format("BNEIC %s, %s, %s", rt, u, s); } @@ -3296,13 +3197,13 @@ static std::string BNEIC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string BNEZC_16_(uint64 instruction, Dis_info *info) +static char *BNEZC_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); int64 s_value = extract_s__se7_0_6_5_4_3_2_1_s1(instruction); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string s = ADDRESS(s_value, 2, info); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); + char *s = ADDRESS(s_value, 2, info); return img_format("BNEZC %s, %s", rt3, s); } @@ -3318,11 +3219,11 @@ static std::string BNEZC_16_(uint64 instruction, Dis_info *info) * s[13:1] ------------- * s[14] - */ -static std::string BPOSGE32C(uint64 instruction, Dis_info *info) +static char *BPOSGE32C(uint64 instruction, Dis_info *info) { int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - std::string s = ADDRESS(s_value, 4, info); + char *s = ADDRESS(s_value, 4, info); return img_format("BPOSGE32C %s", s); } @@ -3338,11 +3239,11 @@ static std::string BPOSGE32C(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string BREAK_16_(uint64 instruction, Dis_info *info) +static char *BREAK_16_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_2_1_0(instruction); - std::string code = IMMEDIATE(code_value); + char *code = IMMEDIATE(code_value); return img_format("BREAK %s", code); } @@ -3358,11 +3259,11 @@ static std::string BREAK_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string BREAK_32_(uint64 instruction, Dis_info *info) +static char *BREAK_32_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_18_to_0(instruction); - std::string code = IMMEDIATE(code_value); + char *code = IMMEDIATE(code_value); return img_format("BREAK %s", code); } @@ -3378,11 +3279,11 @@ static std::string BREAK_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string BRSC(uint64 instruction, Dis_info *info) +static char *BRSC(uint64 instruction, Dis_info *info) { uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rs = GPR(rs_value); + const char *rs = GPR(rs_value); return img_format("BRSC %s", rs); } @@ -3398,15 +3299,15 @@ static std::string BRSC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CACHE(uint64 instruction, Dis_info *info) +static char *CACHE(uint64 instruction, Dis_info *info) { uint64 op_value = extract_op_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string op = IMMEDIATE(op_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + char *op = IMMEDIATE(op_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("CACHE %s, %s(%s)", op, s, rs); } @@ -3422,15 +3323,15 @@ static std::string CACHE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CACHEE(uint64 instruction, Dis_info *info) +static char *CACHEE(uint64 instruction, Dis_info *info) { uint64 op_value = extract_op_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string op = IMMEDIATE(op_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + char *op = IMMEDIATE(op_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("CACHEE %s, %s(%s)", op, s, rs); } @@ -3446,13 +3347,13 @@ static std::string CACHEE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CEIL_L_D(uint64 instruction, Dis_info *info) +static char *CEIL_L_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("CEIL.L.D %s, %s", ft, fs); } @@ -3468,13 +3369,13 @@ static std::string CEIL_L_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CEIL_L_S(uint64 instruction, Dis_info *info) +static char *CEIL_L_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("CEIL.L.S %s, %s", ft, fs); } @@ -3490,13 +3391,13 @@ static std::string CEIL_L_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CEIL_W_D(uint64 instruction, Dis_info *info) +static char *CEIL_W_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("CEIL.W.D %s, %s", ft, fs); } @@ -3512,13 +3413,13 @@ static std::string CEIL_W_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CEIL_W_S(uint64 instruction, Dis_info *info) +static char *CEIL_W_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("CEIL.W.S %s, %s", ft, fs); } @@ -3534,13 +3435,13 @@ static std::string CEIL_W_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CFC1(uint64 instruction, Dis_info *info) +static char *CFC1(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string cs = CPR(cs_value); + const char *rt = GPR(rt_value); + char *cs = CPR(cs_value); return img_format("CFC1 %s, %s", rt, cs); } @@ -3556,13 +3457,13 @@ static std::string CFC1(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CFC2(uint64 instruction, Dis_info *info) +static char *CFC2(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string cs = CPR(cs_value); + const char *rt = GPR(rt_value); + char *cs = CPR(cs_value); return img_format("CFC2 %s, %s", rt, cs); } @@ -3578,13 +3479,13 @@ static std::string CFC2(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CLASS_D(uint64 instruction, Dis_info *info) +static char *CLASS_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("CLASS.D %s, %s", ft, fs); } @@ -3600,13 +3501,13 @@ static std::string CLASS_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CLASS_S(uint64 instruction, Dis_info *info) +static char *CLASS_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("CLASS.S %s, %s", ft, fs); } @@ -3622,13 +3523,13 @@ static std::string CLASS_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CLO(uint64 instruction, Dis_info *info) +static char *CLO(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("CLO %s, %s", rt, rs); } @@ -3644,13 +3545,13 @@ static std::string CLO(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CLZ(uint64 instruction, Dis_info *info) +static char *CLZ(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("CLZ %s, %s", rt, rs); } @@ -3666,15 +3567,15 @@ static std::string CLZ(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_AF_D(uint64 instruction, Dis_info *info) +static char *CMP_AF_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.AF.D %s, %s, %s", fd, fs, ft); } @@ -3690,15 +3591,15 @@ static std::string CMP_AF_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_AF_S(uint64 instruction, Dis_info *info) +static char *CMP_AF_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.AF.S %s, %s, %s", fd, fs, ft); } @@ -3714,15 +3615,15 @@ static std::string CMP_AF_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_EQ_D(uint64 instruction, Dis_info *info) +static char *CMP_EQ_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.EQ.D %s, %s, %s", fd, fs, ft); } @@ -3737,13 +3638,13 @@ static std::string CMP_EQ_D(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -static std::string CMP_EQ_PH(uint64 instruction, Dis_info *info) +static char *CMP_EQ_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("CMP.EQ.PH %s, %s", rs, rt); } @@ -3759,15 +3660,15 @@ static std::string CMP_EQ_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_EQ_S(uint64 instruction, Dis_info *info) +static char *CMP_EQ_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.EQ.S %s, %s, %s", fd, fs, ft); } @@ -3783,15 +3684,15 @@ static std::string CMP_EQ_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_LE_D(uint64 instruction, Dis_info *info) +static char *CMP_LE_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.LE.D %s, %s, %s", fd, fs, ft); } @@ -3806,13 +3707,13 @@ static std::string CMP_LE_D(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -static std::string CMP_LE_PH(uint64 instruction, Dis_info *info) +static char *CMP_LE_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("CMP.LE.PH %s, %s", rs, rt); } @@ -3828,15 +3729,15 @@ static std::string CMP_LE_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_LE_S(uint64 instruction, Dis_info *info) +static char *CMP_LE_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.LE.S %s, %s, %s", fd, fs, ft); } @@ -3852,15 +3753,15 @@ static std::string CMP_LE_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_LT_D(uint64 instruction, Dis_info *info) +static char *CMP_LT_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.LT.D %s, %s, %s", fd, fs, ft); } @@ -3875,13 +3776,13 @@ static std::string CMP_LT_D(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -static std::string CMP_LT_PH(uint64 instruction, Dis_info *info) +static char *CMP_LT_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("CMP.LT.PH %s, %s", rs, rt); } @@ -3897,15 +3798,15 @@ static std::string CMP_LT_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_LT_S(uint64 instruction, Dis_info *info) +static char *CMP_LT_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.LT.S %s, %s, %s", fd, fs, ft); } @@ -3921,15 +3822,15 @@ static std::string CMP_LT_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_NE_D(uint64 instruction, Dis_info *info) +static char *CMP_NE_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.NE.D %s, %s, %s", fd, fs, ft); } @@ -3945,15 +3846,15 @@ static std::string CMP_NE_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_NE_S(uint64 instruction, Dis_info *info) +static char *CMP_NE_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.NE.S %s, %s, %s", fd, fs, ft); } @@ -3969,15 +3870,15 @@ static std::string CMP_NE_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_OR_D(uint64 instruction, Dis_info *info) +static char *CMP_OR_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.OR.D %s, %s, %s", fd, fs, ft); } @@ -3993,15 +3894,15 @@ static std::string CMP_OR_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_OR_S(uint64 instruction, Dis_info *info) +static char *CMP_OR_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.OR.S %s, %s, %s", fd, fs, ft); } @@ -4017,15 +3918,15 @@ static std::string CMP_OR_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_SAF_D(uint64 instruction, Dis_info *info) +static char *CMP_SAF_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.SAF.D %s, %s, %s", fd, fs, ft); } @@ -4041,15 +3942,15 @@ static std::string CMP_SAF_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_SAF_S(uint64 instruction, Dis_info *info) +static char *CMP_SAF_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.SAF.S %s, %s, %s", fd, fs, ft); } @@ -4065,15 +3966,15 @@ static std::string CMP_SAF_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_SEQ_D(uint64 instruction, Dis_info *info) +static char *CMP_SEQ_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.SEQ.D %s, %s, %s", fd, fs, ft); } @@ -4089,15 +3990,15 @@ static std::string CMP_SEQ_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_SEQ_S(uint64 instruction, Dis_info *info) +static char *CMP_SEQ_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.SEQ.S %s, %s, %s", fd, fs, ft); } @@ -4113,15 +4014,15 @@ static std::string CMP_SEQ_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_SLE_D(uint64 instruction, Dis_info *info) +static char *CMP_SLE_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.SLE.D %s, %s, %s", fd, fs, ft); } @@ -4137,15 +4038,15 @@ static std::string CMP_SLE_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_SLE_S(uint64 instruction, Dis_info *info) +static char *CMP_SLE_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.SLE.S %s, %s, %s", fd, fs, ft); } @@ -4161,15 +4062,15 @@ static std::string CMP_SLE_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_SLT_D(uint64 instruction, Dis_info *info) +static char *CMP_SLT_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.SLT.D %s, %s, %s", fd, fs, ft); } @@ -4185,15 +4086,15 @@ static std::string CMP_SLT_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_SLT_S(uint64 instruction, Dis_info *info) +static char *CMP_SLT_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.SLT.S %s, %s, %s", fd, fs, ft); } @@ -4209,15 +4110,15 @@ static std::string CMP_SLT_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_SNE_D(uint64 instruction, Dis_info *info) +static char *CMP_SNE_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.SNE.D %s, %s, %s", fd, fs, ft); } @@ -4233,15 +4134,15 @@ static std::string CMP_SNE_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_SNE_S(uint64 instruction, Dis_info *info) +static char *CMP_SNE_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.SNE.S %s, %s, %s", fd, fs, ft); } @@ -4257,15 +4158,15 @@ static std::string CMP_SNE_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_SOR_D(uint64 instruction, Dis_info *info) +static char *CMP_SOR_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.SOR.D %s, %s, %s", fd, fs, ft); } @@ -4281,15 +4182,15 @@ static std::string CMP_SOR_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_SOR_S(uint64 instruction, Dis_info *info) +static char *CMP_SOR_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.SOR.S %s, %s, %s", fd, fs, ft); } @@ -4305,15 +4206,15 @@ static std::string CMP_SOR_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_SUEQ_D(uint64 instruction, Dis_info *info) +static char *CMP_SUEQ_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.SUEQ.D %s, %s, %s", fd, fs, ft); } @@ -4329,15 +4230,15 @@ static std::string CMP_SUEQ_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_SUEQ_S(uint64 instruction, Dis_info *info) +static char *CMP_SUEQ_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.SUEQ.S %s, %s, %s", fd, fs, ft); } @@ -4353,15 +4254,15 @@ static std::string CMP_SUEQ_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_SULE_D(uint64 instruction, Dis_info *info) +static char *CMP_SULE_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.SULE.D %s, %s, %s", fd, fs, ft); } @@ -4377,15 +4278,15 @@ static std::string CMP_SULE_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_SULE_S(uint64 instruction, Dis_info *info) +static char *CMP_SULE_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.SULE.S %s, %s, %s", fd, fs, ft); } @@ -4401,15 +4302,15 @@ static std::string CMP_SULE_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_SULT_D(uint64 instruction, Dis_info *info) +static char *CMP_SULT_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.SULT.D %s, %s, %s", fd, fs, ft); } @@ -4425,15 +4326,15 @@ static std::string CMP_SULT_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_SULT_S(uint64 instruction, Dis_info *info) +static char *CMP_SULT_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.SULT.S %s, %s, %s", fd, fs, ft); } @@ -4449,15 +4350,15 @@ static std::string CMP_SULT_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_SUN_D(uint64 instruction, Dis_info *info) +static char *CMP_SUN_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.SUN.D %s, %s, %s", fd, fs, ft); } @@ -4473,15 +4374,15 @@ static std::string CMP_SUN_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_SUNE_D(uint64 instruction, Dis_info *info) +static char *CMP_SUNE_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.SUNE.D %s, %s, %s", fd, fs, ft); } @@ -4497,15 +4398,15 @@ static std::string CMP_SUNE_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_SUNE_S(uint64 instruction, Dis_info *info) +static char *CMP_SUNE_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.SUNE.S %s, %s, %s", fd, fs, ft); } @@ -4521,15 +4422,15 @@ static std::string CMP_SUNE_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_SUN_S(uint64 instruction, Dis_info *info) +static char *CMP_SUN_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.SUN.S %s, %s, %s", fd, fs, ft); } @@ -4545,15 +4446,15 @@ static std::string CMP_SUN_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_UEQ_D(uint64 instruction, Dis_info *info) +static char *CMP_UEQ_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.UEQ.D %s, %s, %s", fd, fs, ft); } @@ -4569,15 +4470,15 @@ static std::string CMP_UEQ_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_UEQ_S(uint64 instruction, Dis_info *info) +static char *CMP_UEQ_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.UEQ.S %s, %s, %s", fd, fs, ft); } @@ -4593,15 +4494,15 @@ static std::string CMP_UEQ_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_ULE_D(uint64 instruction, Dis_info *info) +static char *CMP_ULE_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.ULE.D %s, %s, %s", fd, fs, ft); } @@ -4617,15 +4518,15 @@ static std::string CMP_ULE_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_ULE_S(uint64 instruction, Dis_info *info) +static char *CMP_ULE_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.ULE.S %s, %s, %s", fd, fs, ft); } @@ -4641,15 +4542,15 @@ static std::string CMP_ULE_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_ULT_D(uint64 instruction, Dis_info *info) +static char *CMP_ULT_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.ULT.D %s, %s, %s", fd, fs, ft); } @@ -4665,15 +4566,15 @@ static std::string CMP_ULT_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_ULT_S(uint64 instruction, Dis_info *info) +static char *CMP_ULT_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.ULT.S %s, %s, %s", fd, fs, ft); } @@ -4689,15 +4590,15 @@ static std::string CMP_ULT_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_UN_D(uint64 instruction, Dis_info *info) +static char *CMP_UN_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.UN.D %s, %s, %s", fd, fs, ft); } @@ -4713,15 +4614,15 @@ static std::string CMP_UN_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_UNE_D(uint64 instruction, Dis_info *info) +static char *CMP_UNE_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.UNE.D %s, %s, %s", fd, fs, ft); } @@ -4737,15 +4638,15 @@ static std::string CMP_UNE_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_UNE_S(uint64 instruction, Dis_info *info) +static char *CMP_UNE_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.UNE.S %s, %s, %s", fd, fs, ft); } @@ -4761,15 +4662,15 @@ static std::string CMP_UNE_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMP_UN_S(uint64 instruction, Dis_info *info) +static char *CMP_UN_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("CMP.UN.S %s, %s, %s", fd, fs, ft); } @@ -4786,15 +4687,15 @@ static std::string CMP_UN_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMPGDU_EQ_QB(uint64 instruction, Dis_info *info) +static char *CMPGDU_EQ_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("CMPGDU.EQ.QB %s, %s, %s", rd, rs, rt); } @@ -4811,15 +4712,15 @@ static std::string CMPGDU_EQ_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMPGDU_LE_QB(uint64 instruction, Dis_info *info) +static char *CMPGDU_LE_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("CMPGDU.LE.QB %s, %s, %s", rd, rs, rt); } @@ -4836,15 +4737,15 @@ static std::string CMPGDU_LE_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMPGDU_LT_QB(uint64 instruction, Dis_info *info) +static char *CMPGDU_LT_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("CMPGDU.LT.QB %s, %s, %s", rd, rs, rt); } @@ -4861,15 +4762,15 @@ static std::string CMPGDU_LT_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMPGU_EQ_QB(uint64 instruction, Dis_info *info) +static char *CMPGU_EQ_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("CMPGU.EQ.QB %s, %s, %s", rd, rs, rt); } @@ -4886,15 +4787,15 @@ static std::string CMPGU_EQ_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMPGU_LE_QB(uint64 instruction, Dis_info *info) +static char *CMPGU_LE_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("CMPGU.LE.QB %s, %s, %s", rd, rs, rt); } @@ -4911,15 +4812,15 @@ static std::string CMPGU_LE_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CMPGU_LT_QB(uint64 instruction, Dis_info *info) +static char *CMPGU_LT_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("CMPGU.LT.QB %s, %s, %s", rd, rs, rt); } @@ -4935,13 +4836,13 @@ static std::string CMPGU_LT_QB(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -static std::string CMPU_EQ_QB(uint64 instruction, Dis_info *info) +static char *CMPU_EQ_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("CMPU.EQ.QB %s, %s", rs, rt); } @@ -4957,13 +4858,13 @@ static std::string CMPU_EQ_QB(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -static std::string CMPU_LE_QB(uint64 instruction, Dis_info *info) +static char *CMPU_LE_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("CMPU.LE.QB %s, %s", rs, rt); } @@ -4979,13 +4880,13 @@ static std::string CMPU_LE_QB(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -static std::string CMPU_LT_QB(uint64 instruction, Dis_info *info) +static char *CMPU_LT_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("CMPU.LT.QB %s, %s", rs, rt); } @@ -5001,11 +4902,11 @@ static std::string CMPU_LT_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string COP2_1(uint64 instruction, Dis_info *info) +static char *COP2_1(uint64 instruction, Dis_info *info) { uint64 cofun_value = extract_cofun_25_24_23(instruction); - std::string cofun = IMMEDIATE(cofun_value); + char *cofun = IMMEDIATE(cofun_value); return img_format("COP2_1 %s", cofun); } @@ -5021,13 +4922,13 @@ static std::string COP2_1(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CTC1(uint64 instruction, Dis_info *info) +static char *CTC1(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string cs = CPR(cs_value); + const char *rt = GPR(rt_value); + char *cs = CPR(cs_value); return img_format("CTC1 %s, %s", rt, cs); } @@ -5043,13 +4944,13 @@ static std::string CTC1(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CTC2(uint64 instruction, Dis_info *info) +static char *CTC2(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string cs = CPR(cs_value); + const char *rt = GPR(rt_value); + char *cs = CPR(cs_value); return img_format("CTC2 %s, %s", rt, cs); } @@ -5065,13 +4966,13 @@ static std::string CTC2(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CVT_D_L(uint64 instruction, Dis_info *info) +static char *CVT_D_L(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("CVT.D.L %s, %s", ft, fs); } @@ -5087,13 +4988,13 @@ static std::string CVT_D_L(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CVT_D_S(uint64 instruction, Dis_info *info) +static char *CVT_D_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("CVT.D.S %s, %s", ft, fs); } @@ -5109,13 +5010,13 @@ static std::string CVT_D_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CVT_D_W(uint64 instruction, Dis_info *info) +static char *CVT_D_W(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("CVT.D.W %s, %s", ft, fs); } @@ -5131,13 +5032,13 @@ static std::string CVT_D_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CVT_L_D(uint64 instruction, Dis_info *info) +static char *CVT_L_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("CVT.L.D %s, %s", ft, fs); } @@ -5153,13 +5054,13 @@ static std::string CVT_L_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CVT_L_S(uint64 instruction, Dis_info *info) +static char *CVT_L_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("CVT.L.S %s, %s", ft, fs); } @@ -5175,13 +5076,13 @@ static std::string CVT_L_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CVT_S_D(uint64 instruction, Dis_info *info) +static char *CVT_S_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("CVT.S.D %s, %s", ft, fs); } @@ -5197,13 +5098,13 @@ static std::string CVT_S_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CVT_S_L(uint64 instruction, Dis_info *info) +static char *CVT_S_L(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("CVT.S.L %s, %s", ft, fs); } @@ -5219,13 +5120,13 @@ static std::string CVT_S_L(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CVT_S_PL(uint64 instruction, Dis_info *info) +static char *CVT_S_PL(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("CVT.S.PL %s, %s", ft, fs); } @@ -5241,13 +5142,13 @@ static std::string CVT_S_PL(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CVT_S_PU(uint64 instruction, Dis_info *info) +static char *CVT_S_PU(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("CVT.S.PU %s, %s", ft, fs); } @@ -5263,13 +5164,13 @@ static std::string CVT_S_PU(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CVT_S_W(uint64 instruction, Dis_info *info) +static char *CVT_S_W(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("CVT.S.W %s, %s", ft, fs); } @@ -5285,13 +5186,13 @@ static std::string CVT_S_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CVT_W_D(uint64 instruction, Dis_info *info) +static char *CVT_W_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("CVT.W.D %s, %s", ft, fs); } @@ -5307,13 +5208,13 @@ static std::string CVT_W_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string CVT_W_S(uint64 instruction, Dis_info *info) +static char *CVT_W_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("CVT.W.S %s, %s", ft, fs); } @@ -5329,13 +5230,13 @@ static std::string CVT_W_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DADDIU_48_(uint64 instruction, Dis_info *info) +static char *DADDIU_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); return img_format("DADDIU %s, %s", rt, s); } @@ -5351,15 +5252,15 @@ static std::string DADDIU_48_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DADDIU_NEG_(uint64 instruction, Dis_info *info) +static char *DADDIU_NEG_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string u = IMMEDIATE(neg_copy(u_value)); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *u = IMMEDIATE(neg_copy(u_value)); return img_format("DADDIU %s, %s, %s", rt, rs, u); } @@ -5375,15 +5276,15 @@ static std::string DADDIU_NEG_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DADDIU_U12_(uint64 instruction, Dis_info *info) +static char *DADDIU_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string u = IMMEDIATE(u_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *u = IMMEDIATE(u_value); return img_format("DADDIU %s, %s, %s", rt, rs, u); } @@ -5399,15 +5300,15 @@ static std::string DADDIU_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DADD(uint64 instruction, Dis_info *info) +static char *DADD(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DADD %s, %s, %s", rd, rs, rt); } @@ -5423,15 +5324,15 @@ static std::string DADD(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DADDU(uint64 instruction, Dis_info *info) +static char *DADDU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DADDU %s, %s, %s", rd, rs, rt); } @@ -5447,13 +5348,13 @@ static std::string DADDU(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DCLO(uint64 instruction, Dis_info *info) +static char *DCLO(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("DCLO %s, %s", rt, rs); } @@ -5469,13 +5370,13 @@ static std::string DCLO(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DCLZ(uint64 instruction, Dis_info *info) +static char *DCLZ(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("DCLZ %s, %s", rt, rs); } @@ -5491,15 +5392,15 @@ static std::string DCLZ(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DDIV(uint64 instruction, Dis_info *info) +static char *DDIV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DDIV %s, %s, %s", rd, rs, rt); } @@ -5515,15 +5416,15 @@ static std::string DDIV(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DDIVU(uint64 instruction, Dis_info *info) +static char *DDIVU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DDIVU %s, %s, %s", rd, rs, rt); } @@ -5539,11 +5440,11 @@ static std::string DDIVU(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DERET(uint64 instruction, Dis_info *info) +static char *DERET(uint64 instruction, Dis_info *info) { (void)instruction; - return "DERET "; + return g_strdup("DERET "); } @@ -5557,17 +5458,17 @@ static std::string DERET(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DEXTM(uint64 instruction, Dis_info *info) +static char *DEXTM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction); uint64 lsb_value = extract_lsb_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string lsb = IMMEDIATE(lsb_value); - std::string msbd = IMMEDIATE(encode_msbd_from_size(msbd_value)); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *lsb = IMMEDIATE(lsb_value); + char *msbd = IMMEDIATE(encode_msbd_from_size(msbd_value)); return img_format("DEXTM %s, %s, %s, %s", rt, rs, lsb, msbd); } @@ -5583,17 +5484,17 @@ static std::string DEXTM(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DEXT(uint64 instruction, Dis_info *info) +static char *DEXT(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction); uint64 lsb_value = extract_lsb_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string lsb = IMMEDIATE(lsb_value); - std::string msbd = IMMEDIATE(encode_msbd_from_size(msbd_value)); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *lsb = IMMEDIATE(lsb_value); + char *msbd = IMMEDIATE(encode_msbd_from_size(msbd_value)); return img_format("DEXT %s, %s, %s, %s", rt, rs, lsb, msbd); } @@ -5609,17 +5510,17 @@ static std::string DEXT(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DEXTU(uint64 instruction, Dis_info *info) +static char *DEXTU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction); uint64 lsb_value = extract_lsb_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string lsb = IMMEDIATE(lsb_value); - std::string msbd = IMMEDIATE(encode_msbd_from_size(msbd_value)); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *lsb = IMMEDIATE(lsb_value); + char *msbd = IMMEDIATE(encode_msbd_from_size(msbd_value)); return img_format("DEXTU %s, %s, %s, %s", rt, rs, lsb, msbd); } @@ -5635,17 +5536,17 @@ static std::string DEXTU(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DINSM(uint64 instruction, Dis_info *info) +static char *DINSM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction); uint64 lsb_value = extract_lsb_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string pos = IMMEDIATE(lsb_value); - std::string size = IMMEDIATE(msbd_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *pos = IMMEDIATE(lsb_value); + char *size = IMMEDIATE(msbd_value); /* !!!!!!!!!! - no conversion function */ return img_format("DINSM %s, %s, %s, %s", rt, rs, pos, size); @@ -5663,17 +5564,17 @@ static std::string DINSM(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DINS(uint64 instruction, Dis_info *info) +static char *DINS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction); uint64 lsb_value = extract_lsb_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string pos = IMMEDIATE(lsb_value); - std::string size = IMMEDIATE(msbd_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *pos = IMMEDIATE(lsb_value); + char *size = IMMEDIATE(msbd_value); /* !!!!!!!!!! - no conversion function */ return img_format("DINS %s, %s, %s, %s", rt, rs, pos, size); @@ -5691,17 +5592,17 @@ static std::string DINS(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DINSU(uint64 instruction, Dis_info *info) +static char *DINSU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction); uint64 lsb_value = extract_lsb_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string pos = IMMEDIATE(lsb_value); - std::string size = IMMEDIATE(msbd_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *pos = IMMEDIATE(lsb_value); + char *size = IMMEDIATE(msbd_value); /* !!!!!!!!!! - no conversion function */ return img_format("DINSU %s, %s, %s, %s", rt, rs, pos, size); @@ -5719,11 +5620,11 @@ static std::string DINSU(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DI(uint64 instruction, Dis_info *info) +static char *DI(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); - std::string rt = GPR(rt_value); + const char *rt = GPR(rt_value); return img_format("DI %s", rt); } @@ -5739,15 +5640,15 @@ static std::string DI(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DIV(uint64 instruction, Dis_info *info) +static char *DIV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DIV %s, %s, %s", rd, rs, rt); } @@ -5763,15 +5664,15 @@ static std::string DIV(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DIV_D(uint64 instruction, Dis_info *info) +static char *DIV_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("DIV.D %s, %s, %s", fd, fs, ft); } @@ -5787,15 +5688,15 @@ static std::string DIV_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DIV_S(uint64 instruction, Dis_info *info) +static char *DIV_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("DIV.S %s, %s, %s", fd, fs, ft); } @@ -5811,15 +5712,15 @@ static std::string DIV_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DIVU(uint64 instruction, Dis_info *info) +static char *DIVU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DIVU %s, %s, %s", rd, rs, rt); } @@ -5835,17 +5736,17 @@ static std::string DIVU(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DLSA(uint64 instruction, Dis_info *info) +static char *DLSA(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); uint64 u2_value = extract_u2_10_9(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); - std::string u2 = IMMEDIATE(u2_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *u2 = IMMEDIATE(u2_value); return img_format("DLSA %s, %s, %s, %s", rd, rs, rt, u2); } @@ -5861,13 +5762,13 @@ static std::string DLSA(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DLUI_48_(uint64 instruction, Dis_info *info) +static char *DLUI_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); uint64 u_value = extract_u_31_to_0__s32(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); return img_format("DLUI %s, %s", rt, u); } @@ -5883,15 +5784,15 @@ static std::string DLUI_48_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DMFC0(uint64 instruction, Dis_info *info) +static char *DMFC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - std::string rt = GPR(rt_value); - std::string c0s = CPR(c0s_value); - std::string sel = IMMEDIATE(sel_value); + const char *rt = GPR(rt_value); + char *c0s = CPR(c0s_value); + char *sel = IMMEDIATE(sel_value); return img_format("DMFC0 %s, %s, %s", rt, c0s, sel); } @@ -5907,13 +5808,13 @@ static std::string DMFC0(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DMFC1(uint64 instruction, Dis_info *info) +static char *DMFC1(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string fs = FPR(fs_value); + const char *rt = GPR(rt_value); + const char *fs = FPR(fs_value); return img_format("DMFC1 %s, %s", rt, fs); } @@ -5929,13 +5830,13 @@ static std::string DMFC1(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DMFC2(uint64 instruction, Dis_info *info) +static char *DMFC2(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string cs = CPR(cs_value); + const char *rt = GPR(rt_value); + char *cs = CPR(cs_value); return img_format("DMFC2 %s, %s", rt, cs); } @@ -5951,15 +5852,15 @@ static std::string DMFC2(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DMFGC0(uint64 instruction, Dis_info *info) +static char *DMFGC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - std::string rt = GPR(rt_value); - std::string c0s = CPR(c0s_value); - std::string sel = IMMEDIATE(sel_value); + const char *rt = GPR(rt_value); + char *c0s = CPR(c0s_value); + char *sel = IMMEDIATE(sel_value); return img_format("DMFGC0 %s, %s, %s", rt, c0s, sel); } @@ -5975,15 +5876,15 @@ static std::string DMFGC0(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DMOD(uint64 instruction, Dis_info *info) +static char *DMOD(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DMOD %s, %s, %s", rd, rs, rt); } @@ -5999,15 +5900,15 @@ static std::string DMOD(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DMODU(uint64 instruction, Dis_info *info) +static char *DMODU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DMODU %s, %s, %s", rd, rs, rt); } @@ -6023,15 +5924,15 @@ static std::string DMODU(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DMTC0(uint64 instruction, Dis_info *info) +static char *DMTC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - std::string rt = GPR(rt_value); - std::string c0s = CPR(c0s_value); - std::string sel = IMMEDIATE(sel_value); + const char *rt = GPR(rt_value); + char *c0s = CPR(c0s_value); + char *sel = IMMEDIATE(sel_value); return img_format("DMTC0 %s, %s, %s", rt, c0s, sel); } @@ -6047,13 +5948,13 @@ static std::string DMTC0(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DMTC1(uint64 instruction, Dis_info *info) +static char *DMTC1(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string fs = FPR(fs_value); + const char *rt = GPR(rt_value); + const char *fs = FPR(fs_value); return img_format("DMTC1 %s, %s", rt, fs); } @@ -6069,13 +5970,13 @@ static std::string DMTC1(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DMTC2(uint64 instruction, Dis_info *info) +static char *DMTC2(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string cs = CPR(cs_value); + const char *rt = GPR(rt_value); + char *cs = CPR(cs_value); return img_format("DMTC2 %s, %s", rt, cs); } @@ -6091,15 +5992,15 @@ static std::string DMTC2(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DMTGC0(uint64 instruction, Dis_info *info) +static char *DMTGC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - std::string rt = GPR(rt_value); - std::string c0s = CPR(c0s_value); - std::string sel = IMMEDIATE(sel_value); + const char *rt = GPR(rt_value); + char *c0s = CPR(c0s_value); + char *sel = IMMEDIATE(sel_value); return img_format("DMTGC0 %s, %s, %s", rt, c0s, sel); } @@ -6115,11 +6016,11 @@ static std::string DMTGC0(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DMT(uint64 instruction, Dis_info *info) +static char *DMT(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); - std::string rt = GPR(rt_value); + const char *rt = GPR(rt_value); return img_format("DMT %s", rt); } @@ -6135,15 +6036,15 @@ static std::string DMT(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DMUH(uint64 instruction, Dis_info *info) +static char *DMUH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DMUH %s, %s, %s", rd, rs, rt); } @@ -6159,15 +6060,15 @@ static std::string DMUH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DMUHU(uint64 instruction, Dis_info *info) +static char *DMUHU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DMUHU %s, %s, %s", rd, rs, rt); } @@ -6183,15 +6084,15 @@ static std::string DMUHU(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DMUL(uint64 instruction, Dis_info *info) +static char *DMUL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DMUL %s, %s, %s", rd, rs, rt); } @@ -6207,15 +6108,15 @@ static std::string DMUL(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DMULU(uint64 instruction, Dis_info *info) +static char *DMULU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DMULU %s, %s, %s", rd, rs, rt); } @@ -6232,15 +6133,15 @@ static std::string DMULU(uint64 instruction, Dis_info *info) * rs ----- * ac -- */ -static std::string DPA_W_PH(uint64 instruction, Dis_info *info) +static char *DPA_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DPA.W.PH %s, %s, %s", ac, rs, rt); } @@ -6256,15 +6157,15 @@ static std::string DPA_W_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DPAQ_SA_L_W(uint64 instruction, Dis_info *info) +static char *DPAQ_SA_L_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DPAQ_SA.L.W %s, %s, %s", ac, rs, rt); } @@ -6280,15 +6181,15 @@ static std::string DPAQ_SA_L_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DPAQ_S_W_PH(uint64 instruction, Dis_info *info) +static char *DPAQ_S_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DPAQ_S.W.PH %s, %s, %s", ac, rs, rt); } @@ -6304,15 +6205,15 @@ static std::string DPAQ_S_W_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DPAQX_SA_W_PH(uint64 instruction, Dis_info *info) +static char *DPAQX_SA_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DPAQX_SA.W.PH %s, %s, %s", ac, rs, rt); } @@ -6328,15 +6229,15 @@ static std::string DPAQX_SA_W_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DPAQX_S_W_PH(uint64 instruction, Dis_info *info) +static char *DPAQX_S_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DPAQX_S.W.PH %s, %s, %s", ac, rs, rt); } @@ -6352,15 +6253,15 @@ static std::string DPAQX_S_W_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DPAU_H_QBL(uint64 instruction, Dis_info *info) +static char *DPAU_H_QBL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DPAU.H.QBL %s, %s, %s", ac, rs, rt); } @@ -6376,15 +6277,15 @@ static std::string DPAU_H_QBL(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DPAU_H_QBR(uint64 instruction, Dis_info *info) +static char *DPAU_H_QBR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DPAU.H.QBR %s, %s, %s", ac, rs, rt); } @@ -6400,15 +6301,15 @@ static std::string DPAU_H_QBR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DPAX_W_PH(uint64 instruction, Dis_info *info) +static char *DPAX_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DPAX.W.PH %s, %s, %s", ac, rs, rt); } @@ -6424,15 +6325,15 @@ static std::string DPAX_W_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DPS_W_PH(uint64 instruction, Dis_info *info) +static char *DPS_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DPS.W.PH %s, %s, %s", ac, rs, rt); } @@ -6448,15 +6349,15 @@ static std::string DPS_W_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DPSQ_SA_L_W(uint64 instruction, Dis_info *info) +static char *DPSQ_SA_L_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DPSQ_SA.L.W %s, %s, %s", ac, rs, rt); } @@ -6472,15 +6373,15 @@ static std::string DPSQ_SA_L_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DPSQ_S_W_PH(uint64 instruction, Dis_info *info) +static char *DPSQ_S_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DPSQ_S.W.PH %s, %s, %s", ac, rs, rt); } @@ -6496,15 +6397,15 @@ static std::string DPSQ_S_W_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DPSQX_SA_W_PH(uint64 instruction, Dis_info *info) +static char *DPSQX_SA_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DPSQX_SA.W.PH %s, %s, %s", ac, rs, rt); } @@ -6520,15 +6421,15 @@ static std::string DPSQX_SA_W_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DPSQX_S_W_PH(uint64 instruction, Dis_info *info) +static char *DPSQX_S_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DPSQX_S.W.PH %s, %s, %s", ac, rs, rt); } @@ -6544,15 +6445,15 @@ static std::string DPSQX_S_W_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DPSU_H_QBL(uint64 instruction, Dis_info *info) +static char *DPSU_H_QBL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DPSU.H.QBL %s, %s, %s", ac, rs, rt); } @@ -6568,15 +6469,15 @@ static std::string DPSU_H_QBL(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DPSU_H_QBR(uint64 instruction, Dis_info *info) +static char *DPSU_H_QBR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DPSU.H.QBR %s, %s, %s", ac, rs, rt); } @@ -6592,15 +6493,15 @@ static std::string DPSU_H_QBR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DPSX_W_PH(uint64 instruction, Dis_info *info) +static char *DPSX_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DPSX.W.PH %s, %s, %s", ac, rs, rt); } @@ -6616,15 +6517,15 @@ static std::string DPSX_W_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DROTR(uint64 instruction, Dis_info *info) +static char *DROTR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string shift = IMMEDIATE(shift_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *shift = IMMEDIATE(shift_value); return img_format("DROTR %s, %s, %s", rt, rs, shift); } @@ -6640,15 +6541,15 @@ static std::string DROTR(uint64 instruction, Dis_info *info) * rs ----- * shift ----- */ -static std::string DROTR32(uint64 instruction, Dis_info *info) +static char *DROTR32(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string shift = IMMEDIATE(shift_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *shift = IMMEDIATE(shift_value); return img_format("DROTR32 %s, %s, %s", rt, rs, shift); } @@ -6664,15 +6565,15 @@ static std::string DROTR32(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DROTRV(uint64 instruction, Dis_info *info) +static char *DROTRV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DROTRV %s, %s, %s", rd, rs, rt); } @@ -6688,17 +6589,17 @@ static std::string DROTRV(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DROTX(uint64 instruction, Dis_info *info) +static char *DROTX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shiftx_value = extract_shiftx_11_10_9_8_7_6(instruction); uint64 shift_value = extract_shift_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string shift = IMMEDIATE(shift_value); - std::string shiftx = IMMEDIATE(shiftx_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *shift = IMMEDIATE(shift_value); + char *shiftx = IMMEDIATE(shiftx_value); return img_format("DROTX %s, %s, %s, %s", rt, rs, shift, shiftx); } @@ -6714,15 +6615,15 @@ static std::string DROTX(uint64 instruction, Dis_info *info) * rs ----- * shift ----- */ -static std::string DSLL(uint64 instruction, Dis_info *info) +static char *DSLL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string shift = IMMEDIATE(shift_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *shift = IMMEDIATE(shift_value); return img_format("DSLL %s, %s, %s", rt, rs, shift); } @@ -6738,15 +6639,15 @@ static std::string DSLL(uint64 instruction, Dis_info *info) * rs ----- * shift ----- */ -static std::string DSLL32(uint64 instruction, Dis_info *info) +static char *DSLL32(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string shift = IMMEDIATE(shift_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *shift = IMMEDIATE(shift_value); return img_format("DSLL32 %s, %s, %s", rt, rs, shift); } @@ -6762,15 +6663,15 @@ static std::string DSLL32(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DSLLV(uint64 instruction, Dis_info *info) +static char *DSLLV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DSLLV %s, %s, %s", rd, rs, rt); } @@ -6786,15 +6687,15 @@ static std::string DSLLV(uint64 instruction, Dis_info *info) * rs ----- * shift ----- */ -static std::string DSRA(uint64 instruction, Dis_info *info) +static char *DSRA(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string shift = IMMEDIATE(shift_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *shift = IMMEDIATE(shift_value); return img_format("DSRA %s, %s, %s", rt, rs, shift); } @@ -6810,15 +6711,15 @@ static std::string DSRA(uint64 instruction, Dis_info *info) * rs ----- * shift ----- */ -static std::string DSRA32(uint64 instruction, Dis_info *info) +static char *DSRA32(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string shift = IMMEDIATE(shift_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *shift = IMMEDIATE(shift_value); return img_format("DSRA32 %s, %s, %s", rt, rs, shift); } @@ -6834,15 +6735,15 @@ static std::string DSRA32(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DSRAV(uint64 instruction, Dis_info *info) +static char *DSRAV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DSRAV %s, %s, %s", rd, rs, rt); } @@ -6858,15 +6759,15 @@ static std::string DSRAV(uint64 instruction, Dis_info *info) * rs ----- * shift ----- */ -static std::string DSRL(uint64 instruction, Dis_info *info) +static char *DSRL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string shift = IMMEDIATE(shift_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *shift = IMMEDIATE(shift_value); return img_format("DSRL %s, %s, %s", rt, rs, shift); } @@ -6882,15 +6783,15 @@ static std::string DSRL(uint64 instruction, Dis_info *info) * rs ----- * shift ----- */ -static std::string DSRL32(uint64 instruction, Dis_info *info) +static char *DSRL32(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string shift = IMMEDIATE(shift_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *shift = IMMEDIATE(shift_value); return img_format("DSRL32 %s, %s, %s", rt, rs, shift); } @@ -6906,15 +6807,15 @@ static std::string DSRL32(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DSRLV(uint64 instruction, Dis_info *info) +static char *DSRLV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DSRLV %s, %s, %s", rd, rs, rt); } @@ -6930,15 +6831,15 @@ static std::string DSRLV(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DSUB(uint64 instruction, Dis_info *info) +static char *DSUB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DSUB %s, %s, %s", rd, rs, rt); } @@ -6954,15 +6855,15 @@ static std::string DSUB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DSUBU(uint64 instruction, Dis_info *info) +static char *DSUBU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("DSUBU %s, %s, %s", rd, rs, rt); } @@ -6978,11 +6879,11 @@ static std::string DSUBU(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DVPE(uint64 instruction, Dis_info *info) +static char *DVPE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); - std::string rt = GPR(rt_value); + const char *rt = GPR(rt_value); return img_format("DVPE %s", rt); } @@ -6998,11 +6899,11 @@ static std::string DVPE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string DVP(uint64 instruction, Dis_info *info) +static char *DVP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); - std::string rt = GPR(rt_value); + const char *rt = GPR(rt_value); return img_format("DVP %s", rt); } @@ -7018,11 +6919,11 @@ static std::string DVP(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string EHB(uint64 instruction, Dis_info *info) +static char *EHB(uint64 instruction, Dis_info *info) { (void)instruction; - return "EHB "; + return g_strdup("EHB "); } @@ -7036,11 +6937,11 @@ static std::string EHB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string EI(uint64 instruction, Dis_info *info) +static char *EI(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); - std::string rt = GPR(rt_value); + const char *rt = GPR(rt_value); return img_format("EI %s", rt); } @@ -7056,11 +6957,11 @@ static std::string EI(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string EMT(uint64 instruction, Dis_info *info) +static char *EMT(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); - std::string rt = GPR(rt_value); + const char *rt = GPR(rt_value); return img_format("EMT %s", rt); } @@ -7076,11 +6977,11 @@ static std::string EMT(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string ERET(uint64 instruction, Dis_info *info) +static char *ERET(uint64 instruction, Dis_info *info) { (void)instruction; - return "ERET "; + return g_strdup("ERET "); } @@ -7094,11 +6995,11 @@ static std::string ERET(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string ERETNC(uint64 instruction, Dis_info *info) +static char *ERETNC(uint64 instruction, Dis_info *info) { (void)instruction; - return "ERETNC "; + return g_strdup("ERETNC "); } @@ -7112,11 +7013,11 @@ static std::string ERETNC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string EVP(uint64 instruction, Dis_info *info) +static char *EVP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); - std::string rt = GPR(rt_value); + const char *rt = GPR(rt_value); return img_format("EVP %s", rt); } @@ -7132,11 +7033,11 @@ static std::string EVP(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string EVPE(uint64 instruction, Dis_info *info) +static char *EVPE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); - std::string rt = GPR(rt_value); + const char *rt = GPR(rt_value); return img_format("EVPE %s", rt); } @@ -7152,17 +7053,17 @@ static std::string EVPE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string EXT(uint64 instruction, Dis_info *info) +static char *EXT(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction); uint64 lsb_value = extract_lsb_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string lsb = IMMEDIATE(lsb_value); - std::string msbd = IMMEDIATE(encode_msbd_from_size(msbd_value)); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *lsb = IMMEDIATE(lsb_value); + char *msbd = IMMEDIATE(encode_msbd_from_size(msbd_value)); return img_format("EXT %s, %s, %s, %s", rt, rs, lsb, msbd); } @@ -7178,17 +7079,17 @@ static std::string EXT(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string EXTD(uint64 instruction, Dis_info *info) +static char *EXTD(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); uint64 shift_value = extract_shift_10_9_8_7_6(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); - std::string shift = IMMEDIATE(shift_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *shift = IMMEDIATE(shift_value); return img_format("EXTD %s, %s, %s, %s", rd, rs, rt, shift); } @@ -7204,17 +7105,17 @@ static std::string EXTD(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string EXTD32(uint64 instruction, Dis_info *info) +static char *EXTD32(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); uint64 shift_value = extract_shift_10_9_8_7_6(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); - std::string shift = IMMEDIATE(shift_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *shift = IMMEDIATE(shift_value); return img_format("EXTD32 %s, %s, %s, %s", rd, rs, rt, shift); } @@ -7230,15 +7131,15 @@ static std::string EXTD32(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string EXTPDP(uint64 instruction, Dis_info *info) +static char *EXTPDP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 size_value = extract_size_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(rt_value); - std::string ac = AC(ac_value); - std::string size = IMMEDIATE(size_value); + const char *rt = GPR(rt_value); + const char *ac = AC(ac_value); + char *size = IMMEDIATE(size_value); return img_format("EXTPDP %s, %s, %s", rt, ac, size); } @@ -7254,15 +7155,15 @@ static std::string EXTPDP(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string EXTPDPV(uint64 instruction, Dis_info *info) +static char *EXTPDPV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(rt_value); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); return img_format("EXTPDPV %s, %s, %s", rt, ac, rs); } @@ -7278,15 +7179,15 @@ static std::string EXTPDPV(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string EXTP(uint64 instruction, Dis_info *info) +static char *EXTP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 size_value = extract_size_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(rt_value); - std::string ac = AC(ac_value); - std::string size = IMMEDIATE(size_value); + const char *rt = GPR(rt_value); + const char *ac = AC(ac_value); + char *size = IMMEDIATE(size_value); return img_format("EXTP %s, %s, %s", rt, ac, size); } @@ -7302,15 +7203,15 @@ static std::string EXTP(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string EXTPV(uint64 instruction, Dis_info *info) +static char *EXTPV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(rt_value); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); return img_format("EXTPV %s, %s, %s", rt, ac, rs); } @@ -7327,15 +7228,15 @@ static std::string EXTPV(uint64 instruction, Dis_info *info) * shift ----- * ac -- */ -static std::string EXTR_RS_W(uint64 instruction, Dis_info *info) +static char *EXTR_RS_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 shift_value = extract_shift_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(rt_value); - std::string ac = AC(ac_value); - std::string shift = IMMEDIATE(shift_value); + const char *rt = GPR(rt_value); + const char *ac = AC(ac_value); + char *shift = IMMEDIATE(shift_value); return img_format("EXTR_RS.W %s, %s, %s", rt, ac, shift); } @@ -7352,15 +7253,15 @@ static std::string EXTR_RS_W(uint64 instruction, Dis_info *info) * shift ----- * ac -- */ -static std::string EXTR_R_W(uint64 instruction, Dis_info *info) +static char *EXTR_R_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 shift_value = extract_shift_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(rt_value); - std::string ac = AC(ac_value); - std::string shift = IMMEDIATE(shift_value); + const char *rt = GPR(rt_value); + const char *ac = AC(ac_value); + char *shift = IMMEDIATE(shift_value); return img_format("EXTR_R.W %s, %s, %s", rt, ac, shift); } @@ -7377,15 +7278,15 @@ static std::string EXTR_R_W(uint64 instruction, Dis_info *info) * shift ----- * ac -- */ -static std::string EXTR_S_H(uint64 instruction, Dis_info *info) +static char *EXTR_S_H(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 shift_value = extract_shift_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(rt_value); - std::string ac = AC(ac_value); - std::string shift = IMMEDIATE(shift_value); + const char *rt = GPR(rt_value); + const char *ac = AC(ac_value); + char *shift = IMMEDIATE(shift_value); return img_format("EXTR_S.H %s, %s, %s", rt, ac, shift); } @@ -7402,15 +7303,15 @@ static std::string EXTR_S_H(uint64 instruction, Dis_info *info) * shift ----- * ac -- */ -static std::string EXTR_W(uint64 instruction, Dis_info *info) +static char *EXTR_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 shift_value = extract_shift_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(rt_value); - std::string ac = AC(ac_value); - std::string shift = IMMEDIATE(shift_value); + const char *rt = GPR(rt_value); + const char *ac = AC(ac_value); + char *shift = IMMEDIATE(shift_value); return img_format("EXTR.W %s, %s, %s", rt, ac, shift); } @@ -7427,15 +7328,15 @@ static std::string EXTR_W(uint64 instruction, Dis_info *info) * rs ----- * ac -- */ -static std::string EXTRV_RS_W(uint64 instruction, Dis_info *info) +static char *EXTRV_RS_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(rt_value); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); return img_format("EXTRV_RS.W %s, %s, %s", rt, ac, rs); } @@ -7452,15 +7353,15 @@ static std::string EXTRV_RS_W(uint64 instruction, Dis_info *info) * rs ----- * ac -- */ -static std::string EXTRV_R_W(uint64 instruction, Dis_info *info) +static char *EXTRV_R_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(rt_value); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); return img_format("EXTRV_R.W %s, %s, %s", rt, ac, rs); } @@ -7477,15 +7378,15 @@ static std::string EXTRV_R_W(uint64 instruction, Dis_info *info) * rs ----- * ac -- */ -static std::string EXTRV_S_H(uint64 instruction, Dis_info *info) +static char *EXTRV_S_H(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(rt_value); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); return img_format("EXTRV_S.H %s, %s, %s", rt, ac, rs); } @@ -7502,15 +7403,15 @@ static std::string EXTRV_S_H(uint64 instruction, Dis_info *info) * rs ----- * ac -- */ -static std::string EXTRV_W(uint64 instruction, Dis_info *info) +static char *EXTRV_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(rt_value); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); return img_format("EXTRV.W %s, %s, %s", rt, ac, rs); } @@ -7527,17 +7428,17 @@ static std::string EXTRV_W(uint64 instruction, Dis_info *info) * rd ----- * shift ----- */ -static std::string EXTW(uint64 instruction, Dis_info *info) +static char *EXTW(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); uint64 shift_value = extract_shift_10_9_8_7_6(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); - std::string shift = IMMEDIATE(shift_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *shift = IMMEDIATE(shift_value); return img_format("EXTW %s, %s, %s, %s", rd, rs, rt, shift); } @@ -7553,13 +7454,13 @@ static std::string EXTW(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string FLOOR_L_D(uint64 instruction, Dis_info *info) +static char *FLOOR_L_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("FLOOR.L.D %s, %s", ft, fs); } @@ -7575,13 +7476,13 @@ static std::string FLOOR_L_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string FLOOR_L_S(uint64 instruction, Dis_info *info) +static char *FLOOR_L_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("FLOOR.L.S %s, %s", ft, fs); } @@ -7597,13 +7498,13 @@ static std::string FLOOR_L_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string FLOOR_W_D(uint64 instruction, Dis_info *info) +static char *FLOOR_W_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("FLOOR.W.D %s, %s", ft, fs); } @@ -7619,13 +7520,13 @@ static std::string FLOOR_W_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string FLOOR_W_S(uint64 instruction, Dis_info *info) +static char *FLOOR_W_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("FLOOR.W.S %s, %s", ft, fs); } @@ -7641,15 +7542,15 @@ static std::string FLOOR_W_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string FORK(uint64 instruction, Dis_info *info) +static char *FORK(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("FORK %s, %s, %s", rd, rs, rt); } @@ -7665,11 +7566,11 @@ static std::string FORK(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string HYPCALL(uint64 instruction, Dis_info *info) +static char *HYPCALL(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_17_to_0(instruction); - std::string code = IMMEDIATE(code_value); + char *code = IMMEDIATE(code_value); return img_format("HYPCALL %s", code); } @@ -7685,11 +7586,11 @@ static std::string HYPCALL(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string HYPCALL_16_(uint64 instruction, Dis_info *info) +static char *HYPCALL_16_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_1_0(instruction); - std::string code = IMMEDIATE(code_value); + char *code = IMMEDIATE(code_value); return img_format("HYPCALL %s", code); } @@ -7705,17 +7606,17 @@ static std::string HYPCALL_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string INS(uint64 instruction, Dis_info *info) +static char *INS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction); uint64 lsb_value = extract_lsb_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string pos = IMMEDIATE(lsb_value); - std::string size = IMMEDIATE(msbd_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *pos = IMMEDIATE(lsb_value); + char *size = IMMEDIATE(msbd_value); /* !!!!!!!!!! - no conversion function */ return img_format("INS %s, %s, %s, %s", rt, rs, pos, size); @@ -7732,13 +7633,13 @@ static std::string INS(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -static std::string INSV(uint64 instruction, Dis_info *info) +static char *INSV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("INSV %s, %s", rt, rs); } @@ -7754,11 +7655,11 @@ static std::string INSV(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string IRET(uint64 instruction, Dis_info *info) +static char *IRET(uint64 instruction, Dis_info *info) { (void)instruction; - return "IRET "; + return g_strdup("IRET "); } @@ -7772,11 +7673,11 @@ static std::string IRET(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string JALRC_16_(uint64 instruction, Dis_info *info) +static char *JALRC_16_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_9_8_7_6_5(instruction); - std::string rt = GPR(rt_value); + const char *rt = GPR(rt_value); return img_format("JALRC $%d, %s", 31, rt); } @@ -7792,13 +7693,13 @@ static std::string JALRC_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string JALRC_32_(uint64 instruction, Dis_info *info) +static char *JALRC_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("JALRC %s, %s", rt, rs); } @@ -7814,13 +7715,13 @@ static std::string JALRC_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string JALRC_HB(uint64 instruction, Dis_info *info) +static char *JALRC_HB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("JALRC.HB %s, %s", rt, rs); } @@ -7836,11 +7737,11 @@ static std::string JALRC_HB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string JRC(uint64 instruction, Dis_info *info) +static char *JRC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_9_8_7_6_5(instruction); - std::string rt = GPR(rt_value); + const char *rt = GPR(rt_value); return img_format("JRC %s", rt); } @@ -7856,15 +7757,15 @@ static std::string JRC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LB_16_(uint64 instruction, Dis_info *info) +static char *LB_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_1_0(instruction); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string u = IMMEDIATE(u_value); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); + char *u = IMMEDIATE(u_value); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); return img_format("LB %s, %s(%s)", rt3, u, rs3); } @@ -7880,13 +7781,13 @@ static std::string LB_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LB_GP_(uint64 instruction, Dis_info *info) +static char *LB_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_0(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); return img_format("LB %s, %s($%d)", rt, u, 28); } @@ -7902,15 +7803,15 @@ static std::string LB_GP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LB_S9_(uint64 instruction, Dis_info *info) +static char *LB_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("LB %s, %s(%s)", rt, s, rs); } @@ -7926,15 +7827,15 @@ static std::string LB_S9_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LB_U12_(uint64 instruction, Dis_info *info) +static char *LB_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); + const char *rs = GPR(rs_value); return img_format("LB %s, %s(%s)", rt, u, rs); } @@ -7950,15 +7851,15 @@ static std::string LB_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LBE(uint64 instruction, Dis_info *info) +static char *LBE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("LBE %s, %s(%s)", rt, s, rs); } @@ -7974,15 +7875,15 @@ static std::string LBE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LBU_16_(uint64 instruction, Dis_info *info) +static char *LBU_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_1_0(instruction); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string u = IMMEDIATE(u_value); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); + char *u = IMMEDIATE(u_value); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); return img_format("LBU %s, %s(%s)", rt3, u, rs3); } @@ -7998,13 +7899,13 @@ static std::string LBU_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LBU_GP_(uint64 instruction, Dis_info *info) +static char *LBU_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_0(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); return img_format("LBU %s, %s($%d)", rt, u, 28); } @@ -8020,15 +7921,15 @@ static std::string LBU_GP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LBU_S9_(uint64 instruction, Dis_info *info) +static char *LBU_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("LBU %s, %s(%s)", rt, s, rs); } @@ -8044,15 +7945,15 @@ static std::string LBU_S9_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LBU_U12_(uint64 instruction, Dis_info *info) +static char *LBU_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); + const char *rs = GPR(rs_value); return img_format("LBU %s, %s(%s)", rt, u, rs); } @@ -8068,15 +7969,15 @@ static std::string LBU_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LBUE(uint64 instruction, Dis_info *info) +static char *LBUE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("LBUE %s, %s(%s)", rt, s, rs); } @@ -8092,15 +7993,15 @@ static std::string LBUE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LBUX(uint64 instruction, Dis_info *info) +static char *LBUX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("LBUX %s, %s(%s)", rd, rs, rt); } @@ -8116,15 +8017,15 @@ static std::string LBUX(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LBX(uint64 instruction, Dis_info *info) +static char *LBX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("LBX %s, %s(%s)", rd, rs, rt); } @@ -8140,13 +8041,13 @@ static std::string LBX(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LD_GP_(uint64 instruction, Dis_info *info) +static char *LD_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_to_3__s3(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); return img_format("LD %s, %s($%d)", rt, u, 28); } @@ -8162,15 +8063,15 @@ static std::string LD_GP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LD_S9_(uint64 instruction, Dis_info *info) +static char *LD_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("LD %s, %s(%s)", rt, s, rs); } @@ -8186,15 +8087,15 @@ static std::string LD_S9_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LD_U12_(uint64 instruction, Dis_info *info) +static char *LD_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); + const char *rs = GPR(rs_value); return img_format("LD %s, %s(%s)", rt, u, rs); } @@ -8210,13 +8111,13 @@ static std::string LD_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LDC1_GP_(uint64 instruction, Dis_info *info) +static char *LDC1_GP_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_2__s2(instruction); - std::string ft = FPR(ft_value); - std::string u = IMMEDIATE(u_value); + const char *ft = FPR(ft_value); + char *u = IMMEDIATE(u_value); return img_format("LDC1 %s, %s($%d)", ft, u, 28); } @@ -8232,15 +8133,15 @@ static std::string LDC1_GP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LDC1_S9_(uint64 instruction, Dis_info *info) +static char *LDC1_S9_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string ft = FPR(ft_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + const char *ft = FPR(ft_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("LDC1 %s, %s(%s)", ft, s, rs); } @@ -8256,15 +8157,15 @@ static std::string LDC1_S9_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LDC1_U12_(uint64 instruction, Dis_info *info) +static char *LDC1_U12_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string ft = FPR(ft_value); - std::string u = IMMEDIATE(u_value); - std::string rs = GPR(rs_value); + const char *ft = FPR(ft_value); + char *u = IMMEDIATE(u_value); + const char *rs = GPR(rs_value); return img_format("LDC1 %s, %s(%s)", ft, u, rs); } @@ -8280,15 +8181,15 @@ static std::string LDC1_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LDC1XS(uint64 instruction, Dis_info *info) +static char *LDC1XS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ft_value = extract_ft_15_14_13_12_11(instruction); - std::string ft = FPR(ft_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ft = FPR(ft_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("LDC1XS %s, %s(%s)", ft, rs, rt); } @@ -8304,15 +8205,15 @@ static std::string LDC1XS(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LDC1X(uint64 instruction, Dis_info *info) +static char *LDC1X(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ft_value = extract_ft_15_14_13_12_11(instruction); - std::string ft = FPR(ft_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ft = FPR(ft_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("LDC1X %s, %s(%s)", ft, rs, rt); } @@ -8328,15 +8229,15 @@ static std::string LDC1X(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LDC2(uint64 instruction, Dis_info *info) +static char *LDC2(uint64 instruction, Dis_info *info) { uint64 ct_value = extract_ct_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string ct = CPR(ct_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + char *ct = CPR(ct_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("LDC2 %s, %s(%s)", ct, s, rs); } @@ -8352,17 +8253,17 @@ static std::string LDC2(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LDM(uint64 instruction, Dis_info *info) +static char *LDM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 count3_value = extract_count3_14_13_12(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); - std::string count3 = IMMEDIATE(encode_count3_from_count(count3_value)); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); + char *count3 = IMMEDIATE(encode_count3_from_count(count3_value)); return img_format("LDM %s, %s(%s), %s", rt, s, rs, count3); } @@ -8378,13 +8279,13 @@ static std::string LDM(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LDPC_48_(uint64 instruction, Dis_info *info) +static char *LDPC_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - std::string rt = GPR(rt_value); - std::string s = ADDRESS(s_value, 6, info); + const char *rt = GPR(rt_value); + char *s = ADDRESS(s_value, 6, info); return img_format("LDPC %s, %s", rt, s); } @@ -8400,15 +8301,15 @@ static std::string LDPC_48_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LDX(uint64 instruction, Dis_info *info) +static char *LDX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("LDX %s, %s(%s)", rd, rs, rt); } @@ -8424,15 +8325,15 @@ static std::string LDX(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LDXS(uint64 instruction, Dis_info *info) +static char *LDXS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("LDXS %s, %s(%s)", rd, rs, rt); } @@ -8448,15 +8349,15 @@ static std::string LDXS(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LH_16_(uint64 instruction, Dis_info *info) +static char *LH_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_2_1__s1(instruction); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string u = IMMEDIATE(u_value); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); + char *u = IMMEDIATE(u_value); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); return img_format("LH %s, %s(%s)", rt3, u, rs3); } @@ -8472,13 +8373,13 @@ static std::string LH_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LH_GP_(uint64 instruction, Dis_info *info) +static char *LH_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_1__s1(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); return img_format("LH %s, %s($%d)", rt, u, 28); } @@ -8494,15 +8395,15 @@ static std::string LH_GP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LH_S9_(uint64 instruction, Dis_info *info) +static char *LH_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("LH %s, %s(%s)", rt, s, rs); } @@ -8518,15 +8419,15 @@ static std::string LH_S9_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LH_U12_(uint64 instruction, Dis_info *info) +static char *LH_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); + const char *rs = GPR(rs_value); return img_format("LH %s, %s(%s)", rt, u, rs); } @@ -8542,15 +8443,15 @@ static std::string LH_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LHE(uint64 instruction, Dis_info *info) +static char *LHE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("LHE %s, %s(%s)", rt, s, rs); } @@ -8566,15 +8467,15 @@ static std::string LHE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LHU_16_(uint64 instruction, Dis_info *info) +static char *LHU_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_2_1__s1(instruction); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string u = IMMEDIATE(u_value); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); + char *u = IMMEDIATE(u_value); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); return img_format("LHU %s, %s(%s)", rt3, u, rs3); } @@ -8590,13 +8491,13 @@ static std::string LHU_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LHU_GP_(uint64 instruction, Dis_info *info) +static char *LHU_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_1__s1(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); return img_format("LHU %s, %s($%d)", rt, u, 28); } @@ -8612,15 +8513,15 @@ static std::string LHU_GP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LHU_S9_(uint64 instruction, Dis_info *info) +static char *LHU_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("LHU %s, %s(%s)", rt, s, rs); } @@ -8636,15 +8537,15 @@ static std::string LHU_S9_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LHU_U12_(uint64 instruction, Dis_info *info) +static char *LHU_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); + const char *rs = GPR(rs_value); return img_format("LHU %s, %s(%s)", rt, u, rs); } @@ -8660,15 +8561,15 @@ static std::string LHU_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LHUE(uint64 instruction, Dis_info *info) +static char *LHUE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("LHUE %s, %s(%s)", rt, s, rs); } @@ -8684,15 +8585,15 @@ static std::string LHUE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LHUX(uint64 instruction, Dis_info *info) +static char *LHUX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("LHUX %s, %s(%s)", rd, rs, rt); } @@ -8708,15 +8609,15 @@ static std::string LHUX(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LHUXS(uint64 instruction, Dis_info *info) +static char *LHUXS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("LHUXS %s, %s(%s)", rd, rs, rt); } @@ -8732,15 +8633,15 @@ static std::string LHUXS(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LHXS(uint64 instruction, Dis_info *info) +static char *LHXS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("LHXS %s, %s(%s)", rd, rs, rt); } @@ -8756,15 +8657,15 @@ static std::string LHXS(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LHX(uint64 instruction, Dis_info *info) +static char *LHX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("LHX %s, %s(%s)", rd, rs, rt); } @@ -8780,13 +8681,13 @@ static std::string LHX(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LI_16_(uint64 instruction, Dis_info *info) +static char *LI_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 eu_value = extract_eu_6_5_4_3_2_1_0(instruction); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string eu = IMMEDIATE(encode_eu_from_s_li16(eu_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); + char *eu = IMMEDIATE(encode_eu_from_s_li16(eu_value)); return img_format("LI %s, %s", rt3, eu); } @@ -8802,13 +8703,13 @@ static std::string LI_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LI_48_(uint64 instruction, Dis_info *info) +static char *LI_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); return img_format("LI %s, %s", rt, s); } @@ -8824,15 +8725,15 @@ static std::string LI_48_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LL(uint64 instruction, Dis_info *info) +static char *LL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_s2(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("LL %s, %s(%s)", rt, s, rs); } @@ -8848,15 +8749,15 @@ static std::string LL(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LLD(uint64 instruction, Dis_info *info) +static char *LLD(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_s3(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("LLD %s, %s(%s)", rt, s, rs); } @@ -8872,15 +8773,15 @@ static std::string LLD(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LLDP(uint64 instruction, Dis_info *info) +static char *LLDP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ru_value = extract_ru_7_6_5_4_3(instruction); - std::string rt = GPR(rt_value); - std::string ru = GPR(ru_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *ru = GPR(ru_value); + const char *rs = GPR(rs_value); return img_format("LLDP %s, %s, (%s)", rt, ru, rs); } @@ -8896,15 +8797,15 @@ static std::string LLDP(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LLE(uint64 instruction, Dis_info *info) +static char *LLE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_s2(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("LLE %s, %s(%s)", rt, s, rs); } @@ -8920,15 +8821,15 @@ static std::string LLE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LLWP(uint64 instruction, Dis_info *info) +static char *LLWP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ru_value = extract_ru_7_6_5_4_3(instruction); - std::string rt = GPR(rt_value); - std::string ru = GPR(ru_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *ru = GPR(ru_value); + const char *rs = GPR(rs_value); return img_format("LLWP %s, %s, (%s)", rt, ru, rs); } @@ -8944,15 +8845,15 @@ static std::string LLWP(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LLWPE(uint64 instruction, Dis_info *info) +static char *LLWPE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ru_value = extract_ru_7_6_5_4_3(instruction); - std::string rt = GPR(rt_value); - std::string ru = GPR(ru_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *ru = GPR(ru_value); + const char *rs = GPR(rs_value); return img_format("LLWPE %s, %s, (%s)", rt, ru, rs); } @@ -8968,17 +8869,17 @@ static std::string LLWPE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LSA(uint64 instruction, Dis_info *info) +static char *LSA(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); uint64 u2_value = extract_u2_10_9(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); - std::string u2 = IMMEDIATE(u2_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *u2 = IMMEDIATE(u2_value); return img_format("LSA %s, %s, %s, %s", rd, rs, rt, u2); } @@ -8994,13 +8895,13 @@ static std::string LSA(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LUI(uint64 instruction, Dis_info *info) +static char *LUI(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); int64 s_value = extract_s__se31_0_11_to_2_20_to_12_s12(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); return img_format("LUI %s, %%hi(%s)", rt, s); } @@ -9016,15 +8917,15 @@ static std::string LUI(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LW_16_(uint64 instruction, Dis_info *info) +static char *LW_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_3_2_1_0__s2(instruction); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string u = IMMEDIATE(u_value); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); + char *u = IMMEDIATE(u_value); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); return img_format("LW %s, %s(%s)", rt3, u, rs3); } @@ -9040,15 +8941,15 @@ static std::string LW_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LW_4X4_(uint64 instruction, Dis_info *info) +static char *LW_4X4_(uint64 instruction, Dis_info *info) { uint64 rt4_value = extract_rt4_9_7_6_5(instruction); uint64 rs4_value = extract_rs4_4_2_1_0(instruction); uint64 u_value = extract_u_3_8__s2(instruction); - std::string rt4 = GPR(decode_gpr_gpr4(rt4_value)); - std::string u = IMMEDIATE(u_value); - std::string rs4 = GPR(decode_gpr_gpr4(rs4_value)); + const char *rt4 = GPR(decode_gpr_gpr4(rt4_value)); + char *u = IMMEDIATE(u_value); + const char *rs4 = GPR(decode_gpr_gpr4(rs4_value)); return img_format("LW %s, %s(%s)", rt4, u, rs4); } @@ -9064,13 +8965,13 @@ static std::string LW_4X4_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LW_GP_(uint64 instruction, Dis_info *info) +static char *LW_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_to_2__s2(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); return img_format("LW %s, %s($%d)", rt, u, 28); } @@ -9086,13 +8987,13 @@ static std::string LW_GP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LW_GP16_(uint64 instruction, Dis_info *info) +static char *LW_GP16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 u_value = extract_u_6_5_4_3_2_1_0__s2(instruction); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string u = IMMEDIATE(u_value); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); + char *u = IMMEDIATE(u_value); return img_format("LW %s, %s($%d)", rt3, u, 28); } @@ -9108,15 +9009,15 @@ static std::string LW_GP16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LW_S9_(uint64 instruction, Dis_info *info) +static char *LW_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("LW %s, %s(%s)", rt, s, rs); } @@ -9132,13 +9033,13 @@ static std::string LW_S9_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LW_SP_(uint64 instruction, Dis_info *info) +static char *LW_SP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_9_8_7_6_5(instruction); uint64 u_value = extract_u_4_3_2_1_0__s2(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); return img_format("LW %s, %s($%d)", rt, u, 29); } @@ -9154,15 +9055,15 @@ static std::string LW_SP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LW_U12_(uint64 instruction, Dis_info *info) +static char *LW_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); + const char *rs = GPR(rs_value); return img_format("LW %s, %s(%s)", rt, u, rs); } @@ -9178,13 +9079,13 @@ static std::string LW_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LWC1_GP_(uint64 instruction, Dis_info *info) +static char *LWC1_GP_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_2__s2(instruction); - std::string ft = FPR(ft_value); - std::string u = IMMEDIATE(u_value); + const char *ft = FPR(ft_value); + char *u = IMMEDIATE(u_value); return img_format("LWC1 %s, %s($%d)", ft, u, 28); } @@ -9200,15 +9101,15 @@ static std::string LWC1_GP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LWC1_S9_(uint64 instruction, Dis_info *info) +static char *LWC1_S9_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string ft = FPR(ft_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + const char *ft = FPR(ft_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("LWC1 %s, %s(%s)", ft, s, rs); } @@ -9224,15 +9125,15 @@ static std::string LWC1_S9_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LWC1_U12_(uint64 instruction, Dis_info *info) +static char *LWC1_U12_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string ft = FPR(ft_value); - std::string u = IMMEDIATE(u_value); - std::string rs = GPR(rs_value); + const char *ft = FPR(ft_value); + char *u = IMMEDIATE(u_value); + const char *rs = GPR(rs_value); return img_format("LWC1 %s, %s(%s)", ft, u, rs); } @@ -9248,15 +9149,15 @@ static std::string LWC1_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LWC1X(uint64 instruction, Dis_info *info) +static char *LWC1X(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ft_value = extract_ft_15_14_13_12_11(instruction); - std::string ft = FPR(ft_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ft = FPR(ft_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("LWC1X %s, %s(%s)", ft, rs, rt); } @@ -9272,15 +9173,15 @@ static std::string LWC1X(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LWC1XS(uint64 instruction, Dis_info *info) +static char *LWC1XS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ft_value = extract_ft_15_14_13_12_11(instruction); - std::string ft = FPR(ft_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ft = FPR(ft_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("LWC1XS %s, %s(%s)", ft, rs, rt); } @@ -9296,15 +9197,15 @@ static std::string LWC1XS(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LWC2(uint64 instruction, Dis_info *info) +static char *LWC2(uint64 instruction, Dis_info *info) { uint64 ct_value = extract_ct_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string ct = CPR(ct_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + char *ct = CPR(ct_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("LWC2 %s, %s(%s)", ct, s, rs); } @@ -9320,15 +9221,15 @@ static std::string LWC2(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LWE(uint64 instruction, Dis_info *info) +static char *LWE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("LWE %s, %s(%s)", rt, s, rs); } @@ -9344,17 +9245,17 @@ static std::string LWE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LWM(uint64 instruction, Dis_info *info) +static char *LWM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 count3_value = extract_count3_14_13_12(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); - std::string count3 = IMMEDIATE(encode_count3_from_count(count3_value)); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); + char *count3 = IMMEDIATE(encode_count3_from_count(count3_value)); return img_format("LWM %s, %s(%s), %s", rt, s, rs, count3); } @@ -9370,13 +9271,13 @@ static std::string LWM(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LWPC_48_(uint64 instruction, Dis_info *info) +static char *LWPC_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - std::string rt = GPR(rt_value); - std::string s = ADDRESS(s_value, 6, info); + const char *rt = GPR(rt_value); + char *s = ADDRESS(s_value, 6, info); return img_format("LWPC %s, %s", rt, s); } @@ -9392,13 +9293,13 @@ static std::string LWPC_48_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LWU_GP_(uint64 instruction, Dis_info *info) +static char *LWU_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_2__s2(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); return img_format("LWU %s, %s($%d)", rt, u, 28); } @@ -9414,15 +9315,15 @@ static std::string LWU_GP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LWU_S9_(uint64 instruction, Dis_info *info) +static char *LWU_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("LWU %s, %s(%s)", rt, s, rs); } @@ -9438,15 +9339,15 @@ static std::string LWU_S9_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LWU_U12_(uint64 instruction, Dis_info *info) +static char *LWU_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); + const char *rs = GPR(rs_value); return img_format("LWU %s, %s(%s)", rt, u, rs); } @@ -9462,15 +9363,15 @@ static std::string LWU_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LWUX(uint64 instruction, Dis_info *info) +static char *LWUX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("LWUX %s, %s(%s)", rd, rs, rt); } @@ -9486,15 +9387,15 @@ static std::string LWUX(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LWUXS(uint64 instruction, Dis_info *info) +static char *LWUXS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("LWUXS %s, %s(%s)", rd, rs, rt); } @@ -9510,15 +9411,15 @@ static std::string LWUXS(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LWX(uint64 instruction, Dis_info *info) +static char *LWX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("LWX %s, %s(%s)", rd, rs, rt); } @@ -9534,15 +9435,15 @@ static std::string LWX(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LWXS_16_(uint64 instruction, Dis_info *info) +static char *LWXS_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 rd3_value = extract_rd3_3_2_1(instruction); - std::string rd3 = GPR(decode_gpr_gpr3(rd3_value)); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); - std::string rt3 = IMMEDIATE(decode_gpr_gpr3(rt3_value)); + const char *rd3 = GPR(decode_gpr_gpr3(rd3_value)); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); + char *rt3 = IMMEDIATE(decode_gpr_gpr3(rt3_value)); return img_format("LWXS %s, %s(%s)", rd3, rs3, rt3); } @@ -9558,15 +9459,15 @@ static std::string LWXS_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string LWXS_32_(uint64 instruction, Dis_info *info) +static char *LWXS_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("LWXS %s, %s(%s)", rd, rs, rt); } @@ -9583,15 +9484,15 @@ static std::string LWXS_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MADD_DSP_(uint64 instruction, Dis_info *info) +static char *MADD_DSP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("MADD %s, %s, %s", ac, rs, rt); } @@ -9607,15 +9508,15 @@ static std::string MADD_DSP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MADDF_D(uint64 instruction, Dis_info *info) +static char *MADDF_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("MADDF.D %s, %s, %s", fd, fs, ft); } @@ -9631,15 +9532,15 @@ static std::string MADDF_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MADDF_S(uint64 instruction, Dis_info *info) +static char *MADDF_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("MADDF.S %s, %s, %s", fd, fs, ft); } @@ -9656,15 +9557,15 @@ static std::string MADDF_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MADDU_DSP_(uint64 instruction, Dis_info *info) +static char *MADDU_DSP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("MADDU %s, %s, %s", ac, rs, rt); } @@ -9681,15 +9582,15 @@ static std::string MADDU_DSP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MAQ_S_W_PHL(uint64 instruction, Dis_info *info) +static char *MAQ_S_W_PHL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("MAQ_S.W.PHL %s, %s, %s", ac, rs, rt); } @@ -9706,15 +9607,15 @@ static std::string MAQ_S_W_PHL(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MAQ_S_W_PHR(uint64 instruction, Dis_info *info) +static char *MAQ_S_W_PHR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("MAQ_S.W.PHR %s, %s, %s", ac, rs, rt); } @@ -9731,15 +9632,15 @@ static std::string MAQ_S_W_PHR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MAQ_SA_W_PHL(uint64 instruction, Dis_info *info) +static char *MAQ_SA_W_PHL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("MAQ_SA.W.PHL %s, %s, %s", ac, rs, rt); } @@ -9756,15 +9657,15 @@ static std::string MAQ_SA_W_PHL(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MAQ_SA_W_PHR(uint64 instruction, Dis_info *info) +static char *MAQ_SA_W_PHR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("MAQ_SA.W.PHR %s, %s, %s", ac, rs, rt); } @@ -9780,15 +9681,15 @@ static std::string MAQ_SA_W_PHR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MAX_D(uint64 instruction, Dis_info *info) +static char *MAX_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("MAX.D %s, %s, %s", fd, fs, ft); } @@ -9804,15 +9705,15 @@ static std::string MAX_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MAX_S(uint64 instruction, Dis_info *info) +static char *MAX_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("MAX.S %s, %s, %s", fd, fs, ft); } @@ -9828,15 +9729,15 @@ static std::string MAX_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MAXA_D(uint64 instruction, Dis_info *info) +static char *MAXA_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("MAXA.D %s, %s, %s", fd, fs, ft); } @@ -9852,15 +9753,15 @@ static std::string MAXA_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MAXA_S(uint64 instruction, Dis_info *info) +static char *MAXA_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("MAXA.S %s, %s, %s", fd, fs, ft); } @@ -9876,15 +9777,15 @@ static std::string MAXA_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MFC0(uint64 instruction, Dis_info *info) +static char *MFC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - std::string rt = GPR(rt_value); - std::string c0s = CPR(c0s_value); - std::string sel = IMMEDIATE(sel_value); + const char *rt = GPR(rt_value); + char *c0s = CPR(c0s_value); + char *sel = IMMEDIATE(sel_value); return img_format("MFC0 %s, %s, %s", rt, c0s, sel); } @@ -9900,13 +9801,13 @@ static std::string MFC0(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MFC1(uint64 instruction, Dis_info *info) +static char *MFC1(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string fs = FPR(fs_value); + const char *rt = GPR(rt_value); + const char *fs = FPR(fs_value); return img_format("MFC1 %s, %s", rt, fs); } @@ -9922,13 +9823,13 @@ static std::string MFC1(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MFC2(uint64 instruction, Dis_info *info) +static char *MFC2(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string cs = CPR(cs_value); + const char *rt = GPR(rt_value); + char *cs = CPR(cs_value); return img_format("MFC2 %s, %s", rt, cs); } @@ -9944,15 +9845,15 @@ static std::string MFC2(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MFGC0(uint64 instruction, Dis_info *info) +static char *MFGC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - std::string rt = GPR(rt_value); - std::string c0s = CPR(c0s_value); - std::string sel = IMMEDIATE(sel_value); + const char *rt = GPR(rt_value); + char *c0s = CPR(c0s_value); + char *sel = IMMEDIATE(sel_value); return img_format("MFGC0 %s, %s, %s", rt, c0s, sel); } @@ -9968,15 +9869,15 @@ static std::string MFGC0(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MFHC0(uint64 instruction, Dis_info *info) +static char *MFHC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - std::string rt = GPR(rt_value); - std::string c0s = CPR(c0s_value); - std::string sel = IMMEDIATE(sel_value); + const char *rt = GPR(rt_value); + char *c0s = CPR(c0s_value); + char *sel = IMMEDIATE(sel_value); return img_format("MFHC0 %s, %s, %s", rt, c0s, sel); } @@ -9992,13 +9893,13 @@ static std::string MFHC0(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MFHC1(uint64 instruction, Dis_info *info) +static char *MFHC1(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string fs = FPR(fs_value); + const char *rt = GPR(rt_value); + const char *fs = FPR(fs_value); return img_format("MFHC1 %s, %s", rt, fs); } @@ -10014,13 +9915,13 @@ static std::string MFHC1(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MFHC2(uint64 instruction, Dis_info *info) +static char *MFHC2(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string cs = CPR(cs_value); + const char *rt = GPR(rt_value); + char *cs = CPR(cs_value); return img_format("MFHC2 %s, %s", rt, cs); } @@ -10036,15 +9937,15 @@ static std::string MFHC2(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MFHGC0(uint64 instruction, Dis_info *info) +static char *MFHGC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - std::string rt = GPR(rt_value); - std::string c0s = CPR(c0s_value); - std::string sel = IMMEDIATE(sel_value); + const char *rt = GPR(rt_value); + char *c0s = CPR(c0s_value); + char *sel = IMMEDIATE(sel_value); return img_format("MFHGC0 %s, %s, %s", rt, c0s, sel); } @@ -10059,13 +9960,13 @@ static std::string MFHGC0(uint64 instruction, Dis_info *info) * rt ----- * ac -- */ -static std::string MFHI_DSP_(uint64 instruction, Dis_info *info) +static char *MFHI_DSP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(rt_value); - std::string ac = AC(ac_value); + const char *rt = GPR(rt_value); + const char *ac = AC(ac_value); return img_format("MFHI %s, %s", rt, ac); } @@ -10081,17 +9982,17 @@ static std::string MFHI_DSP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MFHTR(uint64 instruction, Dis_info *info) +static char *MFHTR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); uint64 u_value = extract_u_10(instruction); - std::string rt = GPR(rt_value); - std::string c0s = IMMEDIATE(c0s_value); - std::string u = IMMEDIATE(u_value); - std::string sel = IMMEDIATE(sel_value); + const char *rt = GPR(rt_value); + char *c0s = IMMEDIATE(c0s_value); + char *u = IMMEDIATE(u_value); + char *sel = IMMEDIATE(sel_value); return img_format("MFHTR %s, %s, %s, %s", rt, c0s, u, sel); } @@ -10106,13 +10007,13 @@ static std::string MFHTR(uint64 instruction, Dis_info *info) * rt ----- * ac -- */ -static std::string MFLO_DSP_(uint64 instruction, Dis_info *info) +static char *MFLO_DSP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(rt_value); - std::string ac = AC(ac_value); + const char *rt = GPR(rt_value); + const char *ac = AC(ac_value); return img_format("MFLO %s, %s", rt, ac); } @@ -10128,17 +10029,17 @@ static std::string MFLO_DSP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MFTR(uint64 instruction, Dis_info *info) +static char *MFTR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); uint64 u_value = extract_u_10(instruction); - std::string rt = GPR(rt_value); - std::string c0s = IMMEDIATE(c0s_value); - std::string u = IMMEDIATE(u_value); - std::string sel = IMMEDIATE(sel_value); + const char *rt = GPR(rt_value); + char *c0s = IMMEDIATE(c0s_value); + char *u = IMMEDIATE(u_value); + char *sel = IMMEDIATE(sel_value); return img_format("MFTR %s, %s, %s, %s", rt, c0s, u, sel); } @@ -10154,15 +10055,15 @@ static std::string MFTR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MIN_D(uint64 instruction, Dis_info *info) +static char *MIN_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("MIN.D %s, %s, %s", fd, fs, ft); } @@ -10178,15 +10079,15 @@ static std::string MIN_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MIN_S(uint64 instruction, Dis_info *info) +static char *MIN_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("MIN.S %s, %s, %s", fd, fs, ft); } @@ -10202,15 +10103,15 @@ static std::string MIN_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MINA_D(uint64 instruction, Dis_info *info) +static char *MINA_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("MINA.D %s, %s, %s", fd, fs, ft); } @@ -10226,15 +10127,15 @@ static std::string MINA_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MINA_S(uint64 instruction, Dis_info *info) +static char *MINA_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("MINA.S %s, %s, %s", fd, fs, ft); } @@ -10250,15 +10151,15 @@ static std::string MINA_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MOD(uint64 instruction, Dis_info *info) +static char *MOD(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("MOD %s, %s, %s", rd, rs, rt); } @@ -10274,15 +10175,15 @@ static std::string MOD(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MODSUB(uint64 instruction, Dis_info *info) +static char *MODSUB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("MODSUB %s, %s, %s", rd, rs, rt); } @@ -10298,15 +10199,15 @@ static std::string MODSUB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MODU(uint64 instruction, Dis_info *info) +static char *MODU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("MODU %s, %s, %s", rd, rs, rt); } @@ -10322,13 +10223,13 @@ static std::string MODU(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MOV_D(uint64 instruction, Dis_info *info) +static char *MOV_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("MOV.D %s, %s", ft, fs); } @@ -10344,13 +10245,13 @@ static std::string MOV_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MOV_S(uint64 instruction, Dis_info *info) +static char *MOV_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("MOV.S %s, %s", ft, fs); } @@ -10366,15 +10267,15 @@ static std::string MOV_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MOVE_BALC(uint64 instruction, Dis_info *info) +static char *MOVE_BALC(uint64 instruction, Dis_info *info) { uint64 rtz4_value = extract_rtz4_27_26_25_23_22_21(instruction); uint64 rd1_value = extract_rdl_25_24(instruction); int64 s_value = extract_s__se21_0_20_to_1_s1(instruction); - std::string rd1 = GPR(decode_gpr_gpr1(rd1_value)); - std::string rtz4 = GPR(decode_gpr_gpr4_zero(rtz4_value)); - std::string s = ADDRESS(s_value, 4, info); + const char *rd1 = GPR(decode_gpr_gpr1(rd1_value)); + const char *rtz4 = GPR(decode_gpr_gpr4_zero(rtz4_value)); + char *s = ADDRESS(s_value, 4, info); return img_format("MOVE.BALC %s, %s, %s", rd1, rtz4, s); } @@ -10390,17 +10291,17 @@ static std::string MOVE_BALC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MOVEP(uint64 instruction, Dis_info *info) +static char *MOVEP(uint64 instruction, Dis_info *info) { uint64 rtz4_value = extract_rtz4_9_7_6_5(instruction); uint64 rd2_value = extract_rd2_3_8(instruction); uint64 rsz4_value = extract_rsz4_4_2_1_0(instruction); - std::string rd2 = GPR(decode_gpr_gpr2_reg1(rd2_value)); - std::string re2 = GPR(decode_gpr_gpr2_reg2(rd2_value)); + const char *rd2 = GPR(decode_gpr_gpr2_reg1(rd2_value)); + const char *re2 = GPR(decode_gpr_gpr2_reg2(rd2_value)); /* !!!!!!!!!! - no conversion function */ - std::string rsz4 = GPR(decode_gpr_gpr4_zero(rsz4_value)); - std::string rtz4 = GPR(decode_gpr_gpr4_zero(rtz4_value)); + const char *rsz4 = GPR(decode_gpr_gpr4_zero(rsz4_value)); + const char *rtz4 = GPR(decode_gpr_gpr4_zero(rtz4_value)); return img_format("MOVEP %s, %s, %s, %s", rd2, re2, rsz4, rtz4); /* hand edited */ @@ -10417,16 +10318,16 @@ static std::string MOVEP(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MOVEP_REV_(uint64 instruction, Dis_info *info) +static char *MOVEP_REV_(uint64 instruction, Dis_info *info) { uint64 rt4_value = extract_rt4_9_7_6_5(instruction); uint64 rd2_value = extract_rd2_3_8(instruction); uint64 rs4_value = extract_rs4_4_2_1_0(instruction); - std::string rs4 = GPR(decode_gpr_gpr4(rs4_value)); - std::string rt4 = GPR(decode_gpr_gpr4(rt4_value)); - std::string rd2 = GPR(decode_gpr_gpr2_reg1(rd2_value)); - std::string rs2 = GPR(decode_gpr_gpr2_reg2(rd2_value)); + const char *rs4 = GPR(decode_gpr_gpr4(rs4_value)); + const char *rt4 = GPR(decode_gpr_gpr4(rt4_value)); + const char *rd2 = GPR(decode_gpr_gpr2_reg1(rd2_value)); + const char *rs2 = GPR(decode_gpr_gpr2_reg2(rd2_value)); /* !!!!!!!!!! - no conversion function */ return img_format("MOVEP %s, %s, %s, %s", rs4, rt4, rd2, rs2); @@ -10444,13 +10345,13 @@ static std::string MOVEP_REV_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MOVE(uint64 instruction, Dis_info *info) +static char *MOVE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_9_8_7_6_5(instruction); uint64 rs_value = extract_rs_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("MOVE %s, %s", rt, rs); } @@ -10466,15 +10367,15 @@ static std::string MOVE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MOVN(uint64 instruction, Dis_info *info) +static char *MOVN(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("MOVN %s, %s, %s", rd, rs, rt); } @@ -10490,15 +10391,15 @@ static std::string MOVN(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MOVZ(uint64 instruction, Dis_info *info) +static char *MOVZ(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("MOVZ %s, %s, %s", rd, rs, rt); } @@ -10514,15 +10415,15 @@ static std::string MOVZ(uint64 instruction, Dis_info *info) * rs ----- * ac -- */ -static std::string MSUB_DSP_(uint64 instruction, Dis_info *info) +static char *MSUB_DSP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("MSUB %s, %s, %s", ac, rs, rt); } @@ -10538,15 +10439,15 @@ static std::string MSUB_DSP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MSUBF_D(uint64 instruction, Dis_info *info) +static char *MSUBF_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("MSUBF.D %s, %s, %s", fd, fs, ft); } @@ -10562,15 +10463,15 @@ static std::string MSUBF_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MSUBF_S(uint64 instruction, Dis_info *info) +static char *MSUBF_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("MSUBF.S %s, %s, %s", fd, fs, ft); } @@ -10586,15 +10487,15 @@ static std::string MSUBF_S(uint64 instruction, Dis_info *info) * rs ----- * ac -- */ -static std::string MSUBU_DSP_(uint64 instruction, Dis_info *info) +static char *MSUBU_DSP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("MSUBU %s, %s, %s", ac, rs, rt); } @@ -10610,15 +10511,15 @@ static std::string MSUBU_DSP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MTC0(uint64 instruction, Dis_info *info) +static char *MTC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - std::string rt = GPR(rt_value); - std::string c0s = CPR(c0s_value); - std::string sel = IMMEDIATE(sel_value); + const char *rt = GPR(rt_value); + char *c0s = CPR(c0s_value); + char *sel = IMMEDIATE(sel_value); return img_format("MTC0 %s, %s, %s", rt, c0s, sel); } @@ -10634,13 +10535,13 @@ static std::string MTC0(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MTC1(uint64 instruction, Dis_info *info) +static char *MTC1(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string fs = FPR(fs_value); + const char *rt = GPR(rt_value); + const char *fs = FPR(fs_value); return img_format("MTC1 %s, %s", rt, fs); } @@ -10656,13 +10557,13 @@ static std::string MTC1(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MTC2(uint64 instruction, Dis_info *info) +static char *MTC2(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string cs = CPR(cs_value); + const char *rt = GPR(rt_value); + char *cs = CPR(cs_value); return img_format("MTC2 %s, %s", rt, cs); } @@ -10678,15 +10579,15 @@ static std::string MTC2(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MTGC0(uint64 instruction, Dis_info *info) +static char *MTGC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - std::string rt = GPR(rt_value); - std::string c0s = CPR(c0s_value); - std::string sel = IMMEDIATE(sel_value); + const char *rt = GPR(rt_value); + char *c0s = CPR(c0s_value); + char *sel = IMMEDIATE(sel_value); return img_format("MTGC0 %s, %s, %s", rt, c0s, sel); } @@ -10702,15 +10603,15 @@ static std::string MTGC0(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MTHC0(uint64 instruction, Dis_info *info) +static char *MTHC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - std::string rt = GPR(rt_value); - std::string c0s = CPR(c0s_value); - std::string sel = IMMEDIATE(sel_value); + const char *rt = GPR(rt_value); + char *c0s = CPR(c0s_value); + char *sel = IMMEDIATE(sel_value); return img_format("MTHC0 %s, %s, %s", rt, c0s, sel); } @@ -10726,13 +10627,13 @@ static std::string MTHC0(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MTHC1(uint64 instruction, Dis_info *info) +static char *MTHC1(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string fs = FPR(fs_value); + const char *rt = GPR(rt_value); + const char *fs = FPR(fs_value); return img_format("MTHC1 %s, %s", rt, fs); } @@ -10748,13 +10649,13 @@ static std::string MTHC1(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MTHC2(uint64 instruction, Dis_info *info) +static char *MTHC2(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string cs = CPR(cs_value); + const char *rt = GPR(rt_value); + char *cs = CPR(cs_value); return img_format("MTHC2 %s, %s", rt, cs); } @@ -10770,15 +10671,15 @@ static std::string MTHC2(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MTHGC0(uint64 instruction, Dis_info *info) +static char *MTHGC0(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - std::string rt = GPR(rt_value); - std::string c0s = CPR(c0s_value); - std::string sel = IMMEDIATE(sel_value); + const char *rt = GPR(rt_value); + char *c0s = CPR(c0s_value); + char *sel = IMMEDIATE(sel_value); return img_format("MTHGC0 %s, %s, %s", rt, c0s, sel); } @@ -10793,13 +10694,13 @@ static std::string MTHGC0(uint64 instruction, Dis_info *info) * rs ----- * ac -- */ -static std::string MTHI_DSP_(uint64 instruction, Dis_info *info) +static char *MTHI_DSP_(uint64 instruction, Dis_info *info) { uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rs = GPR(rs_value); - std::string ac = AC(ac_value); + const char *rs = GPR(rs_value); + const char *ac = AC(ac_value); return img_format("MTHI %s, %s", rs, ac); } @@ -10814,13 +10715,13 @@ static std::string MTHI_DSP_(uint64 instruction, Dis_info *info) * rs ----- * ac -- */ -static std::string MTHLIP(uint64 instruction, Dis_info *info) +static char *MTHLIP(uint64 instruction, Dis_info *info) { uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rs = GPR(rs_value); - std::string ac = AC(ac_value); + const char *rs = GPR(rs_value); + const char *ac = AC(ac_value); return img_format("MTHLIP %s, %s", rs, ac); } @@ -10836,17 +10737,17 @@ static std::string MTHLIP(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MTHTR(uint64 instruction, Dis_info *info) +static char *MTHTR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); uint64 u_value = extract_u_10(instruction); - std::string rt = GPR(rt_value); - std::string c0s = IMMEDIATE(c0s_value); - std::string u = IMMEDIATE(u_value); - std::string sel = IMMEDIATE(sel_value); + const char *rt = GPR(rt_value); + char *c0s = IMMEDIATE(c0s_value); + char *u = IMMEDIATE(u_value); + char *sel = IMMEDIATE(sel_value); return img_format("MTHTR %s, %s, %s, %s", rt, c0s, u, sel); } @@ -10861,13 +10762,13 @@ static std::string MTHTR(uint64 instruction, Dis_info *info) * rs ----- * ac -- */ -static std::string MTLO_DSP_(uint64 instruction, Dis_info *info) +static char *MTLO_DSP_(uint64 instruction, Dis_info *info) { uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rs = GPR(rs_value); - std::string ac = AC(ac_value); + const char *rs = GPR(rs_value); + const char *ac = AC(ac_value); return img_format("MTLO %s, %s", rs, ac); } @@ -10883,17 +10784,17 @@ static std::string MTLO_DSP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MTTR(uint64 instruction, Dis_info *info) +static char *MTTR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); uint64 u_value = extract_u_10(instruction); - std::string rt = GPR(rt_value); - std::string c0s = IMMEDIATE(c0s_value); - std::string u = IMMEDIATE(u_value); - std::string sel = IMMEDIATE(sel_value); + const char *rt = GPR(rt_value); + char *c0s = IMMEDIATE(c0s_value); + char *u = IMMEDIATE(u_value); + char *sel = IMMEDIATE(sel_value); return img_format("MTTR %s, %s, %s, %s", rt, c0s, u, sel); } @@ -10909,15 +10810,15 @@ static std::string MTTR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MUH(uint64 instruction, Dis_info *info) +static char *MUH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("MUH %s, %s, %s", rd, rs, rt); } @@ -10933,15 +10834,15 @@ static std::string MUH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MUHU(uint64 instruction, Dis_info *info) +static char *MUHU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("MUHU %s, %s, %s", rd, rs, rt); } @@ -10957,15 +10858,15 @@ static std::string MUHU(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MUL_32_(uint64 instruction, Dis_info *info) +static char *MUL_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("MUL %s, %s, %s", rd, rs, rt); } @@ -10981,13 +10882,13 @@ static std::string MUL_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MUL_4X4_(uint64 instruction, Dis_info *info) +static char *MUL_4X4_(uint64 instruction, Dis_info *info) { uint64 rt4_value = extract_rt4_9_7_6_5(instruction); uint64 rs4_value = extract_rs4_4_2_1_0(instruction); - std::string rs4 = GPR(decode_gpr_gpr4(rs4_value)); - std::string rt4 = GPR(decode_gpr_gpr4(rt4_value)); + const char *rs4 = GPR(decode_gpr_gpr4(rs4_value)); + const char *rt4 = GPR(decode_gpr_gpr4(rt4_value)); return img_format("MUL %s, %s", rs4, rt4); } @@ -11003,15 +10904,15 @@ static std::string MUL_4X4_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MUL_D(uint64 instruction, Dis_info *info) +static char *MUL_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("MUL.D %s, %s, %s", fd, fs, ft); } @@ -11028,15 +10929,15 @@ static std::string MUL_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MUL_PH(uint64 instruction, Dis_info *info) +static char *MUL_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("MUL.PH %s, %s, %s", rd, rs, rt); } @@ -11053,15 +10954,15 @@ static std::string MUL_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MUL_S_PH(uint64 instruction, Dis_info *info) +static char *MUL_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("MUL_S.PH %s, %s, %s", rd, rs, rt); } @@ -11077,15 +10978,15 @@ static std::string MUL_S_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MUL_S(uint64 instruction, Dis_info *info) +static char *MUL_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("MUL.S %s, %s, %s", fd, fs, ft); } @@ -11102,15 +11003,15 @@ static std::string MUL_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MULEQ_S_W_PHL(uint64 instruction, Dis_info *info) +static char *MULEQ_S_W_PHL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("MULEQ_S.W.PHL %s, %s, %s", rd, rs, rt); } @@ -11127,15 +11028,15 @@ static std::string MULEQ_S_W_PHL(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MULEQ_S_W_PHR(uint64 instruction, Dis_info *info) +static char *MULEQ_S_W_PHR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("MULEQ_S.W.PHR %s, %s, %s", rd, rs, rt); } @@ -11152,15 +11053,15 @@ static std::string MULEQ_S_W_PHR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MULEU_S_PH_QBL(uint64 instruction, Dis_info *info) +static char *MULEU_S_PH_QBL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("MULEU_S.PH.QBL %s, %s, %s", rd, rs, rt); } @@ -11177,15 +11078,15 @@ static std::string MULEU_S_PH_QBL(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MULEU_S_PH_QBR(uint64 instruction, Dis_info *info) +static char *MULEU_S_PH_QBR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("MULEU_S.PH.QBR %s, %s, %s", rd, rs, rt); } @@ -11202,15 +11103,15 @@ static std::string MULEU_S_PH_QBR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MULQ_RS_PH(uint64 instruction, Dis_info *info) +static char *MULQ_RS_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("MULQ_RS.PH %s, %s, %s", rd, rs, rt); } @@ -11227,15 +11128,15 @@ static std::string MULQ_RS_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MULQ_RS_W(uint64 instruction, Dis_info *info) +static char *MULQ_RS_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("MULQ_RS.W %s, %s, %s", rd, rs, rt); } @@ -11252,15 +11153,15 @@ static std::string MULQ_RS_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MULQ_S_PH(uint64 instruction, Dis_info *info) +static char *MULQ_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("MULQ_S.PH %s, %s, %s", rd, rs, rt); } @@ -11277,15 +11178,15 @@ static std::string MULQ_S_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MULQ_S_W(uint64 instruction, Dis_info *info) +static char *MULQ_S_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("MULQ_S.W %s, %s, %s", rd, rs, rt); } @@ -11302,15 +11203,15 @@ static std::string MULQ_S_W(uint64 instruction, Dis_info *info) * rs ----- * ac -- */ -static std::string MULSA_W_PH(uint64 instruction, Dis_info *info) +static char *MULSA_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("MULSA.W.PH %s, %s, %s", ac, rs, rt); } @@ -11327,15 +11228,15 @@ static std::string MULSA_W_PH(uint64 instruction, Dis_info *info) * rs ----- * ac -- */ -static std::string MULSAQ_S_W_PH(uint64 instruction, Dis_info *info) +static char *MULSAQ_S_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("MULSAQ_S.W.PH %s, %s, %s", ac, rs, rt); } @@ -11351,15 +11252,15 @@ static std::string MULSAQ_S_W_PH(uint64 instruction, Dis_info *info) * rs ----- * ac -- */ -static std::string MULT_DSP_(uint64 instruction, Dis_info *info) +static char *MULT_DSP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("MULT %s, %s, %s", ac, rs, rt); } @@ -11375,15 +11276,15 @@ static std::string MULT_DSP_(uint64 instruction, Dis_info *info) * rs ----- * ac -- */ -static std::string MULTU_DSP_(uint64 instruction, Dis_info *info) +static char *MULTU_DSP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(ac_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ac = AC(ac_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("MULTU %s, %s, %s", ac, rs, rt); } @@ -11399,15 +11300,15 @@ static std::string MULTU_DSP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string MULU(uint64 instruction, Dis_info *info) +static char *MULU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("MULU %s, %s, %s", rd, rs, rt); } @@ -11423,13 +11324,13 @@ static std::string MULU(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string NEG_D(uint64 instruction, Dis_info *info) +static char *NEG_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("NEG.D %s, %s", ft, fs); } @@ -11445,13 +11346,13 @@ static std::string NEG_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string NEG_S(uint64 instruction, Dis_info *info) +static char *NEG_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("NEG.S %s, %s", ft, fs); } @@ -11467,11 +11368,11 @@ static std::string NEG_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string NOP_16_(uint64 instruction, Dis_info *info) +static char *NOP_16_(uint64 instruction, Dis_info *info) { (void)instruction; - return "NOP "; + return g_strdup("NOP "); } @@ -11485,11 +11386,11 @@ static std::string NOP_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string NOP_32_(uint64 instruction, Dis_info *info) +static char *NOP_32_(uint64 instruction, Dis_info *info) { (void)instruction; - return "NOP "; + return g_strdup("NOP "); } @@ -11503,15 +11404,15 @@ static std::string NOP_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string NOR(uint64 instruction, Dis_info *info) +static char *NOR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("NOR %s, %s, %s", rd, rs, rt); } @@ -11527,13 +11428,13 @@ static std::string NOR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string NOT_16_(uint64 instruction, Dis_info *info) +static char *NOT_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); return img_format("NOT %s, %s", rt3, rs3); } @@ -11549,13 +11450,13 @@ static std::string NOT_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string OR_16_(uint64 instruction, Dis_info *info) +static char *OR_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); return img_format("OR %s, %s", rs3, rt3); } @@ -11571,15 +11472,15 @@ static std::string OR_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string OR_32_(uint64 instruction, Dis_info *info) +static char *OR_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("OR %s, %s, %s", rd, rs, rt); } @@ -11595,15 +11496,15 @@ static std::string OR_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string ORI(uint64 instruction, Dis_info *info) +static char *ORI(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string u = IMMEDIATE(u_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *u = IMMEDIATE(u_value); return img_format("ORI %s, %s, %s", rt, rs, u); } @@ -11620,15 +11521,15 @@ static std::string ORI(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string PACKRL_PH(uint64 instruction, Dis_info *info) +static char *PACKRL_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("PACKRL.PH %s, %s, %s", rd, rs, rt); } @@ -11644,11 +11545,11 @@ static std::string PACKRL_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string PAUSE(uint64 instruction, Dis_info *info) +static char *PAUSE(uint64 instruction, Dis_info *info) { (void)instruction; - return "PAUSE "; + return g_strdup("PAUSE "); } @@ -11663,15 +11564,15 @@ static std::string PAUSE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string PICK_PH(uint64 instruction, Dis_info *info) +static char *PICK_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("PICK.PH %s, %s, %s", rd, rs, rt); } @@ -11688,15 +11589,15 @@ static std::string PICK_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string PICK_QB(uint64 instruction, Dis_info *info) +static char *PICK_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("PICK.QB %s, %s, %s", rd, rs, rt); } @@ -11713,13 +11614,13 @@ static std::string PICK_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string PRECEQ_W_PHL(uint64 instruction, Dis_info *info) +static char *PRECEQ_W_PHL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("PRECEQ.W.PHL %s, %s", rt, rs); } @@ -11736,13 +11637,13 @@ static std::string PRECEQ_W_PHL(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string PRECEQ_W_PHR(uint64 instruction, Dis_info *info) +static char *PRECEQ_W_PHR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("PRECEQ.W.PHR %s, %s", rt, rs); } @@ -11759,13 +11660,13 @@ static std::string PRECEQ_W_PHR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string PRECEQU_PH_QBLA(uint64 instruction, Dis_info *info) +static char *PRECEQU_PH_QBLA(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("PRECEQU.PH.QBLA %s, %s", rt, rs); } @@ -11782,13 +11683,13 @@ static std::string PRECEQU_PH_QBLA(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string PRECEQU_PH_QBL(uint64 instruction, Dis_info *info) +static char *PRECEQU_PH_QBL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("PRECEQU.PH.QBL %s, %s", rt, rs); } @@ -11805,13 +11706,13 @@ static std::string PRECEQU_PH_QBL(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string PRECEQU_PH_QBRA(uint64 instruction, Dis_info *info) +static char *PRECEQU_PH_QBRA(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("PRECEQU.PH.QBRA %s, %s", rt, rs); } @@ -11828,13 +11729,13 @@ static std::string PRECEQU_PH_QBRA(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string PRECEQU_PH_QBR(uint64 instruction, Dis_info *info) +static char *PRECEQU_PH_QBR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("PRECEQU.PH.QBR %s, %s", rt, rs); } @@ -11852,13 +11753,13 @@ static std::string PRECEQU_PH_QBR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string PRECEU_PH_QBLA(uint64 instruction, Dis_info *info) +static char *PRECEU_PH_QBLA(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("PRECEU.PH.QBLA %s, %s", rt, rs); } @@ -11875,13 +11776,13 @@ static std::string PRECEU_PH_QBLA(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string PRECEU_PH_QBL(uint64 instruction, Dis_info *info) +static char *PRECEU_PH_QBL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("PRECEU.PH.QBL %s, %s", rt, rs); } @@ -11899,13 +11800,13 @@ static std::string PRECEU_PH_QBL(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string PRECEU_PH_QBRA(uint64 instruction, Dis_info *info) +static char *PRECEU_PH_QBRA(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("PRECEU.PH.QBRA %s, %s", rt, rs); } @@ -11922,13 +11823,13 @@ static std::string PRECEU_PH_QBRA(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string PRECEU_PH_QBR(uint64 instruction, Dis_info *info) +static char *PRECEU_PH_QBR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("PRECEU.PH.QBR %s, %s", rt, rs); } @@ -11945,15 +11846,15 @@ static std::string PRECEU_PH_QBR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string PRECR_QB_PH(uint64 instruction, Dis_info *info) +static char *PRECR_QB_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("PRECR.QB.PH %s, %s, %s", rd, rs, rt); } @@ -11970,15 +11871,15 @@ static std::string PRECR_QB_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string PRECR_SRA_PH_W(uint64 instruction, Dis_info *info) +static char *PRECR_SRA_PH_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13_12_11(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string sa = IMMEDIATE(sa_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *sa = IMMEDIATE(sa_value); return img_format("PRECR_SRA.PH.W %s, %s, %s", rt, rs, sa); } @@ -11995,15 +11896,15 @@ static std::string PRECR_SRA_PH_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string PRECR_SRA_R_PH_W(uint64 instruction, Dis_info *info) +static char *PRECR_SRA_R_PH_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13_12_11(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string sa = IMMEDIATE(sa_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *sa = IMMEDIATE(sa_value); return img_format("PRECR_SRA_R.PH.W %s, %s, %s", rt, rs, sa); } @@ -12020,15 +11921,15 @@ static std::string PRECR_SRA_R_PH_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string PRECRQ_PH_W(uint64 instruction, Dis_info *info) +static char *PRECRQ_PH_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("PRECRQ.PH.W %s, %s, %s", rd, rs, rt); } @@ -12045,15 +11946,15 @@ static std::string PRECRQ_PH_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string PRECRQ_QB_PH(uint64 instruction, Dis_info *info) +static char *PRECRQ_QB_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("PRECRQ.QB.PH %s, %s, %s", rd, rs, rt); } @@ -12070,15 +11971,15 @@ static std::string PRECRQ_QB_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string PRECRQ_RS_PH_W(uint64 instruction, Dis_info *info) +static char *PRECRQ_RS_PH_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("PRECRQ_RS.PH.W %s, %s, %s", rd, rs, rt); } @@ -12095,15 +11996,15 @@ static std::string PRECRQ_RS_PH_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string PRECRQU_S_QB_PH(uint64 instruction, Dis_info *info) +static char *PRECRQU_S_QB_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("PRECRQU_S.QB.PH %s, %s, %s", rd, rs, rt); } @@ -12119,15 +12020,15 @@ static std::string PRECRQU_S_QB_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string PREF_S9_(uint64 instruction, Dis_info *info) +static char *PREF_S9_(uint64 instruction, Dis_info *info) { uint64 hint_value = extract_hint_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string hint = IMMEDIATE(hint_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + char *hint = IMMEDIATE(hint_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("PREF %s, %s(%s)", hint, s, rs); } @@ -12143,15 +12044,15 @@ static std::string PREF_S9_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string PREF_U12_(uint64 instruction, Dis_info *info) +static char *PREF_U12_(uint64 instruction, Dis_info *info) { uint64 hint_value = extract_hint_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string hint = IMMEDIATE(hint_value); - std::string u = IMMEDIATE(u_value); - std::string rs = GPR(rs_value); + char *hint = IMMEDIATE(hint_value); + char *u = IMMEDIATE(u_value); + const char *rs = GPR(rs_value); return img_format("PREF %s, %s(%s)", hint, u, rs); } @@ -12167,15 +12068,15 @@ static std::string PREF_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string PREFE(uint64 instruction, Dis_info *info) +static char *PREFE(uint64 instruction, Dis_info *info) { uint64 hint_value = extract_hint_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string hint = IMMEDIATE(hint_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + char *hint = IMMEDIATE(hint_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("PREFE %s, %s(%s)", hint, s, rs); } @@ -12191,15 +12092,15 @@ static std::string PREFE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string PREPEND(uint64 instruction, Dis_info *info) +static char *PREPEND(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13_12_11(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string sa = IMMEDIATE(sa_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *sa = IMMEDIATE(sa_value); return img_format("PREPEND %s, %s, %s", rt, rs, sa); } @@ -12214,13 +12115,13 @@ static std::string PREPEND(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -static std::string RADDU_W_QB(uint64 instruction, Dis_info *info) +static char *RADDU_W_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("RADDU.W.QB %s, %s", rt, rs); } @@ -12235,13 +12136,13 @@ static std::string RADDU_W_QB(uint64 instruction, Dis_info *info) * rt ----- * mask ------- */ -static std::string RDDSP(uint64 instruction, Dis_info *info) +static char *RDDSP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 mask_value = extract_mask_20_19_18_17_16_15_14(instruction); - std::string rt = GPR(rt_value); - std::string mask = IMMEDIATE(mask_value); + const char *rt = GPR(rt_value); + char *mask = IMMEDIATE(mask_value); return img_format("RDDSP %s, %s", rt, mask); } @@ -12257,15 +12158,15 @@ static std::string RDDSP(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string RDHWR(uint64 instruction, Dis_info *info) +static char *RDHWR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 hs_value = extract_hs_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_13_12_11(instruction); - std::string rt = GPR(rt_value); - std::string hs = CPR(hs_value); - std::string sel = IMMEDIATE(sel_value); + const char *rt = GPR(rt_value); + char *hs = CPR(hs_value); + char *sel = IMMEDIATE(sel_value); return img_format("RDHWR %s, %s, %s", rt, hs, sel); } @@ -12281,13 +12182,13 @@ static std::string RDHWR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string RDPGPR(uint64 instruction, Dis_info *info) +static char *RDPGPR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("RDPGPR %s, %s", rt, rs); } @@ -12303,13 +12204,13 @@ static std::string RDPGPR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string RECIP_D(uint64 instruction, Dis_info *info) +static char *RECIP_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("RECIP.D %s, %s", ft, fs); } @@ -12325,13 +12226,13 @@ static std::string RECIP_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string RECIP_S(uint64 instruction, Dis_info *info) +static char *RECIP_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("RECIP.S %s, %s", ft, fs); } @@ -12347,13 +12248,13 @@ static std::string RECIP_S(uint64 instruction, Dis_info *info) * rt ----- * s ---------- */ -static std::string REPL_PH(uint64 instruction, Dis_info *info) +static char *REPL_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); int64 s_value = extract_s__se9_20_19_18_17_16_15_14_13_12_11(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); return img_format("REPL.PH %s, %s", rt, s); } @@ -12369,13 +12270,13 @@ static std::string REPL_PH(uint64 instruction, Dis_info *info) * rt ----- * u -------- */ -static std::string REPL_QB(uint64 instruction, Dis_info *info) +static char *REPL_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_19_18_17_16_15_14_13(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); return img_format("REPL.QB %s, %s", rt, u); } @@ -12391,13 +12292,13 @@ static std::string REPL_QB(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -static std::string REPLV_PH(uint64 instruction, Dis_info *info) +static char *REPLV_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("REPLV.PH %s, %s", rt, rs); } @@ -12412,13 +12313,13 @@ static std::string REPLV_PH(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -static std::string REPLV_QB(uint64 instruction, Dis_info *info) +static char *REPLV_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("REPLV.QB %s, %s", rt, rs); } @@ -12434,14 +12335,14 @@ static std::string REPLV_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string RESTORE_32_(uint64 instruction, Dis_info *info) +static char *RESTORE_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 count_value = extract_count_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3__s3(instruction); uint64 gp_value = extract_gp_2(instruction); - std::string u = IMMEDIATE(u_value); + char *u = IMMEDIATE(u_value); return img_format("RESTORE %s%s", u, save_restore_list(rt_value, count_value, gp_value)); } @@ -12457,13 +12358,13 @@ static std::string RESTORE_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string RESTORE_JRC_16_(uint64 instruction, Dis_info *info) +static char *RESTORE_JRC_16_(uint64 instruction, Dis_info *info) { uint64 rt1_value = extract_rtl_11(instruction); uint64 u_value = extract_u_7_6_5_4__s4(instruction); uint64 count_value = extract_count_3_2_1_0(instruction); - std::string u = IMMEDIATE(u_value); + char *u = IMMEDIATE(u_value); return img_format("RESTORE.JRC %s%s", u, save_restore_list(encode_rt1_from_rt(rt1_value), count_value, 0)); } @@ -12479,14 +12380,14 @@ static std::string RESTORE_JRC_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string RESTORE_JRC_32_(uint64 instruction, Dis_info *info) +static char *RESTORE_JRC_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 count_value = extract_count_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3__s3(instruction); uint64 gp_value = extract_gp_2(instruction); - std::string u = IMMEDIATE(u_value); + char *u = IMMEDIATE(u_value); return img_format("RESTORE.JRC %s%s", u, save_restore_list(rt_value, count_value, gp_value)); } @@ -12502,13 +12403,13 @@ static std::string RESTORE_JRC_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string RESTOREF(uint64 instruction, Dis_info *info) +static char *RESTOREF(uint64 instruction, Dis_info *info) { uint64 count_value = extract_count_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3__s3(instruction); - std::string u = IMMEDIATE(u_value); - std::string count = IMMEDIATE(count_value); + char *u = IMMEDIATE(u_value); + char *count = IMMEDIATE(count_value); return img_format("RESTOREF %s, %s", u, count); } @@ -12524,13 +12425,13 @@ static std::string RESTOREF(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string RINT_D(uint64 instruction, Dis_info *info) +static char *RINT_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("RINT.D %s, %s", ft, fs); } @@ -12546,13 +12447,13 @@ static std::string RINT_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string RINT_S(uint64 instruction, Dis_info *info) +static char *RINT_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("RINT.S %s, %s", ft, fs); } @@ -12568,15 +12469,15 @@ static std::string RINT_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string ROTR(uint64 instruction, Dis_info *info) +static char *ROTR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string shift = IMMEDIATE(shift_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *shift = IMMEDIATE(shift_value); return img_format("ROTR %s, %s, %s", rt, rs, shift); } @@ -12592,15 +12493,15 @@ static std::string ROTR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string ROTRV(uint64 instruction, Dis_info *info) +static char *ROTRV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("ROTRV %s, %s, %s", rd, rs, rt); } @@ -12616,7 +12517,7 @@ static std::string ROTRV(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string ROTX(uint64 instruction, Dis_info *info) +static char *ROTX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12624,11 +12525,11 @@ static std::string ROTX(uint64 instruction, Dis_info *info) uint64 stripe_value = extract_stripe_6(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string shift = IMMEDIATE(shift_value); - std::string shiftx = IMMEDIATE(shiftx_value); - std::string stripe = IMMEDIATE(stripe_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *shift = IMMEDIATE(shift_value); + char *shiftx = IMMEDIATE(shiftx_value); + char *stripe = IMMEDIATE(stripe_value); return img_format("ROTX %s, %s, %s, %s, %s", rt, rs, shift, shiftx, stripe); @@ -12645,13 +12546,13 @@ static std::string ROTX(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string ROUND_L_D(uint64 instruction, Dis_info *info) +static char *ROUND_L_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("ROUND.L.D %s, %s", ft, fs); } @@ -12667,13 +12568,13 @@ static std::string ROUND_L_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string ROUND_L_S(uint64 instruction, Dis_info *info) +static char *ROUND_L_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("ROUND.L.S %s, %s", ft, fs); } @@ -12689,13 +12590,13 @@ static std::string ROUND_L_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string ROUND_W_D(uint64 instruction, Dis_info *info) +static char *ROUND_W_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("ROUND.W.D %s, %s", ft, fs); } @@ -12711,13 +12612,13 @@ static std::string ROUND_W_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string ROUND_W_S(uint64 instruction, Dis_info *info) +static char *ROUND_W_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("ROUND.W.S %s, %s", ft, fs); } @@ -12733,13 +12634,13 @@ static std::string ROUND_W_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string RSQRT_D(uint64 instruction, Dis_info *info) +static char *RSQRT_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("RSQRT.D %s, %s", ft, fs); } @@ -12755,13 +12656,13 @@ static std::string RSQRT_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string RSQRT_S(uint64 instruction, Dis_info *info) +static char *RSQRT_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("RSQRT.S %s, %s", ft, fs); } @@ -12777,13 +12678,13 @@ static std::string RSQRT_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SAVE_16_(uint64 instruction, Dis_info *info) +static char *SAVE_16_(uint64 instruction, Dis_info *info) { uint64 rt1_value = extract_rtl_11(instruction); uint64 u_value = extract_u_7_6_5_4__s4(instruction); uint64 count_value = extract_count_3_2_1_0(instruction); - std::string u = IMMEDIATE(u_value); + char *u = IMMEDIATE(u_value); return img_format("SAVE %s%s", u, save_restore_list(encode_rt1_from_rt(rt1_value), count_value, 0)); } @@ -12799,14 +12700,14 @@ static std::string SAVE_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SAVE_32_(uint64 instruction, Dis_info *info) +static char *SAVE_32_(uint64 instruction, Dis_info *info) { uint64 count_value = extract_count_19_18_17_16(instruction); uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3__s3(instruction); uint64 gp_value = extract_gp_2(instruction); - std::string u = IMMEDIATE(u_value); + char *u = IMMEDIATE(u_value); return img_format("SAVE %s%s", u, save_restore_list(rt_value, count_value, gp_value)); } @@ -12822,13 +12723,13 @@ static std::string SAVE_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SAVEF(uint64 instruction, Dis_info *info) +static char *SAVEF(uint64 instruction, Dis_info *info) { uint64 count_value = extract_count_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3__s3(instruction); - std::string u = IMMEDIATE(u_value); - std::string count = IMMEDIATE(count_value); + char *u = IMMEDIATE(u_value); + char *count = IMMEDIATE(count_value); return img_format("SAVEF %s, %s", u, count); } @@ -12844,15 +12745,15 @@ static std::string SAVEF(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SB_16_(uint64 instruction, Dis_info *info) +static char *SB_16_(uint64 instruction, Dis_info *info) { uint64 rtz3_value = extract_rtz3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_1_0(instruction); - std::string rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value)); - std::string u = IMMEDIATE(u_value); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value)); + char *u = IMMEDIATE(u_value); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); return img_format("SB %s, %s(%s)", rtz3, u, rs3); } @@ -12868,13 +12769,13 @@ static std::string SB_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SB_GP_(uint64 instruction, Dis_info *info) +static char *SB_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_0(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); return img_format("SB %s, %s($%d)", rt, u, 28); } @@ -12890,15 +12791,15 @@ static std::string SB_GP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SB_S9_(uint64 instruction, Dis_info *info) +static char *SB_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("SB %s, %s(%s)", rt, s, rs); } @@ -12914,15 +12815,15 @@ static std::string SB_S9_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SB_U12_(uint64 instruction, Dis_info *info) +static char *SB_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); + const char *rs = GPR(rs_value); return img_format("SB %s, %s(%s)", rt, u, rs); } @@ -12938,15 +12839,15 @@ static std::string SB_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SBE(uint64 instruction, Dis_info *info) +static char *SBE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("SBE %s, %s(%s)", rt, s, rs); } @@ -12962,15 +12863,15 @@ static std::string SBE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SBX(uint64 instruction, Dis_info *info) +static char *SBX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("SBX %s, %s(%s)", rd, rs, rt); } @@ -12986,15 +12887,15 @@ static std::string SBX(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SC(uint64 instruction, Dis_info *info) +static char *SC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_s2(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("SC %s, %s(%s)", rt, s, rs); } @@ -13010,15 +12911,15 @@ static std::string SC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SCD(uint64 instruction, Dis_info *info) +static char *SCD(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_s3(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("SCD %s, %s(%s)", rt, s, rs); } @@ -13034,15 +12935,15 @@ static std::string SCD(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SCDP(uint64 instruction, Dis_info *info) +static char *SCDP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ru_value = extract_ru_7_6_5_4_3(instruction); - std::string rt = GPR(rt_value); - std::string ru = GPR(ru_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *ru = GPR(ru_value); + const char *rs = GPR(rs_value); return img_format("SCDP %s, %s, (%s)", rt, ru, rs); } @@ -13058,15 +12959,15 @@ static std::string SCDP(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SCE(uint64 instruction, Dis_info *info) +static char *SCE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_s2(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("SCE %s, %s(%s)", rt, s, rs); } @@ -13082,15 +12983,15 @@ static std::string SCE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SCWP(uint64 instruction, Dis_info *info) +static char *SCWP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ru_value = extract_ru_7_6_5_4_3(instruction); - std::string rt = GPR(rt_value); - std::string ru = GPR(ru_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *ru = GPR(ru_value); + const char *rs = GPR(rs_value); return img_format("SCWP %s, %s, (%s)", rt, ru, rs); } @@ -13106,15 +13007,15 @@ static std::string SCWP(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SCWPE(uint64 instruction, Dis_info *info) +static char *SCWPE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ru_value = extract_ru_7_6_5_4_3(instruction); - std::string rt = GPR(rt_value); - std::string ru = GPR(ru_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *ru = GPR(ru_value); + const char *rs = GPR(rs_value); return img_format("SCWPE %s, %s, (%s)", rt, ru, rs); } @@ -13130,13 +13031,13 @@ static std::string SCWPE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SD_GP_(uint64 instruction, Dis_info *info) +static char *SD_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_to_3__s3(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); return img_format("SD %s, %s($%d)", rt, u, 28); } @@ -13152,15 +13053,15 @@ static std::string SD_GP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SD_S9_(uint64 instruction, Dis_info *info) +static char *SD_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("SD %s, %s(%s)", rt, s, rs); } @@ -13176,15 +13077,15 @@ static std::string SD_S9_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SD_U12_(uint64 instruction, Dis_info *info) +static char *SD_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); + const char *rs = GPR(rs_value); return img_format("SD %s, %s(%s)", rt, u, rs); } @@ -13200,11 +13101,11 @@ static std::string SD_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SDBBP_16_(uint64 instruction, Dis_info *info) +static char *SDBBP_16_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_2_1_0(instruction); - std::string code = IMMEDIATE(code_value); + char *code = IMMEDIATE(code_value); return img_format("SDBBP %s", code); } @@ -13220,11 +13121,11 @@ static std::string SDBBP_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SDBBP_32_(uint64 instruction, Dis_info *info) +static char *SDBBP_32_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_18_to_0(instruction); - std::string code = IMMEDIATE(code_value); + char *code = IMMEDIATE(code_value); return img_format("SDBBP %s", code); } @@ -13240,13 +13141,13 @@ static std::string SDBBP_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SDC1_GP_(uint64 instruction, Dis_info *info) +static char *SDC1_GP_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_2__s2(instruction); - std::string ft = FPR(ft_value); - std::string u = IMMEDIATE(u_value); + const char *ft = FPR(ft_value); + char *u = IMMEDIATE(u_value); return img_format("SDC1 %s, %s($%d)", ft, u, 28); } @@ -13262,15 +13163,15 @@ static std::string SDC1_GP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SDC1_S9_(uint64 instruction, Dis_info *info) +static char *SDC1_S9_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string ft = FPR(ft_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + const char *ft = FPR(ft_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("SDC1 %s, %s(%s)", ft, s, rs); } @@ -13286,15 +13187,15 @@ static std::string SDC1_S9_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SDC1_U12_(uint64 instruction, Dis_info *info) +static char *SDC1_U12_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string ft = FPR(ft_value); - std::string u = IMMEDIATE(u_value); - std::string rs = GPR(rs_value); + const char *ft = FPR(ft_value); + char *u = IMMEDIATE(u_value); + const char *rs = GPR(rs_value); return img_format("SDC1 %s, %s(%s)", ft, u, rs); } @@ -13310,15 +13211,15 @@ static std::string SDC1_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SDC1X(uint64 instruction, Dis_info *info) +static char *SDC1X(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ft_value = extract_ft_15_14_13_12_11(instruction); - std::string ft = FPR(ft_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ft = FPR(ft_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("SDC1X %s, %s(%s)", ft, rs, rt); } @@ -13334,15 +13235,15 @@ static std::string SDC1X(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SDC1XS(uint64 instruction, Dis_info *info) +static char *SDC1XS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ft_value = extract_ft_15_14_13_12_11(instruction); - std::string ft = FPR(ft_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ft = FPR(ft_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("SDC1XS %s, %s(%s)", ft, rs, rt); } @@ -13358,15 +13259,15 @@ static std::string SDC1XS(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SDC2(uint64 instruction, Dis_info *info) +static char *SDC2(uint64 instruction, Dis_info *info) { uint64 cs_value = extract_cs_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string cs = CPR(cs_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + char *cs = CPR(cs_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("SDC2 %s, %s(%s)", cs, s, rs); } @@ -13382,17 +13283,17 @@ static std::string SDC2(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SDM(uint64 instruction, Dis_info *info) +static char *SDM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 count3_value = extract_count3_14_13_12(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); - std::string count3 = IMMEDIATE(encode_count3_from_count(count3_value)); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); + char *count3 = IMMEDIATE(encode_count3_from_count(count3_value)); return img_format("SDM %s, %s(%s), %s", rt, s, rs, count3); } @@ -13408,13 +13309,13 @@ static std::string SDM(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SDPC_48_(uint64 instruction, Dis_info *info) +static char *SDPC_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - std::string rt = GPR(rt_value); - std::string s = ADDRESS(s_value, 6, info); + const char *rt = GPR(rt_value); + char *s = ADDRESS(s_value, 6, info); return img_format("SDPC %s, %s", rt, s); } @@ -13430,15 +13331,15 @@ static std::string SDPC_48_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SDXS(uint64 instruction, Dis_info *info) +static char *SDXS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("SDXS %s, %s(%s)", rd, rs, rt); } @@ -13454,15 +13355,15 @@ static std::string SDXS(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SDX(uint64 instruction, Dis_info *info) +static char *SDX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("SDX %s, %s(%s)", rd, rs, rt); } @@ -13478,13 +13379,13 @@ static std::string SDX(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SEB(uint64 instruction, Dis_info *info) +static char *SEB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("SEB %s, %s", rt, rs); } @@ -13500,13 +13401,13 @@ static std::string SEB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SEH(uint64 instruction, Dis_info *info) +static char *SEH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("SEH %s, %s", rt, rs); } @@ -13522,15 +13423,15 @@ static std::string SEH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SEL_D(uint64 instruction, Dis_info *info) +static char *SEL_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("SEL.D %s, %s, %s", fd, fs, ft); } @@ -13546,15 +13447,15 @@ static std::string SEL_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SEL_S(uint64 instruction, Dis_info *info) +static char *SEL_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("SEL.S %s, %s, %s", fd, fs, ft); } @@ -13570,15 +13471,15 @@ static std::string SEL_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SELEQZ_D(uint64 instruction, Dis_info *info) +static char *SELEQZ_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("SELEQZ.D %s, %s, %s", fd, fs, ft); } @@ -13594,15 +13495,15 @@ static std::string SELEQZ_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SELEQZ_S(uint64 instruction, Dis_info *info) +static char *SELEQZ_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("SELEQZ.S %s, %s, %s", fd, fs, ft); } @@ -13618,15 +13519,15 @@ static std::string SELEQZ_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SELNEZ_D(uint64 instruction, Dis_info *info) +static char *SELNEZ_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("SELNEZ.D %s, %s, %s", fd, fs, ft); } @@ -13642,15 +13543,15 @@ static std::string SELNEZ_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SELNEZ_S(uint64 instruction, Dis_info *info) +static char *SELNEZ_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("SELNEZ.S %s, %s, %s", fd, fs, ft); } @@ -13666,15 +13567,15 @@ static std::string SELNEZ_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SEQI(uint64 instruction, Dis_info *info) +static char *SEQI(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string u = IMMEDIATE(u_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *u = IMMEDIATE(u_value); return img_format("SEQI %s, %s, %s", rt, rs, u); } @@ -13690,15 +13591,15 @@ static std::string SEQI(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SH_16_(uint64 instruction, Dis_info *info) +static char *SH_16_(uint64 instruction, Dis_info *info) { uint64 rtz3_value = extract_rtz3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_2_1__s1(instruction); - std::string rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value)); - std::string u = IMMEDIATE(u_value); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value)); + char *u = IMMEDIATE(u_value); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); return img_format("SH %s, %s(%s)", rtz3, u, rs3); } @@ -13714,13 +13615,13 @@ static std::string SH_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SH_GP_(uint64 instruction, Dis_info *info) +static char *SH_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_1__s1(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); return img_format("SH %s, %s($%d)", rt, u, 28); } @@ -13736,15 +13637,15 @@ static std::string SH_GP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SH_S9_(uint64 instruction, Dis_info *info) +static char *SH_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("SH %s, %s(%s)", rt, s, rs); } @@ -13760,15 +13661,15 @@ static std::string SH_S9_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SH_U12_(uint64 instruction, Dis_info *info) +static char *SH_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); + const char *rs = GPR(rs_value); return img_format("SH %s, %s(%s)", rt, u, rs); } @@ -13784,15 +13685,15 @@ static std::string SH_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SHE(uint64 instruction, Dis_info *info) +static char *SHE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("SHE %s, %s(%s)", rt, s, rs); } @@ -13808,13 +13709,13 @@ static std::string SHE(uint64 instruction, Dis_info *info) * shift ------ * ac -- */ -static std::string SHILO(uint64 instruction, Dis_info *info) +static char *SHILO(uint64 instruction, Dis_info *info) { int64 shift_value = extract_shift__se5_21_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string shift = IMMEDIATE(shift_value); - std::string ac = AC(ac_value); + char *shift = IMMEDIATE(shift_value); + const char *ac = AC(ac_value); return img_format("SHILO %s, %s", ac, shift); } @@ -13830,13 +13731,13 @@ static std::string SHILO(uint64 instruction, Dis_info *info) * rs ----- * ac -- */ -static std::string SHILOV(uint64 instruction, Dis_info *info) +static char *SHILOV(uint64 instruction, Dis_info *info) { uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rs = GPR(rs_value); - std::string ac = AC(ac_value); + const char *rs = GPR(rs_value); + const char *ac = AC(ac_value); return img_format("SHILOV %s, %s", ac, rs); } @@ -13852,15 +13753,15 @@ static std::string SHILOV(uint64 instruction, Dis_info *info) * rs ----- * sa ---- */ -static std::string SHLL_PH(uint64 instruction, Dis_info *info) +static char *SHLL_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13_12(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string sa = IMMEDIATE(sa_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *sa = IMMEDIATE(sa_value); return img_format("SHLL.PH %s, %s, %s", rt, rs, sa); } @@ -13876,15 +13777,15 @@ static std::string SHLL_PH(uint64 instruction, Dis_info *info) * rs ----- * sa --- */ -static std::string SHLL_QB(uint64 instruction, Dis_info *info) +static char *SHLL_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string sa = IMMEDIATE(sa_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *sa = IMMEDIATE(sa_value); return img_format("SHLL.QB %s, %s, %s", rt, rs, sa); } @@ -13901,15 +13802,15 @@ static std::string SHLL_QB(uint64 instruction, Dis_info *info) * rs ----- * sa ---- */ -static std::string SHLL_S_PH(uint64 instruction, Dis_info *info) +static char *SHLL_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13_12(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string sa = IMMEDIATE(sa_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *sa = IMMEDIATE(sa_value); return img_format("SHLL_S.PH %s, %s, %s", rt, rs, sa); } @@ -13925,15 +13826,15 @@ static std::string SHLL_S_PH(uint64 instruction, Dis_info *info) * rs ----- * sa ----- */ -static std::string SHLL_S_W(uint64 instruction, Dis_info *info) +static char *SHLL_S_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13_12_11(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string sa = IMMEDIATE(sa_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *sa = IMMEDIATE(sa_value); return img_format("SHLL_S.W %s, %s, %s", rt, rs, sa); } @@ -13950,15 +13851,15 @@ static std::string SHLL_S_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SHLLV_PH(uint64 instruction, Dis_info *info) +static char *SHLLV_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rd = GPR(rd_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("SHLLV.PH %s, %s, %s", rd, rt, rs); } @@ -13974,15 +13875,15 @@ static std::string SHLLV_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SHLLV_QB(uint64 instruction, Dis_info *info) +static char *SHLLV_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rd = GPR(rd_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("SHLLV.QB %s, %s, %s", rd, rt, rs); } @@ -13999,15 +13900,15 @@ static std::string SHLLV_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SHLLV_S_PH(uint64 instruction, Dis_info *info) +static char *SHLLV_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rd = GPR(rd_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("SHLLV_S.PH %s, %s, %s", rd, rt, rs); } @@ -14023,15 +13924,15 @@ static std::string SHLLV_S_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SHLLV_S_W(uint64 instruction, Dis_info *info) +static char *SHLLV_S_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rd = GPR(rd_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("SHLLV_S.W %s, %s, %s", rd, rt, rs); } @@ -14047,15 +13948,15 @@ static std::string SHLLV_S_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SHRA_PH(uint64 instruction, Dis_info *info) +static char *SHRA_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13_12(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string sa = IMMEDIATE(sa_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *sa = IMMEDIATE(sa_value); return img_format("SHRA.PH %s, %s, %s", rt, rs, sa); } @@ -14071,15 +13972,15 @@ static std::string SHRA_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SHRA_QB(uint64 instruction, Dis_info *info) +static char *SHRA_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string sa = IMMEDIATE(sa_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *sa = IMMEDIATE(sa_value); return img_format("SHRA.QB %s, %s, %s", rt, rs, sa); } @@ -14095,15 +13996,15 @@ static std::string SHRA_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SHRA_R_PH(uint64 instruction, Dis_info *info) +static char *SHRA_R_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13_12(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string sa = IMMEDIATE(sa_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *sa = IMMEDIATE(sa_value); return img_format("SHRA_R.PH %s, %s, %s", rt, rs, sa); } @@ -14119,15 +14020,15 @@ static std::string SHRA_R_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SHRA_R_QB(uint64 instruction, Dis_info *info) +static char *SHRA_R_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string sa = IMMEDIATE(sa_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *sa = IMMEDIATE(sa_value); return img_format("SHRA_R.QB %s, %s, %s", rt, rs, sa); } @@ -14143,15 +14044,15 @@ static std::string SHRA_R_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SHRA_R_W(uint64 instruction, Dis_info *info) +static char *SHRA_R_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13_12_11(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string sa = IMMEDIATE(sa_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *sa = IMMEDIATE(sa_value); return img_format("SHRA_R.W %s, %s, %s", rt, rs, sa); } @@ -14167,15 +14068,15 @@ static std::string SHRA_R_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SHRAV_PH(uint64 instruction, Dis_info *info) +static char *SHRAV_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rd = GPR(rd_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("SHRAV.PH %s, %s, %s", rd, rt, rs); } @@ -14191,15 +14092,15 @@ static std::string SHRAV_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SHRAV_QB(uint64 instruction, Dis_info *info) +static char *SHRAV_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rd = GPR(rd_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("SHRAV.QB %s, %s, %s", rd, rt, rs); } @@ -14215,15 +14116,15 @@ static std::string SHRAV_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SHRAV_R_PH(uint64 instruction, Dis_info *info) +static char *SHRAV_R_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rd = GPR(rd_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("SHRAV_R.PH %s, %s, %s", rd, rt, rs); } @@ -14239,15 +14140,15 @@ static std::string SHRAV_R_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SHRAV_R_QB(uint64 instruction, Dis_info *info) +static char *SHRAV_R_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rd = GPR(rd_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("SHRAV_R.QB %s, %s, %s", rd, rt, rs); } @@ -14263,15 +14164,15 @@ static std::string SHRAV_R_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SHRAV_R_W(uint64 instruction, Dis_info *info) +static char *SHRAV_R_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rd = GPR(rd_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("SHRAV_R.W %s, %s, %s", rd, rt, rs); } @@ -14287,15 +14188,15 @@ static std::string SHRAV_R_W(uint64 instruction, Dis_info *info) * rs ----- * sa ---- */ -static std::string SHRL_PH(uint64 instruction, Dis_info *info) +static char *SHRL_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13_12(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string sa = IMMEDIATE(sa_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *sa = IMMEDIATE(sa_value); return img_format("SHRL.PH %s, %s, %s", rt, rs, sa); } @@ -14311,15 +14212,15 @@ static std::string SHRL_PH(uint64 instruction, Dis_info *info) * rs ----- * sa --- */ -static std::string SHRL_QB(uint64 instruction, Dis_info *info) +static char *SHRL_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string sa = IMMEDIATE(sa_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *sa = IMMEDIATE(sa_value); return img_format("SHRL.QB %s, %s, %s", rt, rs, sa); } @@ -14336,15 +14237,15 @@ static std::string SHRL_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SHRLV_PH(uint64 instruction, Dis_info *info) +static char *SHRLV_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rd = GPR(rd_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("SHRLV.PH %s, %s, %s", rd, rt, rs); } @@ -14360,15 +14261,15 @@ static std::string SHRLV_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SHRLV_QB(uint64 instruction, Dis_info *info) +static char *SHRLV_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rd = GPR(rd_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("SHRLV.QB %s, %s, %s", rd, rt, rs); } @@ -14384,15 +14285,15 @@ static std::string SHRLV_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SHX(uint64 instruction, Dis_info *info) +static char *SHX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("SHX %s, %s(%s)", rd, rs, rt); } @@ -14408,15 +14309,15 @@ static std::string SHX(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SHXS(uint64 instruction, Dis_info *info) +static char *SHXS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("SHXS %s, %s(%s)", rd, rs, rt); } @@ -14432,11 +14333,11 @@ static std::string SHXS(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SIGRIE(uint64 instruction, Dis_info *info) +static char *SIGRIE(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_18_to_0(instruction); - std::string code = IMMEDIATE(code_value); + char *code = IMMEDIATE(code_value); return img_format("SIGRIE %s", code); } @@ -14452,15 +14353,15 @@ static std::string SIGRIE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SLL_16_(uint64 instruction, Dis_info *info) +static char *SLL_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 shift3_value = extract_shift3_2_1_0(instruction); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); - std::string shift3 = IMMEDIATE(encode_shift3_from_shift(shift3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); + char *shift3 = IMMEDIATE(encode_shift3_from_shift(shift3_value)); return img_format("SLL %s, %s, %s", rt3, rs3, shift3); } @@ -14476,15 +14377,15 @@ static std::string SLL_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SLL_32_(uint64 instruction, Dis_info *info) +static char *SLL_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string shift = IMMEDIATE(shift_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *shift = IMMEDIATE(shift_value); return img_format("SLL %s, %s, %s", rt, rs, shift); } @@ -14500,15 +14401,15 @@ static std::string SLL_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SLLV(uint64 instruction, Dis_info *info) +static char *SLLV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("SLLV %s, %s, %s", rd, rs, rt); } @@ -14524,15 +14425,15 @@ static std::string SLLV(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SLT(uint64 instruction, Dis_info *info) +static char *SLT(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("SLT %s, %s, %s", rd, rs, rt); } @@ -14548,15 +14449,15 @@ static std::string SLT(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SLTI(uint64 instruction, Dis_info *info) +static char *SLTI(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string u = IMMEDIATE(u_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *u = IMMEDIATE(u_value); return img_format("SLTI %s, %s, %s", rt, rs, u); } @@ -14572,15 +14473,15 @@ static std::string SLTI(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SLTIU(uint64 instruction, Dis_info *info) +static char *SLTIU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string u = IMMEDIATE(u_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *u = IMMEDIATE(u_value); return img_format("SLTIU %s, %s, %s", rt, rs, u); } @@ -14596,15 +14497,15 @@ static std::string SLTIU(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SLTU(uint64 instruction, Dis_info *info) +static char *SLTU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("SLTU %s, %s, %s", rd, rs, rt); } @@ -14620,15 +14521,15 @@ static std::string SLTU(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SOV(uint64 instruction, Dis_info *info) +static char *SOV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("SOV %s, %s, %s", rd, rs, rt); } @@ -14644,11 +14545,11 @@ static std::string SOV(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SPECIAL2(uint64 instruction, Dis_info *info) +static char *SPECIAL2(uint64 instruction, Dis_info *info) { uint64 op_value = extract_op_25_to_3(instruction); - std::string op = IMMEDIATE(op_value); + char *op = IMMEDIATE(op_value); return img_format("SPECIAL2 %s", op); } @@ -14664,13 +14565,13 @@ static std::string SPECIAL2(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SQRT_D(uint64 instruction, Dis_info *info) +static char *SQRT_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("SQRT.D %s, %s", ft, fs); } @@ -14686,13 +14587,13 @@ static std::string SQRT_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SQRT_S(uint64 instruction, Dis_info *info) +static char *SQRT_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("SQRT.S %s, %s", ft, fs); } @@ -14708,15 +14609,15 @@ static std::string SQRT_S(uint64 instruction, Dis_info *info) * rd ----- * sa ----- */ -static std::string SRA(uint64 instruction, Dis_info *info) +static char *SRA(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string shift = IMMEDIATE(shift_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *shift = IMMEDIATE(shift_value); return img_format("SRA %s, %s, %s", rt, rs, shift); } @@ -14732,15 +14633,15 @@ static std::string SRA(uint64 instruction, Dis_info *info) * rt ----- * rd ----- */ -static std::string SRAV(uint64 instruction, Dis_info *info) +static char *SRAV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("SRAV %s, %s, %s", rd, rs, rt); } @@ -14756,15 +14657,15 @@ static std::string SRAV(uint64 instruction, Dis_info *info) * rt ----- * rd ----- */ -static std::string SRL_16_(uint64 instruction, Dis_info *info) +static char *SRL_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 shift3_value = extract_shift3_2_1_0(instruction); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); - std::string shift3 = IMMEDIATE(encode_shift3_from_shift(shift3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); + char *shift3 = IMMEDIATE(encode_shift3_from_shift(shift3_value)); return img_format("SRL %s, %s, %s", rt3, rs3, shift3); } @@ -14780,15 +14681,15 @@ static std::string SRL_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SRL_32_(uint64 instruction, Dis_info *info) +static char *SRL_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string shift = IMMEDIATE(shift_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *shift = IMMEDIATE(shift_value); return img_format("SRL %s, %s, %s", rt, rs, shift); } @@ -14804,15 +14705,15 @@ static std::string SRL_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SRLV(uint64 instruction, Dis_info *info) +static char *SRLV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("SRLV %s, %s, %s", rd, rs, rt); } @@ -14828,15 +14729,15 @@ static std::string SRLV(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SUB(uint64 instruction, Dis_info *info) +static char *SUB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("SUB %s, %s, %s", rd, rs, rt); } @@ -14852,15 +14753,15 @@ static std::string SUB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SUB_D(uint64 instruction, Dis_info *info) +static char *SUB_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("SUB.D %s, %s, %s", fd, fs, ft); } @@ -14876,15 +14777,15 @@ static std::string SUB_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SUB_S(uint64 instruction, Dis_info *info) +static char *SUB_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(fd_value); - std::string fs = FPR(fs_value); - std::string ft = FPR(ft_value); + const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value); return img_format("SUB.S %s, %s, %s", fd, fs, ft); } @@ -14900,15 +14801,15 @@ static std::string SUB_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SUBQ_PH(uint64 instruction, Dis_info *info) +static char *SUBQ_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("SUBQ.PH %s, %s, %s", rd, rs, rt); } @@ -14925,15 +14826,15 @@ static std::string SUBQ_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SUBQ_S_PH(uint64 instruction, Dis_info *info) +static char *SUBQ_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("SUBQ_S.PH %s, %s, %s", rd, rs, rt); } @@ -14950,15 +14851,15 @@ static std::string SUBQ_S_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SUBQ_S_W(uint64 instruction, Dis_info *info) +static char *SUBQ_S_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("SUBQ_S.W %s, %s, %s", rd, rs, rt); } @@ -14975,15 +14876,15 @@ static std::string SUBQ_S_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SUBQH_PH(uint64 instruction, Dis_info *info) +static char *SUBQH_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("SUBQH.PH %s, %s, %s", rd, rs, rt); } @@ -15000,15 +14901,15 @@ static std::string SUBQH_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SUBQH_R_PH(uint64 instruction, Dis_info *info) +static char *SUBQH_R_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("SUBQH_R.PH %s, %s, %s", rd, rs, rt); } @@ -15025,15 +14926,15 @@ static std::string SUBQH_R_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SUBQH_R_W(uint64 instruction, Dis_info *info) +static char *SUBQH_R_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("SUBQH_R.W %s, %s, %s", rd, rs, rt); } @@ -15050,15 +14951,15 @@ static std::string SUBQH_R_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SUBQH_W(uint64 instruction, Dis_info *info) +static char *SUBQH_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("SUBQH.W %s, %s, %s", rd, rs, rt); } @@ -15074,15 +14975,15 @@ static std::string SUBQH_W(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SUBU_16_(uint64 instruction, Dis_info *info) +static char *SUBU_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 rd3_value = extract_rd3_3_2_1(instruction); - std::string rd3 = GPR(decode_gpr_gpr3(rd3_value)); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); + const char *rd3 = GPR(decode_gpr_gpr3(rd3_value)); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); return img_format("SUBU %s, %s, %s", rd3, rs3, rt3); } @@ -15098,15 +14999,15 @@ static std::string SUBU_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SUBU_32_(uint64 instruction, Dis_info *info) +static char *SUBU_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("SUBU %s, %s, %s", rd, rs, rt); } @@ -15122,15 +15023,15 @@ static std::string SUBU_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SUBU_PH(uint64 instruction, Dis_info *info) +static char *SUBU_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("SUBU.PH %s, %s, %s", rd, rs, rt); } @@ -15146,15 +15047,15 @@ static std::string SUBU_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SUBU_QB(uint64 instruction, Dis_info *info) +static char *SUBU_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("SUBU.QB %s, %s, %s", rd, rs, rt); } @@ -15171,15 +15072,15 @@ static std::string SUBU_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SUBU_S_PH(uint64 instruction, Dis_info *info) +static char *SUBU_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("SUBU_S.PH %s, %s, %s", rd, rs, rt); } @@ -15196,15 +15097,15 @@ static std::string SUBU_S_PH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SUBU_S_QB(uint64 instruction, Dis_info *info) +static char *SUBU_S_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("SUBU_S.QB %s, %s, %s", rd, rs, rt); } @@ -15221,15 +15122,15 @@ static std::string SUBU_S_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SUBUH_QB(uint64 instruction, Dis_info *info) +static char *SUBUH_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("SUBUH.QB %s, %s, %s", rd, rs, rt); } @@ -15246,15 +15147,15 @@ static std::string SUBUH_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SUBUH_R_QB(uint64 instruction, Dis_info *info) +static char *SUBUH_R_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("SUBUH_R.QB %s, %s, %s", rd, rs, rt); } @@ -15270,15 +15171,15 @@ static std::string SUBUH_R_QB(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SW_16_(uint64 instruction, Dis_info *info) +static char *SW_16_(uint64 instruction, Dis_info *info) { uint64 rtz3_value = extract_rtz3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_3_2_1_0__s2(instruction); - std::string rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value)); - std::string u = IMMEDIATE(u_value); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value)); + char *u = IMMEDIATE(u_value); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); return img_format("SW %s, %s(%s)", rtz3, u, rs3); } @@ -15294,15 +15195,15 @@ static std::string SW_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SW_4X4_(uint64 instruction, Dis_info *info) +static char *SW_4X4_(uint64 instruction, Dis_info *info) { uint64 rtz4_value = extract_rtz4_9_7_6_5(instruction); uint64 rs4_value = extract_rs4_4_2_1_0(instruction); uint64 u_value = extract_u_3_8__s2(instruction); - std::string rtz4 = GPR(decode_gpr_gpr4_zero(rtz4_value)); - std::string u = IMMEDIATE(u_value); - std::string rs4 = GPR(decode_gpr_gpr4(rs4_value)); + const char *rtz4 = GPR(decode_gpr_gpr4_zero(rtz4_value)); + char *u = IMMEDIATE(u_value); + const char *rs4 = GPR(decode_gpr_gpr4(rs4_value)); return img_format("SW %s, %s(%s)", rtz4, u, rs4); } @@ -15318,13 +15219,13 @@ static std::string SW_4X4_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SW_GP16_(uint64 instruction, Dis_info *info) +static char *SW_GP16_(uint64 instruction, Dis_info *info) { uint64 u_value = extract_u_6_5_4_3_2_1_0__s2(instruction); uint64 rtz3_value = extract_rtz3_9_8_7(instruction); - std::string rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value)); - std::string u = IMMEDIATE(u_value); + const char *rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value)); + char *u = IMMEDIATE(u_value); return img_format("SW %s, %s($%d)", rtz3, u, 28); } @@ -15340,13 +15241,13 @@ static std::string SW_GP16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SW_GP_(uint64 instruction, Dis_info *info) +static char *SW_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_to_2__s2(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); return img_format("SW %s, %s($%d)", rt, u, 28); } @@ -15362,15 +15263,15 @@ static std::string SW_GP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SW_S9_(uint64 instruction, Dis_info *info) +static char *SW_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("SW %s, %s(%s)", rt, s, rs); } @@ -15386,13 +15287,13 @@ static std::string SW_S9_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SW_SP_(uint64 instruction, Dis_info *info) +static char *SW_SP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_9_8_7_6_5(instruction); uint64 u_value = extract_u_4_3_2_1_0__s2(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); return img_format("SW %s, %s($%d)", rt, u, 29); } @@ -15408,15 +15309,15 @@ static std::string SW_SP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SW_U12_(uint64 instruction, Dis_info *info) +static char *SW_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string u = IMMEDIATE(u_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *u = IMMEDIATE(u_value); + const char *rs = GPR(rs_value); return img_format("SW %s, %s(%s)", rt, u, rs); } @@ -15432,13 +15333,13 @@ static std::string SW_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SWC1_GP_(uint64 instruction, Dis_info *info) +static char *SWC1_GP_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_2__s2(instruction); - std::string ft = FPR(ft_value); - std::string u = IMMEDIATE(u_value); + const char *ft = FPR(ft_value); + char *u = IMMEDIATE(u_value); return img_format("SWC1 %s, %s($%d)", ft, u, 28); } @@ -15454,15 +15355,15 @@ static std::string SWC1_GP_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SWC1_S9_(uint64 instruction, Dis_info *info) +static char *SWC1_S9_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string ft = FPR(ft_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + const char *ft = FPR(ft_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("SWC1 %s, %s(%s)", ft, s, rs); } @@ -15478,15 +15379,15 @@ static std::string SWC1_S9_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SWC1_U12_(uint64 instruction, Dis_info *info) +static char *SWC1_U12_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string ft = FPR(ft_value); - std::string u = IMMEDIATE(u_value); - std::string rs = GPR(rs_value); + const char *ft = FPR(ft_value); + char *u = IMMEDIATE(u_value); + const char *rs = GPR(rs_value); return img_format("SWC1 %s, %s(%s)", ft, u, rs); } @@ -15502,15 +15403,15 @@ static std::string SWC1_U12_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SWC1X(uint64 instruction, Dis_info *info) +static char *SWC1X(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ft_value = extract_ft_15_14_13_12_11(instruction); - std::string ft = FPR(ft_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ft = FPR(ft_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("SWC1X %s, %s(%s)", ft, rs, rt); } @@ -15526,15 +15427,15 @@ static std::string SWC1X(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SWC1XS(uint64 instruction, Dis_info *info) +static char *SWC1XS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ft_value = extract_ft_15_14_13_12_11(instruction); - std::string ft = FPR(ft_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *ft = FPR(ft_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("SWC1XS %s, %s(%s)", ft, rs, rt); } @@ -15550,15 +15451,15 @@ static std::string SWC1XS(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SWC2(uint64 instruction, Dis_info *info) +static char *SWC2(uint64 instruction, Dis_info *info) { uint64 cs_value = extract_cs_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string cs = CPR(cs_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + char *cs = CPR(cs_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("SWC2 %s, %s(%s)", cs, s, rs); } @@ -15574,15 +15475,15 @@ static std::string SWC2(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SWE(uint64 instruction, Dis_info *info) +static char *SWE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("SWE %s, %s(%s)", rt, s, rs); } @@ -15598,17 +15499,17 @@ static std::string SWE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SWM(uint64 instruction, Dis_info *info) +static char *SWM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 count3_value = extract_count3_14_13_12(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); - std::string count3 = IMMEDIATE(encode_count3_from_count(count3_value)); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); + char *count3 = IMMEDIATE(encode_count3_from_count(count3_value)); return img_format("SWM %s, %s(%s), %s", rt, s, rs, count3); } @@ -15624,13 +15525,13 @@ static std::string SWM(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SWPC_48_(uint64 instruction, Dis_info *info) +static char *SWPC_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - std::string rt = GPR(rt_value); - std::string s = ADDRESS(s_value, 6, info); + const char *rt = GPR(rt_value); + char *s = ADDRESS(s_value, 6, info); return img_format("SWPC %s, %s", rt, s); } @@ -15646,15 +15547,15 @@ static std::string SWPC_48_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SWX(uint64 instruction, Dis_info *info) +static char *SWX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("SWX %s, %s(%s)", rd, rs, rt); } @@ -15670,15 +15571,15 @@ static std::string SWX(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SWXS(uint64 instruction, Dis_info *info) +static char *SWXS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("SWXS %s, %s(%s)", rd, rs, rt); } @@ -15694,11 +15595,11 @@ static std::string SWXS(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SYNC(uint64 instruction, Dis_info *info) +static char *SYNC(uint64 instruction, Dis_info *info) { uint64 stype_value = extract_stype_20_19_18_17_16(instruction); - std::string stype = IMMEDIATE(stype_value); + char *stype = IMMEDIATE(stype_value); return img_format("SYNC %s", stype); } @@ -15714,13 +15615,13 @@ static std::string SYNC(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SYNCI(uint64 instruction, Dis_info *info) +static char *SYNCI(uint64 instruction, Dis_info *info) { uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("SYNCI %s(%s)", s, rs); } @@ -15736,13 +15637,13 @@ static std::string SYNCI(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SYNCIE(uint64 instruction, Dis_info *info) +static char *SYNCIE(uint64 instruction, Dis_info *info) { uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("SYNCIE %s(%s)", s, rs); } @@ -15758,11 +15659,11 @@ static std::string SYNCIE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string SYSCALL_16_(uint64 instruction, Dis_info *info) +static char *SYSCALL_16_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_1_0(instruction); - std::string code = IMMEDIATE(code_value); + char *code = IMMEDIATE(code_value); return img_format("SYSCALL %s", code); } @@ -15776,11 +15677,11 @@ static std::string SYSCALL_16_(uint64 instruction, Dis_info *info) * 00000000000010 * code ------------------ */ -static std::string SYSCALL_32_(uint64 instruction, Dis_info *info) +static char *SYSCALL_32_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_17_to_0(instruction); - std::string code = IMMEDIATE(code_value); + char *code = IMMEDIATE(code_value); return img_format("SYSCALL %s", code); } @@ -15796,13 +15697,13 @@ static std::string SYSCALL_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string TEQ(uint64 instruction, Dis_info *info) +static char *TEQ(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("TEQ %s, %s", rs, rt); } @@ -15818,11 +15719,11 @@ static std::string TEQ(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string TLBGINV(uint64 instruction, Dis_info *info) +static char *TLBGINV(uint64 instruction, Dis_info *info) { (void)instruction; - return "TLBGINV "; + return g_strdup("TLBGINV "); } @@ -15836,11 +15737,11 @@ static std::string TLBGINV(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string TLBGINVF(uint64 instruction, Dis_info *info) +static char *TLBGINVF(uint64 instruction, Dis_info *info) { (void)instruction; - return "TLBGINVF "; + return g_strdup("TLBGINVF "); } @@ -15854,11 +15755,11 @@ static std::string TLBGINVF(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string TLBGP(uint64 instruction, Dis_info *info) +static char *TLBGP(uint64 instruction, Dis_info *info) { (void)instruction; - return "TLBGP "; + return g_strdup("TLBGP "); } @@ -15872,11 +15773,11 @@ static std::string TLBGP(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string TLBGR(uint64 instruction, Dis_info *info) +static char *TLBGR(uint64 instruction, Dis_info *info) { (void)instruction; - return "TLBGR "; + return g_strdup("TLBGR "); } @@ -15890,11 +15791,11 @@ static std::string TLBGR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string TLBGWI(uint64 instruction, Dis_info *info) +static char *TLBGWI(uint64 instruction, Dis_info *info) { (void)instruction; - return "TLBGWI "; + return g_strdup("TLBGWI "); } @@ -15908,11 +15809,11 @@ static std::string TLBGWI(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string TLBGWR(uint64 instruction, Dis_info *info) +static char *TLBGWR(uint64 instruction, Dis_info *info) { (void)instruction; - return "TLBGWR "; + return g_strdup("TLBGWR "); } @@ -15926,11 +15827,11 @@ static std::string TLBGWR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string TLBINV(uint64 instruction, Dis_info *info) +static char *TLBINV(uint64 instruction, Dis_info *info) { (void)instruction; - return "TLBINV "; + return g_strdup("TLBINV "); } @@ -15944,11 +15845,11 @@ static std::string TLBINV(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string TLBINVF(uint64 instruction, Dis_info *info) +static char *TLBINVF(uint64 instruction, Dis_info *info) { (void)instruction; - return "TLBINVF "; + return g_strdup("TLBINVF "); } @@ -15962,11 +15863,11 @@ static std::string TLBINVF(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string TLBP(uint64 instruction, Dis_info *info) +static char *TLBP(uint64 instruction, Dis_info *info) { (void)instruction; - return "TLBP "; + return g_strdup("TLBP "); } @@ -15980,11 +15881,11 @@ static std::string TLBP(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string TLBR(uint64 instruction, Dis_info *info) +static char *TLBR(uint64 instruction, Dis_info *info) { (void)instruction; - return "TLBR "; + return g_strdup("TLBR "); } @@ -15998,11 +15899,11 @@ static std::string TLBR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string TLBWI(uint64 instruction, Dis_info *info) +static char *TLBWI(uint64 instruction, Dis_info *info) { (void)instruction; - return "TLBWI "; + return g_strdup("TLBWI "); } @@ -16016,11 +15917,11 @@ static std::string TLBWI(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string TLBWR(uint64 instruction, Dis_info *info) +static char *TLBWR(uint64 instruction, Dis_info *info) { (void)instruction; - return "TLBWR "; + return g_strdup("TLBWR "); } @@ -16034,13 +15935,13 @@ static std::string TLBWR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string TNE(uint64 instruction, Dis_info *info) +static char *TNE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("TNE %s, %s", rs, rt); } @@ -16056,13 +15957,13 @@ static std::string TNE(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string TRUNC_L_D(uint64 instruction, Dis_info *info) +static char *TRUNC_L_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("TRUNC.L.D %s, %s", ft, fs); } @@ -16078,13 +15979,13 @@ static std::string TRUNC_L_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string TRUNC_L_S(uint64 instruction, Dis_info *info) +static char *TRUNC_L_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("TRUNC.L.S %s, %s", ft, fs); } @@ -16100,13 +16001,13 @@ static std::string TRUNC_L_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string TRUNC_W_D(uint64 instruction, Dis_info *info) +static char *TRUNC_W_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("TRUNC.W.D %s, %s", ft, fs); } @@ -16122,13 +16023,13 @@ static std::string TRUNC_W_D(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string TRUNC_W_S(uint64 instruction, Dis_info *info) +static char *TRUNC_W_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(ft_value); - std::string fs = FPR(fs_value); + const char *ft = FPR(ft_value); + const char *fs = FPR(fs_value); return img_format("TRUNC.W.S %s, %s", ft, fs); } @@ -16144,17 +16045,17 @@ static std::string TRUNC_W_S(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string UALDM(uint64 instruction, Dis_info *info) +static char *UALDM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 count3_value = extract_count3_14_13_12(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); - std::string count3 = IMMEDIATE(encode_count3_from_count(count3_value)); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); + char *count3 = IMMEDIATE(encode_count3_from_count(count3_value)); return img_format("UALDM %s, %s(%s), %s", rt, s, rs, count3); } @@ -16170,15 +16071,15 @@ static std::string UALDM(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string UALH(uint64 instruction, Dis_info *info) +static char *UALH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("UALH %s, %s(%s)", rt, s, rs); } @@ -16194,17 +16095,17 @@ static std::string UALH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string UALWM(uint64 instruction, Dis_info *info) +static char *UALWM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 count3_value = extract_count3_14_13_12(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); - std::string count3 = IMMEDIATE(encode_count3_from_count(count3_value)); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); + char *count3 = IMMEDIATE(encode_count3_from_count(count3_value)); return img_format("UALWM %s, %s(%s), %s", rt, s, rs, count3); } @@ -16220,17 +16121,17 @@ static std::string UALWM(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string UASDM(uint64 instruction, Dis_info *info) +static char *UASDM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 count3_value = extract_count3_14_13_12(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); - std::string count3 = IMMEDIATE(encode_count3_from_count(count3_value)); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); + char *count3 = IMMEDIATE(encode_count3_from_count(count3_value)); return img_format("UASDM %s, %s(%s), %s", rt, s, rs, count3); } @@ -16246,15 +16147,15 @@ static std::string UASDM(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string UASH(uint64 instruction, Dis_info *info) +static char *UASH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); return img_format("UASH %s, %s(%s)", rt, s, rs); } @@ -16270,17 +16171,17 @@ static std::string UASH(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string UASWM(uint64 instruction, Dis_info *info) +static char *UASWM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 count3_value = extract_count3_14_13_12(instruction); - std::string rt = GPR(rt_value); - std::string s = IMMEDIATE(s_value); - std::string rs = GPR(rs_value); - std::string count3 = IMMEDIATE(encode_count3_from_count(count3_value)); + const char *rt = GPR(rt_value); + char *s = IMMEDIATE(s_value); + const char *rs = GPR(rs_value); + char *count3 = IMMEDIATE(encode_count3_from_count(count3_value)); return img_format("UASWM %s, %s(%s), %s", rt, s, rs, count3); } @@ -16296,11 +16197,11 @@ static std::string UASWM(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string UDI(uint64 instruction, Dis_info *info) +static char *UDI(uint64 instruction, Dis_info *info) { uint64 op_value = extract_op_25_to_3(instruction); - std::string op = IMMEDIATE(op_value); + char *op = IMMEDIATE(op_value); return img_format("UDI %s", op); } @@ -16314,11 +16215,11 @@ static std::string UDI(uint64 instruction, Dis_info *info) * 001000 1100001101111111 * code ---------- */ -static std::string WAIT(uint64 instruction, Dis_info *info) +static char *WAIT(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_25_24_23_22_21_20_19_18_17_16(instruction); - std::string code = IMMEDIATE(code_value); + char *code = IMMEDIATE(code_value); return img_format("WAIT %s", code); } @@ -16334,13 +16235,13 @@ static std::string WAIT(uint64 instruction, Dis_info *info) * rt ----- * mask ------- */ -static std::string WRDSP(uint64 instruction, Dis_info *info) +static char *WRDSP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 mask_value = extract_mask_20_19_18_17_16_15_14(instruction); - std::string rt = GPR(rt_value); - std::string mask = IMMEDIATE(mask_value); + const char *rt = GPR(rt_value); + char *mask = IMMEDIATE(mask_value); return img_format("WRDSP %s, %s", rt, mask); } @@ -16356,13 +16257,13 @@ static std::string WRDSP(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string WRPGPR(uint64 instruction, Dis_info *info) +static char *WRPGPR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("WRPGPR %s, %s", rt, rs); } @@ -16378,13 +16279,13 @@ static std::string WRPGPR(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string XOR_16_(uint64 instruction, Dis_info *info) +static char *XOR_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); return img_format("XOR %s, %s", rs3, rt3); } @@ -16400,15 +16301,15 @@ static std::string XOR_16_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string XOR_32_(uint64 instruction, Dis_info *info) +static char *XOR_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(rd_value); - std::string rs = GPR(rs_value); - std::string rt = GPR(rt_value); + const char *rd = GPR(rd_value); + const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value); return img_format("XOR %s, %s, %s", rd, rs, rt); } @@ -16424,15 +16325,15 @@ static std::string XOR_32_(uint64 instruction, Dis_info *info) * rs ----- * rd ----- */ -static std::string XORI(uint64 instruction, Dis_info *info) +static char *XORI(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); - std::string u = IMMEDIATE(u_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); + char *u = IMMEDIATE(u_value); return img_format("XORI %s, %s, %s", rt, rs, u); } @@ -16447,13 +16348,13 @@ static std::string XORI(uint64 instruction, Dis_info *info) * rt ----- * rs ----- */ -static std::string YIELD(uint64 instruction, Dis_info *info) +static char *YIELD(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rt = GPR(rt_value); - std::string rs = GPR(rs_value); + const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value); return img_format("YIELD %s, %s", rt, rs); } @@ -22256,25 +22157,22 @@ static const Pool MAJOR[2] = { 0x0 }, /* P16 */ }; -static int Disassemble(const uint16 *data, std::string & dis, +static int Disassemble(const uint16 *data, char **dis, TABLE_ENTRY_TYPE & type, Dis_info *info) { return Disassemble(data, dis, type, MAJOR, 2, info); } -static int nanomips_dis(char *buf, +static int nanomips_dis(char **buf, Dis_info *info, unsigned short one, unsigned short two, unsigned short three) { - std::string disasm; uint16 bits[3] = {one, two, three}; TABLE_ENTRY_TYPE type; - int size = Disassemble(bits, disasm, type, info); - - strcpy(buf, disasm.c_str()); + int size = Disassemble(bits, buf, type, info); return size; } @@ -22283,7 +22181,7 @@ int print_insn_nanomips(bfd_vma memaddr, struct disassemble_info *info) int status; bfd_byte buffer[2]; uint16_t insn1 = 0, insn2 = 0, insn3 = 0; - char buf[200]; + char *buf = NULL; info->bytes_per_chunk = 2; info->display_endian = info->endian; @@ -22345,7 +22243,7 @@ int print_insn_nanomips(bfd_vma memaddr, struct disassemble_info *info) (*info->fprintf_func)(info->stream, " "); } - int length = nanomips_dis(buf, &disassm_info, insn1, insn2, insn3); + int length = nanomips_dis(&buf, &disassm_info, insn1, insn2, insn3); /* FIXME: Should probably use a hash table on the major opcode here. */ From 4066c152b322fad4c89872a30e6febc70a43bf73 Mon Sep 17 00:00:00 2001 From: Milica Lazarevic Date: Mon, 12 Sep 2022 14:26:27 +0200 Subject: [PATCH 437/705] disas/nanomips: Remove IMMEDIATE functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both versions of IMMEDIATE functions have been removed. Before this patch, we'd been calling img_format twice, the first time through the IMMEDIATE to get an appropriate string and the second time to print that string. There's no more need for that. Therefore, calls to IMMEDIATE are removed, and now we're directly printing the integer values instead. Signed-off-by: Milica Lazarevic Reviewed-by: Richard Henderson Message-Id: <20220912122635.74032-17-milica.lazarevic@syrmia.com> Signed-off-by: Philippe Mathieu-Daudé --- disas/nanomips.cpp | 756 ++++++++++++++++----------------------------- 1 file changed, 265 insertions(+), 491 deletions(-) diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp index e4e122f3cf..3b1ca249ce 100644 --- a/disas/nanomips.cpp +++ b/disas/nanomips.cpp @@ -519,18 +519,6 @@ static const char *AC(uint64 reg) } -static char *IMMEDIATE(uint64 value) -{ - return img_format("0x%" PRIx64, value); -} - - -static char *IMMEDIATE(int64 value) -{ - return img_format("%" PRId64, value); -} - - static char *CPR(uint64 reg) { /* needs more work */ @@ -1674,11 +1662,10 @@ static char *ACLR(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - char *bit = IMMEDIATE(bit_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("ACLR %s, %s(%s)", bit, s, rs); + return img_format("ACLR 0x%" PRIx64 ", %" PRId64 "(%s)", + bit_value, s_value, rs); } @@ -1772,9 +1759,8 @@ static char *ADDIU_32_(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *u = IMMEDIATE(u_value); - return img_format("ADDIU %s, %s, %s", rt, rs, u); + return img_format("ADDIU %s, %s, 0x%" PRIx64, rt, rs, u_value); } @@ -1793,9 +1779,8 @@ static char *ADDIU_48_(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); - return img_format("ADDIU %s, %s", rt, s); + return img_format("ADDIU %s, %" PRId64, rt, s_value); } @@ -1814,9 +1799,8 @@ static char *ADDIU_GP48_(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); - return img_format("ADDIU %s, $%d, %s", rt, 28, s); + return img_format("ADDIU %s, $%d, %" PRId64, rt, 28, s_value); } @@ -1835,9 +1819,8 @@ static char *ADDIU_GP_B_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_17_to_0(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); - return img_format("ADDIU %s, $%d, %s", rt, 28, u); + return img_format("ADDIU %s, $%d, 0x%" PRIx64, rt, 28, u_value); } @@ -1856,9 +1839,8 @@ static char *ADDIU_GP_W_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_20_to_2__s2(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); - return img_format("ADDIU %s, $%d, %s", rt, 28, u); + return img_format("ADDIU %s, $%d, 0x%" PRIx64, rt, 28, u_value); } @@ -1879,9 +1861,9 @@ static char *ADDIU_NEG_(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *u = IMMEDIATE(neg_copy(u_value)); + int64 u = neg_copy(u_value); - return img_format("ADDIU %s, %s, %s", rt, rs, u); + return img_format("ADDIU %s, %s, %" PRId64, rt, rs, u); } @@ -1900,9 +1882,8 @@ static char *ADDIU_R1_SP_(uint64 instruction, Dis_info *info) uint64 rt3_value = extract_rt3_9_8_7(instruction); const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); - char *u = IMMEDIATE(u_value); - return img_format("ADDIU %s, $%d, %s", rt3, 29, u); + return img_format("ADDIU %s, $%d, 0x%" PRIx64, rt3, 29, u_value); } @@ -1923,9 +1904,8 @@ static char *ADDIU_R2_(uint64 instruction, Dis_info *info) const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); - char *u = IMMEDIATE(u_value); - return img_format("ADDIU %s, %s, %s", rt3, rs3, u); + return img_format("ADDIU %s, %s, 0x%" PRIx64, rt3, rs3, u_value); } @@ -1943,9 +1923,8 @@ static char *ADDIU_RS5_(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se3_4_2_1_0(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); - return img_format("ADDIU %s, %s", rt, s); + return img_format("ADDIU %s, %" PRId64, rt, s_value); } @@ -2513,9 +2492,9 @@ static char *ANDI_16_(uint64 instruction, Dis_info *info) const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); - char *eu = IMMEDIATE(encode_eu_from_u_andi16(eu_value)); + uint64 eu = encode_eu_from_u_andi16(eu_value); - return img_format("ANDI %s, %s, %s", rt3, rs3, eu); + return img_format("ANDI %s, %s, 0x%" PRIx64, rt3, rs3, eu); } @@ -2537,9 +2516,8 @@ static char *ANDI_32_(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *u = IMMEDIATE(u_value); - return img_format("ANDI %s, %s, %s", rt, rs, u); + return img_format("ANDI %s, %s, 0x%" PRIx64, rt, rs, u_value); } @@ -2561,9 +2539,8 @@ static char *APPEND(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *sa = IMMEDIATE(sa_value); - return img_format("APPEND %s, %s, %s", rt, rs, sa); + return img_format("APPEND %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -2583,11 +2560,10 @@ static char *ASET(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - char *bit = IMMEDIATE(bit_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("ASET %s, %s(%s)", bit, s, rs); + return img_format("ASET 0x%" PRIx64 ", %" PRId64 "(%s)", + bit_value, s_value, rs); } @@ -2670,10 +2646,9 @@ static char *BBEQZC(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); const char *rt = GPR(rt_value); - char *bit = IMMEDIATE(bit_value); char *s = ADDRESS(s_value, 4, info); - return img_format("BBEQZC %s, %s, %s", rt, bit, s); + return img_format("BBEQZC %s, 0x%" PRIx64 ", %s", rt, bit_value, s); } @@ -2694,10 +2669,9 @@ static char *BBNEZC(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); const char *rt = GPR(rt_value); - char *bit = IMMEDIATE(bit_value); char *s = ADDRESS(s_value, 4, info); - return img_format("BBNEZC %s, %s, %s", rt, bit, s); + return img_format("BBNEZC %s, 0x%" PRIx64 ", %s", rt, bit_value, s); } @@ -2894,10 +2868,9 @@ static char *BEQIC(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); char *s = ADDRESS(s_value, 4, info); - return img_format("BEQIC %s, %s, %s", rt, u, s); + return img_format("BEQIC %s, 0x%" PRIx64 ", %s", rt, u_value, s); } @@ -2964,10 +2937,9 @@ static char *BGEIC(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); char *s = ADDRESS(s_value, 4, info); - return img_format("BGEIC %s, %s, %s", rt, u, s); + return img_format("BGEIC %s, 0x%" PRIx64 ", %s", rt, u_value, s); } @@ -2988,10 +2960,9 @@ static char *BGEIUC(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); char *s = ADDRESS(s_value, 4, info); - return img_format("BGEIUC %s, %s, %s", rt, u, s); + return img_format("BGEIUC %s, 0x%" PRIx64 ", %s", rt, u_value, s); } @@ -3060,10 +3031,9 @@ static char *BLTIC(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); char *s = ADDRESS(s_value, 4, info); - return img_format("BLTIC %s, %s, %s", rt, u, s); + return img_format("BLTIC %s, 0x%" PRIx64 ", %s", rt, u_value, s); } @@ -3084,10 +3054,9 @@ static char *BLTIUC(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); char *s = ADDRESS(s_value, 4, info); - return img_format("BLTIUC %s, %s, %s", rt, u, s); + return img_format("BLTIUC %s, 0x%" PRIx64 ", %s", rt, u_value, s); } @@ -3180,10 +3149,9 @@ static char *BNEIC(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); char *s = ADDRESS(s_value, 4, info); - return img_format("BNEIC %s, %s, %s", rt, u, s); + return img_format("BNEIC %s, 0x%" PRIx64 ", %s", rt, u_value, s); } @@ -3243,9 +3211,8 @@ static char *BREAK_16_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_2_1_0(instruction); - char *code = IMMEDIATE(code_value); - return img_format("BREAK %s", code); + return img_format("BREAK 0x%" PRIx64, code_value); } @@ -3263,9 +3230,8 @@ static char *BREAK_32_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_18_to_0(instruction); - char *code = IMMEDIATE(code_value); - return img_format("BREAK %s", code); + return img_format("BREAK 0x%" PRIx64, code_value); } @@ -3305,11 +3271,9 @@ static char *CACHE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - char *op = IMMEDIATE(op_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("CACHE %s, %s(%s)", op, s, rs); + return img_format("CACHE 0x%" PRIx64 ", %s(%s)", op_value, s_value, rs); } @@ -3329,11 +3293,9 @@ static char *CACHEE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - char *op = IMMEDIATE(op_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("CACHEE %s, %s(%s)", op, s, rs); + return img_format("CACHEE 0x%" PRIx64 ", %s(%s)", op_value, s_value, rs); } @@ -4906,9 +4868,8 @@ static char *COP2_1(uint64 instruction, Dis_info *info) { uint64 cofun_value = extract_cofun_25_24_23(instruction); - char *cofun = IMMEDIATE(cofun_value); - return img_format("COP2_1 %s", cofun); + return img_format("COP2_1 0x%" PRIx64, cofun_value); } @@ -5236,9 +5197,8 @@ static char *DADDIU_48_(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); - return img_format("DADDIU %s, %s", rt, s); + return img_format("DADDIU %s, %s", rt, s_value); } @@ -5260,9 +5220,9 @@ static char *DADDIU_NEG_(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *u = IMMEDIATE(neg_copy(u_value)); + int64 u = neg_copy(u_value); - return img_format("DADDIU %s, %s, %s", rt, rs, u); + return img_format("DADDIU %s, %s, %" PRId64, rt, rs, u); } @@ -5284,9 +5244,8 @@ static char *DADDIU_U12_(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *u = IMMEDIATE(u_value); - return img_format("DADDIU %s, %s, %s", rt, rs, u); + return img_format("DADDIU %s, %s, 0x%" PRIx64, rt, rs, u_value); } @@ -5467,10 +5426,10 @@ static char *DEXTM(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *lsb = IMMEDIATE(lsb_value); - char *msbd = IMMEDIATE(encode_msbd_from_size(msbd_value)); + uint64 msbd = encode_msbd_from_size(msbd_value); - return img_format("DEXTM %s, %s, %s, %s", rt, rs, lsb, msbd); + return img_format("DEXTM %s, %s, 0x%" PRIx64 ", 0x%" PRIx64, + rt, rs, lsb_value, msbd); } @@ -5493,10 +5452,10 @@ static char *DEXT(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *lsb = IMMEDIATE(lsb_value); - char *msbd = IMMEDIATE(encode_msbd_from_size(msbd_value)); + uint64 msbd = encode_msbd_from_size(msbd_value); - return img_format("DEXT %s, %s, %s, %s", rt, rs, lsb, msbd); + return img_format("DEXT %s, %s, 0x%" PRIx64 ", 0x%" PRIx64, + rt, rs, lsb_value, msbd); } @@ -5519,10 +5478,10 @@ static char *DEXTU(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *lsb = IMMEDIATE(lsb_value); - char *msbd = IMMEDIATE(encode_msbd_from_size(msbd_value)); + uint64 msbd = encode_msbd_from_size(msbd_value); - return img_format("DEXTU %s, %s, %s, %s", rt, rs, lsb, msbd); + return img_format("DEXTU %s, %s, 0x%" PRIx64 ", 0x%" PRIx64, + rt, rs, lsb_value, msbd); } @@ -5545,11 +5504,10 @@ static char *DINSM(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *pos = IMMEDIATE(lsb_value); - char *size = IMMEDIATE(msbd_value); /* !!!!!!!!!! - no conversion function */ - return img_format("DINSM %s, %s, %s, %s", rt, rs, pos, size); + return img_format("DINSM %s, %s, 0x%" PRIx64 ", 0x%" PRIx64, + rt, rs, lsb_value, msbd_value); /* hand edited */ } @@ -5573,11 +5531,10 @@ static char *DINS(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *pos = IMMEDIATE(lsb_value); - char *size = IMMEDIATE(msbd_value); /* !!!!!!!!!! - no conversion function */ - return img_format("DINS %s, %s, %s, %s", rt, rs, pos, size); + return img_format("DINS %s, %s, 0x%" PRIx64 ", 0x%" PRIx64, + rt, rs, lsb_value, msbd_value); /* hand edited */ } @@ -5601,11 +5558,10 @@ static char *DINSU(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *pos = IMMEDIATE(lsb_value); - char *size = IMMEDIATE(msbd_value); /* !!!!!!!!!! - no conversion function */ - return img_format("DINSU %s, %s, %s, %s", rt, rs, pos, size); + return img_format("DINSU %s, %s, 0x%" PRIx64 ", 0x%" PRIx64, + rt, rs, lsb_value, msbd_value); /* hand edited */ } @@ -5746,9 +5702,8 @@ static char *DLSA(uint64 instruction, Dis_info *info) const char *rd = GPR(rd_value); const char *rs = GPR(rs_value); const char *rt = GPR(rt_value); - char *u2 = IMMEDIATE(u2_value); - return img_format("DLSA %s, %s, %s, %s", rd, rs, rt, u2); + return img_format("DLSA %s, %s, %s, 0x%" PRIx64, rd, rs, rt, u2_value); } @@ -5768,9 +5723,8 @@ static char *DLUI_48_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_31_to_0__s32(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); - return img_format("DLUI %s, %s", rt, u); + return img_format("DLUI %s, 0x%" PRIx64, rt, u_value); } @@ -5792,9 +5746,8 @@ static char *DMFC0(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); char *c0s = CPR(c0s_value); - char *sel = IMMEDIATE(sel_value); - return img_format("DMFC0 %s, %s, %s", rt, c0s, sel); + return img_format("DMFC0 %s, %s, 0x%" PRIx64, rt, c0s, sel_value); } @@ -5860,9 +5813,8 @@ static char *DMFGC0(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); char *c0s = CPR(c0s_value); - char *sel = IMMEDIATE(sel_value); - return img_format("DMFGC0 %s, %s, %s", rt, c0s, sel); + return img_format("DMFGC0 %s, %s, 0x%" PRIx64, rt, c0s, sel_value); } @@ -5932,9 +5884,8 @@ static char *DMTC0(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); char *c0s = CPR(c0s_value); - char *sel = IMMEDIATE(sel_value); - return img_format("DMTC0 %s, %s, %s", rt, c0s, sel); + return img_format("DMTC0 %s, %s, 0x%" PRIx64, rt, c0s, sel_value); } @@ -6000,9 +5951,8 @@ static char *DMTGC0(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); char *c0s = CPR(c0s_value); - char *sel = IMMEDIATE(sel_value); - return img_format("DMTGC0 %s, %s, %s", rt, c0s, sel); + return img_format("DMTGC0 %s, %s, 0x%" PRIx64, rt, c0s, sel_value); } @@ -6525,9 +6475,8 @@ static char *DROTR(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *shift = IMMEDIATE(shift_value); - return img_format("DROTR %s, %s, %s", rt, rs, shift); + return img_format("DROTR %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -6549,9 +6498,8 @@ static char *DROTR32(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *shift = IMMEDIATE(shift_value); - return img_format("DROTR32 %s, %s, %s", rt, rs, shift); + return img_format("DROTR32 %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -6598,10 +6546,9 @@ static char *DROTX(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *shift = IMMEDIATE(shift_value); - char *shiftx = IMMEDIATE(shiftx_value); - return img_format("DROTX %s, %s, %s, %s", rt, rs, shift, shiftx); + return img_format("DROTX %s, %s, 0x%" PRIx64 ", 0x%" PRIx64, + rt, rs, shift_value, shiftx_value); } @@ -6623,9 +6570,8 @@ static char *DSLL(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *shift = IMMEDIATE(shift_value); - return img_format("DSLL %s, %s, %s", rt, rs, shift); + return img_format("DSLL %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -6647,9 +6593,8 @@ static char *DSLL32(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *shift = IMMEDIATE(shift_value); - return img_format("DSLL32 %s, %s, %s", rt, rs, shift); + return img_format("DSLL32 %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -6695,9 +6640,8 @@ static char *DSRA(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *shift = IMMEDIATE(shift_value); - return img_format("DSRA %s, %s, %s", rt, rs, shift); + return img_format("DSRA %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -6719,9 +6663,8 @@ static char *DSRA32(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *shift = IMMEDIATE(shift_value); - return img_format("DSRA32 %s, %s, %s", rt, rs, shift); + return img_format("DSRA32 %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -6767,9 +6710,8 @@ static char *DSRL(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *shift = IMMEDIATE(shift_value); - return img_format("DSRL %s, %s, %s", rt, rs, shift); + return img_format("DSRL %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -6791,9 +6733,8 @@ static char *DSRL32(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *shift = IMMEDIATE(shift_value); - return img_format("DSRL32 %s, %s, %s", rt, rs, shift); + return img_format("DSRL32 %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -7062,10 +7003,10 @@ static char *EXT(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *lsb = IMMEDIATE(lsb_value); - char *msbd = IMMEDIATE(encode_msbd_from_size(msbd_value)); + uint64 msbd = encode_msbd_from_size(msbd_value); - return img_format("EXT %s, %s, %s, %s", rt, rs, lsb, msbd); + return img_format("EXT %s, %s, 0x%" PRIx64 ", 0x%" PRIx64, + rt, rs, lsb_value, msbd); } @@ -7089,9 +7030,8 @@ static char *EXTD(uint64 instruction, Dis_info *info) const char *rd = GPR(rd_value); const char *rs = GPR(rs_value); const char *rt = GPR(rt_value); - char *shift = IMMEDIATE(shift_value); - return img_format("EXTD %s, %s, %s, %s", rd, rs, rt, shift); + return img_format("EXTD %s, %s, %s, 0x%" PRIx64, rd, rs, rt, shift_value); } @@ -7115,9 +7055,8 @@ static char *EXTD32(uint64 instruction, Dis_info *info) const char *rd = GPR(rd_value); const char *rs = GPR(rs_value); const char *rt = GPR(rt_value); - char *shift = IMMEDIATE(shift_value); - return img_format("EXTD32 %s, %s, %s, %s", rd, rs, rt, shift); + return img_format("EXTD32 %s, %s, %s, 0x%" PRIx64, rd, rs, rt, shift_value); } @@ -7139,9 +7078,8 @@ static char *EXTPDP(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *ac = AC(ac_value); - char *size = IMMEDIATE(size_value); - return img_format("EXTPDP %s, %s, %s", rt, ac, size); + return img_format("EXTPDP %s, %s, 0x%" PRIx64, rt, ac, size_value); } @@ -7187,9 +7125,8 @@ static char *EXTP(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *ac = AC(ac_value); - char *size = IMMEDIATE(size_value); - return img_format("EXTP %s, %s, %s", rt, ac, size); + return img_format("EXTP %s, %s, 0x%" PRIx64, rt, ac, size_value); } @@ -7236,9 +7173,8 @@ static char *EXTR_RS_W(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *ac = AC(ac_value); - char *shift = IMMEDIATE(shift_value); - return img_format("EXTR_RS.W %s, %s, %s", rt, ac, shift); + return img_format("EXTR_RS.W %s, %s, 0x%" PRIx64, rt, ac, shift_value); } @@ -7261,9 +7197,8 @@ static char *EXTR_R_W(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *ac = AC(ac_value); - char *shift = IMMEDIATE(shift_value); - return img_format("EXTR_R.W %s, %s, %s", rt, ac, shift); + return img_format("EXTR_R.W %s, %s, 0x%" PRIx64, rt, ac, shift_value); } @@ -7286,9 +7221,8 @@ static char *EXTR_S_H(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *ac = AC(ac_value); - char *shift = IMMEDIATE(shift_value); - return img_format("EXTR_S.H %s, %s, %s", rt, ac, shift); + return img_format("EXTR_S.H %s, %s, 0x%" PRIx64, rt, ac, shift_value); } @@ -7311,9 +7245,8 @@ static char *EXTR_W(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *ac = AC(ac_value); - char *shift = IMMEDIATE(shift_value); - return img_format("EXTR.W %s, %s, %s", rt, ac, shift); + return img_format("EXTR.W %s, %s, 0x%" PRIx64, rt, ac, shift_value); } @@ -7438,9 +7371,8 @@ static char *EXTW(uint64 instruction, Dis_info *info) const char *rd = GPR(rd_value); const char *rs = GPR(rs_value); const char *rt = GPR(rt_value); - char *shift = IMMEDIATE(shift_value); - return img_format("EXTW %s, %s, %s, %s", rd, rs, rt, shift); + return img_format("EXTW %s, %s, %s, 0x%" PRIx64, rd, rs, rt, shift_value); } @@ -7570,9 +7502,8 @@ static char *HYPCALL(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_17_to_0(instruction); - char *code = IMMEDIATE(code_value); - return img_format("HYPCALL %s", code); + return img_format("HYPCALL 0x%" PRIx64, code_value); } @@ -7590,9 +7521,8 @@ static char *HYPCALL_16_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_1_0(instruction); - char *code = IMMEDIATE(code_value); - return img_format("HYPCALL %s", code); + return img_format("HYPCALL 0x%" PRIx64, code_value); } @@ -7615,11 +7545,10 @@ static char *INS(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *pos = IMMEDIATE(lsb_value); - char *size = IMMEDIATE(msbd_value); /* !!!!!!!!!! - no conversion function */ - return img_format("INS %s, %s, %s, %s", rt, rs, pos, size); + return img_format("INS %s, %s, 0x%" PRIx64 ", 0x%" PRIx64, + rt, rs, lsb_value, msbd_value); /* hand edited */ } @@ -7764,10 +7693,9 @@ static char *LB_16_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_1_0(instruction); const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); - char *u = IMMEDIATE(u_value); const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); - return img_format("LB %s, %s(%s)", rt3, u, rs3); + return img_format("LB %s, 0x%" PRIx64 "(%s)", rt3, u_value, rs3); } @@ -7787,9 +7715,8 @@ static char *LB_GP_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_17_to_0(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); - return img_format("LB %s, %s($%d)", rt, u, 28); + return img_format("LB %s, 0x%" PRIx64 "($%d)", rt, u_value, 28); } @@ -7810,10 +7737,9 @@ static char *LB_S9_(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("LB %s, %s(%s)", rt, s, rs); + return img_format("LB %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -7834,10 +7760,9 @@ static char *LB_U12_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); const char *rs = GPR(rs_value); - return img_format("LB %s, %s(%s)", rt, u, rs); + return img_format("LB %s, 0x%" PRIx64 "(%s)", rt, u_value, rs); } @@ -7858,10 +7783,9 @@ static char *LBE(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("LBE %s, %s(%s)", rt, s, rs); + return img_format("LBE %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -7882,10 +7806,9 @@ static char *LBU_16_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_1_0(instruction); const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); - char *u = IMMEDIATE(u_value); const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); - return img_format("LBU %s, %s(%s)", rt3, u, rs3); + return img_format("LBU %s, 0x%" PRIx64 "(%s)", rt3, u_value, rs3); } @@ -7905,9 +7828,8 @@ static char *LBU_GP_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_17_to_0(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); - return img_format("LBU %s, %s($%d)", rt, u, 28); + return img_format("LBU %s, 0x%" PRIx64 "($%d)", rt, u_value, 28); } @@ -7928,10 +7850,9 @@ static char *LBU_S9_(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("LBU %s, %s(%s)", rt, s, rs); + return img_format("LBU %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -7952,10 +7873,9 @@ static char *LBU_U12_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); const char *rs = GPR(rs_value); - return img_format("LBU %s, %s(%s)", rt, u, rs); + return img_format("LBU %s, 0x%" PRIx64 "(%s)", rt, u_value, rs); } @@ -7976,10 +7896,9 @@ static char *LBUE(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("LBUE %s, %s(%s)", rt, s, rs); + return img_format("LBUE %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -8047,9 +7966,8 @@ static char *LD_GP_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_20_to_3__s3(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); - return img_format("LD %s, %s($%d)", rt, u, 28); + return img_format("LD %s, 0x%" PRIx64 "($%d)", rt, u_value, 28); } @@ -8070,10 +7988,9 @@ static char *LD_S9_(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("LD %s, %s(%s)", rt, s, rs); + return img_format("LD %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -8094,10 +8011,9 @@ static char *LD_U12_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); const char *rs = GPR(rs_value); - return img_format("LD %s, %s(%s)", rt, u, rs); + return img_format("LD %s, 0x%" PRIx64 "(%s)", rt, u_value, rs); } @@ -8117,9 +8033,8 @@ static char *LDC1_GP_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_17_to_2__s2(instruction); const char *ft = FPR(ft_value); - char *u = IMMEDIATE(u_value); - return img_format("LDC1 %s, %s($%d)", ft, u, 28); + return img_format("LDC1 %s, 0x%" PRIx64 "($%d)", ft, u_value, 28); } @@ -8140,10 +8055,9 @@ static char *LDC1_S9_(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); const char *ft = FPR(ft_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("LDC1 %s, %s(%s)", ft, s, rs); + return img_format("LDC1 %s, %" PRId64 "(%s)", ft, s_value, rs); } @@ -8164,10 +8078,9 @@ static char *LDC1_U12_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); const char *ft = FPR(ft_value); - char *u = IMMEDIATE(u_value); const char *rs = GPR(rs_value); - return img_format("LDC1 %s, %s(%s)", ft, u, rs); + return img_format("LDC1 %s, 0x%" PRIx64 "(%s)", ft, u_value, rs); } @@ -8236,10 +8149,9 @@ static char *LDC2(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); char *ct = CPR(ct_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("LDC2 %s, %s(%s)", ct, s, rs); + return img_format("LDC2 %s, %" PRId64 "(%s)", ct, s_value, rs); } @@ -8261,11 +8173,11 @@ static char *LDM(uint64 instruction, Dis_info *info) uint64 count3_value = extract_count3_14_13_12(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - char *count3 = IMMEDIATE(encode_count3_from_count(count3_value)); + uint64 count3 = encode_count3_from_count(count3_value); - return img_format("LDM %s, %s(%s), %s", rt, s, rs, count3); + return img_format("LDM %s, %" PRId64 "(%s), 0x%" PRIx64, + rt, s_value, rs, count3); } @@ -8356,10 +8268,9 @@ static char *LH_16_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_2_1__s1(instruction); const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); - char *u = IMMEDIATE(u_value); const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); - return img_format("LH %s, %s(%s)", rt3, u, rs3); + return img_format("LH %s, 0x%" PRIx64 "(%s)", rt3, u_value, rs3); } @@ -8379,9 +8290,8 @@ static char *LH_GP_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_17_to_1__s1(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); - return img_format("LH %s, %s($%d)", rt, u, 28); + return img_format("LH %s, 0x%" PRIx64 "($%d)", rt, u_value, 28); } @@ -8402,10 +8312,9 @@ static char *LH_S9_(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("LH %s, %s(%s)", rt, s, rs); + return img_format("LH %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -8426,10 +8335,9 @@ static char *LH_U12_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); const char *rs = GPR(rs_value); - return img_format("LH %s, %s(%s)", rt, u, rs); + return img_format("LH %s, 0x%" PRIx64 "(%s)", rt, u_value, rs); } @@ -8450,10 +8358,9 @@ static char *LHE(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("LHE %s, %s(%s)", rt, s, rs); + return img_format("LHE %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -8474,10 +8381,9 @@ static char *LHU_16_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_2_1__s1(instruction); const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); - char *u = IMMEDIATE(u_value); const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); - return img_format("LHU %s, %s(%s)", rt3, u, rs3); + return img_format("LHU %s, 0x%" PRIx64 "(%s)", rt3, u_value, rs3); } @@ -8497,9 +8403,8 @@ static char *LHU_GP_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_17_to_1__s1(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); - return img_format("LHU %s, %s($%d)", rt, u, 28); + return img_format("LHU %s, 0x%" PRIx64 "($%d)", rt, u_value, 28); } @@ -8520,10 +8425,9 @@ static char *LHU_S9_(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("LHU %s, %s(%s)", rt, s, rs); + return img_format("LHU %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -8544,10 +8448,9 @@ static char *LHU_U12_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); const char *rs = GPR(rs_value); - return img_format("LHU %s, %s(%s)", rt, u, rs); + return img_format("LHU %s, 0x%" PRIx64 "(%s)", rt, u_value, rs); } @@ -8568,10 +8471,9 @@ static char *LHUE(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("LHUE %s, %s(%s)", rt, s, rs); + return img_format("LHUE %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -8687,9 +8589,9 @@ static char *LI_16_(uint64 instruction, Dis_info *info) uint64 eu_value = extract_eu_6_5_4_3_2_1_0(instruction); const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); - char *eu = IMMEDIATE(encode_eu_from_s_li16(eu_value)); + int64 eu = encode_eu_from_s_li16(eu_value); - return img_format("LI %s, %s", rt3, eu); + return img_format("LI %s, %" PRId64, rt3, eu); } @@ -8709,9 +8611,8 @@ static char *LI_48_(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); - return img_format("LI %s, %s", rt, s); + return img_format("LI %s, %" PRId64, rt, s_value); } @@ -8732,10 +8633,9 @@ static char *LL(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_s2(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("LL %s, %s(%s)", rt, s, rs); + return img_format("LL %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -8756,10 +8656,9 @@ static char *LLD(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_s3(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("LLD %s, %s(%s)", rt, s, rs); + return img_format("LLD %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -8804,10 +8703,9 @@ static char *LLE(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_s2(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("LLE %s, %s(%s)", rt, s, rs); + return img_format("LLE %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -8879,9 +8777,8 @@ static char *LSA(uint64 instruction, Dis_info *info) const char *rd = GPR(rd_value); const char *rs = GPR(rs_value); const char *rt = GPR(rt_value); - char *u2 = IMMEDIATE(u2_value); - return img_format("LSA %s, %s, %s, %s", rd, rs, rt, u2); + return img_format("LSA %s, %s, %s, 0x%" PRIx64, rd, rs, rt, u2_value); } @@ -8901,9 +8798,8 @@ static char *LUI(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se31_0_11_to_2_20_to_12_s12(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); - return img_format("LUI %s, %%hi(%s)", rt, s); + return img_format("LUI %s, %%hi(%" PRId64 ")", rt, s_value); } @@ -8924,10 +8820,9 @@ static char *LW_16_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_3_2_1_0__s2(instruction); const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); - char *u = IMMEDIATE(u_value); const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); - return img_format("LW %s, %s(%s)", rt3, u, rs3); + return img_format("LW %s, 0x%" PRIx64 "(%s)", rt3, u_value, rs3); } @@ -8948,10 +8843,9 @@ static char *LW_4X4_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_3_8__s2(instruction); const char *rt4 = GPR(decode_gpr_gpr4(rt4_value)); - char *u = IMMEDIATE(u_value); const char *rs4 = GPR(decode_gpr_gpr4(rs4_value)); - return img_format("LW %s, %s(%s)", rt4, u, rs4); + return img_format("LW %s, 0x%" PRIx64 "(%s)", rt4, u_value, rs4); } @@ -8971,9 +8865,8 @@ static char *LW_GP_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_20_to_2__s2(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); - return img_format("LW %s, %s($%d)", rt, u, 28); + return img_format("LW %s, 0x%" PRIx64 "($%d)", rt, u_value, 28); } @@ -8993,9 +8886,8 @@ static char *LW_GP16_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_6_5_4_3_2_1_0__s2(instruction); const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); - char *u = IMMEDIATE(u_value); - return img_format("LW %s, %s($%d)", rt3, u, 28); + return img_format("LW %s, 0x%" PRIx64 "($%d)", rt3, u_value, 28); } @@ -9016,10 +8908,9 @@ static char *LW_S9_(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("LW %s, %s(%s)", rt, s, rs); + return img_format("LW %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -9039,9 +8930,8 @@ static char *LW_SP_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_4_3_2_1_0__s2(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); - return img_format("LW %s, %s($%d)", rt, u, 29); + return img_format("LW %s, 0x%" PRIx64 "($%d)", rt, u_value, 29); } @@ -9062,10 +8952,9 @@ static char *LW_U12_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); const char *rs = GPR(rs_value); - return img_format("LW %s, %s(%s)", rt, u, rs); + return img_format("LW %s, 0x%" PRIx64 "(%s)", rt, u_value, rs); } @@ -9085,9 +8974,8 @@ static char *LWC1_GP_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_17_to_2__s2(instruction); const char *ft = FPR(ft_value); - char *u = IMMEDIATE(u_value); - return img_format("LWC1 %s, %s($%d)", ft, u, 28); + return img_format("LWC1 %s, 0x%" PRIx64 "($%d)", ft, u_value, 28); } @@ -9108,10 +8996,9 @@ static char *LWC1_S9_(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); const char *ft = FPR(ft_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("LWC1 %s, %s(%s)", ft, s, rs); + return img_format("LWC1 %s, %" PRId64 "(%s)", ft, s_value, rs); } @@ -9132,10 +9019,9 @@ static char *LWC1_U12_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); const char *ft = FPR(ft_value); - char *u = IMMEDIATE(u_value); const char *rs = GPR(rs_value); - return img_format("LWC1 %s, %s(%s)", ft, u, rs); + return img_format("LWC1 %s, 0x%" PRIx64 "(%s)", ft, u_value, rs); } @@ -9204,10 +9090,9 @@ static char *LWC2(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); char *ct = CPR(ct_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("LWC2 %s, %s(%s)", ct, s, rs); + return img_format("LWC2 %s, %" PRId64 "(%s)", ct, s_value, rs); } @@ -9228,10 +9113,9 @@ static char *LWE(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("LWE %s, %s(%s)", rt, s, rs); + return img_format("LWE %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -9253,11 +9137,11 @@ static char *LWM(uint64 instruction, Dis_info *info) uint64 count3_value = extract_count3_14_13_12(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - char *count3 = IMMEDIATE(encode_count3_from_count(count3_value)); + uint64 count3 = encode_count3_from_count(count3_value); - return img_format("LWM %s, %s(%s), %s", rt, s, rs, count3); + return img_format("LWM %s, %" PRId64 "(%s), 0x%" PRIx64, + rt, s_value, rs, count3); } @@ -9299,9 +9183,8 @@ static char *LWU_GP_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_17_to_2__s2(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); - return img_format("LWU %s, %s($%d)", rt, u, 28); + return img_format("LWU %s, 0x%" PRIx64 "($%d)", rt, u_value, 28); } @@ -9322,10 +9205,9 @@ static char *LWU_S9_(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("LWU %s, %s(%s)", rt, s, rs); + return img_format("LWU %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -9346,10 +9228,9 @@ static char *LWU_U12_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); const char *rs = GPR(rs_value); - return img_format("LWU %s, %s(%s)", rt, u, rs); + return img_format("LWU %s, 0x%" PRIx64 "(%s)", rt, u_value, rs); } @@ -9443,9 +9324,9 @@ static char *LWXS_16_(uint64 instruction, Dis_info *info) const char *rd3 = GPR(decode_gpr_gpr3(rd3_value)); const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); - char *rt3 = IMMEDIATE(decode_gpr_gpr3(rt3_value)); + uint64 rt3 = decode_gpr_gpr3(rt3_value); - return img_format("LWXS %s, %s(%s)", rd3, rs3, rt3); + return img_format("LWXS %s, %s(0x%" PRIx64 ")", rd3, rs3, rt3); } @@ -9785,9 +9666,8 @@ static char *MFC0(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); char *c0s = CPR(c0s_value); - char *sel = IMMEDIATE(sel_value); - return img_format("MFC0 %s, %s, %s", rt, c0s, sel); + return img_format("MFC0 %s, %s, 0x%" PRIx64, rt, c0s, sel_value); } @@ -9853,9 +9733,8 @@ static char *MFGC0(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); char *c0s = CPR(c0s_value); - char *sel = IMMEDIATE(sel_value); - return img_format("MFGC0 %s, %s, %s", rt, c0s, sel); + return img_format("MFGC0 %s, %s, 0x%" PRIx64, rt, c0s, sel_value); } @@ -9877,9 +9756,8 @@ static char *MFHC0(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); char *c0s = CPR(c0s_value); - char *sel = IMMEDIATE(sel_value); - return img_format("MFHC0 %s, %s, %s", rt, c0s, sel); + return img_format("MFHC0 %s, %s, 0x%" PRIx64, rt, c0s, sel_value); } @@ -9945,9 +9823,8 @@ static char *MFHGC0(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); char *c0s = CPR(c0s_value); - char *sel = IMMEDIATE(sel_value); - return img_format("MFHGC0 %s, %s, %s", rt, c0s, sel); + return img_format("MFHGC0 %s, %s, 0x%" PRIx64, rt, c0s, sel_value); } @@ -9990,11 +9867,9 @@ static char *MFHTR(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_10(instruction); const char *rt = GPR(rt_value); - char *c0s = IMMEDIATE(c0s_value); - char *u = IMMEDIATE(u_value); - char *sel = IMMEDIATE(sel_value); - return img_format("MFHTR %s, %s, %s, %s", rt, c0s, u, sel); + return img_format("MFHTR %s, 0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64, + rt, c0s_value, u_value, sel_value); } @@ -10037,11 +9912,9 @@ static char *MFTR(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_10(instruction); const char *rt = GPR(rt_value); - char *c0s = IMMEDIATE(c0s_value); - char *u = IMMEDIATE(u_value); - char *sel = IMMEDIATE(sel_value); - return img_format("MFTR %s, %s, %s, %s", rt, c0s, u, sel); + return img_format("MFTR %s, 0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64, + rt, c0s_value, u_value, sel_value); } @@ -10519,9 +10392,8 @@ static char *MTC0(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); char *c0s = CPR(c0s_value); - char *sel = IMMEDIATE(sel_value); - return img_format("MTC0 %s, %s, %s", rt, c0s, sel); + return img_format("MTC0 %s, %s, 0x%" PRIx64, rt, c0s, sel_value); } @@ -10587,9 +10459,8 @@ static char *MTGC0(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); char *c0s = CPR(c0s_value); - char *sel = IMMEDIATE(sel_value); - return img_format("MTGC0 %s, %s, %s", rt, c0s, sel); + return img_format("MTGC0 %s, %s, 0x%" PRIx64, rt, c0s, sel_value); } @@ -10611,9 +10482,8 @@ static char *MTHC0(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); char *c0s = CPR(c0s_value); - char *sel = IMMEDIATE(sel_value); - return img_format("MTHC0 %s, %s, %s", rt, c0s, sel); + return img_format("MTHC0 %s, %s, 0x%" PRIx64, rt, c0s, sel_value); } @@ -10679,9 +10549,8 @@ static char *MTHGC0(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); char *c0s = CPR(c0s_value); - char *sel = IMMEDIATE(sel_value); - return img_format("MTHGC0 %s, %s, %s", rt, c0s, sel); + return img_format("MTHGC0 %s, %s, 0x%" PRIx64, rt, c0s, sel_value); } @@ -10745,11 +10614,9 @@ static char *MTHTR(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_10(instruction); const char *rt = GPR(rt_value); - char *c0s = IMMEDIATE(c0s_value); - char *u = IMMEDIATE(u_value); - char *sel = IMMEDIATE(sel_value); - return img_format("MTHTR %s, %s, %s, %s", rt, c0s, u, sel); + return img_format("MTHTR %s, 0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64, + rt, c0s_value, u_value, sel_value); } @@ -10792,11 +10659,9 @@ static char *MTTR(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_10(instruction); const char *rt = GPR(rt_value); - char *c0s = IMMEDIATE(c0s_value); - char *u = IMMEDIATE(u_value); - char *sel = IMMEDIATE(sel_value); - return img_format("MTTR %s, %s, %s, %s", rt, c0s, u, sel); + return img_format("MTTR %s, 0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64, + rt, c0s_value, u_value, sel_value); } @@ -11504,9 +11369,8 @@ static char *ORI(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *u = IMMEDIATE(u_value); - return img_format("ORI %s, %s, %s", rt, rs, u); + return img_format("ORI %s, %s, 0x%" PRIx64, rt, rs, u_value); } @@ -11879,9 +11743,8 @@ static char *PRECR_SRA_PH_W(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *sa = IMMEDIATE(sa_value); - return img_format("PRECR_SRA.PH.W %s, %s, %s", rt, rs, sa); + return img_format("PRECR_SRA.PH.W %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -11904,9 +11767,8 @@ static char *PRECR_SRA_R_PH_W(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *sa = IMMEDIATE(sa_value); - return img_format("PRECR_SRA_R.PH.W %s, %s, %s", rt, rs, sa); + return img_format("PRECR_SRA_R.PH.W %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -12026,11 +11888,10 @@ static char *PREF_S9_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - char *hint = IMMEDIATE(hint_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("PREF %s, %s(%s)", hint, s, rs); + return img_format("PREF 0x%" PRIx64 ", %s(%s)", + hint_value, s_value, rs); } @@ -12050,11 +11911,10 @@ static char *PREF_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - char *hint = IMMEDIATE(hint_value); - char *u = IMMEDIATE(u_value); const char *rs = GPR(rs_value); - return img_format("PREF %s, %s(%s)", hint, u, rs); + return img_format("PREF 0x%" PRIx64 ", 0x%" PRIx64 "(%s)", + hint_value, u_value, rs); } @@ -12074,11 +11934,9 @@ static char *PREFE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - char *hint = IMMEDIATE(hint_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("PREFE %s, %s(%s)", hint, s, rs); + return img_format("PREFE 0x%" PRIx64 ", %s(%s)", hint_value, s_value, rs); } @@ -12100,9 +11958,8 @@ static char *PREPEND(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *sa = IMMEDIATE(sa_value); - return img_format("PREPEND %s, %s, %s", rt, rs, sa); + return img_format("PREPEND %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -12142,9 +11999,8 @@ static char *RDDSP(uint64 instruction, Dis_info *info) uint64 mask_value = extract_mask_20_19_18_17_16_15_14(instruction); const char *rt = GPR(rt_value); - char *mask = IMMEDIATE(mask_value); - return img_format("RDDSP %s, %s", rt, mask); + return img_format("RDDSP %s, 0x%" PRIx64, rt, mask_value); } @@ -12166,9 +12022,8 @@ static char *RDHWR(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); char *hs = CPR(hs_value); - char *sel = IMMEDIATE(sel_value); - return img_format("RDHWR %s, %s, %s", rt, hs, sel); + return img_format("RDHWR %s, %s, 0x%" PRIx64, rt, hs, sel_value); } @@ -12254,9 +12109,8 @@ static char *REPL_PH(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se9_20_19_18_17_16_15_14_13_12_11(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); - return img_format("REPL.PH %s, %s", rt, s); + return img_format("REPL.PH %s, %s", rt, s_value); } @@ -12276,9 +12130,8 @@ static char *REPL_QB(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_20_19_18_17_16_15_14_13(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); - return img_format("REPL.QB %s, %s", rt, u); + return img_format("REPL.QB %s, 0x%" PRIx64, rt, u_value); } @@ -12342,8 +12195,7 @@ static char *RESTORE_32_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3__s3(instruction); uint64 gp_value = extract_gp_2(instruction); - char *u = IMMEDIATE(u_value); - return img_format("RESTORE %s%s", u, + return img_format("RESTORE 0x%" PRIx64 "%s", u_value, save_restore_list(rt_value, count_value, gp_value)); } @@ -12364,8 +12216,7 @@ static char *RESTORE_JRC_16_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_7_6_5_4__s4(instruction); uint64 count_value = extract_count_3_2_1_0(instruction); - char *u = IMMEDIATE(u_value); - return img_format("RESTORE.JRC %s%s", u, + return img_format("RESTORE.JRC 0x%" PRIx64 "%s", u_value, save_restore_list(encode_rt1_from_rt(rt1_value), count_value, 0)); } @@ -12387,8 +12238,7 @@ static char *RESTORE_JRC_32_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3__s3(instruction); uint64 gp_value = extract_gp_2(instruction); - char *u = IMMEDIATE(u_value); - return img_format("RESTORE.JRC %s%s", u, + return img_format("RESTORE.JRC 0x%" PRIx64 "%s", u_value, save_restore_list(rt_value, count_value, gp_value)); } @@ -12408,10 +12258,8 @@ static char *RESTOREF(uint64 instruction, Dis_info *info) uint64 count_value = extract_count_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3__s3(instruction); - char *u = IMMEDIATE(u_value); - char *count = IMMEDIATE(count_value); - return img_format("RESTOREF %s, %s", u, count); + return img_format("RESTOREF 0x%" PRIx64 ", %s", u_value, count_value); } @@ -12477,9 +12325,8 @@ static char *ROTR(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *shift = IMMEDIATE(shift_value); - return img_format("ROTR %s, %s, %s", rt, rs, shift); + return img_format("ROTR %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -12527,12 +12374,9 @@ static char *ROTX(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *shift = IMMEDIATE(shift_value); - char *shiftx = IMMEDIATE(shiftx_value); - char *stripe = IMMEDIATE(stripe_value); - return img_format("ROTX %s, %s, %s, %s, %s", - rt, rs, shift, shiftx, stripe); + return img_format("ROTX %s, %s, 0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64, + rt, rs, shift_value, shiftx_value, stripe_value); } @@ -12684,8 +12528,7 @@ static char *SAVE_16_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_7_6_5_4__s4(instruction); uint64 count_value = extract_count_3_2_1_0(instruction); - char *u = IMMEDIATE(u_value); - return img_format("SAVE %s%s", u, + return img_format("SAVE 0x%" PRIx64 "%s", u_value, save_restore_list(encode_rt1_from_rt(rt1_value), count_value, 0)); } @@ -12707,8 +12550,7 @@ static char *SAVE_32_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3__s3(instruction); uint64 gp_value = extract_gp_2(instruction); - char *u = IMMEDIATE(u_value); - return img_format("SAVE %s%s", u, + return img_format("SAVE 0x%" PRIx64 "%s", u_value, save_restore_list(rt_value, count_value, gp_value)); } @@ -12728,10 +12570,8 @@ static char *SAVEF(uint64 instruction, Dis_info *info) uint64 count_value = extract_count_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3__s3(instruction); - char *u = IMMEDIATE(u_value); - char *count = IMMEDIATE(count_value); - return img_format("SAVEF %s, %s", u, count); + return img_format("SAVEF 0x%" PRIx64 ", 0x%" PRIx64, u_value, count_value); } @@ -12752,10 +12592,9 @@ static char *SB_16_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_1_0(instruction); const char *rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value)); - char *u = IMMEDIATE(u_value); const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); - return img_format("SB %s, %s(%s)", rtz3, u, rs3); + return img_format("SB %s, 0x%" PRIx64 "(%s)", rtz3, u_value, rs3); } @@ -12775,9 +12614,8 @@ static char *SB_GP_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_17_to_0(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); - return img_format("SB %s, %s($%d)", rt, u, 28); + return img_format("SB %s, 0x%" PRIx64 "($%d)", rt, u_value, 28); } @@ -12798,10 +12636,9 @@ static char *SB_S9_(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("SB %s, %s(%s)", rt, s, rs); + return img_format("SB %s, %s(%s)", rt, s_value, rs); } @@ -12822,10 +12659,9 @@ static char *SB_U12_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); const char *rs = GPR(rs_value); - return img_format("SB %s, %s(%s)", rt, u, rs); + return img_format("SB %s, 0x%" PRIx64 "(%s)", rt, u_value, rs); } @@ -12846,10 +12682,9 @@ static char *SBE(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("SBE %s, %s(%s)", rt, s, rs); + return img_format("SBE %s, %s(%s)", rt, s_value, rs); } @@ -12894,10 +12729,9 @@ static char *SC(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_s2(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("SC %s, %s(%s)", rt, s, rs); + return img_format("SC %s, %s(%s)", rt, s_value, rs); } @@ -12918,10 +12752,9 @@ static char *SCD(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_s3(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("SCD %s, %s(%s)", rt, s, rs); + return img_format("SCD %s, %s(%s)", rt, s_value, rs); } @@ -12966,10 +12799,9 @@ static char *SCE(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_s2(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("SCE %s, %s(%s)", rt, s, rs); + return img_format("SCE %s, %s(%s)", rt, s_value, rs); } @@ -13037,9 +12869,8 @@ static char *SD_GP_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_20_to_3__s3(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); - return img_format("SD %s, %s($%d)", rt, u, 28); + return img_format("SD %s, 0x%" PRIx64 "($%d)", rt, u_value, 28); } @@ -13060,10 +12891,9 @@ static char *SD_S9_(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("SD %s, %s(%s)", rt, s, rs); + return img_format("SD %s, %s(%s)", rt, s_value, rs); } @@ -13084,10 +12914,9 @@ static char *SD_U12_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); const char *rs = GPR(rs_value); - return img_format("SD %s, %s(%s)", rt, u, rs); + return img_format("SD %s, 0x%" PRIx64 "(%s)", rt, u_value, rs); } @@ -13105,9 +12934,8 @@ static char *SDBBP_16_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_2_1_0(instruction); - char *code = IMMEDIATE(code_value); - return img_format("SDBBP %s", code); + return img_format("SDBBP 0x%" PRIx64, code_value); } @@ -13125,9 +12953,8 @@ static char *SDBBP_32_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_18_to_0(instruction); - char *code = IMMEDIATE(code_value); - return img_format("SDBBP %s", code); + return img_format("SDBBP 0x%" PRIx64, code_value); } @@ -13147,9 +12974,8 @@ static char *SDC1_GP_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_17_to_2__s2(instruction); const char *ft = FPR(ft_value); - char *u = IMMEDIATE(u_value); - return img_format("SDC1 %s, %s($%d)", ft, u, 28); + return img_format("SDC1 %s, 0x%" PRIx64 "($%d)", ft, u_value, 28); } @@ -13170,10 +12996,9 @@ static char *SDC1_S9_(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); const char *ft = FPR(ft_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("SDC1 %s, %s(%s)", ft, s, rs); + return img_format("SDC1 %s, %s(%s)", ft, s_value, rs); } @@ -13194,10 +13019,9 @@ static char *SDC1_U12_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); const char *ft = FPR(ft_value); - char *u = IMMEDIATE(u_value); const char *rs = GPR(rs_value); - return img_format("SDC1 %s, %s(%s)", ft, u, rs); + return img_format("SDC1 %s, 0x%" PRIx64 "(%s)", ft, u_value, rs); } @@ -13266,10 +13090,9 @@ static char *SDC2(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); char *cs = CPR(cs_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("SDC2 %s, %s(%s)", cs, s, rs); + return img_format("SDC2 %s, %s(%s)", cs, s_value, rs); } @@ -13291,11 +13114,10 @@ static char *SDM(uint64 instruction, Dis_info *info) uint64 count3_value = extract_count3_14_13_12(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - char *count3 = IMMEDIATE(encode_count3_from_count(count3_value)); + uint64 count3 = encode_count3_from_count(count3_value); - return img_format("SDM %s, %s(%s), %s", rt, s, rs, count3); + return img_format("SDM %s, %s(%s), 0x%" PRIx64, rt, s_value, rs, count3); } @@ -13575,9 +13397,8 @@ static char *SEQI(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *u = IMMEDIATE(u_value); - return img_format("SEQI %s, %s, %s", rt, rs, u); + return img_format("SEQI %s, %s, 0x%" PRIx64, rt, rs, u_value); } @@ -13598,10 +13419,9 @@ static char *SH_16_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_2_1__s1(instruction); const char *rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value)); - char *u = IMMEDIATE(u_value); const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); - return img_format("SH %s, %s(%s)", rtz3, u, rs3); + return img_format("SH %s, 0x%" PRIx64 "(%s)", rtz3, u_value, rs3); } @@ -13621,9 +13441,8 @@ static char *SH_GP_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_17_to_1__s1(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); - return img_format("SH %s, %s($%d)", rt, u, 28); + return img_format("SH %s, 0x%" PRIx64 "($%d)", rt, u_value, 28); } @@ -13644,10 +13463,9 @@ static char *SH_S9_(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("SH %s, %s(%s)", rt, s, rs); + return img_format("SH %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -13668,10 +13486,9 @@ static char *SH_U12_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); const char *rs = GPR(rs_value); - return img_format("SH %s, %s(%s)", rt, u, rs); + return img_format("SH %s, 0x%" PRIx64 "(%s)", rt, u_value, rs); } @@ -13692,10 +13509,9 @@ static char *SHE(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("SHE %s, %s(%s)", rt, s, rs); + return img_format("SHE %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -13714,10 +13530,9 @@ static char *SHILO(uint64 instruction, Dis_info *info) int64 shift_value = extract_shift__se5_21_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - char *shift = IMMEDIATE(shift_value); const char *ac = AC(ac_value); - return img_format("SHILO %s, %s", ac, shift); + return img_format("SHILO %s, 0x%" PRIx64, ac, shift_value); } @@ -13761,9 +13576,8 @@ static char *SHLL_PH(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *sa = IMMEDIATE(sa_value); - return img_format("SHLL.PH %s, %s, %s", rt, rs, sa); + return img_format("SHLL.PH %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -13785,9 +13599,8 @@ static char *SHLL_QB(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *sa = IMMEDIATE(sa_value); - return img_format("SHLL.QB %s, %s, %s", rt, rs, sa); + return img_format("SHLL.QB %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -13810,9 +13623,8 @@ static char *SHLL_S_PH(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *sa = IMMEDIATE(sa_value); - return img_format("SHLL_S.PH %s, %s, %s", rt, rs, sa); + return img_format("SHLL_S.PH %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -13834,9 +13646,8 @@ static char *SHLL_S_W(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *sa = IMMEDIATE(sa_value); - return img_format("SHLL_S.W %s, %s, %s", rt, rs, sa); + return img_format("SHLL_S.W %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -13956,9 +13767,8 @@ static char *SHRA_PH(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *sa = IMMEDIATE(sa_value); - return img_format("SHRA.PH %s, %s, %s", rt, rs, sa); + return img_format("SHRA.PH %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -13980,9 +13790,8 @@ static char *SHRA_QB(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *sa = IMMEDIATE(sa_value); - return img_format("SHRA.QB %s, %s, %s", rt, rs, sa); + return img_format("SHRA.QB %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -14004,9 +13813,8 @@ static char *SHRA_R_PH(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *sa = IMMEDIATE(sa_value); - return img_format("SHRA_R.PH %s, %s, %s", rt, rs, sa); + return img_format("SHRA_R.PH %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -14028,9 +13836,8 @@ static char *SHRA_R_QB(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *sa = IMMEDIATE(sa_value); - return img_format("SHRA_R.QB %s, %s, %s", rt, rs, sa); + return img_format("SHRA_R.QB %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -14052,9 +13859,8 @@ static char *SHRA_R_W(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *sa = IMMEDIATE(sa_value); - return img_format("SHRA_R.W %s, %s, %s", rt, rs, sa); + return img_format("SHRA_R.W %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -14196,9 +14002,8 @@ static char *SHRL_PH(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *sa = IMMEDIATE(sa_value); - return img_format("SHRL.PH %s, %s, %s", rt, rs, sa); + return img_format("SHRL.PH %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -14220,9 +14025,8 @@ static char *SHRL_QB(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *sa = IMMEDIATE(sa_value); - return img_format("SHRL.QB %s, %s, %s", rt, rs, sa); + return img_format("SHRL.QB %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -14337,9 +14141,8 @@ static char *SIGRIE(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_18_to_0(instruction); - char *code = IMMEDIATE(code_value); - return img_format("SIGRIE %s", code); + return img_format("SIGRIE 0x%" PRIx64, code_value); } @@ -14361,9 +14164,9 @@ static char *SLL_16_(uint64 instruction, Dis_info *info) const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); - char *shift3 = IMMEDIATE(encode_shift3_from_shift(shift3_value)); + uint64 shift3 = encode_shift3_from_shift(shift3_value); - return img_format("SLL %s, %s, %s", rt3, rs3, shift3); + return img_format("SLL %s, %s, 0x%" PRIx64, rt3, rs3, shift3); } @@ -14385,9 +14188,8 @@ static char *SLL_32_(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *shift = IMMEDIATE(shift_value); - return img_format("SLL %s, %s, %s", rt, rs, shift); + return img_format("SLL %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -14457,9 +14259,8 @@ static char *SLTI(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *u = IMMEDIATE(u_value); - return img_format("SLTI %s, %s, %s", rt, rs, u); + return img_format("SLTI %s, %s, 0x%" PRIx64, rt, rs, u_value); } @@ -14481,9 +14282,8 @@ static char *SLTIU(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *u = IMMEDIATE(u_value); - return img_format("SLTIU %s, %s, %s", rt, rs, u); + return img_format("SLTIU %s, %s, 0x%" PRIx64, rt, rs, u_value); } @@ -14549,9 +14349,8 @@ static char *SPECIAL2(uint64 instruction, Dis_info *info) { uint64 op_value = extract_op_25_to_3(instruction); - char *op = IMMEDIATE(op_value); - return img_format("SPECIAL2 %s", op); + return img_format("SPECIAL2 0x%" PRIx64, op_value); } @@ -14617,9 +14416,8 @@ static char *SRA(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *shift = IMMEDIATE(shift_value); - return img_format("SRA %s, %s, %s", rt, rs, shift); + return img_format("SRA %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -14665,9 +14463,9 @@ static char *SRL_16_(uint64 instruction, Dis_info *info) const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); - char *shift3 = IMMEDIATE(encode_shift3_from_shift(shift3_value)); + uint64 shift3 = encode_shift3_from_shift(shift3_value); - return img_format("SRL %s, %s, %s", rt3, rs3, shift3); + return img_format("SRL %s, %s, 0x%" PRIx64, rt3, rs3, shift3); } @@ -14689,9 +14487,8 @@ static char *SRL_32_(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *shift = IMMEDIATE(shift_value); - return img_format("SRL %s, %s, %s", rt, rs, shift); + return img_format("SRL %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -15178,10 +14975,9 @@ static char *SW_16_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_3_2_1_0__s2(instruction); const char *rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value)); - char *u = IMMEDIATE(u_value); const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); - return img_format("SW %s, %s(%s)", rtz3, u, rs3); + return img_format("SW %s, 0x%" PRIx64 "(%s)", rtz3, u_value, rs3); } @@ -15202,10 +14998,9 @@ static char *SW_4X4_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_3_8__s2(instruction); const char *rtz4 = GPR(decode_gpr_gpr4_zero(rtz4_value)); - char *u = IMMEDIATE(u_value); const char *rs4 = GPR(decode_gpr_gpr4(rs4_value)); - return img_format("SW %s, %s(%s)", rtz4, u, rs4); + return img_format("SW %s, 0x%" PRIx64 "(%s)", rtz4, u_value, rs4); } @@ -15225,9 +15020,8 @@ static char *SW_GP16_(uint64 instruction, Dis_info *info) uint64 rtz3_value = extract_rtz3_9_8_7(instruction); const char *rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value)); - char *u = IMMEDIATE(u_value); - return img_format("SW %s, %s($%d)", rtz3, u, 28); + return img_format("SW %s, 0x%" PRIx64 "($%d)", rtz3, u_value, 28); } @@ -15247,9 +15041,8 @@ static char *SW_GP_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_20_to_2__s2(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); - return img_format("SW %s, %s($%d)", rt, u, 28); + return img_format("SW %s, 0x%" PRIx64 "($%d)", rt, u_value, 28); } @@ -15270,10 +15063,9 @@ static char *SW_S9_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("SW %s, %s(%s)", rt, s, rs); + return img_format("SW %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -15293,9 +15085,8 @@ static char *SW_SP_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_4_3_2_1_0__s2(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); - return img_format("SW %s, %s($%d)", rt, u, 29); + return img_format("SW %s, 0x%" PRIx64 "($%d)", rt, u_value, 29); } @@ -15316,10 +15107,9 @@ static char *SW_U12_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); const char *rt = GPR(rt_value); - char *u = IMMEDIATE(u_value); const char *rs = GPR(rs_value); - return img_format("SW %s, %s(%s)", rt, u, rs); + return img_format("SW %s, 0x%" PRIx64 "(%s)", rt, u_value, rs); } @@ -15339,9 +15129,8 @@ static char *SWC1_GP_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_17_to_2__s2(instruction); const char *ft = FPR(ft_value); - char *u = IMMEDIATE(u_value); - return img_format("SWC1 %s, %s($%d)", ft, u, 28); + return img_format("SWC1 %s, 0x%" PRIx64 "($%d)", ft, u_value, 28); } @@ -15362,10 +15151,9 @@ static char *SWC1_S9_(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); const char *ft = FPR(ft_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("SWC1 %s, %s(%s)", ft, s, rs); + return img_format("SWC1 %s, %" PRId64 "(%s)", ft, s_value, rs); } @@ -15386,10 +15174,9 @@ static char *SWC1_U12_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); const char *ft = FPR(ft_value); - char *u = IMMEDIATE(u_value); const char *rs = GPR(rs_value); - return img_format("SWC1 %s, %s(%s)", ft, u, rs); + return img_format("SWC1 %s, 0x%" PRIx64 "(%s)", ft, u_value, rs); } @@ -15458,10 +15245,9 @@ static char *SWC2(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); char *cs = CPR(cs_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("SWC2 %s, %s(%s)", cs, s, rs); + return img_format("SWC2 %s, %" PRId64 "(%s)", cs, s_value, rs); } @@ -15482,10 +15268,9 @@ static char *SWE(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("SWE %s, %s(%s)", rt, s, rs); + return img_format("SWE %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -15507,11 +15292,11 @@ static char *SWM(uint64 instruction, Dis_info *info) uint64 count3_value = extract_count3_14_13_12(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - char *count3 = IMMEDIATE(encode_count3_from_count(count3_value)); + uint64 count3 = encode_count3_from_count(count3_value); - return img_format("SWM %s, %s(%s), %s", rt, s, rs, count3); + return img_format("SWM %s, %" PRId64 "(%s), 0x%" PRIx64, + rt, s_value, rs, count3); } @@ -15599,9 +15384,8 @@ static char *SYNC(uint64 instruction, Dis_info *info) { uint64 stype_value = extract_stype_20_19_18_17_16(instruction); - char *stype = IMMEDIATE(stype_value); - return img_format("SYNC %s", stype); + return img_format("SYNC 0x%" PRIx64, stype_value); } @@ -15620,10 +15404,9 @@ static char *SYNCI(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("SYNCI %s(%s)", s, rs); + return img_format("SYNCI %" PRId64 "(%s)", s_value, rs); } @@ -15642,10 +15425,9 @@ static char *SYNCIE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("SYNCIE %s(%s)", s, rs); + return img_format("SYNCIE %" PRId64 "(%s)", s_value, rs); } @@ -15663,9 +15445,8 @@ static char *SYSCALL_16_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_1_0(instruction); - char *code = IMMEDIATE(code_value); - return img_format("SYSCALL %s", code); + return img_format("SYSCALL 0x%" PRIx64, code_value); } @@ -15681,9 +15462,8 @@ static char *SYSCALL_32_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_17_to_0(instruction); - char *code = IMMEDIATE(code_value); - return img_format("SYSCALL %s", code); + return img_format("SYSCALL 0x%" PRIx64, code_value); } @@ -16053,11 +15833,11 @@ static char *UALDM(uint64 instruction, Dis_info *info) uint64 count3_value = extract_count3_14_13_12(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - char *count3 = IMMEDIATE(encode_count3_from_count(count3_value)); + uint64 count3 = encode_count3_from_count(count3_value); - return img_format("UALDM %s, %s(%s), %s", rt, s, rs, count3); + return img_format("UALDM %s, %" PRId64 "(%s), 0x%" PRIx64, + rt, s_value, rs, count3); } @@ -16078,10 +15858,9 @@ static char *UALH(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("UALH %s, %s(%s)", rt, s, rs); + return img_format("UALH %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -16103,11 +15882,11 @@ static char *UALWM(uint64 instruction, Dis_info *info) uint64 count3_value = extract_count3_14_13_12(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - char *count3 = IMMEDIATE(encode_count3_from_count(count3_value)); + uint64 count3 = encode_count3_from_count(count3_value); - return img_format("UALWM %s, %s(%s), %s", rt, s, rs, count3); + return img_format("UALWM %s, %" PRId64 "(%s), 0x%" PRIx64, + rt, s_value, rs, count3); } @@ -16129,11 +15908,11 @@ static char *UASDM(uint64 instruction, Dis_info *info) uint64 count3_value = extract_count3_14_13_12(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - char *count3 = IMMEDIATE(encode_count3_from_count(count3_value)); + uint64 count3 = encode_count3_from_count(count3_value); - return img_format("UASDM %s, %s(%s), %s", rt, s, rs, count3); + return img_format("UASDM %s, %" PRId64 "(%s), 0x%" PRIx64, + rt, s_value, rs, count3); } @@ -16154,10 +15933,9 @@ static char *UASH(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - return img_format("UASH %s, %s(%s)", rt, s, rs); + return img_format("UASH %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -16179,11 +15957,11 @@ static char *UASWM(uint64 instruction, Dis_info *info) uint64 count3_value = extract_count3_14_13_12(instruction); const char *rt = GPR(rt_value); - char *s = IMMEDIATE(s_value); const char *rs = GPR(rs_value); - char *count3 = IMMEDIATE(encode_count3_from_count(count3_value)); + uint64 count3 = encode_count3_from_count(count3_value); - return img_format("UASWM %s, %s(%s), %s", rt, s, rs, count3); + return img_format("UASWM %s, %" PRId64 "(%s), 0x%" PRIx64, + rt, s_value, rs, count3); } @@ -16201,9 +15979,8 @@ static char *UDI(uint64 instruction, Dis_info *info) { uint64 op_value = extract_op_25_to_3(instruction); - char *op = IMMEDIATE(op_value); - return img_format("UDI %s", op); + return img_format("UDI 0x%" PRIx64, op_value); } @@ -16219,9 +15996,8 @@ static char *WAIT(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_25_24_23_22_21_20_19_18_17_16(instruction); - char *code = IMMEDIATE(code_value); - return img_format("WAIT %s", code); + return img_format("WAIT 0x%" PRIx64, code_value); } @@ -16241,9 +16017,8 @@ static char *WRDSP(uint64 instruction, Dis_info *info) uint64 mask_value = extract_mask_20_19_18_17_16_15_14(instruction); const char *rt = GPR(rt_value); - char *mask = IMMEDIATE(mask_value); - return img_format("WRDSP %s, %s", rt, mask); + return img_format("WRDSP %s, 0x%" PRIx64, rt, mask_value); } @@ -16333,9 +16108,8 @@ static char *XORI(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value); const char *rs = GPR(rs_value); - char *u = IMMEDIATE(u_value); - return img_format("XORI %s, %s, %s", rt, rs, u); + return img_format("XORI %s, %s, 0x%" PRIx64, rt, rs, u_value); } From 043dc73cbc6e9c24c061966cd40fa3c9a702b004 Mon Sep 17 00:00:00 2001 From: Milica Lazarevic Date: Mon, 12 Sep 2022 14:26:28 +0200 Subject: [PATCH 438/705] disas/nanomips: Remove CPR function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CPR functions has been removed. Before this patch, we'd been calling img_format twice, the first time through the CPR function to get an appropriate string and the second time to print that formatted string. There's no more need for that. Therefore, calls to CPR are removed, and now we're directly printing "CP" and integer value instead. Signed-off-by: Milica Lazarevic Reviewed-by: Richard Henderson Message-Id: <20220912122635.74032-18-milica.lazarevic@syrmia.com> Signed-off-by: Philippe Mathieu-Daudé --- disas/nanomips.cpp | 110 +++++++++++++++++++-------------------------- 1 file changed, 45 insertions(+), 65 deletions(-) diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp index 3b1ca249ce..3a3a9a9b69 100644 --- a/disas/nanomips.cpp +++ b/disas/nanomips.cpp @@ -519,13 +519,6 @@ static const char *AC(uint64 reg) } -static char *CPR(uint64 reg) -{ - /* needs more work */ - return img_format("CP%" PRIu64, reg); -} - - static char *ADDRESS(uint64 value, int instruction_size, Dis_info *info) { /* token for string replace */ @@ -2774,10 +2767,9 @@ static char *BC2EQZC(uint64 instruction, Dis_info *info) uint64 ct_value = extract_ct_25_24_23_22_21(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - char *ct = CPR(ct_value); char *s = ADDRESS(s_value, 4, info); - return img_format("BC2EQZC %s, %s", ct, s); + return img_format("BC2EQZC CP%" PRIu64 ", %s", ct_value, s); } @@ -2796,10 +2788,9 @@ static char *BC2NEZC(uint64 instruction, Dis_info *info) uint64 ct_value = extract_ct_25_24_23_22_21(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - char *ct = CPR(ct_value); char *s = ADDRESS(s_value, 4, info); - return img_format("BC2NEZC %s, %s", ct, s); + return img_format("BC2NEZC CP%" PRIu64 ", %s", ct_value, s); } @@ -3403,9 +3394,8 @@ static char *CFC1(uint64 instruction, Dis_info *info) uint64 cs_value = extract_cs_20_19_18_17_16(instruction); const char *rt = GPR(rt_value); - char *cs = CPR(cs_value); - return img_format("CFC1 %s, %s", rt, cs); + return img_format("CFC1 %s, CP%" PRIu64, rt, cs_value); } @@ -3425,9 +3415,8 @@ static char *CFC2(uint64 instruction, Dis_info *info) uint64 cs_value = extract_cs_20_19_18_17_16(instruction); const char *rt = GPR(rt_value); - char *cs = CPR(cs_value); - return img_format("CFC2 %s, %s", rt, cs); + return img_format("CFC2 %s, CP%" PRIu64, rt, cs_value); } @@ -4889,9 +4878,8 @@ static char *CTC1(uint64 instruction, Dis_info *info) uint64 cs_value = extract_cs_20_19_18_17_16(instruction); const char *rt = GPR(rt_value); - char *cs = CPR(cs_value); - return img_format("CTC1 %s, %s", rt, cs); + return img_format("CTC1 %s, CP%" PRIu64, rt, cs_value); } @@ -4911,9 +4899,8 @@ static char *CTC2(uint64 instruction, Dis_info *info) uint64 cs_value = extract_cs_20_19_18_17_16(instruction); const char *rt = GPR(rt_value); - char *cs = CPR(cs_value); - return img_format("CTC2 %s, %s", rt, cs); + return img_format("CTC2 %s, CP%" PRIu64, rt, cs_value); } @@ -5745,9 +5732,9 @@ static char *DMFC0(uint64 instruction, Dis_info *info) uint64 sel_value = extract_sel_15_14_13_12_11(instruction); const char *rt = GPR(rt_value); - char *c0s = CPR(c0s_value); - return img_format("DMFC0 %s, %s, 0x%" PRIx64, rt, c0s, sel_value); + return img_format("DMFC0 %s, CP%" PRIu64 ", 0x%" PRIx64, + rt, c0s_value, sel_value); } @@ -5789,9 +5776,8 @@ static char *DMFC2(uint64 instruction, Dis_info *info) uint64 cs_value = extract_cs_20_19_18_17_16(instruction); const char *rt = GPR(rt_value); - char *cs = CPR(cs_value); - return img_format("DMFC2 %s, %s", rt, cs); + return img_format("DMFC2 %s, CP%" PRIu64, rt, cs_value); } @@ -5812,9 +5798,9 @@ static char *DMFGC0(uint64 instruction, Dis_info *info) uint64 sel_value = extract_sel_15_14_13_12_11(instruction); const char *rt = GPR(rt_value); - char *c0s = CPR(c0s_value); - return img_format("DMFGC0 %s, %s, 0x%" PRIx64, rt, c0s, sel_value); + return img_format("DMFGC0 %s, CP%" PRIu64 ", 0x%" PRIx64, + rt, c0s_value, sel_value); } @@ -5883,9 +5869,9 @@ static char *DMTC0(uint64 instruction, Dis_info *info) uint64 sel_value = extract_sel_15_14_13_12_11(instruction); const char *rt = GPR(rt_value); - char *c0s = CPR(c0s_value); - return img_format("DMTC0 %s, %s, 0x%" PRIx64, rt, c0s, sel_value); + return img_format("DMTC0 %s, CP%" PRIu64 ", 0x%" PRIx64, + rt, c0s_value, sel_value); } @@ -5927,9 +5913,8 @@ static char *DMTC2(uint64 instruction, Dis_info *info) uint64 cs_value = extract_cs_20_19_18_17_16(instruction); const char *rt = GPR(rt_value); - char *cs = CPR(cs_value); - return img_format("DMTC2 %s, %s", rt, cs); + return img_format("DMTC2 %s, CP%" PRIu64, rt, cs_value); } @@ -5950,9 +5935,9 @@ static char *DMTGC0(uint64 instruction, Dis_info *info) uint64 sel_value = extract_sel_15_14_13_12_11(instruction); const char *rt = GPR(rt_value); - char *c0s = CPR(c0s_value); - return img_format("DMTGC0 %s, %s, 0x%" PRIx64, rt, c0s, sel_value); + return img_format("DMTGC0 %s, CP%" PRIu64 ", 0x%" PRIx64, + rt, c0s_value, sel_value); } @@ -8148,10 +8133,10 @@ static char *LDC2(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - char *ct = CPR(ct_value); const char *rs = GPR(rs_value); - return img_format("LDC2 %s, %" PRId64 "(%s)", ct, s_value, rs); + return img_format("LDC2 CP%" PRIu64 ", %" PRId64 "(%s)", + ct_value, s_value, rs); } @@ -9089,10 +9074,10 @@ static char *LWC2(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - char *ct = CPR(ct_value); const char *rs = GPR(rs_value); - return img_format("LWC2 %s, %" PRId64 "(%s)", ct, s_value, rs); + return img_format("LWC2 CP%" PRIu64 ", %" PRId64 "(%s)", + ct_value, s_value, rs); } @@ -9665,9 +9650,9 @@ static char *MFC0(uint64 instruction, Dis_info *info) uint64 sel_value = extract_sel_15_14_13_12_11(instruction); const char *rt = GPR(rt_value); - char *c0s = CPR(c0s_value); - return img_format("MFC0 %s, %s, 0x%" PRIx64, rt, c0s, sel_value); + return img_format("MFC0 %s, CP%" PRIu64 ", 0x%" PRIx64, + rt, c0s_value, sel_value); } @@ -9709,9 +9694,8 @@ static char *MFC2(uint64 instruction, Dis_info *info) uint64 cs_value = extract_cs_20_19_18_17_16(instruction); const char *rt = GPR(rt_value); - char *cs = CPR(cs_value); - return img_format("MFC2 %s, %s", rt, cs); + return img_format("MFC2 %s, CP%" PRIu64, rt, cs_value); } @@ -9732,9 +9716,9 @@ static char *MFGC0(uint64 instruction, Dis_info *info) uint64 sel_value = extract_sel_15_14_13_12_11(instruction); const char *rt = GPR(rt_value); - char *c0s = CPR(c0s_value); - return img_format("MFGC0 %s, %s, 0x%" PRIx64, rt, c0s, sel_value); + return img_format("MFGC0 %s, CP%" PRIu64 ", 0x%" PRIx64, + rt, c0s_value, sel_value); } @@ -9755,9 +9739,9 @@ static char *MFHC0(uint64 instruction, Dis_info *info) uint64 sel_value = extract_sel_15_14_13_12_11(instruction); const char *rt = GPR(rt_value); - char *c0s = CPR(c0s_value); - return img_format("MFHC0 %s, %s, 0x%" PRIx64, rt, c0s, sel_value); + return img_format("MFHC0 %s, CP%" PRIu64 ", 0x%" PRIx64, + rt, c0s_value, sel_value); } @@ -9799,9 +9783,8 @@ static char *MFHC2(uint64 instruction, Dis_info *info) uint64 cs_value = extract_cs_20_19_18_17_16(instruction); const char *rt = GPR(rt_value); - char *cs = CPR(cs_value); - return img_format("MFHC2 %s, %s", rt, cs); + return img_format("MFHC2 %s, CP%" PRIu64, rt, cs_value); } @@ -9822,9 +9805,9 @@ static char *MFHGC0(uint64 instruction, Dis_info *info) uint64 sel_value = extract_sel_15_14_13_12_11(instruction); const char *rt = GPR(rt_value); - char *c0s = CPR(c0s_value); - return img_format("MFHGC0 %s, %s, 0x%" PRIx64, rt, c0s, sel_value); + return img_format("MFHGC0 %s, CP%" PRIu64 ", 0x%" PRIx64, + rt, c0s_value, sel_value); } @@ -10391,9 +10374,9 @@ static char *MTC0(uint64 instruction, Dis_info *info) uint64 sel_value = extract_sel_15_14_13_12_11(instruction); const char *rt = GPR(rt_value); - char *c0s = CPR(c0s_value); - return img_format("MTC0 %s, %s, 0x%" PRIx64, rt, c0s, sel_value); + return img_format("MTC0 %s, CP%" PRIu64 ", 0x%" PRIx64, + rt, c0s_value, sel_value); } @@ -10435,9 +10418,8 @@ static char *MTC2(uint64 instruction, Dis_info *info) uint64 cs_value = extract_cs_20_19_18_17_16(instruction); const char *rt = GPR(rt_value); - char *cs = CPR(cs_value); - return img_format("MTC2 %s, %s", rt, cs); + return img_format("MTC2 %s, CP%" PRIu64, rt, cs_value); } @@ -10458,9 +10440,9 @@ static char *MTGC0(uint64 instruction, Dis_info *info) uint64 sel_value = extract_sel_15_14_13_12_11(instruction); const char *rt = GPR(rt_value); - char *c0s = CPR(c0s_value); - return img_format("MTGC0 %s, %s, 0x%" PRIx64, rt, c0s, sel_value); + return img_format("MTGC0 %s, CP%" PRIu64 ", 0x%" PRIx64, + rt, c0s_value, sel_value); } @@ -10481,9 +10463,9 @@ static char *MTHC0(uint64 instruction, Dis_info *info) uint64 sel_value = extract_sel_15_14_13_12_11(instruction); const char *rt = GPR(rt_value); - char *c0s = CPR(c0s_value); - return img_format("MTHC0 %s, %s, 0x%" PRIx64, rt, c0s, sel_value); + return img_format("MTHC0 %s, CP%" PRIu64 ", 0x%" PRIx64, + rt, c0s_value, sel_value); } @@ -10525,9 +10507,8 @@ static char *MTHC2(uint64 instruction, Dis_info *info) uint64 cs_value = extract_cs_20_19_18_17_16(instruction); const char *rt = GPR(rt_value); - char *cs = CPR(cs_value); - return img_format("MTHC2 %s, %s", rt, cs); + return img_format("MTHC2 %s, CP%" PRIu64, rt, cs_value); } @@ -10548,9 +10529,9 @@ static char *MTHGC0(uint64 instruction, Dis_info *info) uint64 sel_value = extract_sel_15_14_13_12_11(instruction); const char *rt = GPR(rt_value); - char *c0s = CPR(c0s_value); - return img_format("MTHGC0 %s, %s, 0x%" PRIx64, rt, c0s, sel_value); + return img_format("MTHGC0 %s, CP%" PRIu64 ", 0x%" PRIx64, + rt, c0s_value, sel_value); } @@ -12021,9 +12002,9 @@ static char *RDHWR(uint64 instruction, Dis_info *info) uint64 sel_value = extract_sel_13_12_11(instruction); const char *rt = GPR(rt_value); - char *hs = CPR(hs_value); - return img_format("RDHWR %s, %s, 0x%" PRIx64, rt, hs, sel_value); + return img_format("RDHWR %s, CP%" PRIu64 ", 0x%" PRIx64, + rt, hs_value, sel_value); } @@ -13089,10 +13070,9 @@ static char *SDC2(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - char *cs = CPR(cs_value); const char *rs = GPR(rs_value); - return img_format("SDC2 %s, %s(%s)", cs, s_value, rs); + return img_format("SDC2 CP%" PRIu64 ", %s(%s)", cs_value, s_value, rs); } @@ -15244,10 +15224,10 @@ static char *SWC2(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - char *cs = CPR(cs_value); const char *rs = GPR(rs_value); - return img_format("SWC2 %s, %" PRId64 "(%s)", cs, s_value, rs); + return img_format("SWC2 CP%" PRIu64 ", %" PRId64 "(%s)", + cs_value, s_value, rs); } From 22e7b52acd8ffd10478167652b291db11c9c047d Mon Sep 17 00:00:00 2001 From: Milica Lazarevic Date: Mon, 12 Sep 2022 14:26:29 +0200 Subject: [PATCH 439/705] disas/nanomips: Prevent memory leaking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit g_autofree attribute is added for every dynamically allocated string to prevent memory leaking. The implementation of the several functions that work with dynamically allocated strings is slightly changed so we can add those attributes. Signed-off-by: Milica Lazarevic Reviewed-by: Richard Henderson Message-Id: <20220912122635.74032-19-milica.lazarevic@syrmia.com> Signed-off-by: Philippe Mathieu-Daudé --- disas/nanomips.cpp | 96 ++++++++++++++++++++++++---------------------- 1 file changed, 51 insertions(+), 45 deletions(-) diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp index 3a3a9a9b69..ce93fdad62 100644 --- a/disas/nanomips.cpp +++ b/disas/nanomips.cpp @@ -1937,7 +1937,7 @@ static char *ADDIUPC_32_(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se21_0_20_to_1_s1(instruction); const char *rt = GPR(rt_value); - char *s = ADDRESS(s_value, 4, info); + g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("ADDIUPC %s, %s", rt, s); } @@ -1959,7 +1959,7 @@ static char *ADDIUPC_48_(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); const char *rt = GPR(rt_value); - char *s = ADDRESS(s_value, 6, info); + g_autofree char *s = ADDRESS(s_value, 6, info); return img_format("ADDIUPC %s, %s", rt, s); } @@ -2417,7 +2417,7 @@ static char *ALUIPC(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se31_0_11_to_2_20_to_12_s12(instruction); const char *rt = GPR(rt_value); - char *s = ADDRESS(s_value, 4, info); + g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("ALUIPC %s, %%pcrel_hi(%s)", rt, s); } @@ -2574,7 +2574,7 @@ static char *BALC_16_(uint64 instruction, Dis_info *info) { int64 s_value = extract_s__se10_0_9_8_7_6_5_4_3_2_1_s1(instruction); - char *s = ADDRESS(s_value, 2, info); + g_autofree char *s = ADDRESS(s_value, 2, info); return img_format("BALC %s", s); } @@ -2594,7 +2594,7 @@ static char *BALC_32_(uint64 instruction, Dis_info *info) { int64 s_value = extract_s__se25_0_24_to_1_s1(instruction); - char *s = ADDRESS(s_value, 4, info); + g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BALC %s", s); } @@ -2639,7 +2639,7 @@ static char *BBEQZC(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); const char *rt = GPR(rt_value); - char *s = ADDRESS(s_value, 4, info); + g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BBEQZC %s, 0x%" PRIx64 ", %s", rt, bit_value, s); } @@ -2662,7 +2662,7 @@ static char *BBNEZC(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); const char *rt = GPR(rt_value); - char *s = ADDRESS(s_value, 4, info); + g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BBNEZC %s, 0x%" PRIx64 ", %s", rt, bit_value, s); } @@ -2682,7 +2682,7 @@ static char *BC_16_(uint64 instruction, Dis_info *info) { int64 s_value = extract_s__se10_0_9_8_7_6_5_4_3_2_1_s1(instruction); - char *s = ADDRESS(s_value, 2, info); + g_autofree char *s = ADDRESS(s_value, 2, info); return img_format("BC %s", s); } @@ -2702,7 +2702,7 @@ static char *BC_32_(uint64 instruction, Dis_info *info) { int64 s_value = extract_s__se25_0_24_to_1_s1(instruction); - char *s = ADDRESS(s_value, 4, info); + g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BC %s", s); } @@ -2724,7 +2724,7 @@ static char *BC1EQZC(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); const char *ft = FPR(ft_value); - char *s = ADDRESS(s_value, 4, info); + g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BC1EQZC %s, %s", ft, s); } @@ -2746,7 +2746,7 @@ static char *BC1NEZC(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); const char *ft = FPR(ft_value); - char *s = ADDRESS(s_value, 4, info); + g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BC1NEZC %s, %s", ft, s); } @@ -2767,7 +2767,7 @@ static char *BC2EQZC(uint64 instruction, Dis_info *info) uint64 ct_value = extract_ct_25_24_23_22_21(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - char *s = ADDRESS(s_value, 4, info); + g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BC2EQZC CP%" PRIu64 ", %s", ct_value, s); } @@ -2788,7 +2788,7 @@ static char *BC2NEZC(uint64 instruction, Dis_info *info) uint64 ct_value = extract_ct_25_24_23_22_21(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - char *s = ADDRESS(s_value, 4, info); + g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BC2NEZC CP%" PRIu64 ", %s", ct_value, s); } @@ -2812,7 +2812,7 @@ static char *BEQC_16_(uint64 instruction, Dis_info *info) const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); - char *u = ADDRESS(u_value, 2, info); + g_autofree char *u = ADDRESS(u_value, 2, info); return img_format("BEQC %s, %s, %s", rs3, rt3, u); } @@ -2836,7 +2836,7 @@ static char *BEQC_32_(uint64 instruction, Dis_info *info) const char *rs = GPR(rs_value); const char *rt = GPR(rt_value); - char *s = ADDRESS(s_value, 4, info); + g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BEQC %s, %s, %s", rs, rt, s); } @@ -2859,7 +2859,7 @@ static char *BEQIC(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); const char *rt = GPR(rt_value); - char *s = ADDRESS(s_value, 4, info); + g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BEQIC %s, 0x%" PRIx64 ", %s", rt, u_value, s); } @@ -2881,7 +2881,7 @@ static char *BEQZC_16_(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se7_0_6_5_4_3_2_1_s1(instruction); const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); - char *s = ADDRESS(s_value, 2, info); + g_autofree char *s = ADDRESS(s_value, 2, info); return img_format("BEQZC %s, %s", rt3, s); } @@ -2905,7 +2905,7 @@ static char *BGEC(uint64 instruction, Dis_info *info) const char *rs = GPR(rs_value); const char *rt = GPR(rt_value); - char *s = ADDRESS(s_value, 4, info); + g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BGEC %s, %s, %s", rs, rt, s); } @@ -2928,7 +2928,7 @@ static char *BGEIC(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); const char *rt = GPR(rt_value); - char *s = ADDRESS(s_value, 4, info); + g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BGEIC %s, 0x%" PRIx64 ", %s", rt, u_value, s); } @@ -2951,7 +2951,7 @@ static char *BGEIUC(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); const char *rt = GPR(rt_value); - char *s = ADDRESS(s_value, 4, info); + g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BGEIUC %s, 0x%" PRIx64 ", %s", rt, u_value, s); } @@ -2975,7 +2975,7 @@ static char *BGEUC(uint64 instruction, Dis_info *info) const char *rs = GPR(rs_value); const char *rt = GPR(rt_value); - char *s = ADDRESS(s_value, 4, info); + g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BGEUC %s, %s, %s", rs, rt, s); } @@ -2999,7 +2999,7 @@ static char *BLTC(uint64 instruction, Dis_info *info) const char *rs = GPR(rs_value); const char *rt = GPR(rt_value); - char *s = ADDRESS(s_value, 4, info); + g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BLTC %s, %s, %s", rs, rt, s); } @@ -3022,7 +3022,7 @@ static char *BLTIC(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); const char *rt = GPR(rt_value); - char *s = ADDRESS(s_value, 4, info); + g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BLTIC %s, 0x%" PRIx64 ", %s", rt, u_value, s); } @@ -3045,7 +3045,7 @@ static char *BLTIUC(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); const char *rt = GPR(rt_value); - char *s = ADDRESS(s_value, 4, info); + g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BLTIUC %s, 0x%" PRIx64 ", %s", rt, u_value, s); } @@ -3069,7 +3069,7 @@ static char *BLTUC(uint64 instruction, Dis_info *info) const char *rs = GPR(rs_value); const char *rt = GPR(rt_value); - char *s = ADDRESS(s_value, 4, info); + g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BLTUC %s, %s, %s", rs, rt, s); } @@ -3093,7 +3093,7 @@ static char *BNEC_16_(uint64 instruction, Dis_info *info) const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); - char *u = ADDRESS(u_value, 2, info); + g_autofree char *u = ADDRESS(u_value, 2, info); return img_format("BNEC %s, %s, %s", rs3, rt3, u); } @@ -3117,7 +3117,7 @@ static char *BNEC_32_(uint64 instruction, Dis_info *info) const char *rs = GPR(rs_value); const char *rt = GPR(rt_value); - char *s = ADDRESS(s_value, 4, info); + g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BNEC %s, %s, %s", rs, rt, s); } @@ -3140,7 +3140,7 @@ static char *BNEIC(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); const char *rt = GPR(rt_value); - char *s = ADDRESS(s_value, 4, info); + g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BNEIC %s, 0x%" PRIx64 ", %s", rt, u_value, s); } @@ -3162,7 +3162,7 @@ static char *BNEZC_16_(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se7_0_6_5_4_3_2_1_s1(instruction); const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); - char *s = ADDRESS(s_value, 2, info); + g_autofree char *s = ADDRESS(s_value, 2, info); return img_format("BNEZC %s, %s", rt3, s); } @@ -3182,7 +3182,7 @@ static char *BPOSGE32C(uint64 instruction, Dis_info *info) { int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - char *s = ADDRESS(s_value, 4, info); + g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BPOSGE32C %s", s); } @@ -8182,7 +8182,7 @@ static char *LDPC_48_(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); const char *rt = GPR(rt_value); - char *s = ADDRESS(s_value, 6, info); + g_autofree char *s = ADDRESS(s_value, 6, info); return img_format("LDPC %s, %s", rt, s); } @@ -9146,7 +9146,7 @@ static char *LWPC_48_(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); const char *rt = GPR(rt_value); - char *s = ADDRESS(s_value, 6, info); + g_autofree char *s = ADDRESS(s_value, 6, info); return img_format("LWPC %s, %s", rt, s); } @@ -10131,7 +10131,7 @@ static char *MOVE_BALC(uint64 instruction, Dis_info *info) const char *rd1 = GPR(decode_gpr_gpr1(rd1_value)); const char *rtz4 = GPR(decode_gpr_gpr4_zero(rtz4_value)); - char *s = ADDRESS(s_value, 4, info); + g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("MOVE.BALC %s, %s, %s", rd1, rtz4, s); } @@ -12176,8 +12176,9 @@ static char *RESTORE_32_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3__s3(instruction); uint64 gp_value = extract_gp_2(instruction); - return img_format("RESTORE 0x%" PRIx64 "%s", u_value, - save_restore_list(rt_value, count_value, gp_value)); + g_autofree char *save_restore_str = save_restore_list( + rt_value, count_value, gp_value); + return img_format("RESTORE 0x%" PRIx64 "%s", u_value, save_restore_str); } @@ -12197,8 +12198,9 @@ static char *RESTORE_JRC_16_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_7_6_5_4__s4(instruction); uint64 count_value = extract_count_3_2_1_0(instruction); - return img_format("RESTORE.JRC 0x%" PRIx64 "%s", u_value, - save_restore_list(encode_rt1_from_rt(rt1_value), count_value, 0)); + g_autofree char *save_restore_str = save_restore_list( + encode_rt1_from_rt(rt1_value), count_value, 0); + return img_format("RESTORE.JRC 0x%" PRIx64 "%s", u_value, save_restore_str); } @@ -12219,8 +12221,10 @@ static char *RESTORE_JRC_32_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3__s3(instruction); uint64 gp_value = extract_gp_2(instruction); + g_autofree char *save_restore_str = save_restore_list( + rt_value, count_value, gp_value); return img_format("RESTORE.JRC 0x%" PRIx64 "%s", u_value, - save_restore_list(rt_value, count_value, gp_value)); + save_restore_str); } @@ -12509,8 +12513,9 @@ static char *SAVE_16_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_7_6_5_4__s4(instruction); uint64 count_value = extract_count_3_2_1_0(instruction); - return img_format("SAVE 0x%" PRIx64 "%s", u_value, - save_restore_list(encode_rt1_from_rt(rt1_value), count_value, 0)); + g_autofree char *save_restore_str = save_restore_list( + encode_rt1_from_rt(rt1_value), count_value, 0); + return img_format("SAVE 0x%" PRIx64 "%s", u_value, save_restore_str); } @@ -12531,8 +12536,9 @@ static char *SAVE_32_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3__s3(instruction); uint64 gp_value = extract_gp_2(instruction); - return img_format("SAVE 0x%" PRIx64 "%s", u_value, - save_restore_list(rt_value, count_value, gp_value)); + g_autofree char *save_restore_str = save_restore_list( + rt_value, count_value, gp_value); + return img_format("SAVE 0x%" PRIx64 "%s", u_value, save_restore_str); } @@ -13117,7 +13123,7 @@ static char *SDPC_48_(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); const char *rt = GPR(rt_value); - char *s = ADDRESS(s_value, 6, info); + g_autofree char *s = ADDRESS(s_value, 6, info); return img_format("SDPC %s, %s", rt, s); } @@ -15296,7 +15302,7 @@ static char *SWPC_48_(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); const char *rt = GPR(rt_value); - char *s = ADDRESS(s_value, 6, info); + g_autofree char *s = ADDRESS(s_value, 6, info); return img_format("SWPC %s, %s", rt, s); } @@ -21935,7 +21941,7 @@ int print_insn_nanomips(bfd_vma memaddr, struct disassemble_info *info) int status; bfd_byte buffer[2]; uint16_t insn1 = 0, insn2 = 0, insn3 = 0; - char *buf = NULL; + g_autofree char *buf = NULL; info->bytes_per_chunk = 2; info->display_endian = info->endian; From 49ec1c98a3992952836a08b797902b9d49ae4b9d Mon Sep 17 00:00:00 2001 From: Milica Lazarevic Date: Mon, 12 Sep 2022 14:26:30 +0200 Subject: [PATCH 440/705] disas/nanomips: Remove function overloading MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Disassemble function that calls the other variant of it is deleted. Where it is called, now we're directly calling the other implementation. Signed-off-by: Milica Lazarevic Reviewed-by: Richard Henderson Message-Id: <20220912122635.74032-20-milica.lazarevic@syrmia.com> Signed-off-by: Philippe Mathieu-Daudé --- disas/nanomips.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp index ce93fdad62..85f5784770 100644 --- a/disas/nanomips.cpp +++ b/disas/nanomips.cpp @@ -21917,12 +21917,6 @@ static const Pool MAJOR[2] = { 0x0 }, /* P16 */ }; -static int Disassemble(const uint16 *data, char **dis, - TABLE_ENTRY_TYPE & type, Dis_info *info) -{ - return Disassemble(data, dis, type, MAJOR, 2, info); -} - static int nanomips_dis(char **buf, Dis_info *info, unsigned short one, @@ -21932,7 +21926,7 @@ static int nanomips_dis(char **buf, uint16 bits[3] = {one, two, three}; TABLE_ENTRY_TYPE type; - int size = Disassemble(bits, buf, type, info); + int size = Disassemble(bits, buf, type, MAJOR, 2, info); return size; } From 3f2aec0778853afe190114bc6f1d18ab0239da09 Mon Sep 17 00:00:00 2001 From: Milica Lazarevic Date: Mon, 12 Sep 2022 14:26:31 +0200 Subject: [PATCH 441/705] disas/nanomips: Expand Dis_info struct MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch expands the Dis_info struct, which should hold the necessary data for handling runtime errors. Fields fprintf_func and stream are in charge of error printing. Field buf enables the use of sigsetjmp() and siglongjmp() functions. Support for runtime error handling will be added later. We're filling Dis_info at the entrance of the nanoMIPS disassembler, i.e. print_insn_nanomips. Next, we're adding that information as an argument wherever we need to. Signed-off-by: Milica Lazarevic Reviewed-by: Richard Henderson Message-Id: <20220912122635.74032-21-milica.lazarevic@syrmia.com> Signed-off-by: Philippe Mathieu-Daudé --- disas/nanomips.cpp | 2708 ++++++++++++++++++++++---------------------- 1 file changed, 1357 insertions(+), 1351 deletions(-) diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp index 85f5784770..73329462ee 100644 --- a/disas/nanomips.cpp +++ b/disas/nanomips.cpp @@ -72,6 +72,9 @@ enum TABLE_ATTRIBUTE_TYPE { typedef struct Dis_info { img_address m_pc; + fprintf_function fprintf_func; + FILE *stream; + sigjmp_buf buf; } Dis_info; typedef bool (*conditional_function)(uint64 instruction); @@ -124,7 +127,7 @@ static int64 sign_extend(int64 data, int msb) static uint64 renumber_registers(uint64 index, uint64 *register_list, - size_t register_list_size) + size_t register_list_size, Dis_info *info) { if (index < register_list_size) { return register_list[index]; @@ -163,12 +166,12 @@ static uint64 renumber_registers(uint64 index, uint64 *register_list, * - MUL[4X4] * - SW[4X4] */ -static uint64 decode_gpr_gpr4(uint64 d) +static uint64 decode_gpr_gpr4(uint64 d, Dis_info *info) { static uint64 register_list[] = { 8, 9, 10, 11, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23 }; return renumber_registers(d, register_list, - sizeof(register_list) / sizeof(register_list[0])); + sizeof(register_list) / sizeof(register_list[0]), info); } @@ -199,12 +202,12 @@ static uint64 decode_gpr_gpr4(uint64 d) * - MOVEP * - SW[4X4] */ -static uint64 decode_gpr_gpr4_zero(uint64 d) +static uint64 decode_gpr_gpr4_zero(uint64 d, Dis_info *info) { static uint64 register_list[] = { 8, 9, 10, 0, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23 }; return renumber_registers(d, register_list, - sizeof(register_list) / sizeof(register_list[0])); + sizeof(register_list) / sizeof(register_list[0]), info); } @@ -258,11 +261,11 @@ static uint64 decode_gpr_gpr4_zero(uint64 d) * - SW[16] * - XOR[16] */ -static uint64 decode_gpr_gpr3(uint64 d) +static uint64 decode_gpr_gpr3(uint64 d, Dis_info *info) { static uint64 register_list[] = { 16, 17, 18, 19, 4, 5, 6, 7 }; return renumber_registers(d, register_list, - sizeof(register_list) / sizeof(register_list[0])); + sizeof(register_list) / sizeof(register_list[0]), info); } @@ -298,11 +301,11 @@ static uint64 decode_gpr_gpr3(uint64 d) * - SW[16] * - SW[GP16] */ -static uint64 decode_gpr_gpr3_src_store(uint64 d) +static uint64 decode_gpr_gpr3_src_store(uint64 d, Dis_info *info) { static uint64 register_list[] = { 0, 17, 18, 19, 4, 5, 6, 7 }; return renumber_registers(d, register_list, - sizeof(register_list) / sizeof(register_list[0])); + sizeof(register_list) / sizeof(register_list[0]), info); } @@ -328,11 +331,11 @@ static uint64 decode_gpr_gpr3_src_store(uint64 d) * - MOVEP * - MOVEP[REV] */ -static uint64 decode_gpr_gpr2_reg1(uint64 d) +static uint64 decode_gpr_gpr2_reg1(uint64 d, Dis_info *info) { static uint64 register_list[] = { 4, 5, 6, 7 }; return renumber_registers(d, register_list, - sizeof(register_list) / sizeof(register_list[0])); + sizeof(register_list) / sizeof(register_list[0]), info); } @@ -358,11 +361,11 @@ static uint64 decode_gpr_gpr2_reg1(uint64 d) * - MOVEP * - MOVEP[REV] */ -static uint64 decode_gpr_gpr2_reg2(uint64 d) +static uint64 decode_gpr_gpr2_reg2(uint64 d, Dis_info *info) { static uint64 register_list[] = { 5, 6, 7, 8 }; return renumber_registers(d, register_list, - sizeof(register_list) / sizeof(register_list[0])); + sizeof(register_list) / sizeof(register_list[0]), info); } @@ -387,11 +390,11 @@ static uint64 decode_gpr_gpr2_reg2(uint64 d) * * - MOVE.BALC */ -static uint64 decode_gpr_gpr1(uint64 d) +static uint64 decode_gpr_gpr1(uint64 d, Dis_info *info) { static uint64 register_list[] = { 4, 5 }; return renumber_registers(d, register_list, - sizeof(register_list) / sizeof(register_list[0])); + sizeof(register_list) / sizeof(register_list[0]), info); } @@ -450,7 +453,7 @@ static uint64 encode_rt1_from_rt(uint64 d) } -static const char *GPR(uint64 reg) +static const char *GPR(uint64 reg, Dis_info *info) { static const char *gpr_reg[32] = { "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", @@ -468,7 +471,8 @@ static const char *GPR(uint64 reg) } -static char *save_restore_list(uint64 rt, uint64 count, uint64 gp) +static char *save_restore_list(uint64 rt, uint64 count, uint64 gp, + Dis_info *info) { char *reg_list[34]; reg_list[0] = (char *)""; @@ -478,7 +482,7 @@ static char *save_restore_list(uint64 rt, uint64 count, uint64 gp) bool use_gp = gp && (counter == count - 1); uint64 this_rt = use_gp ? 28 : ((rt & 0x10) | (rt + counter)) & 0x1f; /* glib usage below requires casting away const */ - reg_list[counter + 1] = (char *)GPR(this_rt); + reg_list[counter + 1] = (char *)GPR(this_rt, info); } reg_list[count + 1] = NULL; @@ -486,7 +490,7 @@ static char *save_restore_list(uint64 rt, uint64 count, uint64 gp) } -static const char *FPR(uint64 reg) +static const char *FPR(uint64 reg, Dis_info *info) { static const char *fpr_reg[32] = { "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", @@ -504,7 +508,7 @@ static const char *FPR(uint64 reg) } -static const char *AC(uint64 reg) +static const char *AC(uint64 reg, Dis_info *info) { static const char *ac_reg[4] = { "ac0", "ac1", "ac2", "ac3" @@ -1545,8 +1549,8 @@ static char *ABS_D(uint64 instruction, Dis_info *info) uint64 fd_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *fs = FPR(fs_value); - const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value, info); + const char *fd = FPR(fd_value, info); return img_format("ABS.D %s, %s", fd, fs); } @@ -1567,8 +1571,8 @@ static char *ABS_S(uint64 instruction, Dis_info *info) uint64 fd_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *fs = FPR(fs_value); - const char *fd = FPR(fd_value); + const char *fs = FPR(fs_value, info); + const char *fd = FPR(fd_value, info); return img_format("ABS.S %s, %s", fd, fs); } @@ -1589,8 +1593,8 @@ static char *ABSQ_S_PH(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("ABSQ_S.PH %s, %s", rt, rs); } @@ -1611,8 +1615,8 @@ static char *ABSQ_S_QB(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("ABSQ_S.QB %s, %s", rt, rs); } @@ -1633,8 +1637,8 @@ static char *ABSQ_S_W(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("ABSQ_S.W %s, %s", rt, rs); } @@ -1655,7 +1659,7 @@ static char *ACLR(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *rs = GPR(rs_value); + const char *rs = GPR(rs_value, info); return img_format("ACLR 0x%" PRIx64 ", %" PRId64 "(%s)", bit_value, s_value, rs); @@ -1677,9 +1681,9 @@ static char *ADD(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("ADD %s, %s, %s", rd, rs, rt); } @@ -1702,9 +1706,9 @@ static char *ADD_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); - const char *fd = FPR(fd_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); + const char *fd = FPR(fd_value, info); return img_format("ADD.D %s, %s, %s", fd, fs, ft); } @@ -1727,9 +1731,9 @@ static char *ADD_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); - const char *fd = FPR(fd_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); + const char *fd = FPR(fd_value, info); return img_format("ADD.S %s, %s, %s", fd, fs, ft); } @@ -1750,8 +1754,8 @@ static char *ADDIU_32_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_15_to_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("ADDIU %s, %s, 0x%" PRIx64, rt, rs, u_value); } @@ -1771,7 +1775,7 @@ static char *ADDIU_48_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("ADDIU %s, %" PRId64, rt, s_value); } @@ -1791,7 +1795,7 @@ static char *ADDIU_GP48_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("ADDIU %s, $%d, %" PRId64, rt, 28, s_value); } @@ -1811,7 +1815,7 @@ static char *ADDIU_GP_B_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_0(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("ADDIU %s, $%d, 0x%" PRIx64, rt, 28, u_value); } @@ -1831,7 +1835,7 @@ static char *ADDIU_GP_W_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_to_2__s2(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("ADDIU %s, $%d, 0x%" PRIx64, rt, 28, u_value); } @@ -1852,8 +1856,8 @@ static char *ADDIU_NEG_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); int64 u = neg_copy(u_value); return img_format("ADDIU %s, %s, %" PRId64, rt, rs, u); @@ -1874,7 +1878,7 @@ static char *ADDIU_R1_SP_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_5_4_3_2_1_0__s2(instruction); uint64 rt3_value = extract_rt3_9_8_7(instruction); - const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); return img_format("ADDIU %s, $%d, 0x%" PRIx64, rt3, 29, u_value); } @@ -1895,8 +1899,8 @@ static char *ADDIU_R2_(uint64 instruction, Dis_info *info) uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_2_1_0__s2(instruction); - const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); - const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); return img_format("ADDIU %s, %s, 0x%" PRIx64, rt3, rs3, u_value); } @@ -1915,7 +1919,7 @@ static char *ADDIU_RS5_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_9_8_7_6_5(instruction); int64 s_value = extract_s__se3_4_2_1_0(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("ADDIU %s, %" PRId64, rt, s_value); } @@ -1936,7 +1940,7 @@ static char *ADDIUPC_32_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); int64 s_value = extract_s__se21_0_20_to_1_s1(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("ADDIUPC %s, %s", rt, s); @@ -1958,7 +1962,7 @@ static char *ADDIUPC_48_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); g_autofree char *s = ADDRESS(s_value, 6, info); return img_format("ADDIUPC %s, %s", rt, s); @@ -1981,9 +1985,9 @@ static char *ADDQ_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("ADDQ.PH %s, %s, %s", rd, rs, rt); } @@ -2006,9 +2010,9 @@ static char *ADDQ_S_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("ADDQ_S.PH %s, %s, %s", rd, rs, rt); } @@ -2030,9 +2034,9 @@ static char *ADDQ_S_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("ADDQ_S.W %s, %s, %s", rd, rs, rt); } @@ -2055,9 +2059,9 @@ static char *ADDQH_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("ADDQH.PH %s, %s, %s", rd, rs, rt); } @@ -2080,9 +2084,9 @@ static char *ADDQH_R_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("ADDQH_R.PH %s, %s, %s", rd, rs, rt); } @@ -2105,9 +2109,9 @@ static char *ADDQH_R_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("ADDQH_R.W %s, %s, %s", rd, rs, rt); } @@ -2130,9 +2134,9 @@ static char *ADDQH_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("ADDQH.W %s, %s, %s", rd, rs, rt); } @@ -2154,9 +2158,9 @@ static char *ADDSC(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("ADDSC %s, %s, %s", rd, rs, rt); } @@ -2177,9 +2181,9 @@ static char *ADDU_16_(uint64 instruction, Dis_info *info) uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 rd3_value = extract_rd3_3_2_1(instruction); - const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); - const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); - const char *rd3 = GPR(decode_gpr_gpr3(rd3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); + const char *rd3 = GPR(decode_gpr_gpr3(rd3_value, info), info); return img_format("ADDU %s, %s, %s", rd3, rs3, rt3); } @@ -2201,9 +2205,9 @@ static char *ADDU_32_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("ADDU %s, %s, %s", rd, rs, rt); } @@ -2224,8 +2228,8 @@ static char *ADDU_4X4_(uint64 instruction, Dis_info *info) uint64 rt4_value = extract_rt4_9_7_6_5(instruction); uint64 rs4_value = extract_rs4_4_2_1_0(instruction); - const char *rs4 = GPR(decode_gpr_gpr4(rs4_value)); - const char *rt4 = GPR(decode_gpr_gpr4(rt4_value)); + const char *rs4 = GPR(decode_gpr_gpr4(rs4_value, info), info); + const char *rt4 = GPR(decode_gpr_gpr4(rt4_value, info), info); return img_format("ADDU %s, %s", rs4, rt4); } @@ -2247,9 +2251,9 @@ static char *ADDU_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("ADDU.PH %s, %s, %s", rd, rs, rt); } @@ -2271,9 +2275,9 @@ static char *ADDU_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("ADDU.QB %s, %s, %s", rd, rs, rt); } @@ -2296,9 +2300,9 @@ static char *ADDU_S_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("ADDU_S.PH %s, %s, %s", rd, rs, rt); } @@ -2320,9 +2324,9 @@ static char *ADDU_S_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("ADDU_S.QB %s, %s, %s", rd, rs, rt); } @@ -2345,9 +2349,9 @@ static char *ADDUH_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("ADDUH.QB %s, %s, %s", rd, rs, rt); } @@ -2370,9 +2374,9 @@ static char *ADDUH_R_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("ADDUH_R.QB %s, %s, %s", rd, rs, rt); } @@ -2393,9 +2397,9 @@ static char *ADDWC(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("ADDWC %s, %s, %s", rd, rs, rt); } @@ -2416,7 +2420,7 @@ static char *ALUIPC(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); int64 s_value = extract_s__se31_0_11_to_2_20_to_12_s12(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("ALUIPC %s, %%pcrel_hi(%s)", rt, s); @@ -2437,8 +2441,8 @@ static char *AND_16_(uint64 instruction, Dis_info *info) uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); - const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); - const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); return img_format("AND %s, %s", rs3, rt3); } @@ -2460,9 +2464,9 @@ static char *AND_32_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("AND %s, %s, %s", rd, rs, rt); } @@ -2483,8 +2487,8 @@ static char *ANDI_16_(uint64 instruction, Dis_info *info) uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 eu_value = extract_eu_3_2_1_0(instruction); - const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); - const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); uint64 eu = encode_eu_from_u_andi16(eu_value); return img_format("ANDI %s, %s, 0x%" PRIx64, rt3, rs3, eu); @@ -2507,8 +2511,8 @@ static char *ANDI_32_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("ANDI %s, %s, 0x%" PRIx64, rt, rs, u_value); } @@ -2530,8 +2534,8 @@ static char *APPEND(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13_12_11(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("APPEND %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -2553,7 +2557,7 @@ static char *ASET(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *rs = GPR(rs_value); + const char *rs = GPR(rs_value, info); return img_format("ASET 0x%" PRIx64 ", %" PRId64 "(%s)", bit_value, s_value, rs); @@ -2615,8 +2619,8 @@ static char *BALRSC(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("BALRSC %s, %s", rt, rs); } @@ -2638,7 +2642,7 @@ static char *BBEQZC(uint64 instruction, Dis_info *info) uint64 bit_value = extract_bit_16_15_14_13_12_11(instruction); int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BBEQZC %s, 0x%" PRIx64 ", %s", rt, bit_value, s); @@ -2661,7 +2665,7 @@ static char *BBNEZC(uint64 instruction, Dis_info *info) uint64 bit_value = extract_bit_16_15_14_13_12_11(instruction); int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BBNEZC %s, 0x%" PRIx64 ", %s", rt, bit_value, s); @@ -2723,7 +2727,7 @@ static char *BC1EQZC(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - const char *ft = FPR(ft_value); + const char *ft = FPR(ft_value, info); g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BC1EQZC %s, %s", ft, s); @@ -2745,7 +2749,7 @@ static char *BC1NEZC(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - const char *ft = FPR(ft_value); + const char *ft = FPR(ft_value, info); g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BC1NEZC %s, %s", ft, s); @@ -2810,8 +2814,8 @@ static char *BEQC_16_(uint64 instruction, Dis_info *info) uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_3_2_1_0__s1(instruction); - const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); - const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); g_autofree char *u = ADDRESS(u_value, 2, info); return img_format("BEQC %s, %s, %s", rs3, rt3, u); @@ -2834,8 +2838,8 @@ static char *BEQC_32_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BEQC %s, %s, %s", rs, rt, s); @@ -2858,7 +2862,7 @@ static char *BEQIC(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BEQIC %s, 0x%" PRIx64 ", %s", rt, u_value, s); @@ -2880,7 +2884,7 @@ static char *BEQZC_16_(uint64 instruction, Dis_info *info) uint64 rt3_value = extract_rt3_9_8_7(instruction); int64 s_value = extract_s__se7_0_6_5_4_3_2_1_s1(instruction); - const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); g_autofree char *s = ADDRESS(s_value, 2, info); return img_format("BEQZC %s, %s", rt3, s); @@ -2903,8 +2907,8 @@ static char *BGEC(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BGEC %s, %s, %s", rs, rt, s); @@ -2927,7 +2931,7 @@ static char *BGEIC(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BGEIC %s, 0x%" PRIx64 ", %s", rt, u_value, s); @@ -2950,7 +2954,7 @@ static char *BGEIUC(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BGEIUC %s, 0x%" PRIx64 ", %s", rt, u_value, s); @@ -2973,8 +2977,8 @@ static char *BGEUC(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BGEUC %s, %s, %s", rs, rt, s); @@ -2997,8 +3001,8 @@ static char *BLTC(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BLTC %s, %s, %s", rs, rt, s); @@ -3021,7 +3025,7 @@ static char *BLTIC(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BLTIC %s, 0x%" PRIx64 ", %s", rt, u_value, s); @@ -3044,7 +3048,7 @@ static char *BLTIUC(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BLTIUC %s, 0x%" PRIx64 ", %s", rt, u_value, s); @@ -3067,8 +3071,8 @@ static char *BLTUC(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BLTUC %s, %s, %s", rs, rt, s); @@ -3091,8 +3095,8 @@ static char *BNEC_16_(uint64 instruction, Dis_info *info) uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_3_2_1_0__s1(instruction); - const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); - const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); g_autofree char *u = ADDRESS(u_value, 2, info); return img_format("BNEC %s, %s, %s", rs3, rt3, u); @@ -3115,8 +3119,8 @@ static char *BNEC_32_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BNEC %s, %s, %s", rs, rt, s); @@ -3139,7 +3143,7 @@ static char *BNEIC(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("BNEIC %s, 0x%" PRIx64 ", %s", rt, u_value, s); @@ -3161,7 +3165,7 @@ static char *BNEZC_16_(uint64 instruction, Dis_info *info) uint64 rt3_value = extract_rt3_9_8_7(instruction); int64 s_value = extract_s__se7_0_6_5_4_3_2_1_s1(instruction); - const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); g_autofree char *s = ADDRESS(s_value, 2, info); return img_format("BNEZC %s, %s", rt3, s); @@ -3240,7 +3244,7 @@ static char *BRSC(uint64 instruction, Dis_info *info) { uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rs = GPR(rs_value); + const char *rs = GPR(rs_value, info); return img_format("BRSC %s", rs); } @@ -3262,7 +3266,7 @@ static char *CACHE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *rs = GPR(rs_value); + const char *rs = GPR(rs_value, info); return img_format("CACHE 0x%" PRIx64 ", %s(%s)", op_value, s_value, rs); } @@ -3284,7 +3288,7 @@ static char *CACHEE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *rs = GPR(rs_value); + const char *rs = GPR(rs_value, info); return img_format("CACHEE 0x%" PRIx64 ", %s(%s)", op_value, s_value, rs); } @@ -3305,8 +3309,8 @@ static char *CEIL_L_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("CEIL.L.D %s, %s", ft, fs); } @@ -3327,8 +3331,8 @@ static char *CEIL_L_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("CEIL.L.S %s, %s", ft, fs); } @@ -3349,8 +3353,8 @@ static char *CEIL_W_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("CEIL.W.D %s, %s", ft, fs); } @@ -3371,8 +3375,8 @@ static char *CEIL_W_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("CEIL.W.S %s, %s", ft, fs); } @@ -3393,7 +3397,7 @@ static char *CFC1(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("CFC1 %s, CP%" PRIu64, rt, cs_value); } @@ -3414,7 +3418,7 @@ static char *CFC2(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("CFC2 %s, CP%" PRIu64, rt, cs_value); } @@ -3435,8 +3439,8 @@ static char *CLASS_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("CLASS.D %s, %s", ft, fs); } @@ -3457,8 +3461,8 @@ static char *CLASS_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("CLASS.S %s, %s", ft, fs); } @@ -3479,8 +3483,8 @@ static char *CLO(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("CLO %s, %s", rt, rs); } @@ -3501,8 +3505,8 @@ static char *CLZ(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("CLZ %s, %s", rt, rs); } @@ -3524,9 +3528,9 @@ static char *CMP_AF_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.AF.D %s, %s, %s", fd, fs, ft); } @@ -3548,9 +3552,9 @@ static char *CMP_AF_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.AF.S %s, %s, %s", fd, fs, ft); } @@ -3572,9 +3576,9 @@ static char *CMP_EQ_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.EQ.D %s, %s, %s", fd, fs, ft); } @@ -3594,8 +3598,8 @@ static char *CMP_EQ_PH(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("CMP.EQ.PH %s, %s", rs, rt); } @@ -3617,9 +3621,9 @@ static char *CMP_EQ_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.EQ.S %s, %s, %s", fd, fs, ft); } @@ -3641,9 +3645,9 @@ static char *CMP_LE_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.LE.D %s, %s, %s", fd, fs, ft); } @@ -3663,8 +3667,8 @@ static char *CMP_LE_PH(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("CMP.LE.PH %s, %s", rs, rt); } @@ -3686,9 +3690,9 @@ static char *CMP_LE_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.LE.S %s, %s, %s", fd, fs, ft); } @@ -3710,9 +3714,9 @@ static char *CMP_LT_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.LT.D %s, %s, %s", fd, fs, ft); } @@ -3732,8 +3736,8 @@ static char *CMP_LT_PH(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("CMP.LT.PH %s, %s", rs, rt); } @@ -3755,9 +3759,9 @@ static char *CMP_LT_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.LT.S %s, %s, %s", fd, fs, ft); } @@ -3779,9 +3783,9 @@ static char *CMP_NE_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.NE.D %s, %s, %s", fd, fs, ft); } @@ -3803,9 +3807,9 @@ static char *CMP_NE_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.NE.S %s, %s, %s", fd, fs, ft); } @@ -3827,9 +3831,9 @@ static char *CMP_OR_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.OR.D %s, %s, %s", fd, fs, ft); } @@ -3851,9 +3855,9 @@ static char *CMP_OR_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.OR.S %s, %s, %s", fd, fs, ft); } @@ -3875,9 +3879,9 @@ static char *CMP_SAF_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.SAF.D %s, %s, %s", fd, fs, ft); } @@ -3899,9 +3903,9 @@ static char *CMP_SAF_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.SAF.S %s, %s, %s", fd, fs, ft); } @@ -3923,9 +3927,9 @@ static char *CMP_SEQ_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.SEQ.D %s, %s, %s", fd, fs, ft); } @@ -3947,9 +3951,9 @@ static char *CMP_SEQ_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.SEQ.S %s, %s, %s", fd, fs, ft); } @@ -3971,9 +3975,9 @@ static char *CMP_SLE_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.SLE.D %s, %s, %s", fd, fs, ft); } @@ -3995,9 +3999,9 @@ static char *CMP_SLE_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.SLE.S %s, %s, %s", fd, fs, ft); } @@ -4019,9 +4023,9 @@ static char *CMP_SLT_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.SLT.D %s, %s, %s", fd, fs, ft); } @@ -4043,9 +4047,9 @@ static char *CMP_SLT_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.SLT.S %s, %s, %s", fd, fs, ft); } @@ -4067,9 +4071,9 @@ static char *CMP_SNE_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.SNE.D %s, %s, %s", fd, fs, ft); } @@ -4091,9 +4095,9 @@ static char *CMP_SNE_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.SNE.S %s, %s, %s", fd, fs, ft); } @@ -4115,9 +4119,9 @@ static char *CMP_SOR_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.SOR.D %s, %s, %s", fd, fs, ft); } @@ -4139,9 +4143,9 @@ static char *CMP_SOR_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.SOR.S %s, %s, %s", fd, fs, ft); } @@ -4163,9 +4167,9 @@ static char *CMP_SUEQ_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.SUEQ.D %s, %s, %s", fd, fs, ft); } @@ -4187,9 +4191,9 @@ static char *CMP_SUEQ_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.SUEQ.S %s, %s, %s", fd, fs, ft); } @@ -4211,9 +4215,9 @@ static char *CMP_SULE_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.SULE.D %s, %s, %s", fd, fs, ft); } @@ -4235,9 +4239,9 @@ static char *CMP_SULE_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.SULE.S %s, %s, %s", fd, fs, ft); } @@ -4259,9 +4263,9 @@ static char *CMP_SULT_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.SULT.D %s, %s, %s", fd, fs, ft); } @@ -4283,9 +4287,9 @@ static char *CMP_SULT_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.SULT.S %s, %s, %s", fd, fs, ft); } @@ -4307,9 +4311,9 @@ static char *CMP_SUN_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.SUN.D %s, %s, %s", fd, fs, ft); } @@ -4331,9 +4335,9 @@ static char *CMP_SUNE_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.SUNE.D %s, %s, %s", fd, fs, ft); } @@ -4355,9 +4359,9 @@ static char *CMP_SUNE_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.SUNE.S %s, %s, %s", fd, fs, ft); } @@ -4379,9 +4383,9 @@ static char *CMP_SUN_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.SUN.S %s, %s, %s", fd, fs, ft); } @@ -4403,9 +4407,9 @@ static char *CMP_UEQ_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.UEQ.D %s, %s, %s", fd, fs, ft); } @@ -4427,9 +4431,9 @@ static char *CMP_UEQ_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.UEQ.S %s, %s, %s", fd, fs, ft); } @@ -4451,9 +4455,9 @@ static char *CMP_ULE_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.ULE.D %s, %s, %s", fd, fs, ft); } @@ -4475,9 +4479,9 @@ static char *CMP_ULE_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.ULE.S %s, %s, %s", fd, fs, ft); } @@ -4499,9 +4503,9 @@ static char *CMP_ULT_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.ULT.D %s, %s, %s", fd, fs, ft); } @@ -4523,9 +4527,9 @@ static char *CMP_ULT_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.ULT.S %s, %s, %s", fd, fs, ft); } @@ -4547,9 +4551,9 @@ static char *CMP_UN_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.UN.D %s, %s, %s", fd, fs, ft); } @@ -4571,9 +4575,9 @@ static char *CMP_UNE_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.UNE.D %s, %s, %s", fd, fs, ft); } @@ -4595,9 +4599,9 @@ static char *CMP_UNE_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.UNE.S %s, %s, %s", fd, fs, ft); } @@ -4619,9 +4623,9 @@ static char *CMP_UN_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("CMP.UN.S %s, %s, %s", fd, fs, ft); } @@ -4644,9 +4648,9 @@ static char *CMPGDU_EQ_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("CMPGDU.EQ.QB %s, %s, %s", rd, rs, rt); } @@ -4669,9 +4673,9 @@ static char *CMPGDU_LE_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("CMPGDU.LE.QB %s, %s, %s", rd, rs, rt); } @@ -4694,9 +4698,9 @@ static char *CMPGDU_LT_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("CMPGDU.LT.QB %s, %s, %s", rd, rs, rt); } @@ -4719,9 +4723,9 @@ static char *CMPGU_EQ_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("CMPGU.EQ.QB %s, %s, %s", rd, rs, rt); } @@ -4744,9 +4748,9 @@ static char *CMPGU_LE_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("CMPGU.LE.QB %s, %s, %s", rd, rs, rt); } @@ -4769,9 +4773,9 @@ static char *CMPGU_LT_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("CMPGU.LT.QB %s, %s, %s", rd, rs, rt); } @@ -4792,8 +4796,8 @@ static char *CMPU_EQ_QB(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("CMPU.EQ.QB %s, %s", rs, rt); } @@ -4814,8 +4818,8 @@ static char *CMPU_LE_QB(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("CMPU.LE.QB %s, %s", rs, rt); } @@ -4836,8 +4840,8 @@ static char *CMPU_LT_QB(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("CMPU.LT.QB %s, %s", rs, rt); } @@ -4877,7 +4881,7 @@ static char *CTC1(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("CTC1 %s, CP%" PRIu64, rt, cs_value); } @@ -4898,7 +4902,7 @@ static char *CTC2(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("CTC2 %s, CP%" PRIu64, rt, cs_value); } @@ -4919,8 +4923,8 @@ static char *CVT_D_L(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("CVT.D.L %s, %s", ft, fs); } @@ -4941,8 +4945,8 @@ static char *CVT_D_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("CVT.D.S %s, %s", ft, fs); } @@ -4963,8 +4967,8 @@ static char *CVT_D_W(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("CVT.D.W %s, %s", ft, fs); } @@ -4985,8 +4989,8 @@ static char *CVT_L_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("CVT.L.D %s, %s", ft, fs); } @@ -5007,8 +5011,8 @@ static char *CVT_L_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("CVT.L.S %s, %s", ft, fs); } @@ -5029,8 +5033,8 @@ static char *CVT_S_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("CVT.S.D %s, %s", ft, fs); } @@ -5051,8 +5055,8 @@ static char *CVT_S_L(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("CVT.S.L %s, %s", ft, fs); } @@ -5073,8 +5077,8 @@ static char *CVT_S_PL(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("CVT.S.PL %s, %s", ft, fs); } @@ -5095,8 +5099,8 @@ static char *CVT_S_PU(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("CVT.S.PU %s, %s", ft, fs); } @@ -5117,8 +5121,8 @@ static char *CVT_S_W(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("CVT.S.W %s, %s", ft, fs); } @@ -5139,8 +5143,8 @@ static char *CVT_W_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("CVT.W.D %s, %s", ft, fs); } @@ -5161,8 +5165,8 @@ static char *CVT_W_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("CVT.W.S %s, %s", ft, fs); } @@ -5183,7 +5187,7 @@ static char *DADDIU_48_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("DADDIU %s, %s", rt, s_value); } @@ -5205,8 +5209,8 @@ static char *DADDIU_NEG_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); int64 u = neg_copy(u_value); return img_format("DADDIU %s, %s, %" PRId64, rt, rs, u); @@ -5229,8 +5233,8 @@ static char *DADDIU_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("DADDIU %s, %s, 0x%" PRIx64, rt, rs, u_value); } @@ -5252,9 +5256,9 @@ static char *DADD(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DADD %s, %s, %s", rd, rs, rt); } @@ -5276,9 +5280,9 @@ static char *DADDU(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DADDU %s, %s, %s", rd, rs, rt); } @@ -5299,8 +5303,8 @@ static char *DCLO(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("DCLO %s, %s", rt, rs); } @@ -5321,8 +5325,8 @@ static char *DCLZ(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("DCLZ %s, %s", rt, rs); } @@ -5344,9 +5348,9 @@ static char *DDIV(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DDIV %s, %s, %s", rd, rs, rt); } @@ -5368,9 +5372,9 @@ static char *DDIVU(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DDIVU %s, %s, %s", rd, rs, rt); } @@ -5411,8 +5415,8 @@ static char *DEXTM(uint64 instruction, Dis_info *info) uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction); uint64 lsb_value = extract_lsb_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); uint64 msbd = encode_msbd_from_size(msbd_value); return img_format("DEXTM %s, %s, 0x%" PRIx64 ", 0x%" PRIx64, @@ -5437,8 +5441,8 @@ static char *DEXT(uint64 instruction, Dis_info *info) uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction); uint64 lsb_value = extract_lsb_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); uint64 msbd = encode_msbd_from_size(msbd_value); return img_format("DEXT %s, %s, 0x%" PRIx64 ", 0x%" PRIx64, @@ -5463,8 +5467,8 @@ static char *DEXTU(uint64 instruction, Dis_info *info) uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction); uint64 lsb_value = extract_lsb_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); uint64 msbd = encode_msbd_from_size(msbd_value); return img_format("DEXTU %s, %s, 0x%" PRIx64 ", 0x%" PRIx64, @@ -5489,8 +5493,8 @@ static char *DINSM(uint64 instruction, Dis_info *info) uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction); uint64 lsb_value = extract_lsb_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); /* !!!!!!!!!! - no conversion function */ return img_format("DINSM %s, %s, 0x%" PRIx64 ", 0x%" PRIx64, @@ -5516,8 +5520,8 @@ static char *DINS(uint64 instruction, Dis_info *info) uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction); uint64 lsb_value = extract_lsb_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); /* !!!!!!!!!! - no conversion function */ return img_format("DINS %s, %s, 0x%" PRIx64 ", 0x%" PRIx64, @@ -5543,8 +5547,8 @@ static char *DINSU(uint64 instruction, Dis_info *info) uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction); uint64 lsb_value = extract_lsb_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); /* !!!!!!!!!! - no conversion function */ return img_format("DINSU %s, %s, 0x%" PRIx64 ", 0x%" PRIx64, @@ -5567,7 +5571,7 @@ static char *DI(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("DI %s", rt); } @@ -5589,9 +5593,9 @@ static char *DIV(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DIV %s, %s, %s", rd, rs, rt); } @@ -5613,9 +5617,9 @@ static char *DIV_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("DIV.D %s, %s, %s", fd, fs, ft); } @@ -5637,9 +5641,9 @@ static char *DIV_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("DIV.S %s, %s, %s", fd, fs, ft); } @@ -5661,9 +5665,9 @@ static char *DIVU(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DIVU %s, %s, %s", rd, rs, rt); } @@ -5686,9 +5690,9 @@ static char *DLSA(uint64 instruction, Dis_info *info) uint64 rd_value = extract_rd_15_14_13_12_11(instruction); uint64 u2_value = extract_u2_10_9(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DLSA %s, %s, %s, 0x%" PRIx64, rd, rs, rt, u2_value); } @@ -5709,7 +5713,7 @@ static char *DLUI_48_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_41_40_39_38_37(instruction); uint64 u_value = extract_u_31_to_0__s32(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("DLUI %s, 0x%" PRIx64, rt, u_value); } @@ -5731,7 +5735,7 @@ static char *DMFC0(uint64 instruction, Dis_info *info) uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("DMFC0 %s, CP%" PRIu64 ", 0x%" PRIx64, rt, c0s_value, sel_value); @@ -5753,8 +5757,8 @@ static char *DMFC1(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *fs = FPR(fs_value); + const char *rt = GPR(rt_value, info); + const char *fs = FPR(fs_value, info); return img_format("DMFC1 %s, %s", rt, fs); } @@ -5775,7 +5779,7 @@ static char *DMFC2(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("DMFC2 %s, CP%" PRIu64, rt, cs_value); } @@ -5797,7 +5801,7 @@ static char *DMFGC0(uint64 instruction, Dis_info *info) uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("DMFGC0 %s, CP%" PRIu64 ", 0x%" PRIx64, rt, c0s_value, sel_value); @@ -5820,9 +5824,9 @@ static char *DMOD(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DMOD %s, %s, %s", rd, rs, rt); } @@ -5844,9 +5848,9 @@ static char *DMODU(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DMODU %s, %s, %s", rd, rs, rt); } @@ -5868,7 +5872,7 @@ static char *DMTC0(uint64 instruction, Dis_info *info) uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("DMTC0 %s, CP%" PRIu64 ", 0x%" PRIx64, rt, c0s_value, sel_value); @@ -5890,8 +5894,8 @@ static char *DMTC1(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *fs = FPR(fs_value); + const char *rt = GPR(rt_value, info); + const char *fs = FPR(fs_value, info); return img_format("DMTC1 %s, %s", rt, fs); } @@ -5912,7 +5916,7 @@ static char *DMTC2(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("DMTC2 %s, CP%" PRIu64, rt, cs_value); } @@ -5934,7 +5938,7 @@ static char *DMTGC0(uint64 instruction, Dis_info *info) uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("DMTGC0 %s, CP%" PRIu64 ", 0x%" PRIx64, rt, c0s_value, sel_value); @@ -5955,7 +5959,7 @@ static char *DMT(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("DMT %s", rt); } @@ -5977,9 +5981,9 @@ static char *DMUH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DMUH %s, %s, %s", rd, rs, rt); } @@ -6001,9 +6005,9 @@ static char *DMUHU(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DMUHU %s, %s, %s", rd, rs, rt); } @@ -6025,9 +6029,9 @@ static char *DMUL(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DMUL %s, %s, %s", rd, rs, rt); } @@ -6049,9 +6053,9 @@ static char *DMULU(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DMULU %s, %s, %s", rd, rs, rt); } @@ -6074,9 +6078,9 @@ static char *DPA_W_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DPA.W.PH %s, %s, %s", ac, rs, rt); } @@ -6098,9 +6102,9 @@ static char *DPAQ_SA_L_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DPAQ_SA.L.W %s, %s, %s", ac, rs, rt); } @@ -6122,9 +6126,9 @@ static char *DPAQ_S_W_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DPAQ_S.W.PH %s, %s, %s", ac, rs, rt); } @@ -6146,9 +6150,9 @@ static char *DPAQX_SA_W_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DPAQX_SA.W.PH %s, %s, %s", ac, rs, rt); } @@ -6170,9 +6174,9 @@ static char *DPAQX_S_W_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DPAQX_S.W.PH %s, %s, %s", ac, rs, rt); } @@ -6194,9 +6198,9 @@ static char *DPAU_H_QBL(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DPAU.H.QBL %s, %s, %s", ac, rs, rt); } @@ -6218,9 +6222,9 @@ static char *DPAU_H_QBR(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DPAU.H.QBR %s, %s, %s", ac, rs, rt); } @@ -6242,9 +6246,9 @@ static char *DPAX_W_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DPAX.W.PH %s, %s, %s", ac, rs, rt); } @@ -6266,9 +6270,9 @@ static char *DPS_W_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DPS.W.PH %s, %s, %s", ac, rs, rt); } @@ -6290,9 +6294,9 @@ static char *DPSQ_SA_L_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DPSQ_SA.L.W %s, %s, %s", ac, rs, rt); } @@ -6314,9 +6318,9 @@ static char *DPSQ_S_W_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DPSQ_S.W.PH %s, %s, %s", ac, rs, rt); } @@ -6338,9 +6342,9 @@ static char *DPSQX_SA_W_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DPSQX_SA.W.PH %s, %s, %s", ac, rs, rt); } @@ -6362,9 +6366,9 @@ static char *DPSQX_S_W_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DPSQX_S.W.PH %s, %s, %s", ac, rs, rt); } @@ -6386,9 +6390,9 @@ static char *DPSU_H_QBL(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DPSU.H.QBL %s, %s, %s", ac, rs, rt); } @@ -6410,9 +6414,9 @@ static char *DPSU_H_QBR(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DPSU.H.QBR %s, %s, %s", ac, rs, rt); } @@ -6434,9 +6438,9 @@ static char *DPSX_W_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DPSX.W.PH %s, %s, %s", ac, rs, rt); } @@ -6458,8 +6462,8 @@ static char *DROTR(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("DROTR %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -6481,8 +6485,8 @@ static char *DROTR32(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("DROTR32 %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -6504,9 +6508,9 @@ static char *DROTRV(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DROTRV %s, %s, %s", rd, rs, rt); } @@ -6529,8 +6533,8 @@ static char *DROTX(uint64 instruction, Dis_info *info) uint64 shiftx_value = extract_shiftx_11_10_9_8_7_6(instruction); uint64 shift_value = extract_shift_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("DROTX %s, %s, 0x%" PRIx64 ", 0x%" PRIx64, rt, rs, shift_value, shiftx_value); @@ -6553,8 +6557,8 @@ static char *DSLL(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("DSLL %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -6576,8 +6580,8 @@ static char *DSLL32(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("DSLL32 %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -6599,9 +6603,9 @@ static char *DSLLV(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DSLLV %s, %s, %s", rd, rs, rt); } @@ -6623,8 +6627,8 @@ static char *DSRA(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("DSRA %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -6646,8 +6650,8 @@ static char *DSRA32(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("DSRA32 %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -6669,9 +6673,9 @@ static char *DSRAV(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DSRAV %s, %s, %s", rd, rs, rt); } @@ -6693,8 +6697,8 @@ static char *DSRL(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("DSRL %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -6716,8 +6720,8 @@ static char *DSRL32(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("DSRL32 %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -6739,9 +6743,9 @@ static char *DSRLV(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DSRLV %s, %s, %s", rd, rs, rt); } @@ -6763,9 +6767,9 @@ static char *DSUB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DSUB %s, %s, %s", rd, rs, rt); } @@ -6787,9 +6791,9 @@ static char *DSUBU(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("DSUBU %s, %s, %s", rd, rs, rt); } @@ -6809,7 +6813,7 @@ static char *DVPE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("DVPE %s", rt); } @@ -6829,7 +6833,7 @@ static char *DVP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("DVP %s", rt); } @@ -6867,7 +6871,7 @@ static char *EI(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("EI %s", rt); } @@ -6887,7 +6891,7 @@ static char *EMT(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("EMT %s", rt); } @@ -6943,7 +6947,7 @@ static char *EVP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("EVP %s", rt); } @@ -6963,7 +6967,7 @@ static char *EVPE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("EVPE %s", rt); } @@ -6986,8 +6990,8 @@ static char *EXT(uint64 instruction, Dis_info *info) uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction); uint64 lsb_value = extract_lsb_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); uint64 msbd = encode_msbd_from_size(msbd_value); return img_format("EXT %s, %s, 0x%" PRIx64 ", 0x%" PRIx64, @@ -7012,9 +7016,9 @@ static char *EXTD(uint64 instruction, Dis_info *info) uint64 rd_value = extract_rd_15_14_13_12_11(instruction); uint64 shift_value = extract_shift_10_9_8_7_6(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("EXTD %s, %s, %s, 0x%" PRIx64, rd, rs, rt, shift_value); } @@ -7037,9 +7041,9 @@ static char *EXTD32(uint64 instruction, Dis_info *info) uint64 rd_value = extract_rd_15_14_13_12_11(instruction); uint64 shift_value = extract_shift_10_9_8_7_6(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("EXTD32 %s, %s, %s, 0x%" PRIx64, rd, rs, rt, shift_value); } @@ -7061,8 +7065,8 @@ static char *EXTPDP(uint64 instruction, Dis_info *info) uint64 size_value = extract_size_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *rt = GPR(rt_value); - const char *ac = AC(ac_value); + const char *rt = GPR(rt_value, info); + const char *ac = AC(ac_value, info); return img_format("EXTPDP %s, %s, 0x%" PRIx64, rt, ac, size_value); } @@ -7084,9 +7088,9 @@ static char *EXTPDPV(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *rt = GPR(rt_value); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); return img_format("EXTPDPV %s, %s, %s", rt, ac, rs); } @@ -7108,8 +7112,8 @@ static char *EXTP(uint64 instruction, Dis_info *info) uint64 size_value = extract_size_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *rt = GPR(rt_value); - const char *ac = AC(ac_value); + const char *rt = GPR(rt_value, info); + const char *ac = AC(ac_value, info); return img_format("EXTP %s, %s, 0x%" PRIx64, rt, ac, size_value); } @@ -7131,9 +7135,9 @@ static char *EXTPV(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *rt = GPR(rt_value); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); return img_format("EXTPV %s, %s, %s", rt, ac, rs); } @@ -7156,8 +7160,8 @@ static char *EXTR_RS_W(uint64 instruction, Dis_info *info) uint64 shift_value = extract_shift_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *rt = GPR(rt_value); - const char *ac = AC(ac_value); + const char *rt = GPR(rt_value, info); + const char *ac = AC(ac_value, info); return img_format("EXTR_RS.W %s, %s, 0x%" PRIx64, rt, ac, shift_value); } @@ -7180,8 +7184,8 @@ static char *EXTR_R_W(uint64 instruction, Dis_info *info) uint64 shift_value = extract_shift_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *rt = GPR(rt_value); - const char *ac = AC(ac_value); + const char *rt = GPR(rt_value, info); + const char *ac = AC(ac_value, info); return img_format("EXTR_R.W %s, %s, 0x%" PRIx64, rt, ac, shift_value); } @@ -7204,8 +7208,8 @@ static char *EXTR_S_H(uint64 instruction, Dis_info *info) uint64 shift_value = extract_shift_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *rt = GPR(rt_value); - const char *ac = AC(ac_value); + const char *rt = GPR(rt_value, info); + const char *ac = AC(ac_value, info); return img_format("EXTR_S.H %s, %s, 0x%" PRIx64, rt, ac, shift_value); } @@ -7228,8 +7232,8 @@ static char *EXTR_W(uint64 instruction, Dis_info *info) uint64 shift_value = extract_shift_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *rt = GPR(rt_value); - const char *ac = AC(ac_value); + const char *rt = GPR(rt_value, info); + const char *ac = AC(ac_value, info); return img_format("EXTR.W %s, %s, 0x%" PRIx64, rt, ac, shift_value); } @@ -7252,9 +7256,9 @@ static char *EXTRV_RS_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *rt = GPR(rt_value); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); return img_format("EXTRV_RS.W %s, %s, %s", rt, ac, rs); } @@ -7277,9 +7281,9 @@ static char *EXTRV_R_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *rt = GPR(rt_value); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); return img_format("EXTRV_R.W %s, %s, %s", rt, ac, rs); } @@ -7302,9 +7306,9 @@ static char *EXTRV_S_H(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *rt = GPR(rt_value); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); return img_format("EXTRV_S.H %s, %s, %s", rt, ac, rs); } @@ -7327,9 +7331,9 @@ static char *EXTRV_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *rt = GPR(rt_value); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); return img_format("EXTRV.W %s, %s, %s", rt, ac, rs); } @@ -7353,9 +7357,9 @@ static char *EXTW(uint64 instruction, Dis_info *info) uint64 rd_value = extract_rd_15_14_13_12_11(instruction); uint64 shift_value = extract_shift_10_9_8_7_6(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("EXTW %s, %s, %s, 0x%" PRIx64, rd, rs, rt, shift_value); } @@ -7376,8 +7380,8 @@ static char *FLOOR_L_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("FLOOR.L.D %s, %s", ft, fs); } @@ -7398,8 +7402,8 @@ static char *FLOOR_L_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("FLOOR.L.S %s, %s", ft, fs); } @@ -7420,8 +7424,8 @@ static char *FLOOR_W_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("FLOOR.W.D %s, %s", ft, fs); } @@ -7442,8 +7446,8 @@ static char *FLOOR_W_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("FLOOR.W.S %s, %s", ft, fs); } @@ -7465,9 +7469,9 @@ static char *FORK(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("FORK %s, %s, %s", rd, rs, rt); } @@ -7528,8 +7532,8 @@ static char *INS(uint64 instruction, Dis_info *info) uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction); uint64 lsb_value = extract_lsb_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); /* !!!!!!!!!! - no conversion function */ return img_format("INS %s, %s, 0x%" PRIx64 ", 0x%" PRIx64, @@ -7552,8 +7556,8 @@ static char *INSV(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("INSV %s, %s", rt, rs); } @@ -7591,7 +7595,7 @@ static char *JALRC_16_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_9_8_7_6_5(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("JALRC $%d, %s", 31, rt); } @@ -7612,8 +7616,8 @@ static char *JALRC_32_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("JALRC %s, %s", rt, rs); } @@ -7634,8 +7638,8 @@ static char *JALRC_HB(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("JALRC.HB %s, %s", rt, rs); } @@ -7655,7 +7659,7 @@ static char *JRC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_9_8_7_6_5(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("JRC %s", rt); } @@ -7677,8 +7681,8 @@ static char *LB_16_(uint64 instruction, Dis_info *info) uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_1_0(instruction); - const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); - const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); return img_format("LB %s, 0x%" PRIx64 "(%s)", rt3, u_value, rs3); } @@ -7699,7 +7703,7 @@ static char *LB_GP_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_0(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("LB %s, 0x%" PRIx64 "($%d)", rt, u_value, 28); } @@ -7721,8 +7725,8 @@ static char *LB_S9_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("LB %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -7744,8 +7748,8 @@ static char *LB_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("LB %s, 0x%" PRIx64 "(%s)", rt, u_value, rs); } @@ -7767,8 +7771,8 @@ static char *LBE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("LBE %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -7790,8 +7794,8 @@ static char *LBU_16_(uint64 instruction, Dis_info *info) uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_1_0(instruction); - const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); - const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); return img_format("LBU %s, 0x%" PRIx64 "(%s)", rt3, u_value, rs3); } @@ -7812,7 +7816,7 @@ static char *LBU_GP_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_0(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("LBU %s, 0x%" PRIx64 "($%d)", rt, u_value, 28); } @@ -7834,8 +7838,8 @@ static char *LBU_S9_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("LBU %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -7857,8 +7861,8 @@ static char *LBU_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("LBU %s, 0x%" PRIx64 "(%s)", rt, u_value, rs); } @@ -7880,8 +7884,8 @@ static char *LBUE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("LBUE %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -7903,9 +7907,9 @@ static char *LBUX(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("LBUX %s, %s(%s)", rd, rs, rt); } @@ -7927,9 +7931,9 @@ static char *LBX(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("LBX %s, %s(%s)", rd, rs, rt); } @@ -7950,7 +7954,7 @@ static char *LD_GP_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_to_3__s3(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("LD %s, 0x%" PRIx64 "($%d)", rt, u_value, 28); } @@ -7972,8 +7976,8 @@ static char *LD_S9_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("LD %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -7995,8 +7999,8 @@ static char *LD_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("LD %s, 0x%" PRIx64 "(%s)", rt, u_value, rs); } @@ -8017,7 +8021,7 @@ static char *LDC1_GP_(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_2__s2(instruction); - const char *ft = FPR(ft_value); + const char *ft = FPR(ft_value, info); return img_format("LDC1 %s, 0x%" PRIx64 "($%d)", ft, u_value, 28); } @@ -8039,8 +8043,8 @@ static char *LDC1_S9_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *ft = FPR(ft_value); - const char *rs = GPR(rs_value); + const char *ft = FPR(ft_value, info); + const char *rs = GPR(rs_value, info); return img_format("LDC1 %s, %" PRId64 "(%s)", ft, s_value, rs); } @@ -8062,8 +8066,8 @@ static char *LDC1_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - const char *ft = FPR(ft_value); - const char *rs = GPR(rs_value); + const char *ft = FPR(ft_value, info); + const char *rs = GPR(rs_value, info); return img_format("LDC1 %s, 0x%" PRIx64 "(%s)", ft, u_value, rs); } @@ -8085,9 +8089,9 @@ static char *LDC1XS(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ft_value = extract_ft_15_14_13_12_11(instruction); - const char *ft = FPR(ft_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ft = FPR(ft_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("LDC1XS %s, %s(%s)", ft, rs, rt); } @@ -8109,9 +8113,9 @@ static char *LDC1X(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ft_value = extract_ft_15_14_13_12_11(instruction); - const char *ft = FPR(ft_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ft = FPR(ft_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("LDC1X %s, %s(%s)", ft, rs, rt); } @@ -8133,7 +8137,7 @@ static char *LDC2(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *rs = GPR(rs_value); + const char *rs = GPR(rs_value, info); return img_format("LDC2 CP%" PRIu64 ", %" PRId64 "(%s)", ct_value, s_value, rs); @@ -8157,8 +8161,8 @@ static char *LDM(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 count3_value = extract_count3_14_13_12(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); uint64 count3 = encode_count3_from_count(count3_value); return img_format("LDM %s, %" PRId64 "(%s), 0x%" PRIx64, @@ -8181,7 +8185,7 @@ static char *LDPC_48_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); g_autofree char *s = ADDRESS(s_value, 6, info); return img_format("LDPC %s, %s", rt, s); @@ -8204,9 +8208,9 @@ static char *LDX(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("LDX %s, %s(%s)", rd, rs, rt); } @@ -8228,9 +8232,9 @@ static char *LDXS(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("LDXS %s, %s(%s)", rd, rs, rt); } @@ -8252,8 +8256,8 @@ static char *LH_16_(uint64 instruction, Dis_info *info) uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_2_1__s1(instruction); - const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); - const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); return img_format("LH %s, 0x%" PRIx64 "(%s)", rt3, u_value, rs3); } @@ -8274,7 +8278,7 @@ static char *LH_GP_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_1__s1(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("LH %s, 0x%" PRIx64 "($%d)", rt, u_value, 28); } @@ -8296,8 +8300,8 @@ static char *LH_S9_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("LH %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -8319,8 +8323,8 @@ static char *LH_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("LH %s, 0x%" PRIx64 "(%s)", rt, u_value, rs); } @@ -8342,8 +8346,8 @@ static char *LHE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("LHE %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -8365,8 +8369,8 @@ static char *LHU_16_(uint64 instruction, Dis_info *info) uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_2_1__s1(instruction); - const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); - const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); return img_format("LHU %s, 0x%" PRIx64 "(%s)", rt3, u_value, rs3); } @@ -8387,7 +8391,7 @@ static char *LHU_GP_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_1__s1(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("LHU %s, 0x%" PRIx64 "($%d)", rt, u_value, 28); } @@ -8409,8 +8413,8 @@ static char *LHU_S9_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("LHU %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -8432,8 +8436,8 @@ static char *LHU_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("LHU %s, 0x%" PRIx64 "(%s)", rt, u_value, rs); } @@ -8455,8 +8459,8 @@ static char *LHUE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("LHUE %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -8478,9 +8482,9 @@ static char *LHUX(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("LHUX %s, %s(%s)", rd, rs, rt); } @@ -8502,9 +8506,9 @@ static char *LHUXS(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("LHUXS %s, %s(%s)", rd, rs, rt); } @@ -8526,9 +8530,9 @@ static char *LHXS(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("LHXS %s, %s(%s)", rd, rs, rt); } @@ -8550,9 +8554,9 @@ static char *LHX(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("LHX %s, %s(%s)", rd, rs, rt); } @@ -8573,7 +8577,7 @@ static char *LI_16_(uint64 instruction, Dis_info *info) uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 eu_value = extract_eu_6_5_4_3_2_1_0(instruction); - const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); int64 eu = encode_eu_from_s_li16(eu_value); return img_format("LI %s, %" PRId64, rt3, eu); @@ -8595,7 +8599,7 @@ static char *LI_48_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("LI %s, %" PRId64, rt, s_value); } @@ -8617,8 +8621,8 @@ static char *LL(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_s2(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("LL %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -8640,8 +8644,8 @@ static char *LLD(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_s3(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("LLD %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -8663,9 +8667,9 @@ static char *LLDP(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ru_value = extract_ru_7_6_5_4_3(instruction); - const char *rt = GPR(rt_value); - const char *ru = GPR(ru_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *ru = GPR(ru_value, info); + const char *rs = GPR(rs_value, info); return img_format("LLDP %s, %s, (%s)", rt, ru, rs); } @@ -8687,8 +8691,8 @@ static char *LLE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_s2(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("LLE %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -8710,9 +8714,9 @@ static char *LLWP(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ru_value = extract_ru_7_6_5_4_3(instruction); - const char *rt = GPR(rt_value); - const char *ru = GPR(ru_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *ru = GPR(ru_value, info); + const char *rs = GPR(rs_value, info); return img_format("LLWP %s, %s, (%s)", rt, ru, rs); } @@ -8734,9 +8738,9 @@ static char *LLWPE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ru_value = extract_ru_7_6_5_4_3(instruction); - const char *rt = GPR(rt_value); - const char *ru = GPR(ru_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *ru = GPR(ru_value, info); + const char *rs = GPR(rs_value, info); return img_format("LLWPE %s, %s, (%s)", rt, ru, rs); } @@ -8759,9 +8763,9 @@ static char *LSA(uint64 instruction, Dis_info *info) uint64 rd_value = extract_rd_15_14_13_12_11(instruction); uint64 u2_value = extract_u2_10_9(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("LSA %s, %s, %s, 0x%" PRIx64, rd, rs, rt, u2_value); } @@ -8782,7 +8786,7 @@ static char *LUI(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); int64 s_value = extract_s__se31_0_11_to_2_20_to_12_s12(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("LUI %s, %%hi(%" PRId64 ")", rt, s_value); } @@ -8804,8 +8808,8 @@ static char *LW_16_(uint64 instruction, Dis_info *info) uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_3_2_1_0__s2(instruction); - const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); - const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); return img_format("LW %s, 0x%" PRIx64 "(%s)", rt3, u_value, rs3); } @@ -8827,8 +8831,8 @@ static char *LW_4X4_(uint64 instruction, Dis_info *info) uint64 rs4_value = extract_rs4_4_2_1_0(instruction); uint64 u_value = extract_u_3_8__s2(instruction); - const char *rt4 = GPR(decode_gpr_gpr4(rt4_value)); - const char *rs4 = GPR(decode_gpr_gpr4(rs4_value)); + const char *rt4 = GPR(decode_gpr_gpr4(rt4_value, info), info); + const char *rs4 = GPR(decode_gpr_gpr4(rs4_value, info), info); return img_format("LW %s, 0x%" PRIx64 "(%s)", rt4, u_value, rs4); } @@ -8849,7 +8853,7 @@ static char *LW_GP_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_to_2__s2(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("LW %s, 0x%" PRIx64 "($%d)", rt, u_value, 28); } @@ -8870,7 +8874,7 @@ static char *LW_GP16_(uint64 instruction, Dis_info *info) uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 u_value = extract_u_6_5_4_3_2_1_0__s2(instruction); - const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); return img_format("LW %s, 0x%" PRIx64 "($%d)", rt3, u_value, 28); } @@ -8892,8 +8896,8 @@ static char *LW_S9_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("LW %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -8914,7 +8918,7 @@ static char *LW_SP_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_9_8_7_6_5(instruction); uint64 u_value = extract_u_4_3_2_1_0__s2(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("LW %s, 0x%" PRIx64 "($%d)", rt, u_value, 29); } @@ -8936,8 +8940,8 @@ static char *LW_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("LW %s, 0x%" PRIx64 "(%s)", rt, u_value, rs); } @@ -8958,7 +8962,7 @@ static char *LWC1_GP_(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_2__s2(instruction); - const char *ft = FPR(ft_value); + const char *ft = FPR(ft_value, info); return img_format("LWC1 %s, 0x%" PRIx64 "($%d)", ft, u_value, 28); } @@ -8980,8 +8984,8 @@ static char *LWC1_S9_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *ft = FPR(ft_value); - const char *rs = GPR(rs_value); + const char *ft = FPR(ft_value, info); + const char *rs = GPR(rs_value, info); return img_format("LWC1 %s, %" PRId64 "(%s)", ft, s_value, rs); } @@ -9003,8 +9007,8 @@ static char *LWC1_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - const char *ft = FPR(ft_value); - const char *rs = GPR(rs_value); + const char *ft = FPR(ft_value, info); + const char *rs = GPR(rs_value, info); return img_format("LWC1 %s, 0x%" PRIx64 "(%s)", ft, u_value, rs); } @@ -9026,9 +9030,9 @@ static char *LWC1X(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ft_value = extract_ft_15_14_13_12_11(instruction); - const char *ft = FPR(ft_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ft = FPR(ft_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("LWC1X %s, %s(%s)", ft, rs, rt); } @@ -9050,9 +9054,9 @@ static char *LWC1XS(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ft_value = extract_ft_15_14_13_12_11(instruction); - const char *ft = FPR(ft_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ft = FPR(ft_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("LWC1XS %s, %s(%s)", ft, rs, rt); } @@ -9074,7 +9078,7 @@ static char *LWC2(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *rs = GPR(rs_value); + const char *rs = GPR(rs_value, info); return img_format("LWC2 CP%" PRIu64 ", %" PRId64 "(%s)", ct_value, s_value, rs); @@ -9097,8 +9101,8 @@ static char *LWE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("LWE %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -9121,8 +9125,8 @@ static char *LWM(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 count3_value = extract_count3_14_13_12(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); uint64 count3 = encode_count3_from_count(count3_value); return img_format("LWM %s, %" PRId64 "(%s), 0x%" PRIx64, @@ -9145,7 +9149,7 @@ static char *LWPC_48_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); g_autofree char *s = ADDRESS(s_value, 6, info); return img_format("LWPC %s, %s", rt, s); @@ -9167,7 +9171,7 @@ static char *LWU_GP_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_2__s2(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("LWU %s, 0x%" PRIx64 "($%d)", rt, u_value, 28); } @@ -9189,8 +9193,8 @@ static char *LWU_S9_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("LWU %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -9212,8 +9216,8 @@ static char *LWU_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("LWU %s, 0x%" PRIx64 "(%s)", rt, u_value, rs); } @@ -9235,9 +9239,9 @@ static char *LWUX(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("LWUX %s, %s(%s)", rd, rs, rt); } @@ -9259,9 +9263,9 @@ static char *LWUXS(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("LWUXS %s, %s(%s)", rd, rs, rt); } @@ -9283,9 +9287,9 @@ static char *LWX(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("LWX %s, %s(%s)", rd, rs, rt); } @@ -9307,9 +9311,9 @@ static char *LWXS_16_(uint64 instruction, Dis_info *info) uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 rd3_value = extract_rd3_3_2_1(instruction); - const char *rd3 = GPR(decode_gpr_gpr3(rd3_value)); - const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); - uint64 rt3 = decode_gpr_gpr3(rt3_value); + const char *rd3 = GPR(decode_gpr_gpr3(rd3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); + uint64 rt3 = decode_gpr_gpr3(rt3_value, info); return img_format("LWXS %s, %s(0x%" PRIx64 ")", rd3, rs3, rt3); } @@ -9331,9 +9335,9 @@ static char *LWXS_32_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("LWXS %s, %s(%s)", rd, rs, rt); } @@ -9356,9 +9360,9 @@ static char *MADD_DSP_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("MADD %s, %s, %s", ac, rs, rt); } @@ -9380,9 +9384,9 @@ static char *MADDF_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("MADDF.D %s, %s, %s", fd, fs, ft); } @@ -9404,9 +9408,9 @@ static char *MADDF_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("MADDF.S %s, %s, %s", fd, fs, ft); } @@ -9429,9 +9433,9 @@ static char *MADDU_DSP_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("MADDU %s, %s, %s", ac, rs, rt); } @@ -9454,9 +9458,9 @@ static char *MAQ_S_W_PHL(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("MAQ_S.W.PHL %s, %s, %s", ac, rs, rt); } @@ -9479,9 +9483,9 @@ static char *MAQ_S_W_PHR(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("MAQ_S.W.PHR %s, %s, %s", ac, rs, rt); } @@ -9504,9 +9508,9 @@ static char *MAQ_SA_W_PHL(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("MAQ_SA.W.PHL %s, %s, %s", ac, rs, rt); } @@ -9529,9 +9533,9 @@ static char *MAQ_SA_W_PHR(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("MAQ_SA.W.PHR %s, %s, %s", ac, rs, rt); } @@ -9553,9 +9557,9 @@ static char *MAX_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("MAX.D %s, %s, %s", fd, fs, ft); } @@ -9577,9 +9581,9 @@ static char *MAX_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("MAX.S %s, %s, %s", fd, fs, ft); } @@ -9601,9 +9605,9 @@ static char *MAXA_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("MAXA.D %s, %s, %s", fd, fs, ft); } @@ -9625,9 +9629,9 @@ static char *MAXA_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("MAXA.S %s, %s, %s", fd, fs, ft); } @@ -9649,7 +9653,7 @@ static char *MFC0(uint64 instruction, Dis_info *info) uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("MFC0 %s, CP%" PRIu64 ", 0x%" PRIx64, rt, c0s_value, sel_value); @@ -9671,8 +9675,8 @@ static char *MFC1(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *fs = FPR(fs_value); + const char *rt = GPR(rt_value, info); + const char *fs = FPR(fs_value, info); return img_format("MFC1 %s, %s", rt, fs); } @@ -9693,7 +9697,7 @@ static char *MFC2(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("MFC2 %s, CP%" PRIu64, rt, cs_value); } @@ -9715,7 +9719,7 @@ static char *MFGC0(uint64 instruction, Dis_info *info) uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("MFGC0 %s, CP%" PRIu64 ", 0x%" PRIx64, rt, c0s_value, sel_value); @@ -9738,7 +9742,7 @@ static char *MFHC0(uint64 instruction, Dis_info *info) uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("MFHC0 %s, CP%" PRIu64 ", 0x%" PRIx64, rt, c0s_value, sel_value); @@ -9760,8 +9764,8 @@ static char *MFHC1(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *fs = FPR(fs_value); + const char *rt = GPR(rt_value, info); + const char *fs = FPR(fs_value, info); return img_format("MFHC1 %s, %s", rt, fs); } @@ -9782,7 +9786,7 @@ static char *MFHC2(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("MFHC2 %s, CP%" PRIu64, rt, cs_value); } @@ -9804,7 +9808,7 @@ static char *MFHGC0(uint64 instruction, Dis_info *info) uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("MFHGC0 %s, CP%" PRIu64 ", 0x%" PRIx64, rt, c0s_value, sel_value); @@ -9825,8 +9829,8 @@ static char *MFHI_DSP_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *rt = GPR(rt_value); - const char *ac = AC(ac_value); + const char *rt = GPR(rt_value, info); + const char *ac = AC(ac_value, info); return img_format("MFHI %s, %s", rt, ac); } @@ -9849,7 +9853,7 @@ static char *MFHTR(uint64 instruction, Dis_info *info) uint64 sel_value = extract_sel_15_14_13_12_11(instruction); uint64 u_value = extract_u_10(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("MFHTR %s, 0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64, rt, c0s_value, u_value, sel_value); @@ -9870,8 +9874,8 @@ static char *MFLO_DSP_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *rt = GPR(rt_value); - const char *ac = AC(ac_value); + const char *rt = GPR(rt_value, info); + const char *ac = AC(ac_value, info); return img_format("MFLO %s, %s", rt, ac); } @@ -9894,7 +9898,7 @@ static char *MFTR(uint64 instruction, Dis_info *info) uint64 sel_value = extract_sel_15_14_13_12_11(instruction); uint64 u_value = extract_u_10(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("MFTR %s, 0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64, rt, c0s_value, u_value, sel_value); @@ -9917,9 +9921,9 @@ static char *MIN_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("MIN.D %s, %s, %s", fd, fs, ft); } @@ -9941,9 +9945,9 @@ static char *MIN_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("MIN.S %s, %s, %s", fd, fs, ft); } @@ -9965,9 +9969,9 @@ static char *MINA_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("MINA.D %s, %s, %s", fd, fs, ft); } @@ -9989,9 +9993,9 @@ static char *MINA_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("MINA.S %s, %s, %s", fd, fs, ft); } @@ -10013,9 +10017,9 @@ static char *MOD(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("MOD %s, %s, %s", rd, rs, rt); } @@ -10037,9 +10041,9 @@ static char *MODSUB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("MODSUB %s, %s, %s", rd, rs, rt); } @@ -10061,9 +10065,9 @@ static char *MODU(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("MODU %s, %s, %s", rd, rs, rt); } @@ -10084,8 +10088,8 @@ static char *MOV_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("MOV.D %s, %s", ft, fs); } @@ -10106,8 +10110,8 @@ static char *MOV_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("MOV.S %s, %s", ft, fs); } @@ -10129,8 +10133,8 @@ static char *MOVE_BALC(uint64 instruction, Dis_info *info) uint64 rd1_value = extract_rdl_25_24(instruction); int64 s_value = extract_s__se21_0_20_to_1_s1(instruction); - const char *rd1 = GPR(decode_gpr_gpr1(rd1_value)); - const char *rtz4 = GPR(decode_gpr_gpr4_zero(rtz4_value)); + const char *rd1 = GPR(decode_gpr_gpr1(rd1_value, info), info); + const char *rtz4 = GPR(decode_gpr_gpr4_zero(rtz4_value, info), info); g_autofree char *s = ADDRESS(s_value, 4, info); return img_format("MOVE.BALC %s, %s, %s", rd1, rtz4, s); @@ -10153,11 +10157,11 @@ static char *MOVEP(uint64 instruction, Dis_info *info) uint64 rd2_value = extract_rd2_3_8(instruction); uint64 rsz4_value = extract_rsz4_4_2_1_0(instruction); - const char *rd2 = GPR(decode_gpr_gpr2_reg1(rd2_value)); - const char *re2 = GPR(decode_gpr_gpr2_reg2(rd2_value)); + const char *rd2 = GPR(decode_gpr_gpr2_reg1(rd2_value, info), info); + const char *re2 = GPR(decode_gpr_gpr2_reg2(rd2_value, info), info); /* !!!!!!!!!! - no conversion function */ - const char *rsz4 = GPR(decode_gpr_gpr4_zero(rsz4_value)); - const char *rtz4 = GPR(decode_gpr_gpr4_zero(rtz4_value)); + const char *rsz4 = GPR(decode_gpr_gpr4_zero(rsz4_value, info), info); + const char *rtz4 = GPR(decode_gpr_gpr4_zero(rtz4_value, info), info); return img_format("MOVEP %s, %s, %s, %s", rd2, re2, rsz4, rtz4); /* hand edited */ @@ -10180,10 +10184,10 @@ static char *MOVEP_REV_(uint64 instruction, Dis_info *info) uint64 rd2_value = extract_rd2_3_8(instruction); uint64 rs4_value = extract_rs4_4_2_1_0(instruction); - const char *rs4 = GPR(decode_gpr_gpr4(rs4_value)); - const char *rt4 = GPR(decode_gpr_gpr4(rt4_value)); - const char *rd2 = GPR(decode_gpr_gpr2_reg1(rd2_value)); - const char *rs2 = GPR(decode_gpr_gpr2_reg2(rd2_value)); + const char *rs4 = GPR(decode_gpr_gpr4(rs4_value, info), info); + const char *rt4 = GPR(decode_gpr_gpr4(rt4_value, info), info); + const char *rd2 = GPR(decode_gpr_gpr2_reg1(rd2_value, info), info); + const char *rs2 = GPR(decode_gpr_gpr2_reg2(rd2_value, info), info); /* !!!!!!!!!! - no conversion function */ return img_format("MOVEP %s, %s, %s, %s", rs4, rt4, rd2, rs2); @@ -10206,8 +10210,8 @@ static char *MOVE(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_9_8_7_6_5(instruction); uint64 rs_value = extract_rs_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("MOVE %s, %s", rt, rs); } @@ -10229,9 +10233,9 @@ static char *MOVN(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("MOVN %s, %s, %s", rd, rs, rt); } @@ -10253,9 +10257,9 @@ static char *MOVZ(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("MOVZ %s, %s, %s", rd, rs, rt); } @@ -10277,9 +10281,9 @@ static char *MSUB_DSP_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("MSUB %s, %s, %s", ac, rs, rt); } @@ -10301,9 +10305,9 @@ static char *MSUBF_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("MSUBF.D %s, %s, %s", fd, fs, ft); } @@ -10325,9 +10329,9 @@ static char *MSUBF_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("MSUBF.S %s, %s, %s", fd, fs, ft); } @@ -10349,9 +10353,9 @@ static char *MSUBU_DSP_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("MSUBU %s, %s, %s", ac, rs, rt); } @@ -10373,7 +10377,7 @@ static char *MTC0(uint64 instruction, Dis_info *info) uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("MTC0 %s, CP%" PRIu64 ", 0x%" PRIx64, rt, c0s_value, sel_value); @@ -10395,8 +10399,8 @@ static char *MTC1(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *fs = FPR(fs_value); + const char *rt = GPR(rt_value, info); + const char *fs = FPR(fs_value, info); return img_format("MTC1 %s, %s", rt, fs); } @@ -10417,7 +10421,7 @@ static char *MTC2(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("MTC2 %s, CP%" PRIu64, rt, cs_value); } @@ -10439,7 +10443,7 @@ static char *MTGC0(uint64 instruction, Dis_info *info) uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("MTGC0 %s, CP%" PRIu64 ", 0x%" PRIx64, rt, c0s_value, sel_value); @@ -10462,7 +10466,7 @@ static char *MTHC0(uint64 instruction, Dis_info *info) uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("MTHC0 %s, CP%" PRIu64 ", 0x%" PRIx64, rt, c0s_value, sel_value); @@ -10484,8 +10488,8 @@ static char *MTHC1(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *fs = FPR(fs_value); + const char *rt = GPR(rt_value, info); + const char *fs = FPR(fs_value, info); return img_format("MTHC1 %s, %s", rt, fs); } @@ -10506,7 +10510,7 @@ static char *MTHC2(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("MTHC2 %s, CP%" PRIu64, rt, cs_value); } @@ -10528,7 +10532,7 @@ static char *MTHGC0(uint64 instruction, Dis_info *info) uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_15_14_13_12_11(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("MTHGC0 %s, CP%" PRIu64 ", 0x%" PRIx64, rt, c0s_value, sel_value); @@ -10549,8 +10553,8 @@ static char *MTHI_DSP_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *rs = GPR(rs_value); - const char *ac = AC(ac_value); + const char *rs = GPR(rs_value, info); + const char *ac = AC(ac_value, info); return img_format("MTHI %s, %s", rs, ac); } @@ -10570,8 +10574,8 @@ static char *MTHLIP(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *rs = GPR(rs_value); - const char *ac = AC(ac_value); + const char *rs = GPR(rs_value, info); + const char *ac = AC(ac_value, info); return img_format("MTHLIP %s, %s", rs, ac); } @@ -10594,7 +10598,7 @@ static char *MTHTR(uint64 instruction, Dis_info *info) uint64 sel_value = extract_sel_15_14_13_12_11(instruction); uint64 u_value = extract_u_10(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("MTHTR %s, 0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64, rt, c0s_value, u_value, sel_value); @@ -10615,8 +10619,8 @@ static char *MTLO_DSP_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *rs = GPR(rs_value); - const char *ac = AC(ac_value); + const char *rs = GPR(rs_value, info); + const char *ac = AC(ac_value, info); return img_format("MTLO %s, %s", rs, ac); } @@ -10639,7 +10643,7 @@ static char *MTTR(uint64 instruction, Dis_info *info) uint64 sel_value = extract_sel_15_14_13_12_11(instruction); uint64 u_value = extract_u_10(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("MTTR %s, 0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64, rt, c0s_value, u_value, sel_value); @@ -10662,9 +10666,9 @@ static char *MUH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("MUH %s, %s, %s", rd, rs, rt); } @@ -10686,9 +10690,9 @@ static char *MUHU(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("MUHU %s, %s, %s", rd, rs, rt); } @@ -10710,9 +10714,9 @@ static char *MUL_32_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("MUL %s, %s, %s", rd, rs, rt); } @@ -10733,8 +10737,8 @@ static char *MUL_4X4_(uint64 instruction, Dis_info *info) uint64 rt4_value = extract_rt4_9_7_6_5(instruction); uint64 rs4_value = extract_rs4_4_2_1_0(instruction); - const char *rs4 = GPR(decode_gpr_gpr4(rs4_value)); - const char *rt4 = GPR(decode_gpr_gpr4(rt4_value)); + const char *rs4 = GPR(decode_gpr_gpr4(rs4_value, info), info); + const char *rt4 = GPR(decode_gpr_gpr4(rt4_value, info), info); return img_format("MUL %s, %s", rs4, rt4); } @@ -10756,9 +10760,9 @@ static char *MUL_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("MUL.D %s, %s, %s", fd, fs, ft); } @@ -10781,9 +10785,9 @@ static char *MUL_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("MUL.PH %s, %s, %s", rd, rs, rt); } @@ -10806,9 +10810,9 @@ static char *MUL_S_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("MUL_S.PH %s, %s, %s", rd, rs, rt); } @@ -10830,9 +10834,9 @@ static char *MUL_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("MUL.S %s, %s, %s", fd, fs, ft); } @@ -10855,9 +10859,9 @@ static char *MULEQ_S_W_PHL(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("MULEQ_S.W.PHL %s, %s, %s", rd, rs, rt); } @@ -10880,9 +10884,9 @@ static char *MULEQ_S_W_PHR(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("MULEQ_S.W.PHR %s, %s, %s", rd, rs, rt); } @@ -10905,9 +10909,9 @@ static char *MULEU_S_PH_QBL(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("MULEU_S.PH.QBL %s, %s, %s", rd, rs, rt); } @@ -10930,9 +10934,9 @@ static char *MULEU_S_PH_QBR(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("MULEU_S.PH.QBR %s, %s, %s", rd, rs, rt); } @@ -10955,9 +10959,9 @@ static char *MULQ_RS_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("MULQ_RS.PH %s, %s, %s", rd, rs, rt); } @@ -10980,9 +10984,9 @@ static char *MULQ_RS_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("MULQ_RS.W %s, %s, %s", rd, rs, rt); } @@ -11005,9 +11009,9 @@ static char *MULQ_S_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("MULQ_S.PH %s, %s, %s", rd, rs, rt); } @@ -11030,9 +11034,9 @@ static char *MULQ_S_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("MULQ_S.W %s, %s, %s", rd, rs, rt); } @@ -11055,9 +11059,9 @@ static char *MULSA_W_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("MULSA.W.PH %s, %s, %s", ac, rs, rt); } @@ -11080,9 +11084,9 @@ static char *MULSAQ_S_W_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("MULSAQ_S.W.PH %s, %s, %s", ac, rs, rt); } @@ -11104,9 +11108,9 @@ static char *MULT_DSP_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("MULT %s, %s, %s", ac, rs, rt); } @@ -11128,9 +11132,9 @@ static char *MULTU_DSP_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *ac = AC(ac_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("MULTU %s, %s, %s", ac, rs, rt); } @@ -11152,9 +11156,9 @@ static char *MULU(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("MULU %s, %s, %s", rd, rs, rt); } @@ -11175,8 +11179,8 @@ static char *NEG_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("NEG.D %s, %s", ft, fs); } @@ -11197,8 +11201,8 @@ static char *NEG_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("NEG.S %s, %s", ft, fs); } @@ -11256,9 +11260,9 @@ static char *NOR(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("NOR %s, %s, %s", rd, rs, rt); } @@ -11279,8 +11283,8 @@ static char *NOT_16_(uint64 instruction, Dis_info *info) uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); - const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); - const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); return img_format("NOT %s, %s", rt3, rs3); } @@ -11301,8 +11305,8 @@ static char *OR_16_(uint64 instruction, Dis_info *info) uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); - const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); - const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); return img_format("OR %s, %s", rs3, rt3); } @@ -11324,9 +11328,9 @@ static char *OR_32_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("OR %s, %s, %s", rd, rs, rt); } @@ -11348,8 +11352,8 @@ static char *ORI(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("ORI %s, %s, 0x%" PRIx64, rt, rs, u_value); } @@ -11372,9 +11376,9 @@ static char *PACKRL_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("PACKRL.PH %s, %s, %s", rd, rs, rt); } @@ -11415,9 +11419,9 @@ static char *PICK_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("PICK.PH %s, %s, %s", rd, rs, rt); } @@ -11440,9 +11444,9 @@ static char *PICK_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("PICK.QB %s, %s, %s", rd, rs, rt); } @@ -11464,8 +11468,8 @@ static char *PRECEQ_W_PHL(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("PRECEQ.W.PHL %s, %s", rt, rs); } @@ -11487,8 +11491,8 @@ static char *PRECEQ_W_PHR(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("PRECEQ.W.PHR %s, %s", rt, rs); } @@ -11510,8 +11514,8 @@ static char *PRECEQU_PH_QBLA(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("PRECEQU.PH.QBLA %s, %s", rt, rs); } @@ -11533,8 +11537,8 @@ static char *PRECEQU_PH_QBL(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("PRECEQU.PH.QBL %s, %s", rt, rs); } @@ -11556,8 +11560,8 @@ static char *PRECEQU_PH_QBRA(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("PRECEQU.PH.QBRA %s, %s", rt, rs); } @@ -11579,8 +11583,8 @@ static char *PRECEQU_PH_QBR(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("PRECEQU.PH.QBR %s, %s", rt, rs); } @@ -11603,8 +11607,8 @@ static char *PRECEU_PH_QBLA(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("PRECEU.PH.QBLA %s, %s", rt, rs); } @@ -11626,8 +11630,8 @@ static char *PRECEU_PH_QBL(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("PRECEU.PH.QBL %s, %s", rt, rs); } @@ -11650,8 +11654,8 @@ static char *PRECEU_PH_QBRA(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("PRECEU.PH.QBRA %s, %s", rt, rs); } @@ -11673,8 +11677,8 @@ static char *PRECEU_PH_QBR(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("PRECEU.PH.QBR %s, %s", rt, rs); } @@ -11697,9 +11701,9 @@ static char *PRECR_QB_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("PRECR.QB.PH %s, %s, %s", rd, rs, rt); } @@ -11722,8 +11726,8 @@ static char *PRECR_SRA_PH_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13_12_11(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("PRECR_SRA.PH.W %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -11746,8 +11750,8 @@ static char *PRECR_SRA_R_PH_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13_12_11(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("PRECR_SRA_R.PH.W %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -11770,9 +11774,9 @@ static char *PRECRQ_PH_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("PRECRQ.PH.W %s, %s, %s", rd, rs, rt); } @@ -11795,9 +11799,9 @@ static char *PRECRQ_QB_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("PRECRQ.QB.PH %s, %s, %s", rd, rs, rt); } @@ -11820,9 +11824,9 @@ static char *PRECRQ_RS_PH_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("PRECRQ_RS.PH.W %s, %s, %s", rd, rs, rt); } @@ -11845,9 +11849,9 @@ static char *PRECRQU_S_QB_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("PRECRQU_S.QB.PH %s, %s, %s", rd, rs, rt); } @@ -11869,7 +11873,7 @@ static char *PREF_S9_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *rs = GPR(rs_value); + const char *rs = GPR(rs_value, info); return img_format("PREF 0x%" PRIx64 ", %s(%s)", hint_value, s_value, rs); @@ -11892,7 +11896,7 @@ static char *PREF_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - const char *rs = GPR(rs_value); + const char *rs = GPR(rs_value, info); return img_format("PREF 0x%" PRIx64 ", 0x%" PRIx64 "(%s)", hint_value, u_value, rs); @@ -11915,7 +11919,7 @@ static char *PREFE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *rs = GPR(rs_value); + const char *rs = GPR(rs_value, info); return img_format("PREFE 0x%" PRIx64 ", %s(%s)", hint_value, s_value, rs); } @@ -11937,8 +11941,8 @@ static char *PREPEND(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13_12_11(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("PREPEND %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -11958,8 +11962,8 @@ static char *RADDU_W_QB(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("RADDU.W.QB %s, %s", rt, rs); } @@ -11979,7 +11983,7 @@ static char *RDDSP(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 mask_value = extract_mask_20_19_18_17_16_15_14(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("RDDSP %s, 0x%" PRIx64, rt, mask_value); } @@ -12001,7 +12005,7 @@ static char *RDHWR(uint64 instruction, Dis_info *info) uint64 hs_value = extract_hs_20_19_18_17_16(instruction); uint64 sel_value = extract_sel_13_12_11(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("RDHWR %s, CP%" PRIu64 ", 0x%" PRIx64, rt, hs_value, sel_value); @@ -12023,8 +12027,8 @@ static char *RDPGPR(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("RDPGPR %s, %s", rt, rs); } @@ -12045,8 +12049,8 @@ static char *RECIP_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("RECIP.D %s, %s", ft, fs); } @@ -12067,8 +12071,8 @@ static char *RECIP_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("RECIP.S %s, %s", ft, fs); } @@ -12089,7 +12093,7 @@ static char *REPL_PH(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); int64 s_value = extract_s__se9_20_19_18_17_16_15_14_13_12_11(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("REPL.PH %s, %s", rt, s_value); } @@ -12110,7 +12114,7 @@ static char *REPL_QB(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_19_18_17_16_15_14_13(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("REPL.QB %s, 0x%" PRIx64, rt, u_value); } @@ -12131,8 +12135,8 @@ static char *REPLV_PH(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("REPLV.PH %s, %s", rt, rs); } @@ -12152,8 +12156,8 @@ static char *REPLV_QB(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("REPLV.QB %s, %s", rt, rs); } @@ -12177,7 +12181,7 @@ static char *RESTORE_32_(uint64 instruction, Dis_info *info) uint64 gp_value = extract_gp_2(instruction); g_autofree char *save_restore_str = save_restore_list( - rt_value, count_value, gp_value); + rt_value, count_value, gp_value, info); return img_format("RESTORE 0x%" PRIx64 "%s", u_value, save_restore_str); } @@ -12199,7 +12203,7 @@ static char *RESTORE_JRC_16_(uint64 instruction, Dis_info *info) uint64 count_value = extract_count_3_2_1_0(instruction); g_autofree char *save_restore_str = save_restore_list( - encode_rt1_from_rt(rt1_value), count_value, 0); + encode_rt1_from_rt(rt1_value), count_value, 0, info); return img_format("RESTORE.JRC 0x%" PRIx64 "%s", u_value, save_restore_str); } @@ -12222,7 +12226,7 @@ static char *RESTORE_JRC_32_(uint64 instruction, Dis_info *info) uint64 gp_value = extract_gp_2(instruction); g_autofree char *save_restore_str = save_restore_list( - rt_value, count_value, gp_value); + rt_value, count_value, gp_value, info); return img_format("RESTORE.JRC 0x%" PRIx64 "%s", u_value, save_restore_str); } @@ -12263,8 +12267,8 @@ static char *RINT_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("RINT.D %s, %s", ft, fs); } @@ -12285,8 +12289,8 @@ static char *RINT_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("RINT.S %s, %s", ft, fs); } @@ -12308,8 +12312,8 @@ static char *ROTR(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("ROTR %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -12331,9 +12335,9 @@ static char *ROTRV(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("ROTRV %s, %s, %s", rd, rs, rt); } @@ -12357,8 +12361,8 @@ static char *ROTX(uint64 instruction, Dis_info *info) uint64 stripe_value = extract_stripe_6(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("ROTX %s, %s, 0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64, rt, rs, shift_value, shiftx_value, stripe_value); @@ -12380,8 +12384,8 @@ static char *ROUND_L_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("ROUND.L.D %s, %s", ft, fs); } @@ -12402,8 +12406,8 @@ static char *ROUND_L_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("ROUND.L.S %s, %s", ft, fs); } @@ -12424,8 +12428,8 @@ static char *ROUND_W_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("ROUND.W.D %s, %s", ft, fs); } @@ -12446,8 +12450,8 @@ static char *ROUND_W_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("ROUND.W.S %s, %s", ft, fs); } @@ -12468,8 +12472,8 @@ static char *RSQRT_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("RSQRT.D %s, %s", ft, fs); } @@ -12490,8 +12494,8 @@ static char *RSQRT_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("RSQRT.S %s, %s", ft, fs); } @@ -12514,7 +12518,7 @@ static char *SAVE_16_(uint64 instruction, Dis_info *info) uint64 count_value = extract_count_3_2_1_0(instruction); g_autofree char *save_restore_str = save_restore_list( - encode_rt1_from_rt(rt1_value), count_value, 0); + encode_rt1_from_rt(rt1_value), count_value, 0, info); return img_format("SAVE 0x%" PRIx64 "%s", u_value, save_restore_str); } @@ -12537,7 +12541,7 @@ static char *SAVE_32_(uint64 instruction, Dis_info *info) uint64 gp_value = extract_gp_2(instruction); g_autofree char *save_restore_str = save_restore_list( - rt_value, count_value, gp_value); + rt_value, count_value, gp_value, info); return img_format("SAVE 0x%" PRIx64 "%s", u_value, save_restore_str); } @@ -12578,8 +12582,8 @@ static char *SB_16_(uint64 instruction, Dis_info *info) uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_1_0(instruction); - const char *rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value)); - const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); return img_format("SB %s, 0x%" PRIx64 "(%s)", rtz3, u_value, rs3); } @@ -12600,7 +12604,7 @@ static char *SB_GP_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_0(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("SB %s, 0x%" PRIx64 "($%d)", rt, u_value, 28); } @@ -12622,8 +12626,8 @@ static char *SB_S9_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SB %s, %s(%s)", rt, s_value, rs); } @@ -12645,8 +12649,8 @@ static char *SB_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SB %s, 0x%" PRIx64 "(%s)", rt, u_value, rs); } @@ -12668,8 +12672,8 @@ static char *SBE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SBE %s, %s(%s)", rt, s_value, rs); } @@ -12691,9 +12695,9 @@ static char *SBX(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("SBX %s, %s(%s)", rd, rs, rt); } @@ -12715,8 +12719,8 @@ static char *SC(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_s2(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SC %s, %s(%s)", rt, s_value, rs); } @@ -12738,8 +12742,8 @@ static char *SCD(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_s3(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SCD %s, %s(%s)", rt, s_value, rs); } @@ -12761,9 +12765,9 @@ static char *SCDP(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ru_value = extract_ru_7_6_5_4_3(instruction); - const char *rt = GPR(rt_value); - const char *ru = GPR(ru_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *ru = GPR(ru_value, info); + const char *rs = GPR(rs_value, info); return img_format("SCDP %s, %s, (%s)", rt, ru, rs); } @@ -12785,8 +12789,8 @@ static char *SCE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_s2(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SCE %s, %s(%s)", rt, s_value, rs); } @@ -12808,9 +12812,9 @@ static char *SCWP(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ru_value = extract_ru_7_6_5_4_3(instruction); - const char *rt = GPR(rt_value); - const char *ru = GPR(ru_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *ru = GPR(ru_value, info); + const char *rs = GPR(rs_value, info); return img_format("SCWP %s, %s, (%s)", rt, ru, rs); } @@ -12832,9 +12836,9 @@ static char *SCWPE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ru_value = extract_ru_7_6_5_4_3(instruction); - const char *rt = GPR(rt_value); - const char *ru = GPR(ru_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *ru = GPR(ru_value, info); + const char *rs = GPR(rs_value, info); return img_format("SCWPE %s, %s, (%s)", rt, ru, rs); } @@ -12855,7 +12859,7 @@ static char *SD_GP_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_to_3__s3(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("SD %s, 0x%" PRIx64 "($%d)", rt, u_value, 28); } @@ -12877,8 +12881,8 @@ static char *SD_S9_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SD %s, %s(%s)", rt, s_value, rs); } @@ -12900,8 +12904,8 @@ static char *SD_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SD %s, 0x%" PRIx64 "(%s)", rt, u_value, rs); } @@ -12960,7 +12964,7 @@ static char *SDC1_GP_(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_2__s2(instruction); - const char *ft = FPR(ft_value); + const char *ft = FPR(ft_value, info); return img_format("SDC1 %s, 0x%" PRIx64 "($%d)", ft, u_value, 28); } @@ -12982,8 +12986,8 @@ static char *SDC1_S9_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *ft = FPR(ft_value); - const char *rs = GPR(rs_value); + const char *ft = FPR(ft_value, info); + const char *rs = GPR(rs_value, info); return img_format("SDC1 %s, %s(%s)", ft, s_value, rs); } @@ -13005,8 +13009,8 @@ static char *SDC1_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - const char *ft = FPR(ft_value); - const char *rs = GPR(rs_value); + const char *ft = FPR(ft_value, info); + const char *rs = GPR(rs_value, info); return img_format("SDC1 %s, 0x%" PRIx64 "(%s)", ft, u_value, rs); } @@ -13028,9 +13032,9 @@ static char *SDC1X(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ft_value = extract_ft_15_14_13_12_11(instruction); - const char *ft = FPR(ft_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ft = FPR(ft_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("SDC1X %s, %s(%s)", ft, rs, rt); } @@ -13052,9 +13056,9 @@ static char *SDC1XS(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ft_value = extract_ft_15_14_13_12_11(instruction); - const char *ft = FPR(ft_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ft = FPR(ft_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("SDC1XS %s, %s(%s)", ft, rs, rt); } @@ -13076,7 +13080,7 @@ static char *SDC2(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *rs = GPR(rs_value); + const char *rs = GPR(rs_value, info); return img_format("SDC2 CP%" PRIu64 ", %s(%s)", cs_value, s_value, rs); } @@ -13099,8 +13103,8 @@ static char *SDM(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 count3_value = extract_count3_14_13_12(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); uint64 count3 = encode_count3_from_count(count3_value); return img_format("SDM %s, %s(%s), 0x%" PRIx64, rt, s_value, rs, count3); @@ -13122,7 +13126,7 @@ static char *SDPC_48_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); g_autofree char *s = ADDRESS(s_value, 6, info); return img_format("SDPC %s, %s", rt, s); @@ -13145,9 +13149,9 @@ static char *SDXS(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("SDXS %s, %s(%s)", rd, rs, rt); } @@ -13169,9 +13173,9 @@ static char *SDX(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("SDX %s, %s(%s)", rd, rs, rt); } @@ -13192,8 +13196,8 @@ static char *SEB(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SEB %s, %s", rt, rs); } @@ -13214,8 +13218,8 @@ static char *SEH(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SEH %s, %s", rt, rs); } @@ -13237,9 +13241,9 @@ static char *SEL_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("SEL.D %s, %s, %s", fd, fs, ft); } @@ -13261,9 +13265,9 @@ static char *SEL_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("SEL.S %s, %s, %s", fd, fs, ft); } @@ -13285,9 +13289,9 @@ static char *SELEQZ_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("SELEQZ.D %s, %s, %s", fd, fs, ft); } @@ -13309,9 +13313,9 @@ static char *SELEQZ_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("SELEQZ.S %s, %s, %s", fd, fs, ft); } @@ -13333,9 +13337,9 @@ static char *SELNEZ_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("SELNEZ.D %s, %s, %s", fd, fs, ft); } @@ -13357,9 +13361,9 @@ static char *SELNEZ_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("SELNEZ.S %s, %s, %s", fd, fs, ft); } @@ -13381,8 +13385,8 @@ static char *SEQI(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SEQI %s, %s, 0x%" PRIx64, rt, rs, u_value); } @@ -13404,8 +13408,8 @@ static char *SH_16_(uint64 instruction, Dis_info *info) uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_2_1__s1(instruction); - const char *rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value)); - const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); return img_format("SH %s, 0x%" PRIx64 "(%s)", rtz3, u_value, rs3); } @@ -13426,7 +13430,7 @@ static char *SH_GP_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_1__s1(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("SH %s, 0x%" PRIx64 "($%d)", rt, u_value, 28); } @@ -13448,8 +13452,8 @@ static char *SH_S9_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SH %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -13471,8 +13475,8 @@ static char *SH_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SH %s, 0x%" PRIx64 "(%s)", rt, u_value, rs); } @@ -13494,8 +13498,8 @@ static char *SHE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SHE %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -13516,7 +13520,7 @@ static char *SHILO(uint64 instruction, Dis_info *info) int64 shift_value = extract_shift__se5_21_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *ac = AC(ac_value); + const char *ac = AC(ac_value, info); return img_format("SHILO %s, 0x%" PRIx64, ac, shift_value); } @@ -13537,8 +13541,8 @@ static char *SHILOV(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - const char *rs = GPR(rs_value); - const char *ac = AC(ac_value); + const char *rs = GPR(rs_value, info); + const char *ac = AC(ac_value, info); return img_format("SHILOV %s, %s", ac, rs); } @@ -13560,8 +13564,8 @@ static char *SHLL_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13_12(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SHLL.PH %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -13583,8 +13587,8 @@ static char *SHLL_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SHLL.QB %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -13607,8 +13611,8 @@ static char *SHLL_S_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13_12(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SHLL_S.PH %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -13630,8 +13634,8 @@ static char *SHLL_S_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13_12_11(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SHLL_S.W %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -13654,9 +13658,9 @@ static char *SHLLV_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rd = GPR(rd_value, info); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SHLLV.PH %s, %s, %s", rd, rt, rs); } @@ -13678,9 +13682,9 @@ static char *SHLLV_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rd = GPR(rd_value, info); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SHLLV.QB %s, %s, %s", rd, rt, rs); } @@ -13703,9 +13707,9 @@ static char *SHLLV_S_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rd = GPR(rd_value, info); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SHLLV_S.PH %s, %s, %s", rd, rt, rs); } @@ -13727,9 +13731,9 @@ static char *SHLLV_S_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rd = GPR(rd_value, info); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SHLLV_S.W %s, %s, %s", rd, rt, rs); } @@ -13751,8 +13755,8 @@ static char *SHRA_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13_12(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SHRA.PH %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -13774,8 +13778,8 @@ static char *SHRA_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SHRA.QB %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -13797,8 +13801,8 @@ static char *SHRA_R_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13_12(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SHRA_R.PH %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -13820,8 +13824,8 @@ static char *SHRA_R_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SHRA_R.QB %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -13843,8 +13847,8 @@ static char *SHRA_R_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13_12_11(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SHRA_R.W %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -13866,9 +13870,9 @@ static char *SHRAV_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rd = GPR(rd_value, info); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SHRAV.PH %s, %s, %s", rd, rt, rs); } @@ -13890,9 +13894,9 @@ static char *SHRAV_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rd = GPR(rd_value, info); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SHRAV.QB %s, %s, %s", rd, rt, rs); } @@ -13914,9 +13918,9 @@ static char *SHRAV_R_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rd = GPR(rd_value, info); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SHRAV_R.PH %s, %s, %s", rd, rt, rs); } @@ -13938,9 +13942,9 @@ static char *SHRAV_R_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rd = GPR(rd_value, info); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SHRAV_R.QB %s, %s, %s", rd, rt, rs); } @@ -13962,9 +13966,9 @@ static char *SHRAV_R_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rd = GPR(rd_value, info); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SHRAV_R.W %s, %s, %s", rd, rt, rs); } @@ -13986,8 +13990,8 @@ static char *SHRL_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13_12(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SHRL.PH %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -14009,8 +14013,8 @@ static char *SHRL_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 sa_value = extract_sa_15_14_13(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SHRL.QB %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -14033,9 +14037,9 @@ static char *SHRLV_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rd = GPR(rd_value, info); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SHRLV.PH %s, %s, %s", rd, rt, rs); } @@ -14057,9 +14061,9 @@ static char *SHRLV_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rd = GPR(rd_value, info); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SHRLV.QB %s, %s, %s", rd, rt, rs); } @@ -14081,9 +14085,9 @@ static char *SHX(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("SHX %s, %s(%s)", rd, rs, rt); } @@ -14105,9 +14109,9 @@ static char *SHXS(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("SHXS %s, %s(%s)", rd, rs, rt); } @@ -14148,8 +14152,8 @@ static char *SLL_16_(uint64 instruction, Dis_info *info) uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 shift3_value = extract_shift3_2_1_0(instruction); - const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); - const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); uint64 shift3 = encode_shift3_from_shift(shift3_value); return img_format("SLL %s, %s, 0x%" PRIx64, rt3, rs3, shift3); @@ -14172,8 +14176,8 @@ static char *SLL_32_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SLL %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -14195,9 +14199,9 @@ static char *SLLV(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("SLLV %s, %s, %s", rd, rs, rt); } @@ -14219,9 +14223,9 @@ static char *SLT(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("SLT %s, %s, %s", rd, rs, rt); } @@ -14243,8 +14247,8 @@ static char *SLTI(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SLTI %s, %s, 0x%" PRIx64, rt, rs, u_value); } @@ -14266,8 +14270,8 @@ static char *SLTIU(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SLTIU %s, %s, 0x%" PRIx64, rt, rs, u_value); } @@ -14289,9 +14293,9 @@ static char *SLTU(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("SLTU %s, %s, %s", rd, rs, rt); } @@ -14313,9 +14317,9 @@ static char *SOV(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("SOV %s, %s, %s", rd, rs, rt); } @@ -14355,8 +14359,8 @@ static char *SQRT_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("SQRT.D %s, %s", ft, fs); } @@ -14377,8 +14381,8 @@ static char *SQRT_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("SQRT.S %s, %s", ft, fs); } @@ -14400,8 +14404,8 @@ static char *SRA(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SRA %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -14423,9 +14427,9 @@ static char *SRAV(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("SRAV %s, %s, %s", rd, rs, rt); } @@ -14447,8 +14451,8 @@ static char *SRL_16_(uint64 instruction, Dis_info *info) uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 shift3_value = extract_shift3_2_1_0(instruction); - const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); - const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); uint64 shift3 = encode_shift3_from_shift(shift3_value); return img_format("SRL %s, %s, 0x%" PRIx64, rt3, rs3, shift3); @@ -14471,8 +14475,8 @@ static char *SRL_32_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shift_value = extract_shift_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SRL %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -14494,9 +14498,9 @@ static char *SRLV(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("SRLV %s, %s, %s", rd, rs, rt); } @@ -14518,9 +14522,9 @@ static char *SUB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("SUB %s, %s, %s", rd, rs, rt); } @@ -14542,9 +14546,9 @@ static char *SUB_D(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("SUB.D %s, %s, %s", fd, fs, ft); } @@ -14566,9 +14570,9 @@ static char *SUB_S(uint64 instruction, Dis_info *info) uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - const char *fd = FPR(fd_value); - const char *fs = FPR(fs_value); - const char *ft = FPR(ft_value); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); return img_format("SUB.S %s, %s, %s", fd, fs, ft); } @@ -14590,9 +14594,9 @@ static char *SUBQ_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("SUBQ.PH %s, %s, %s", rd, rs, rt); } @@ -14615,9 +14619,9 @@ static char *SUBQ_S_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("SUBQ_S.PH %s, %s, %s", rd, rs, rt); } @@ -14640,9 +14644,9 @@ static char *SUBQ_S_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("SUBQ_S.W %s, %s, %s", rd, rs, rt); } @@ -14665,9 +14669,9 @@ static char *SUBQH_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("SUBQH.PH %s, %s, %s", rd, rs, rt); } @@ -14690,9 +14694,9 @@ static char *SUBQH_R_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("SUBQH_R.PH %s, %s, %s", rd, rs, rt); } @@ -14715,9 +14719,9 @@ static char *SUBQH_R_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("SUBQH_R.W %s, %s, %s", rd, rs, rt); } @@ -14740,9 +14744,9 @@ static char *SUBQH_W(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("SUBQH.W %s, %s, %s", rd, rs, rt); } @@ -14764,9 +14768,9 @@ static char *SUBU_16_(uint64 instruction, Dis_info *info) uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 rd3_value = extract_rd3_3_2_1(instruction); - const char *rd3 = GPR(decode_gpr_gpr3(rd3_value)); - const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); - const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); + const char *rd3 = GPR(decode_gpr_gpr3(rd3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); return img_format("SUBU %s, %s, %s", rd3, rs3, rt3); } @@ -14788,9 +14792,9 @@ static char *SUBU_32_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("SUBU %s, %s, %s", rd, rs, rt); } @@ -14812,9 +14816,9 @@ static char *SUBU_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("SUBU.PH %s, %s, %s", rd, rs, rt); } @@ -14836,9 +14840,9 @@ static char *SUBU_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("SUBU.QB %s, %s, %s", rd, rs, rt); } @@ -14861,9 +14865,9 @@ static char *SUBU_S_PH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("SUBU_S.PH %s, %s, %s", rd, rs, rt); } @@ -14886,9 +14890,9 @@ static char *SUBU_S_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("SUBU_S.QB %s, %s, %s", rd, rs, rt); } @@ -14911,9 +14915,9 @@ static char *SUBUH_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("SUBUH.QB %s, %s, %s", rd, rs, rt); } @@ -14936,9 +14940,9 @@ static char *SUBUH_R_QB(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("SUBUH_R.QB %s, %s, %s", rd, rs, rt); } @@ -14960,8 +14964,8 @@ static char *SW_16_(uint64 instruction, Dis_info *info) uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_3_2_1_0__s2(instruction); - const char *rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value)); - const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); return img_format("SW %s, 0x%" PRIx64 "(%s)", rtz3, u_value, rs3); } @@ -14983,8 +14987,8 @@ static char *SW_4X4_(uint64 instruction, Dis_info *info) uint64 rs4_value = extract_rs4_4_2_1_0(instruction); uint64 u_value = extract_u_3_8__s2(instruction); - const char *rtz4 = GPR(decode_gpr_gpr4_zero(rtz4_value)); - const char *rs4 = GPR(decode_gpr_gpr4(rs4_value)); + const char *rtz4 = GPR(decode_gpr_gpr4_zero(rtz4_value, info), info); + const char *rs4 = GPR(decode_gpr_gpr4(rs4_value, info), info); return img_format("SW %s, 0x%" PRIx64 "(%s)", rtz4, u_value, rs4); } @@ -15005,7 +15009,7 @@ static char *SW_GP16_(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_6_5_4_3_2_1_0__s2(instruction); uint64 rtz3_value = extract_rtz3_9_8_7(instruction); - const char *rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value)); + const char *rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value, info), info); return img_format("SW %s, 0x%" PRIx64 "($%d)", rtz3, u_value, 28); } @@ -15026,7 +15030,7 @@ static char *SW_GP_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_to_2__s2(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("SW %s, 0x%" PRIx64 "($%d)", rt, u_value, 28); } @@ -15048,8 +15052,8 @@ static char *SW_S9_(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SW %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -15070,7 +15074,7 @@ static char *SW_SP_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_9_8_7_6_5(instruction); uint64 u_value = extract_u_4_3_2_1_0__s2(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("SW %s, 0x%" PRIx64 "($%d)", rt, u_value, 29); } @@ -15092,8 +15096,8 @@ static char *SW_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SW %s, 0x%" PRIx64 "(%s)", rt, u_value, rs); } @@ -15114,7 +15118,7 @@ static char *SWC1_GP_(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_2__s2(instruction); - const char *ft = FPR(ft_value); + const char *ft = FPR(ft_value, info); return img_format("SWC1 %s, 0x%" PRIx64 "($%d)", ft, u_value, 28); } @@ -15136,8 +15140,8 @@ static char *SWC1_S9_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *ft = FPR(ft_value); - const char *rs = GPR(rs_value); + const char *ft = FPR(ft_value, info); + const char *rs = GPR(rs_value, info); return img_format("SWC1 %s, %" PRId64 "(%s)", ft, s_value, rs); } @@ -15159,8 +15163,8 @@ static char *SWC1_U12_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - const char *ft = FPR(ft_value); - const char *rs = GPR(rs_value); + const char *ft = FPR(ft_value, info); + const char *rs = GPR(rs_value, info); return img_format("SWC1 %s, 0x%" PRIx64 "(%s)", ft, u_value, rs); } @@ -15182,9 +15186,9 @@ static char *SWC1X(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ft_value = extract_ft_15_14_13_12_11(instruction); - const char *ft = FPR(ft_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ft = FPR(ft_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("SWC1X %s, %s(%s)", ft, rs, rt); } @@ -15206,9 +15210,9 @@ static char *SWC1XS(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ft_value = extract_ft_15_14_13_12_11(instruction); - const char *ft = FPR(ft_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *ft = FPR(ft_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("SWC1XS %s, %s(%s)", ft, rs, rt); } @@ -15230,7 +15234,7 @@ static char *SWC2(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *rs = GPR(rs_value); + const char *rs = GPR(rs_value, info); return img_format("SWC2 CP%" PRIu64 ", %" PRId64 "(%s)", cs_value, s_value, rs); @@ -15253,8 +15257,8 @@ static char *SWE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("SWE %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -15277,8 +15281,8 @@ static char *SWM(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 count3_value = extract_count3_14_13_12(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); uint64 count3 = encode_count3_from_count(count3_value); return img_format("SWM %s, %" PRId64 "(%s), 0x%" PRIx64, @@ -15301,7 +15305,7 @@ static char *SWPC_48_(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); g_autofree char *s = ADDRESS(s_value, 6, info); return img_format("SWPC %s, %s", rt, s); @@ -15324,9 +15328,9 @@ static char *SWX(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("SWX %s, %s(%s)", rd, rs, rt); } @@ -15348,9 +15352,9 @@ static char *SWXS(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("SWXS %s, %s(%s)", rd, rs, rt); } @@ -15390,7 +15394,7 @@ static char *SYNCI(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *rs = GPR(rs_value); + const char *rs = GPR(rs_value, info); return img_format("SYNCI %" PRId64 "(%s)", s_value, rs); } @@ -15411,7 +15415,7 @@ static char *SYNCIE(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *rs = GPR(rs_value); + const char *rs = GPR(rs_value, info); return img_format("SYNCIE %" PRId64 "(%s)", s_value, rs); } @@ -15468,8 +15472,8 @@ static char *TEQ(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("TEQ %s, %s", rs, rt); } @@ -15706,8 +15710,8 @@ static char *TNE(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("TNE %s, %s", rs, rt); } @@ -15728,8 +15732,8 @@ static char *TRUNC_L_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("TRUNC.L.D %s, %s", ft, fs); } @@ -15750,8 +15754,8 @@ static char *TRUNC_L_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("TRUNC.L.S %s, %s", ft, fs); } @@ -15772,8 +15776,8 @@ static char *TRUNC_W_D(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("TRUNC.W.D %s, %s", ft, fs); } @@ -15794,8 +15798,8 @@ static char *TRUNC_W_S(uint64 instruction, Dis_info *info) uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - const char *ft = FPR(ft_value); - const char *fs = FPR(fs_value); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); return img_format("TRUNC.W.S %s, %s", ft, fs); } @@ -15818,8 +15822,8 @@ static char *UALDM(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 count3_value = extract_count3_14_13_12(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); uint64 count3 = encode_count3_from_count(count3_value); return img_format("UALDM %s, %" PRId64 "(%s), 0x%" PRIx64, @@ -15843,8 +15847,8 @@ static char *UALH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("UALH %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -15867,8 +15871,8 @@ static char *UALWM(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 count3_value = extract_count3_14_13_12(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); uint64 count3 = encode_count3_from_count(count3_value); return img_format("UALWM %s, %" PRId64 "(%s), 0x%" PRIx64, @@ -15893,8 +15897,8 @@ static char *UASDM(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 count3_value = extract_count3_14_13_12(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); uint64 count3 = encode_count3_from_count(count3_value); return img_format("UASDM %s, %" PRId64 "(%s), 0x%" PRIx64, @@ -15918,8 +15922,8 @@ static char *UASH(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("UASH %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -15942,8 +15946,8 @@ static char *UASWM(uint64 instruction, Dis_info *info) int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 count3_value = extract_count3_14_13_12(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); uint64 count3 = encode_count3_from_count(count3_value); return img_format("UASWM %s, %" PRId64 "(%s), 0x%" PRIx64, @@ -16002,7 +16006,7 @@ static char *WRDSP(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 mask_value = extract_mask_20_19_18_17_16_15_14(instruction); - const char *rt = GPR(rt_value); + const char *rt = GPR(rt_value, info); return img_format("WRDSP %s, 0x%" PRIx64, rt, mask_value); } @@ -16023,8 +16027,8 @@ static char *WRPGPR(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("WRPGPR %s, %s", rt, rs); } @@ -16045,8 +16049,8 @@ static char *XOR_16_(uint64 instruction, Dis_info *info) uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); - const char *rs3 = GPR(decode_gpr_gpr3(rs3_value)); - const char *rt3 = GPR(decode_gpr_gpr3(rt3_value)); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); return img_format("XOR %s, %s", rs3, rt3); } @@ -16068,9 +16072,9 @@ static char *XOR_32_(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - const char *rd = GPR(rd_value); - const char *rs = GPR(rs_value); - const char *rt = GPR(rt_value); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); return img_format("XOR %s, %s, %s", rd, rs, rt); } @@ -16092,8 +16096,8 @@ static char *XORI(uint64 instruction, Dis_info *info) uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("XORI %s, %s, 0x%" PRIx64, rt, rs, u_value); } @@ -16113,8 +16117,8 @@ static char *YIELD(uint64 instruction, Dis_info *info) uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - const char *rt = GPR(rt_value); - const char *rs = GPR(rs_value); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); return img_format("YIELD %s, %s", rt, rs); } @@ -21948,6 +21952,8 @@ int print_insn_nanomips(bfd_vma memaddr, struct disassemble_info *info) Dis_info disassm_info; disassm_info.m_pc = memaddr; + disassm_info.fprintf_func = info->fprintf_func; + disassm_info.stream = info->stream; status = (*info->read_memory_func)(memaddr, buffer, 2, info); if (status != 0) { From 39399c381d3bfc8f651f6d64f9f1f37d9763a8e3 Mon Sep 17 00:00:00 2001 From: Milica Lazarevic Date: Mon, 12 Sep 2022 14:26:32 +0200 Subject: [PATCH 442/705] disas/nanomips: Replace exception handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since there's no support for exception handling in C, the try-catch blocks have been deleted, and throw clauses are replaced. When a runtime error happens, we're printing out the error message. Disassembling of the current instruction interrupts. This behavior is achieved by adding sigsetjmp() to discard further disassembling after the error message prints and by adding the siglongjmp() function to imitate throwing an error. The goal was to maintain the same output as it was. Signed-off-by: Milica Lazarevic Reviewed-by: Richard Henderson Message-Id: <20220912122635.74032-22-milica.lazarevic@syrmia.com> Signed-off-by: Philippe Mathieu-Daudé --- disas/nanomips.cpp | 100 ++++++++++++++++++++------------------------- 1 file changed, 45 insertions(+), 55 deletions(-) diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp index 73329462ee..1832c2d3cf 100644 --- a/disas/nanomips.cpp +++ b/disas/nanomips.cpp @@ -31,7 +31,6 @@ #include "disas/dis-asm.h" #include -#include #include #include @@ -133,10 +132,9 @@ static uint64 renumber_registers(uint64 index, uint64 *register_list, return register_list[index]; } - throw std::runtime_error(img_format( - "Invalid register mapping index %" PRIu64 - ", size of list = %zu", - index, register_list_size)); + info->fprintf_func(info->stream, "Invalid register mapping index %" PRIu64 + ", size of list = %zu", index, register_list_size); + siglongjmp(info->buf, 1); } @@ -466,8 +464,9 @@ static const char *GPR(uint64 reg, Dis_info *info) return gpr_reg[reg]; } - throw std::runtime_error(img_format("Invalid GPR register index %" PRIu64, - reg)); + info->fprintf_func(info->stream, "Invalid GPR register index %" PRIu64, + reg); + siglongjmp(info->buf, 1); } @@ -503,8 +502,9 @@ static const char *FPR(uint64 reg, Dis_info *info) return fpr_reg[reg]; } - throw std::runtime_error(img_format("Invalid FPR register index %" PRIu64, - reg)); + info->fprintf_func(info->stream, "Invalid FPR register index %" PRIu64, + reg); + siglongjmp(info->buf, 1); } @@ -518,8 +518,9 @@ static const char *AC(uint64 reg, Dis_info *info) return ac_reg[reg]; } - throw std::runtime_error(img_format("Invalid AC register index %" PRIu64, - reg)); + info->fprintf_func(info->stream, "Invalid AC register index %" PRIu64, + reg); + siglongjmp(info->buf, 1); } @@ -562,55 +563,38 @@ static int Disassemble(const uint16 *data, char **dis, TABLE_ENTRY_TYPE & type, const Pool *table, int table_size, Dis_info *info) { - try - { - for (int i = 0; i < table_size; i++) { - uint64 op_code = extract_op_code_value(data, - table[i].instructions_size); - if ((op_code & table[i].mask) == table[i].value) { - /* possible match */ - conditional_function cond = table[i].condition; - if ((cond == NULL) || cond(op_code)) { - try - { - if (table[i].type == pool) { - return Disassemble(data, dis, type, - table[i].next_table, - table[i].next_table_size, - info); - } else if ((table[i].type == instruction) || - (table[i].type == call_instruction) || - (table[i].type == branch_instruction) || - (table[i].type == return_instruction)) { - disassembly_function dis_fn = table[i].disassembly; - if (dis_fn == 0) { - *dis = g_strdup( - "disassembler failure - bad table entry"); - return -6; - } - type = table[i].type; - *dis = dis_fn(op_code, info); - return table[i].instructions_size; - } else { - *dis = g_strdup("reserved instruction"); - return -2; - } - } - catch (std::runtime_error & e) - { - *dis = g_strdup(e.what()); - return -3; /* runtime error */ + for (int i = 0; i < table_size; i++) { + uint64 op_code = extract_op_code_value(data, + table[i].instructions_size); + if ((op_code & table[i].mask) == table[i].value) { + /* possible match */ + conditional_function cond = table[i].condition; + if ((cond == NULL) || cond(op_code)) { + if (table[i].type == pool) { + return Disassemble(data, dis, type, + table[i].next_table, + table[i].next_table_size, + info); + } else if ((table[i].type == instruction) || + (table[i].type == call_instruction) || + (table[i].type == branch_instruction) || + (table[i].type == return_instruction)) { + disassembly_function dis_fn = table[i].disassembly; + if (dis_fn == 0) { + *dis = g_strdup( + "disassembler failure - bad table entry"); + return -6; } + type = table[i].type; + *dis = dis_fn(op_code, info); + return table[i].instructions_size; + } else { + *dis = g_strdup("reserved instruction"); + return -2; } } } } - catch (std::exception & e) - { - *dis = g_strdup(e.what()); - return -4; /* runtime error */ - } - *dis = g_strdup("failed to disassemble"); return -1; /* failed to disassemble */ } @@ -22003,6 +21987,12 @@ int print_insn_nanomips(bfd_vma memaddr, struct disassemble_info *info) (*info->fprintf_func)(info->stream, " "); } + /* Handle runtime errors. */ + if (sigsetjmp(disassm_info.buf, 0) != 0) { + info->insn_type = dis_noninsn; + return insn3 ? 6 : insn2 ? 4 : 2; + } + int length = nanomips_dis(&buf, &disassm_info, insn1, insn2, insn3); /* FIXME: Should probably use a hash table on the major opcode here. */ From e8ba8ef873222178e238618d6d4b65b82cf47f41 Mon Sep 17 00:00:00 2001 From: Milica Lazarevic Date: Mon, 12 Sep 2022 14:26:33 +0200 Subject: [PATCH 443/705] disas/nanomips: Replace Cpp enums for C enums MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change enums to typedef enums to keep naming clear. Signed-off-by: Milica Lazarevic Reviewed-by: Thomas Huth Reviewed-by: Richard Henderson Message-Id: <20220912122635.74032-23-milica.lazarevic@syrmia.com> Signed-off-by: Philippe Mathieu-Daudé --- disas/nanomips.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp index 1832c2d3cf..8b4bc910a4 100644 --- a/disas/nanomips.cpp +++ b/disas/nanomips.cpp @@ -40,16 +40,16 @@ typedef uint32_t uint32; typedef uint16_t uint16; typedef uint64_t img_address; -enum TABLE_ENTRY_TYPE { +typedef enum { instruction, call_instruction, branch_instruction, return_instruction, reserved_block, pool, -}; +} TABLE_ENTRY_TYPE; -enum TABLE_ATTRIBUTE_TYPE { +typedef enum { MIPS64_ = 0x00000001, XNP_ = 0x00000002, XMMS_ = 0x00000004, @@ -67,7 +67,7 @@ enum TABLE_ATTRIBUTE_TYPE { TLB_ = 0x00004000, MVH_ = 0x00008000, ALL_ATTRIBUTES = 0xffffffffull, -}; +} TABLE_ATTRIBUTE_TYPE; typedef struct Dis_info { img_address m_pc; From a0fee129445af73c1de7b56472dff14113bc4dc7 Mon Sep 17 00:00:00 2001 From: Milica Lazarevic Date: Mon, 12 Sep 2022 14:26:34 +0200 Subject: [PATCH 444/705] disas/nanomips: Remove argument passing by ref MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaced argument passing by reference with passing by address. Signed-off-by: Milica Lazarevic Reviewed-by: Thomas Huth Reviewed-by: Richard Henderson Message-Id: <20220912122635.74032-24-milica.lazarevic@syrmia.com> Signed-off-by: Philippe Mathieu-Daudé --- disas/nanomips.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp index 8b4bc910a4..9647f1a8e3 100644 --- a/disas/nanomips.cpp +++ b/disas/nanomips.cpp @@ -560,7 +560,7 @@ static uint64 extract_op_code_value(const uint16 *data, int size) * disassembly string - on error will constain error string */ static int Disassemble(const uint16 *data, char **dis, - TABLE_ENTRY_TYPE & type, const Pool *table, + TABLE_ENTRY_TYPE *type, const Pool *table, int table_size, Dis_info *info) { for (int i = 0; i < table_size; i++) { @@ -585,7 +585,7 @@ static int Disassemble(const uint16 *data, char **dis, "disassembler failure - bad table entry"); return -6; } - type = table[i].type; + *type = table[i].type; *dis = dis_fn(op_code, info); return table[i].instructions_size; } else { @@ -21914,7 +21914,7 @@ static int nanomips_dis(char **buf, uint16 bits[3] = {one, two, three}; TABLE_ENTRY_TYPE type; - int size = Disassemble(bits, buf, type, MAJOR, 2, info); + int size = Disassemble(bits, buf, &type, MAJOR, 2, info); return size; } From 2413e000bb6efd47fda78ae1dfebd946323e3d9d Mon Sep 17 00:00:00 2001 From: Milica Lazarevic Date: Mon, 12 Sep 2022 14:26:35 +0200 Subject: [PATCH 445/705] disas/nanomips: Rename nanomips.cpp to nanomips.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that everything has been converted to C code the nanomips.cpp file has been renamed. Therefore, meson.build file is also changed. Signed-off-by: Milica Lazarevic Reviewed-by: Richard Henderson Message-Id: <20220912122635.74032-25-milica.lazarevic@syrmia.com> Signed-off-by: Philippe Mathieu-Daudé --- disas/meson.build | 2 +- disas/{nanomips.cpp => nanomips.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename disas/{nanomips.cpp => nanomips.c} (100%) diff --git a/disas/meson.build b/disas/meson.build index ba22f7cbcd..1977f5cd92 100644 --- a/disas/meson.build +++ b/disas/meson.build @@ -5,7 +5,7 @@ common_ss.add(when: 'CONFIG_HPPA_DIS', if_true: files('hppa.c')) common_ss.add(when: 'CONFIG_M68K_DIS', if_true: files('m68k.c')) common_ss.add(when: 'CONFIG_MICROBLAZE_DIS', if_true: files('microblaze.c')) common_ss.add(when: 'CONFIG_MIPS_DIS', if_true: files('mips.c')) -common_ss.add(when: 'CONFIG_NANOMIPS_DIS', if_true: files('nanomips.cpp')) +common_ss.add(when: 'CONFIG_NANOMIPS_DIS', if_true: files('nanomips.c')) common_ss.add(when: 'CONFIG_NIOS2_DIS', if_true: files('nios2.c')) common_ss.add(when: 'CONFIG_RISCV_DIS', if_true: files('riscv.c')) common_ss.add(when: 'CONFIG_SH4_DIS', if_true: files('sh4.c')) diff --git a/disas/nanomips.cpp b/disas/nanomips.c similarity index 100% rename from disas/nanomips.cpp rename to disas/nanomips.c From a6d89b454cec2de235595ea311d3cc3c49c3aaaa Mon Sep 17 00:00:00 2001 From: David Daney Date: Fri, 14 Oct 2022 13:23:22 +0200 Subject: [PATCH 446/705] disas/mips: Fix branch displacement for BEQZC and BNEZC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit disas/mips.c got added in commit 6643d27ea0 ("MIPS disas support") apparently based on binutils tag 'gdb_6_1-branchpoint' [1]. Back then, MIPSr6 was not supported (added in binutils commit 7361da2c952 during 2014 [2]). Binutils codebase diverged so much over the last 18 years, it is not possible to simply cherry-pick their changes, so fix it BEQZC / BNEZC 21-bit signed branch displacement locally. [1] https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=opcodes/mips-dis.c;hb=refs/tags/gdb_6_1-branchpoint [2] https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=7361da2c952 Fixes: 31837be3ee ("target-mips: add compact and CP1 branches") Signed-off-by: David Daney Reviewed-by: Marcin Nowakowski [PMD: Added commit description] Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20221014112322.61119-1-philmd@fungible.com> Signed-off-by: Philippe Mathieu-Daudé --- disas/mips.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/disas/mips.c b/disas/mips.c index b9a5204304..5aacacb2c8 100644 --- a/disas/mips.c +++ b/disas/mips.c @@ -20,6 +20,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, see . */ #include "qemu/osdep.h" +#include "qemu/bitops.h" #include "disas/dis-asm.h" /* mips.h. Mips opcode list for GDB, the GNU debugger. @@ -1334,9 +1335,9 @@ const struct mips_opcode mips_builtin_opcodes[] = {"balc", "+p", 0xe8000000, 0xfc000000, UBD|WR_31, 0, I32R6}, {"bc", "+p", 0xc8000000, 0xfc000000, UBD|WR_31, 0, I32R6}, {"jic", "t,o", 0xd8000000, 0xffe00000, UBD|RD_t, 0, I32R6}, -{"beqzc", "s,+p", 0xd8000000, 0xfc000000, CBD|RD_s, 0, I32R6}, +{"beqzc", "s,+q", 0xd8000000, 0xfc000000, CBD|RD_s, 0, I32R6}, {"jialc", "t,o", 0xf8000000, 0xffe00000, UBD|RD_t, 0, I32R6}, -{"bnezc", "s,+p", 0xf8000000, 0xfc000000, CBD|RD_s, 0, I32R6}, +{"bnezc", "s,+q", 0xf8000000, 0xfc000000, CBD|RD_s, 0, I32R6}, {"beqzalc", "s,t,p", 0x20000000, 0xffe00000, CBD|RD_s|RD_t, 0, I32R6}, {"bovc", "s,t,p", 0x20000000, 0xfc000000, CBD|RD_s|RD_t, 0, I32R6}, {"beqc", "s,t,p", 0x20000000, 0xfc000000, CBD|RD_s|RD_t, 0, I32R6}, @@ -4462,6 +4463,13 @@ print_insn_args (const char *d, (*info->print_address_func) (info->target, info); break; + case 'q': + /* Sign extend the displacement with 21 bits. */ + delta = sextract32(l, OP_SH_DELTA, 21); + info->target = (delta << 2) + pc + INSNLEN; + (*info->print_address_func) (info->target, info); + break; + case 't': /* Coprocessor 0 reg name */ (*info->fprintf_func) (info->stream, "%s", mips_cp0_names[(l >> OP_SH_RT) & From 503a35e7fdb75aef73d25c43589afcdff6d03ccf Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Sat, 22 Oct 2022 17:04:26 +0200 Subject: [PATCH 447/705] hw/i386/pc: Create DMA controllers in south bridges MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Just like in the real hardware (and in PIIX4), create the DMA controllers in the south bridges. Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20221022150508.26830-2-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/i386/pc.c | 3 --- hw/i386/pc_piix.c | 2 ++ hw/isa/Kconfig | 2 ++ hw/isa/lpc_ich9.c | 3 +++ hw/isa/piix3.c | 9 +++++++-- 5 files changed, 14 insertions(+), 5 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 3e86083db3..ef14da5094 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -47,7 +47,6 @@ #include "multiboot.h" #include "hw/rtc/mc146818rtc.h" #include "hw/intc/i8259.h" -#include "hw/dma/i8257.h" #include "hw/timer/i8254.h" #include "hw/input/i8042.h" #include "hw/irq.h" @@ -1320,8 +1319,6 @@ void pc_basic_device_init(struct PCMachineState *pcms, pcspk_init(pcms->pcspk, isa_bus, pit); } - i8257_dma_init(isa_bus, 0); - /* Super I/O */ pc_superio_init(isa_bus, create_fdctrl, pcms->i8042_enabled, pcms->vmport != ON_OFF_AUTO_ON); diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 0b1a79c0fa..7a55b9ca8e 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -26,6 +26,7 @@ #include CONFIG_DEVICES #include "qemu/units.h" +#include "hw/dma/i8257.h" #include "hw/loader.h" #include "hw/i386/x86.h" #include "hw/i386/pc.h" @@ -225,6 +226,7 @@ static void pc_init1(MachineState *machine, pci_bus = NULL; isa_bus = isa_bus_new(NULL, get_system_memory(), system_io, &error_abort); + i8257_dma_init(isa_bus, 0); pcms->hpet_enabled = false; } isa_bus_irqs(isa_bus, x86ms->gsi); diff --git a/hw/isa/Kconfig b/hw/isa/Kconfig index 20de7e9294..60aad28800 100644 --- a/hw/isa/Kconfig +++ b/hw/isa/Kconfig @@ -33,6 +33,7 @@ config PC87312 config PIIX3 bool + select I8257 select ISA_BUS config PIIX4 @@ -68,6 +69,7 @@ config LPC_ICH9 bool # For historical reasons, SuperIO devices are created in the board # for ICH9. + select I8257 select ISA_BUS select ACPI_SMBUS select ACPI_X86_ICH diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index 4553b5925b..8694e58b21 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -34,6 +34,7 @@ #include "qapi/error.h" #include "qapi/visitor.h" #include "qemu/range.h" +#include "hw/dma/i8257.h" #include "hw/isa/isa.h" #include "migration/vmstate.h" #include "hw/irq.h" @@ -722,6 +723,8 @@ static void ich9_lpc_realize(PCIDevice *d, Error **errp) qdev_init_gpio_out_named(dev, lpc->gsi, ICH9_GPIO_GSI, GSI_NUM_PINS); isa_bus_irqs(isa_bus, lpc->gsi); + + i8257_dma_init(isa_bus, 0); } static bool ich9_rst_cnt_needed(void *opaque) diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c index 48f9ab1096..44a9998752 100644 --- a/hw/isa/piix3.c +++ b/hw/isa/piix3.c @@ -25,6 +25,7 @@ #include "qemu/osdep.h" #include "qemu/range.h" #include "qapi/error.h" +#include "hw/dma/i8257.h" #include "hw/southbridge/piix.h" #include "hw/irq.h" #include "hw/isa/isa.h" @@ -295,9 +296,11 @@ static const MemoryRegionOps rcr_ops = { static void pci_piix3_realize(PCIDevice *dev, Error **errp) { PIIX3State *d = PIIX3_PCI_DEVICE(dev); + ISABus *isa_bus; - if (!isa_bus_new(DEVICE(d), get_system_memory(), - pci_address_space_io(dev), errp)) { + isa_bus = isa_bus_new(DEVICE(d), get_system_memory(), + pci_address_space_io(dev), errp); + if (!isa_bus) { return; } @@ -307,6 +310,8 @@ static void pci_piix3_realize(PCIDevice *dev, Error **errp) PIIX_RCR_IOPORT, &d->rcr_mem, 1); qemu_register_reset(piix3_reset, d); + + i8257_dma_init(isa_bus, 0); } static void build_pci_isa_aml(AcpiDevAmlIf *adev, Aml *scope) From 05c049f12b88370de7289bf39b14088c7d656caa Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Sat, 22 Oct 2022 17:04:28 +0200 Subject: [PATCH 448/705] hw/isa/piix3: Remove extra ';' outside of functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the "extra-semi" clang-tidy check. Signed-off-by: Bernhard Beschow Reviewed-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20221022150508.26830-4-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/isa/piix3.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c index 44a9998752..04895ce2e5 100644 --- a/hw/isa/piix3.c +++ b/hw/isa/piix3.c @@ -375,7 +375,7 @@ static void piix3_realize(PCIDevice *dev, Error **errp) pci_bus_irqs(pci_bus, piix3_set_irq, pci_slot_get_pirq, piix3, PIIX_NUM_PIRQS); pci_bus_set_route_irq_fn(pci_bus, piix3_route_intx_pin_to_irq); -}; +} static void piix3_class_init(ObjectClass *klass, void *data) { @@ -410,7 +410,7 @@ static void piix3_xen_realize(PCIDevice *dev, Error **errp) */ pci_bus_irqs(pci_bus, xen_piix3_set_irq, xen_pci_slot_get_pirq, piix3, XEN_PIIX_NUM_PIRQS); -}; +} static void piix3_xen_class_init(ObjectClass *klass, void *data) { @@ -418,7 +418,7 @@ static void piix3_xen_class_init(ObjectClass *klass, void *data) k->config_write = piix3_write_config_xen; k->realize = piix3_xen_realize; -}; +} static const TypeInfo piix3_xen_info = { .name = TYPE_PIIX3_XEN_DEVICE, From 3ee15e807407defcd774586549a00674d58be970 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Sat, 22 Oct 2022 17:04:29 +0200 Subject: [PATCH 449/705] hw/isa/piix3: Add size constraints to rcr_ops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to the PIIX3 datasheet, the reset control register is one byte in size. Moreover, PIIX4 has it, so add it to PIIX3 as well. Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20221022150508.26830-5-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/isa/piix3.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c index 04895ce2e5..72dbf688d9 100644 --- a/hw/isa/piix3.c +++ b/hw/isa/piix3.c @@ -290,7 +290,11 @@ static uint64_t rcr_read(void *opaque, hwaddr addr, unsigned len) static const MemoryRegionOps rcr_ops = { .read = rcr_read, .write = rcr_write, - .endianness = DEVICE_LITTLE_ENDIAN + .endianness = DEVICE_LITTLE_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, }; static void pci_piix3_realize(PCIDevice *dev, Error **errp) From a1b05751faf7769cec3b1751da0239d2ced27b35 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Sat, 22 Oct 2022 17:04:30 +0200 Subject: [PATCH 450/705] hw/isa/piix3: Modernize reset handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rather than registering the reset handler via a function which appends the handler to a global list, prefer to implement it as a virtual method - PIIX4 does the same already. Note that this means that piix3_reset can now also be called writing to the relevant configuration space register on a PCI bridge. Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20221022150508.26830-6-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/isa/piix3.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c index 72dbf688d9..723ad0a896 100644 --- a/hw/isa/piix3.c +++ b/hw/isa/piix3.c @@ -31,7 +31,6 @@ #include "hw/isa/isa.h" #include "hw/xen/xen.h" #include "sysemu/xen.h" -#include "sysemu/reset.h" #include "sysemu/runstate.h" #include "migration/vmstate.h" #include "hw/acpi/acpi_aml_interface.h" @@ -156,9 +155,9 @@ static void piix3_write_config_xen(PCIDevice *dev, piix3_write_config(dev, address, val, len); } -static void piix3_reset(void *opaque) +static void piix3_reset(DeviceState *dev) { - PIIX3State *d = opaque; + PIIX3State *d = PIIX3_PCI_DEVICE(dev); uint8_t *pci_conf = d->dev.config; pci_conf[0x04] = 0x07; /* master, memory and I/O */ @@ -313,8 +312,6 @@ static void pci_piix3_realize(PCIDevice *dev, Error **errp) memory_region_add_subregion_overlap(pci_address_space_io(dev), PIIX_RCR_IOPORT, &d->rcr_mem, 1); - qemu_register_reset(piix3_reset, d); - i8257_dma_init(isa_bus, 0); } @@ -337,6 +334,7 @@ static void pci_piix3_class_init(ObjectClass *klass, void *data) PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); AcpiDevAmlIfClass *adevc = ACPI_DEV_AML_IF_CLASS(klass); + dc->reset = piix3_reset; dc->desc = "ISA bridge"; dc->vmsd = &vmstate_piix3; dc->hotpluggable = false; From 57654b8e98785f2188b64dd45489dc29b426663c Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Sat, 22 Oct 2022 17:04:31 +0200 Subject: [PATCH 451/705] hw/isa/piix3: Prefer pci_address_space() over get_system_memory() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit get_system_memory() accesses global state while pci_address_space() uses whatever has been passed to the device instance, so avoid the global. Moreover, PIIX4 uses pci_address_space() here as well. Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20221022150508.26830-7-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/isa/piix3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c index 723ad0a896..0bea4aefe7 100644 --- a/hw/isa/piix3.c +++ b/hw/isa/piix3.c @@ -301,7 +301,7 @@ static void pci_piix3_realize(PCIDevice *dev, Error **errp) PIIX3State *d = PIIX3_PCI_DEVICE(dev); ISABus *isa_bus; - isa_bus = isa_bus_new(DEVICE(d), get_system_memory(), + isa_bus = isa_bus_new(DEVICE(d), pci_address_space(dev), pci_address_space_io(dev), errp); if (!isa_bus) { return; From 0b6fdb933b04637a240bd132d626d1daf2d8d7a7 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Sat, 22 Oct 2022 17:04:32 +0200 Subject: [PATCH 452/705] hw/isa/piix4: Rename wrongly named method MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This method post-loads the southbridge, not the IDE device. Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20221022150508.26830-8-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/isa/piix4.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c index 15f344dbb7..c88d3bf3bf 100644 --- a/hw/isa/piix4.c +++ b/hw/isa/piix4.c @@ -141,7 +141,7 @@ static void piix4_isa_reset(DeviceState *dev) pci_conf[0xae] = 0x00; } -static int piix4_ide_post_load(void *opaque, int version_id) +static int piix4_post_load(void *opaque, int version_id) { PIIX4State *s = opaque; @@ -156,7 +156,7 @@ static const VMStateDescription vmstate_piix4 = { .name = "PIIX4", .version_id = 3, .minimum_version_id = 2, - .post_load = piix4_ide_post_load, + .post_load = piix4_post_load, .fields = (VMStateField[]) { VMSTATE_PCI_DEVICE(dev, PIIX4State), VMSTATE_UINT8_V(rcr, PIIX4State, 3), From bb2e9b1d660a4bf11c169388b577c851c51ffe24 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Sat, 22 Oct 2022 17:04:33 +0200 Subject: [PATCH 453/705] hw/ide/piix: Introduce TYPE_ macros for PIIX IDE controllers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Suggested-by: Mark Cave-Ayland Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20221022150508.26830-9-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/i386/pc_piix.c | 3 ++- hw/ide/piix.c | 5 +++-- hw/isa/piix4.c | 3 ++- include/hw/ide/piix.h | 7 +++++++ 4 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 include/hw/ide/piix.h diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 7a55b9ca8e..0ad0ed1603 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -40,6 +40,7 @@ #include "hw/usb.h" #include "net/net.h" #include "hw/ide/pci.h" +#include "hw/ide/piix.h" #include "hw/irq.h" #include "sysemu/kvm.h" #include "hw/kvm/clock.h" @@ -259,7 +260,7 @@ static void pc_init1(MachineState *machine, if (pcmc->pci_enabled) { PCIDevice *dev; - dev = pci_create_simple(pci_bus, piix3_devfn + 1, "piix3-ide"); + dev = pci_create_simple(pci_bus, piix3_devfn + 1, TYPE_PIIX3_IDE); pci_ide_create_devs(dev); idebus[0] = qdev_get_child_bus(&dev->qdev, "ide.0"); idebus[1] = qdev_get_child_bus(&dev->qdev, "ide.1"); diff --git a/hw/ide/piix.c b/hw/ide/piix.c index de1f4f0efb..267dbf37db 100644 --- a/hw/ide/piix.c +++ b/hw/ide/piix.c @@ -36,6 +36,7 @@ #include "sysemu/blockdev.h" #include "sysemu/dma.h" +#include "hw/ide/piix.h" #include "hw/ide/pci.h" #include "trace.h" @@ -202,7 +203,7 @@ static void piix3_ide_class_init(ObjectClass *klass, void *data) } static const TypeInfo piix3_ide_info = { - .name = "piix3-ide", + .name = TYPE_PIIX3_IDE, .parent = TYPE_PCI_IDE, .class_init = piix3_ide_class_init, }; @@ -224,7 +225,7 @@ static void piix4_ide_class_init(ObjectClass *klass, void *data) } static const TypeInfo piix4_ide_info = { - .name = "piix4-ide", + .name = TYPE_PIIX4_IDE, .parent = TYPE_PCI_IDE, .class_init = piix4_ide_class_init, }; diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c index c88d3bf3bf..e05e65d3bc 100644 --- a/hw/isa/piix4.c +++ b/hw/isa/piix4.c @@ -28,6 +28,7 @@ #include "hw/irq.h" #include "hw/southbridge/piix.h" #include "hw/pci/pci.h" +#include "hw/ide/piix.h" #include "hw/isa/isa.h" #include "hw/intc/i8259.h" #include "hw/dma/i8257.h" @@ -277,7 +278,7 @@ static void piix4_init(Object *obj) PIIX4State *s = PIIX4_PCI_DEVICE(obj); object_initialize_child(obj, "rtc", &s->rtc, TYPE_MC146818_RTC); - object_initialize_child(obj, "ide", &s->ide, "piix4-ide"); + object_initialize_child(obj, "ide", &s->ide, TYPE_PIIX4_IDE); object_initialize_child(obj, "uhci", &s->uhci, "piix4-usb-uhci"); object_initialize_child(obj, "pm", &s->pm, TYPE_PIIX4_PM); diff --git a/include/hw/ide/piix.h b/include/hw/ide/piix.h new file mode 100644 index 0000000000..ef3ef3d62d --- /dev/null +++ b/include/hw/ide/piix.h @@ -0,0 +1,7 @@ +#ifndef HW_IDE_PIIX_H +#define HW_IDE_PIIX_H + +#define TYPE_PIIX3_IDE "piix3-ide" +#define TYPE_PIIX4_IDE "piix4-ide" + +#endif /* HW_IDE_PIIX_H */ From 90ba5c511a7ed0c4e849bc556326c32df9876ee8 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Sat, 22 Oct 2022 17:04:43 +0200 Subject: [PATCH 454/705] hw/isa/piix3: Remove unused include MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ammends commit 988fb613215993dd0ce642b89ca8182c479d39dd. Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20221022150508.26830-19-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/isa/piix3.c | 1 - 1 file changed, 1 deletion(-) diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c index 0bea4aefe7..808fd4eadf 100644 --- a/hw/isa/piix3.c +++ b/hw/isa/piix3.c @@ -30,7 +30,6 @@ #include "hw/irq.h" #include "hw/isa/isa.h" #include "hw/xen/xen.h" -#include "sysemu/xen.h" #include "sysemu/runstate.h" #include "migration/vmstate.h" #include "hw/acpi/acpi_aml_interface.h" From e5b6c3e2fe0564306c71ec322717101aa88835c7 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Sat, 22 Oct 2022 17:04:50 +0200 Subject: [PATCH 455/705] hw/mips/malta: Reuse dev variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While at it, move the assignments closer to where they are used. Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20221022150508.26830-26-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/mips/malta.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/hw/mips/malta.c b/hw/mips/malta.c index 2d4341bd50..4f67d3ef1e 100644 --- a/hw/mips/malta.c +++ b/hw/mips/malta.c @@ -1264,7 +1264,6 @@ void mips_malta_init(MachineState *machine) MaltaState *s; PCIDevice *piix4; DeviceState *dev; - DeviceState *pm_dev; s = MIPS_MALTA(qdev_new(TYPE_MIPS_MALTA)); sysbus_realize_and_unref(SYS_BUS_DEVICE(s), &error_fatal); @@ -1430,13 +1429,13 @@ void mips_malta_init(MachineState *machine) TYPE_PIIX4_PCI_DEVICE); dev = DEVICE(piix4); isa_bus = ISA_BUS(qdev_get_child_bus(dev, "isa.0")); - pm_dev = DEVICE(object_resolve_path_component(OBJECT(dev), "pm")); - smbus = I2C_BUS(qdev_get_child_bus(pm_dev, "i2c")); /* Interrupt controller */ qdev_connect_gpio_out_named(dev, "intr", 0, i8259_irq); /* generate SPD EEPROM data */ + dev = DEVICE(object_resolve_path_component(OBJECT(piix4), "pm")); + smbus = I2C_BUS(qdev_get_child_bus(dev, "i2c")); generate_eeprom_spd(&smbus_eeprom_buf[0 * 256], ram_size); generate_eeprom_serial(&smbus_eeprom_buf[6 * 256]); smbus_eeprom_init(smbus, 8, smbus_eeprom_buf, smbus_eeprom_size); From 195f7e77de374b6b9776be3bbbc71c7a11ae5622 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Sat, 22 Oct 2022 17:04:51 +0200 Subject: [PATCH 456/705] hw/isa/Kconfig: Fix dependencies of piix4 southbridge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bernhard Beschow Message-Id: <20221022150508.26830-27-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- configs/devices/mips-softmmu/common.mak | 1 - hw/isa/Kconfig | 6 ++++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/configs/devices/mips-softmmu/common.mak b/configs/devices/mips-softmmu/common.mak index d2202c839e..416161f833 100644 --- a/configs/devices/mips-softmmu/common.mak +++ b/configs/devices/mips-softmmu/common.mak @@ -23,7 +23,6 @@ CONFIG_APM=y CONFIG_I8257=y CONFIG_PIIX4=y CONFIG_IDE_ISA=y -CONFIG_IDE_PIIX=y CONFIG_PFLASH_CFI01=y CONFIG_I8259=y CONFIG_MC146818RTC=y diff --git a/hw/isa/Kconfig b/hw/isa/Kconfig index 60aad28800..18b5c6bf3f 100644 --- a/hw/isa/Kconfig +++ b/hw/isa/Kconfig @@ -40,7 +40,13 @@ config PIIX4 bool # For historical reasons, SuperIO devices are created in the board # for PIIX4. + select ACPI_PIIX4 + select I8254 + select I8257 + select I8259 + select IDE_PIIX select ISA_BUS + select MC146818RTC select USB_UHCI config VT82C686 From a1c100d0fbdcee230341262c3874513ce70ff38f Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Sat, 22 Oct 2022 17:04:52 +0200 Subject: [PATCH 457/705] hw/isa/piix4: Add missing initialization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PIIX3 clears its reset control register, so do the same in PIIX4. Signed-off-by: Bernhard Beschow Message-Id: <20221022150508.26830-28-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/isa/piix4.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c index e05e65d3bc..9126eb9edf 100644 --- a/hw/isa/piix4.c +++ b/hw/isa/piix4.c @@ -140,6 +140,8 @@ static void piix4_isa_reset(DeviceState *dev) pci_conf[0xab] = 0x00; pci_conf[0xac] = 0x00; pci_conf[0xae] = 0x00; + + d->rcr = 0; } static int piix4_post_load(void *opaque, int version_id) From d240d3fb14031ed2b00b86ab8e9082ba6bebce4d Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Sat, 22 Oct 2022 17:04:53 +0200 Subject: [PATCH 458/705] hw/isa/piix4: Move pci_ide_create_devs() call to board code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For the VIA south bridges there was a comment to have the call in board code. Move it there for PIIX4 as well for consistency. Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20221022150508.26830-29-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/isa/piix4.c | 1 - hw/mips/malta.c | 10 ++++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c index 9126eb9edf..8fc1db6dc9 100644 --- a/hw/isa/piix4.c +++ b/hw/isa/piix4.c @@ -257,7 +257,6 @@ static void piix4_realize(PCIDevice *dev, Error **errp) if (!qdev_realize(DEVICE(&s->ide), BUS(pci_bus), errp)) { return; } - pci_ide_create_devs(PCI_DEVICE(&s->ide)); /* USB */ qdev_prop_set_int32(DEVICE(&s->uhci), "addr", dev->devfn + 2); diff --git a/hw/mips/malta.c b/hw/mips/malta.c index 4f67d3ef1e..ecd889cedb 100644 --- a/hw/mips/malta.c +++ b/hw/mips/malta.c @@ -40,7 +40,7 @@ #include "hw/pci/pci.h" #include "qemu/log.h" #include "hw/mips/bios.h" -#include "hw/ide.h" +#include "hw/ide/pci.h" #include "hw/irq.h" #include "hw/loader.h" #include "elf.h" @@ -1427,11 +1427,13 @@ void mips_malta_init(MachineState *machine) /* Southbridge */ piix4 = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(10, 0), true, TYPE_PIIX4_PCI_DEVICE); - dev = DEVICE(piix4); - isa_bus = ISA_BUS(qdev_get_child_bus(dev, "isa.0")); + isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(piix4), "isa.0")); + + dev = DEVICE(object_resolve_path_component(OBJECT(piix4), "ide")); + pci_ide_create_devs(PCI_DEVICE(dev)); /* Interrupt controller */ - qdev_connect_gpio_out_named(dev, "intr", 0, i8259_irq); + qdev_connect_gpio_out_named(DEVICE(piix4), "intr", 0, i8259_irq); /* generate SPD EEPROM data */ dev = DEVICE(object_resolve_path_component(OBJECT(piix4), "pm")); From 3c43fc333be7747a29405bdf6b3bd9e82fa22164 Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Mon, 24 Oct 2022 15:35:40 +0100 Subject: [PATCH 459/705] hw/mips/boston: Don't set link_up for xilinx-pcie MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PCIe port 0 and 1 had link_up set as false previously, that makes those two ports effectively useless. It can be annoying for users to find that the device they plug on those buses won't work at all. As link_up is true by default, just don't set it again in boston platform code. Signed-off-by: Jiaxun Yang Message-Id: <20221024143540.97545-1-jiaxun.yang@flygoat.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/mips/boston.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/hw/mips/boston.c b/hw/mips/boston.c index cab63f43bf..2333bb67b4 100644 --- a/hw/mips/boston.c +++ b/hw/mips/boston.c @@ -425,7 +425,7 @@ static inline XilinxPCIEHost * xilinx_pcie_init(MemoryRegion *sys_mem, uint32_t bus_nr, hwaddr cfg_base, uint64_t cfg_size, hwaddr mmio_base, uint64_t mmio_size, - qemu_irq irq, bool link_up) + qemu_irq irq) { DeviceState *dev; MemoryRegion *cfg, *mmio; @@ -437,7 +437,6 @@ xilinx_pcie_init(MemoryRegion *sys_mem, uint32_t bus_nr, qdev_prop_set_uint64(dev, "cfg_size", cfg_size); qdev_prop_set_uint64(dev, "mmio_base", mmio_base); qdev_prop_set_uint64(dev, "mmio_size", mmio_size); - qdev_prop_set_bit(dev, "link_up", link_up); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); @@ -730,21 +729,21 @@ static void boston_mach_init(MachineState *machine) boston_memmap[BOSTON_PCIE0].size, boston_memmap[BOSTON_PCIE0_MMIO].base, boston_memmap[BOSTON_PCIE0_MMIO].size, - get_cps_irq(&s->cps, 2), false); + get_cps_irq(&s->cps, 2)); xilinx_pcie_init(sys_mem, 1, boston_memmap[BOSTON_PCIE1].base, boston_memmap[BOSTON_PCIE1].size, boston_memmap[BOSTON_PCIE1_MMIO].base, boston_memmap[BOSTON_PCIE1_MMIO].size, - get_cps_irq(&s->cps, 1), false); + get_cps_irq(&s->cps, 1)); pcie2 = xilinx_pcie_init(sys_mem, 2, boston_memmap[BOSTON_PCIE2].base, boston_memmap[BOSTON_PCIE2].size, boston_memmap[BOSTON_PCIE2_MMIO].base, boston_memmap[BOSTON_PCIE2_MMIO].size, - get_cps_irq(&s->cps, 0), true); + get_cps_irq(&s->cps, 0)); platreg = g_new(MemoryRegion, 1); memory_region_init_io(platreg, NULL, &boston_platreg_ops, s, From 36d7487b2aa033e9792fb310c39d106ffcadaa4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Wed, 26 Oct 2022 21:18:19 +0200 Subject: [PATCH 460/705] hw/mips/bootloader: Allow bl_gen_jump_kernel to optionally set register MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When one of the $sp/$a[0..3] register is already set, we might want bl_gen_jump_kernel() to NOT set it again. Pass a boolean argument for each register, to allow to optionally set them. Tested-by: Jiaxun Yang Reviewed-by: Jiaxun Yang Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20221026191821.28167-2-philmd@linaro.org> --- hw/mips/bootloader.c | 28 +++++++++++++++++++++------- hw/mips/boston.c | 5 ++++- hw/mips/fuloong2e.c | 8 ++++++-- include/hw/mips/bootloader.h | 8 ++++++-- 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/hw/mips/bootloader.c b/hw/mips/bootloader.c index 99991f8b2b..f5f42f2bf2 100644 --- a/hw/mips/bootloader.c +++ b/hw/mips/bootloader.c @@ -165,15 +165,29 @@ void bl_gen_jump_to(uint32_t **p, target_ulong jump_addr) bl_gen_nop(p); /* delay slot */ } -void bl_gen_jump_kernel(uint32_t **p, target_ulong sp, target_ulong a0, - target_ulong a1, target_ulong a2, target_ulong a3, +void bl_gen_jump_kernel(uint32_t **p, + bool set_sp, target_ulong sp, + bool set_a0, target_ulong a0, + bool set_a1, target_ulong a1, + bool set_a2, target_ulong a2, + bool set_a3, target_ulong a3, target_ulong kernel_addr) { - bl_gen_load_ulong(p, BL_REG_SP, sp); - bl_gen_load_ulong(p, BL_REG_A0, a0); - bl_gen_load_ulong(p, BL_REG_A1, a1); - bl_gen_load_ulong(p, BL_REG_A2, a2); - bl_gen_load_ulong(p, BL_REG_A3, a3); + if (set_sp) { + bl_gen_load_ulong(p, BL_REG_SP, sp); + } + if (set_a0) { + bl_gen_load_ulong(p, BL_REG_A0, a0); + } + if (set_a1) { + bl_gen_load_ulong(p, BL_REG_A1, a1); + } + if (set_a2) { + bl_gen_load_ulong(p, BL_REG_A2, a2); + } + if (set_a3) { + bl_gen_load_ulong(p, BL_REG_A3, a3); + } bl_gen_jump_to(p, kernel_addr); } diff --git a/hw/mips/boston.c b/hw/mips/boston.c index 2333bb67b4..edda87e23c 100644 --- a/hw/mips/boston.c +++ b/hw/mips/boston.c @@ -352,7 +352,10 @@ static void gen_firmware(uint32_t *p, hwaddr kernel_entry, hwaddr fdt_addr) * a2/$6 = 0 * a3/$7 = 0 */ - bl_gen_jump_kernel(&p, 0, (int32_t)-2, fdt_addr, 0, 0, kernel_entry); + bl_gen_jump_kernel(&p, + true, 0, true, (int32_t)-2, + true, fdt_addr, true, 0, true, 0, + kernel_entry); } static const void *boston_fdt_filter(void *opaque, const void *fdt_orig, diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c index 50c61f0e4a..34befa5dd5 100644 --- a/hw/mips/fuloong2e.c +++ b/hw/mips/fuloong2e.c @@ -179,8 +179,12 @@ static void write_bootloader(CPUMIPSState *env, uint8_t *base, /* Second part of the bootloader */ p = (uint32_t *)(base + 0x040); - bl_gen_jump_kernel(&p, ENVP_VADDR - 64, 2, ENVP_VADDR, ENVP_VADDR + 8, - loaderparams.ram_size, kernel_addr); + bl_gen_jump_kernel(&p, + true, ENVP_VADDR - 64, + true, 2, true, ENVP_VADDR, + true, ENVP_VADDR + 8, + true, loaderparams.ram_size, + kernel_addr); } static void main_cpu_reset(void *opaque) diff --git a/include/hw/mips/bootloader.h b/include/hw/mips/bootloader.h index b5f48d71bb..fffb0b7da8 100644 --- a/include/hw/mips/bootloader.h +++ b/include/hw/mips/bootloader.h @@ -12,8 +12,12 @@ #include "exec/cpu-defs.h" void bl_gen_jump_to(uint32_t **p, target_ulong jump_addr); -void bl_gen_jump_kernel(uint32_t **p, target_ulong sp, target_ulong a0, - target_ulong a1, target_ulong a2, target_ulong a3, +void bl_gen_jump_kernel(uint32_t **p, + bool set_sp, target_ulong sp, + bool set_a0, target_ulong a0, + bool set_a1, target_ulong a1, + bool set_a2, target_ulong a2, + bool set_a3, target_ulong a3, target_ulong kernel_addr); void bl_gen_write_ulong(uint32_t **p, target_ulong addr, target_ulong val); void bl_gen_write_u32(uint32_t **p, target_ulong addr, uint32_t val); From fe1f2f4e92782b00ed7edb355c227a2073cfa45b Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Wed, 26 Oct 2022 21:18:20 +0200 Subject: [PATCH 461/705] hw/mips: Use bl_gen_kernel_jump to generate bootloaders MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace embedded binary with generated code. Signed-off-by: Jiaxun Yang Message-Id: <20210127065424.114125-3-jiaxun.yang@flygoat.com> [PMD: Pass semihosting_get_argc() to bl_gen_jump_kernel()] Tested-by: Jiaxun Yang Reviewed-by: Jiaxun Yang Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20221026191821.28167-3-philmd@linaro.org> --- hw/mips/malta.c | 43 ++++++++++++------------------------------- 1 file changed, 12 insertions(+), 31 deletions(-) diff --git a/hw/mips/malta.c b/hw/mips/malta.c index ecd889cedb..39729881bf 100644 --- a/hw/mips/malta.c +++ b/hw/mips/malta.c @@ -36,6 +36,7 @@ #include "hw/i2c/smbus_eeprom.h" #include "hw/block/flash.h" #include "hw/mips/mips.h" +#include "hw/mips/bootloader.h" #include "hw/mips/cpudevs.h" #include "hw/pci/pci.h" #include "qemu/log.h" @@ -865,30 +866,6 @@ static void write_bootloader(uint8_t *base, uint64_t run_addr, /* Second part of the bootloader */ p = (uint32_t *) (base + 0x580); - if (semihosting_get_argc()) { - /* Preserve a0 content as arguments have been passed */ - stl_p(p++, 0x00000000); /* nop */ - } else { - stl_p(p++, 0x24040002); /* addiu a0, zero, 2 */ - } - - /* lui sp, high(ENVP_VADDR) */ - stl_p(p++, 0x3c1d0000 | (((ENVP_VADDR - 64) >> 16) & 0xffff)); - /* ori sp, sp, low(ENVP_VADDR) */ - stl_p(p++, 0x37bd0000 | ((ENVP_VADDR - 64) & 0xffff)); - /* lui a1, high(ENVP_VADDR) */ - stl_p(p++, 0x3c050000 | ((ENVP_VADDR >> 16) & 0xffff)); - /* ori a1, a1, low(ENVP_VADDR) */ - stl_p(p++, 0x34a50000 | (ENVP_VADDR & 0xffff)); - /* lui a2, high(ENVP_VADDR + 8) */ - stl_p(p++, 0x3c060000 | (((ENVP_VADDR + 8) >> 16) & 0xffff)); - /* ori a2, a2, low(ENVP_VADDR + 8) */ - stl_p(p++, 0x34c60000 | ((ENVP_VADDR + 8) & 0xffff)); - /* lui a3, high(ram_low_size) */ - stl_p(p++, 0x3c070000 | (loaderparams.ram_low_size >> 16)); - /* ori a3, a3, low(ram_low_size) */ - stl_p(p++, 0x34e70000 | (loaderparams.ram_low_size & 0xffff)); - /* Load BAR registers as done by YAMON */ stl_p(p++, 0x3c09b400); /* lui t1, 0xb400 */ @@ -940,13 +917,17 @@ static void write_bootloader(uint8_t *base, uint64_t run_addr, #endif stl_p(p++, 0xad280088); /* sw t0, 0x0088(t1) */ - /* Jump to kernel code */ - stl_p(p++, 0x3c1f0000 | - ((kernel_entry >> 16) & 0xffff)); /* lui ra, high(kernel_entry) */ - stl_p(p++, 0x37ff0000 | - (kernel_entry & 0xffff)); /* ori ra, ra, low(kernel_entry) */ - stl_p(p++, 0x03e00009); /* jalr ra */ - stl_p(p++, 0x00000000); /* nop */ + bl_gen_jump_kernel(&p, + true, ENVP_VADDR - 64, + /* + * If semihosting is used, arguments have already been + * passed, so we preserve $a0. + */ + !semihosting_get_argc(), 2, + true, ENVP_VADDR, + true, ENVP_VADDR + 8, + true, loaderparams.ram_low_size, + kernel_entry); /* YAMON subroutines */ p = (uint32_t *) (base + 0x800); From 0c8427baf0f66bdaecae41891304f6e15242e682 Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Wed, 26 Oct 2022 21:18:21 +0200 Subject: [PATCH 462/705] hw/mips/malta: Use bootloader helper to set BAR registers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Translate embedded assembly into IO writes which is more readable. Signed-off-by: Jiaxun Yang Message-Id: <20210127065424.114125-4-jiaxun.yang@flygoat.com> [PMD: Explode addresses/values to ease review/maintainance] Tested-by: Jiaxun Yang Reviewed-by: Jiaxun Yang Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20221026191821.28167-4-philmd@linaro.org> --- hw/mips/malta.c | 79 +++++++++++++++++++++++-------------------------- 1 file changed, 37 insertions(+), 42 deletions(-) diff --git a/hw/mips/malta.c b/hw/mips/malta.c index 39729881bf..c0a2e0ab04 100644 --- a/hw/mips/malta.c +++ b/hw/mips/malta.c @@ -866,56 +866,51 @@ static void write_bootloader(uint8_t *base, uint64_t run_addr, /* Second part of the bootloader */ p = (uint32_t *) (base + 0x580); - /* Load BAR registers as done by YAMON */ - stl_p(p++, 0x3c09b400); /* lui t1, 0xb400 */ + /* + * Load BAR registers as done by YAMON: + * + * - set up PCI0 I/O BARs from 0x18000000 to 0x181fffff + * - set up PCI0 MEM0 at 0x10000000, size 0x7e00000 + * - set up PCI0 MEM1 at 0x18200000, size 0xbc00000 + * + */ + /* Bus endianess is always reversed */ #if TARGET_BIG_ENDIAN - stl_p(p++, 0x3c08df00); /* lui t0, 0xdf00 */ +#define cpu_to_gt32 cpu_to_le32 #else - stl_p(p++, 0x340800df); /* ori t0, r0, 0x00df */ +#define cpu_to_gt32 cpu_to_be32 #endif - stl_p(p++, 0xad280068); /* sw t0, 0x0068(t1) */ - stl_p(p++, 0x3c09bbe0); /* lui t1, 0xbbe0 */ + /* move GT64120 registers from 0x14000000 to 0x1be00000 */ + bl_gen_write_u32(&p, /* GT_ISD */ + cpu_mips_phys_to_kseg1(NULL, 0x14000000 + 0x68), + cpu_to_gt32(0x1be00000 << 3)); -#if TARGET_BIG_ENDIAN - stl_p(p++, 0x3c08c000); /* lui t0, 0xc000 */ -#else - stl_p(p++, 0x340800c0); /* ori t0, r0, 0x00c0 */ -#endif - stl_p(p++, 0xad280048); /* sw t0, 0x0048(t1) */ -#if TARGET_BIG_ENDIAN - stl_p(p++, 0x3c084000); /* lui t0, 0x4000 */ -#else - stl_p(p++, 0x34080040); /* ori t0, r0, 0x0040 */ -#endif - stl_p(p++, 0xad280050); /* sw t0, 0x0050(t1) */ + /* setup MEM-to-PCI0 mapping */ + /* setup PCI0 io window to 0x18000000-0x181fffff */ + bl_gen_write_u32(&p, /* GT_PCI0IOLD */ + cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x48), + cpu_to_gt32(0x18000000 << 3)); + bl_gen_write_u32(&p, /* GT_PCI0IOHD */ + cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x50), + cpu_to_gt32(0x08000000 << 3)); + /* setup PCI0 mem windows */ + bl_gen_write_u32(&p, /* GT_PCI0M0LD */ + cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x58), + cpu_to_gt32(0x10000000 << 3)); + bl_gen_write_u32(&p, /* GT_PCI0M0HD */ + cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x60), + cpu_to_gt32(0x07e00000 << 3)); -#if TARGET_BIG_ENDIAN - stl_p(p++, 0x3c088000); /* lui t0, 0x8000 */ -#else - stl_p(p++, 0x34080080); /* ori t0, r0, 0x0080 */ -#endif - stl_p(p++, 0xad280058); /* sw t0, 0x0058(t1) */ -#if TARGET_BIG_ENDIAN - stl_p(p++, 0x3c083f00); /* lui t0, 0x3f00 */ -#else - stl_p(p++, 0x3408003f); /* ori t0, r0, 0x003f */ -#endif - stl_p(p++, 0xad280060); /* sw t0, 0x0060(t1) */ + bl_gen_write_u32(&p, /* GT_PCI0M1LD */ + cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x80), + cpu_to_gt32(0x18200000 << 3)); + bl_gen_write_u32(&p, /* GT_PCI0M1HD */ + cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x88), + cpu_to_gt32(0x0bc00000 << 3)); -#if TARGET_BIG_ENDIAN - stl_p(p++, 0x3c08c100); /* lui t0, 0xc100 */ -#else - stl_p(p++, 0x340800c1); /* ori t0, r0, 0x00c1 */ -#endif - stl_p(p++, 0xad280080); /* sw t0, 0x0080(t1) */ -#if TARGET_BIG_ENDIAN - stl_p(p++, 0x3c085e00); /* lui t0, 0x5e00 */ -#else - stl_p(p++, 0x3408005e); /* ori t0, r0, 0x005e */ -#endif - stl_p(p++, 0xad280088); /* sw t0, 0x0088(t1) */ +#undef cpu_to_gt32 bl_gen_jump_kernel(&p, true, ENVP_VADDR - 64, From 5107fd3effb1cfec3b96d9e819f1605048640e31 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 31 Oct 2022 13:29:01 +0000 Subject: [PATCH 463/705] net/vhost-vdpa.c: Fix clang compilation failure Commit 8801ccd0500437 introduced a compilation failure with clang version 10.0.0-4ubuntu1: ../../net/vhost-vdpa.c:654:16: error: variable 'vdpa_device_fd' is used uninitialized whenever 'if' condition is false [-Werror,-Wsometimes-uninitialized] } else if (opts->has_vhostfd) { ^~~~~~~~~~~~~~~~~ ../../net/vhost-vdpa.c:662:33: note: uninitialized use occurs here r = vhost_vdpa_get_features(vdpa_device_fd, &features, errp); ^~~~~~~~~~~~~~ ../../net/vhost-vdpa.c:654:12: note: remove the 'if' if its condition is always true } else if (opts->has_vhostfd) { ^~~~~~~~~~~~~~~~~~~~~~~ ../../net/vhost-vdpa.c:629:23: note: initialize the variable 'vdpa_device_fd' to silence this warning int vdpa_device_fd; ^ = 0 1 error generated. It's a false positive -- the compiler doesn't manage to figure out that the error checks further up mean that there's no code path where vdpa_device_fd isn't initialized. Put another way, the problem is that we check "if (opts->has_vhostfd)" when in fact that condition must always be true. A cleverer static analyser would probably warn that we were checking an always-true condition. Fix the compilation failure by removing the unnecessary if(). Fixes: 8801ccd0500437 ("vhost-vdpa: allow passing opened vhostfd to vhost-vdpa") Signed-off-by: Peter Maydell Message-Id: <20221031132901.1277150-1-peter.maydell@linaro.org> Signed-off-by: Stefan Hajnoczi --- net/vhost-vdpa.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c index 854ebd61ae..e370ecb8eb 100644 --- a/net/vhost-vdpa.c +++ b/net/vhost-vdpa.c @@ -651,7 +651,8 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name, if (vdpa_device_fd == -1) { return -errno; } - } else if (opts->has_vhostfd) { + } else { + /* has_vhostfd */ vdpa_device_fd = monitor_fd_param(monitor_cur(), opts->vhostfd, errp); if (vdpa_device_fd == -1) { error_prepend(errp, "vhost-vdpa: unable to parse vhostfd: "); From 03d9e4c0dba9d1b5d0c532ac3518415466ebdf8f Mon Sep 17 00:00:00 2001 From: Alberto Faria Date: Fri, 28 Oct 2022 14:16:35 +0100 Subject: [PATCH 464/705] block/blkio: Add virtio-blk-vfio-pci BlockDriver libblkio 1.1.0 [1] introduces a virtio-blk-vfio-pci driver, which accesses a virtio-blk PCI device using VFIO. Add a corresponding BlockDriver. [1] https://gitlab.com/libblkio/libblkio/-/tree/v1.1.0 Signed-off-by: Alberto Faria Message-id: 20221028131635.710267-1-afaria@redhat.com Signed-off-by: Stefan Hajnoczi --- block/blkio.c | 8 ++++++++ qapi/block-core.json | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/block/blkio.c b/block/blkio.c index 82f26eedd2..f55eb774b4 100644 --- a/block/blkio.c +++ b/block/blkio.c @@ -25,6 +25,7 @@ */ #define DRIVER_IO_URING "io_uring" #define DRIVER_NVME_IO_URING "nvme-io_uring" +#define DRIVER_VIRTIO_BLK_VFIO_PCI "virtio-blk-vfio-pci" #define DRIVER_VIRTIO_BLK_VHOST_USER "virtio-blk-vhost-user" #define DRIVER_VIRTIO_BLK_VHOST_VDPA "virtio-blk-vhost-vdpa" @@ -704,6 +705,8 @@ static int blkio_file_open(BlockDriverState *bs, QDict *options, int flags, ret = blkio_io_uring_open(bs, options, flags, errp); } else if (strcmp(blkio_driver, DRIVER_NVME_IO_URING) == 0) { ret = blkio_nvme_io_uring(bs, options, flags, errp); + } else if (strcmp(blkio_driver, DRIVER_VIRTIO_BLK_VFIO_PCI) == 0) { + ret = blkio_virtio_blk_common_open(bs, options, flags, errp); } else if (strcmp(blkio_driver, DRIVER_VIRTIO_BLK_VHOST_USER) == 0) { ret = blkio_virtio_blk_common_open(bs, options, flags, errp); } else if (strcmp(blkio_driver, DRIVER_VIRTIO_BLK_VHOST_VDPA) == 0) { @@ -989,6 +992,10 @@ static BlockDriver bdrv_nvme_io_uring = BLKIO_DRIVER( .bdrv_needs_filename = true, ); +static BlockDriver bdrv_virtio_blk_vfio_pci = BLKIO_DRIVER( + DRIVER_VIRTIO_BLK_VFIO_PCI +); + static BlockDriver bdrv_virtio_blk_vhost_user = BLKIO_DRIVER( DRIVER_VIRTIO_BLK_VHOST_USER ); @@ -1001,6 +1008,7 @@ static void bdrv_blkio_init(void) { bdrv_register(&bdrv_io_uring); bdrv_register(&bdrv_nvme_io_uring); + bdrv_register(&bdrv_virtio_blk_vfio_pci); bdrv_register(&bdrv_virtio_blk_vhost_user); bdrv_register(&bdrv_virtio_blk_vhost_vdpa); } diff --git a/qapi/block-core.json b/qapi/block-core.json index cb5079e645..81bbb0b893 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -2960,6 +2960,7 @@ 'raw', 'rbd', { 'name': 'replication', 'if': 'CONFIG_REPLICATION' }, 'ssh', 'throttle', 'vdi', 'vhdx', + { 'name': 'virtio-blk-vfio-pci', 'if': 'CONFIG_BLKIO' }, { 'name': 'virtio-blk-vhost-user', 'if': 'CONFIG_BLKIO' }, { 'name': 'virtio-blk-vhost-vdpa', 'if': 'CONFIG_BLKIO' }, 'vmdk', 'vpc', 'vvfat' ] } @@ -3711,6 +3712,20 @@ 'data': { 'filename': 'str' }, 'if': 'CONFIG_BLKIO' } +## +# @BlockdevOptionsVirtioBlkVfioPci: +# +# Driver specific block device options for the virtio-blk-vfio-pci backend. +# +# @path: path to the PCI device's sysfs directory (e.g. +# /sys/bus/pci/devices/0000:00:01.0). +# +# Since: 7.2 +## +{ 'struct': 'BlockdevOptionsVirtioBlkVfioPci', + 'data': { 'path': 'str' }, + 'if': 'CONFIG_BLKIO' } + ## # @BlockdevOptionsVirtioBlkVhostUser: # @@ -4390,6 +4405,9 @@ 'throttle': 'BlockdevOptionsThrottle', 'vdi': 'BlockdevOptionsGenericFormat', 'vhdx': 'BlockdevOptionsGenericFormat', + 'virtio-blk-vfio-pci': + { 'type': 'BlockdevOptionsVirtioBlkVfioPci', + 'if': 'CONFIG_BLKIO' }, 'virtio-blk-vhost-user': { 'type': 'BlockdevOptionsVirtioBlkVhostUser', 'if': 'CONFIG_BLKIO' }, From 4c8f4fda0504564580f5c0a37e2d4b32ff17d2a1 Mon Sep 17 00:00:00 2001 From: Alberto Faria Date: Sat, 29 Oct 2022 13:20:31 +0100 Subject: [PATCH 465/705] block/blkio: Tolerate device size changes Some libblkio drivers may be able to work with regular files (e.g., io_uring) or otherwise resizable devices. Conservatively set BlockDriver::has_variable_length to true to ensure bdrv_nb_sectors() always gives up-to-date results. Also implement BlockDriver::bdrv_co_truncate for the case where no preallocation is needed and the device already has a size compatible with what was requested. Signed-off-by: Alberto Faria Message-id: 20221029122031.975273-1-afaria@redhat.com Signed-off-by: Stefan Hajnoczi --- block/blkio.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/block/blkio.c b/block/blkio.c index f55eb774b4..d850506acd 100644 --- a/block/blkio.c +++ b/block/blkio.c @@ -848,6 +848,31 @@ static int64_t blkio_getlength(BlockDriverState *bs) return capacity; } +static int coroutine_fn blkio_truncate(BlockDriverState *bs, int64_t offset, + bool exact, PreallocMode prealloc, + BdrvRequestFlags flags, Error **errp) +{ + int64_t current_length; + + if (prealloc != PREALLOC_MODE_OFF) { + error_setg(errp, "Unsupported preallocation mode '%s'", + PreallocMode_str(prealloc)); + return -ENOTSUP; + } + + current_length = blkio_getlength(bs); + + if (offset > current_length) { + error_setg(errp, "Cannot grow device"); + return -EINVAL; + } else if (exact && offset != current_length) { + error_setg(errp, "Cannot resize device"); + return -ENOTSUP; + } + + return 0; +} + static int blkio_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) { return 0; @@ -963,10 +988,12 @@ static void blkio_refresh_limits(BlockDriverState *bs, Error **errp) { \ .format_name = name, \ .protocol_name = name, \ + .has_variable_length = true, \ .instance_size = sizeof(BDRVBlkioState), \ .bdrv_file_open = blkio_file_open, \ .bdrv_close = blkio_close, \ .bdrv_getlength = blkio_getlength, \ + .bdrv_co_truncate = blkio_truncate, \ .bdrv_get_info = blkio_get_info, \ .bdrv_attach_aio_context = blkio_attach_aio_context, \ .bdrv_detach_aio_context = blkio_detach_aio_context, \ From 6c32fc0df9cd901add75618c831fb26a9eb742cb Mon Sep 17 00:00:00 2001 From: Alberto Faria Date: Sat, 29 Oct 2022 00:38:54 +0100 Subject: [PATCH 466/705] block/blkio: Make driver nvme-io_uring take a "path" instead of a "filename" The nvme-io_uring driver expects a character special file such as /dev/ng0n1. Follow the convention of having a "filename" option when a regular file is expected, and a "path" option otherwise. This makes io_uring the only libblkio-based driver with a "filename" option, as it accepts a regular file (even though it can also take a block special file). Signed-off-by: Alberto Faria Message-id: 20221028233854.839933-1-afaria@redhat.com Signed-off-by: Stefan Hajnoczi --- block/blkio.c | 12 ++++++++---- qapi/block-core.json | 4 ++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/block/blkio.c b/block/blkio.c index d850506acd..620fab28a7 100644 --- a/block/blkio.c +++ b/block/blkio.c @@ -640,12 +640,17 @@ static int blkio_io_uring_open(BlockDriverState *bs, QDict *options, int flags, static int blkio_nvme_io_uring(BlockDriverState *bs, QDict *options, int flags, Error **errp) { - const char *filename = qdict_get_str(options, "filename"); + const char *path = qdict_get_try_str(options, "path"); BDRVBlkioState *s = bs->opaque; int ret; - ret = blkio_set_str(s->blkio, "path", filename); - qdict_del(options, "filename"); + if (!path) { + error_setg(errp, "missing 'path' option"); + return -EINVAL; + } + + ret = blkio_set_str(s->blkio, "path", path); + qdict_del(options, "path"); if (ret < 0) { error_setg_errno(errp, -ret, "failed to set path: %s", blkio_get_error_msg()); @@ -1016,7 +1021,6 @@ static BlockDriver bdrv_io_uring = BLKIO_DRIVER( static BlockDriver bdrv_nvme_io_uring = BLKIO_DRIVER( DRIVER_NVME_IO_URING, - .bdrv_needs_filename = true, ); static BlockDriver bdrv_virtio_blk_vfio_pci = BLKIO_DRIVER( diff --git a/qapi/block-core.json b/qapi/block-core.json index 81bbb0b893..6d904004f8 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -3704,12 +3704,12 @@ # # Driver specific block device options for the nvme-io_uring backend. # -# @filename: path to the image file +# @path: path to the image file # # Since: 7.2 ## { 'struct': 'BlockdevOptionsNvmeIoUring', - 'data': { 'filename': 'str' }, + 'data': { 'path': 'str' }, 'if': 'CONFIG_BLKIO' } ## From cc4a140a755e775f15fbc6339487b55b86b0ed1e Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Fri, 28 Oct 2022 13:56:17 +0200 Subject: [PATCH 467/705] mac_newworld: Drop some variables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Values not used frequently enough may not worth putting in a local variable, especially with names almost as long as the original value because that does not improve readability, to the contrary it makes it harder to see what value is used. Drop a few such variables. This is the same clean up that was done for mac_oldworld in commit b8df32555ce5. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Mark Cave-Ayland Message-Id: Signed-off-by: Mark Cave-Ayland --- hw/ppc/mac_newworld.c | 65 +++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 36 deletions(-) diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index cf7eb72391..27e4e8d136 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -106,18 +106,13 @@ static void ppc_core99_reset(void *opaque) /* PowerPC Mac99 hardware initialisation */ static void ppc_core99_init(MachineState *machine) { - ram_addr_t ram_size = machine->ram_size; - const char *bios_name = machine->firmware ?: PROM_FILENAME; - const char *kernel_filename = machine->kernel_filename; - const char *kernel_cmdline = machine->kernel_cmdline; - const char *initrd_filename = machine->initrd_filename; - const char *boot_device = machine->boot_config.order; Core99MachineState *core99_machine = CORE99_MACHINE(machine); PowerPCCPU *cpu = NULL; CPUPPCState *env = NULL; char *filename; IrqLines *openpic_irqs; - int linux_boot, i, j, k; + int i, j, k, ppc_boot_device, machine_arch, bios_size; + const char *bios_name = machine->firmware ?: PROM_FILENAME; MemoryRegion *bios = g_new(MemoryRegion, 1); hwaddr kernel_base, initrd_base, cmdline_base = 0; long kernel_size, initrd_size; @@ -129,22 +124,16 @@ static void ppc_core99_init(MachineState *machine) MACIOIDEState *macio_ide; BusState *adb_bus; MacIONVRAMState *nvr; - int bios_size; - int ppc_boot_device; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; void *fw_cfg; - int machine_arch; SysBusDevice *s; DeviceState *dev, *pic_dev; DeviceState *uninorth_internal_dev = NULL, *uninorth_agp_dev = NULL; hwaddr nvram_addr = 0xFFF04000; uint64_t tbfreq; - unsigned int smp_cpus = machine->smp.cpus; - - linux_boot = (kernel_filename != NULL); /* init CPUs */ - for (i = 0; i < smp_cpus; i++) { + for (i = 0; i < machine->smp.cpus; i++) { cpu = POWERPC_CPU(cpu_create(machine->cpu_type)); env = &cpu->env; @@ -184,7 +173,7 @@ static void ppc_core99_init(MachineState *machine) exit(1); } - if (linux_boot) { + if (machine->kernel_filename) { int bswap_needed; #ifdef BSWAP_NEEDED @@ -194,29 +183,31 @@ static void ppc_core99_init(MachineState *machine) #endif kernel_base = KERNEL_LOAD_ADDR; - kernel_size = load_elf(kernel_filename, NULL, + kernel_size = load_elf(machine->kernel_filename, NULL, translate_kernel_address, NULL, NULL, NULL, NULL, NULL, 1, PPC_ELF_MACHINE, 0, 0); if (kernel_size < 0) - kernel_size = load_aout(kernel_filename, kernel_base, - ram_size - kernel_base, bswap_needed, - TARGET_PAGE_SIZE); + kernel_size = load_aout(machine->kernel_filename, kernel_base, + machine->ram_size - kernel_base, + bswap_needed, TARGET_PAGE_SIZE); if (kernel_size < 0) - kernel_size = load_image_targphys(kernel_filename, + kernel_size = load_image_targphys(machine->kernel_filename, kernel_base, - ram_size - kernel_base); + machine->ram_size - kernel_base); if (kernel_size < 0) { - error_report("could not load kernel '%s'", kernel_filename); + error_report("could not load kernel '%s'", + machine->kernel_filename); exit(1); } /* load initrd */ - if (initrd_filename) { + if (machine->initrd_filename) { initrd_base = TARGET_PAGE_ALIGN(kernel_base + kernel_size + KERNEL_GAP); - initrd_size = load_image_targphys(initrd_filename, initrd_base, - ram_size - initrd_base); + initrd_size = load_image_targphys(machine->initrd_filename, + initrd_base, + machine->ram_size - initrd_base); if (initrd_size < 0) { error_report("could not load initial ram disk '%s'", - initrd_filename); + machine->initrd_filename); exit(1); } cmdline_base = TARGET_PAGE_ALIGN(initrd_base + initrd_size); @@ -235,9 +226,10 @@ static void ppc_core99_init(MachineState *machine) /* We consider that NewWorld PowerMac never have any floppy drive * For now, OHW cannot boot from the network. */ - for (i = 0; boot_device[i] != '\0'; i++) { - if (boot_device[i] >= 'c' && boot_device[i] <= 'f') { - ppc_boot_device = boot_device[i]; + for (i = 0; machine->boot_config.order[i] != '\0'; i++) { + if (machine->boot_config.order[i] >= 'c' && + machine->boot_config.order[i] <= 'f') { + ppc_boot_device = machine->boot_config.order[i]; break; } } @@ -254,8 +246,8 @@ static void ppc_core99_init(MachineState *machine) memory_region_add_subregion(get_system_memory(), 0xf8000000, sysbus_mmio_get_region(s, 0)); - openpic_irqs = g_new0(IrqLines, smp_cpus); - for (i = 0; i < smp_cpus; i++) { + openpic_irqs = g_new0(IrqLines, machine->smp.cpus); + for (i = 0; i < machine->smp.cpus; i++) { /* Mac99 IRQ connection between OpenPIC outputs pins * and PowerPC input pins */ @@ -398,7 +390,7 @@ static void ppc_core99_init(MachineState *machine) /* OpenPIC */ s = SYS_BUS_DEVICE(pic_dev); k = 0; - for (i = 0; i < smp_cpus; i++) { + for (i = 0; i < machine->smp.cpus; i++) { for (j = 0; j < OPENPIC_OUTPUT_NB; j++) { sysbus_connect_irq(s, k++, openpic_irqs[i].irq[j]); } @@ -480,15 +472,16 @@ static void ppc_core99_init(MachineState *machine) sysbus_mmio_map(s, 0, CFG_ADDR); sysbus_mmio_map(s, 1, CFG_ADDR + 2); - fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus); + fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)machine->smp.cpus); fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)machine->smp.max_cpus); - fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); + fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)machine->ram_size); fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, machine_arch); fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base); fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size); - if (kernel_cmdline) { + if (machine->kernel_cmdline) { fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, cmdline_base); - pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE, kernel_cmdline); + pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE, + machine->kernel_cmdline); } else { fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0); } From 94c92e1a863b704df5b6c5160e88fd682efc4fe4 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Fri, 28 Oct 2022 13:56:18 +0200 Subject: [PATCH 468/705] mac_oldworld: Drop some more variables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop some more local variables additionally to commit b8df32555ce5 to match clean ups done to mac_newwold in previous patch. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Mark Cave-Ayland Message-Id: <1b9a448431d9b1198432151af0511316cfc20d21.1666957578.git.balaton@eik.bme.hu> Signed-off-by: Mark Cave-Ayland --- hw/ppc/mac_oldworld.c | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c index 03732ca7ed..86512d31ad 100644 --- a/hw/ppc/mac_oldworld.c +++ b/hw/ppc/mac_oldworld.c @@ -80,14 +80,13 @@ static void ppc_heathrow_reset(void *opaque) static void ppc_heathrow_init(MachineState *machine) { - ram_addr_t ram_size = machine->ram_size; const char *bios_name = machine->firmware ?: PROM_FILENAME; - const char *boot_device = machine->boot_config.order; PowerPCCPU *cpu = NULL; CPUPPCState *env = NULL; char *filename; - int i; + int i, bios_size; MemoryRegion *bios = g_new(MemoryRegion, 1); + uint64_t bios_addr; uint32_t kernel_base, initrd_base, cmdline_base = 0; int32_t kernel_size, initrd_size; PCIBus *pci_bus; @@ -97,16 +96,13 @@ static void ppc_heathrow_init(MachineState *machine) SysBusDevice *s; DeviceState *dev, *pic_dev, *grackle_dev; BusState *adb_bus; - uint64_t bios_addr; - int bios_size; - unsigned int smp_cpus = machine->smp.cpus; uint16_t ppc_boot_device; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; void *fw_cfg; uint64_t tbfreq; /* init CPUs */ - for (i = 0; i < smp_cpus; i++) { + for (i = 0; i < machine->smp.cpus; i++) { cpu = POWERPC_CPU(cpu_create(machine->cpu_type)); env = &cpu->env; @@ -116,9 +112,9 @@ static void ppc_heathrow_init(MachineState *machine) } /* allocate RAM */ - if (ram_size > 2047 * MiB) { + if (machine->ram_size > 2047 * MiB) { error_report("Too much memory for this machine: %" PRId64 " MB, " - "maximum 2047 MB", ram_size / MiB); + "maximum 2047 MB", machine->ram_size / MiB); exit(1); } @@ -165,12 +161,12 @@ static void ppc_heathrow_init(MachineState *machine) NULL, NULL, 1, PPC_ELF_MACHINE, 0, 0); if (kernel_size < 0) kernel_size = load_aout(machine->kernel_filename, kernel_base, - ram_size - kernel_base, bswap_needed, - TARGET_PAGE_SIZE); + machine->ram_size - kernel_base, + bswap_needed, TARGET_PAGE_SIZE); if (kernel_size < 0) kernel_size = load_image_targphys(machine->kernel_filename, kernel_base, - ram_size - kernel_base); + machine->ram_size - kernel_base); if (kernel_size < 0) { error_report("could not load kernel '%s'", machine->kernel_filename); @@ -182,7 +178,7 @@ static void ppc_heathrow_init(MachineState *machine) KERNEL_GAP); initrd_size = load_image_targphys(machine->initrd_filename, initrd_base, - ram_size - initrd_base); + machine->ram_size - initrd_base); if (initrd_size < 0) { error_report("could not load initial ram disk '%s'", machine->initrd_filename); @@ -201,19 +197,22 @@ static void ppc_heathrow_init(MachineState *machine) initrd_base = 0; initrd_size = 0; ppc_boot_device = '\0'; - for (i = 0; boot_device[i] != '\0'; i++) { - /* TOFIX: for now, the second IDE channel is not properly + for (i = 0; machine->boot_config.order[i] != '\0'; i++) { + /* + * TOFIX: for now, the second IDE channel is not properly * used by OHW. The Mac floppy disk are not emulated. * For now, OHW cannot boot from the network. */ #if 0 - if (boot_device[i] >= 'a' && boot_device[i] <= 'f') { - ppc_boot_device = boot_device[i]; + if (machine->boot_config.order[i] >= 'a' && + machine->boot_config.order[i] <= 'f') { + ppc_boot_device = machine->boot_config.order[i]; break; } #else - if (boot_device[i] >= 'c' && boot_device[i] <= 'd') { - ppc_boot_device = boot_device[i]; + if (machine->boot_config.order[i] >= 'c' && + machine->boot_config.order[i] <= 'd') { + ppc_boot_device = machine->boot_config.order[i]; break; } #endif @@ -266,7 +265,7 @@ static void ppc_heathrow_init(MachineState *machine) } /* Connect the heathrow PIC outputs to the 6xx bus */ - for (i = 0; i < smp_cpus; i++) { + for (i = 0; i < machine->smp.cpus; i++) { switch (PPC_INPUT(env)) { case PPC_FLAGS_INPUT_6xx: /* XXX: we register only 1 output pin for heathrow PIC */ @@ -323,9 +322,9 @@ static void ppc_heathrow_init(MachineState *machine) sysbus_mmio_map(s, 0, CFG_ADDR); sysbus_mmio_map(s, 1, CFG_ADDR + 2); - fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus); + fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)machine->smp.cpus); fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)machine->smp.max_cpus); - fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); + fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)machine->ram_size); fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, ARCH_HEATHROW); fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base); fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size); From 6b924abe99902ef4fa5b74a24c251fb38fd1e528 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Fri, 28 Oct 2022 13:56:19 +0200 Subject: [PATCH 469/705] mac_{old|new}world: Set tbfreq at declaration The tbfreq variable is only set once in an if-else which can be done at the variable declaration saving some lines of code and making it simpler. Signed-off-by: BALATON Zoltan Reviewed-by: Mark Cave-Ayland Message-Id: <15668da8eb8bad4561428a5f25b02f91e16d9c1b.1666957578.git.balaton@eik.bme.hu> Signed-off-by: Mark Cave-Ayland --- hw/ppc/mac_newworld.c | 9 +-------- hw/ppc/mac_oldworld.c | 9 +-------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index 27e4e8d136..6327694f85 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -130,7 +130,7 @@ static void ppc_core99_init(MachineState *machine) DeviceState *dev, *pic_dev; DeviceState *uninorth_internal_dev = NULL, *uninorth_agp_dev = NULL; hwaddr nvram_addr = 0xFFF04000; - uint64_t tbfreq; + uint64_t tbfreq = kvm_enabled() ? kvmppc_get_tbfreq() : TBFREQ; /* init CPUs */ for (i = 0; i < machine->smp.cpus; i++) { @@ -343,13 +343,6 @@ static void ppc_core99_init(MachineState *machine) has_adb = (core99_machine->via_config == CORE99_VIA_CONFIG_CUDA || core99_machine->via_config == CORE99_VIA_CONFIG_PMU_ADB); - /* Timebase Frequency */ - if (kvm_enabled()) { - tbfreq = kvmppc_get_tbfreq(); - } else { - tbfreq = TBFREQ; - } - /* init basic PC hardware */ pci_bus = PCI_HOST_BRIDGE(uninorth_pci)->bus; diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c index 86512d31ad..5cabc410e7 100644 --- a/hw/ppc/mac_oldworld.c +++ b/hw/ppc/mac_oldworld.c @@ -99,7 +99,7 @@ static void ppc_heathrow_init(MachineState *machine) uint16_t ppc_boot_device; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; void *fw_cfg; - uint64_t tbfreq; + uint64_t tbfreq = kvm_enabled() ? kvmppc_get_tbfreq() : TBFREQ; /* init CPUs */ for (i = 0; i < machine->smp.cpus; i++) { @@ -223,13 +223,6 @@ static void ppc_heathrow_init(MachineState *machine) } } - /* Timebase Frequency */ - if (kvm_enabled()) { - tbfreq = kvmppc_get_tbfreq(); - } else { - tbfreq = TBFREQ; - } - /* Grackle PCI host bridge */ grackle_dev = qdev_new(TYPE_GRACKLE_PCI_HOST_BRIDGE); qdev_prop_set_uint32(grackle_dev, "ofw-addr", 0x80000000); From 6120dc8d9d7be4285c93f20f8978e820934b6d6f Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Fri, 28 Oct 2022 13:56:20 +0200 Subject: [PATCH 470/705] mac_{old|new}world: Avoid else branch by setting default value Several variables are set in if-else branches where the else branch can be removed by setting a default value at the variable declaration which leads to simlpler code that is easier to follow. Signed-off-by: BALATON Zoltan Reviewed-by: Mark Cave-Ayland Message-Id: <8dac3515b29976a61dacda07752175d7531dca3c.1666957578.git.balaton@eik.bme.hu> Signed-off-by: Mark Cave-Ayland --- hw/ppc/mac_newworld.c | 19 ++++--------------- hw/ppc/mac_oldworld.c | 18 ++++-------------- 2 files changed, 8 insertions(+), 29 deletions(-) diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index 6327694f85..6bc3bd19be 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -111,11 +111,11 @@ static void ppc_core99_init(MachineState *machine) CPUPPCState *env = NULL; char *filename; IrqLines *openpic_irqs; - int i, j, k, ppc_boot_device, machine_arch, bios_size; + int i, j, k, ppc_boot_device, machine_arch, bios_size = -1; const char *bios_name = machine->firmware ?: PROM_FILENAME; MemoryRegion *bios = g_new(MemoryRegion, 1); - hwaddr kernel_base, initrd_base, cmdline_base = 0; - long kernel_size, initrd_size; + hwaddr kernel_base = 0, initrd_base = 0, cmdline_base = 0; + long kernel_size = 0, initrd_size = 0; UNINHostState *uninorth_pci; PCIBus *pci_bus; PCIDevice *macio; @@ -165,8 +165,6 @@ static void ppc_core99_init(MachineState *machine) bios_size = load_image_targphys(filename, PROM_BASE, PROM_SIZE); } g_free(filename); - } else { - bios_size = -1; } if (bios_size < 0 || bios_size > PROM_SIZE) { error_report("could not load PowerPC bios '%s'", bios_name); @@ -174,15 +172,12 @@ static void ppc_core99_init(MachineState *machine) } if (machine->kernel_filename) { - int bswap_needed; + int bswap_needed = 0; #ifdef BSWAP_NEEDED bswap_needed = 1; -#else - bswap_needed = 0; #endif kernel_base = KERNEL_LOAD_ADDR; - kernel_size = load_elf(machine->kernel_filename, NULL, translate_kernel_address, NULL, NULL, NULL, NULL, NULL, 1, PPC_ELF_MACHINE, 0, 0); @@ -212,16 +207,10 @@ static void ppc_core99_init(MachineState *machine) } cmdline_base = TARGET_PAGE_ALIGN(initrd_base + initrd_size); } else { - initrd_base = 0; - initrd_size = 0; cmdline_base = TARGET_PAGE_ALIGN(kernel_base + kernel_size + KERNEL_GAP); } ppc_boot_device = 'm'; } else { - kernel_base = 0; - kernel_size = 0; - initrd_base = 0; - initrd_size = 0; ppc_boot_device = '\0'; /* We consider that NewWorld PowerMac never have any floppy drive * For now, OHW cannot boot from the network. diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c index 5cabc410e7..cb67e44081 100644 --- a/hw/ppc/mac_oldworld.c +++ b/hw/ppc/mac_oldworld.c @@ -84,11 +84,11 @@ static void ppc_heathrow_init(MachineState *machine) PowerPCCPU *cpu = NULL; CPUPPCState *env = NULL; char *filename; - int i, bios_size; + int i, bios_size = -1; MemoryRegion *bios = g_new(MemoryRegion, 1); uint64_t bios_addr; - uint32_t kernel_base, initrd_base, cmdline_base = 0; - int32_t kernel_size, initrd_size; + uint32_t kernel_base = 0, initrd_base = 0, cmdline_base = 0; + int32_t kernel_size = 0, initrd_size = 0; PCIBus *pci_bus; PCIDevice *macio; MACIOIDEState *macio_ide; @@ -139,8 +139,6 @@ static void ppc_heathrow_init(MachineState *machine) bios_addr = PROM_BASE; } g_free(filename); - } else { - bios_size = -1; } if (bios_size < 0 || bios_addr - PROM_BASE + bios_size > PROM_SIZE) { error_report("could not load PowerPC bios '%s'", bios_name); @@ -148,12 +146,10 @@ static void ppc_heathrow_init(MachineState *machine) } if (machine->kernel_filename) { - int bswap_needed; + int bswap_needed = 0; #ifdef BSWAP_NEEDED bswap_needed = 1; -#else - bswap_needed = 0; #endif kernel_base = KERNEL_LOAD_ADDR; kernel_size = load_elf(machine->kernel_filename, NULL, @@ -186,16 +182,10 @@ static void ppc_heathrow_init(MachineState *machine) } cmdline_base = TARGET_PAGE_ALIGN(initrd_base + initrd_size); } else { - initrd_base = 0; - initrd_size = 0; cmdline_base = TARGET_PAGE_ALIGN(kernel_base + kernel_size + KERNEL_GAP); } ppc_boot_device = 'm'; } else { - kernel_base = 0; - kernel_size = 0; - initrd_base = 0; - initrd_size = 0; ppc_boot_device = '\0'; for (i = 0; machine->boot_config.order[i] != '\0'; i++) { /* From 50c496d2728b26fa93a99dbdb4c93e619c6afe9d Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Fri, 28 Oct 2022 13:56:21 +0200 Subject: [PATCH 471/705] mac_newworld: Clean up creation of Uninorth devices Map regions in ascending order and reorganise code a bit to avoid some casts and move Uninorth parts together. Signed-off-by: BALATON Zoltan Reviewed-by: Mark Cave-Ayland Message-Id: Signed-off-by: Mark Cave-Ayland --- hw/ppc/mac_newworld.c | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index 6bc3bd19be..e2f456b547 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -228,13 +228,6 @@ static void ppc_core99_init(MachineState *machine) } } - /* UniN init */ - dev = qdev_new(TYPE_UNI_NORTH); - s = SYS_BUS_DEVICE(dev); - sysbus_realize_and_unref(s, &error_fatal); - memory_region_add_subregion(get_system_memory(), 0xf8000000, - sysbus_mmio_get_region(s, 0)); - openpic_irqs = g_new0(IrqLines, machine->smp.cpus); for (i = 0; i < machine->smp.cpus; i++) { /* Mac99 IRQ connection between OpenPIC outputs pins @@ -275,24 +268,30 @@ static void ppc_core99_init(MachineState *machine) } } + /* UniN init */ + s = SYS_BUS_DEVICE(qdev_new(TYPE_UNI_NORTH)); + sysbus_realize_and_unref(s, &error_fatal); + memory_region_add_subregion(get_system_memory(), 0xf8000000, + sysbus_mmio_get_region(s, 0)); + if (PPC_INPUT(env) == PPC_FLAGS_INPUT_970) { + machine_arch = ARCH_MAC99_U3; /* 970 gets a U3 bus */ /* Uninorth AGP bus */ dev = qdev_new(TYPE_U3_AGP_HOST_BRIDGE); - sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); uninorth_pci = U3_AGP_HOST_BRIDGE(dev); s = SYS_BUS_DEVICE(dev); + sysbus_realize_and_unref(s, &error_fatal); + sysbus_mmio_map(s, 0, 0xf0800000); + sysbus_mmio_map(s, 1, 0xf0c00000); /* PCI hole */ - memory_region_add_subregion(get_system_memory(), 0x80000000ULL, + memory_region_add_subregion(get_system_memory(), 0x80000000, sysbus_mmio_get_region(s, 2)); /* Register 8 MB of ISA IO space */ memory_region_add_subregion(get_system_memory(), 0xf2000000, sysbus_mmio_get_region(s, 3)); - sysbus_mmio_map(s, 0, 0xf0800000); - sysbus_mmio_map(s, 1, 0xf0c00000); - - machine_arch = ARCH_MAC99_U3; } else { + machine_arch = ARCH_MAC99; /* Use values found on a real PowerMac */ /* Uninorth AGP bus */ uninorth_agp_dev = qdev_new(TYPE_UNI_NORTH_AGP_HOST_BRIDGE); @@ -309,22 +308,20 @@ static void ppc_core99_init(MachineState *machine) sysbus_mmio_map(s, 0, 0xf4800000); sysbus_mmio_map(s, 1, 0xf4c00000); - /* Uninorth main bus */ + /* Uninorth main bus - this must be last to make it the default */ dev = qdev_new(TYPE_UNI_NORTH_PCI_HOST_BRIDGE); qdev_prop_set_uint32(dev, "ofw-addr", 0xf2000000); - sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); uninorth_pci = UNI_NORTH_PCI_HOST_BRIDGE(dev); s = SYS_BUS_DEVICE(dev); + sysbus_realize_and_unref(s, &error_fatal); + sysbus_mmio_map(s, 0, 0xf2800000); + sysbus_mmio_map(s, 1, 0xf2c00000); /* PCI hole */ - memory_region_add_subregion(get_system_memory(), 0x80000000ULL, + memory_region_add_subregion(get_system_memory(), 0x80000000, sysbus_mmio_get_region(s, 2)); /* Register 8 MB of ISA IO space */ memory_region_add_subregion(get_system_memory(), 0xf2000000, sysbus_mmio_get_region(s, 3)); - sysbus_mmio_map(s, 0, 0xf2800000); - sysbus_mmio_map(s, 1, 0xf2c00000); - - machine_arch = ARCH_MAC99; } machine->usb |= defaults_enabled() && !machine->usb_disabled; From 18e0383b5c21df348f9d3a1e4bd12747561535f2 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Fri, 28 Oct 2022 13:56:22 +0200 Subject: [PATCH 472/705] mac_{old|new}world: Reduce number of QOM casts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit By storing the device pointers in a variable with the right type the number of QOM casts can be reduced which also makes the code more readable. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Mark Cave-Ayland Message-Id: Signed-off-by: Mark Cave-Ayland --- hw/ppc/mac_newworld.c | 61 ++++++++++++++++++++----------------------- hw/ppc/mac_oldworld.c | 26 ++++++++---------- 2 files changed, 39 insertions(+), 48 deletions(-) diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index e2f456b547..4bfffa586b 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -116,18 +116,16 @@ static void ppc_core99_init(MachineState *machine) MemoryRegion *bios = g_new(MemoryRegion, 1); hwaddr kernel_base = 0, initrd_base = 0, cmdline_base = 0; long kernel_size = 0, initrd_size = 0; - UNINHostState *uninorth_pci; PCIBus *pci_bus; - PCIDevice *macio; - ESCCState *escc; bool has_pmu, has_adb; + Object *macio; MACIOIDEState *macio_ide; BusState *adb_bus; MacIONVRAMState *nvr; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; void *fw_cfg; SysBusDevice *s; - DeviceState *dev, *pic_dev; + DeviceState *dev, *pic_dev, *uninorth_pci_dev; DeviceState *uninorth_internal_dev = NULL, *uninorth_agp_dev = NULL; hwaddr nvram_addr = 0xFFF04000; uint64_t tbfreq = kvm_enabled() ? kvmppc_get_tbfreq() : TBFREQ; @@ -229,6 +227,7 @@ static void ppc_core99_init(MachineState *machine) } openpic_irqs = g_new0(IrqLines, machine->smp.cpus); + dev = DEVICE(cpu); for (i = 0; i < machine->smp.cpus; i++) { /* Mac99 IRQ connection between OpenPIC outputs pins * and PowerPC input pins @@ -236,30 +235,30 @@ static void ppc_core99_init(MachineState *machine) switch (PPC_INPUT(env)) { case PPC_FLAGS_INPUT_6xx: openpic_irqs[i].irq[OPENPIC_OUTPUT_INT] = - qdev_get_gpio_in(DEVICE(cpu), PPC6xx_INPUT_INT); + qdev_get_gpio_in(dev, PPC6xx_INPUT_INT); openpic_irqs[i].irq[OPENPIC_OUTPUT_CINT] = - qdev_get_gpio_in(DEVICE(cpu), PPC6xx_INPUT_INT); + qdev_get_gpio_in(dev, PPC6xx_INPUT_INT); openpic_irqs[i].irq[OPENPIC_OUTPUT_MCK] = - qdev_get_gpio_in(DEVICE(cpu), PPC6xx_INPUT_MCP); + qdev_get_gpio_in(dev, PPC6xx_INPUT_MCP); /* Not connected ? */ openpic_irqs[i].irq[OPENPIC_OUTPUT_DEBUG] = NULL; /* Check this */ openpic_irqs[i].irq[OPENPIC_OUTPUT_RESET] = - qdev_get_gpio_in(DEVICE(cpu), PPC6xx_INPUT_HRESET); + qdev_get_gpio_in(dev, PPC6xx_INPUT_HRESET); break; #if defined(TARGET_PPC64) case PPC_FLAGS_INPUT_970: openpic_irqs[i].irq[OPENPIC_OUTPUT_INT] = - qdev_get_gpio_in(DEVICE(cpu), PPC970_INPUT_INT); + qdev_get_gpio_in(dev, PPC970_INPUT_INT); openpic_irqs[i].irq[OPENPIC_OUTPUT_CINT] = - qdev_get_gpio_in(DEVICE(cpu), PPC970_INPUT_INT); + qdev_get_gpio_in(dev, PPC970_INPUT_INT); openpic_irqs[i].irq[OPENPIC_OUTPUT_MCK] = - qdev_get_gpio_in(DEVICE(cpu), PPC970_INPUT_MCP); + qdev_get_gpio_in(dev, PPC970_INPUT_MCP); /* Not connected ? */ openpic_irqs[i].irq[OPENPIC_OUTPUT_DEBUG] = NULL; /* Check this */ openpic_irqs[i].irq[OPENPIC_OUTPUT_RESET] = - qdev_get_gpio_in(DEVICE(cpu), PPC970_INPUT_HRESET); + qdev_get_gpio_in(dev, PPC970_INPUT_HRESET); break; #endif /* defined(TARGET_PPC64) */ default: @@ -278,9 +277,8 @@ static void ppc_core99_init(MachineState *machine) machine_arch = ARCH_MAC99_U3; /* 970 gets a U3 bus */ /* Uninorth AGP bus */ - dev = qdev_new(TYPE_U3_AGP_HOST_BRIDGE); - uninorth_pci = U3_AGP_HOST_BRIDGE(dev); - s = SYS_BUS_DEVICE(dev); + uninorth_pci_dev = qdev_new(TYPE_U3_AGP_HOST_BRIDGE); + s = SYS_BUS_DEVICE(uninorth_pci_dev); sysbus_realize_and_unref(s, &error_fatal); sysbus_mmio_map(s, 0, 0xf0800000); sysbus_mmio_map(s, 1, 0xf0c00000); @@ -309,10 +307,9 @@ static void ppc_core99_init(MachineState *machine) sysbus_mmio_map(s, 1, 0xf4c00000); /* Uninorth main bus - this must be last to make it the default */ - dev = qdev_new(TYPE_UNI_NORTH_PCI_HOST_BRIDGE); - qdev_prop_set_uint32(dev, "ofw-addr", 0xf2000000); - uninorth_pci = UNI_NORTH_PCI_HOST_BRIDGE(dev); - s = SYS_BUS_DEVICE(dev); + uninorth_pci_dev = qdev_new(TYPE_UNI_NORTH_PCI_HOST_BRIDGE); + qdev_prop_set_uint32(uninorth_pci_dev, "ofw-addr", 0xf2000000); + s = SYS_BUS_DEVICE(uninorth_pci_dev); sysbus_realize_and_unref(s, &error_fatal); sysbus_mmio_map(s, 0, 0xf2800000); sysbus_mmio_map(s, 1, 0xf2c00000); @@ -330,24 +327,24 @@ static void ppc_core99_init(MachineState *machine) core99_machine->via_config == CORE99_VIA_CONFIG_PMU_ADB); /* init basic PC hardware */ - pci_bus = PCI_HOST_BRIDGE(uninorth_pci)->bus; + pci_bus = PCI_HOST_BRIDGE(uninorth_pci_dev)->bus; /* MacIO */ - macio = pci_new(-1, TYPE_NEWWORLD_MACIO); + macio = OBJECT(pci_new(-1, TYPE_NEWWORLD_MACIO)); dev = DEVICE(macio); qdev_prop_set_uint64(dev, "frequency", tbfreq); qdev_prop_set_bit(dev, "has-pmu", has_pmu); qdev_prop_set_bit(dev, "has-adb", has_adb); - escc = ESCC(object_resolve_path_component(OBJECT(macio), "escc")); - qdev_prop_set_chr(DEVICE(escc), "chrA", serial_hd(0)); - qdev_prop_set_chr(DEVICE(escc), "chrB", serial_hd(1)); + dev = DEVICE(object_resolve_path_component(macio, "escc")); + qdev_prop_set_chr(dev, "chrA", serial_hd(0)); + qdev_prop_set_chr(dev, "chrB", serial_hd(1)); - pci_realize_and_unref(macio, pci_bus, &error_fatal); + pci_realize_and_unref(PCI_DEVICE(macio), pci_bus, &error_fatal); - pic_dev = DEVICE(object_resolve_path_component(OBJECT(macio), "pic")); + pic_dev = DEVICE(object_resolve_path_component(macio, "pic")); for (i = 0; i < 4; i++) { - qdev_connect_gpio_out(DEVICE(uninorth_pci), i, + qdev_connect_gpio_out(uninorth_pci_dev, i, qdev_get_gpio_in(pic_dev, 0x1b + i)); } @@ -379,19 +376,17 @@ static void ppc_core99_init(MachineState *machine) /* We only emulate 2 out of 3 IDE controllers for now */ ide_drive_get(hd, ARRAY_SIZE(hd)); - macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio), - "ide[0]")); + macio_ide = MACIO_IDE(object_resolve_path_component(macio, "ide[0]")); macio_ide_init_drives(macio_ide, hd); - macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio), - "ide[1]")); + macio_ide = MACIO_IDE(object_resolve_path_component(macio, "ide[1]")); macio_ide_init_drives(macio_ide, &hd[MAX_IDE_DEVS]); if (has_adb) { if (has_pmu) { - dev = DEVICE(object_resolve_path_component(OBJECT(macio), "pmu")); + dev = DEVICE(object_resolve_path_component(macio, "pmu")); } else { - dev = DEVICE(object_resolve_path_component(OBJECT(macio), "cuda")); + dev = DEVICE(object_resolve_path_component(macio, "cuda")); } adb_bus = qdev_get_child_bus(dev, "adb.0"); diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c index cb67e44081..a497507f1d 100644 --- a/hw/ppc/mac_oldworld.c +++ b/hw/ppc/mac_oldworld.c @@ -90,9 +90,8 @@ static void ppc_heathrow_init(MachineState *machine) uint32_t kernel_base = 0, initrd_base = 0, cmdline_base = 0; int32_t kernel_size = 0, initrd_size = 0; PCIBus *pci_bus; - PCIDevice *macio; + Object *macio; MACIOIDEState *macio_ide; - ESCCState *escc; SysBusDevice *s; DeviceState *dev, *pic_dev, *grackle_dev; BusState *adb_bus; @@ -231,17 +230,16 @@ static void ppc_heathrow_init(MachineState *machine) pci_bus = PCI_HOST_BRIDGE(grackle_dev)->bus; /* MacIO */ - macio = pci_new(PCI_DEVFN(16, 0), TYPE_OLDWORLD_MACIO); - dev = DEVICE(macio); - qdev_prop_set_uint64(dev, "frequency", tbfreq); + macio = OBJECT(pci_new(PCI_DEVFN(16, 0), TYPE_OLDWORLD_MACIO)); + qdev_prop_set_uint64(DEVICE(macio), "frequency", tbfreq); - escc = ESCC(object_resolve_path_component(OBJECT(macio), "escc")); - qdev_prop_set_chr(DEVICE(escc), "chrA", serial_hd(0)); - qdev_prop_set_chr(DEVICE(escc), "chrB", serial_hd(1)); + dev = DEVICE(object_resolve_path_component(macio, "escc")); + qdev_prop_set_chr(dev, "chrA", serial_hd(0)); + qdev_prop_set_chr(dev, "chrB", serial_hd(1)); - pci_realize_and_unref(macio, pci_bus, &error_fatal); + pci_realize_and_unref(PCI_DEVICE(macio), pci_bus, &error_fatal); - pic_dev = DEVICE(object_resolve_path_component(OBJECT(macio), "pic")); + pic_dev = DEVICE(object_resolve_path_component(macio, "pic")); for (i = 0; i < 4; i++) { qdev_connect_gpio_out(grackle_dev, i, qdev_get_gpio_in(pic_dev, 0x15 + i)); @@ -269,16 +267,14 @@ static void ppc_heathrow_init(MachineState *machine) /* MacIO IDE */ ide_drive_get(hd, ARRAY_SIZE(hd)); - macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio), - "ide[0]")); + macio_ide = MACIO_IDE(object_resolve_path_component(macio, "ide[0]")); macio_ide_init_drives(macio_ide, hd); - macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio), - "ide[1]")); + macio_ide = MACIO_IDE(object_resolve_path_component(macio, "ide[1]")); macio_ide_init_drives(macio_ide, &hd[MAX_IDE_DEVS]); /* MacIO CUDA/ADB */ - dev = DEVICE(object_resolve_path_component(OBJECT(macio), "cuda")); + dev = DEVICE(object_resolve_path_component(macio, "cuda")); adb_bus = qdev_get_child_bus(dev, "adb.0"); dev = qdev_new(TYPE_ADB_KEYBOARD); qdev_realize_and_unref(dev, adb_bus, &error_fatal); From cfb47bfaa107c3bf8d084d7a027741825fac4fbc Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Fri, 28 Oct 2022 13:56:23 +0200 Subject: [PATCH 473/705] hw/ppc/mac.h: Move newworld specific parts out from shared header Move the parts specific to and only used by mac99 out from the shared mac.h into mac_newworld.c where they better belong. Signed-off-by: BALATON Zoltan Reviewed-by: Mark Cave-Ayland Message-Id: Signed-off-by: Mark Cave-Ayland --- hw/ppc/mac.h | 24 ------------------------ hw/ppc/mac_newworld.c | 19 +++++++++++++++++++ hw/ppc/mac_oldworld.c | 1 + 3 files changed, 20 insertions(+), 24 deletions(-) diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h index a1fa8f8e41..e97087c7e7 100644 --- a/hw/ppc/mac.h +++ b/hw/ppc/mac.h @@ -26,15 +26,8 @@ #ifndef PPC_MAC_H #define PPC_MAC_H -#include "qemu/units.h" #include "exec/memory.h" -#include "hw/boards.h" #include "hw/sysbus.h" -#include "hw/input/adb.h" -#include "hw/misc/mos6522.h" -#include "hw/pci/pci_host.h" -#include "hw/pci-host/uninorth.h" -#include "qom/object.h" #define NVRAM_SIZE 0x2000 #define PROM_FILENAME "openbios-ppc" @@ -65,23 +58,6 @@ #define NEWWORLD_EXTING_GPIO1 0x2f #define NEWWORLD_EXTING_GPIO9 0x37 -/* Core99 machine */ -#define TYPE_CORE99_MACHINE MACHINE_TYPE_NAME("mac99") -typedef struct Core99MachineState Core99MachineState; -DECLARE_INSTANCE_CHECKER(Core99MachineState, CORE99_MACHINE, - TYPE_CORE99_MACHINE) - -#define CORE99_VIA_CONFIG_CUDA 0x0 -#define CORE99_VIA_CONFIG_PMU 0x1 -#define CORE99_VIA_CONFIG_PMU_ADB 0x2 - -struct Core99MachineState { - /*< private >*/ - MachineState parent; - - uint8_t via_config; -}; - /* Grackle PCI */ #define TYPE_GRACKLE_PCI_HOST_BRIDGE "grackle-pcihost" diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index 4bfffa586b..873c9f5cb4 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -48,10 +48,13 @@ #include "qemu/osdep.h" #include "qemu/datadir.h" +#include "qemu/units.h" #include "qapi/error.h" #include "hw/ppc/ppc.h" #include "hw/qdev-properties.h" #include "hw/ppc/mac.h" +#include "hw/boards.h" +#include "hw/pci-host/uninorth.h" #include "hw/input/adb.h" #include "hw/ppc/mac_dbdma.h" #include "hw/pci/pci.h" @@ -83,6 +86,22 @@ #define PROM_BASE 0xfff00000 #define PROM_SIZE (1 * MiB) +#define TYPE_CORE99_MACHINE MACHINE_TYPE_NAME("mac99") +typedef struct Core99MachineState Core99MachineState; +DECLARE_INSTANCE_CHECKER(Core99MachineState, CORE99_MACHINE, + TYPE_CORE99_MACHINE) + +#define CORE99_VIA_CONFIG_CUDA 0x0 +#define CORE99_VIA_CONFIG_PMU 0x1 +#define CORE99_VIA_CONFIG_PMU_ADB 0x2 + +struct Core99MachineState { + /*< private >*/ + MachineState parent; + + uint8_t via_config; +}; + static void fw_cfg_boot_set(void *opaque, const char *boot_device, Error **errp) { diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c index a497507f1d..f323a49d7a 100644 --- a/hw/ppc/mac_oldworld.c +++ b/hw/ppc/mac_oldworld.c @@ -31,6 +31,7 @@ #include "hw/ppc/ppc.h" #include "hw/qdev-properties.h" #include "mac.h" +#include "hw/boards.h" #include "hw/input/adb.h" #include "sysemu/sysemu.h" #include "net/net.h" From 55078ea7775f207db5d8bca252151fc85741a8ca Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Fri, 28 Oct 2022 13:56:24 +0200 Subject: [PATCH 474/705] hw/ppc/mac.h: Move macio specific parts out from shared header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the parts specific to and only used by macio out from the shared mac.h into macio.c where they better belong. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Mark Cave-Ayland Message-Id: Signed-off-by: Mark Cave-Ayland --- hw/misc/macio/macio.c | 5 +++-- hw/ppc/mac.h | 23 ----------------------- include/hw/misc/macio/macio.h | 21 +++++++++++++++++++++ 3 files changed, 24 insertions(+), 25 deletions(-) diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c index c1fad43f6c..f9f0758b03 100644 --- a/hw/misc/macio/macio.c +++ b/hw/misc/macio/macio.c @@ -37,8 +37,9 @@ #include "hw/intc/heathrow_pic.h" #include "trace.h" -/* Note: this code is strongly inspirated from the corresponding code - * in PearPC */ +#define ESCC_CLOCK 3686400 + +/* Note: this code is strongly inspired by the corresponding code in PearPC */ /* * The mac-io has two interfaces to the ESCC. One is called "escc-legacy", diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h index e97087c7e7..55cb02c990 100644 --- a/hw/ppc/mac.h +++ b/hw/ppc/mac.h @@ -35,29 +35,6 @@ #define KERNEL_LOAD_ADDR 0x01000000 #define KERNEL_GAP 0x00100000 -#define ESCC_CLOCK 3686400 - -/* Old World IRQs */ -#define OLDWORLD_CUDA_IRQ 0x12 -#define OLDWORLD_ESCCB_IRQ 0x10 -#define OLDWORLD_ESCCA_IRQ 0xf -#define OLDWORLD_IDE0_IRQ 0xd -#define OLDWORLD_IDE0_DMA_IRQ 0x2 -#define OLDWORLD_IDE1_IRQ 0xe -#define OLDWORLD_IDE1_DMA_IRQ 0x3 - -/* New World IRQs */ -#define NEWWORLD_CUDA_IRQ 0x19 -#define NEWWORLD_PMU_IRQ 0x19 -#define NEWWORLD_ESCCB_IRQ 0x24 -#define NEWWORLD_ESCCA_IRQ 0x25 -#define NEWWORLD_IDE0_IRQ 0xd -#define NEWWORLD_IDE0_DMA_IRQ 0x2 -#define NEWWORLD_IDE1_IRQ 0xe -#define NEWWORLD_IDE1_DMA_IRQ 0x3 -#define NEWWORLD_EXTING_GPIO1 0x2f -#define NEWWORLD_EXTING_GPIO9 0x37 - /* Grackle PCI */ #define TYPE_GRACKLE_PCI_HOST_BRIDGE "grackle-pcihost" diff --git a/include/hw/misc/macio/macio.h b/include/hw/misc/macio/macio.h index 6c05f3bfd2..26cf15b1ce 100644 --- a/include/hw/misc/macio/macio.h +++ b/include/hw/misc/macio/macio.h @@ -38,6 +38,27 @@ #include "hw/ppc/openpic.h" #include "qom/object.h" +/* Old World IRQs */ +#define OLDWORLD_CUDA_IRQ 0x12 +#define OLDWORLD_ESCCB_IRQ 0x10 +#define OLDWORLD_ESCCA_IRQ 0xf +#define OLDWORLD_IDE0_IRQ 0xd +#define OLDWORLD_IDE0_DMA_IRQ 0x2 +#define OLDWORLD_IDE1_IRQ 0xe +#define OLDWORLD_IDE1_DMA_IRQ 0x3 + +/* New World IRQs */ +#define NEWWORLD_CUDA_IRQ 0x19 +#define NEWWORLD_PMU_IRQ 0x19 +#define NEWWORLD_ESCCB_IRQ 0x24 +#define NEWWORLD_ESCCA_IRQ 0x25 +#define NEWWORLD_IDE0_IRQ 0xd +#define NEWWORLD_IDE0_DMA_IRQ 0x2 +#define NEWWORLD_IDE1_IRQ 0xe +#define NEWWORLD_IDE1_DMA_IRQ 0x3 +#define NEWWORLD_EXTING_GPIO1 0x2f +#define NEWWORLD_EXTING_GPIO9 0x37 + /* MacIO virtual bus */ #define TYPE_MACIO_BUS "macio-bus" OBJECT_DECLARE_SIMPLE_TYPE(MacIOBusState, MACIO_BUS) From 87e5a4f8c23236a559c63ca089c35d3e6066d3df Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Fri, 28 Oct 2022 13:56:25 +0200 Subject: [PATCH 475/705] hw/ppc/mac.h: Move grackle-pcihost type declaration out to a header Signed-off-by: BALATON Zoltan Reviewed-by: Mark Cave-Ayland Message-Id: Signed-off-by: Mark Cave-Ayland --- MAINTAINERS | 1 + hw/pci-host/grackle.c | 14 +---------- hw/ppc/mac.h | 3 --- hw/ppc/mac_oldworld.c | 1 + include/hw/pci-host/grackle.h | 44 +++++++++++++++++++++++++++++++++++ 5 files changed, 47 insertions(+), 16 deletions(-) create mode 100644 include/hw/pci-host/grackle.h diff --git a/MAINTAINERS b/MAINTAINERS index c41d8d65e2..9f424bceb1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1344,6 +1344,7 @@ F: hw/intc/heathrow_pic.c F: hw/input/adb* F: include/hw/intc/heathrow_pic.h F: include/hw/input/adb* +F: include/hw/pci-host/grackle.h F: pc-bios/qemu_vga.ndrv PReP diff --git a/hw/pci-host/grackle.c b/hw/pci-host/grackle.c index b05facf463..e4c7303859 100644 --- a/hw/pci-host/grackle.c +++ b/hw/pci-host/grackle.c @@ -24,7 +24,6 @@ */ #include "qemu/osdep.h" -#include "hw/pci/pci_host.h" #include "hw/ppc/mac.h" #include "hw/qdev-properties.h" #include "hw/pci/pci.h" @@ -33,18 +32,7 @@ #include "qemu/module.h" #include "trace.h" #include "qom/object.h" - -OBJECT_DECLARE_SIMPLE_TYPE(GrackleState, GRACKLE_PCI_HOST_BRIDGE) - -struct GrackleState { - PCIHostState parent_obj; - - uint32_t ofw_addr; - qemu_irq irqs[4]; - MemoryRegion pci_mmio; - MemoryRegion pci_hole; - MemoryRegion pci_io; -}; +#include "hw/pci-host/grackle.h" /* Don't know if this matches real hardware, but it agrees with OHW. */ static int pci_grackle_map_irq(PCIDevice *pci_dev, int irq_num) diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h index 55cb02c990..fe77a6c6db 100644 --- a/hw/ppc/mac.h +++ b/hw/ppc/mac.h @@ -35,9 +35,6 @@ #define KERNEL_LOAD_ADDR 0x01000000 #define KERNEL_GAP 0x00100000 -/* Grackle PCI */ -#define TYPE_GRACKLE_PCI_HOST_BRIDGE "grackle-pcihost" - /* Mac NVRAM */ #define TYPE_MACIO_NVRAM "macio-nvram" OBJECT_DECLARE_SIMPLE_TYPE(MacIONVRAMState, MACIO_NVRAM) diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c index f323a49d7a..47a1abf248 100644 --- a/hw/ppc/mac_oldworld.c +++ b/hw/ppc/mac_oldworld.c @@ -38,6 +38,7 @@ #include "hw/isa/isa.h" #include "hw/pci/pci.h" #include "hw/pci/pci_host.h" +#include "hw/pci-host/grackle.h" #include "hw/nvram/fw_cfg.h" #include "hw/char/escc.h" #include "hw/misc/macio/macio.h" diff --git a/include/hw/pci-host/grackle.h b/include/hw/pci-host/grackle.h new file mode 100644 index 0000000000..7ad3a779f0 --- /dev/null +++ b/include/hw/pci-host/grackle.h @@ -0,0 +1,44 @@ +/* + * QEMU Grackle PCI host (heathrow OldWorld PowerMac) + * + * Copyright (c) 2006-2007 Fabrice Bellard + * Copyright (c) 2007 Jocelyn Mayer + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef GRACKLE_H +#define GRACKLE_H + +#include "hw/pci/pci_host.h" + +#define TYPE_GRACKLE_PCI_HOST_BRIDGE "grackle-pcihost" +OBJECT_DECLARE_SIMPLE_TYPE(GrackleState, GRACKLE_PCI_HOST_BRIDGE) + +struct GrackleState { + PCIHostState parent_obj; + + uint32_t ofw_addr; + qemu_irq irqs[4]; + MemoryRegion pci_mmio; + MemoryRegion pci_hole; + MemoryRegion pci_io; +}; + +#endif From 3d0031c17d32515914d9b92e540a55af0c7032ca Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Fri, 28 Oct 2022 13:56:26 +0200 Subject: [PATCH 476/705] hw/ppc/mac.h: Move PROM and KERNEL defines to board code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PROM_FILENAME and KERNEL_* defines are used by mac_oldworld and mac_newworld but they don't have to be identical so these could be moved to the individual boards. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Mark Cave-Ayland Message-Id: <5fa693334adf166d23931c81d81ada4e3441ed7d.1666957578.git.balaton@eik.bme.hu> Signed-off-by: Mark Cave-Ayland --- hw/ppc/mac.h | 4 ---- hw/ppc/mac_newworld.c | 4 ++++ hw/ppc/mac_oldworld.c | 7 ++++++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h index fe77a6c6db..3e2df262ee 100644 --- a/hw/ppc/mac.h +++ b/hw/ppc/mac.h @@ -30,10 +30,6 @@ #include "hw/sysbus.h" #define NVRAM_SIZE 0x2000 -#define PROM_FILENAME "openbios-ppc" - -#define KERNEL_LOAD_ADDR 0x01000000 -#define KERNEL_GAP 0x00100000 /* Mac NVRAM */ #define TYPE_MACIO_NVRAM "macio-nvram" diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index 873c9f5cb4..c75c59fe3e 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -83,9 +83,13 @@ #define NDRV_VGA_FILENAME "qemu_vga.ndrv" +#define PROM_FILENAME "openbios-ppc" #define PROM_BASE 0xfff00000 #define PROM_SIZE (1 * MiB) +#define KERNEL_LOAD_ADDR 0x01000000 +#define KERNEL_GAP 0x00100000 + #define TYPE_CORE99_MACHINE MACHINE_TYPE_NAME("mac99") typedef struct Core99MachineState Core99MachineState; DECLARE_INSTANCE_CHECKER(Core99MachineState, CORE99_MACHINE, diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c index 47a1abf248..ae8e0ff30a 100644 --- a/hw/ppc/mac_oldworld.c +++ b/hw/ppc/mac_oldworld.c @@ -58,10 +58,15 @@ #define NDRV_VGA_FILENAME "qemu_vga.ndrv" -#define GRACKLE_BASE 0xfec00000 +#define PROM_FILENAME "openbios-ppc" #define PROM_BASE 0xffc00000 #define PROM_SIZE (4 * MiB) +#define KERNEL_LOAD_ADDR 0x01000000 +#define KERNEL_GAP 0x00100000 + +#define GRACKLE_BASE 0xfec00000 + static void fw_cfg_boot_set(void *opaque, const char *boot_device, Error **errp) { From 443f07b73d139e6944bc6af472b6e9df790b6e38 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Fri, 28 Oct 2022 13:56:27 +0200 Subject: [PATCH 477/705] hw/ppc/mac.h: Rename to include/hw/nvram/mac_nvram.h All that is left in mac.h now belongs to the nvram emulation so rename it accordingly and only include it where it is really used. Signed-off-by: BALATON Zoltan Reviewed-by: Mark Cave-Ayland Message-Id: Signed-off-by: Mark Cave-Ayland --- MAINTAINERS | 1 + hw/ide/macio.c | 1 - hw/intc/heathrow_pic.c | 1 - hw/intc/openpic.c | 1 - hw/misc/macio/cuda.c | 1 - hw/misc/macio/gpio.c | 1 - hw/misc/macio/macio.c | 1 - hw/misc/macio/pmu.c | 1 - hw/nvram/mac_nvram.c | 2 +- hw/pci-host/grackle.c | 1 - hw/pci-host/uninorth.c | 1 - hw/ppc/mac_newworld.c | 2 +- hw/ppc/mac_oldworld.c | 1 - include/hw/misc/macio/macio.h | 2 +- hw/ppc/mac.h => include/hw/nvram/mac_nvram.h | 11 ++++++----- 15 files changed, 10 insertions(+), 18 deletions(-) rename hw/ppc/mac.h => include/hw/nvram/mac_nvram.h (89%) diff --git a/MAINTAINERS b/MAINTAINERS index 9f424bceb1..223afc2e13 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1327,6 +1327,7 @@ F: hw/nvram/mac_nvram.c F: hw/input/adb* F: include/hw/misc/macio/ F: include/hw/misc/mos6522.h +F: include/hw/nvram/mac_nvram.h F: include/hw/ppc/mac_dbdma.h F: include/hw/pci-host/uninorth.h F: include/hw/input/adb* diff --git a/hw/ide/macio.c b/hw/ide/macio.c index 1c15c37ec5..e604466acb 100644 --- a/hw/ide/macio.c +++ b/hw/ide/macio.c @@ -24,7 +24,6 @@ */ #include "qemu/osdep.h" -#include "hw/ppc/mac.h" #include "hw/ppc/mac_dbdma.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" diff --git a/hw/intc/heathrow_pic.c b/hw/intc/heathrow_pic.c index cb97c315da..13048a2735 100644 --- a/hw/intc/heathrow_pic.c +++ b/hw/intc/heathrow_pic.c @@ -24,7 +24,6 @@ */ #include "qemu/osdep.h" -#include "hw/ppc/mac.h" #include "migration/vmstate.h" #include "qemu/module.h" #include "hw/intc/heathrow_pic.h" diff --git a/hw/intc/openpic.c b/hw/intc/openpic.c index b0787e8ee7..c757adbe53 100644 --- a/hw/intc/openpic.c +++ b/hw/intc/openpic.c @@ -32,7 +32,6 @@ #include "qemu/osdep.h" #include "hw/irq.h" -#include "hw/ppc/mac.h" #include "hw/pci/pci.h" #include "hw/ppc/openpic.h" #include "hw/ppc/ppc_e500.h" diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c index 1498113cfc..0d4c13319a 100644 --- a/hw/misc/macio/cuda.c +++ b/hw/misc/macio/cuda.c @@ -25,7 +25,6 @@ #include "qemu/osdep.h" #include "hw/irq.h" -#include "hw/ppc/mac.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" #include "hw/input/adb.h" diff --git a/hw/misc/macio/gpio.c b/hw/misc/macio/gpio.c index b1bcf830c3..c8ac5633b2 100644 --- a/hw/misc/macio/gpio.c +++ b/hw/misc/macio/gpio.c @@ -24,7 +24,6 @@ */ #include "qemu/osdep.h" -#include "hw/ppc/mac.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" #include "hw/misc/macio/macio.h" diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c index f9f0758b03..93a7c7bbc8 100644 --- a/hw/misc/macio/macio.c +++ b/hw/misc/macio/macio.c @@ -26,7 +26,6 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "qemu/module.h" -#include "hw/ppc/mac.h" #include "hw/misc/macio/cuda.h" #include "hw/pci/pci.h" #include "hw/ppc/mac_dbdma.h" diff --git a/hw/misc/macio/pmu.c b/hw/misc/macio/pmu.c index 336502a84b..70562ed8d0 100644 --- a/hw/misc/macio/pmu.c +++ b/hw/misc/macio/pmu.c @@ -29,7 +29,6 @@ */ #include "qemu/osdep.h" -#include "hw/ppc/mac.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" #include "hw/input/adb.h" diff --git a/hw/nvram/mac_nvram.c b/hw/nvram/mac_nvram.c index 11f2d31cdb..3d9ddda217 100644 --- a/hw/nvram/mac_nvram.c +++ b/hw/nvram/mac_nvram.c @@ -25,7 +25,7 @@ #include "qemu/osdep.h" #include "hw/nvram/chrp_nvram.h" -#include "hw/ppc/mac.h" +#include "hw/nvram/mac_nvram.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" #include "qemu/cutils.h" diff --git a/hw/pci-host/grackle.c b/hw/pci-host/grackle.c index e4c7303859..95945ac0f4 100644 --- a/hw/pci-host/grackle.c +++ b/hw/pci-host/grackle.c @@ -24,7 +24,6 @@ */ #include "qemu/osdep.h" -#include "hw/ppc/mac.h" #include "hw/qdev-properties.h" #include "hw/pci/pci.h" #include "hw/irq.h" diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c index d25b62d6a5..aebd44d265 100644 --- a/hw/pci-host/uninorth.c +++ b/hw/pci-host/uninorth.c @@ -24,7 +24,6 @@ #include "qemu/osdep.h" #include "hw/irq.h" -#include "hw/ppc/mac.h" #include "hw/qdev-properties.h" #include "qemu/module.h" #include "hw/pci/pci.h" diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index c75c59fe3e..eb597bbe20 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -52,7 +52,7 @@ #include "qapi/error.h" #include "hw/ppc/ppc.h" #include "hw/qdev-properties.h" -#include "hw/ppc/mac.h" +#include "hw/nvram/mac_nvram.h" #include "hw/boards.h" #include "hw/pci-host/uninorth.h" #include "hw/input/adb.h" diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c index ae8e0ff30a..23d9268281 100644 --- a/hw/ppc/mac_oldworld.c +++ b/hw/ppc/mac_oldworld.c @@ -30,7 +30,6 @@ #include "qapi/error.h" #include "hw/ppc/ppc.h" #include "hw/qdev-properties.h" -#include "mac.h" #include "hw/boards.h" #include "hw/input/adb.h" #include "sysemu/sysemu.h" diff --git a/include/hw/misc/macio/macio.h b/include/hw/misc/macio/macio.h index 26cf15b1ce..95d30a1745 100644 --- a/include/hw/misc/macio/macio.h +++ b/include/hw/misc/macio/macio.h @@ -33,7 +33,7 @@ #include "hw/misc/macio/cuda.h" #include "hw/misc/macio/gpio.h" #include "hw/misc/macio/pmu.h" -#include "hw/ppc/mac.h" +#include "hw/nvram/mac_nvram.h" #include "hw/ppc/mac_dbdma.h" #include "hw/ppc/openpic.h" #include "qom/object.h" diff --git a/hw/ppc/mac.h b/include/hw/nvram/mac_nvram.h similarity index 89% rename from hw/ppc/mac.h rename to include/hw/nvram/mac_nvram.h index 3e2df262ee..baa9f6a5a6 100644 --- a/hw/ppc/mac.h +++ b/include/hw/nvram/mac_nvram.h @@ -1,5 +1,5 @@ /* - * QEMU PowerMac emulation shared definitions and prototypes + * PowerMac NVRAM emulation * * Copyright (c) 2004-2007 Fabrice Bellard * Copyright (c) 2007 Jocelyn Mayer @@ -23,8 +23,8 @@ * THE SOFTWARE. */ -#ifndef PPC_MAC_H -#define PPC_MAC_H +#ifndef MAC_NVRAM_H +#define MAC_NVRAM_H #include "exec/memory.h" #include "hw/sysbus.h" @@ -47,5 +47,6 @@ struct MacIONVRAMState { uint8_t *data; }; -void pmac_format_nvram_partition (MacIONVRAMState *nvr, int len); -#endif /* PPC_MAC_H */ +void pmac_format_nvram_partition(MacIONVRAMState *nvr, int len); + +#endif /* MAC_NVRAM_H */ From 458586fe19585d6949c79c898e2181048565c774 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Fri, 28 Oct 2022 13:56:28 +0200 Subject: [PATCH 478/705] mac_nvram: Use NVRAM_SIZE constant The NVRAM_SIZE constant was defined but not used. Rename it to MACIO_NVRAM_SIZE to match the device model and use it where appropriate. Signed-off-by: BALATON Zoltan Reviewed-by: Mark Cave-Ayland Message-Id: <5b53c70438dfb46837af8a094e753706b06c4ec6.1666957578.git.balaton@eik.bme.hu> Signed-off-by: Mark Cave-Ayland --- hw/misc/macio/macio.c | 2 +- hw/ppc/mac_newworld.c | 4 ++-- include/hw/nvram/mac_nvram.h | 3 +-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c index 93a7c7bbc8..08dbdd7fc0 100644 --- a/hw/misc/macio/macio.c +++ b/hw/misc/macio/macio.c @@ -226,7 +226,7 @@ static void macio_oldworld_init(Object *obj) object_initialize_child(OBJECT(s), "nvram", &os->nvram, TYPE_MACIO_NVRAM); dev = DEVICE(&os->nvram); - qdev_prop_set_uint32(dev, "size", 0x2000); + qdev_prop_set_uint32(dev, "size", MACIO_NVRAM_SIZE); qdev_prop_set_uint32(dev, "it_shift", 4); for (i = 0; i < 2; i++) { diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index eb597bbe20..6b2d781dea 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -450,12 +450,12 @@ static void ppc_core99_init(MachineState *machine) nvram_addr = 0xFFE00000; } dev = qdev_new(TYPE_MACIO_NVRAM); - qdev_prop_set_uint32(dev, "size", 0x2000); + qdev_prop_set_uint32(dev, "size", MACIO_NVRAM_SIZE); qdev_prop_set_uint32(dev, "it_shift", 1); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, nvram_addr); nvr = MACIO_NVRAM(dev); - pmac_format_nvram_partition(nvr, 0x2000); + pmac_format_nvram_partition(nvr, MACIO_NVRAM_SIZE); /* No PCI init: the BIOS will do it */ dev = qdev_new(TYPE_FW_CFG_MEM); diff --git a/include/hw/nvram/mac_nvram.h b/include/hw/nvram/mac_nvram.h index baa9f6a5a6..b780aca470 100644 --- a/include/hw/nvram/mac_nvram.h +++ b/include/hw/nvram/mac_nvram.h @@ -29,9 +29,8 @@ #include "exec/memory.h" #include "hw/sysbus.h" -#define NVRAM_SIZE 0x2000 +#define MACIO_NVRAM_SIZE 0x2000 -/* Mac NVRAM */ #define TYPE_MACIO_NVRAM "macio-nvram" OBJECT_DECLARE_SIMPLE_TYPE(MacIONVRAMState, MACIO_NVRAM) From cc537e1338cc4f16f93f9d1d37ac54fb1c3ffe4f Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Fri, 28 Oct 2022 13:56:29 +0200 Subject: [PATCH 479/705] mac_{old|new}world: Code style fix adding missing braces to if-s Signed-off-by: BALATON Zoltan Reviewed-by: Mark Cave-Ayland Message-Id: Signed-off-by: Mark Cave-Ayland --- hw/ppc/mac_newworld.c | 6 ++++-- hw/ppc/mac_oldworld.c | 9 ++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index 6b2d781dea..37123daa6b 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -202,14 +202,16 @@ static void ppc_core99_init(MachineState *machine) kernel_size = load_elf(machine->kernel_filename, NULL, translate_kernel_address, NULL, NULL, NULL, NULL, NULL, 1, PPC_ELF_MACHINE, 0, 0); - if (kernel_size < 0) + if (kernel_size < 0) { kernel_size = load_aout(machine->kernel_filename, kernel_base, machine->ram_size - kernel_base, bswap_needed, TARGET_PAGE_SIZE); - if (kernel_size < 0) + } + if (kernel_size < 0) { kernel_size = load_image_targphys(machine->kernel_filename, kernel_base, machine->ram_size - kernel_base); + } if (kernel_size < 0) { error_report("could not load kernel '%s'", machine->kernel_filename); diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c index 23d9268281..558c639202 100644 --- a/hw/ppc/mac_oldworld.c +++ b/hw/ppc/mac_oldworld.c @@ -160,14 +160,16 @@ static void ppc_heathrow_init(MachineState *machine) kernel_size = load_elf(machine->kernel_filename, NULL, translate_kernel_address, NULL, NULL, NULL, NULL, NULL, 1, PPC_ELF_MACHINE, 0, 0); - if (kernel_size < 0) + if (kernel_size < 0) { kernel_size = load_aout(machine->kernel_filename, kernel_base, machine->ram_size - kernel_base, bswap_needed, TARGET_PAGE_SIZE); - if (kernel_size < 0) + } + if (kernel_size < 0) { kernel_size = load_image_targphys(machine->kernel_filename, kernel_base, machine->ram_size - kernel_base); + } if (kernel_size < 0) { error_report("could not load kernel '%s'", machine->kernel_filename); @@ -291,8 +293,9 @@ static void ppc_heathrow_init(MachineState *machine) pci_create_simple(pci_bus, -1, "pci-ohci"); } - if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8) + if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8) { graphic_depth = 15; + } /* No PCI init: the BIOS will do it */ From 53cb552daeb57e0a35f648e42fb28fa38842bd0c Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Fri, 28 Oct 2022 13:56:30 +0200 Subject: [PATCH 480/705] mac_newworld: Turn CORE99_VIA_CONFIG defines into an enum This might allow the compiler to check values. Signed-off-by: BALATON Zoltan Reviewed-by: Mark Cave-Ayland Message-Id: Signed-off-by: Mark Cave-Ayland --- hw/ppc/mac_newworld.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index 37123daa6b..601ea518f8 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -95,15 +95,17 @@ typedef struct Core99MachineState Core99MachineState; DECLARE_INSTANCE_CHECKER(Core99MachineState, CORE99_MACHINE, TYPE_CORE99_MACHINE) -#define CORE99_VIA_CONFIG_CUDA 0x0 -#define CORE99_VIA_CONFIG_PMU 0x1 -#define CORE99_VIA_CONFIG_PMU_ADB 0x2 +typedef enum { + CORE99_VIA_CONFIG_CUDA = 0, + CORE99_VIA_CONFIG_PMU, + CORE99_VIA_CONFIG_PMU_ADB +} Core99ViaConfig; struct Core99MachineState { /*< private >*/ MachineState parent; - uint8_t via_config; + Core99ViaConfig via_config; }; static void fw_cfg_boot_set(void *opaque, const char *boot_device, From 3a5f6805c7ca7deb8d1abaf0153936eeb51d074e Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 17 Oct 2022 07:28:30 +0300 Subject: [PATCH 481/705] tcg/sparc: Remove support for sparc32plus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since 9b9c37c36439, we have only supported sparc64 cpus. Debian and Gentoo now only support 64-bit sparc64 userland, so it is time to drop the 32-bit sparc64 userland: sparc32plus. Reviewed-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- tcg/sparc/tcg-target.c.inc | 166 +++++++------------------------------ tcg/sparc/tcg-target.h | 11 --- tcg/tcg.c | 75 +---------------- 3 files changed, 33 insertions(+), 219 deletions(-) diff --git a/tcg/sparc/tcg-target.c.inc b/tcg/sparc/tcg-target.c.inc index 72d9552fd0..097bcfcd12 100644 --- a/tcg/sparc/tcg-target.c.inc +++ b/tcg/sparc/tcg-target.c.inc @@ -22,6 +22,11 @@ * THE SOFTWARE. */ +/* We only support generating code for 64-bit mode. */ +#ifndef __arch64__ +#error "unsupported code generation mode" +#endif + #include "../tcg-pool.c.inc" #ifdef CONFIG_DEBUG_TCG @@ -61,12 +66,6 @@ static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = { }; #endif -#ifdef __arch64__ -# define SPARC64 1 -#else -# define SPARC64 0 -#endif - #define TCG_CT_CONST_S11 0x100 #define TCG_CT_CONST_S13 0x200 #define TCG_CT_CONST_ZERO 0x400 @@ -91,11 +90,7 @@ static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = { * high bits of the %i and %l registers garbage at all times. */ #define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 32) -#if SPARC64 # define ALL_GENERAL_REGS64 ALL_GENERAL_REGS -#else -# define ALL_GENERAL_REGS64 MAKE_64BIT_MASK(0, 16) -#endif #define ALL_QLDST_REGS (ALL_GENERAL_REGS & ~SOFTMMU_RESERVE_REGS) #define ALL_QLDST_REGS64 (ALL_GENERAL_REGS64 & ~SOFTMMU_RESERVE_REGS) @@ -306,11 +301,7 @@ static bool check_fit_i32(int32_t val, unsigned int bits) } #define check_fit_tl check_fit_i64 -#if SPARC64 -# define check_fit_ptr check_fit_i64 -#else -# define check_fit_ptr check_fit_i32 -#endif +#define check_fit_ptr check_fit_i64 static bool patch_reloc(tcg_insn_unit *src_rw, int type, intptr_t value, intptr_t addend) @@ -573,11 +564,6 @@ static void tcg_out_sety(TCGContext *s, TCGReg rs) tcg_out32(s, WRY | INSN_RS1(TCG_REG_G0) | INSN_RS2(rs)); } -static void tcg_out_rdy(TCGContext *s, TCGReg rd) -{ - tcg_out32(s, RDY | INSN_RD(rd)); -} - static void tcg_out_div32(TCGContext *s, TCGReg rd, TCGReg rs1, int32_t val2, int val2const, int uns) { @@ -914,9 +900,7 @@ static void emit_extend(TCGContext *s, TCGReg r, int op) tcg_out_arithi(s, r, r, 16, SHIFT_SRL); break; case MO_32: - if (SPARC64) { - tcg_out_arith(s, r, r, 0, SHIFT_SRL); - } + tcg_out_arith(s, r, r, 0, SHIFT_SRL); break; case MO_64: break; @@ -948,7 +932,6 @@ static void build_trampolines(TCGContext *s) }; int i; - TCGReg ra; for (i = 0; i < ARRAY_SIZE(qemu_ld_helpers); ++i) { if (qemu_ld_helpers[i] == NULL) { @@ -961,16 +944,8 @@ static void build_trampolines(TCGContext *s) } qemu_ld_trampoline[i] = tcg_splitwx_to_rx(s->code_ptr); - if (SPARC64 || TARGET_LONG_BITS == 32) { - ra = TCG_REG_O3; - } else { - /* Install the high part of the address. */ - tcg_out_arithi(s, TCG_REG_O1, TCG_REG_O2, 32, SHIFT_SRLX); - ra = TCG_REG_O4; - } - /* Set the retaddr operand. */ - tcg_out_mov(s, TCG_TYPE_PTR, ra, TCG_REG_O7); + tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O3, TCG_REG_O7); /* Tail call. */ tcg_out_jmpl_const(s, qemu_ld_helpers[i], true, true); /* delay slot -- set the env argument */ @@ -988,37 +963,10 @@ static void build_trampolines(TCGContext *s) } qemu_st_trampoline[i] = tcg_splitwx_to_rx(s->code_ptr); - if (SPARC64) { - emit_extend(s, TCG_REG_O2, i); - ra = TCG_REG_O4; - } else { - ra = TCG_REG_O1; - if (TARGET_LONG_BITS == 64) { - /* Install the high part of the address. */ - tcg_out_arithi(s, ra, ra + 1, 32, SHIFT_SRLX); - ra += 2; - } else { - ra += 1; - } - if ((i & MO_SIZE) == MO_64) { - /* Install the high part of the data. */ - tcg_out_arithi(s, ra, ra + 1, 32, SHIFT_SRLX); - ra += 2; - } else { - emit_extend(s, ra, i); - ra += 1; - } - /* Skip the oi argument. */ - ra += 1; - } - + emit_extend(s, TCG_REG_O2, i); + /* Set the retaddr operand. */ - if (ra >= TCG_REG_O6) { - tcg_out_st(s, TCG_TYPE_PTR, TCG_REG_O7, TCG_REG_CALL_STACK, - TCG_TARGET_CALL_STACK_OFFSET); - } else { - tcg_out_mov(s, TCG_TYPE_PTR, ra, TCG_REG_O7); - } + tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O4, TCG_REG_O7); /* Tail call. */ tcg_out_jmpl_const(s, qemu_st_helpers[i], true, true); @@ -1047,11 +995,6 @@ static void build_trampolines(TCGContext *s) qemu_unalign_st_trampoline = tcg_splitwx_to_rx(s->code_ptr); } - if (!SPARC64 && TARGET_LONG_BITS == 64) { - /* Install the high part of the address. */ - tcg_out_arithi(s, TCG_REG_O1, TCG_REG_O2, 32, SHIFT_SRLX); - } - /* Tail call. */ tcg_out_jmpl_const(s, helper, true, true); /* delay slot -- set the env argument */ @@ -1182,7 +1125,7 @@ static TCGReg tcg_out_tlb_load(TCGContext *s, TCGReg addr, int mem_index, tcg_out_cmp(s, r0, r2, 0); /* If the guest address must be zero-extended, do so now. */ - if (SPARC64 && TARGET_LONG_BITS == 32) { + if (TARGET_LONG_BITS == 32) { tcg_out_arithi(s, r0, addr, 0, SHIFT_SRL); return r0; } @@ -1231,7 +1174,7 @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg data, TCGReg addr, #ifdef CONFIG_SOFTMMU unsigned memi = get_mmuidx(oi); - TCGReg addrz, param; + TCGReg addrz; const tcg_insn_unit *func; addrz = tcg_out_tlb_load(s, addr, memi, memop, @@ -1251,12 +1194,7 @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg data, TCGReg addr, /* TLB Miss. */ - param = TCG_REG_O1; - if (!SPARC64 && TARGET_LONG_BITS == 64) { - /* Skip the high-part; we'll perform the extract in the trampoline. */ - param++; - } - tcg_out_mov(s, TCG_TYPE_REG, param++, addrz); + tcg_out_mov(s, TCG_TYPE_REG, TCG_REG_O1, addrz); /* We use the helpers to extend SB and SW data, leaving the case of SL needing explicit extending below. */ @@ -1268,30 +1206,13 @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg data, TCGReg addr, tcg_debug_assert(func != NULL); tcg_out_call_nodelay(s, func, false); /* delay slot */ - tcg_out_movi(s, TCG_TYPE_I32, param, oi); + tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_O2, oi); - /* Recall that all of the helpers return 64-bit results. - Which complicates things for sparcv8plus. */ - if (SPARC64) { - /* We let the helper sign-extend SB and SW, but leave SL for here. */ - if (is_64 && (memop & MO_SSIZE) == MO_SL) { - tcg_out_arithi(s, data, TCG_REG_O0, 0, SHIFT_SRA); - } else { - tcg_out_mov(s, TCG_TYPE_REG, data, TCG_REG_O0); - } + /* We let the helper sign-extend SB and SW, but leave SL for here. */ + if (is_64 && (memop & MO_SSIZE) == MO_SL) { + tcg_out_arithi(s, data, TCG_REG_O0, 0, SHIFT_SRA); } else { - if ((memop & MO_SIZE) == MO_64) { - tcg_out_arithi(s, TCG_REG_O0, TCG_REG_O0, 32, SHIFT_SLLX); - tcg_out_arithi(s, TCG_REG_O1, TCG_REG_O1, 0, SHIFT_SRL); - tcg_out_arith(s, data, TCG_REG_O0, TCG_REG_O1, ARITH_OR); - } else if (is_64) { - /* Re-extend from 32-bit rather than reassembling when we - know the high register must be an extension. */ - tcg_out_arithi(s, data, TCG_REG_O1, 0, - memop & MO_SIGN ? SHIFT_SRA : SHIFT_SRL); - } else { - tcg_out_mov(s, TCG_TYPE_I32, data, TCG_REG_O1); - } + tcg_out_mov(s, TCG_TYPE_REG, data, TCG_REG_O0); } *label_ptr |= INSN_OFF19(tcg_ptr_byte_diff(s->code_ptr, label_ptr)); @@ -1301,7 +1222,7 @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg data, TCGReg addr, unsigned s_bits = memop & MO_SIZE; unsigned t_bits; - if (SPARC64 && TARGET_LONG_BITS == 32) { + if (TARGET_LONG_BITS == 32) { tcg_out_arithi(s, TCG_REG_T1, addr, 0, SHIFT_SRL); addr = TCG_REG_T1; } @@ -1337,10 +1258,9 @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg data, TCGReg addr, * operation in the delay slot, and failure need only invoke the * handler for SIGBUS. */ - TCGReg arg_low = TCG_REG_O1 + (!SPARC64 && TARGET_LONG_BITS == 64); tcg_out_call_nodelay(s, qemu_unalign_ld_trampoline, false); /* delay slot -- move to low part of argument reg */ - tcg_out_mov_delay(s, arg_low, addr); + tcg_out_mov_delay(s, TCG_REG_O1, addr); } else { /* Underalignment: load by pieces of minimum alignment. */ int ld_opc, a_size, s_size, i; @@ -1400,7 +1320,7 @@ static void tcg_out_qemu_st(TCGContext *s, TCGReg data, TCGReg addr, #ifdef CONFIG_SOFTMMU unsigned memi = get_mmuidx(oi); - TCGReg addrz, param; + TCGReg addrz; const tcg_insn_unit *func; addrz = tcg_out_tlb_load(s, addr, memi, memop, @@ -1418,23 +1338,14 @@ static void tcg_out_qemu_st(TCGContext *s, TCGReg data, TCGReg addr, /* TLB Miss. */ - param = TCG_REG_O1; - if (!SPARC64 && TARGET_LONG_BITS == 64) { - /* Skip the high-part; we'll perform the extract in the trampoline. */ - param++; - } - tcg_out_mov(s, TCG_TYPE_REG, param++, addrz); - if (!SPARC64 && (memop & MO_SIZE) == MO_64) { - /* Skip the high-part; we'll perform the extract in the trampoline. */ - param++; - } - tcg_out_mov(s, TCG_TYPE_REG, param++, data); + tcg_out_mov(s, TCG_TYPE_REG, TCG_REG_O1, addrz); + tcg_out_mov(s, TCG_TYPE_REG, TCG_REG_O2, data); func = qemu_st_trampoline[memop & (MO_BSWAP | MO_SIZE)]; tcg_debug_assert(func != NULL); tcg_out_call_nodelay(s, func, false); /* delay slot */ - tcg_out_movi(s, TCG_TYPE_I32, param, oi); + tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_O3, oi); *label_ptr |= INSN_OFF19(tcg_ptr_byte_diff(s->code_ptr, label_ptr)); #else @@ -1443,7 +1354,7 @@ static void tcg_out_qemu_st(TCGContext *s, TCGReg data, TCGReg addr, unsigned s_bits = memop & MO_SIZE; unsigned t_bits; - if (SPARC64 && TARGET_LONG_BITS == 32) { + if (TARGET_LONG_BITS == 32) { tcg_out_arithi(s, TCG_REG_T1, addr, 0, SHIFT_SRL); addr = TCG_REG_T1; } @@ -1479,10 +1390,9 @@ static void tcg_out_qemu_st(TCGContext *s, TCGReg data, TCGReg addr, * operation in the delay slot, and failure need only invoke the * handler for SIGBUS. */ - TCGReg arg_low = TCG_REG_O1 + (!SPARC64 && TARGET_LONG_BITS == 64); tcg_out_call_nodelay(s, qemu_unalign_st_trampoline, false); /* delay slot -- move to low part of argument reg */ - tcg_out_mov_delay(s, arg_low, addr); + tcg_out_mov_delay(s, TCG_REG_O1, addr); } else { /* Underalignment: store by pieces of minimum alignment. */ int st_opc, a_size, s_size, i; @@ -1719,14 +1629,9 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_muls2_i32: c = ARITH_SMUL; do_mul2: - /* The 32-bit multiply insns produce a full 64-bit result. If the - destination register can hold it, we can avoid the slower RDY. */ + /* The 32-bit multiply insns produce a full 64-bit result. */ tcg_out_arithc(s, a0, a2, args[3], const_args[3], c); - if (SPARC64 || a0 <= TCG_REG_O7) { - tcg_out_arithi(s, a1, a0, 32, SHIFT_SRLX); - } else { - tcg_out_rdy(s, a1); - } + tcg_out_arithi(s, a1, a0, 32, SHIFT_SRLX); break; case INDEX_op_qemu_ld_i32: @@ -1984,16 +1889,11 @@ static void tcg_target_init(TCGContext *s) tcg_regset_set_reg(s->reserved_regs, TCG_REG_T2); /* for internal use */ } -#if SPARC64 -# define ELF_HOST_MACHINE EM_SPARCV9 -#else -# define ELF_HOST_MACHINE EM_SPARC32PLUS -# define ELF_HOST_FLAGS EF_SPARC_32PLUS -#endif +#define ELF_HOST_MACHINE EM_SPARCV9 typedef struct { DebugFrameHeader h; - uint8_t fde_def_cfa[SPARC64 ? 4 : 2]; + uint8_t fde_def_cfa[4]; uint8_t fde_win_save; uint8_t fde_ret_save[3]; } DebugFrame; @@ -2010,12 +1910,8 @@ static const DebugFrame debug_frame = { .h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset), .fde_def_cfa = { -#if SPARC64 12, 30, /* DW_CFA_def_cfa i6, 2047 */ (2047 & 0x7f) | 0x80, (2047 >> 7) -#else - 13, 30 /* DW_CFA_def_cfa_register i6 */ -#endif }, .fde_win_save = 0x2d, /* DW_CFA_GNU_window_save */ .fde_ret_save = { 9, 15, 31 }, /* DW_CFA_register o7, i7 */ diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h index c050763049..8655acdbe5 100644 --- a/tcg/sparc/tcg-target.h +++ b/tcg/sparc/tcg-target.h @@ -25,8 +25,6 @@ #ifndef SPARC_TCG_TARGET_H #define SPARC_TCG_TARGET_H -#define TCG_TARGET_REG_BITS 64 - #define TCG_TARGET_INSN_UNIT_SIZE 4 #define TCG_TARGET_TLB_DISPLACEMENT_BITS 32 #define TCG_TARGET_NB_REGS 32 @@ -70,19 +68,10 @@ typedef enum { /* used for function call generation */ #define TCG_REG_CALL_STACK TCG_REG_O6 -#ifdef __arch64__ #define TCG_TARGET_STACK_BIAS 2047 #define TCG_TARGET_STACK_ALIGN 16 #define TCG_TARGET_CALL_STACK_OFFSET (128 + 6*8 + TCG_TARGET_STACK_BIAS) -#else -#define TCG_TARGET_STACK_BIAS 0 -#define TCG_TARGET_STACK_ALIGN 8 -#define TCG_TARGET_CALL_STACK_OFFSET (64 + 4 + 6*4) -#endif - -#ifdef __arch64__ #define TCG_TARGET_EXTEND_ARGS 1 -#endif #if defined(__VIS__) && __VIS__ >= 0x300 #define use_vis3_instructions 1 diff --git a/tcg/tcg.c b/tcg/tcg.c index 612a12f58f..c9e664ee31 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -1487,39 +1487,7 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args) } #endif -#if defined(__sparc__) && !defined(__arch64__) \ - && !defined(CONFIG_TCG_INTERPRETER) - /* We have 64-bit values in one register, but need to pass as two - separate parameters. Split them. */ - int orig_typemask = typemask; - int orig_nargs = nargs; - TCGv_i64 retl, reth; - TCGTemp *split_args[MAX_OPC_PARAM]; - - retl = NULL; - reth = NULL; - typemask = 0; - for (i = real_args = 0; i < nargs; ++i) { - int argtype = extract32(orig_typemask, (i + 1) * 3, 3); - bool is_64bit = (argtype & ~1) == dh_typecode_i64; - - if (is_64bit) { - TCGv_i64 orig = temp_tcgv_i64(args[i]); - TCGv_i32 h = tcg_temp_new_i32(); - TCGv_i32 l = tcg_temp_new_i32(); - tcg_gen_extr_i64_i32(l, h, orig); - split_args[real_args++] = tcgv_i32_temp(h); - typemask |= dh_typecode_i32 << (real_args * 3); - split_args[real_args++] = tcgv_i32_temp(l); - typemask |= dh_typecode_i32 << (real_args * 3); - } else { - split_args[real_args++] = args[i]; - typemask |= argtype << (real_args * 3); - } - } - nargs = real_args; - args = split_args; -#elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64 +#if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64 for (i = 0; i < nargs; ++i) { int argtype = extract32(typemask, (i + 1) * 3, 3); bool is_32bit = (argtype & ~1) == dh_typecode_i32; @@ -1542,22 +1510,6 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args) pi = 0; if (ret != NULL) { -#if defined(__sparc__) && !defined(__arch64__) \ - && !defined(CONFIG_TCG_INTERPRETER) - if ((typemask & 6) == dh_typecode_i64) { - /* The 32-bit ABI is going to return the 64-bit value in - the %o0/%o1 register pair. Prepare for this by using - two return temporaries, and reassemble below. */ - retl = tcg_temp_new_i64(); - reth = tcg_temp_new_i64(); - op->args[pi++] = tcgv_i64_arg(reth); - op->args[pi++] = tcgv_i64_arg(retl); - nb_rets = 2; - } else { - op->args[pi++] = temp_arg(ret); - nb_rets = 1; - } -#else if (TCG_TARGET_REG_BITS < 64 && (typemask & 6) == dh_typecode_i64) { #if HOST_BIG_ENDIAN op->args[pi++] = temp_arg(ret + 1); @@ -1571,7 +1523,6 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args) op->args[pi++] = temp_arg(ret); nb_rets = 1; } -#endif } else { nb_rets = 0; } @@ -1634,29 +1585,7 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args) tcg_debug_assert(TCGOP_CALLI(op) == real_args); tcg_debug_assert(pi <= ARRAY_SIZE(op->args)); -#if defined(__sparc__) && !defined(__arch64__) \ - && !defined(CONFIG_TCG_INTERPRETER) - /* Free all of the parts we allocated above. */ - for (i = real_args = 0; i < orig_nargs; ++i) { - int argtype = extract32(orig_typemask, (i + 1) * 3, 3); - bool is_64bit = (argtype & ~1) == dh_typecode_i64; - - if (is_64bit) { - tcg_temp_free_internal(args[real_args++]); - tcg_temp_free_internal(args[real_args++]); - } else { - real_args++; - } - } - if ((orig_typemask & 6) == dh_typecode_i64) { - /* The 32-bit ABI returned two 32-bit pieces. Re-assemble them. - Note that describing these as TCGv_i64 eliminates an unnecessary - zero-extension that tcg_gen_concat_i32_i64 would create. */ - tcg_gen_concat32_i64(temp_tcgv_i64(ret), retl, reth); - tcg_temp_free_i64(retl); - tcg_temp_free_i64(reth); - } -#elif defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64 +#if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64 for (i = 0; i < nargs; ++i) { int argtype = extract32(typemask, (i + 1) * 3, 3); bool is_32bit = (argtype & ~1) == dh_typecode_i32; From 6d0b52ed889f47fa8e39e9611d7bce15cc533369 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 17 Oct 2022 08:00:57 +0300 Subject: [PATCH 482/705] tcg/sparc64: Rename from tcg/sparc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Emphasize that we only support full 64-bit code generation. Reviewed-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- MAINTAINERS | 2 +- meson.build | 4 +--- tcg/{sparc => sparc64}/tcg-target-con-set.h | 0 tcg/{sparc => sparc64}/tcg-target-con-str.h | 0 tcg/{sparc => sparc64}/tcg-target.c.inc | 0 tcg/{sparc => sparc64}/tcg-target.h | 0 6 files changed, 2 insertions(+), 4 deletions(-) rename tcg/{sparc => sparc64}/tcg-target-con-set.h (100%) rename tcg/{sparc => sparc64}/tcg-target-con-str.h (100%) rename tcg/{sparc => sparc64}/tcg-target.c.inc (100%) rename tcg/{sparc => sparc64}/tcg-target.h (100%) diff --git a/MAINTAINERS b/MAINTAINERS index c41d8d65e2..62bbbba214 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3370,7 +3370,7 @@ L: qemu-s390x@nongnu.org SPARC TCG target S: Odd Fixes -F: tcg/sparc/ +F: tcg/sparc64/ F: disas/sparc.c TCI TCG target diff --git a/meson.build b/meson.build index 1c1afcc9b8..d809d51791 100644 --- a/meson.build +++ b/meson.build @@ -49,7 +49,7 @@ qapi_trace_events = [] bsd_oses = ['gnu/kfreebsd', 'freebsd', 'netbsd', 'openbsd', 'dragonfly', 'darwin'] supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux'] supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv', 'x86', 'x86_64', - 'arm', 'aarch64', 'loongarch64', 'mips', 'mips64', 'sparc', 'sparc64'] + 'arm', 'aarch64', 'loongarch64', 'mips', 'mips64', 'sparc64'] cpu = host_machine.cpu_family() @@ -469,8 +469,6 @@ if get_option('tcg').allowed() endif if get_option('tcg_interpreter') tcg_arch = 'tci' - elif host_arch == 'sparc64' - tcg_arch = 'sparc' elif host_arch == 'x86_64' tcg_arch = 'i386' elif host_arch == 'ppc64' diff --git a/tcg/sparc/tcg-target-con-set.h b/tcg/sparc64/tcg-target-con-set.h similarity index 100% rename from tcg/sparc/tcg-target-con-set.h rename to tcg/sparc64/tcg-target-con-set.h diff --git a/tcg/sparc/tcg-target-con-str.h b/tcg/sparc64/tcg-target-con-str.h similarity index 100% rename from tcg/sparc/tcg-target-con-str.h rename to tcg/sparc64/tcg-target-con-str.h diff --git a/tcg/sparc/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc similarity index 100% rename from tcg/sparc/tcg-target.c.inc rename to tcg/sparc64/tcg-target.c.inc diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc64/tcg-target.h similarity index 100% rename from tcg/sparc/tcg-target.h rename to tcg/sparc64/tcg-target.h From a59a293126604183dd63bf8b890393e32e7702c4 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 17 Oct 2022 08:17:45 +0300 Subject: [PATCH 483/705] tcg/sparc64: Remove sparc32plus constraints With sparc64 we need not distinguish between registers that can hold 32-bit values and those that can hold 64-bit values. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson --- tcg/sparc64/tcg-target-con-set.h | 16 +---- tcg/sparc64/tcg-target-con-str.h | 3 - tcg/sparc64/tcg-target.c.inc | 109 ++++++++++++------------------- 3 files changed, 44 insertions(+), 84 deletions(-) diff --git a/tcg/sparc64/tcg-target-con-set.h b/tcg/sparc64/tcg-target-con-set.h index 3b751dc3fb..31e6fea1fc 100644 --- a/tcg/sparc64/tcg-target-con-set.h +++ b/tcg/sparc64/tcg-target-con-set.h @@ -11,22 +11,12 @@ */ C_O0_I1(r) C_O0_I2(rZ, r) -C_O0_I2(RZ, r) C_O0_I2(rZ, rJ) -C_O0_I2(RZ, RJ) -C_O0_I2(sZ, A) -C_O0_I2(SZ, A) -C_O1_I1(r, A) -C_O1_I1(R, A) +C_O0_I2(sZ, s) +C_O1_I1(r, s) C_O1_I1(r, r) -C_O1_I1(r, R) -C_O1_I1(R, r) -C_O1_I1(R, R) -C_O1_I2(R, R, R) +C_O1_I2(r, r, r) C_O1_I2(r, rZ, rJ) -C_O1_I2(R, RZ, RJ) C_O1_I4(r, rZ, rJ, rI, 0) -C_O1_I4(R, RZ, RJ, RI, 0) C_O2_I2(r, r, rZ, rJ) -C_O2_I4(R, R, RZ, RZ, RJ, RI) C_O2_I4(r, r, rZ, rZ, rJ, rJ) diff --git a/tcg/sparc64/tcg-target-con-str.h b/tcg/sparc64/tcg-target-con-str.h index fdb25d9313..8f5c7aef97 100644 --- a/tcg/sparc64/tcg-target-con-str.h +++ b/tcg/sparc64/tcg-target-con-str.h @@ -9,10 +9,7 @@ * REGS(letter, register_mask) */ REGS('r', ALL_GENERAL_REGS) -REGS('R', ALL_GENERAL_REGS64) REGS('s', ALL_QLDST_REGS) -REGS('S', ALL_QLDST_REGS64) -REGS('A', TARGET_LONG_BITS == 64 ? ALL_QLDST_REGS64 : ALL_QLDST_REGS) /* * Define constraint letters for constants: diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc index 097bcfcd12..cb9453efdd 100644 --- a/tcg/sparc64/tcg-target.c.inc +++ b/tcg/sparc64/tcg-target.c.inc @@ -80,19 +80,8 @@ static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = { #else #define SOFTMMU_RESERVE_REGS 0 #endif - -/* - * Note that sparcv8plus can only hold 64 bit quantities in %g and %o - * registers. These are saved manually by the kernel in full 64-bit - * slots. The %i and %l registers are saved by the register window - * mechanism, which only allocates space for 32 bits. Given that this - * window spill/fill can happen on any signal, we must consider the - * high bits of the %i and %l registers garbage at all times. - */ #define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 32) -# define ALL_GENERAL_REGS64 ALL_GENERAL_REGS #define ALL_QLDST_REGS (ALL_GENERAL_REGS & ~SOFTMMU_RESERVE_REGS) -#define ALL_QLDST_REGS64 (ALL_GENERAL_REGS64 & ~SOFTMMU_RESERVE_REGS) /* Define some temporary registers. T2 is used for constant generation. */ #define TCG_REG_T1 TCG_REG_G1 @@ -1738,107 +1727,91 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op) return C_O0_I1(r); case INDEX_op_ld8u_i32: + case INDEX_op_ld8u_i64: case INDEX_op_ld8s_i32: + case INDEX_op_ld8s_i64: case INDEX_op_ld16u_i32: + case INDEX_op_ld16u_i64: case INDEX_op_ld16s_i32: + case INDEX_op_ld16s_i64: case INDEX_op_ld_i32: + case INDEX_op_ld32u_i64: + case INDEX_op_ld32s_i64: + case INDEX_op_ld_i64: case INDEX_op_neg_i32: + case INDEX_op_neg_i64: case INDEX_op_not_i32: + case INDEX_op_not_i64: + case INDEX_op_ext32s_i64: + case INDEX_op_ext32u_i64: + case INDEX_op_ext_i32_i64: + case INDEX_op_extu_i32_i64: + case INDEX_op_extrl_i64_i32: + case INDEX_op_extrh_i64_i32: return C_O1_I1(r, r); case INDEX_op_st8_i32: + case INDEX_op_st8_i64: case INDEX_op_st16_i32: + case INDEX_op_st16_i64: case INDEX_op_st_i32: + case INDEX_op_st32_i64: + case INDEX_op_st_i64: return C_O0_I2(rZ, r); case INDEX_op_add_i32: + case INDEX_op_add_i64: case INDEX_op_mul_i32: + case INDEX_op_mul_i64: case INDEX_op_div_i32: + case INDEX_op_div_i64: case INDEX_op_divu_i32: + case INDEX_op_divu_i64: case INDEX_op_sub_i32: + case INDEX_op_sub_i64: case INDEX_op_and_i32: + case INDEX_op_and_i64: case INDEX_op_andc_i32: + case INDEX_op_andc_i64: case INDEX_op_or_i32: + case INDEX_op_or_i64: case INDEX_op_orc_i32: + case INDEX_op_orc_i64: case INDEX_op_xor_i32: + case INDEX_op_xor_i64: case INDEX_op_shl_i32: + case INDEX_op_shl_i64: case INDEX_op_shr_i32: + case INDEX_op_shr_i64: case INDEX_op_sar_i32: + case INDEX_op_sar_i64: case INDEX_op_setcond_i32: + case INDEX_op_setcond_i64: return C_O1_I2(r, rZ, rJ); case INDEX_op_brcond_i32: + case INDEX_op_brcond_i64: return C_O0_I2(rZ, rJ); case INDEX_op_movcond_i32: + case INDEX_op_movcond_i64: return C_O1_I4(r, rZ, rJ, rI, 0); case INDEX_op_add2_i32: + case INDEX_op_add2_i64: case INDEX_op_sub2_i32: + case INDEX_op_sub2_i64: return C_O2_I4(r, r, rZ, rZ, rJ, rJ); case INDEX_op_mulu2_i32: case INDEX_op_muls2_i32: return C_O2_I2(r, r, rZ, rJ); - - case INDEX_op_ld8u_i64: - case INDEX_op_ld8s_i64: - case INDEX_op_ld16u_i64: - case INDEX_op_ld16s_i64: - case INDEX_op_ld32u_i64: - case INDEX_op_ld32s_i64: - case INDEX_op_ld_i64: - case INDEX_op_ext_i32_i64: - case INDEX_op_extu_i32_i64: - return C_O1_I1(R, r); - - case INDEX_op_st8_i64: - case INDEX_op_st16_i64: - case INDEX_op_st32_i64: - case INDEX_op_st_i64: - return C_O0_I2(RZ, r); - - case INDEX_op_add_i64: - case INDEX_op_mul_i64: - case INDEX_op_div_i64: - case INDEX_op_divu_i64: - case INDEX_op_sub_i64: - case INDEX_op_and_i64: - case INDEX_op_andc_i64: - case INDEX_op_or_i64: - case INDEX_op_orc_i64: - case INDEX_op_xor_i64: - case INDEX_op_shl_i64: - case INDEX_op_shr_i64: - case INDEX_op_sar_i64: - case INDEX_op_setcond_i64: - return C_O1_I2(R, RZ, RJ); - - case INDEX_op_neg_i64: - case INDEX_op_not_i64: - case INDEX_op_ext32s_i64: - case INDEX_op_ext32u_i64: - return C_O1_I1(R, R); - - case INDEX_op_extrl_i64_i32: - case INDEX_op_extrh_i64_i32: - return C_O1_I1(r, R); - - case INDEX_op_brcond_i64: - return C_O0_I2(RZ, RJ); - case INDEX_op_movcond_i64: - return C_O1_I4(R, RZ, RJ, RI, 0); - case INDEX_op_add2_i64: - case INDEX_op_sub2_i64: - return C_O2_I4(R, R, RZ, RZ, RJ, RI); case INDEX_op_muluh_i64: - return C_O1_I2(R, R, R); + return C_O1_I2(r, r, r); case INDEX_op_qemu_ld_i32: - return C_O1_I1(r, A); case INDEX_op_qemu_ld_i64: - return C_O1_I1(R, A); + return C_O1_I1(r, s); case INDEX_op_qemu_st_i32: - return C_O0_I2(sZ, A); case INDEX_op_qemu_st_i64: - return C_O0_I2(SZ, A); + return C_O0_I2(sZ, s); default: g_assert_not_reached(); @@ -1859,7 +1832,7 @@ static void tcg_target_init(TCGContext *s) #endif tcg_target_available_regs[TCG_TYPE_I32] = ALL_GENERAL_REGS; - tcg_target_available_regs[TCG_TYPE_I64] = ALL_GENERAL_REGS64; + tcg_target_available_regs[TCG_TYPE_I64] = ALL_GENERAL_REGS; tcg_target_call_clobber_regs = 0; tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_G1); From 9dd1d56e570e5119fef2b28fda811d6891e597a8 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Sat, 29 Oct 2022 06:23:44 +1100 Subject: [PATCH 484/705] tcg/tci: fix logic error when registering helpers via FFI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When registering helpers via FFI for TCI, the inner loop that iterates parameters of the helper reuses (and thus pollutes) the same variable used by the outer loop that iterates all helpers, thus made some helpers unregistered. Fix this logic error by using a dedicated temporary variable for the inner loop. Fixes: 22f15579fa ("tcg: Build ffi data structures for helpers") Reviewed-by: Alex Bennée Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Icenowy Zheng Message-Id: <20221028072145.1593205-1-uwu@icenowy.me> [rth: Move declaration of j to the for loop itself] Signed-off-by: Richard Henderson --- tcg/tcg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tcg/tcg.c b/tcg/tcg.c index c9e664ee31..b6c46b7e25 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -634,9 +634,9 @@ static void tcg_context_init(unsigned max_cpus) if (nargs != 0) { ca->cif.arg_types = ca->args; - for (i = 0; i < nargs; ++i) { - int typecode = extract32(typemask, (i + 1) * 3, 3); - ca->args[i] = typecode_to_ffi[typecode]; + for (int j = 0; j < nargs; ++j) { + int typecode = extract32(typemask, (j + 1) * 3, 3); + ca->args[j] = typecode_to_ffi[typecode]; } } From 6392bd6b90a488b3254b1cb85d79bf262ed5f9e0 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 22:15:04 +1000 Subject: [PATCH 485/705] accel/tcg: Introduce cpu_unwind_state_data Add a way to examine the unwind data without actually restoring the data back into env. Reviewed-by: Claudio Fontana Signed-off-by: Richard Henderson --- accel/tcg/internal.h | 4 +-- accel/tcg/translate-all.c | 74 ++++++++++++++++++++++++++------------- include/exec/exec-all.h | 21 ++++++++--- 3 files changed, 68 insertions(+), 31 deletions(-) diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h index 1227bb69bd..9c06b320b7 100644 --- a/accel/tcg/internal.h +++ b/accel/tcg/internal.h @@ -106,8 +106,8 @@ void tb_reset_jump(TranslationBlock *tb, int n); TranslationBlock *tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc, tb_page_addr_t phys_page2); bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc); -int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, - uintptr_t searched_pc, bool reset_icount); +void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, + uintptr_t host_pc, bool reset_icount); /* Return the current PC from CPU, which may be cached in TB. */ static inline target_ulong log_pc(CPUState *cpu, const TranslationBlock *tb) diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index f185356a36..319becb698 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -247,52 +247,66 @@ static int encode_search(TranslationBlock *tb, uint8_t *block) return p - block; } -/* The cpu state corresponding to 'searched_pc' is restored. - * When reset_icount is true, current TB will be interrupted and - * icount should be recalculated. - */ -int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, - uintptr_t searched_pc, bool reset_icount) +static int cpu_unwind_data_from_tb(TranslationBlock *tb, uintptr_t host_pc, + uint64_t *data) { - uint64_t data[TARGET_INSN_START_WORDS]; - uintptr_t host_pc = (uintptr_t)tb->tc.ptr; + uintptr_t iter_pc = (uintptr_t)tb->tc.ptr; const uint8_t *p = tb->tc.ptr + tb->tc.size; int i, j, num_insns = tb->icount; -#ifdef CONFIG_PROFILER - TCGProfile *prof = &tcg_ctx->prof; - int64_t ti = profile_getclock(); -#endif - searched_pc -= GETPC_ADJ; + host_pc -= GETPC_ADJ; - if (searched_pc < host_pc) { + if (host_pc < iter_pc) { return -1; } - memset(data, 0, sizeof(data)); + memset(data, 0, sizeof(uint64_t) * TARGET_INSN_START_WORDS); if (!TARGET_TB_PCREL) { data[0] = tb_pc(tb); } - /* Reconstruct the stored insn data while looking for the point at - which the end of the insn exceeds the searched_pc. */ + /* + * Reconstruct the stored insn data while looking for the point + * at which the end of the insn exceeds host_pc. + */ for (i = 0; i < num_insns; ++i) { for (j = 0; j < TARGET_INSN_START_WORDS; ++j) { data[j] += decode_sleb128(&p); } - host_pc += decode_sleb128(&p); - if (host_pc > searched_pc) { - goto found; + iter_pc += decode_sleb128(&p); + if (iter_pc > host_pc) { + return num_insns - i; } } return -1; +} + +/* + * The cpu state corresponding to 'host_pc' is restored. + * When reset_icount is true, current TB will be interrupted and + * icount should be recalculated. + */ +void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, + uintptr_t host_pc, bool reset_icount) +{ + uint64_t data[TARGET_INSN_START_WORDS]; +#ifdef CONFIG_PROFILER + TCGProfile *prof = &tcg_ctx->prof; + int64_t ti = profile_getclock(); +#endif + int insns_left = cpu_unwind_data_from_tb(tb, host_pc, data); + + if (insns_left < 0) { + return; + } - found: if (reset_icount && (tb_cflags(tb) & CF_USE_ICOUNT)) { assert(icount_enabled()); - /* Reset the cycle counter to the start of the block - and shift if to the number of actually executed instructions */ - cpu_neg(cpu)->icount_decr.u16.low += num_insns - i; + /* + * Reset the cycle counter to the start of the block and + * shift if to the number of actually executed instructions. + */ + cpu_neg(cpu)->icount_decr.u16.low += insns_left; } cpu->cc->tcg_ops->restore_state_to_opc(cpu, tb, data); @@ -302,7 +316,6 @@ int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, prof->restore_time + profile_getclock() - ti); qatomic_set(&prof->restore_count, prof->restore_count + 1); #endif - return 0; } bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit) @@ -335,6 +348,17 @@ bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit) return false; } +bool cpu_unwind_state_data(CPUState *cpu, uintptr_t host_pc, uint64_t *data) +{ + if (in_code_gen_buffer((const void *)(host_pc - tcg_splitwx_diff))) { + TranslationBlock *tb = tcg_tb_lookup(host_pc); + if (tb) { + return cpu_unwind_data_from_tb(tb, host_pc, data) >= 0; + } + } + return false; +} + void page_init(void) { page_size_init(); diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index e948992a80..7d851f5907 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -39,20 +39,33 @@ typedef ram_addr_t tb_page_addr_t; #define TB_PAGE_ADDR_FMT RAM_ADDR_FMT #endif +/** + * cpu_unwind_state_data: + * @cpu: the cpu context + * @host_pc: the host pc within the translation + * @data: output data + * + * Attempt to load the the unwind state for a host pc occurring in + * translated code. If @host_pc is not in translated code, the + * function returns false; otherwise @data is loaded. + * This is the same unwind info as given to restore_state_to_opc. + */ +bool cpu_unwind_state_data(CPUState *cpu, uintptr_t host_pc, uint64_t *data); + /** * cpu_restore_state: - * @cpu: the vCPU state is to be restore to - * @searched_pc: the host PC the fault occurred at + * @cpu: the cpu context + * @host_pc: the host pc within the translation * @will_exit: true if the TB executed will be interrupted after some cpu adjustments. Required for maintaining the correct icount valus * @return: true if state was restored, false otherwise * * Attempt to restore the state for a fault occurring in translated - * code. If the searched_pc is not in translated code no state is + * code. If @host_pc is not in translated code no state is * restored and the function returns false. */ -bool cpu_restore_state(CPUState *cpu, uintptr_t searched_pc, bool will_exit); +bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit); G_NORETURN void cpu_loop_exit_noexc(CPUState *cpu); G_NORETURN void cpu_loop_exit(CPUState *cpu); From 6532426aa056673b1a20e4c1efa3fc26f0567077 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Fri, 28 Oct 2022 11:56:57 +0200 Subject: [PATCH 486/705] tests/lcitool: Rename non-Debian specific helper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This helper is not Debian specific, rename it to cross_build(). Signed-off-by: Alex Bennée Acked-by: Richard Henderson Message-Id: <20220929114231.583801-10-alex.bennee@linaro.org> Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé Message-Id: <20221028095659.48734-2-philmd@linaro.org> --- tests/lcitool/refresh | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/tests/lcitool/refresh b/tests/lcitool/refresh index e45c99adbe..a6a7c23c1d 100755 --- a/tests/lcitool/refresh +++ b/tests/lcitool/refresh @@ -93,7 +93,7 @@ debian11_extras = [ ] -def debian_cross_build(prefix, targets): +def cross_build(prefix, targets): conf = "ENV QEMU_CONFIGURE_OPTS --cross-prefix=%s\n" % (prefix) targets = "ENV DEF_TARGET_LIST %s\n" % (targets) return "".join([conf, targets]) @@ -121,45 +121,45 @@ try: # generate_dockerfile("debian-amd64-cross", "debian-11", cross="x86_64", - trailer=debian_cross_build("x86_64-linux-gnu-", - "x86_64-softmmu," - "x86_64-linux-user," - "i386-softmmu,i386-linux-user")) + trailer=cross_build("x86_64-linux-gnu-", + "x86_64-softmmu," + "x86_64-linux-user," + "i386-softmmu,i386-linux-user")) generate_dockerfile("debian-arm64-cross", "debian-11", cross="aarch64", - trailer=debian_cross_build("aarch64-linux-gnu-", - "aarch64-softmmu,aarch64-linux-user")) + trailer=cross_build("aarch64-linux-gnu-", + "aarch64-softmmu,aarch64-linux-user")) generate_dockerfile("debian-armel-cross", "debian-11", cross="armv6l", - trailer=debian_cross_build("arm-linux-gnueabi-", - "arm-softmmu,arm-linux-user,armeb-linux-user")) + trailer=cross_build("arm-linux-gnueabi-", + "arm-softmmu,arm-linux-user,armeb-linux-user")) generate_dockerfile("debian-armhf-cross", "debian-11", cross="armv7l", - trailer=debian_cross_build("arm-linux-gnueabihf-", - "arm-softmmu,arm-linux-user")) + trailer=cross_build("arm-linux-gnueabihf-", + "arm-softmmu,arm-linux-user")) generate_dockerfile("debian-mips64el-cross", "debian-11", cross="mips64el", - trailer=debian_cross_build("mips64el-linux-gnuabi64-", - "mips64el-softmmu,mips64el-linux-user")) + trailer=cross_build("mips64el-linux-gnuabi64-", + "mips64el-softmmu,mips64el-linux-user")) generate_dockerfile("debian-mipsel-cross", "debian-11", cross="mipsel", - trailer=debian_cross_build("mipsel-linux-gnu-", - "mipsel-softmmu,mipsel-linux-user")) + trailer=cross_build("mipsel-linux-gnu-", + "mipsel-softmmu,mipsel-linux-user")) generate_dockerfile("debian-ppc64el-cross", "debian-11", cross="ppc64le", - trailer=debian_cross_build("powerpc64le-linux-gnu-", - "ppc64-softmmu,ppc64-linux-user")) + trailer=cross_build("powerpc64le-linux-gnu-", + "ppc64-softmmu,ppc64-linux-user")) generate_dockerfile("debian-s390x-cross", "debian-11", cross="s390x", - trailer=debian_cross_build("s390x-linux-gnu-", - "s390x-softmmu,s390x-linux-user")) + trailer=cross_build("s390x-linux-gnu-", + "s390x-softmmu,s390x-linux-user")) # # Cirrus packages lists for GitLab From 9e243b7669054574e5cfbc2a7282dbb62827627b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Fri, 28 Oct 2022 11:56:59 +0200 Subject: [PATCH 487/705] tests/docker: update fedora-win[32|64]-cross with lcitool MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert another two dockerfiles to lcitool and update. Signed-off-by: Alex Bennée Acked-by: Richard Henderson Message-Id: <20220929114231.583801-10-alex.bennee@linaro.org> Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé Message-Id: <20221028095659.48734-4-philmd@linaro.org> --- .../dockerfiles/fedora-win32-cross.docker | 139 ++++++++++++------ .../dockerfiles/fedora-win64-cross.docker | 138 ++++++++++++----- tests/lcitool/refresh | 10 ++ 3 files changed, 207 insertions(+), 80 deletions(-) diff --git a/tests/docker/dockerfiles/fedora-win32-cross.docker b/tests/docker/dockerfiles/fedora-win32-cross.docker index aca37aabc4..75383ba185 100644 --- a/tests/docker/dockerfiles/fedora-win32-cross.docker +++ b/tests/docker/dockerfiles/fedora-win32-cross.docker @@ -1,46 +1,103 @@ +# THIS FILE WAS AUTO-GENERATED +# +# $ lcitool dockerfile --layers all --cross mingw32 fedora-35 qemu +# +# https://gitlab.com/libvirt/libvirt-ci + FROM registry.fedoraproject.org/fedora:35 -# Please keep this list sorted alphabetically -ENV PACKAGES \ - bc \ - bison \ - bzip2 \ - ccache \ - diffutils \ - findutils \ - flex \ - gcc \ - gettext \ - git \ - glib2-devel \ - hostname \ - make \ - meson \ - mingw32-bzip2 \ - mingw32-curl \ - mingw32-glib2 \ - mingw32-gmp \ - mingw32-gnutls \ - mingw32-gtk3 \ - mingw32-libffi \ - mingw32-libjpeg-turbo \ - mingw32-libpng \ - mingw32-libtasn1 \ - mingw32-libusbx \ - mingw32-nettle \ - mingw32-nsis \ - mingw32-pixman \ - mingw32-pkg-config \ - mingw32-SDL2 \ - msitools \ - perl \ - python3 \ - python3-PyYAML \ - tar \ - which +RUN dnf install -y nosync && \ + echo -e '#!/bin/sh\n\ +if test -d /usr/lib64\n\ +then\n\ + export LD_PRELOAD=/usr/lib64/nosync/nosync.so\n\ +else\n\ + export LD_PRELOAD=/usr/lib/nosync/nosync.so\n\ +fi\n\ +exec "$@"' > /usr/bin/nosync && \ + chmod +x /usr/bin/nosync && \ + nosync dnf update -y && \ + nosync dnf install -y \ + bash \ + bc \ + bison \ + bzip2 \ + ca-certificates \ + ccache \ + ctags \ + dbus-daemon \ + diffutils \ + findutils \ + flex \ + gcovr \ + genisoimage \ + git \ + glib2-devel \ + glibc-langpack-en \ + hostname \ + llvm \ + make \ + meson \ + ninja-build \ + nmap-ncat \ + openssh-clients \ + pcre-static \ + perl-base \ + python3 \ + python3-PyYAML \ + python3-numpy \ + python3-opencv \ + python3-pillow \ + python3-pip \ + python3-sphinx \ + python3-sphinx_rtd_theme \ + rpm \ + sed \ + sparse \ + spice-protocol \ + tar \ + tesseract \ + tesseract-langpack-eng \ + texinfo \ + util-linux \ + which && \ + nosync dnf autoremove -y && \ + nosync dnf clean all -y -RUN dnf install -y $PACKAGES -RUN rpm -q $PACKAGES | sort > /packages.txt +ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" +ENV LANG "en_US.UTF-8" +ENV MAKE "/usr/bin/make" +ENV NINJA "/usr/bin/ninja" +ENV PYTHON "/usr/bin/python3" -# Specify the cross prefix for this image (see tests/docker/common.rc) +RUN nosync dnf install -y \ + mingw32-SDL2 \ + mingw32-SDL2_image \ + mingw32-bzip2 \ + mingw32-curl \ + mingw32-gcc \ + mingw32-gcc-c++ \ + mingw32-gettext \ + mingw32-glib2 \ + mingw32-gnutls \ + mingw32-gtk3 \ + mingw32-libgcrypt \ + mingw32-libjpeg-turbo \ + mingw32-libpng \ + mingw32-libtasn1 \ + mingw32-nettle \ + mingw32-nsis \ + mingw32-pixman \ + mingw32-pkg-config && \ + nosync dnf clean all -y && \ + rpm -qa | sort > /packages.txt && \ + mkdir -p /usr/libexec/ccache-wrappers && \ + ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/i686-w64-mingw32-c++ && \ + ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/i686-w64-mingw32-cc && \ + ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/i686-w64-mingw32-g++ && \ + ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/i686-w64-mingw32-gcc + +ENV ABI "i686-w64-mingw32" +ENV MESON_OPTS "--cross-file=/usr/share/mingw/toolchain-mingw32.meson" ENV QEMU_CONFIGURE_OPTS --cross-prefix=i686-w64-mingw32- +ENV DEF_TARGET_LIST i386-softmmu diff --git a/tests/docker/dockerfiles/fedora-win64-cross.docker b/tests/docker/dockerfiles/fedora-win64-cross.docker index 3642766479..98c03dc13b 100644 --- a/tests/docker/dockerfiles/fedora-win64-cross.docker +++ b/tests/docker/dockerfiles/fedora-win64-cross.docker @@ -1,43 +1,103 @@ +# THIS FILE WAS AUTO-GENERATED +# +# $ lcitool dockerfile --layers all --cross mingw64 fedora-35 qemu +# +# https://gitlab.com/libvirt/libvirt-ci + FROM registry.fedoraproject.org/fedora:35 -# Please keep this list sorted alphabetically -ENV PACKAGES \ - bc \ - bison \ - bzip2 \ - ccache \ - diffutils \ - findutils \ - flex \ - gcc \ - gettext \ - git \ - glib2-devel \ - hostname \ - make \ - meson \ - mingw32-nsis \ - mingw64-bzip2 \ - mingw64-curl \ - mingw64-glib2 \ - mingw64-gmp \ - mingw64-gtk3 \ - mingw64-libffi \ - mingw64-libjpeg-turbo \ - mingw64-libpng \ - mingw64-libtasn1 \ - mingw64-libusbx \ - mingw64-pixman \ - mingw64-pkg-config \ - msitools \ - perl \ - python3 \ - python3-PyYAML \ - tar \ - which +RUN dnf install -y nosync && \ + echo -e '#!/bin/sh\n\ +if test -d /usr/lib64\n\ +then\n\ + export LD_PRELOAD=/usr/lib64/nosync/nosync.so\n\ +else\n\ + export LD_PRELOAD=/usr/lib/nosync/nosync.so\n\ +fi\n\ +exec "$@"' > /usr/bin/nosync && \ + chmod +x /usr/bin/nosync && \ + nosync dnf update -y && \ + nosync dnf install -y \ + bash \ + bc \ + bison \ + bzip2 \ + ca-certificates \ + ccache \ + ctags \ + dbus-daemon \ + diffutils \ + findutils \ + flex \ + gcovr \ + genisoimage \ + git \ + glib2-devel \ + glibc-langpack-en \ + hostname \ + llvm \ + make \ + meson \ + ninja-build \ + nmap-ncat \ + openssh-clients \ + pcre-static \ + perl-base \ + python3 \ + python3-PyYAML \ + python3-numpy \ + python3-opencv \ + python3-pillow \ + python3-pip \ + python3-sphinx \ + python3-sphinx_rtd_theme \ + rpm \ + sed \ + sparse \ + spice-protocol \ + tar \ + tesseract \ + tesseract-langpack-eng \ + texinfo \ + util-linux \ + which && \ + nosync dnf autoremove -y && \ + nosync dnf clean all -y -RUN dnf install -y $PACKAGES -RUN rpm -q $PACKAGES | sort > /packages.txt +ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" +ENV LANG "en_US.UTF-8" +ENV MAKE "/usr/bin/make" +ENV NINJA "/usr/bin/ninja" +ENV PYTHON "/usr/bin/python3" -# Specify the cross prefix for this image (see tests/docker/common.rc) -ENV QEMU_CONFIGURE_OPTS --cross-prefix=x86_64-w64-mingw32- --disable-capstone +RUN nosync dnf install -y \ + mingw32-nsis \ + mingw64-SDL2 \ + mingw64-SDL2_image \ + mingw64-bzip2 \ + mingw64-curl \ + mingw64-gcc \ + mingw64-gcc-c++ \ + mingw64-gettext \ + mingw64-glib2 \ + mingw64-gnutls \ + mingw64-gtk3 \ + mingw64-libgcrypt \ + mingw64-libjpeg-turbo \ + mingw64-libpng \ + mingw64-libtasn1 \ + mingw64-nettle \ + mingw64-pixman \ + mingw64-pkg-config && \ + nosync dnf clean all -y && \ + rpm -qa | sort > /packages.txt && \ + mkdir -p /usr/libexec/ccache-wrappers && \ + ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/x86_64-w64-mingw32-c++ && \ + ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/x86_64-w64-mingw32-cc && \ + ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/x86_64-w64-mingw32-g++ && \ + ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/x86_64-w64-mingw32-gcc + +ENV ABI "x86_64-w64-mingw32" +ENV MESON_OPTS "--cross-file=/usr/share/mingw/toolchain-mingw64.meson" +ENV QEMU_CONFIGURE_OPTS --cross-prefix=x86_64-w64-mingw32- +ENV DEF_TARGET_LIST x86_64-softmmu diff --git a/tests/lcitool/refresh b/tests/lcitool/refresh index a6a7c23c1d..ce0b24c0b1 100755 --- a/tests/lcitool/refresh +++ b/tests/lcitool/refresh @@ -161,6 +161,16 @@ try: trailer=cross_build("s390x-linux-gnu-", "s390x-softmmu,s390x-linux-user")) + generate_dockerfile("fedora-win32-cross", "fedora-35", + cross="mingw32", + trailer=cross_build("i686-w64-mingw32-", + "i386-softmmu")) + + generate_dockerfile("fedora-win64-cross", "fedora-35", + cross="mingw64", + trailer=cross_build("x86_64-w64-mingw32-", + "x86_64-softmmu")) + # # Cirrus packages lists for GitLab # From 5b1229fa2dfde161ee322faaaeb35a99765c8712 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Fri, 28 Oct 2022 11:56:58 +0200 Subject: [PATCH 488/705] tests/lcitool: Refresh to latest libvirt-ci module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need an updated lcitool for this to deal with the weirdness of a 32bit nsis tool for both 32 and 64 bit builds. Acked-by: Richard Henderson Message-Id: <20220929114231.583801-10-alex.bennee@linaro.org> Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé Message-Id: <20221028095659.48734-3-philmd@linaro.org> [AJB: no longer triggers whitespace changes due to rebase] Signed-off-by: Alex Bennée --- tests/lcitool/libvirt-ci | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/lcitool/libvirt-ci b/tests/lcitool/libvirt-ci index 79691a50a5..d40e203631 160000 --- a/tests/lcitool/libvirt-ci +++ b/tests/lcitool/libvirt-ci @@ -1 +1 @@ -Subproject commit 79691a50a5f99bd7adda236f66c3c09371b01afa +Subproject commit d40e203631eb3eacee17e8cf8fd20aa5152db62a From b1314192524a8a43f3d4fb1cae8c447a2b255308 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Thu, 27 Oct 2022 19:36:08 +0100 Subject: [PATCH 489/705] tests/docker: update test-mingw to run single build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While the test-build test happily run for mingw the test-mingw case runs more of the packaging inline with what our CI does. It however fails if we don't find both compilers and expects to be run on a docker image with both. Remove that distinction and make it work more like the other build test scripts. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Alex Bennée Message-Id: <20221027183637.2772968-3-alex.bennee@linaro.org> --- tests/docker/test-mingw | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/tests/docker/test-mingw b/tests/docker/test-mingw index 0bc6d78872..18366972eb 100755 --- a/tests/docker/test-mingw +++ b/tests/docker/test-mingw @@ -13,14 +13,12 @@ . common.rc -requires_binary x86_64-w64-mingw32-gcc -requires_binary i686-w64-mingw32-gcc +requires_binary x86_64-w64-mingw32-gcc i686-w64-mingw32-gcc cd "$BUILD_DIR" -for prefix in x86_64-w64-mingw32- i686-w64-mingw32-; do - TARGET_LIST=${TARGET_LIST:-$DEF_TARGET_LIST} \ - build_qemu --cross-prefix=$prefix \ +TARGET_LIST=${TARGET_LIST:-$DEF_TARGET_LIST} \ +build_qemu \ --enable-trace-backends=simple \ --enable-gnutls \ --enable-nettle \ @@ -29,8 +27,6 @@ for prefix in x86_64-w64-mingw32- i686-w64-mingw32-; do --enable-bzip2 \ --enable-guest-agent \ --enable-docs - install_qemu - make installer - make clean - -done +install_qemu +make installer +make clean From ed77c37ac8500d750d5858d02dc78b761dc998be Mon Sep 17 00:00:00 2001 From: Anton Johansson Date: Thu, 27 Oct 2022 19:36:09 +0100 Subject: [PATCH 490/705] tests/docker: Add flex/bison to `debian-all-test` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds flex/bison to the debian-all-test-cross container which was missed in the previous CI patch. These dependencies are required by the idef-parser patchset for target/hexagon. Signed-off-by: Anton Johansson Signed-off-by: Alex Bennée Reviewed-by: Thomas Huth Message-Id: <20221011173229.57909-1-anjo@rev.ng> Message-Id: <20221027183637.2772968-4-alex.bennee@linaro.org> --- tests/docker/dockerfiles/debian-all-test-cross.docker | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/docker/dockerfiles/debian-all-test-cross.docker b/tests/docker/dockerfiles/debian-all-test-cross.docker index 2beb077fb4..8dc5e1b5de 100644 --- a/tests/docker/dockerfiles/debian-all-test-cross.docker +++ b/tests/docker/dockerfiles/debian-all-test-cross.docker @@ -20,8 +20,10 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ # Add extra build tools and as many cross compilers as we can for testing RUN DEBIAN_FRONTEND=noninteractive eatmydata \ apt install -y --no-install-recommends \ + bison \ ccache \ clang \ + flex \ git \ ninja-build \ gcc-aarch64-linux-gnu \ From c3b570b5a9a24d25ab522def7c928c6a3be3d842 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Thu, 27 Oct 2022 19:36:10 +0100 Subject: [PATCH 491/705] configure: don't enable cross compilers unless in target_list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This avoids the unfortunate effect of always builds the pc-bios blobs for targets the user isn't interested in. Reviewed-by: Richard Henderson Suggested-by: Paolo Bonzini Signed-off-by: Alex Bennée Message-Id: <20221027183637.2772968-5-alex.bennee@linaro.org> --- configure | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/configure b/configure index 81561be7c1..dd6f58dcde 100755 --- a/configure +++ b/configure @@ -1877,6 +1877,15 @@ probe_target_compiler() { container_cross_ranlib= container_cross_strip= + # We shall skip configuring the target compiler if the user didn't + # bother enabling an appropriate guest. This avoids building + # extraneous firmware images and tests. + if test "${target_list#*$1}" != "$1"; then + break; + else + return 1 + fi + target_arch=${1%%-*} case $target_arch in aarch64) container_hosts="x86_64 aarch64" ;; From 977cccb8451ecf0fd60388aec95dc9c1ab35afc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Thu, 27 Oct 2022 19:36:11 +0100 Subject: [PATCH 492/705] configure: fix the --enable-static --disable-pie case MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous tweak was incomplete as it missed a leg. Fixes: abafb64b6d (configure: explicitly set cflags for --disable-pie) Reviewed-by: Richard Henderson Signed-off-by: Alex Bennée Message-Id: <20221027183637.2772968-6-alex.bennee@linaro.org> --- configure | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/configure b/configure index dd6f58dcde..8c2c4c1a04 100755 --- a/configure +++ b/configure @@ -1327,6 +1327,8 @@ static THREAD int tls_var; int main(void) { return tls_var; } EOF +# Meson currently only handles pie as a boolean for now so if we have +# explicitly disabled PIE we need to extend our cflags because it wont. if test "$static" = "yes"; then if test "$pie" != "no" && compile_prog "-Werror -fPIE -DPIE" "-static-pie"; then CONFIGURE_CFLAGS="-fPIE -DPIE $CONFIGURE_CFLAGS" @@ -1335,13 +1337,12 @@ if test "$static" = "yes"; then error_exit "-static-pie not available due to missing toolchain support" else pie="no" + QEMU_CFLAGS="-fno-pie -no-pie $QEMU_CFLAGS" fi elif test "$pie" = "no"; then if compile_prog "-Werror -fno-pie" "-no-pie"; then CONFIGURE_CFLAGS="-fno-pie $CONFIGURE_CFLAGS" CONFIGURE_LDFLAGS="-no-pie $CONFIGURE_LDFLAGS" - # Meson currently only handles pie as a boolean for now so if we have - # explicitly disabled PIE we need to extend our cflags because it wont. QEMU_CFLAGS="-fno-pie -no-pie $QEMU_CFLAGS" fi elif compile_prog "-Werror -fPIE -DPIE" "-pie"; then From e6025635db6a6fb406a6910fc1b45ea597ea9f9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Thu, 27 Oct 2022 19:36:12 +0100 Subject: [PATCH 493/705] tests/avocado: extend the timeout for x86_64 tcg tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These are timing out on gitlab. Acked-by: Richard Henderson Reviewed-by: Thomas Huth Signed-off-by: Alex Bennée Message-Id: <20221027183637.2772968-7-alex.bennee@linaro.org> --- tests/avocado/boot_linux.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/avocado/boot_linux.py b/tests/avocado/boot_linux.py index b7522ad3a1..571d33882a 100644 --- a/tests/avocado/boot_linux.py +++ b/tests/avocado/boot_linux.py @@ -19,6 +19,7 @@ class BootLinuxX8664(LinuxTest): """ :avocado: tags=arch:x86_64 """ + timeout = 480 def test_pc_i440fx_tcg(self): """ From b4c82b1b4d030b0b3edbab7173b6888aa12e7e0a Mon Sep 17 00:00:00 2001 From: Anton Johansson Date: Thu, 27 Oct 2022 19:36:13 +0100 Subject: [PATCH 494/705] tests/docker: Add flex/bison to `debian-hexagon-cross` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit debian-hexagon-cross contains two images, one to build the toolchain used for building the Hexagon tests themselves, and one image to build QEMU and run the tests. This commit adds flex/bison to the final image that builds QEMU so that it can also build idef-parser. Note: This container is not built by the CI and needs to be rebuilt and updated manually. Signed-off-by: Anton Johansson Reviewed-by: Thomas Huth Message-Id: <20221014223642.147845-1-anjo@rev.ng> Signed-off-by: Alex Bennée Message-Id: <20221027183637.2772968-8-alex.bennee@linaro.org> --- tests/docker/dockerfiles/debian-hexagon-cross.docker | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/docker/dockerfiles/debian-hexagon-cross.docker b/tests/docker/dockerfiles/debian-hexagon-cross.docker index 8d219bb81d..c4238e893f 100644 --- a/tests/docker/dockerfiles/debian-hexagon-cross.docker +++ b/tests/docker/dockerfiles/debian-hexagon-cross.docker @@ -43,7 +43,7 @@ RUN cat /etc/apt/sources.list | sed "s/^deb\ /deb-src /" >> /etc/apt/sources.lis # Install QEMU build deps for use in CI RUN apt update && \ DEBIAN_FRONTEND=noninteractive apt install -yy eatmydata && \ - DEBIAN_FRONTEND=noninteractive eatmydata apt install -yy git ninja-build && \ + DEBIAN_FRONTEND=noninteractive eatmydata apt install -yy bison flex git ninja-build && \ DEBIAN_FRONTEND=noninteractive eatmydata \ apt build-dep -yy --arch-only qemu COPY --from=0 /usr/local /usr/local From 991e9051238e15207ca3fbfc630fd98f0e2b86cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Thu, 27 Oct 2022 19:36:14 +0100 Subject: [PATCH 495/705] tests/tcg: use regular semihosting for nios2-softmmu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The nios2 code now plugs into the common semihosting code so we can use the same redirect invocation as the other boards. There is however a bug raised for the fact the tests don't seem to be completing properly and silently passing anyway: https://gitlab.com/qemu-project/qemu/-/issues/1258 Reviewed-by: Richard Henderson Signed-off-by: Alex Bennée Message-Id: <20221027183637.2772968-9-alex.bennee@linaro.org> --- tests/tcg/nios2/Makefile.softmmu-target | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/tcg/nios2/Makefile.softmmu-target b/tests/tcg/nios2/Makefile.softmmu-target index c3d0594a39..bc7fd55060 100644 --- a/tests/tcg/nios2/Makefile.softmmu-target +++ b/tests/tcg/nios2/Makefile.softmmu-target @@ -25,8 +25,7 @@ LDFLAGS += -Wl,-T$(LINK_SCRIPT) -static -nostdlib $(CRT_OBJS) -lgcc %: %.o $(LINK_SCRIPT) $(CRT_OBJS) $(call quiet-command, $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS), LD, $@) -# FIXME: nios2 semihosting writes to stdout, not a chardev -QEMU_OPTS = -M 10m50-ghrd,vic=on -semihosting >$@.out -kernel +QEMU_OPTS = -M 10m50-ghrd,vic=on -semihosting-config enable=on,target=native,chardev=output -kernel memory: CFLAGS+=-DCHECK_UNALIGNED=0 TESTS += $(MULTIARCH_TESTS) From 25916dd65d7e72f7bb5b9727bb346a9d17993072 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 27 Oct 2022 19:36:15 +0100 Subject: [PATCH 496/705] tests/tcg/nios2: Tweak 10m50-ghrd.ld MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit More closely follow the default linker script for nios2. This magically fixes a problem resolving .got relocs from the toolchain's libgcc.a. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1258 Signed-off-by: Richard Henderson Signed-off-by: Alex Bennée Message-Id: <20221024035341.2971123-1-richard.henderson@linaro.org> Message-Id: <20221027183637.2772968-10-alex.bennee@linaro.org> --- tests/tcg/nios2/10m50-ghrd.ld | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/tests/tcg/nios2/10m50-ghrd.ld b/tests/tcg/nios2/10m50-ghrd.ld index 7db0d59ad7..71cdda450c 100644 --- a/tests/tcg/nios2/10m50-ghrd.ld +++ b/tests/tcg/nios2/10m50-ghrd.ld @@ -44,11 +44,15 @@ SECTIONS .data : ALIGN(4) { *(.shdata) *(.data .data.* .gnu.linkonce.d.*) - . = ALIGN(4); - _gp = ABSOLUTE(. + 0x8000); - *(.got.plt) *(.got) - *(.lit8) - *(.lit4) + } >ram :RAM + + HIDDEN (_gp = ALIGN(16) + 0x7ff0); + PROVIDE_HIDDEN (gp = _gp); + .got : ALIGN(4) { + *(.got.plt) *(.igot.plt) *(.got) *(.igot) + } >ram :RAM + + .sdata : ALIGN(4) { *(.sdata .sdata.* .gnu.linkonce.s.*) } >ram :RAM From 3878d0c7d7de9fe201513b8ee31e38e53361a97d Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 27 Oct 2022 19:36:16 +0100 Subject: [PATCH 497/705] semihosting/arm-compat-semi: Avoid using hardcoded /tmp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use g_get_tmp_dir() to get the directory to use for temporary files. Signed-off-by: Bin Meng Reviewed-by: Alex Bennée Signed-off-by: Alex Bennée Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20221006151927.2079583-2-bmeng.cn@gmail.com> Message-Id: <20221027183637.2772968-11-alex.bennee@linaro.org> --- semihosting/arm-compat-semi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c index bfea9e9337..62d8bae97f 100644 --- a/semihosting/arm-compat-semi.c +++ b/semihosting/arm-compat-semi.c @@ -503,7 +503,8 @@ void do_common_semihosting(CPUState *cs) GET_ARG(0); GET_ARG(1); GET_ARG(2); - len = asprintf(&s, "/tmp/qemu-%x%02x", getpid(), (int)arg1 & 0xff); + len = asprintf(&s, "%s/qemu-%x%02x", g_get_tmp_dir(), + getpid(), (int)arg1 & 0xff); if (len < 0) { common_semi_set_ret(cs, -1); break; From eb6b2edf8e1a5845c81f3c4da905f1f8bbc0dec3 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 27 Oct 2022 19:36:17 +0100 Subject: [PATCH 498/705] tcg: Avoid using hardcoded /tmp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use g_get_tmp_dir() to get the directory to use for temporary files. Signed-off-by: Bin Meng Reviewed-by: Marc-André Lureau Reviewed-by: Alex Bennée Signed-off-by: Alex Bennée Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20221006151927.2079583-3-bmeng.cn@gmail.com> Message-Id: <20221027183637.2772968-12-alex.bennee@linaro.org> --- tcg/tcg.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tcg/tcg.c b/tcg/tcg.c index 612a12f58f..84921b64f7 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -4729,7 +4729,8 @@ static void tcg_register_jit_int(const void *buf_ptr, size_t buf_size, /* Enable this block to be able to debug the ELF image file creation. One can use readelf, objdump, or other inspection utilities. */ { - FILE *f = fopen("/tmp/qemu.jit", "w+b"); + g_autofree char *jit = g_strdup_printf("%s/qemu.jit", g_get_tmp_dir()); + FILE *f = fopen(jit, "w+b"); if (f) { if (fwrite(img, img_size, 1, f) != img_size) { /* Avoid stupid unused return value warning for fwrite. */ From c2632994e93eee2f165113f1c78775b113f99926 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 27 Oct 2022 19:36:19 +0100 Subject: [PATCH 499/705] block/vvfat: Unify the mkdir() call MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is a difference in the mkdir() call for win32 and non-win32 platforms, and currently is handled in the codes with #ifdefs. glib provides a portable g_mkdir() API and we can use it to unify the codes without #ifdefs. Signed-off-by: Bin Meng Reviewed-by: Marc-André Lureau Signed-off-by: Alex Bennée Reviewed-by: Kevin Wolf Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20221006151927.2079583-6-bmeng.cn@gmail.com> Message-Id: <20221027183637.2772968-14-alex.bennee@linaro.org> --- block/vvfat.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/block/vvfat.c b/block/vvfat.c index c5b1442145..723c91216e 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -25,6 +25,7 @@ #include "qemu/osdep.h" #include +#include #include "qapi/error.h" #include "block/block_int.h" #include "block/qdict.h" @@ -2726,13 +2727,9 @@ static int handle_renames_and_mkdirs(BDRVVVFATState* s) mapping_t* mapping; int j, parent_path_len; -#ifdef __MINGW32__ - if (mkdir(commit->path)) + if (g_mkdir(commit->path, 0755)) { return -5; -#else - if (mkdir(commit->path, 0755)) - return -5; -#endif + } mapping = insert_mapping(s, commit->param.mkdir.cluster, commit->param.mkdir.cluster + 1); From 34b55848a15bca120d9b9381881c40b045409ee9 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 27 Oct 2022 19:36:20 +0100 Subject: [PATCH 500/705] hw/usb: dev-mtp: Use g_mkdir() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use g_mkdir() to create a directory on all platforms. Signed-off-by: Bin Meng Acked-by: Gerd Hoffmann Signed-off-by: Alex Bennée Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20221006151927.2079583-8-bmeng.cn@gmail.com> Message-Id: <20221027183637.2772968-15-alex.bennee@linaro.org> --- hw/usb/dev-mtp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c index 5831395cef..1cac1cd435 100644 --- a/hw/usb/dev-mtp.c +++ b/hw/usb/dev-mtp.c @@ -14,7 +14,7 @@ #include "qemu/error-report.h" #include #include - +#include #include @@ -1622,7 +1622,7 @@ static void usb_mtp_write_data(MTPState *s, uint32_t handle) if (s->dataset.filename) { path = g_strdup_printf("%s/%s", parent->path, s->dataset.filename); if (s->dataset.format == FMT_ASSOCIATION) { - ret = mkdir(path, mask); + ret = g_mkdir(path, mask); if (!ret) { usb_mtp_queue_result(s, RES_OK, d->trans, 3, QEMU_STORAGE_ID, From 48fad83ff49bd47368223cf1121351f51cf3565f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Thu, 27 Oct 2022 19:36:21 +0100 Subject: [PATCH 501/705] MAINTAINERS: add entries for the key build bits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes to the build files are a bit special in that they usually go through other maintainer trees. However considering the build system is the root of everything a developer is likely to do we should at least set it out in MAINTAINERS. I'm going to nominate Paolo for meson stuff given the conversion was his passion project. I'm happy to cast an eye over configure stuff considering a lot of the cross compile logic is in there anyway. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Alex Bennée Acked-by: Thomas Huth Cc: Paolo Bonzini Message-Id: <20221027183637.2772968-16-alex.bennee@linaro.org> --- MAINTAINERS | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index c41d8d65e2..663f1b6581 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -547,12 +547,14 @@ F: */*win32* F: include/*/*win32* X: qga/*win32* F: qemu.nsi +F: scripts/nsis.py Darwin (macOS, iOS) M: Philippe Mathieu-Daudé S: Odd Fixes F: .gitlab-ci.d/cirrus/macos-* F: */*.m +F: scripts/entitlement.sh Alpha Machines -------------- @@ -3762,6 +3764,29 @@ F: docs/about/deprecated.rst Build System ------------ +Meson +M: Paolo Bonzini +R: Marc-André Lureau +R: Daniel P. Berrange +R: Thomas Huth +R: Philippe Mathieu-Daudé +S: Maintained +F: meson.build +F: meson_options.txt +F: scripts/meson-buildoptions.* +F: scripts/check_sparse.py +F: scripts/symlink-install-tree.py + +Top Level Makefile and configure +M: Paolo Bonzini +R: Alex Bennée +R: Thomas Huth +S: Maintained +F: Makefile +F: configure +F: scripts/mtest2make.py +F: tests/Makefile.include + GIT submodules M: Daniel P. Berrange S: Odd Fixes From 97cfba13996067a572db168214e3ccbc22f7adaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Thu, 27 Oct 2022 19:36:22 +0100 Subject: [PATCH 502/705] MAINTAINERS: add features_to_c.sh to gdbstub files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Signed-off-by: Alex Bennée Message-Id: <20221027183637.2772968-17-alex.bennee@linaro.org> --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 663f1b6581..8a466fd6f4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2687,6 +2687,7 @@ F: gdbstub/* F: include/exec/gdbstub.h F: gdb-xml/ F: tests/tcg/multiarch/gdbstub/ +F: scripts/feature_to_c.sh Memory API M: Paolo Bonzini From 162f916453fb9e2d1d1c45cd081a8f8c66f29b9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Thu, 27 Oct 2022 19:36:23 +0100 Subject: [PATCH 503/705] MAINTAINERS: fix-up for check-tcg Makefile changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: fc76c56d3f ("tests/tcg: cleanup Makefile inclusions") Reviewed-by: Richard Henderson Signed-off-by: Alex Bennée Message-Id: <20221027183637.2772968-18-alex.bennee@linaro.org> --- MAINTAINERS | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 8a466fd6f4..f59b568e5b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3727,8 +3727,7 @@ Guest Test Compilation Support M: Alex Bennée R: Philippe Mathieu-Daudé S: Maintained -F: tests/tcg/Makefile -F: tests/tcg/Makefile.include +F: tests/tcg/Makefile.target Integration Testing with the Avocado framework W: https://trello.com/b/6Qi1pxVn/avocado-qemu From 5104b73824670316b1ae1736054e4ba8ab77f345 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Thu, 27 Oct 2022 19:36:24 +0100 Subject: [PATCH 504/705] tests/avocado: set -machine none for userfwd and vnc tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These are exercising core QEMU features and don't actually run code. Not specifying a machine will fail when avocado chooses the native arch binary to run. Be explicit. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Alex Bennée Message-Id: <20221027183637.2772968-19-alex.bennee@linaro.org> --- tests/avocado/info_usernet.py | 3 +++ tests/avocado/vnc.py | 1 + 2 files changed, 4 insertions(+) diff --git a/tests/avocado/info_usernet.py b/tests/avocado/info_usernet.py index b862a47dba..fdc4d90c42 100644 --- a/tests/avocado/info_usernet.py +++ b/tests/avocado/info_usernet.py @@ -14,6 +14,9 @@ from qemu.utils import get_info_usernet_hostfwd_port class InfoUsernet(QemuSystemTest): + """ + :avocado: tags=machine:none + """ def test_hostfwd(self): self.require_netdev('user') diff --git a/tests/avocado/vnc.py b/tests/avocado/vnc.py index 187fd3febc..aeeefc70be 100644 --- a/tests/avocado/vnc.py +++ b/tests/avocado/vnc.py @@ -53,6 +53,7 @@ def find_free_ports(count: int) -> List[int]: class Vnc(QemuSystemTest): """ :avocado: tags=vnc,quick + :avocado: tags=machine:none """ def test_no_vnc(self): self.vm.add_args('-nodefaults', '-S') From cc45d25c65cf69b54fda0794ef74f53daaa272c2 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 27 Oct 2022 19:36:25 +0100 Subject: [PATCH 505/705] tests/avocado: raspi2_initrd: Wait for guest shutdown message before stopping MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The avocado test tests/avocado/boot_linux_console.py:BootLinuxConsole.test_arm_raspi2_initrd finishes with exec_command(self, 'halt') # Wait for VM to shut down gracefully self.vm.wait() In theory this should be fine. In practice it runs into two bugs: * when the test calls self.vm.wait() Avocado closes the socket connection to the guest serial console immediately, so the avocado logs don't have the last part of the guest output: https://gitlab.com/qemu-project/qemu/-/issues/1265 * when the socket is closed, a bug in the QEMU socket chardev means that it loses any data that the guest UART has not yet consumed. This means that the guest doesn't always read the full 'halt' command string, so the test intermittently fails with a timeout: https://gitlab.com/qemu-project/qemu/-/issues/1264 Work around both of these by waiting for the guest to print the string that means it has completed the shutdown process. This fixes a very long standing intermittent failure in this test. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/636 Signed-off-by: Peter Maydell Signed-off-by: Alex Bennée Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Thomas Huth Message-Id: <20221020102012.3015662-1-peter.maydell@linaro.org> Message-Id: <20221027183637.2772968-20-alex.bennee@linaro.org> --- tests/avocado/boot_linux_console.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/avocado/boot_linux_console.py b/tests/avocado/boot_linux_console.py index ca9d09b0d7..eed4b49e6e 100644 --- a/tests/avocado/boot_linux_console.py +++ b/tests/avocado/boot_linux_console.py @@ -489,7 +489,7 @@ class BootLinuxConsole(LinuxKernelTest): 'BCM2835') exec_command_and_wait_for_pattern(self, 'cat /proc/iomem', '/soc/cprman@7e101000') - exec_command(self, 'halt') + exec_command_and_wait_for_pattern(self, 'halt', 'reboot: System halted') # Wait for VM to shut down gracefully self.vm.wait() From 500f73b1aa24b10278a6bf496ad3263b24964388 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Thu, 27 Oct 2022 19:36:26 +0100 Subject: [PATCH 506/705] tests/avocado: disable sh4 rd2 tests on Gitlab MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Running repeated invocations on a number of test boxes show a fairly high error rate: $ retry.py -n 100 -c -- ./tests/venv/bin/avocado run tests/avocado/boot_linux_console.py:BootLinuxConsole.test_sh4_r2d retry.py called with ['./tests/venv/bin/avocado', 'run', 'tests/avocado/boot_linux_console.py:BootLinuxConsole.test_sh4_r2d'] Results: Run, Ret, Pass/Fail, Time, Total Pass, Total Run ... Results summary: 0: 94 times (94.00%), avg time 2.254 (0.00 varience/0.04 deviation) 1: 3 times (3.00%), avg time 1.837 (0.02 varience/0.14 deviation) 8: 3 times (3.00%), avg time 91.288 (0.02 varience/0.15 deviation) Examining the logs they fall into various categories of un-handled unaligned access by user space and unexpected FPU usage by the kernel which ultimately lead to the failure to reach the login prompt. This could be bugs in the translator that only get hit occasionally or just a flaky kernel - its hard to tell. To avoid these failures gating CI lets skip on GitLab. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Alex Bennée Cc: Thomas Huth Cc: Yoshinori Sato Cc: Magnus Damm Message-Id: <20221027183637.2772968-21-alex.bennee@linaro.org> --- tests/avocado/boot_linux_console.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/avocado/boot_linux_console.py b/tests/avocado/boot_linux_console.py index eed4b49e6e..4c9d551f47 100644 --- a/tests/avocado/boot_linux_console.py +++ b/tests/avocado/boot_linux_console.py @@ -15,6 +15,7 @@ import shutil from avocado import skip from avocado import skipUnless +from avocado import skipIf from avocado_qemu import QemuSystemTest from avocado_qemu import exec_command from avocado_qemu import exec_command_and_wait_for_pattern @@ -1175,6 +1176,10 @@ class BootLinuxConsole(LinuxKernelTest): self.vm.add_args('-M', 'graphics=off') self.do_test_advcal_2018('15', tar_hash, 'invaders.elf') + # This test has a 6-10% failure rate on various hosts that look + # like issues with a buggy kernel. As a result we don't want it + # gating releases on Gitlab. + @skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab') def test_sh4_r2d(self): """ :avocado: tags=arch:sh4 From bc483a91d5a2182387e82913a7e22c86b6b1c85c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Thu, 27 Oct 2022 19:36:27 +0100 Subject: [PATCH 507/705] tests/tcg: re-enable linux-test for sh4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This test was marked as broken due to bug #704 which was fixed by aee14c77f4 (linux-user: Rewrite do_getdents, do_getdents64). Local testing shows this is solid now so lets re-enable the test. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Alex Bennée Cc: Yoshinori Sato Message-Id: <20221027183637.2772968-22-alex.bennee@linaro.org> --- tests/tcg/sh4/Makefile.target | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/tcg/sh4/Makefile.target b/tests/tcg/sh4/Makefile.target index 35ebe6b4e3..32b019bdf1 100644 --- a/tests/tcg/sh4/Makefile.target +++ b/tests/tcg/sh4/Makefile.target @@ -13,12 +13,6 @@ run-signals: signals run-plugin-signals-with-%: $(call skip-test, $<, "BROKEN") -# This test is currently broken: https://gitlab.com/qemu-project/qemu/-/issues/704 -run-linux-test: linux-test - $(call skip-test, $<, "BROKEN") -run-plugin-linux-test-with-%: - $(call skip-test, $<, "BROKEN") - # This test is currently unreliable: https://gitlab.com/qemu-project/qemu/-/issues/856 run-threadcount: $(call skip-test, $<, "BROKEN") From 839866fcbd4f2ce554f3c16bf68a520ebc2da310 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Thu, 27 Oct 2022 19:36:28 +0100 Subject: [PATCH 508/705] tests/tcg: re-enable threadcount for sh4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This test was marked as broken due to bug #856 which was fixed by ab419fd8a0 (target/sh4: Fix TB_FLAG_UNALIGN). Local testing shows this is solid now so lets re-enable the test. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Alex Bennée Cc: Yoshinori Sato Message-Id: <20221027183637.2772968-23-alex.bennee@linaro.org> --- tests/tcg/sh4/Makefile.target | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/tcg/sh4/Makefile.target b/tests/tcg/sh4/Makefile.target index 32b019bdf1..47c39a44b6 100644 --- a/tests/tcg/sh4/Makefile.target +++ b/tests/tcg/sh4/Makefile.target @@ -12,9 +12,3 @@ run-signals: signals $(call skip-test, $<, "BROKEN") run-plugin-signals-with-%: $(call skip-test, $<, "BROKEN") - -# This test is currently unreliable: https://gitlab.com/qemu-project/qemu/-/issues/856 -run-threadcount: - $(call skip-test, $<, "BROKEN") -run-plugin-threadcount-with-%: - $(call skip-test, $<, "BROKEN") From efe7c4f08d543cd4181c672bedba5575390db2a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Thu, 27 Oct 2022 19:36:29 +0100 Subject: [PATCH 509/705] target/s390x: don't use ld_code2 to probe next pc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This isn't an translator picking up an instruction so we shouldn't use the translator_lduw function which has side effects for plugins. Reviewed-by: David Hildenbrand Reviewed-by: Richard Henderson Acked-by: Ilya Leoshkevich Signed-off-by: Alex Bennée Message-Id: <20221027183637.2772968-24-alex.bennee@linaro.org> --- target/s390x/tcg/translate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c index 5798928473..9df7f9e693 100644 --- a/target/s390x/tcg/translate.c +++ b/target/s390x/tcg/translate.c @@ -6612,7 +6612,7 @@ static void s390x_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) static target_ulong get_next_pc(CPUS390XState *env, DisasContext *s, uint64_t pc) { - uint64_t insn = ld_code2(env, s, pc); + uint64_t insn = cpu_lduw_code(env, pc); return pc + get_ilen((insn >> 8) & 0xff); } From 621aab6c7dffaa37a9d9b89d246894e516eb3c46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Thu, 27 Oct 2022 19:36:30 +0100 Subject: [PATCH 510/705] target/s390x: don't probe next pc for EXecuted insns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have finished the TB anyway so we can shortcut the other tests by checking dc->ex_value first. Reviewed-by: David Hildenbrand Reviewed-by: Richard Henderson Acked-by: Ilya Leoshkevich Signed-off-by: Alex Bennée Message-Id: <20221027183637.2772968-25-alex.bennee@linaro.org> --- target/s390x/tcg/translate.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c index 9df7f9e693..f4122db434 100644 --- a/target/s390x/tcg/translate.c +++ b/target/s390x/tcg/translate.c @@ -6624,9 +6624,9 @@ static void s390x_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) dc->base.is_jmp = translate_one(env, dc); if (dc->base.is_jmp == DISAS_NEXT) { - if (!is_same_page(dcbase, dc->base.pc_next) || - !is_same_page(dcbase, get_next_pc(env, dc, dc->base.pc_next)) || - dc->ex_value) { + if (dc->ex_value || + !is_same_page(dcbase, dc->base.pc_next) || + !is_same_page(dcbase, get_next_pc(env, dc, dc->base.pc_next))) { dc->base.is_jmp = DISAS_TOO_MANY; } } From 9fa97e04ae5677cc383b674f8efbf17950b07622 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Thu, 27 Oct 2022 19:36:31 +0100 Subject: [PATCH 511/705] target/s390x: fake instruction loading when handling 'ex' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The s390x EXecute instruction is a bit weird as we synthesis the executed instruction from what we have stored in memory. This missed the plugin instrumentation. Work around this with a special helper to inform the rest of the translator about the instruction so things stay consistent. Reviewed-by: David Hildenbrand Acked-by: Ilya Leoshkevich Reviewed-by: Richard Henderson Signed-off-by: Alex Bennée Cc: Richard Henderson Message-Id: <20221027183637.2772968-26-alex.bennee@linaro.org> --- include/exec/translator.h | 17 +++++++++++++++++ target/s390x/tcg/translate.c | 6 ++++++ 2 files changed, 23 insertions(+) diff --git a/include/exec/translator.h b/include/exec/translator.h index 3b77f5f4aa..af2ff95cd5 100644 --- a/include/exec/translator.h +++ b/include/exec/translator.h @@ -211,6 +211,23 @@ translator_ldq_swap(CPUArchState *env, DisasContextBase *db, return ret; } +/** + * translator_fake_ldb - fake instruction load + * @insn8: byte of instruction + * @pc: program counter of instruction + * + * This is a special case helper used where the instruction we are + * about to translate comes from somewhere else (e.g. being + * re-synthesised for s390x "ex"). It ensures we update other areas of + * the translator with details of the executed instruction. + */ + +static inline void translator_fake_ldb(uint8_t insn8, abi_ptr pc) +{ + plugin_insn_append(pc, &insn8, sizeof(insn8)); +} + + /* * Return whether addr is on the same page as where disassembly started. * Translators can use this to enforce the rule that only single-insn diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c index f4122db434..03efccdf9f 100644 --- a/target/s390x/tcg/translate.c +++ b/target/s390x/tcg/translate.c @@ -6317,12 +6317,18 @@ static const DisasInsn *extract_insn(CPUS390XState *env, DisasContext *s) if (unlikely(s->ex_value)) { /* Drop the EX data now, so that it's clear on exception paths. */ TCGv_i64 zero = tcg_const_i64(0); + int i; tcg_gen_st_i64(zero, cpu_env, offsetof(CPUS390XState, ex_value)); tcg_temp_free_i64(zero); /* Extract the values saved by EXECUTE. */ insn = s->ex_value & 0xffffffffffff0000ull; ilen = s->ex_value & 0xf; + /* register insn bytes with translator so plugins work */ + for (i = 0; i < ilen; i++) { + uint8_t byte = extract64(insn, 56 - (i * 8), 8); + translator_fake_ldb(byte, pc + i); + } op = insn >> 56; } else { insn = ld_code2(env, s, pc); From d1d94d968d30ce57674b7e3f2752657e1cd2e4b6 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 27 Oct 2022 19:36:32 +0100 Subject: [PATCH 512/705] tests/tcg: include CONFIG_PLUGIN in config-host.mak MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Paolo Bonzini Signed-off-by: Alex Bennée Reviewed-by: Thomas Huth Message-Id: <20221013131304.623740-1-pbonzini@redhat.com> Message-Id: <20221027183637.2772968-27-alex.bennee@linaro.org> --- configure | 3 +++ 1 file changed, 3 insertions(+) diff --git a/configure b/configure index 8c2c4c1a04..4275f5419f 100755 --- a/configure +++ b/configure @@ -2486,6 +2486,9 @@ echo "HOST_CC=$host_cc" >> $config_host_mak if test -n "$gdb_bin"; then echo "HAVE_GDB_BIN=$gdb_bin" >> $config_host_mak fi +if test "$plugins" = "yes" ; then + echo "CONFIG_PLUGIN=y" >> $config_host_mak +fi tcg_tests_targets= for target in $target_list; do From a4cc0b7dd7dc27f6afb5d4e0338d953e36319c65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Thu, 27 Oct 2022 19:36:33 +0100 Subject: [PATCH 513/705] contrib/plugins: enable debug on CONFIG_DEBUG_TCG MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We used to rely on QEMU_CFLAGS to expose the debug flags but now this is synthesised by meson and only available to the main build. Add our own flags if we detect the build has been enabled with CONFIG_DEBUG_TCG (which is the default for --enable-debug anyway). Signed-off-by: Alex Bennée Reviewed-by: Philippe Mathieu-Daudé Cc: Paolo Bonzini Message-Id: <20221027183637.2772968-28-alex.bennee@linaro.org> --- contrib/plugins/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/plugins/Makefile b/contrib/plugins/Makefile index df3499f4f2..23e0396687 100644 --- a/contrib/plugins/Makefile +++ b/contrib/plugins/Makefile @@ -29,6 +29,7 @@ SONAMES := $(addsuffix .so,$(addprefix lib,$(NAMES))) CFLAGS = $(GLIB_CFLAGS) CFLAGS += -fPIC -Wall $(filter -W%, $(QEMU_CFLAGS)) CFLAGS += $(if $(findstring no-psabi,$(QEMU_CFLAGS)),-Wpsabi) +CFLAGS += $(if $(CONFIG_DEBUG_TCG), -ggdb -O0) CFLAGS += -I$(SRC_PATH)/include/qemu all: $(SONAMES) From 14fd492b89b512735ac3abf8f5300db865129378 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Thu, 27 Oct 2022 19:36:34 +0100 Subject: [PATCH 514/705] contrib/plugins: protect execlog's last_exec expansion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We originally naively treated expansion as safe because we expected each new CPU/thread to appear in order. However the -M raspi2 model triggered a case where a new high cpu_index thread started executing just before a smaller one. Clean this up by converting the GArray into the simpler GPtrArray and then holding a lock for the expansion. Signed-off-by: Alex Bennée Cc: Alexandre Iooss Reviewed-by: Richard Henderson Message-Id: <20221027183637.2772968-29-alex.bennee@linaro.org> --- contrib/plugins/execlog.c | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/contrib/plugins/execlog.c b/contrib/plugins/execlog.c index 1b3bb7ebba..e255bd21fd 100644 --- a/contrib/plugins/execlog.c +++ b/contrib/plugins/execlog.c @@ -18,11 +18,30 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION; /* Store last executed instruction on each vCPU as a GString */ -GArray *last_exec; +static GPtrArray *last_exec; +static GMutex expand_array_lock; static GPtrArray *imatches; static GArray *amatches; +/* + * Expand last_exec array. + * + * As we could have multiple threads trying to do this we need to + * serialise the expansion under a lock. Threads accessing already + * created entries can continue without issue even if the ptr array + * gets reallocated during resize. + */ +static void expand_last_exec(int cpu_index) +{ + g_mutex_lock(&expand_array_lock); + while (cpu_index >= last_exec->len) { + GString *s = g_string_new(NULL); + g_ptr_array_add(last_exec, s); + } + g_mutex_unlock(&expand_array_lock); +} + /** * Add memory read or write information to current instruction log */ @@ -33,7 +52,7 @@ static void vcpu_mem(unsigned int cpu_index, qemu_plugin_meminfo_t info, /* Find vCPU in array */ g_assert(cpu_index < last_exec->len); - s = g_array_index(last_exec, GString *, cpu_index); + s = g_ptr_array_index(last_exec, cpu_index); /* Indicate type of memory access */ if (qemu_plugin_mem_is_store(info)) { @@ -61,11 +80,10 @@ static void vcpu_insn_exec(unsigned int cpu_index, void *udata) GString *s; /* Find or create vCPU in array */ - while (cpu_index >= last_exec->len) { - s = g_string_new(NULL); - g_array_append_val(last_exec, s); + if (cpu_index >= last_exec->len) { + expand_last_exec(cpu_index); } - s = g_array_index(last_exec, GString *, cpu_index); + s = g_ptr_array_index(last_exec, cpu_index); /* Print previous instruction in cache */ if (s->len) { @@ -163,7 +181,7 @@ static void plugin_exit(qemu_plugin_id_t id, void *p) guint i; GString *s; for (i = 0; i < last_exec->len; i++) { - s = g_array_index(last_exec, GString *, i); + s = g_ptr_array_index(last_exec, i); if (s->str) { qemu_plugin_outs(s->str); qemu_plugin_outs("\n"); @@ -201,7 +219,11 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id, * Initialize dynamic array to cache vCPU instruction. In user mode * we don't know the size before emulation. */ - last_exec = g_array_new(FALSE, FALSE, sizeof(GString *)); + if (info->system_emulation) { + last_exec = g_ptr_array_sized_new(info->system.max_vcpus); + } else { + last_exec = g_ptr_array_new(); + } for (int i = 0; i < argc; i++) { char *opt = argv[i]; From 68406d10859385c88da73d0106254a7f47e6652e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Thu, 27 Oct 2022 19:36:35 +0100 Subject: [PATCH 515/705] tests/unit: cleanups for test-io-channel-command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This test is hanging under heavy load when the two socats race while trying to create the socket. I've tried various approaches to avoid the race but it seems "creat=0" won't stop socat trying to create a pipe if it executes first. In the end I just use a small sleep which seems to be reliable enough on the load situations I've tried. While I was there I also properly created a tmpdir for the socket to live in which is cleaned up at the end of the test. Signed-off-by: Alex Bennée Reviewed-by: Daniel P. Berrangé Cc: Thomas Huth Cc: Marc-André Lureau Cc: Juan Quintela Message-Id: <20221027183637.2772968-30-alex.bennee@linaro.org> --- tests/unit/test-io-channel-command.c | 45 +++++++++++++++++----------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/tests/unit/test-io-channel-command.c b/tests/unit/test-io-channel-command.c index 7eee939c07..43e29c8cfb 100644 --- a/tests/unit/test-io-channel-command.c +++ b/tests/unit/test-io-channel-command.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include #include "io/channel-command.h" #include "io-channel-helpers.h" #include "qapi/error.h" @@ -26,32 +27,32 @@ #define TEST_FIFO "test-io-channel-command.fifo" -#define SOCAT_SRC "PIPE:" TEST_FIFO ",wronly" -#define SOCAT_DST "PIPE:" TEST_FIFO ",rdonly" - static char *socat = NULL; static void test_io_channel_command_fifo(bool async) { + g_autofree gchar *tmpdir = g_dir_make_tmp("qemu-test-io-channel.XXXXXX", NULL); + g_autofree gchar *fifo = g_strdup_printf("%s/%s", tmpdir, TEST_FIFO); + g_autoptr(GString) srcargs = g_string_new(socat); + g_autoptr(GString) dstargs = g_string_new(socat); + g_auto(GStrv) srcargv; + g_auto(GStrv) dstargv; QIOChannel *src, *dst; QIOChannelTest *test; - const char *srcargv[] = { - socat, "-", SOCAT_SRC, NULL, - }; - const char *dstargv[] = { - socat, SOCAT_DST, "-", NULL, - }; - if (!socat) { - g_test_skip("socat is not found in PATH"); - return; - } + g_string_append_printf(srcargs, " - PIPE:%s,wronly", fifo); + g_string_append_printf(dstargs, " PIPE:%s,rdonly -", fifo); - unlink(TEST_FIFO); - src = QIO_CHANNEL(qio_channel_command_new_spawn(srcargv, + srcargv = g_strsplit(srcargs->str, " ", -1); + dstargv = g_strsplit(dstargs->str, " ", -1); + + src = QIO_CHANNEL(qio_channel_command_new_spawn((const char **) srcargv, O_WRONLY, &error_abort)); - dst = QIO_CHANNEL(qio_channel_command_new_spawn(dstargv, + /* try to avoid a race to create the socket */ + g_usleep(1000); + + dst = QIO_CHANNEL(qio_channel_command_new_spawn((const char **) dstargv, O_RDONLY, &error_abort)); @@ -62,17 +63,27 @@ static void test_io_channel_command_fifo(bool async) object_unref(OBJECT(src)); object_unref(OBJECT(dst)); - unlink(TEST_FIFO); + g_rmdir(tmpdir); } static void test_io_channel_command_fifo_async(void) { + if (!socat) { + g_test_skip("socat is not found in PATH"); + return; + } + test_io_channel_command_fifo(true); } static void test_io_channel_command_fifo_sync(void) { + if (!socat) { + g_test_skip("socat is not found in PATH"); + return; + } + test_io_channel_command_fifo(false); } From 339bf0c071eff5e6ff1d9ddb3ad5cd02e4cd9ca3 Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Thu, 27 Oct 2022 19:36:36 +0100 Subject: [PATCH 516/705] tests/vm: use -o IdentitiesOnly=yes for ssh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When one has a lot of keys in ~/.ssh directory, the ssh command will try all of them before the one specified on the command line, and this may cause the remote ssh server to reject the connection due to too many failed authentication attempts. Fix by adding -o IdentitiesOnly=yes, which makes the ssh client consider only the keys specified on the command line. Signed-off-by: Ilya Leoshkevich Reviewed-by: Thomas Huth Message-Id: <20221027113026.2280863-1-iii@linux.ibm.com> Signed-off-by: Alex Bennée Message-Id: <20221027183637.2772968-31-alex.bennee@linaro.org> --- tests/vm/basevm.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py index 4fd9af10b7..2276364c42 100644 --- a/tests/vm/basevm.py +++ b/tests/vm/basevm.py @@ -233,7 +233,8 @@ class BaseVM(object): "-o", "UserKnownHostsFile=" + os.devnull, "-o", "ConnectTimeout={}".format(self._config["ssh_timeout"]), - "-p", str(self.ssh_port), "-i", self._ssh_tmp_key_file] + "-p", str(self.ssh_port), "-i", self._ssh_tmp_key_file, + "-o", "IdentitiesOnly=yes"] # If not in debug mode, set ssh to quiet mode to # avoid printing the results of commands. if not self.debug: From f484f213c9f4ae1cd30ebdaadc7b539d745d39fb Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 22:45:29 +1000 Subject: [PATCH 517/705] target/i386: Use cpu_unwind_state_data for tpr access Avoid cpu_restore_state, and modifying env->eip out from underneath the translator with TARGET_TB_PCREL. There is some slight duplication from x86_restore_state_to_opc, but it's just a few lines. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1269 Reviewed-by: Claudio Fontana Signed-off-by: Richard Henderson --- target/i386/helper.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/target/i386/helper.c b/target/i386/helper.c index b62a1e48e2..0ac2da066d 100644 --- a/target/i386/helper.c +++ b/target/i386/helper.c @@ -509,6 +509,27 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank, } } +static inline target_ulong get_memio_eip(CPUX86State *env) +{ +#ifdef CONFIG_TCG + uint64_t data[TARGET_INSN_START_WORDS]; + CPUState *cs = env_cpu(env); + + if (!cpu_unwind_state_data(cs, cs->mem_io_pc, data)) { + return env->eip; + } + + /* Per x86_restore_state_to_opc. */ + if (TARGET_TB_PCREL) { + return (env->eip & TARGET_PAGE_MASK) | data[0]; + } else { + return data[0] - env->segs[R_CS].base; + } +#else + qemu_build_not_reached(); +#endif +} + void cpu_report_tpr_access(CPUX86State *env, TPRAccess access) { X86CPU *cpu = env_archcpu(env); @@ -519,9 +540,9 @@ void cpu_report_tpr_access(CPUX86State *env, TPRAccess access) cpu_interrupt(cs, CPU_INTERRUPT_TPR); } else if (tcg_enabled()) { - cpu_restore_state(cs, cs->mem_io_pc, false); + target_ulong eip = get_memio_eip(env); - apic_handle_tpr_access_report(cpu->apic_state, env->eip, access); + apic_handle_tpr_access_report(cpu->apic_state, eip, access); } } #endif /* !CONFIG_USER_ONLY */ From 5813c5c74a755fd0c1b10be38c6fdf5c54c468e4 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 22:54:15 +1000 Subject: [PATCH 518/705] target/openrisc: Always exit after mtspr npc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have called cpu_restore_state asserting will_exit. Do not go back on that promise. This affects icount. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/openrisc/sys_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c index 09b3c97d7c..a3508e421d 100644 --- a/target/openrisc/sys_helper.c +++ b/target/openrisc/sys_helper.c @@ -51,8 +51,8 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb) if (env->pc != rb) { env->pc = rb; env->dflag = 0; - cpu_loop_exit(cs); } + cpu_loop_exit(cs); break; case TO_SPR(0, 17): /* SR */ From cc30dc441b44ad15f4adfb13d9a68cba6fa39a23 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 22:55:26 +1000 Subject: [PATCH 519/705] target/openrisc: Use cpu_unwind_state_data for mfspr Since we do not plan to exit, use cpu_unwind_state_data and extract exactly the data requested. This is a bug fix, in that we no longer clobber dflag. Consider: l.j L2 // branch l.mfspr r1, ppc // delay L1: boom L2: l.lwa r3, (r4) Here, dflag would be set by cpu_restore_state (because that is the current state of the cpu), but but not cleared by tb_stop on exiting the TB (because DisasContext has recorded the current value as zero). The next TB begins at L2 with dflag incorrectly set. If the load has a tlb miss, then the exception will be delivered as per a delay slot: with DSX set in the status register and PC decremented (delay slots restart by re-executing the branch). This will cause the return from interrupt to go to L1, and boom! Signed-off-by: Richard Henderson --- target/openrisc/sys_helper.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c index a3508e421d..dde2fa1623 100644 --- a/target/openrisc/sys_helper.c +++ b/target/openrisc/sys_helper.c @@ -199,6 +199,7 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd, target_ulong spr) { #ifndef CONFIG_USER_ONLY + uint64_t data[TARGET_INSN_START_WORDS]; MachineState *ms = MACHINE(qdev_get_machine()); OpenRISCCPU *cpu = env_archcpu(env); CPUState *cs = env_cpu(env); @@ -232,14 +233,20 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd, return env->evbar; case TO_SPR(0, 16): /* NPC (equals PC) */ - cpu_restore_state(cs, GETPC(), false); + if (cpu_unwind_state_data(cs, GETPC(), data)) { + return data[0]; + } return env->pc; case TO_SPR(0, 17): /* SR */ return cpu_get_sr(env); case TO_SPR(0, 18): /* PPC */ - cpu_restore_state(cs, GETPC(), false); + if (cpu_unwind_state_data(cs, GETPC(), data)) { + if (data[1] & 2) { + return data[0] - 4; + } + } return env->ppc; case TO_SPR(0, 32): /* EPCR */ From 3d419a4dd227f174447e0b3978028a1cd52ccc5e Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 23:09:57 +1000 Subject: [PATCH 520/705] accel/tcg: Remove will_exit argument from cpu_restore_state The value passed is always true, and if the target's synchronize_from_tb hook is non-trivial, not exiting may be erroneous. Reviewed-by: Claudio Fontana Signed-off-by: Richard Henderson --- accel/tcg/cpu-exec-common.c | 2 +- accel/tcg/translate-all.c | 12 ++---------- include/exec/exec-all.h | 5 +---- target/alpha/helper.c | 2 +- target/alpha/mem_helper.c | 2 +- target/arm/op_helper.c | 2 +- target/arm/tlb_helper.c | 8 ++++---- target/cris/helper.c | 2 +- target/i386/tcg/sysemu/svm_helper.c | 2 +- target/m68k/op_helper.c | 4 ++-- target/microblaze/helper.c | 2 +- target/nios2/op_helper.c | 2 +- target/openrisc/sys_helper.c | 4 ++-- target/ppc/excp_helper.c | 2 +- target/s390x/tcg/excp_helper.c | 2 +- target/tricore/op_helper.c | 2 +- target/xtensa/helper.c | 6 +++--- 17 files changed, 25 insertions(+), 36 deletions(-) diff --git a/accel/tcg/cpu-exec-common.c b/accel/tcg/cpu-exec-common.c index be6fe45aa5..c7bc8c6efa 100644 --- a/accel/tcg/cpu-exec-common.c +++ b/accel/tcg/cpu-exec-common.c @@ -71,7 +71,7 @@ void cpu_loop_exit(CPUState *cpu) void cpu_loop_exit_restore(CPUState *cpu, uintptr_t pc) { if (pc) { - cpu_restore_state(cpu, pc, true); + cpu_restore_state(cpu, pc); } cpu_loop_exit(cpu); } diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 319becb698..90997fed47 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -318,16 +318,8 @@ void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, #endif } -bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit) +bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc) { - /* - * The pc update associated with restore without exit will - * break the relative pc adjustments performed by TARGET_TB_PCREL. - */ - if (TARGET_TB_PCREL) { - assert(will_exit); - } - /* * The host_pc has to be in the rx region of the code buffer. * If it is not we will not be able to resolve it here. @@ -341,7 +333,7 @@ bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit) if (in_code_gen_buffer((const void *)(host_pc - tcg_splitwx_diff))) { TranslationBlock *tb = tcg_tb_lookup(host_pc); if (tb) { - cpu_restore_state_from_tb(cpu, tb, host_pc, will_exit); + cpu_restore_state_from_tb(cpu, tb, host_pc, true); return true; } } diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 7d851f5907..9b7bfbf09a 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -56,16 +56,13 @@ bool cpu_unwind_state_data(CPUState *cpu, uintptr_t host_pc, uint64_t *data); * cpu_restore_state: * @cpu: the cpu context * @host_pc: the host pc within the translation - * @will_exit: true if the TB executed will be interrupted after some - cpu adjustments. Required for maintaining the correct - icount valus * @return: true if state was restored, false otherwise * * Attempt to restore the state for a fault occurring in translated * code. If @host_pc is not in translated code no state is * restored and the function returns false. */ -bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit); +bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc); G_NORETURN void cpu_loop_exit_noexc(CPUState *cpu); G_NORETURN void cpu_loop_exit(CPUState *cpu); diff --git a/target/alpha/helper.c b/target/alpha/helper.c index a5a389b5a3..970c869771 100644 --- a/target/alpha/helper.c +++ b/target/alpha/helper.c @@ -532,7 +532,7 @@ G_NORETURN void dynamic_excp(CPUAlphaState *env, uintptr_t retaddr, cs->exception_index = excp; env->error_code = error; if (retaddr) { - cpu_restore_state(cs, retaddr, true); + cpu_restore_state(cs, retaddr); /* Floating-point exceptions (our only users) point to the next PC. */ env->pc += 4; } diff --git a/target/alpha/mem_helper.c b/target/alpha/mem_helper.c index 47283a0612..a39b52c5dd 100644 --- a/target/alpha/mem_helper.c +++ b/target/alpha/mem_helper.c @@ -28,7 +28,7 @@ static void do_unaligned_access(CPUAlphaState *env, vaddr addr, uintptr_t retadd uint64_t pc; uint32_t insn; - cpu_restore_state(env_cpu(env), retaddr, true); + cpu_restore_state(env_cpu(env), retaddr); pc = env->pc; insn = cpu_ldl_code(env, pc); diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c index c5bde1cfcc..70672bcd9f 100644 --- a/target/arm/op_helper.c +++ b/target/arm/op_helper.c @@ -78,7 +78,7 @@ void raise_exception_ra(CPUARMState *env, uint32_t excp, uint32_t syndrome, * we must restore CPU state here before setting the syndrome * the caller passed us, and cannot use cpu_loop_exit_restore(). */ - cpu_restore_state(cs, ra, true); + cpu_restore_state(cs, ra); raise_exception(env, excp, syndrome, target_el); } diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c index 69b0dc69df..0f4f4fc809 100644 --- a/target/arm/tlb_helper.c +++ b/target/arm/tlb_helper.c @@ -156,7 +156,7 @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr, ARMMMUFaultInfo fi = {}; /* now we have a real cpu fault */ - cpu_restore_state(cs, retaddr, true); + cpu_restore_state(cs, retaddr); fi.type = ARMFault_Alignment; arm_deliver_fault(cpu, vaddr, access_type, mmu_idx, &fi); @@ -196,7 +196,7 @@ void arm_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, ARMMMUFaultInfo fi = {}; /* now we have a real cpu fault */ - cpu_restore_state(cs, retaddr, true); + cpu_restore_state(cs, retaddr); fi.ea = arm_extabort_type(response); fi.type = ARMFault_SyncExternal; @@ -252,7 +252,7 @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size, return false; } else { /* now we have a real cpu fault */ - cpu_restore_state(cs, retaddr, true); + cpu_restore_state(cs, retaddr); arm_deliver_fault(cpu, address, access_type, mmu_idx, fi); } } @@ -271,7 +271,7 @@ void arm_cpu_record_sigsegv(CPUState *cs, vaddr addr, * We report both ESR and FAR to signal handlers. * For now, it's easiest to deliver the fault normally. */ - cpu_restore_state(cs, ra, true); + cpu_restore_state(cs, ra); arm_deliver_fault(cpu, addr, access_type, MMU_USER_IDX, &fi); } diff --git a/target/cris/helper.c b/target/cris/helper.c index 91e4aeb178..81a72699b5 100644 --- a/target/cris/helper.c +++ b/target/cris/helper.c @@ -87,7 +87,7 @@ bool cris_cpu_tlb_fill(CPUState *cs, vaddr address, int size, cs->exception_index = EXCP_BUSFAULT; env->fault_vector = res.bf_vec; if (retaddr) { - if (cpu_restore_state(cs, retaddr, true)) { + if (cpu_restore_state(cs, retaddr)) { /* Evaluate flags after retranslation. */ helper_top_evaluate_flags(env); } diff --git a/target/i386/tcg/sysemu/svm_helper.c b/target/i386/tcg/sysemu/svm_helper.c index 8e88567399..2d27731b60 100644 --- a/target/i386/tcg/sysemu/svm_helper.c +++ b/target/i386/tcg/sysemu/svm_helper.c @@ -704,7 +704,7 @@ void cpu_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1, { CPUState *cs = env_cpu(env); - cpu_restore_state(cs, retaddr, true); + cpu_restore_state(cs, retaddr); qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmexit(%08x, %016" PRIx64 ", %016" PRIx64 ", " TARGET_FMT_lx ")!\n", diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c index 5da176d642..1ce850bbc5 100644 --- a/target/m68k/op_helper.c +++ b/target/m68k/op_helper.c @@ -460,7 +460,7 @@ void m68k_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr, M68kCPU *cpu = M68K_CPU(cs); CPUM68KState *env = &cpu->env; - cpu_restore_state(cs, retaddr, true); + cpu_restore_state(cs, retaddr); if (m68k_feature(env, M68K_FEATURE_M68040)) { env->mmu.mmusr = 0; @@ -558,7 +558,7 @@ raise_exception_format2(CPUM68KState *env, int tt, int ilen, uintptr_t raddr) cs->exception_index = tt; /* Recover PC and CC_OP for the beginning of the insn. */ - cpu_restore_state(cs, raddr, true); + cpu_restore_state(cs, raddr); /* Flags are current in env->cc_*, or are undefined. */ env->cc_op = CC_OP_FLAGS; diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c index a607fe68e5..98bdb82de8 100644 --- a/target/microblaze/helper.c +++ b/target/microblaze/helper.c @@ -277,7 +277,7 @@ void mb_cpu_do_unaligned_access(CPUState *cs, vaddr addr, uint32_t esr, iflags; /* Recover the pc and iflags from the corresponding insn_start. */ - cpu_restore_state(cs, retaddr, true); + cpu_restore_state(cs, retaddr); iflags = cpu->env.iflags; qemu_log_mask(CPU_LOG_INT, diff --git a/target/nios2/op_helper.c b/target/nios2/op_helper.c index 2e30d0a908..0aaf33ffc2 100644 --- a/target/nios2/op_helper.c +++ b/target/nios2/op_helper.c @@ -40,7 +40,7 @@ void nios2_cpu_loop_exit_advance(CPUNios2State *env, uintptr_t retaddr) * Do this here, rather than in restore_state_to_opc(), * lest we affect QEMU internal exceptions, like EXCP_DEBUG. */ - cpu_restore_state(cs, retaddr, true); + cpu_restore_state(cs, retaddr); env->pc += 4; cpu_loop_exit(cs); } diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c index dde2fa1623..ec145960e3 100644 --- a/target/openrisc/sys_helper.c +++ b/target/openrisc/sys_helper.c @@ -45,7 +45,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb) break; case TO_SPR(0, 16): /* NPC */ - cpu_restore_state(cs, GETPC(), true); + cpu_restore_state(cs, GETPC()); /* ??? Mirror or1ksim in not trashing delayed branch state when "jumping" to the current instruction. */ if (env->pc != rb) { @@ -131,7 +131,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb) case TO_SPR(8, 0): /* PMR */ env->pmr = rb; if (env->pmr & PMR_DME || env->pmr & PMR_SME) { - cpu_restore_state(cs, GETPC(), true); + cpu_restore_state(cs, GETPC()); env->pc += 4; cs->halted = 1; raise_exception(cpu, EXCP_HALTED); diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 09a81561d4..a05a2ed595 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -3075,7 +3075,7 @@ void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr, uint32_t insn; /* Restore state and reload the insn we executed, for filling in DSISR. */ - cpu_restore_state(cs, retaddr, true); + cpu_restore_state(cs, retaddr); insn = cpu_ldl_code(env, env->nip); switch (env->mmu_model) { diff --git a/target/s390x/tcg/excp_helper.c b/target/s390x/tcg/excp_helper.c index 29ccf70df1..2cd6d062b9 100644 --- a/target/s390x/tcg/excp_helper.c +++ b/target/s390x/tcg/excp_helper.c @@ -39,7 +39,7 @@ G_NORETURN void tcg_s390_program_interrupt(CPUS390XState *env, { CPUState *cs = env_cpu(env); - cpu_restore_state(cs, ra, true); + cpu_restore_state(cs, ra); qemu_log_mask(CPU_LOG_INT, "program interrupt at %#" PRIx64 "\n", env->psw.addr); trigger_pgm_exception(env, code); diff --git a/target/tricore/op_helper.c b/target/tricore/op_helper.c index a79c838a92..532ae6b74c 100644 --- a/target/tricore/op_helper.c +++ b/target/tricore/op_helper.c @@ -31,7 +31,7 @@ void raise_exception_sync_internal(CPUTriCoreState *env, uint32_t class, int tin { CPUState *cs = env_cpu(env); /* in case we come from a helper-call we need to restore the PC */ - cpu_restore_state(cs, pc, true); + cpu_restore_state(cs, pc); /* Tin is loaded into d[15] */ env->gpr_d[15] = tin; diff --git a/target/xtensa/helper.c b/target/xtensa/helper.c index e0a9caab4b..2aa9777a8e 100644 --- a/target/xtensa/helper.c +++ b/target/xtensa/helper.c @@ -253,7 +253,7 @@ void xtensa_cpu_do_unaligned_access(CPUState *cs, assert(xtensa_option_enabled(env->config, XTENSA_OPTION_UNALIGNED_EXCEPTION)); - cpu_restore_state(CPU(cpu), retaddr, true); + cpu_restore_state(CPU(cpu), retaddr); HELPER(exception_cause_vaddr)(env, env->pc, LOAD_STORE_ALIGNMENT_CAUSE, addr); @@ -284,7 +284,7 @@ bool xtensa_cpu_tlb_fill(CPUState *cs, vaddr address, int size, } else if (probe) { return false; } else { - cpu_restore_state(cs, retaddr, true); + cpu_restore_state(cs, retaddr); HELPER(exception_cause_vaddr)(env, env->pc, ret, address); } } @@ -297,7 +297,7 @@ void xtensa_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr, XtensaCPU *cpu = XTENSA_CPU(cs); CPUXtensaState *env = &cpu->env; - cpu_restore_state(cs, retaddr, true); + cpu_restore_state(cs, retaddr); HELPER(exception_cause_vaddr)(env, env->pc, access_type == MMU_INST_FETCH ? INSTR_PIF_ADDR_ERROR_CAUSE : From cfa29dd50611a0ecea9888818692290148773c0d Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 23:12:56 +1000 Subject: [PATCH 521/705] accel/tcg: Remove reset_icount argument from cpu_restore_state_from_tb The value passed is always true. Reviewed-by: Claudio Fontana Signed-off-by: Richard Henderson --- accel/tcg/internal.h | 2 +- accel/tcg/tb-maint.c | 4 ++-- accel/tcg/translate-all.c | 15 +++++++-------- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h index 9c06b320b7..cb13bade4f 100644 --- a/accel/tcg/internal.h +++ b/accel/tcg/internal.h @@ -107,7 +107,7 @@ TranslationBlock *tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc, tb_page_addr_t phys_page2); bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc); void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, - uintptr_t host_pc, bool reset_icount); + uintptr_t host_pc); /* Return the current PC from CPU, which may be cached in TB. */ static inline target_ulong log_pc(CPUState *cpu, const TranslationBlock *tb) diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c index c8e921089d..0cdb35548c 100644 --- a/accel/tcg/tb-maint.c +++ b/accel/tcg/tb-maint.c @@ -536,7 +536,7 @@ tb_invalidate_phys_page_range__locked(struct page_collection *pages, * restore the CPU state. */ current_tb_modified = true; - cpu_restore_state_from_tb(cpu, current_tb, retaddr, true); + cpu_restore_state_from_tb(cpu, current_tb, retaddr); } #endif /* TARGET_HAS_PRECISE_SMC */ tb_phys_invalidate__locked(tb); @@ -685,7 +685,7 @@ bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc) * function to partially restore the CPU state. */ current_tb_modified = true; - cpu_restore_state_from_tb(cpu, current_tb, pc, true); + cpu_restore_state_from_tb(cpu, current_tb, pc); } #endif /* TARGET_HAS_PRECISE_SMC */ tb_phys_invalidate(tb, addr); diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 90997fed47..0089578f8f 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -282,12 +282,11 @@ static int cpu_unwind_data_from_tb(TranslationBlock *tb, uintptr_t host_pc, } /* - * The cpu state corresponding to 'host_pc' is restored. - * When reset_icount is true, current TB will be interrupted and - * icount should be recalculated. + * The cpu state corresponding to 'host_pc' is restored in + * preparation for exiting the TB. */ void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, - uintptr_t host_pc, bool reset_icount) + uintptr_t host_pc) { uint64_t data[TARGET_INSN_START_WORDS]; #ifdef CONFIG_PROFILER @@ -300,7 +299,7 @@ void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, return; } - if (reset_icount && (tb_cflags(tb) & CF_USE_ICOUNT)) { + if (tb_cflags(tb) & CF_USE_ICOUNT) { assert(icount_enabled()); /* * Reset the cycle counter to the start of the block and @@ -333,7 +332,7 @@ bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc) if (in_code_gen_buffer((const void *)(host_pc - tcg_splitwx_diff))) { TranslationBlock *tb = tcg_tb_lookup(host_pc); if (tb) { - cpu_restore_state_from_tb(cpu, tb, host_pc, true); + cpu_restore_state_from_tb(cpu, tb, host_pc); return true; } } @@ -1032,7 +1031,7 @@ void tb_check_watchpoint(CPUState *cpu, uintptr_t retaddr) tb = tcg_tb_lookup(retaddr); if (tb) { /* We can use retranslation to find the PC. */ - cpu_restore_state_from_tb(cpu, tb, retaddr, true); + cpu_restore_state_from_tb(cpu, tb, retaddr); tb_phys_invalidate(tb, -1); } else { /* The exception probably happened in a helper. The CPU state should @@ -1068,7 +1067,7 @@ void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr) cpu_abort(cpu, "cpu_io_recompile: could not find TB for pc=%p", (void *)retaddr); } - cpu_restore_state_from_tb(cpu, tb, retaddr, true); + cpu_restore_state_from_tb(cpu, tb, retaddr); /* * Some guests must re-execute the branch when re-executing a delay From 631793308679cf0436cd7145a9ff318331c982c9 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 24 Oct 2022 16:16:30 +1000 Subject: [PATCH 522/705] target/i386: Expand eflags updates inline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The helpers for reset_rf, cli, sti, clac, stac are completely trivial; implement them inline. Drop some nearby #if 0 code. Reviewed-by: Paolo Bonzini Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- target/i386/helper.h | 5 ----- target/i386/tcg/cc_helper.c | 41 ------------------------------------- target/i386/tcg/translate.c | 30 ++++++++++++++++++++++----- 3 files changed, 25 insertions(+), 51 deletions(-) diff --git a/target/i386/helper.h b/target/i386/helper.h index 88143b2a24..b7de5429ef 100644 --- a/target/i386/helper.h +++ b/target/i386/helper.h @@ -56,13 +56,8 @@ DEF_HELPER_2(syscall, void, env, int) DEF_HELPER_2(sysret, void, env, int) #endif DEF_HELPER_FLAGS_2(pause, TCG_CALL_NO_WG, noreturn, env, int) -DEF_HELPER_1(reset_rf, void, env) DEF_HELPER_FLAGS_3(raise_interrupt, TCG_CALL_NO_WG, noreturn, env, int, int) DEF_HELPER_FLAGS_2(raise_exception, TCG_CALL_NO_WG, noreturn, env, int) -DEF_HELPER_1(cli, void, env) -DEF_HELPER_1(sti, void, env) -DEF_HELPER_1(clac, void, env) -DEF_HELPER_1(stac, void, env) DEF_HELPER_3(boundw, void, env, tl, int) DEF_HELPER_3(boundl, void, env, tl, int) diff --git a/target/i386/tcg/cc_helper.c b/target/i386/tcg/cc_helper.c index cc7ea9e8b9..6227dbb30b 100644 --- a/target/i386/tcg/cc_helper.c +++ b/target/i386/tcg/cc_helper.c @@ -346,44 +346,3 @@ void helper_clts(CPUX86State *env) env->cr[0] &= ~CR0_TS_MASK; env->hflags &= ~HF_TS_MASK; } - -void helper_reset_rf(CPUX86State *env) -{ - env->eflags &= ~RF_MASK; -} - -void helper_cli(CPUX86State *env) -{ - env->eflags &= ~IF_MASK; -} - -void helper_sti(CPUX86State *env) -{ - env->eflags |= IF_MASK; -} - -void helper_clac(CPUX86State *env) -{ - env->eflags &= ~AC_MASK; -} - -void helper_stac(CPUX86State *env) -{ - env->eflags |= AC_MASK; -} - -#if 0 -/* vm86plus instructions */ -void helper_cli_vm(CPUX86State *env) -{ - env->eflags &= ~VIF_MASK; -} - -void helper_sti_vm(CPUX86State *env) -{ - env->eflags |= VIF_MASK; - if (env->eflags & VIP_MASK) { - raise_exception_ra(env, EXCP0D_GPF, GETPC()); - } -} -#endif diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c index 546c427c23..0ee548ce56 100644 --- a/target/i386/tcg/translate.c +++ b/target/i386/tcg/translate.c @@ -2746,6 +2746,26 @@ static void gen_reset_hflag(DisasContext *s, uint32_t mask) } } +static void gen_set_eflags(DisasContext *s, target_ulong mask) +{ + TCGv t = tcg_temp_new(); + + tcg_gen_ld_tl(t, cpu_env, offsetof(CPUX86State, eflags)); + tcg_gen_ori_tl(t, t, mask); + tcg_gen_st_tl(t, cpu_env, offsetof(CPUX86State, eflags)); + tcg_temp_free(t); +} + +static void gen_reset_eflags(DisasContext *s, target_ulong mask) +{ + TCGv t = tcg_temp_new(); + + tcg_gen_ld_tl(t, cpu_env, offsetof(CPUX86State, eflags)); + tcg_gen_andi_tl(t, t, ~mask); + tcg_gen_st_tl(t, cpu_env, offsetof(CPUX86State, eflags)); + tcg_temp_free(t); +} + /* Clear BND registers during legacy branches. */ static void gen_bnd_jmp(DisasContext *s) { @@ -2776,7 +2796,7 @@ do_gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf, bool jr) } if (s->base.tb->flags & HF_RF_MASK) { - gen_helper_reset_rf(cpu_env); + gen_reset_eflags(s, RF_MASK); } if (recheck_tf) { gen_helper_rechecking_single_step(cpu_env); @@ -5502,12 +5522,12 @@ static bool disas_insn(DisasContext *s, CPUState *cpu) #endif case 0xfa: /* cli */ if (check_iopl(s)) { - gen_helper_cli(cpu_env); + gen_reset_eflags(s, IF_MASK); } break; case 0xfb: /* sti */ if (check_iopl(s)) { - gen_helper_sti(cpu_env); + gen_set_eflags(s, IF_MASK); /* interruptions are enabled only the first insn after sti */ gen_update_eip_next(s); gen_eob_inhibit_irq(s, true); @@ -5789,7 +5809,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu) || CPL(s) != 0) { goto illegal_op; } - gen_helper_clac(cpu_env); + gen_reset_eflags(s, AC_MASK); s->base.is_jmp = DISAS_EOB_NEXT; break; @@ -5798,7 +5818,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu) || CPL(s) != 0) { goto illegal_op; } - gen_helper_stac(cpu_env); + gen_set_eflags(s, AC_MASK); s->base.is_jmp = DISAS_EOB_NEXT; break; From 4e4fa6c12d97ee3ee87623c153009a5abd7b428e Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 31 Oct 2022 13:26:36 +1100 Subject: [PATCH 523/705] accel/tcg: Complete cpu initialization before registration Delay cpu_list_add until realize is complete, so that cross-cpu interaction does not happen with incomplete cpu state. For this, we must delay plugin initialization out of tcg_exec_realizefn, because no cpu_index has been assigned. Fixes a problem with cross-cpu jump cache flushing, when the jump cache has not yet been allocated. Fixes: a976a99a2975 ("include/hw/core: Create struct CPUJumpCache") Acked-by: Ilya Leoshkevich Reported-by: Ilya Leoshkevich Signed-off-by: Richard Henderson --- accel/tcg/cpu-exec.c | 8 +++++--- accel/tcg/translate-all.c | 16 +++++++--------- cpu.c | 10 +++++++++- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c index 82b06c1824..356fe348de 100644 --- a/accel/tcg/cpu-exec.c +++ b/accel/tcg/cpu-exec.c @@ -1052,23 +1052,25 @@ void tcg_exec_realizefn(CPUState *cpu, Error **errp) cc->tcg_ops->initialize(); tcg_target_initialized = true; } - tlb_init(cpu); - qemu_plugin_vcpu_init_hook(cpu); + cpu->tb_jmp_cache = g_new0(CPUJumpCache, 1); + tlb_init(cpu); #ifndef CONFIG_USER_ONLY tcg_iommu_init_notifier_list(cpu); #endif /* !CONFIG_USER_ONLY */ + /* qemu_plugin_vcpu_init_hook delayed until cpu_index assigned. */ } /* undo the initializations in reverse order */ void tcg_exec_unrealizefn(CPUState *cpu) { + qemu_plugin_vcpu_exit_hook(cpu); #ifndef CONFIG_USER_ONLY tcg_iommu_free_notifier_list(cpu); #endif /* !CONFIG_USER_ONLY */ - qemu_plugin_vcpu_exit_hook(cpu); tlb_destroy(cpu); + g_free(cpu->tb_jmp_cache); } #ifndef CONFIG_USER_ONLY diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 0089578f8f..921944a5ab 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -1580,15 +1580,13 @@ void tcg_flush_jmp_cache(CPUState *cpu) { CPUJumpCache *jc = cpu->tb_jmp_cache; - if (likely(jc)) { - for (int i = 0; i < TB_JMP_CACHE_SIZE; i++) { - qatomic_set(&jc->array[i].tb, NULL); - } - } else { - /* This should happen once during realize, and thus never race. */ - jc = g_new0(CPUJumpCache, 1); - jc = qatomic_xchg(&cpu->tb_jmp_cache, jc); - assert(jc == NULL); + /* During early initialization, the cache may not yet be allocated. */ + if (unlikely(jc == NULL)) { + return; + } + + for (int i = 0; i < TB_JMP_CACHE_SIZE; i++) { + qatomic_set(&jc->array[i].tb, NULL); } } diff --git a/cpu.c b/cpu.c index 2a09b05205..4a7d865427 100644 --- a/cpu.c +++ b/cpu.c @@ -134,15 +134,23 @@ void cpu_exec_realizefn(CPUState *cpu, Error **errp) /* cache the cpu class for the hotpath */ cpu->cc = CPU_GET_CLASS(cpu); - cpu_list_add(cpu); if (!accel_cpu_realizefn(cpu, errp)) { return; } + /* NB: errp parameter is unused currently */ if (tcg_enabled()) { tcg_exec_realizefn(cpu, errp); } + /* Wait until cpu initialization complete before exposing cpu. */ + cpu_list_add(cpu); + + /* Plugin initialization must wait until cpu_index assigned. */ + if (tcg_enabled()) { + qemu_plugin_vcpu_init_hook(cpu); + } + #ifdef CONFIG_USER_ONLY assert(qdev_get_vmsd(DEVICE(cpu)) == NULL || qdev_get_vmsd(DEVICE(cpu))->unmigratable); From 83d92559cdf0ce842e52e5bbf230f7f62a6206aa Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Fri, 28 Oct 2022 14:42:27 +0200 Subject: [PATCH 524/705] tests/tcg/multiarch: Add munmap-pthread.c Add a test to detect races between munmap() and creating new threads. Signed-off-by: Ilya Leoshkevich Message-Id: <20221028124227.2354792-3-iii@linux.ibm.com> [rth: add more return insns] Signed-off-by: Richard Henderson --- tests/tcg/multiarch/Makefile.target | 3 ++ tests/tcg/multiarch/munmap-pthread.c | 79 ++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 tests/tcg/multiarch/munmap-pthread.c diff --git a/tests/tcg/multiarch/Makefile.target b/tests/tcg/multiarch/Makefile.target index 78104f9bbb..5f0fee1aad 100644 --- a/tests/tcg/multiarch/Makefile.target +++ b/tests/tcg/multiarch/Makefile.target @@ -36,6 +36,9 @@ threadcount: LDFLAGS+=-lpthread signals: LDFLAGS+=-lrt -lpthread +munmap-pthread: CFLAGS+=-pthread +munmap-pthread: LDFLAGS+=-pthread + # We define the runner for test-mmap after the individual # architectures have defined their supported pages sizes. If no # additional page sizes are defined we only run the default test. diff --git a/tests/tcg/multiarch/munmap-pthread.c b/tests/tcg/multiarch/munmap-pthread.c new file mode 100644 index 0000000000..d7143b00d5 --- /dev/null +++ b/tests/tcg/multiarch/munmap-pthread.c @@ -0,0 +1,79 @@ +/* Test that munmap() and thread creation do not race. */ +#include +#include +#include +#include +#include +#include +#include + +static const char nop_func[] = { +#if defined(__aarch64__) + 0xc0, 0x03, 0x5f, 0xd6, /* ret */ +#elif defined(__alpha__) + 0x01, 0x80, 0xFA, 0x6B, /* ret */ +#elif defined(__arm__) + 0x1e, 0xff, 0x2f, 0xe1, /* bx lr */ +#elif defined(__riscv) + 0x67, 0x80, 0x00, 0x00, /* ret */ +#elif defined(__s390__) + 0x07, 0xfe, /* br %r14 */ +#elif defined(__i386__) || defined(__x86_64__) + 0xc3, /* ret */ +#endif +}; + +static void *thread_mmap_munmap(void *arg) +{ + volatile bool *run = arg; + char *p; + int ret; + + while (*run) { + p = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + assert(p != MAP_FAILED); + + /* Create a small translation block. */ + memcpy(p, nop_func, sizeof(nop_func)); + ((void(*)(void))p)(); + + ret = munmap(p, getpagesize()); + assert(ret == 0); + } + + return NULL; +} + +static void *thread_dummy(void *arg) +{ + return NULL; +} + +int main(void) +{ + pthread_t mmap_munmap, dummy; + volatile bool run = true; + int i, ret; + + /* Without a template, nothing to test. */ + if (sizeof(nop_func) == 0) { + return EXIT_SUCCESS; + } + + ret = pthread_create(&mmap_munmap, NULL, thread_mmap_munmap, (void *)&run); + assert(ret == 0); + + for (i = 0; i < 1000; i++) { + ret = pthread_create(&dummy, NULL, thread_dummy, NULL); + assert(ret == 0); + ret = pthread_join(dummy, NULL); + assert(ret == 0); + } + + run = false; + ret = pthread_join(mmap_munmap, NULL); + assert(ret == 0); + + return EXIT_SUCCESS; +} From d38cc6fd1cafc3f834bb529f79bfc23089e9e54f Mon Sep 17 00:00:00 2001 From: Klaus Jensen Date: Wed, 19 Oct 2022 22:28:02 +0200 Subject: [PATCH 525/705] hw/nvme: reenable cqe batching Commit 2e53b0b45024 ("hw/nvme: Use ioeventfd to handle doorbell updates") had the unintended effect of disabling batching of CQEs. This patch changes the sq/cq timers to bottom halfs and instead of calling nvme_post_cqes() immediately (causing an interrupt per cqe), we defer the call. | iops -----------------+------ baseline | 138k +cqe batching | 233k Fixes: 2e53b0b45024 ("hw/nvme: Use ioeventfd to handle doorbell updates") Reviewed-by: Keith Busch Reviewed-by: Jinhao Fan Signed-off-by: Klaus Jensen --- hw/nvme/ctrl.c | 26 +++++++++++--------------- hw/nvme/nvme.h | 4 ++-- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c index 87aeba0564..73c870a429 100644 --- a/hw/nvme/ctrl.c +++ b/hw/nvme/ctrl.c @@ -1401,13 +1401,7 @@ static void nvme_enqueue_req_completion(NvmeCQueue *cq, NvmeRequest *req) QTAILQ_REMOVE(&req->sq->out_req_list, req, entry); QTAILQ_INSERT_TAIL(&cq->req_list, req, entry); - if (req->sq->ioeventfd_enabled) { - /* Post CQE directly since we are in main loop thread */ - nvme_post_cqes(cq); - } else { - /* Schedule the timer to post CQE later since we are in vcpu thread */ - timer_mod(cq->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 500); - } + qemu_bh_schedule(cq->bh); } static void nvme_process_aers(void *opaque) @@ -4252,7 +4246,7 @@ static void nvme_cq_notifier(EventNotifier *e) nvme_irq_deassert(n, cq); } - nvme_post_cqes(cq); + qemu_bh_schedule(cq->bh); } static int nvme_init_cq_ioeventfd(NvmeCQueue *cq) @@ -4307,7 +4301,7 @@ static void nvme_free_sq(NvmeSQueue *sq, NvmeCtrl *n) uint16_t offset = sq->sqid << 3; n->sq[sq->sqid] = NULL; - timer_free(sq->timer); + qemu_bh_delete(sq->bh); if (sq->ioeventfd_enabled) { memory_region_del_eventfd(&n->iomem, 0x1000 + offset, 4, false, 0, &sq->notifier); @@ -4381,7 +4375,8 @@ static void nvme_init_sq(NvmeSQueue *sq, NvmeCtrl *n, uint64_t dma_addr, sq->io_req[i].sq = sq; QTAILQ_INSERT_TAIL(&(sq->req_list), &sq->io_req[i], entry); } - sq->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, nvme_process_sq, sq); + + sq->bh = qemu_bh_new(nvme_process_sq, sq); if (n->dbbuf_enabled) { sq->db_addr = n->dbbuf_dbs + (sqid << 3); @@ -4698,7 +4693,7 @@ static void nvme_free_cq(NvmeCQueue *cq, NvmeCtrl *n) uint16_t offset = (cq->cqid << 3) + (1 << 2); n->cq[cq->cqid] = NULL; - timer_free(cq->timer); + qemu_bh_delete(cq->bh); if (cq->ioeventfd_enabled) { memory_region_del_eventfd(&n->iomem, 0x1000 + offset, 4, false, 0, &cq->notifier); @@ -4771,7 +4766,7 @@ static void nvme_init_cq(NvmeCQueue *cq, NvmeCtrl *n, uint64_t dma_addr, } } n->cq[cqid] = cq; - cq->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, nvme_post_cqes, cq); + cq->bh = qemu_bh_new(nvme_post_cqes, cq); } static uint16_t nvme_create_cq(NvmeCtrl *n, NvmeRequest *req) @@ -6913,9 +6908,9 @@ static void nvme_process_db(NvmeCtrl *n, hwaddr addr, int val) if (start_sqs) { NvmeSQueue *sq; QTAILQ_FOREACH(sq, &cq->sq_list, entry) { - timer_mod(sq->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 500); + qemu_bh_schedule(sq->bh); } - timer_mod(cq->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 500); + qemu_bh_schedule(cq->bh); } if (cq->tail == cq->head) { @@ -6984,7 +6979,8 @@ static void nvme_process_db(NvmeCtrl *n, hwaddr addr, int val) pci_dma_write(&n->parent_obj, sq->db_addr, &sq->tail, sizeof(sq->tail)); } - timer_mod(sq->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 500); + + qemu_bh_schedule(sq->bh); } } diff --git a/hw/nvme/nvme.h b/hw/nvme/nvme.h index 79f5c281c2..7adf042ec3 100644 --- a/hw/nvme/nvme.h +++ b/hw/nvme/nvme.h @@ -375,7 +375,7 @@ typedef struct NvmeSQueue { uint64_t dma_addr; uint64_t db_addr; uint64_t ei_addr; - QEMUTimer *timer; + QEMUBH *bh; EventNotifier notifier; bool ioeventfd_enabled; NvmeRequest *io_req; @@ -396,7 +396,7 @@ typedef struct NvmeCQueue { uint64_t dma_addr; uint64_t db_addr; uint64_t ei_addr; - QEMUTimer *timer; + QEMUBH *bh; EventNotifier notifier; bool ioeventfd_enabled; QTAILQ_HEAD(, NvmeSQueue) sq_list; From 632cb6cf07122b330d8ef419ec2f4aab561a9fba Mon Sep 17 00:00:00 2001 From: Francis Pravin Antony Michael Raj Date: Wed, 2 Nov 2022 09:06:00 +0100 Subject: [PATCH 526/705] hw/nvme: Abort copy command when format is one while pif As per the NVMe Command Set specification Section 3.2.2, if i) The namespace is formatted to use 16b Guard Protection Information (i.e., pif = 0) and ii) The Descriptor Format is not cleared to 0h Then the copy command should be aborted with the status code of Invalid Namespace or Format Fixes: 44219b6029fc ("hw/nvme: 64-bit pi support") Signed-off-by: Francis Pravin Antony Michael Raj Signed-off-by: Jonathan Derrick Reviewed-by: Klaus Jensen Signed-off-by: Klaus Jensen --- hw/nvme/ctrl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c index 73c870a429..9a9857ccf8 100644 --- a/hw/nvme/ctrl.c +++ b/hw/nvme/ctrl.c @@ -3034,7 +3034,8 @@ static uint16_t nvme_copy(NvmeCtrl *n, NvmeRequest *req) goto invalid; } - if (ns->pif && format != 0x1) { + if ((ns->pif == 0x0 && format != 0x0) || + (ns->pif != 0x0 && format != 0x1)) { status = NVME_INVALID_FORMAT | NVME_DNR; goto invalid; } From 4ad08e8a57f0a779dbf58bcdccd8c9b6f6432512 Mon Sep 17 00:00:00 2001 From: Ani Sinha Date: Wed, 31 Aug 2022 10:23:10 +0530 Subject: [PATCH 527/705] hw/i386/e820: remove legacy reserved entries for e820 e820 reserved entries were used before the dynamic entries with fw config files were intoduced. Please see the following change: 7d67110f2d9a6("pc: add etc/e820 fw_cfg file") Identical support was introduced into seabios as well with the following commit: ce39bd4031820 ("Add support for etc/e820 fw_cfg file") Both the above commits are now quite old. QEMU machines 1.7 and newer no longer use the reserved entries. Seabios uses fw config files and dynamic e820 entries by default and only falls back to using reserved entries when it has to work with old qemu (versions earlier than 1.7). Please see functions qemu_cfg_e820() and qemu_early_e820(). It is safe to remove legacy FW_CFG_E820_TABLE and associated code now as QEMU 7.0 has deprecated i440fx machines 1.7 and older. It would be incredibly rare to run the latest qemu version with a very old version of seabios that did not support fw config files for e820. As far as I could see, edk2/ovfm never supported reserved entries and uses fw config files from the beginning. So there should be no incompatibilities with ovfm as well. CC: Gerd Hoffmann Signed-off-by: Ani Sinha Acked-by: Gerd Hoffmann Message-Id: <20220831045311.33083-1-ani@anisinha.ca> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/e820_memory_layout.c | 20 +------------------- hw/i386/e820_memory_layout.h | 8 -------- hw/i386/fw_cfg.c | 3 --- hw/i386/fw_cfg.h | 1 - hw/i386/microvm.c | 2 -- 5 files changed, 1 insertion(+), 33 deletions(-) diff --git a/hw/i386/e820_memory_layout.c b/hw/i386/e820_memory_layout.c index bcf9eaf837..06970ac44a 100644 --- a/hw/i386/e820_memory_layout.c +++ b/hw/i386/e820_memory_layout.c @@ -11,29 +11,11 @@ #include "e820_memory_layout.h" static size_t e820_entries; -struct e820_table e820_reserve; struct e820_entry *e820_table; int e820_add_entry(uint64_t address, uint64_t length, uint32_t type) { - int index = le32_to_cpu(e820_reserve.count); - struct e820_entry *entry; - - if (type != E820_RAM) { - /* old FW_CFG_E820_TABLE entry -- reservations only */ - if (index >= E820_NR_ENTRIES) { - return -EBUSY; - } - entry = &e820_reserve.entry[index++]; - - entry->address = cpu_to_le64(address); - entry->length = cpu_to_le64(length); - entry->type = cpu_to_le32(type); - - e820_reserve.count = cpu_to_le32(index); - } - - /* new "etc/e820" file -- include ram too */ + /* new "etc/e820" file -- include ram and reserved entries */ e820_table = g_renew(struct e820_entry, e820_table, e820_entries + 1); e820_table[e820_entries].address = cpu_to_le64(address); e820_table[e820_entries].length = cpu_to_le64(length); diff --git a/hw/i386/e820_memory_layout.h b/hw/i386/e820_memory_layout.h index 04f93780f9..7c239aa033 100644 --- a/hw/i386/e820_memory_layout.h +++ b/hw/i386/e820_memory_layout.h @@ -16,20 +16,12 @@ #define E820_NVS 4 #define E820_UNUSABLE 5 -#define E820_NR_ENTRIES 16 - struct e820_entry { uint64_t address; uint64_t length; uint32_t type; } QEMU_PACKED __attribute((__aligned__(4))); -struct e820_table { - uint32_t count; - struct e820_entry entry[E820_NR_ENTRIES]; -} QEMU_PACKED __attribute((__aligned__(4))); - -extern struct e820_table e820_reserve; extern struct e820_entry *e820_table; int e820_add_entry(uint64_t address, uint64_t length, uint32_t type); diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c index a283785a8d..72a42f3c66 100644 --- a/hw/i386/fw_cfg.c +++ b/hw/i386/fw_cfg.c @@ -36,7 +36,6 @@ const char *fw_cfg_arch_key_name(uint16_t key) {FW_CFG_ACPI_TABLES, "acpi_tables"}, {FW_CFG_SMBIOS_ENTRIES, "smbios_entries"}, {FW_CFG_IRQ0_OVERRIDE, "irq0_override"}, - {FW_CFG_E820_TABLE, "e820_table"}, {FW_CFG_HPET, "hpet"}, }; @@ -127,8 +126,6 @@ FWCfgState *fw_cfg_arch_create(MachineState *ms, #endif fw_cfg_add_i32(fw_cfg, FW_CFG_IRQ0_OVERRIDE, 1); - fw_cfg_add_bytes(fw_cfg, FW_CFG_E820_TABLE, - &e820_reserve, sizeof(e820_reserve)); fw_cfg_add_file(fw_cfg, "etc/e820", e820_table, sizeof(struct e820_entry) * e820_get_num_entries()); diff --git a/hw/i386/fw_cfg.h b/hw/i386/fw_cfg.h index 275f15c1c5..86ca7c1c0c 100644 --- a/hw/i386/fw_cfg.h +++ b/hw/i386/fw_cfg.h @@ -17,7 +17,6 @@ #define FW_CFG_ACPI_TABLES (FW_CFG_ARCH_LOCAL + 0) #define FW_CFG_SMBIOS_ENTRIES (FW_CFG_ARCH_LOCAL + 1) #define FW_CFG_IRQ0_OVERRIDE (FW_CFG_ARCH_LOCAL + 2) -#define FW_CFG_E820_TABLE (FW_CFG_ARCH_LOCAL + 3) #define FW_CFG_HPET (FW_CFG_ARCH_LOCAL + 4) FWCfgState *fw_cfg_arch_create(MachineState *ms, diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c index ffd1884100..170a331e3f 100644 --- a/hw/i386/microvm.c +++ b/hw/i386/microvm.c @@ -324,8 +324,6 @@ static void microvm_memory_init(MicrovmMachineState *mms) fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, machine->smp.max_cpus); fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)machine->ram_size); fw_cfg_add_i32(fw_cfg, FW_CFG_IRQ0_OVERRIDE, 1); - fw_cfg_add_bytes(fw_cfg, FW_CFG_E820_TABLE, - &e820_reserve, sizeof(e820_reserve)); fw_cfg_add_file(fw_cfg, "etc/e820", e820_table, sizeof(struct e820_entry) * e820_get_num_entries()); From 0ecc4e91614fde87ad916008cd5c33420fd76dbd Mon Sep 17 00:00:00 2001 From: Robert Hoo Date: Thu, 22 Sep 2022 20:21:51 +0800 Subject: [PATCH 528/705] tests/acpi: allow SSDT changes Signed-off-by: Robert Hoo Reviewed-by: Jingqi Liu Message-Id: <20220922122155.1326543-2-robert.hu@linux.intel.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- tests/qtest/bios-tables-test-allowed-diff.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h index dfb8523c8b..eb8bae1407 100644 --- a/tests/qtest/bios-tables-test-allowed-diff.h +++ b/tests/qtest/bios-tables-test-allowed-diff.h @@ -1 +1,3 @@ /* List of comma-separated changed AML files to ignore */ +"tests/data/acpi/pc/SSDT.dimmpxm", +"tests/data/acpi/q35/SSDT.dimmpxm", From 63bb20d669dc21174f11ab1620f6ac52679cde54 Mon Sep 17 00:00:00 2001 From: Robert Hoo Date: Thu, 22 Sep 2022 20:21:52 +0800 Subject: [PATCH 529/705] acpi/ssdt: Fix aml_or() and aml_and() in if clause In If condition, using bitwise and/or, rather than logical and/or. The result change in AML code: If (((Local6 == Zero) | (Arg0 != Local0))) ==> If (((Local6 == Zero) || (Arg0 != Local0))) If (((ObjectType (Arg3) == 0x04) & (SizeOf (Arg3) == One))) ==> If (((ObjectType (Arg3) == 0x04) && (SizeOf (Arg3) == One))) Fixes: 90623ebf603 ("nvdimm acpi: check UUID") Fixes: 4568c948066 ("nvdimm acpi: save arg3 of _DSM method") Signed-off-by: Robert Hoo Reviewed-by: Jingqi Liu Reviewed-by: Igor Mammedov Message-Id: <20220922122155.1326543-3-robert.hu@linux.intel.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/nvdimm.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c index 31e46df0bd..201317c611 100644 --- a/hw/acpi/nvdimm.c +++ b/hw/acpi/nvdimm.c @@ -1037,7 +1037,7 @@ static void nvdimm_build_common_dsm(Aml *dev, uuid_invalid = aml_lnot(aml_equal(uuid, expected_uuid)); - unsupport = aml_if(aml_or(unpatched, uuid_invalid, NULL)); + unsupport = aml_if(aml_lor(unpatched, uuid_invalid)); /* * function 0 is called to inquire what functions are supported by @@ -1069,10 +1069,9 @@ static void nvdimm_build_common_dsm(Aml *dev, * in the DSM Spec. */ pckg = aml_arg(3); - ifctx = aml_if(aml_and(aml_equal(aml_object_type(pckg), + ifctx = aml_if(aml_land(aml_equal(aml_object_type(pckg), aml_int(4 /* Package */)) /* It is a Package? */, - aml_equal(aml_sizeof(pckg), aml_int(1)) /* 1 element? */, - NULL)); + aml_equal(aml_sizeof(pckg), aml_int(1)) /* 1 element? */)); pckg_index = aml_local(2); pckg_buf = aml_local(3); From d773f38be34d6f0c8bd627e3f961363108f43e45 Mon Sep 17 00:00:00 2001 From: Robert Hoo Date: Thu, 22 Sep 2022 20:21:53 +0800 Subject: [PATCH 530/705] acpi/nvdimm: define macro for NVDIMM Device _DSM Since it will be heavily used in next patch, define macro NVDIMM_DEVICE_DSM_UUID for "4309AC30-0D11-11E4-9191-0800200C9A66", which is NVDIMM device specific method uuid defined in NVDIMM _DSM interface spec, Section 3. [1] No functional changes in this patch. [1] https://pmem.io/documents/IntelOptanePMem_DSM_Interface-V2.0.pdf Signed-off-by: Robert Hoo Reviewed-by: Igor Mammedov Message-Id: <20220922122155.1326543-4-robert.hu@linux.intel.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/nvdimm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c index 201317c611..afff911c1e 100644 --- a/hw/acpi/nvdimm.c +++ b/hw/acpi/nvdimm.c @@ -922,6 +922,7 @@ void nvdimm_init_acpi_state(NVDIMMState *state, MemoryRegion *io, #define NVDIMM_DSM_RFIT_STATUS "RSTA" #define NVDIMM_QEMU_RSVD_UUID "648B9CF2-CDA1-4312-8AD9-49C4AF32BD62" +#define NVDIMM_DEVICE_DSM_UUID "4309AC30-0D11-11E4-9191-0800200C9A66" static void nvdimm_build_common_dsm(Aml *dev, NVDIMMState *nvdimm_state) @@ -1029,8 +1030,7 @@ static void nvdimm_build_common_dsm(Aml *dev, /* UUID for QEMU internal use */), expected_uuid)); aml_append(elsectx, ifctx); elsectx2 = aml_else(); - aml_append(elsectx2, aml_store( - aml_touuid("4309AC30-0D11-11E4-9191-0800200C9A66") + aml_append(elsectx2, aml_store(aml_touuid(NVDIMM_DEVICE_DSM_UUID) /* UUID for NVDIMM Devices */, expected_uuid)); aml_append(elsectx, elsectx2); aml_append(method, elsectx); From 4ad44f624b1e9ba9073db4b8d963c379f71f7683 Mon Sep 17 00:00:00 2001 From: Robert Hoo Date: Thu, 22 Sep 2022 20:21:54 +0800 Subject: [PATCH 531/705] acpi/nvdimm: Implement ACPI NVDIMM Label Methods Recent ACPI spec [1] has defined NVDIMM Label Methods _LS{I,R,W}, which deprecates corresponding _DSM Functions defined by PMEM _DSM Interface spec [2]. Since the semantics of the new Label Methods are almost same as old _DSM methods, the implementations here simply wrapper old ones. ASL form diff can be found in next patch of updating golden master binaries. [1] ACPI Spec v6.4, 6.5.10 NVDIMM Label Methods https://uefi.org/sites/default/files/resources/ACPI_Spec_6_4_Jan22.pdf [2] Intel PMEM _DSM Interface Spec v2.0, 3.10 Deprecated Functions https://pmem.io/documents/IntelOptanePMem_DSM_Interface-V2.0.pdf Signed-off-by: Robert Hoo Message-Id: <20220922122155.1326543-5-robert.hu@linux.intel.com> Reviewed-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/nvdimm.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c index afff911c1e..a3b25a92f3 100644 --- a/hw/acpi/nvdimm.c +++ b/hw/acpi/nvdimm.c @@ -1243,6 +1243,7 @@ static void nvdimm_build_fit(Aml *dev) static void nvdimm_build_nvdimm_devices(Aml *root_dev, uint32_t ram_slots) { uint32_t slot; + Aml *method, *pkg, *field, *com_call; for (slot = 0; slot < ram_slots; slot++) { uint32_t handle = nvdimm_slot_to_handle(slot); @@ -1260,6 +1261,100 @@ static void nvdimm_build_nvdimm_devices(Aml *root_dev, uint32_t ram_slots) */ aml_append(nvdimm_dev, aml_name_decl("_ADR", aml_int(handle))); + /* + * ACPI v6.4: Section 6.5.10 NVDIMM Label Methods + */ + /* _LSI */ + method = aml_method("_LSI", 0, AML_SERIALIZED); + com_call = aml_call5(NVDIMM_COMMON_DSM, + aml_touuid(NVDIMM_DEVICE_DSM_UUID), + aml_int(1), aml_int(4), aml_int(0), + aml_int(handle)); + aml_append(method, aml_store(com_call, aml_local(0))); + + aml_append(method, aml_create_dword_field(aml_local(0), + aml_int(0), "STTS")); + aml_append(method, aml_create_dword_field(aml_local(0), aml_int(4), + "SLSA")); + aml_append(method, aml_create_dword_field(aml_local(0), aml_int(8), + "MAXT")); + + pkg = aml_package(3); + aml_append(pkg, aml_name("STTS")); + aml_append(pkg, aml_name("SLSA")); + aml_append(pkg, aml_name("MAXT")); + aml_append(method, aml_store(pkg, aml_local(1))); + aml_append(method, aml_return(aml_local(1))); + + aml_append(nvdimm_dev, method); + + /* _LSR */ + method = aml_method("_LSR", 2, AML_SERIALIZED); + aml_append(method, aml_name_decl("INPT", aml_buffer(8, NULL))); + + aml_append(method, aml_create_dword_field(aml_name("INPT"), + aml_int(0), "OFST")); + aml_append(method, aml_create_dword_field(aml_name("INPT"), + aml_int(4), "LEN")); + aml_append(method, aml_store(aml_arg(0), aml_name("OFST"))); + aml_append(method, aml_store(aml_arg(1), aml_name("LEN"))); + + pkg = aml_package(1); + aml_append(pkg, aml_name("INPT")); + aml_append(method, aml_store(pkg, aml_local(0))); + + com_call = aml_call5(NVDIMM_COMMON_DSM, + aml_touuid(NVDIMM_DEVICE_DSM_UUID), + aml_int(1), aml_int(5), aml_local(0), + aml_int(handle)); + aml_append(method, aml_store(com_call, aml_local(3))); + field = aml_create_dword_field(aml_local(3), aml_int(0), "STTS"); + aml_append(method, field); + field = aml_create_field(aml_local(3), aml_int(32), + aml_shiftleft(aml_name("LEN"), aml_int(3)), + "LDAT"); + aml_append(method, field); + aml_append(method, aml_name_decl("LSA", aml_buffer(0, NULL))); + aml_append(method, aml_to_buffer(aml_name("LDAT"), aml_name("LSA"))); + + pkg = aml_package(2); + aml_append(pkg, aml_name("STTS")); + aml_append(pkg, aml_name("LSA")); + + aml_append(method, aml_store(pkg, aml_local(1))); + aml_append(method, aml_return(aml_local(1))); + + aml_append(nvdimm_dev, method); + + /* _LSW */ + method = aml_method("_LSW", 3, AML_SERIALIZED); + aml_append(method, aml_store(aml_arg(2), aml_local(2))); + aml_append(method, aml_name_decl("INPT", aml_buffer(8, NULL))); + field = aml_create_dword_field(aml_name("INPT"), + aml_int(0), "OFST"); + aml_append(method, field); + field = aml_create_dword_field(aml_name("INPT"), + aml_int(4), "TLEN"); + aml_append(method, field); + aml_append(method, aml_store(aml_arg(0), aml_name("OFST"))); + aml_append(method, aml_store(aml_arg(1), aml_name("TLEN"))); + + aml_append(method, aml_concatenate(aml_name("INPT"), aml_local(2), + aml_name("INPT"))); + pkg = aml_package(1); + aml_append(pkg, aml_name("INPT")); + aml_append(method, aml_store(pkg, aml_local(0))); + com_call = aml_call5(NVDIMM_COMMON_DSM, + aml_touuid(NVDIMM_DEVICE_DSM_UUID), + aml_int(1), aml_int(6), aml_local(0), + aml_int(handle)); + aml_append(method, aml_store(com_call, aml_local(3))); + field = aml_create_dword_field(aml_local(3), aml_int(0), "STTS"); + aml_append(method, field); + aml_append(method, aml_return(aml_name("STTS"))); + + aml_append(nvdimm_dev, method); + nvdimm_build_device_dsm(nvdimm_dev, handle); aml_append(root_dev, nvdimm_dev); } From a023c4b2e754b6289fe066f61d2b77ecee871224 Mon Sep 17 00:00:00 2001 From: Robert Hoo Date: Thu, 22 Sep 2022 20:21:55 +0800 Subject: [PATCH 532/705] test/acpi/bios-tables-test: SSDT: update golden master binaries And empty bios-tables-test-allowed-diff.h. Diff of ASL form, from qtest testlog.txt: @@ -1,30 +1,30 @@ /* * Intel ACPI Component Architecture * AML/ASL+ Disassembler version 20180629 (64-bit version) * Copyright (c) 2000 - 2018 Intel Corporation * * Disassembling to symbolic ASL+ operators * - * Disassembly of tests/data/acpi/pc/SSDT.dimmpxm, Thu Sep 22 18:25:06 2022 + * Disassembly of /tmp/aml-YYZZS1, Thu Sep 22 18:25:06 2022 * * Original Table Header: * Signature "SSDT" - * Length 0x000002DE (734) + * Length 0x00000717 (1815) * Revision 0x01 - * Checksum 0x56 + * Checksum 0xBC * OEM ID "BOCHS " * OEM Table ID "NVDIMM" * OEM Revision 0x00000001 (1) * Compiler ID "BXPC" * Compiler Version 0x00000001 (1) */ DefinitionBlock ("", "SSDT", 1, "BOCHS ", "NVDIMM", 0x00000001) { Scope (\_SB) { Device (NVDR) { Name (_HID, "ACPI0012" /* NVDIMM Root Device */) // _HID: Hardware ID Method (NCAL, 5, Serialized) { Local6 = MEMA /* \MEMA */ @@ -49,52 +49,52 @@ ODAT, 32736 } If ((Arg4 == Zero)) { Local0 = ToUUID ("2f10e7a4-9e91-11e4-89d3-123b93f75cba") } ElseIf ((Arg4 == 0x00010000)) { Local0 = ToUUID ("648b9cf2-cda1-4312-8ad9-49c4af32bd62") } Else { Local0 = ToUUID ("4309ac30-0d11-11e4-9191-0800200c9a66") } - If (((Local6 == Zero) | (Arg0 != Local0))) + If (((Local6 == Zero) || (Arg0 != Local0))) { If ((Arg2 == Zero)) { Return (Buffer (One) { 0x00 // . }) } Return (Buffer (One) { 0x01 // . }) } HDLE = Arg4 REVS = Arg1 FUNC = Arg2 - If (((ObjectType (Arg3) == 0x04) & (SizeOf (Arg3) == One))) + If (((ObjectType (Arg3) == 0x04) && (SizeOf (Arg3) == One))) { Local2 = Arg3 [Zero] Local3 = DerefOf (Local2) FARG = Local3 } NTFI = Local6 Local1 = (RLEN - 0x04) If ((Local1 < 0x08)) { Local2 = Zero Name (TBUF, Buffer (One) { 0x00 // . }) Local7 = Buffer (Zero){} @@ -161,45 +161,234 @@ Else { If ((Local1 == Zero)) { Return (Local2) } Local3 += Local1 Concatenate (Local2, Local0, Local2) } } } Device (NV00) { Name (_ADR, One) // _ADR: Address + Method (_LSI, 0, Serialized) // _LSI: Label Storage Information + { + Local0 = NCAL (ToUUID ("4309ac30-0d11-11e4-9191-0800200c9a66"), One, 0x04, Zero, One) + CreateDWordField (Local0, Zero, STTS) + CreateDWordField (Local0, 0x04, SLSA) + CreateDWordField (Local0, 0x08, MAXT) + Local1 = Package (0x03) + { + STTS, + SLSA, + MAXT + } + Return (Local1) + } + + Method (_LSR, 2, Serialized) // _LSR: Label Storage Read + { + Name (INPT, Buffer (0x08) + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // ........ + }) + CreateDWordField (INPT, Zero, OFST) + CreateDWordField (INPT, 0x04, LEN) + OFST = Arg0 + LEN = Arg1 + Local0 = Package (0x01) + { + INPT + } + Local3 = NCAL (ToUUID ("4309ac30-0d11-11e4-9191-0800200c9a66"), One, 0x05, Local0, One) + CreateDWordField (Local3, Zero, STTS) + CreateField (Local3, 0x20, (LEN << 0x03), LDAT) + Name (LSA, Buffer (Zero){}) + ToBuffer (LDAT, LSA) /* \_SB_.NVDR.NV00._LSR.LSA_ */ + Local1 = Package (0x02) + { + STTS, + LSA + } + Return (Local1) + } + + Method (_LSW, 3, Serialized) // _LSW: Label Storage Write + { + Local2 = Arg2 + Name (INPT, Buffer (0x08) + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // ........ + }) + CreateDWordField (INPT, Zero, OFST) + CreateDWordField (INPT, 0x04, TLEN) + OFST = Arg0 + TLEN = Arg1 + Concatenate (INPT, Local2, INPT) /* \_SB_.NVDR.NV00._LSW.INPT */ + Local0 = Package (0x01) + { + INPT + } + Local3 = NCAL (ToUUID ("4309ac30-0d11-11e4-9191-0800200c9a66"), One, 0x06, Local0, One) + CreateDWordField (Local3, Zero, STTS) + Return (STTS) /* \_SB_.NVDR.NV00._LSW.STTS */ + } + (iterates in each NV) Message-Id: <20220922122155.1326543-6-robert.hu@linux.intel.com> Signed-off-by: Robert Hoo Acked-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- tests/data/acpi/pc/SSDT.dimmpxm | Bin 734 -> 1815 bytes tests/data/acpi/q35/SSDT.dimmpxm | Bin 734 -> 1815 bytes tests/data/acpi/virt/SSDT.memhp | Bin 736 -> 1817 bytes tests/qtest/bios-tables-test-allowed-diff.h | 2 -- 4 files changed, 2 deletions(-) diff --git a/tests/data/acpi/pc/SSDT.dimmpxm b/tests/data/acpi/pc/SSDT.dimmpxm index ac55387d57e48adb99eb738a102308688a262fb8..70f133412f5e0aa128ab210245a8de7304eeb843 100644 GIT binary patch literal 1815 zcmdUwyKmD_6vnUPv~g}y6emHgc**|(X$OSF0FILox3Lr1ZmHx-examI3c8|YVC!RO z2@)c;%774ZDvwC)2sTzGCN_pj>?}wOz&%bMqC!xRK#<|wbI(0K`Q7hx6kRVFqX~qV z7sa|%)dh8?Br6KtBZP{x4GGpv_2!(V7cFzGeuJKCoK=-eBcjxh3x)9sl%G1ON@8t< zC}l-#nk#BUt~04IjN>%dLxHlK*k;x!u1QobwmcfE+b^ zczo}A|8-XCzLj4+n|SHk{n4mic$$>>kzKymqe^LJ0ZG7X5M#F6I*C?GzXSG@cDl2fPncQ;69=?`MKx80Oyc z9B;|BU2{zuQ)dbV&Js%+lfN=#)pVIV;6G{kbZ#&Nx-i*)4_an>N&6Rd6+ zI@DnAgic;g(t#T0WVK=NDa_GVIQn#oVA@DG+o@4h6y0>WY85C8xG delta 135 zcmbQvcaN1TIM^lR9uortW7tG4X>Nb5nD}6)_~<4#t%(LAjJ^|Hw{uC>PEKQ(G&v)I zVKOVD5|2#vdc3J@?GX?|$Ee=z7T*O(4YV z6zft|7u04+RusBN2o+}<60Di(?O97NTIOo~7CqNEt16d9M5!Sc3gZ(fKXqD_#M%f^ z%8J-Bm(_+`XHsJr$7!yK3TmZL##~83omGvBESM|j;DD``YGpwyH+7*htx7^g)UGdo zN|-Cz=v1qfRiR!IjpfgY;Ecb32%p25@LlF&|Jg2o|4sIa|8e$(J-8fP@E6j695sA+ z`rzi^byn)Vm0vxdcT{mo#dk$uiW9Fa%IdxhOA>=bwNmt?_2s}66=^{?k z4H4y)gjSJ_Bv-HK1|oB?5aUFHt?j~m6{IAZp&4ZUaMxL(smx^jv*W034ARyPbC zYOr@gCod=IKn-)U+A#PO=IARNeR@zpphT46IJL~$7jHhwsZh{k|A1x4X1tz91v7Lr z=TT|kLF!$N8plxxi>mS%HjtAnjzK5nKsK46WH(ZzNb5nD}6)_~<4#t%(LAjJ^|Hw{uC>PEKQ(G&v)I zVKOVD5|2#vI+-M9YF^Att1yLmNzx{zTx?yqYuZI? z1Th`zLPREImV$f1om*F~+!x#nBDfImne>50v;JW#` zT-LI+*@9B7vNZtYZ#85blhaFcrj|F2HED_ERlzJPg>gx4D7oC^6lAI=YqC@sr`2Lr zY8tDxhEj(yfOwol*-DkF&`dzm=q513*YuK-HM-|8!Iuk_Vpc8AYT43EP0p4i_4?}P zn9)szS+!EEW$Oh=U;PsE&v=VK#WYChIT_VR*;rNZU54?O#}*#pyy{w*piA7 zXziTec5J%7iPv#p6LSE|EgV~SouEbU*@Oq%NMixmb+#X1$Ry2zR*eQI@%%!&1A?mQ z5)(b9mJ~fM)JvKUbRGwaHK@>00XQx-%3(#Qk=3(+wV0t8u$e!$<%K%|1Em|5y<+1% z1kYw_M8HT}BpcE(oKk=xbJb)I7w}>Z1$QUMQKWG#Jnf4fc1-}cpC2UsQEcYiacy_m zu^eMfo~X^{a)K!pR4#LE#H?tFaKL}mD2_yd8)EBP&mvK+qDgENs?sf;rcUshu4}l5 zYdf$rN}M%RiJ;UPx|kpWdx^tO4>tgn2xlb9EHn4STL|Y&D6Fx5z%pWSZqH?c>6(#t znKXEic~@b^2@JwysyxO8&S{E7uoCA;HXUPRHxsn&{2WeajrZYjzKmoJ26_z4(L>At z368!o)c3;C-~zz a!T(E6@c)Su2b|w`f*0^VjQvV}l)nP3li&~l delta 150 zcmbQq_kfivIM^lR0TTlQqx3{BX>LdDnD}6)_~<4Nt%(LAjQ$f{cXCPAPEKQ(G&v)I zVKO_T5|2#vWc Date: Sat, 8 Oct 2022 16:50:27 +0800 Subject: [PATCH 533/705] virtio-crypto: Support asynchronous mode virtio-crypto: Modify the current interface of virtio-crypto device to support asynchronous mode. Signed-off-by: lei he Message-Id: <20221008085030.70212-2-helei.sig11@bytedance.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- backends/cryptodev-builtin.c | 69 +++++-- backends/cryptodev-vhost-user.c | 53 +++-- backends/cryptodev.c | 44 +++-- hw/virtio/virtio-crypto.c | 339 ++++++++++++++++++-------------- include/sysemu/cryptodev.h | 60 ++++-- 5 files changed, 347 insertions(+), 218 deletions(-) diff --git a/backends/cryptodev-builtin.c b/backends/cryptodev-builtin.c index 125cbad1d3..cda6ca3b71 100644 --- a/backends/cryptodev-builtin.c +++ b/backends/cryptodev-builtin.c @@ -355,42 +355,62 @@ static int cryptodev_builtin_create_akcipher_session( return index; } -static int64_t cryptodev_builtin_create_session( +static int cryptodev_builtin_create_session( CryptoDevBackend *backend, CryptoDevBackendSessionInfo *sess_info, - uint32_t queue_index, Error **errp) + uint32_t queue_index, + CryptoDevCompletionFunc cb, + void *opaque) { CryptoDevBackendBuiltin *builtin = CRYPTODEV_BACKEND_BUILTIN(backend); CryptoDevBackendSymSessionInfo *sym_sess_info; CryptoDevBackendAsymSessionInfo *asym_sess_info; + int ret, status; + Error *local_error = NULL; switch (sess_info->op_code) { case VIRTIO_CRYPTO_CIPHER_CREATE_SESSION: sym_sess_info = &sess_info->u.sym_sess_info; - return cryptodev_builtin_create_cipher_session( - builtin, sym_sess_info, errp); + ret = cryptodev_builtin_create_cipher_session( + builtin, sym_sess_info, &local_error); + break; case VIRTIO_CRYPTO_AKCIPHER_CREATE_SESSION: asym_sess_info = &sess_info->u.asym_sess_info; - return cryptodev_builtin_create_akcipher_session( - builtin, asym_sess_info, errp); + ret = cryptodev_builtin_create_akcipher_session( + builtin, asym_sess_info, &local_error); + break; case VIRTIO_CRYPTO_HASH_CREATE_SESSION: case VIRTIO_CRYPTO_MAC_CREATE_SESSION: default: - error_setg(errp, "Unsupported opcode :%" PRIu32 "", + error_setg(&local_error, "Unsupported opcode :%" PRIu32 "", sess_info->op_code); - return -1; + return -VIRTIO_CRYPTO_NOTSUPP; } - return -1; + if (local_error) { + error_report_err(local_error); + } + if (ret < 0) { + status = -VIRTIO_CRYPTO_ERR; + } else { + sess_info->session_id = ret; + status = VIRTIO_CRYPTO_OK; + } + if (cb) { + cb(opaque, status); + } + return 0; } static int cryptodev_builtin_close_session( CryptoDevBackend *backend, uint64_t session_id, - uint32_t queue_index, Error **errp) + uint32_t queue_index, + CryptoDevCompletionFunc cb, + void *opaque) { CryptoDevBackendBuiltin *builtin = CRYPTODEV_BACKEND_BUILTIN(backend); @@ -407,6 +427,9 @@ static int cryptodev_builtin_close_session( g_free(session); builtin->sessions[session_id] = NULL; + if (cb) { + cb(opaque, VIRTIO_CRYPTO_OK); + } return 0; } @@ -506,7 +529,9 @@ static int cryptodev_builtin_asym_operation( static int cryptodev_builtin_operation( CryptoDevBackend *backend, CryptoDevBackendOpInfo *op_info, - uint32_t queue_index, Error **errp) + uint32_t queue_index, + CryptoDevCompletionFunc cb, + void *opaque) { CryptoDevBackendBuiltin *builtin = CRYPTODEV_BACKEND_BUILTIN(backend); @@ -514,11 +539,12 @@ static int cryptodev_builtin_operation( CryptoDevBackendSymOpInfo *sym_op_info; CryptoDevBackendAsymOpInfo *asym_op_info; enum CryptoDevBackendAlgType algtype = op_info->algtype; - int ret = -VIRTIO_CRYPTO_ERR; + int status = -VIRTIO_CRYPTO_ERR; + Error *local_error = NULL; if (op_info->session_id >= MAX_NUM_SESSIONS || builtin->sessions[op_info->session_id] == NULL) { - error_setg(errp, "Cannot find a valid session id: %" PRIu64 "", + error_setg(&local_error, "Cannot find a valid session id: %" PRIu64 "", op_info->session_id); return -VIRTIO_CRYPTO_INVSESS; } @@ -526,14 +552,21 @@ static int cryptodev_builtin_operation( sess = builtin->sessions[op_info->session_id]; if (algtype == CRYPTODEV_BACKEND_ALG_SYM) { sym_op_info = op_info->u.sym_op_info; - ret = cryptodev_builtin_sym_operation(sess, sym_op_info, errp); + status = cryptodev_builtin_sym_operation(sess, sym_op_info, + &local_error); } else if (algtype == CRYPTODEV_BACKEND_ALG_ASYM) { asym_op_info = op_info->u.asym_op_info; - ret = cryptodev_builtin_asym_operation(sess, op_info->op_code, - asym_op_info, errp); + status = cryptodev_builtin_asym_operation(sess, op_info->op_code, + asym_op_info, &local_error); } - return ret; + if (local_error) { + error_report_err(local_error); + } + if (cb) { + cb(opaque, status); + } + return 0; } static void cryptodev_builtin_cleanup( @@ -548,7 +581,7 @@ static void cryptodev_builtin_cleanup( for (i = 0; i < MAX_NUM_SESSIONS; i++) { if (builtin->sessions[i] != NULL) { - cryptodev_builtin_close_session(backend, i, 0, &error_abort); + cryptodev_builtin_close_session(backend, i, 0, NULL, NULL); } } diff --git a/backends/cryptodev-vhost-user.c b/backends/cryptodev-vhost-user.c index f9c5867e38..ab3028e045 100644 --- a/backends/cryptodev-vhost-user.c +++ b/backends/cryptodev-vhost-user.c @@ -259,13 +259,18 @@ static int64_t cryptodev_vhost_user_sym_create_session( return -1; } -static int64_t cryptodev_vhost_user_create_session( +static int cryptodev_vhost_user_create_session( CryptoDevBackend *backend, CryptoDevBackendSessionInfo *sess_info, - uint32_t queue_index, Error **errp) + uint32_t queue_index, + CryptoDevCompletionFunc cb, + void *opaque) { uint32_t op_code = sess_info->op_code; CryptoDevBackendSymSessionInfo *sym_sess_info; + int64_t ret; + Error *local_error = NULL; + int status; switch (op_code) { case VIRTIO_CRYPTO_CIPHER_CREATE_SESSION: @@ -273,27 +278,42 @@ static int64_t cryptodev_vhost_user_create_session( case VIRTIO_CRYPTO_MAC_CREATE_SESSION: case VIRTIO_CRYPTO_AEAD_CREATE_SESSION: sym_sess_info = &sess_info->u.sym_sess_info; - return cryptodev_vhost_user_sym_create_session(backend, sym_sess_info, - queue_index, errp); - default: - error_setg(errp, "Unsupported opcode :%" PRIu32 "", - sess_info->op_code); - return -1; + ret = cryptodev_vhost_user_sym_create_session(backend, sym_sess_info, + queue_index, &local_error); + break; + default: + error_setg(&local_error, "Unsupported opcode :%" PRIu32 "", + sess_info->op_code); + return -VIRTIO_CRYPTO_NOTSUPP; } - return -1; + if (local_error) { + error_report_err(local_error); + } + if (ret < 0) { + status = -VIRTIO_CRYPTO_ERR; + } else { + sess_info->session_id = ret; + status = VIRTIO_CRYPTO_OK; + } + if (cb) { + cb(opaque, status); + } + return 0; } static int cryptodev_vhost_user_close_session( CryptoDevBackend *backend, uint64_t session_id, - uint32_t queue_index, Error **errp) + uint32_t queue_index, + CryptoDevCompletionFunc cb, + void *opaque) { CryptoDevBackendClient *cc = backend->conf.peers.ccs[queue_index]; CryptoDevBackendVhost *vhost_crypto; - int ret; + int ret = -1, status; vhost_crypto = cryptodev_vhost_user_get_vhost(cc, backend, queue_index); if (vhost_crypto) { @@ -301,12 +321,17 @@ static int cryptodev_vhost_user_close_session( ret = dev->vhost_ops->vhost_crypto_close_session(dev, session_id); if (ret < 0) { - return -1; + status = -VIRTIO_CRYPTO_ERR; } else { - return 0; + status = VIRTIO_CRYPTO_OK; } + } else { + status = -VIRTIO_CRYPTO_NOTSUPP; } - return -1; + if (cb) { + cb(opaque, status); + } + return 0; } static void cryptodev_vhost_user_cleanup( diff --git a/backends/cryptodev.c b/backends/cryptodev.c index 33eb4e1a70..54ee8c81f5 100644 --- a/backends/cryptodev.c +++ b/backends/cryptodev.c @@ -26,6 +26,7 @@ #include "qapi/error.h" #include "qapi/visitor.h" #include "qemu/config-file.h" +#include "qemu/error-report.h" #include "qom/object_interfaces.h" #include "hw/virtio/virtio-crypto.h" @@ -72,69 +73,72 @@ void cryptodev_backend_cleanup( } } -int64_t cryptodev_backend_create_session( +int cryptodev_backend_create_session( CryptoDevBackend *backend, CryptoDevBackendSessionInfo *sess_info, - uint32_t queue_index, Error **errp) + uint32_t queue_index, + CryptoDevCompletionFunc cb, + void *opaque) { CryptoDevBackendClass *bc = CRYPTODEV_BACKEND_GET_CLASS(backend); if (bc->create_session) { - return bc->create_session(backend, sess_info, queue_index, errp); + return bc->create_session(backend, sess_info, queue_index, cb, opaque); } - - return -1; + return -VIRTIO_CRYPTO_NOTSUPP; } int cryptodev_backend_close_session( CryptoDevBackend *backend, uint64_t session_id, - uint32_t queue_index, Error **errp) + uint32_t queue_index, + CryptoDevCompletionFunc cb, + void *opaque) { CryptoDevBackendClass *bc = CRYPTODEV_BACKEND_GET_CLASS(backend); if (bc->close_session) { - return bc->close_session(backend, session_id, queue_index, errp); + return bc->close_session(backend, session_id, queue_index, cb, opaque); } - - return -1; + return -VIRTIO_CRYPTO_NOTSUPP; } static int cryptodev_backend_operation( CryptoDevBackend *backend, CryptoDevBackendOpInfo *op_info, - uint32_t queue_index, Error **errp) + uint32_t queue_index, + CryptoDevCompletionFunc cb, + void *opaque) { CryptoDevBackendClass *bc = CRYPTODEV_BACKEND_GET_CLASS(backend); if (bc->do_op) { - return bc->do_op(backend, op_info, queue_index, errp); + return bc->do_op(backend, op_info, queue_index, cb, opaque); } - - return -VIRTIO_CRYPTO_ERR; + return -VIRTIO_CRYPTO_NOTSUPP; } int cryptodev_backend_crypto_operation( CryptoDevBackend *backend, - void *opaque, - uint32_t queue_index, Error **errp) + void *opaque1, + uint32_t queue_index, + CryptoDevCompletionFunc cb, void *opaque2) { - VirtIOCryptoReq *req = opaque; + VirtIOCryptoReq *req = opaque1; CryptoDevBackendOpInfo *op_info = &req->op_info; enum CryptoDevBackendAlgType algtype = req->flags; if ((algtype != CRYPTODEV_BACKEND_ALG_SYM) && (algtype != CRYPTODEV_BACKEND_ALG_ASYM)) { - error_setg(errp, "Unsupported cryptodev alg type: %" PRIu32 "", - algtype); - + error_report("Unsupported cryptodev alg type: %" PRIu32 "", algtype); return -VIRTIO_CRYPTO_NOTSUPP; } - return cryptodev_backend_operation(backend, op_info, queue_index, errp); + return cryptodev_backend_operation(backend, op_info, queue_index, + cb, opaque2); } static void diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c index df4bde210b..97da74e719 100644 --- a/hw/virtio/virtio-crypto.c +++ b/hw/virtio/virtio-crypto.c @@ -27,6 +27,39 @@ #define VIRTIO_CRYPTO_VM_VERSION 1 +typedef struct VirtIOCryptoSessionReq { + VirtIODevice *vdev; + VirtQueue *vq; + VirtQueueElement *elem; + CryptoDevBackendSessionInfo info; + CryptoDevCompletionFunc cb; +} VirtIOCryptoSessionReq; + +static void virtio_crypto_free_create_session_req(VirtIOCryptoSessionReq *sreq) +{ + switch (sreq->info.op_code) { + case VIRTIO_CRYPTO_CIPHER_CREATE_SESSION: + g_free(sreq->info.u.sym_sess_info.cipher_key); + g_free(sreq->info.u.sym_sess_info.auth_key); + break; + + case VIRTIO_CRYPTO_AKCIPHER_CREATE_SESSION: + g_free(sreq->info.u.asym_sess_info.key); + break; + + case VIRTIO_CRYPTO_CIPHER_DESTROY_SESSION: + case VIRTIO_CRYPTO_HASH_DESTROY_SESSION: + case VIRTIO_CRYPTO_MAC_DESTROY_SESSION: + case VIRTIO_CRYPTO_AEAD_DESTROY_SESSION: + case VIRTIO_CRYPTO_AKCIPHER_DESTROY_SESSION: + break; + + default: + error_report("Unknown opcode: %u", sreq->info.op_code); + } + g_free(sreq); +} + /* * Transfer virtqueue index to crypto queue index. * The control virtqueue is after the data virtqueues @@ -75,27 +108,24 @@ virtio_crypto_cipher_session_helper(VirtIODevice *vdev, return 0; } -static int64_t +static int virtio_crypto_create_sym_session(VirtIOCrypto *vcrypto, struct virtio_crypto_sym_create_session_req *sess_req, uint32_t queue_id, uint32_t opcode, - struct iovec *iov, unsigned int out_num) + struct iovec *iov, unsigned int out_num, + VirtIOCryptoSessionReq *sreq) { VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto); - CryptoDevBackendSessionInfo info; - CryptoDevBackendSymSessionInfo *sym_info; - int64_t session_id; + CryptoDevBackendSymSessionInfo *sym_info = &sreq->info.u.sym_sess_info; int queue_index; uint32_t op_type; - Error *local_err = NULL; int ret; - memset(&info, 0, sizeof(info)); op_type = ldl_le_p(&sess_req->op_type); - info.op_code = opcode; + sreq->info.op_code = opcode; - sym_info = &info.u.sym_sess_info; + sym_info = &sreq->info.u.sym_sess_info; sym_info->op_type = op_type; if (op_type == VIRTIO_CRYPTO_SYM_OP_CIPHER) { @@ -103,7 +133,7 @@ virtio_crypto_create_sym_session(VirtIOCrypto *vcrypto, &sess_req->u.cipher.para, &iov, &out_num); if (ret < 0) { - goto err; + return ret; } } else if (op_type == VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING) { size_t s; @@ -112,7 +142,7 @@ virtio_crypto_create_sym_session(VirtIOCrypto *vcrypto, &sess_req->u.chain.para.cipher_param, &iov, &out_num); if (ret < 0) { - goto err; + return ret; } /* hash part */ sym_info->alg_chain_order = ldl_le_p( @@ -129,8 +159,7 @@ virtio_crypto_create_sym_session(VirtIOCrypto *vcrypto, if (sym_info->auth_key_len > vcrypto->conf.max_auth_key_len) { error_report("virtio-crypto length of auth key is too big: %u", sym_info->auth_key_len); - ret = -VIRTIO_CRYPTO_ERR; - goto err; + return -VIRTIO_CRYPTO_ERR; } /* get auth key */ if (sym_info->auth_key_len > 0) { @@ -140,8 +169,7 @@ virtio_crypto_create_sym_session(VirtIOCrypto *vcrypto, if (unlikely(s != sym_info->auth_key_len)) { virtio_error(vdev, "virtio-crypto authenticated key incorrect"); - ret = -EFAULT; - goto err; + return -EFAULT; } iov_discard_front(&iov, &out_num, sym_info->auth_key_len); } @@ -153,49 +181,30 @@ virtio_crypto_create_sym_session(VirtIOCrypto *vcrypto, } else { /* VIRTIO_CRYPTO_SYM_HASH_MODE_NESTED */ error_report("unsupported hash mode"); - ret = -VIRTIO_CRYPTO_NOTSUPP; - goto err; + return -VIRTIO_CRYPTO_NOTSUPP; } } else { /* VIRTIO_CRYPTO_SYM_OP_NONE */ error_report("unsupported cipher op_type: VIRTIO_CRYPTO_SYM_OP_NONE"); - ret = -VIRTIO_CRYPTO_NOTSUPP; - goto err; + return -VIRTIO_CRYPTO_NOTSUPP; } queue_index = virtio_crypto_vq2q(queue_id); - session_id = cryptodev_backend_create_session( - vcrypto->cryptodev, - &info, queue_index, &local_err); - if (session_id >= 0) { - ret = session_id; - } else { - if (local_err) { - error_report_err(local_err); - } - ret = -VIRTIO_CRYPTO_ERR; - } - -err: - g_free(sym_info->cipher_key); - g_free(sym_info->auth_key); - return ret; + return cryptodev_backend_create_session(vcrypto->cryptodev, &sreq->info, + queue_index, sreq->cb, sreq); } -static int64_t +static int virtio_crypto_create_asym_session(VirtIOCrypto *vcrypto, struct virtio_crypto_akcipher_create_session_req *sess_req, uint32_t queue_id, uint32_t opcode, - struct iovec *iov, unsigned int out_num) + struct iovec *iov, unsigned int out_num, + VirtIOCryptoSessionReq *sreq) { VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto); - CryptoDevBackendSessionInfo info = {0}; - CryptoDevBackendAsymSessionInfo *asym_info; - int64_t session_id; + CryptoDevBackendAsymSessionInfo *asym_info = &sreq->info.u.asym_sess_info; int queue_index; uint32_t algo, keytype, keylen; - g_autofree uint8_t *key = NULL; - Error *local_err = NULL; algo = ldl_le_p(&sess_req->para.algo); keytype = ldl_le_p(&sess_req->para.keytype); @@ -208,20 +217,19 @@ virtio_crypto_create_asym_session(VirtIOCrypto *vcrypto, } if (keylen) { - key = g_malloc(keylen); - if (iov_to_buf(iov, out_num, 0, key, keylen) != keylen) { + asym_info->key = g_malloc(keylen); + if (iov_to_buf(iov, out_num, 0, asym_info->key, keylen) != keylen) { virtio_error(vdev, "virtio-crypto asym key incorrect"); return -EFAULT; } iov_discard_front(&iov, &out_num, keylen); } - info.op_code = opcode; - asym_info = &info.u.asym_sess_info; + sreq->info.op_code = opcode; + asym_info = &sreq->info.u.asym_sess_info; asym_info->algo = algo; asym_info->keytype = keytype; asym_info->keylen = keylen; - asym_info->key = key; switch (asym_info->algo) { case VIRTIO_CRYPTO_AKCIPHER_RSA: asym_info->u.rsa.padding_algo = @@ -237,45 +245,95 @@ virtio_crypto_create_asym_session(VirtIOCrypto *vcrypto, } queue_index = virtio_crypto_vq2q(queue_id); - session_id = cryptodev_backend_create_session(vcrypto->cryptodev, &info, - queue_index, &local_err); - if (session_id < 0) { - if (local_err) { - error_report_err(local_err); - } - return -VIRTIO_CRYPTO_ERR; - } - - return session_id; + return cryptodev_backend_create_session(vcrypto->cryptodev, &sreq->info, + queue_index, sreq->cb, sreq); } -static uint8_t +static int virtio_crypto_handle_close_session(VirtIOCrypto *vcrypto, struct virtio_crypto_destroy_session_req *close_sess_req, - uint32_t queue_id) + uint32_t queue_id, + VirtIOCryptoSessionReq *sreq) { - int ret; uint64_t session_id; - uint32_t status; - Error *local_err = NULL; session_id = ldq_le_p(&close_sess_req->session_id); DPRINTF("close session, id=%" PRIu64 "\n", session_id); - ret = cryptodev_backend_close_session( - vcrypto->cryptodev, session_id, queue_id, &local_err); - if (ret == 0) { - status = VIRTIO_CRYPTO_OK; + return cryptodev_backend_close_session( + vcrypto->cryptodev, session_id, queue_id, sreq->cb, sreq); +} + +static void virtio_crypto_create_session_completion(void *opaque, int ret) +{ + VirtIOCryptoSessionReq *sreq = (VirtIOCryptoSessionReq *)opaque; + VirtQueue *vq = sreq->vq; + VirtQueueElement *elem = sreq->elem; + VirtIODevice *vdev = sreq->vdev; + struct virtio_crypto_session_input input; + struct iovec *in_iov = elem->in_sg; + unsigned in_num = elem->in_num; + size_t s; + + memset(&input, 0, sizeof(input)); + /* Serious errors, need to reset virtio crypto device */ + if (ret == -EFAULT) { + virtqueue_detach_element(vq, elem, 0); + goto out; + } else if (ret == -VIRTIO_CRYPTO_NOTSUPP) { + stl_le_p(&input.status, VIRTIO_CRYPTO_NOTSUPP); + } else if (ret == -VIRTIO_CRYPTO_KEY_REJECTED) { + stl_le_p(&input.status, VIRTIO_CRYPTO_KEY_REJECTED); + } else if (ret != VIRTIO_CRYPTO_OK) { + stl_le_p(&input.status, VIRTIO_CRYPTO_ERR); } else { - if (local_err) { - error_report_err(local_err); - } else { - error_report("destroy session failed"); - } - status = VIRTIO_CRYPTO_ERR; + /* Set the session id */ + stq_le_p(&input.session_id, sreq->info.session_id); + stl_le_p(&input.status, VIRTIO_CRYPTO_OK); } - return status; + s = iov_from_buf(in_iov, in_num, 0, &input, sizeof(input)); + if (unlikely(s != sizeof(input))) { + virtio_error(vdev, "virtio-crypto input incorrect"); + virtqueue_detach_element(vq, elem, 0); + goto out; + } + virtqueue_push(vq, elem, sizeof(input)); + virtio_notify(vdev, vq); + +out: + g_free(elem); + virtio_crypto_free_create_session_req(sreq); +} + +static void virtio_crypto_destroy_session_completion(void *opaque, int ret) +{ + VirtIOCryptoSessionReq *sreq = (VirtIOCryptoSessionReq *)opaque; + VirtQueue *vq = sreq->vq; + VirtQueueElement *elem = sreq->elem; + VirtIODevice *vdev = sreq->vdev; + struct iovec *in_iov = elem->in_sg; + unsigned in_num = elem->in_num; + uint8_t status; + size_t s; + + if (ret < 0) { + status = VIRTIO_CRYPTO_ERR; + } else { + status = VIRTIO_CRYPTO_OK; + } + s = iov_from_buf(in_iov, in_num, 0, &status, sizeof(status)); + if (unlikely(s != sizeof(status))) { + virtio_error(vdev, "virtio-crypto status incorrect"); + virtqueue_detach_element(vq, elem, 0); + goto out; + } + virtqueue_push(vq, elem, sizeof(status)); + virtio_notify(vdev, vq); + +out: + g_free(elem); + g_free(sreq); } static void virtio_crypto_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq) @@ -283,16 +341,16 @@ static void virtio_crypto_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq) VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev); struct virtio_crypto_op_ctrl_req ctrl; VirtQueueElement *elem; - struct iovec *in_iov; - struct iovec *out_iov; - unsigned in_num; + VirtIOCryptoSessionReq *sreq; unsigned out_num; + unsigned in_num; uint32_t queue_id; uint32_t opcode; struct virtio_crypto_session_input input; - int64_t session_id; - uint8_t status; size_t s; + int ret; + struct iovec *out_iov; + struct iovec *in_iov; for (;;) { g_autofree struct iovec *out_iov_copy = NULL; @@ -327,44 +385,34 @@ static void virtio_crypto_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq) opcode = ldl_le_p(&ctrl.header.opcode); queue_id = ldl_le_p(&ctrl.header.queue_id); - memset(&input, 0, sizeof(input)); + sreq = g_new0(VirtIOCryptoSessionReq, 1); + sreq->vdev = vdev; + sreq->vq = vq; + sreq->elem = elem; + switch (opcode) { case VIRTIO_CRYPTO_CIPHER_CREATE_SESSION: - session_id = virtio_crypto_create_sym_session(vcrypto, - &ctrl.u.sym_create_session, - queue_id, opcode, - out_iov, out_num); - goto check_session; + sreq->cb = virtio_crypto_create_session_completion; + ret = virtio_crypto_create_sym_session(vcrypto, + &ctrl.u.sym_create_session, + queue_id, opcode, + out_iov, out_num, + sreq); + if (ret < 0) { + virtio_crypto_create_session_completion(sreq, ret); + } + break; case VIRTIO_CRYPTO_AKCIPHER_CREATE_SESSION: - session_id = virtio_crypto_create_asym_session(vcrypto, + sreq->cb = virtio_crypto_create_session_completion; + ret = virtio_crypto_create_asym_session(vcrypto, &ctrl.u.akcipher_create_session, queue_id, opcode, - out_iov, out_num); - -check_session: - /* Serious errors, need to reset virtio crypto device */ - if (session_id == -EFAULT) { - virtqueue_detach_element(vq, elem, 0); - break; - } else if (session_id == -VIRTIO_CRYPTO_NOTSUPP) { - stl_le_p(&input.status, VIRTIO_CRYPTO_NOTSUPP); - } else if (session_id == -VIRTIO_CRYPTO_ERR) { - stl_le_p(&input.status, VIRTIO_CRYPTO_ERR); - } else { - /* Set the session id */ - stq_le_p(&input.session_id, session_id); - stl_le_p(&input.status, VIRTIO_CRYPTO_OK); + out_iov, out_num, + sreq); + if (ret < 0) { + virtio_crypto_create_session_completion(sreq, ret); } - - s = iov_from_buf(in_iov, in_num, 0, &input, sizeof(input)); - if (unlikely(s != sizeof(input))) { - virtio_error(vdev, "virtio-crypto input incorrect"); - virtqueue_detach_element(vq, elem, 0); - break; - } - virtqueue_push(vq, elem, sizeof(input)); - virtio_notify(vdev, vq); break; case VIRTIO_CRYPTO_CIPHER_DESTROY_SESSION: @@ -372,37 +420,36 @@ check_session: case VIRTIO_CRYPTO_MAC_DESTROY_SESSION: case VIRTIO_CRYPTO_AEAD_DESTROY_SESSION: case VIRTIO_CRYPTO_AKCIPHER_DESTROY_SESSION: - status = virtio_crypto_handle_close_session(vcrypto, - &ctrl.u.destroy_session, queue_id); - /* The status only occupy one byte, we can directly use it */ - s = iov_from_buf(in_iov, in_num, 0, &status, sizeof(status)); - if (unlikely(s != sizeof(status))) { - virtio_error(vdev, "virtio-crypto status incorrect"); - virtqueue_detach_element(vq, elem, 0); - break; + sreq->cb = virtio_crypto_destroy_session_completion; + ret = virtio_crypto_handle_close_session(vcrypto, + &ctrl.u.destroy_session, queue_id, + sreq); + if (ret < 0) { + virtio_crypto_destroy_session_completion(sreq, ret); } - virtqueue_push(vq, elem, sizeof(status)); - virtio_notify(vdev, vq); break; + case VIRTIO_CRYPTO_HASH_CREATE_SESSION: case VIRTIO_CRYPTO_MAC_CREATE_SESSION: case VIRTIO_CRYPTO_AEAD_CREATE_SESSION: default: + memset(&input, 0, sizeof(input)); error_report("virtio-crypto unsupported ctrl opcode: %d", opcode); stl_le_p(&input.status, VIRTIO_CRYPTO_NOTSUPP); s = iov_from_buf(in_iov, in_num, 0, &input, sizeof(input)); if (unlikely(s != sizeof(input))) { virtio_error(vdev, "virtio-crypto input incorrect"); virtqueue_detach_element(vq, elem, 0); - break; + } else { + virtqueue_push(vq, elem, sizeof(input)); + virtio_notify(vdev, vq); } - virtqueue_push(vq, elem, sizeof(input)); - virtio_notify(vdev, vq); + g_free(sreq); + g_free(elem); break; } /* end switch case */ - g_free(elem); } /* end for loop */ } @@ -448,6 +495,7 @@ static void virtio_crypto_free_request(VirtIOCryptoReq *req) } } + g_free(req->in_iov); g_free(req); } @@ -458,6 +506,7 @@ virtio_crypto_sym_input_data_helper(VirtIODevice *vdev, CryptoDevBackendSymOpInfo *sym_op_info) { size_t s, len; + struct iovec *in_iov = req->in_iov; if (status != VIRTIO_CRYPTO_OK) { return; @@ -465,18 +514,18 @@ virtio_crypto_sym_input_data_helper(VirtIODevice *vdev, len = sym_op_info->src_len; /* Save the cipher result */ - s = iov_from_buf(req->in_iov, req->in_num, 0, sym_op_info->dst, len); + s = iov_from_buf(in_iov, req->in_num, 0, sym_op_info->dst, len); if (s != len) { virtio_error(vdev, "virtio-crypto dest data incorrect"); return; } - iov_discard_front(&req->in_iov, &req->in_num, len); + iov_discard_front(&in_iov, &req->in_num, len); if (sym_op_info->op_type == VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING) { /* Save the digest result */ - s = iov_from_buf(req->in_iov, req->in_num, 0, + s = iov_from_buf(in_iov, req->in_num, 0, sym_op_info->digest_result, sym_op_info->digest_result_len); if (s != sym_op_info->digest_result_len) { @@ -491,6 +540,7 @@ virtio_crypto_akcipher_input_data_helper(VirtIODevice *vdev, CryptoDevBackendAsymOpInfo *asym_op_info) { size_t s, len; + struct iovec *in_iov = req->in_iov; if (status != VIRTIO_CRYPTO_OK) { return; @@ -501,23 +551,24 @@ virtio_crypto_akcipher_input_data_helper(VirtIODevice *vdev, return; } - s = iov_from_buf(req->in_iov, req->in_num, 0, asym_op_info->dst, len); + s = iov_from_buf(in_iov, req->in_num, 0, asym_op_info->dst, len); if (s != len) { virtio_error(vdev, "virtio-crypto asym dest data incorrect"); return; } - iov_discard_front(&req->in_iov, &req->in_num, len); + iov_discard_front(&in_iov, &req->in_num, len); /* For akcipher, dst_len may be changed after operation */ req->in_len = sizeof(struct virtio_crypto_inhdr) + asym_op_info->dst_len; } - -static void virtio_crypto_req_complete(VirtIOCryptoReq *req, uint8_t status) +static void virtio_crypto_req_complete(void *opaque, int ret) { + VirtIOCryptoReq *req = (VirtIOCryptoReq *)opaque; VirtIOCrypto *vcrypto = req->vcrypto; VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto); + uint8_t status = -ret; if (req->flags == CRYPTODEV_BACKEND_ALG_SYM) { virtio_crypto_sym_input_data_helper(vdev, req, status, @@ -529,6 +580,7 @@ static void virtio_crypto_req_complete(VirtIOCryptoReq *req, uint8_t status) stb_p(&req->in->status, status); virtqueue_push(req->vq, &req->elem, req->in_len); virtio_notify(vdev, req->vq); + virtio_crypto_free_request(req); } static VirtIOCryptoReq * @@ -773,9 +825,7 @@ virtio_crypto_handle_request(VirtIOCryptoReq *request) unsigned in_num; unsigned out_num; uint32_t opcode; - uint8_t status = VIRTIO_CRYPTO_ERR; CryptoDevBackendOpInfo *op_info = &request->op_info; - Error *local_err = NULL; if (elem->out_num < 1 || elem->in_num < 1) { virtio_error(vdev, "virtio-crypto dataq missing headers"); @@ -815,6 +865,8 @@ virtio_crypto_handle_request(VirtIOCryptoReq *request) */ request->in_num = in_num; request->in_iov = in_iov; + /* now, we free the in_iov_copy inside virtio_crypto_free_request */ + in_iov_copy = NULL; opcode = ldl_le_p(&req.header.opcode); op_info->session_id = ldq_le_p(&req.header.session_id); @@ -843,23 +895,15 @@ check_result: if (ret == -EFAULT) { return -1; } else if (ret == -VIRTIO_CRYPTO_NOTSUPP) { - virtio_crypto_req_complete(request, VIRTIO_CRYPTO_NOTSUPP); - virtio_crypto_free_request(request); + virtio_crypto_req_complete(request, -VIRTIO_CRYPTO_NOTSUPP); } else { - - /* Set request's parameter */ ret = cryptodev_backend_crypto_operation(vcrypto->cryptodev, - request, queue_index, &local_err); + request, queue_index, + virtio_crypto_req_complete, + request); if (ret < 0) { - status = -ret; - if (local_err) { - error_report_err(local_err); - } - } else { /* ret == VIRTIO_CRYPTO_OK */ - status = ret; + virtio_crypto_req_complete(request, ret); } - virtio_crypto_req_complete(request, status); - virtio_crypto_free_request(request); } break; @@ -870,8 +914,7 @@ check_result: default: error_report("virtio-crypto unsupported dataq opcode: %u", opcode); - virtio_crypto_req_complete(request, VIRTIO_CRYPTO_NOTSUPP); - virtio_crypto_free_request(request); + virtio_crypto_req_complete(request, -VIRTIO_CRYPTO_NOTSUPP); } return 0; @@ -1011,7 +1054,7 @@ static void virtio_crypto_device_realize(DeviceState *dev, Error **errp) vcrypto->vqs[i].vcrypto = vcrypto; } - vcrypto->ctrl_vq = virtio_add_queue(vdev, 64, virtio_crypto_handle_ctrl); + vcrypto->ctrl_vq = virtio_add_queue(vdev, 1024, virtio_crypto_handle_ctrl); if (!cryptodev_backend_is_ready(vcrypto->cryptodev)) { vcrypto->status &= ~VIRTIO_CRYPTO_S_HW_READY; } else { diff --git a/include/sysemu/cryptodev.h b/include/sysemu/cryptodev.h index 37c3a360fd..32e9f4cf8a 100644 --- a/include/sysemu/cryptodev.h +++ b/include/sysemu/cryptodev.h @@ -113,6 +113,7 @@ typedef struct CryptoDevBackendSessionInfo { CryptoDevBackendSymSessionInfo sym_sess_info; CryptoDevBackendAsymSessionInfo asym_sess_info; } u; + uint64_t session_id; } CryptoDevBackendSessionInfo; /** @@ -188,21 +189,30 @@ typedef struct CryptoDevBackendOpInfo { } u; } CryptoDevBackendOpInfo; +typedef void (*CryptoDevCompletionFunc) (void *opaque, int ret); struct CryptoDevBackendClass { ObjectClass parent_class; void (*init)(CryptoDevBackend *backend, Error **errp); void (*cleanup)(CryptoDevBackend *backend, Error **errp); - int64_t (*create_session)(CryptoDevBackend *backend, - CryptoDevBackendSessionInfo *sess_info, - uint32_t queue_index, Error **errp); + int (*create_session)(CryptoDevBackend *backend, + CryptoDevBackendSessionInfo *sess_info, + uint32_t queue_index, + CryptoDevCompletionFunc cb, + void *opaque); + int (*close_session)(CryptoDevBackend *backend, - uint64_t session_id, - uint32_t queue_index, Error **errp); + uint64_t session_id, + uint32_t queue_index, + CryptoDevCompletionFunc cb, + void *opaque); + int (*do_op)(CryptoDevBackend *backend, - CryptoDevBackendOpInfo *op_info, - uint32_t queue_index, Error **errp); + CryptoDevBackendOpInfo *op_info, + uint32_t queue_index, + CryptoDevCompletionFunc cb, + void *opaque); }; typedef enum CryptoDevBackendOptionsType { @@ -303,15 +313,20 @@ void cryptodev_backend_cleanup( * @sess_info: parameters needed by session creating * @queue_index: queue index of cryptodev backend client * @errp: pointer to a NULL-initialized error object + * @cb: callback when session create is compeleted + * @opaque: parameter passed to callback * - * Create a session for symmetric/symmetric algorithms + * Create a session for symmetric/asymmetric algorithms * - * Returns: session id on success, or -1 on error + * Returns: 0 for success and cb will be called when creation is completed, + * negative value for error, and cb will not be called. */ -int64_t cryptodev_backend_create_session( +int cryptodev_backend_create_session( CryptoDevBackend *backend, CryptoDevBackendSessionInfo *sess_info, - uint32_t queue_index, Error **errp); + uint32_t queue_index, + CryptoDevCompletionFunc cb, + void *opaque); /** * cryptodev_backend_close_session: @@ -319,34 +334,43 @@ int64_t cryptodev_backend_create_session( * @session_id: the session id * @queue_index: queue index of cryptodev backend client * @errp: pointer to a NULL-initialized error object + * @cb: callback when session create is compeleted + * @opaque: parameter passed to callback * * Close a session for which was previously * created by cryptodev_backend_create_session() * - * Returns: 0 on success, or Negative on error + * Returns: 0 for success and cb will be called when creation is completed, + * negative value for error, and cb will not be called. */ int cryptodev_backend_close_session( CryptoDevBackend *backend, uint64_t session_id, - uint32_t queue_index, Error **errp); + uint32_t queue_index, + CryptoDevCompletionFunc cb, + void *opaque); /** * cryptodev_backend_crypto_operation: * @backend: the cryptodev backend object - * @opaque: pointer to a VirtIOCryptoReq object + * @opaque1: pointer to a VirtIOCryptoReq object * @queue_index: queue index of cryptodev backend client * @errp: pointer to a NULL-initialized error object + * @cb: callbacks when operation is completed + * @opaque2: parameter passed to cb * * Do crypto operation, such as encryption and * decryption * - * Returns: VIRTIO_CRYPTO_OK on success, - * or -VIRTIO_CRYPTO_* on error + * Returns: 0 for success and cb will be called when creation is completed, + * negative value for error, and cb will not be called. */ int cryptodev_backend_crypto_operation( CryptoDevBackend *backend, - void *opaque, - uint32_t queue_index, Error **errp); + void *opaque1, + uint32_t queue_index, + CryptoDevCompletionFunc cb, + void *opaque2); /** * cryptodev_backend_set_used: From 3b34ccad6695f3fd3e48555d895d450f750c00e6 Mon Sep 17 00:00:00 2001 From: Lei He Date: Sat, 8 Oct 2022 16:50:28 +0800 Subject: [PATCH 534/705] crypto: Support DER encodings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add encoding interfaces for DER encoding: 1. support decoding of 'bit string', 'octet string', 'object id' and 'context specific tag' for DER encoder. 2. implemented a simple DER encoder. 3. add more testsuits for DER encoder. Signed-off-by: lei he Message-Id: <20221008085030.70212-3-helei.sig11@bytedance.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Daniel P. Berrangé --- crypto/der.c | 313 ++++++++++++++++++++++++++++++++--- crypto/der.h | 211 ++++++++++++++++++++++- tests/unit/test-crypto-der.c | 126 +++++++++++--- 3 files changed, 600 insertions(+), 50 deletions(-) diff --git a/crypto/der.c b/crypto/der.c index f877390bbb..dab3fe4f24 100644 --- a/crypto/der.c +++ b/crypto/der.c @@ -22,20 +22,93 @@ #include "qemu/osdep.h" #include "crypto/der.h" +typedef struct QCryptoDerEncodeNode { + uint8_t tag; + struct QCryptoDerEncodeNode *parent; + struct QCryptoDerEncodeNode *next; + /* for constructed type, data is null */ + const uint8_t *data; + size_t dlen; +} QCryptoDerEncodeNode; + +typedef struct QCryptoEncodeContext { + QCryptoDerEncodeNode root; + QCryptoDerEncodeNode *current_parent; + QCryptoDerEncodeNode *tail; +} QCryptoEncodeContext; + enum QCryptoDERTypeTag { QCRYPTO_DER_TYPE_TAG_BOOL = 0x1, QCRYPTO_DER_TYPE_TAG_INT = 0x2, QCRYPTO_DER_TYPE_TAG_BIT_STR = 0x3, QCRYPTO_DER_TYPE_TAG_OCT_STR = 0x4, - QCRYPTO_DER_TYPE_TAG_OCT_NULL = 0x5, - QCRYPTO_DER_TYPE_TAG_OCT_OID = 0x6, + QCRYPTO_DER_TYPE_TAG_NULL = 0x5, + QCRYPTO_DER_TYPE_TAG_OID = 0x6, QCRYPTO_DER_TYPE_TAG_SEQ = 0x10, QCRYPTO_DER_TYPE_TAG_SET = 0x11, }; -#define QCRYPTO_DER_CONSTRUCTED_MASK 0x20 +enum QCryptoDERTagClass { + QCRYPTO_DER_TAG_CLASS_UNIV = 0x0, + QCRYPTO_DER_TAG_CLASS_APPL = 0x1, + QCRYPTO_DER_TAG_CLASS_CONT = 0x2, + QCRYPTO_DER_TAG_CLASS_PRIV = 0x3, +}; + +enum QCryptoDERTagEnc { + QCRYPTO_DER_TAG_ENC_PRIM = 0x0, + QCRYPTO_DER_TAG_ENC_CONS = 0x1, +}; + +#define QCRYPTO_DER_TAG_ENC_MASK 0x20 +#define QCRYPTO_DER_TAG_ENC_SHIFT 5 + +#define QCRYPTO_DER_TAG_CLASS_MASK 0xc0 +#define QCRYPTO_DER_TAG_CLASS_SHIFT 6 + +#define QCRYPTO_DER_TAG_VAL_MASK 0x1f #define QCRYPTO_DER_SHORT_LEN_MASK 0x80 +#define QCRYPTO_DER_TAG(class, enc, val) \ + (((class) << QCRYPTO_DER_TAG_CLASS_SHIFT) | \ + ((enc) << QCRYPTO_DER_TAG_ENC_SHIFT) | (val)) + +/** + * qcrypto_der_encode_length: + * @src_len: the length of source data + * @dst: distination to save the encoded 'length', if dst is NULL, only compute + * the expected buffer size in bytes. + * @dst_len: output parameter, indicates how many bytes wrote. + * + * Encode the 'length' part of TLV tuple. + */ +static void qcrypto_der_encode_length(size_t src_len, + uint8_t *dst, size_t *dst_len) +{ + size_t max_length = 0xFF; + uint8_t length_bytes = 0, header_byte; + + if (src_len < QCRYPTO_DER_SHORT_LEN_MASK) { + header_byte = src_len; + *dst_len = 1; + } else { + for (length_bytes = 1; max_length < src_len; length_bytes++) { + max_length = (max_length << 8) + max_length; + } + header_byte = length_bytes; + header_byte |= QCRYPTO_DER_SHORT_LEN_MASK; + *dst_len = length_bytes + 1; + } + if (!dst) { + return; + } + *dst++ = header_byte; + /* Bigendian length bytes */ + for (; length_bytes > 0; length_bytes--) { + *dst++ = ((src_len >> (length_bytes - 1) * 8) & 0xFF); + } +} + static uint8_t qcrypto_der_peek_byte(const uint8_t **data, size_t *dlen) { return **data; @@ -150,40 +223,230 @@ static int qcrypto_der_extract_data(const uint8_t **data, size_t *dlen, return qcrypto_der_extract_definite_data(data, dlen, cb, ctx, errp); } -int qcrypto_der_decode_int(const uint8_t **data, size_t *dlen, - QCryptoDERDecodeCb cb, void *ctx, Error **errp) +static int qcrypto_der_decode_tlv(const uint8_t expected_tag, + const uint8_t **data, size_t *dlen, + QCryptoDERDecodeCb cb, + void *ctx, Error **errp) { + const uint8_t *saved_data = *data; + size_t saved_dlen = *dlen; uint8_t tag; + int data_length; + if (*dlen < 1) { error_setg(errp, "Need more data"); return -1; } tag = qcrypto_der_cut_byte(data, dlen); - - /* INTEGER must encoded in primitive-form */ - if (tag != QCRYPTO_DER_TYPE_TAG_INT) { - error_setg(errp, "Invalid integer type tag: %u", tag); - return -1; + if (tag != expected_tag) { + error_setg(errp, "Unexpected tag: expected: %u, actual: %u", + expected_tag, tag); + goto error; } - return qcrypto_der_extract_data(data, dlen, cb, ctx, errp); + data_length = qcrypto_der_extract_data(data, dlen, cb, ctx, errp); + if (data_length < 0) { + goto error; + } + return data_length; + +error: + *data = saved_data; + *dlen = saved_dlen; + return -1; +} + +int qcrypto_der_decode_int(const uint8_t **data, size_t *dlen, + QCryptoDERDecodeCb cb, void *ctx, Error **errp) +{ + const uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_UNIV, + QCRYPTO_DER_TAG_ENC_PRIM, + QCRYPTO_DER_TYPE_TAG_INT); + return qcrypto_der_decode_tlv(tag, data, dlen, cb, ctx, errp); } int qcrypto_der_decode_seq(const uint8_t **data, size_t *dlen, QCryptoDERDecodeCb cb, void *ctx, Error **errp) { - uint8_t tag; - if (*dlen < 1) { - error_setg(errp, "Need more data"); - return -1; - } - tag = qcrypto_der_cut_byte(data, dlen); - - /* SEQUENCE must use constructed form */ - if (tag != (QCRYPTO_DER_TYPE_TAG_SEQ | QCRYPTO_DER_CONSTRUCTED_MASK)) { - error_setg(errp, "Invalid type sequence tag: %u", tag); - return -1; - } - - return qcrypto_der_extract_data(data, dlen, cb, ctx, errp); + uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_UNIV, + QCRYPTO_DER_TAG_ENC_CONS, + QCRYPTO_DER_TYPE_TAG_SEQ); + return qcrypto_der_decode_tlv(tag, data, dlen, cb, ctx, errp); +} + +int qcrypto_der_decode_octet_str(const uint8_t **data, size_t *dlen, + QCryptoDERDecodeCb cb, void *ctx, Error **errp) +{ + uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_UNIV, + QCRYPTO_DER_TAG_ENC_PRIM, + QCRYPTO_DER_TYPE_TAG_OCT_STR); + return qcrypto_der_decode_tlv(tag, data, dlen, cb, ctx, errp); +} + +int qcrypto_der_decode_bit_str(const uint8_t **data, size_t *dlen, + QCryptoDERDecodeCb cb, void *ctx, Error **errp) +{ + uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_UNIV, + QCRYPTO_DER_TAG_ENC_PRIM, + QCRYPTO_DER_TYPE_TAG_BIT_STR); + return qcrypto_der_decode_tlv(tag, data, dlen, cb, ctx, errp); +} + +int qcrypto_der_decode_oid(const uint8_t **data, size_t *dlen, + QCryptoDERDecodeCb cb, void *ctx, Error **errp) +{ + uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_UNIV, + QCRYPTO_DER_TAG_ENC_PRIM, + QCRYPTO_DER_TYPE_TAG_OID); + return qcrypto_der_decode_tlv(tag, data, dlen, cb, ctx, errp); +} + +int qcrypto_der_decode_ctx_tag(const uint8_t **data, size_t *dlen, int tag_id, + QCryptoDERDecodeCb cb, void *ctx, Error **errp) +{ + uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_CONT, + QCRYPTO_DER_TAG_ENC_CONS, + tag_id); + return qcrypto_der_decode_tlv(tag, data, dlen, cb, ctx, errp); +} + +static void qcrypto_der_encode_prim(QCryptoEncodeContext *ctx, uint8_t tag, + const uint8_t *data, size_t dlen) +{ + QCryptoDerEncodeNode *node = g_new0(QCryptoDerEncodeNode, 1); + size_t nbytes_len; + + node->tag = tag; + node->data = data; + node->dlen = dlen; + node->parent = ctx->current_parent; + + qcrypto_der_encode_length(dlen, NULL, &nbytes_len); + /* 1 byte for Tag, nbyte_len for Length, and dlen for Value */ + node->parent->dlen += 1 + nbytes_len + dlen; + + ctx->tail->next = node; + ctx->tail = node; +} + +QCryptoEncodeContext *qcrypto_der_encode_ctx_new(void) +{ + QCryptoEncodeContext *ctx = g_new0(QCryptoEncodeContext, 1); + ctx->current_parent = &ctx->root; + ctx->tail = &ctx->root; + return ctx; +} + +static void qcrypto_der_encode_cons_begin(QCryptoEncodeContext *ctx, + uint8_t tag) +{ + QCryptoDerEncodeNode *node = g_new0(QCryptoDerEncodeNode, 1); + + node->tag = tag; + node->parent = ctx->current_parent; + ctx->current_parent = node; + ctx->tail->next = node; + ctx->tail = node; +} + +static void qcrypto_der_encode_cons_end(QCryptoEncodeContext *ctx) +{ + QCryptoDerEncodeNode *cons_node = ctx->current_parent; + size_t nbytes_len; + + qcrypto_der_encode_length(cons_node->dlen, NULL, &nbytes_len); + /* 1 byte for Tag, nbyte_len for Length, and dlen for Value */ + cons_node->parent->dlen += 1 + nbytes_len + cons_node->dlen; + ctx->current_parent = cons_node->parent; +} + +void qcrypto_der_encode_seq_begin(QCryptoEncodeContext *ctx) +{ + uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_UNIV, + QCRYPTO_DER_TAG_ENC_CONS, + QCRYPTO_DER_TYPE_TAG_SEQ); + qcrypto_der_encode_cons_begin(ctx, tag); +} + +void qcrypto_der_encode_seq_end(QCryptoEncodeContext *ctx) +{ + qcrypto_der_encode_cons_end(ctx); +} + +void qcrypto_der_encode_oid(QCryptoEncodeContext *ctx, + const uint8_t *src, size_t src_len) +{ + uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_UNIV, + QCRYPTO_DER_TAG_ENC_PRIM, + QCRYPTO_DER_TYPE_TAG_OID); + qcrypto_der_encode_prim(ctx, tag, src, src_len); +} + +void qcrypto_der_encode_int(QCryptoEncodeContext *ctx, + const uint8_t *src, size_t src_len) +{ + uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_UNIV, + QCRYPTO_DER_TAG_ENC_PRIM, + QCRYPTO_DER_TYPE_TAG_INT); + qcrypto_der_encode_prim(ctx, tag, src, src_len); +} + +void qcrypto_der_encode_null(QCryptoEncodeContext *ctx) +{ + uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_UNIV, + QCRYPTO_DER_TAG_ENC_PRIM, + QCRYPTO_DER_TYPE_TAG_NULL); + qcrypto_der_encode_prim(ctx, tag, NULL, 0); +} + +void qcrypto_der_encode_octet_str(QCryptoEncodeContext *ctx, + const uint8_t *src, size_t src_len) +{ + uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_UNIV, + QCRYPTO_DER_TAG_ENC_PRIM, + QCRYPTO_DER_TYPE_TAG_OCT_STR); + qcrypto_der_encode_prim(ctx, tag, src, src_len); +} + +void qcrypto_der_encode_octet_str_begin(QCryptoEncodeContext *ctx) +{ + uint8_t tag = QCRYPTO_DER_TAG(QCRYPTO_DER_TAG_CLASS_UNIV, + QCRYPTO_DER_TAG_ENC_PRIM, + QCRYPTO_DER_TYPE_TAG_OCT_STR); + qcrypto_der_encode_cons_begin(ctx, tag); +} + +void qcrypto_der_encode_octet_str_end(QCryptoEncodeContext *ctx) +{ + qcrypto_der_encode_cons_end(ctx); +} + +size_t qcrypto_der_encode_ctx_buffer_len(QCryptoEncodeContext *ctx) +{ + return ctx->root.dlen; +} + +void qcrypto_der_encode_ctx_flush_and_free(QCryptoEncodeContext *ctx, + uint8_t *dst) +{ + QCryptoDerEncodeNode *node, *prev; + size_t len; + + for (prev = &ctx->root; + (node = prev->next) && (prev->next = node->next, 1);) { + /* Tag */ + *dst++ = node->tag; + + /* Length */ + qcrypto_der_encode_length(node->dlen, dst, &len); + dst += len; + + /* Value */ + if (node->data) { + memcpy(dst, node->data, node->dlen); + dst += node->dlen; + } + g_free(node); + } + g_free(ctx); } diff --git a/crypto/der.h b/crypto/der.h index e3d3aeacdc..0e895bbeec 100644 --- a/crypto/der.h +++ b/crypto/der.h @@ -22,6 +22,11 @@ #include "qapi/error.h" +typedef struct QCryptoEncodeContext QCryptoEncodeContext; + +/* rsaEncryption: 1.2.840.113549.1.1.1 */ +#define QCRYPTO_OID_rsaEncryption "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01" + /* Simple decoder used to parse DER encoded rsa keys. */ /** @@ -47,14 +52,13 @@ typedef int (*QCryptoDERDecodeCb) (void *opaque, const uint8_t *value, * will be set to the rest length of data, if cb is not NULL, must * return 0 to make decode success, at last, the length of the data * part of the decoded INTEGER will be returned. Otherwise, -1 is - * returned. + * returned and the valued of *data and *dlen keep unchanged. */ int qcrypto_der_decode_int(const uint8_t **data, size_t *dlen, QCryptoDERDecodeCb cb, void *opaque, Error **errp); - /** * qcrypto_der_decode_seq: * @@ -70,7 +74,7 @@ int qcrypto_der_decode_int(const uint8_t **data, * will be set to the rest length of data, if cb is not NULL, must * return 0 to make decode success, at last, the length of the data * part of the decoded SEQUENCE will be returned. Otherwise, -1 is - * returned. + * returned and the valued of *data and *dlen keep unchanged. */ int qcrypto_der_decode_seq(const uint8_t **data, size_t *dlen, @@ -78,4 +82,205 @@ int qcrypto_der_decode_seq(const uint8_t **data, void *opaque, Error **errp); +/** + * qcrypto_der_decode_oid: + * + * Decode OID from DER-encoded data, similar with der_decode_int. + * + * @data: pointer to address of input data + * @dlen: pointer to length of input data + * @cb: callback invoked when decode succeed, if cb equals NULL, no + * callback will be invoked + * @opaque: parameter passed to cb + * + * Returns: On success, *data points to rest data, and *dlen + * will be set to the rest length of data, if cb is not NULL, must + * return 0 to make decode success, at last, the length of the data + * part of the decoded OID will be returned. Otherwise, -1 is + * returned and the valued of *data and *dlen keep unchanged. + */ +int qcrypto_der_decode_oid(const uint8_t **data, + size_t *dlen, + QCryptoDERDecodeCb cb, + void *opaque, + Error **errp); + +/** + * qcrypto_der_decode_octet_str: + * + * Decode OCTET STRING from DER-encoded data, similar with der_decode_int. + * + * @data: pointer to address of input data + * @dlen: pointer to length of input data + * @cb: callback invoked when decode succeed, if cb equals NULL, no + * callback will be invoked + * @opaque: parameter passed to cb + * + * Returns: On success, *data points to rest data, and *dlen + * will be set to the rest length of data, if cb is not NULL, must + * return 0 to make decode success, at last, the length of the data + * part of the decoded OCTET STRING will be returned. Otherwise, -1 is + * returned and the valued of *data and *dlen keep unchanged. + */ +int qcrypto_der_decode_octet_str(const uint8_t **data, + size_t *dlen, + QCryptoDERDecodeCb cb, + void *opaque, + Error **errp); + +/** + * qcrypto_der_decode_bit_str: + * + * Decode BIT STRING from DER-encoded data, similar with der_decode_int. + * + * @data: pointer to address of input data + * @dlen: pointer to length of input data + * @cb: callback invoked when decode succeed, if cb equals NULL, no + * callback will be invoked + * @opaque: parameter passed to cb + * + * Returns: On success, *data points to rest data, and *dlen + * will be set to the rest length of data, if cb is not NULL, must + * return 0 to make decode success, at last, the length of the data + * part of the decoded BIT STRING will be returned. Otherwise, -1 is + * returned and the valued of *data and *dlen keep unchanged. + */ +int qcrypto_der_decode_bit_str(const uint8_t **data, + size_t *dlen, + QCryptoDERDecodeCb cb, + void *opaque, + Error **errp); + + +/** + * qcrypto_der_decode_ctx_tag: + * + * Decode context specific tag + * + * @data: pointer to address of input data + * @dlen: pointer to length of input data + * @tag: expected value of context specific tag + * @cb: callback invoked when decode succeed, if cb equals NULL, no + * callback will be invoked + * @opaque: parameter passed to cb + * + * Returns: On success, *data points to rest data, and *dlen + * will be set to the rest length of data, if cb is not NULL, must + * return 0 to make decode success, at last, the length of the data + * part of the decoded BIT STRING will be returned. Otherwise, -1 is + * returned and the valued of *data and *dlen keep unchanged. + */ +int qcrypto_der_decode_ctx_tag(const uint8_t **data, + size_t *dlen, int tag_id, + QCryptoDERDecodeCb cb, + void *opaque, + Error **errp); + +/** + * qcrypto_der_encode_ctx_new: + * + * Allocate a context used for der encoding. + */ +QCryptoEncodeContext *qcrypto_der_encode_ctx_new(void); + +/** + * qcrypto_der_encode_seq_begin: + * @ctx: the encode context. + * + * Start encoding a SEQUENCE for ctx. + * + */ +void qcrypto_der_encode_seq_begin(QCryptoEncodeContext *ctx); + +/** + * qcrypto_der_encode_seq_begin: + * @ctx: the encode context. + * + * Finish uencoding a SEQUENCE for ctx. + * + */ +void qcrypto_der_encode_seq_end(QCryptoEncodeContext *ctx); + + +/** + * qcrypto_der_encode_oid: + * @ctx: the encode context. + * @src: the source data of oid, note it should be already encoded, this + * function only add tag and length part for it. + * + * Encode an oid into ctx. + */ +void qcrypto_der_encode_oid(QCryptoEncodeContext *ctx, + const uint8_t *src, size_t src_len); + +/** + * qcrypto_der_encode_int: + * @ctx: the encode context. + * @src: the source data of integer, note it should be already encoded, this + * function only add tag and length part for it. + * + * Encode an integer into ctx. + */ +void qcrypto_der_encode_int(QCryptoEncodeContext *ctx, + const uint8_t *src, size_t src_len); + +/** + * qcrypto_der_encode_null: + * @ctx: the encode context. + * + * Encode a null into ctx. + */ +void qcrypto_der_encode_null(QCryptoEncodeContext *ctx); + +/** + * qcrypto_der_encode_octet_str: + * @ctx: the encode context. + * @src: the source data of the octet string. + * + * Encode a octet string into ctx. + */ +void qcrypto_der_encode_octet_str(QCryptoEncodeContext *ctx, + const uint8_t *src, size_t src_len); + +/** + * qcrypto_der_encode_octet_str_begin: + * @ctx: the encode context. + * + * Start encoding a octet string, All fields between + * qcrypto_der_encode_octet_str_begin and qcrypto_der_encode_octet_str_end + * are encoded as an octet string. This is useful when we need to encode a + * encoded SEQUNCE as OCTET STRING. + */ +void qcrypto_der_encode_octet_str_begin(QCryptoEncodeContext *ctx); + +/** + * qcrypto_der_encode_octet_str_end: + * @ctx: the encode context. + * + * Finish encoding a octet string, All fields between + * qcrypto_der_encode_octet_str_begin and qcrypto_der_encode_octet_str_end + * are encoded as an octet string. This is useful when we need to encode a + * encoded SEQUNCE as OCTET STRING. + */ +void qcrypto_der_encode_octet_str_end(QCryptoEncodeContext *ctx); + +/** + * qcrypto_der_encode_ctx_buffer_len: + * @ctx: the encode context. + * + * Compute the expected buffer size to save all encoded things. + */ +size_t qcrypto_der_encode_ctx_buffer_len(QCryptoEncodeContext *ctx); + +/** + * qcrypto_der_encode_ctx_flush_and_free: + * @ctx: the encode context. + * @dst: the distination to save the encoded data, the length of dst should + * not less than qcrypto_der_encode_cxt_buffer_len + * + * Flush all encoded data into dst, then free ctx. + */ +void qcrypto_der_encode_ctx_flush_and_free(QCryptoEncodeContext *ctx, + uint8_t *dst); + #endif /* QCRYPTO_ASN1_DECODER_H */ diff --git a/tests/unit/test-crypto-der.c b/tests/unit/test-crypto-der.c index aed0f28d68..d218a7f170 100644 --- a/tests/unit/test-crypto-der.c +++ b/tests/unit/test-crypto-der.c @@ -147,13 +147,58 @@ static const uint8_t test_rsa2048_priv_key[] = "\x4e\x2f\x4c\xf9\xab\x97\x38\xe4\x20\x32\x32\x96\xc8\x9e\x79\xd3" "\x12"; +static const uint8_t test_ecdsa_p192_priv_key[] = + "\x30\x53" /* SEQUENCE, offset 0, length 83 */ + "\x02\x01\x01" /* INTEGER, offset 2, length 1 */ + "\x04\x18" /* OCTET STRING, offset 5, length 24 */ + "\xcb\xc8\x86\x0e\x66\x3c\xf7\x5a\x44\x13\xb8\xef\xea\x1d\x7b\xa6" + "\x1c\xda\xf4\x1b\xc7\x67\x6b\x35" + "\xa1\x34" /* CONTEXT SPECIFIC 1, offset 31, length 52 */ + "\x03\x32" /* BIT STRING, offset 33, length 50 */ + "\x00\x04\xc4\x16\xb3\xff\xac\xd5\x87\x98\xf7\xd9\x45\xfe\xd3\x5c" + "\x17\x9d\xb2\x36\x22\xcc\x07\xb3\x6d\x3c\x4e\x04\x5f\xeb\xb6\x52" + "\x58\xfb\x36\x10\x52\xb7\x01\x62\x0e\x94\x51\x1d\xe2\xef\x10\x82" + "\x88\x78"; + +static const uint8_t test_ecdsa_p256_priv_key[] = + "\x30\x77" /* SEQUENCE, offset 0, length 119 */ + "\x02\x01\x01" /* INTEGER, offset 2, length 1 */ + "\x04\x20" /* OCTET STRING, offset 5, length 32 */ + "\xf6\x92\xdd\x29\x1c\x6e\xef\xb6\xb2\x73\x9f\x40\x1b\xb3\x2a\x28" + "\xd2\x37\xd6\x4a\x5b\xe4\x40\x4c\x6a\x95\x99\xfa\xf7\x92\x49\xbe" + "\xa0\x0a" /* CONTEXT SPECIFIC 0, offset 39, length 10 */ + "\x06\x08" /* OID, offset 41, length 8 */ + "\x2a\x86\x48\xce\x3d\x03\x01\x07" + "\xa1\x44" /* CONTEXT SPECIFIC 1, offset 51, length 68 */ + "\x03\x42" /* BIT STRING, offset 53, length 66 */ + "\x00\x04\xed\x42\x9c\x67\x79\xbe\x46\x83\x88\x3e\x8c\xc1\x33\xf3" + "\xc3\xf6\x2c\xf3\x13\x6a\x00\xc2\xc9\x3e\x87\x7f\x86\x39\xe6\xae" + "\xe3\xb9\xba\x2f\x58\x63\x32\x62\x62\x54\x07\x27\xf9\x5a\x3a\xc7" + "\x3a\x6b\x5b\xbc\x0d\x33\xba\xbb\xd4\xa3\xff\x4f\x9e\xdd\xf5\x59" + "\xc0\xf6"; + #define MAX_CHECKER_COUNT 32 +static int qcrypto_wrapped_decode_ctx_tag0(const uint8_t **data, size_t *dlen, + QCryptoDERDecodeCb cb, void *opaque, + Error **errp) +{ + return qcrypto_der_decode_ctx_tag(data, dlen, 0, cb, opaque, errp); +} + +static int qcrypto_wrapped_decode_ctx_tag1(const uint8_t **data, size_t *dlen, + QCryptoDERDecodeCb cb, void *opaque, + Error **errp) +{ + return qcrypto_der_decode_ctx_tag(data, dlen, 1, cb, opaque, errp); +} + typedef struct QCryptoAns1DecoderResultChecker QCryptoAns1DecoderResultChecker; struct QCryptoAns1DecoderResultChecker { int (*action) (const uint8_t **data, size_t *dlen, QCryptoDERDecodeCb cb, void *opaque, Error **errp); QCryptoDERDecodeCb cb; + bool constructed; const uint8_t *exp_value; size_t exp_vlen; }; @@ -204,7 +249,7 @@ static void test_ans1(const void *opaque) g_assert(checker->action(&c->data, &c->dlen, checker_callback, (void *)checker, &error_abort) == checker->exp_vlen); - if (checker->action == qcrypto_der_decode_seq) { + if (checker->constructed) { ++seq_depth; ctx[seq_depth].data = checker->exp_value; ctx[seq_depth].dlen = checker->exp_vlen; @@ -225,25 +270,25 @@ static QCryptoAns1DecoderTestData test_data[] = { .test_data = test_rsa512_priv_key, .test_data_len = sizeof(test_rsa512_priv_key) - 1, .checker = { - { qcrypto_der_decode_seq, checker_callback, + { qcrypto_der_decode_seq, checker_callback, true, test_rsa512_priv_key + 4, 313 }, - { qcrypto_der_decode_int, checker_callback, + { qcrypto_der_decode_int, checker_callback, false, test_rsa512_priv_key + 4 + 2, 1 }, - { qcrypto_der_decode_int, checker_callback, + { qcrypto_der_decode_int, checker_callback, false, test_rsa512_priv_key + 7 + 2, 65 }, - { qcrypto_der_decode_int, checker_callback, + { qcrypto_der_decode_int, checker_callback, false, test_rsa512_priv_key + 74 + 2, 3 }, - { qcrypto_der_decode_int, checker_callback, + { qcrypto_der_decode_int, checker_callback, false, test_rsa512_priv_key + 79 + 2, 64 }, - { qcrypto_der_decode_int, checker_callback, + { qcrypto_der_decode_int, checker_callback, false, test_rsa512_priv_key + 145 + 2, 33 }, - { qcrypto_der_decode_int, checker_callback, + { qcrypto_der_decode_int, checker_callback, false, test_rsa512_priv_key + 180 + 2, 33 }, - { qcrypto_der_decode_int, checker_callback, + { qcrypto_der_decode_int, checker_callback, false, test_rsa512_priv_key + 215 + 2, 32 }, - { qcrypto_der_decode_int, checker_callback, + { qcrypto_der_decode_int, checker_callback, false, test_rsa512_priv_key + 249 + 2, 32 }, - { qcrypto_der_decode_int, checker_callback, + { qcrypto_der_decode_int, checker_callback, false, test_rsa512_priv_key + 283 + 2, 32 }, }, }, @@ -252,29 +297,66 @@ static QCryptoAns1DecoderTestData test_data[] = { .test_data = test_rsa2048_priv_key, .test_data_len = sizeof(test_rsa2048_priv_key) - 1, .checker = { - { qcrypto_der_decode_seq, checker_callback, + { qcrypto_der_decode_seq, checker_callback, true, test_rsa2048_priv_key + 4, 1190 }, - { qcrypto_der_decode_int, checker_callback, + { qcrypto_der_decode_int, checker_callback, false, test_rsa2048_priv_key + 4 + 2, 1 }, - { qcrypto_der_decode_int, checker_callback, + { qcrypto_der_decode_int, checker_callback, false, test_rsa2048_priv_key + 7 + 4, 257 }, - { qcrypto_der_decode_int, checker_callback, + { qcrypto_der_decode_int, checker_callback, false, test_rsa2048_priv_key + 268 + 2, 3 }, - { qcrypto_der_decode_int, checker_callback, + { qcrypto_der_decode_int, checker_callback, false, test_rsa2048_priv_key + 273 + 4, 257 }, - { qcrypto_der_decode_int, checker_callback, + { qcrypto_der_decode_int, checker_callback, false, test_rsa2048_priv_key + 534 + 3, 129 }, - { qcrypto_der_decode_int, checker_callback, + { qcrypto_der_decode_int, checker_callback, false, test_rsa2048_priv_key + 666 + 3, 129 }, - { qcrypto_der_decode_int, checker_callback, + { qcrypto_der_decode_int, checker_callback, false, test_rsa2048_priv_key + 798 + 3, 129 }, - { qcrypto_der_decode_int, checker_callback, + { qcrypto_der_decode_int, checker_callback, false, test_rsa2048_priv_key + 930 + 3, 129 }, - { qcrypto_der_decode_int, checker_callback, + { qcrypto_der_decode_int, checker_callback, false, test_rsa2048_priv_key + 1062 + 3, 129 }, }, }, - +{ + .path = "/crypto/der/parse-ecdsa-p192-priv-key", + .test_data = test_ecdsa_p192_priv_key, + .test_data_len = sizeof(test_ecdsa_p192_priv_key) - 1, + .checker = { + { qcrypto_der_decode_seq, checker_callback, true, + test_ecdsa_p192_priv_key + 2, 83 }, + { qcrypto_der_decode_int, checker_callback, false, + test_ecdsa_p192_priv_key + 2 + 2, 1 }, + { qcrypto_der_decode_octet_str, checker_callback, false, + test_ecdsa_p192_priv_key + 5 + 2, 24 }, + { qcrypto_wrapped_decode_ctx_tag1, checker_callback, true, + test_ecdsa_p192_priv_key + 31 + 2, 52 }, + { qcrypto_der_decode_bit_str , checker_callback, false, + test_ecdsa_p192_priv_key + 33 + 2, 50 }, + }, +}, +{ + .path = "/crypto/der/parse-ecdsa-p256-priv-key", + .test_data = test_ecdsa_p256_priv_key, + .test_data_len = sizeof(test_ecdsa_p256_priv_key) - 1, + .checker = { + { qcrypto_der_decode_seq, checker_callback, true, + test_ecdsa_p256_priv_key + 2, 119 }, + { qcrypto_der_decode_int, checker_callback, false, + test_ecdsa_p256_priv_key + 2 + 2, 1 }, + { qcrypto_der_decode_octet_str, checker_callback, false, + test_ecdsa_p256_priv_key + 5 + 2, 32 }, + { qcrypto_wrapped_decode_ctx_tag0, checker_callback, true, + test_ecdsa_p256_priv_key + 39 + 2, 10 }, + { qcrypto_der_decode_oid, checker_callback, false, + test_ecdsa_p256_priv_key + 41 + 2, 8 }, + { qcrypto_wrapped_decode_ctx_tag1, checker_callback, true, + test_ecdsa_p256_priv_key + 51 + 2, 68 }, + { qcrypto_der_decode_bit_str , checker_callback, false, + test_ecdsa_p256_priv_key + 53 + 2, 66 }, + }, +}, }; int main(int argc, char **argv) From 58660863ba5ca4f74fa70671da2899b264dc5f34 Mon Sep 17 00:00:00 2001 From: Lei He Date: Sat, 8 Oct 2022 16:50:29 +0800 Subject: [PATCH 535/705] crypto: Support export akcipher to pkcs8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit crypto: support export RSA private keys with PKCS#8 standard. So that users can upload this private key to linux kernel. Signed-off-by: lei he Message-Id: <20221008085030.70212-4-helei.sig11@bytedance.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Daniel P. Berrangé --- crypto/akcipher.c | 18 +++++++++++++++++ crypto/rsakey.c | 42 +++++++++++++++++++++++++++++++++++++++ crypto/rsakey.h | 11 +++++++++- include/crypto/akcipher.h | 21 ++++++++++++++++++++ 4 files changed, 91 insertions(+), 1 deletion(-) diff --git a/crypto/akcipher.c b/crypto/akcipher.c index ad88379c1e..e4bbc6e5f1 100644 --- a/crypto/akcipher.c +++ b/crypto/akcipher.c @@ -22,6 +22,8 @@ #include "qemu/osdep.h" #include "crypto/akcipher.h" #include "akcipherpriv.h" +#include "der.h" +#include "rsakey.h" #if defined(CONFIG_GCRYPT) #include "akcipher-gcrypt.c.inc" @@ -106,3 +108,19 @@ void qcrypto_akcipher_free(QCryptoAkCipher *akcipher) drv->free(akcipher); } + +int qcrypto_akcipher_export_p8info(const QCryptoAkCipherOptions *opts, + uint8_t *key, size_t keylen, + uint8_t **dst, size_t *dst_len, + Error **errp) +{ + switch (opts->alg) { + case QCRYPTO_AKCIPHER_ALG_RSA: + qcrypto_akcipher_rsakey_export_p8info(key, keylen, dst, dst_len); + return 0; + + default: + error_setg(errp, "Unsupported algorithm: %u", opts->alg); + return -1; + } +} diff --git a/crypto/rsakey.c b/crypto/rsakey.c index cc40e072f0..7d6f273aef 100644 --- a/crypto/rsakey.c +++ b/crypto/rsakey.c @@ -19,6 +19,8 @@ * */ +#include "qemu/osdep.h" +#include "der.h" #include "rsakey.h" void qcrypto_akcipher_rsakey_free(QCryptoAkCipherRSAKey *rsa_key) @@ -37,6 +39,46 @@ void qcrypto_akcipher_rsakey_free(QCryptoAkCipherRSAKey *rsa_key) g_free(rsa_key); } +/** + * PKCS#8 private key info for RSA + * + * PrivateKeyInfo ::= SEQUENCE { + * version INTEGER, + * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, + * privateKey OCTET STRING, + * attributes [0] IMPLICIT Attributes OPTIONAL + * } + */ +void qcrypto_akcipher_rsakey_export_p8info(const uint8_t *key, + size_t keylen, + uint8_t **dst, + size_t *dlen) +{ + QCryptoEncodeContext *ctx = qcrypto_der_encode_ctx_new(); + uint8_t version = 0; + + qcrypto_der_encode_seq_begin(ctx); + + /* version */ + qcrypto_der_encode_int(ctx, &version, sizeof(version)); + + /* algorithm identifier */ + qcrypto_der_encode_seq_begin(ctx); + qcrypto_der_encode_oid(ctx, (uint8_t *)QCRYPTO_OID_rsaEncryption, + sizeof(QCRYPTO_OID_rsaEncryption) - 1); + qcrypto_der_encode_null(ctx); + qcrypto_der_encode_seq_end(ctx); + + /* RSA private key */ + qcrypto_der_encode_octet_str(ctx, key, keylen); + + qcrypto_der_encode_seq_end(ctx); + + *dlen = qcrypto_der_encode_ctx_buffer_len(ctx); + *dst = g_malloc(*dlen); + qcrypto_der_encode_ctx_flush_and_free(ctx, *dst); +} + #if defined(CONFIG_NETTLE) && defined(CONFIG_HOGWEED) #include "rsakey-nettle.c.inc" #else diff --git a/crypto/rsakey.h b/crypto/rsakey.h index 974b76f659..00b3eccec7 100644 --- a/crypto/rsakey.h +++ b/crypto/rsakey.h @@ -22,7 +22,6 @@ #ifndef QCRYPTO_RSAKEY_H #define QCRYPTO_RSAKEY_H -#include "qemu/osdep.h" #include "qemu/host-utils.h" #include "crypto/akcipher.h" @@ -84,6 +83,16 @@ QCryptoAkCipherRSAKey *qcrypto_akcipher_rsakey_parse( QCryptoAkCipherKeyType type, const uint8_t *key, size_t keylen, Error **errp); +/** + * qcrypto_akcipher_rsakey_export_as_p8info: + * + * Export RSA private key to PKCS#8 private key info. + */ +void qcrypto_akcipher_rsakey_export_p8info(const uint8_t *key, + size_t keylen, + uint8_t **dst, + size_t *dlen); + void qcrypto_akcipher_rsakey_free(QCryptoAkCipherRSAKey *key); G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoAkCipherRSAKey, diff --git a/include/crypto/akcipher.h b/include/crypto/akcipher.h index 51f5fa2774..214e58ca47 100644 --- a/include/crypto/akcipher.h +++ b/include/crypto/akcipher.h @@ -153,6 +153,27 @@ int qcrypto_akcipher_max_dgst_len(QCryptoAkCipher *akcipher); */ void qcrypto_akcipher_free(QCryptoAkCipher *akcipher); +/** + * qcrypto_akcipher_export_p8info: + * @opts: the options of the akcipher to be exported. + * @key: the original key of the akcipher to be exported. + * @keylen: length of the 'key' + * @dst: output parameter, if export succeed, *dst is set to the + * PKCS#8 encoded private key, caller MUST free this key with + * g_free after use. + * @dst_len: output parameter, indicates the length of PKCS#8 encoded + * key. + * + * Export the akcipher into DER encoded pkcs#8 private key info, expects + * |key| stores a valid asymmetric PRIVATE key. + * + * Returns: 0 for succeed, otherwise -1 is returned. + */ +int qcrypto_akcipher_export_p8info(const QCryptoAkCipherOptions *opts, + uint8_t *key, size_t keylen, + uint8_t **dst, size_t *dst_len, + Error **errp); + G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoAkCipher, qcrypto_akcipher_free) #endif /* QCRYPTO_AKCIPHER_H */ From 39fff6f3e8b3dd4f1708f8bdde0a51adbe63188a Mon Sep 17 00:00:00 2001 From: Lei He Date: Sat, 8 Oct 2022 16:50:30 +0800 Subject: [PATCH 536/705] cryptodev: Add a lkcf-backend for cryptodev cryptodev: Added a new type of backend named lkcf-backend for cryptodev. This backend upload asymmetric keys to linux kernel, and let kernel do the accelerations if possible. The lkcf stands for Linux Kernel Cryptography Framework. Signed-off-by: lei he Message-Id: <20221008085030.70212-5-helei.sig11@bytedance.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- backends/cryptodev-lkcf.c | 645 +++++++++++++++++++++++++++++++++++++ backends/meson.build | 3 + include/sysemu/cryptodev.h | 1 + qapi/qom.json | 2 + 4 files changed, 651 insertions(+) create mode 100644 backends/cryptodev-lkcf.c diff --git a/backends/cryptodev-lkcf.c b/backends/cryptodev-lkcf.c new file mode 100644 index 0000000000..133bd706a4 --- /dev/null +++ b/backends/cryptodev-lkcf.c @@ -0,0 +1,645 @@ +/* + * QEMU Cryptodev backend for QEMU cipher APIs + * + * Copyright (c) 2022 Bytedance.Inc + * + * Authors: + * lei he + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + */ + +#include "qemu/osdep.h" +#include "crypto/cipher.h" +#include "crypto/akcipher.h" +#include "qapi/error.h" +#include "qemu/main-loop.h" +#include "qemu/thread.h" +#include "qemu/error-report.h" +#include "qemu/queue.h" +#include "qom/object.h" +#include "sysemu/cryptodev.h" +#include "standard-headers/linux/virtio_crypto.h" + +#include +#include + +/** + * @TYPE_CRYPTODEV_BACKEND_LKCF: + * name of backend that uses linux kernel crypto framework + */ +#define TYPE_CRYPTODEV_BACKEND_LKCF "cryptodev-backend-lkcf" + +OBJECT_DECLARE_SIMPLE_TYPE(CryptoDevBackendLKCF, CRYPTODEV_BACKEND_LKCF) + +#define INVALID_KEY_ID -1 +#define MAX_SESSIONS 256 +#define NR_WORKER_THREAD 64 + +#define KCTL_KEY_TYPE_PKEY "asymmetric" +/** + * Here the key is uploaded to the thread-keyring of worker thread, at least + * util linux-6.0: + * 1. process keyring seems to behave unexpectedly if main-thread does not + * create the keyring before creating any other thread. + * 2. at present, the guest kernel never perform multiple operations on a + * session. + * 3. it can reduce the load of the main-loop because the key passed by the + * guest kernel has been already checked. + */ +#define KCTL_KEY_RING KEY_SPEC_THREAD_KEYRING + +typedef struct CryptoDevBackendLKCFSession { + uint8_t *key; + size_t keylen; + QCryptoAkCipherKeyType keytype; + QCryptoAkCipherOptions akcipher_opts; +} CryptoDevBackendLKCFSession; + +typedef struct CryptoDevBackendLKCF CryptoDevBackendLKCF; +typedef struct CryptoDevLKCFTask CryptoDevLKCFTask; +struct CryptoDevLKCFTask { + CryptoDevBackendLKCFSession *sess; + CryptoDevBackendOpInfo *op_info; + CryptoDevCompletionFunc cb; + void *opaque; + int status; + CryptoDevBackendLKCF *lkcf; + QSIMPLEQ_ENTRY(CryptoDevLKCFTask) queue; +}; + +typedef struct CryptoDevBackendLKCF { + CryptoDevBackend parent_obj; + CryptoDevBackendLKCFSession *sess[MAX_SESSIONS]; + QSIMPLEQ_HEAD(, CryptoDevLKCFTask) requests; + QSIMPLEQ_HEAD(, CryptoDevLKCFTask) responses; + QemuMutex mutex; + QemuCond cond; + QemuMutex rsp_mutex; + + /** + * There is no async interface for asymmetric keys like AF_ALG sockets, + * we don't seem to have better way than create a lots of thread. + */ + QemuThread worker_threads[NR_WORKER_THREAD]; + bool running; + int eventfd; +} CryptoDevBackendLKCF; + +static void *cryptodev_lkcf_worker(void *arg); +static int cryptodev_lkcf_close_session(CryptoDevBackend *backend, + uint64_t session_id, + uint32_t queue_index, + CryptoDevCompletionFunc cb, + void *opaque); + +static void cryptodev_lkcf_handle_response(void *opaque) +{ + CryptoDevBackendLKCF *lkcf = (CryptoDevBackendLKCF *)opaque; + QSIMPLEQ_HEAD(, CryptoDevLKCFTask) responses; + CryptoDevLKCFTask *task, *next; + eventfd_t nevent; + + QSIMPLEQ_INIT(&responses); + eventfd_read(lkcf->eventfd, &nevent); + + qemu_mutex_lock(&lkcf->rsp_mutex); + QSIMPLEQ_PREPEND(&responses, &lkcf->responses); + qemu_mutex_unlock(&lkcf->rsp_mutex); + + QSIMPLEQ_FOREACH_SAFE(task, &responses, queue, next) { + if (task->cb) { + task->cb(task->opaque, task->status); + } + g_free(task); + } +} + +static int cryptodev_lkcf_set_op_desc(QCryptoAkCipherOptions *opts, + char *key_desc, + size_t desc_len, + Error **errp) +{ + QCryptoAkCipherOptionsRSA *rsa_opt; + if (opts->alg != QCRYPTO_AKCIPHER_ALG_RSA) { + error_setg(errp, "Unsupported alg: %u", opts->alg); + return -1; + } + + rsa_opt = &opts->u.rsa; + if (rsa_opt->padding_alg == QCRYPTO_RSA_PADDING_ALG_PKCS1) { + snprintf(key_desc, desc_len, "enc=%s hash=%s", + QCryptoRSAPaddingAlgorithm_str(rsa_opt->padding_alg), + QCryptoHashAlgorithm_str(rsa_opt->hash_alg)); + + } else { + snprintf(key_desc, desc_len, "enc=%s", + QCryptoRSAPaddingAlgorithm_str(rsa_opt->padding_alg)); + } + return 0; +} + +static int cryptodev_lkcf_set_rsa_opt(int virtio_padding_alg, + int virtio_hash_alg, + QCryptoAkCipherOptionsRSA *opt, + Error **errp) +{ + if (virtio_padding_alg == VIRTIO_CRYPTO_RSA_PKCS1_PADDING) { + opt->padding_alg = QCRYPTO_RSA_PADDING_ALG_PKCS1; + + switch (virtio_hash_alg) { + case VIRTIO_CRYPTO_RSA_MD5: + opt->hash_alg = QCRYPTO_HASH_ALG_MD5; + break; + + case VIRTIO_CRYPTO_RSA_SHA1: + opt->hash_alg = QCRYPTO_HASH_ALG_SHA1; + break; + + case VIRTIO_CRYPTO_RSA_SHA256: + opt->hash_alg = QCRYPTO_HASH_ALG_SHA256; + break; + + case VIRTIO_CRYPTO_RSA_SHA512: + opt->hash_alg = QCRYPTO_HASH_ALG_SHA512; + break; + + default: + error_setg(errp, "Unsupported rsa hash algo: %d", virtio_hash_alg); + return -1; + } + return 0; + } + + if (virtio_padding_alg == VIRTIO_CRYPTO_RSA_RAW_PADDING) { + opt->padding_alg = QCRYPTO_RSA_PADDING_ALG_RAW; + return 0; + } + + error_setg(errp, "Unsupported rsa padding algo: %u", virtio_padding_alg); + return -1; +} + +static int cryptodev_lkcf_get_unused_session_index(CryptoDevBackendLKCF *lkcf) +{ + size_t i; + + for (i = 0; i < MAX_SESSIONS; i++) { + if (lkcf->sess[i] == NULL) { + return i; + } + } + return -1; +} + +static void cryptodev_lkcf_init(CryptoDevBackend *backend, Error **errp) +{ + /* Only support one queue */ + int queues = backend->conf.peers.queues, i; + CryptoDevBackendClient *cc; + CryptoDevBackendLKCF *lkcf = + CRYPTODEV_BACKEND_LKCF(backend); + + if (queues != 1) { + error_setg(errp, + "Only support one queue in cryptodev-builtin backend"); + return; + } + lkcf->eventfd = eventfd(0, 0); + if (lkcf->eventfd < 0) { + error_setg(errp, "Failed to create eventfd: %d", errno); + return; + } + + cc = cryptodev_backend_new_client("cryptodev-lkcf", NULL); + cc->info_str = g_strdup_printf("cryptodev-lkcf0"); + cc->queue_index = 0; + cc->type = CRYPTODEV_BACKEND_TYPE_LKCF; + backend->conf.peers.ccs[0] = cc; + + backend->conf.crypto_services = + 1u << VIRTIO_CRYPTO_SERVICE_AKCIPHER; + backend->conf.akcipher_algo = 1u << VIRTIO_CRYPTO_AKCIPHER_RSA; + lkcf->running = true; + + QSIMPLEQ_INIT(&lkcf->requests); + QSIMPLEQ_INIT(&lkcf->responses); + qemu_mutex_init(&lkcf->mutex); + qemu_mutex_init(&lkcf->rsp_mutex); + qemu_cond_init(&lkcf->cond); + for (i = 0; i < NR_WORKER_THREAD; i++) { + qemu_thread_create(&lkcf->worker_threads[i], "lkcf-worker", + cryptodev_lkcf_worker, lkcf, 0); + } + qemu_set_fd_handler( + lkcf->eventfd, cryptodev_lkcf_handle_response, NULL, lkcf); + cryptodev_backend_set_ready(backend, true); +} + +static void cryptodev_lkcf_cleanup(CryptoDevBackend *backend, Error **errp) +{ + CryptoDevBackendLKCF *lkcf = CRYPTODEV_BACKEND_LKCF(backend); + size_t i; + int queues = backend->conf.peers.queues; + CryptoDevBackendClient *cc; + CryptoDevLKCFTask *task, *next; + + qemu_mutex_lock(&lkcf->mutex); + lkcf->running = false; + qemu_mutex_unlock(&lkcf->mutex); + qemu_cond_broadcast(&lkcf->cond); + + close(lkcf->eventfd); + for (i = 0; i < NR_WORKER_THREAD; i++) { + qemu_thread_join(&lkcf->worker_threads[i]); + } + + QSIMPLEQ_FOREACH_SAFE(task, &lkcf->requests, queue, next) { + if (task->cb) { + task->cb(task->opaque, task->status); + } + g_free(task); + } + + QSIMPLEQ_FOREACH_SAFE(task, &lkcf->responses, queue, next) { + if (task->cb) { + task->cb(task->opaque, task->status); + } + g_free(task); + } + + qemu_mutex_destroy(&lkcf->mutex); + qemu_cond_destroy(&lkcf->cond); + qemu_mutex_destroy(&lkcf->rsp_mutex); + + for (i = 0; i < MAX_SESSIONS; i++) { + if (lkcf->sess[i] != NULL) { + cryptodev_lkcf_close_session(backend, i, 0, NULL, NULL); + } + } + + for (i = 0; i < queues; i++) { + cc = backend->conf.peers.ccs[i]; + if (cc) { + cryptodev_backend_free_client(cc); + backend->conf.peers.ccs[i] = NULL; + } + } + + cryptodev_backend_set_ready(backend, false); +} + +static void cryptodev_lkcf_execute_task(CryptoDevLKCFTask *task) +{ + CryptoDevBackendLKCFSession *session = task->sess; + CryptoDevBackendAsymOpInfo *asym_op_info; + bool kick = false; + int ret, status, op_code = task->op_info->op_code; + size_t p8info_len; + g_autofree uint8_t *p8info = NULL; + Error *local_error = NULL; + key_serial_t key_id = INVALID_KEY_ID; + char op_desc[64]; + g_autoptr(QCryptoAkCipher) akcipher = NULL; + + /** + * We only offload private key session: + * 1. currently, the Linux kernel can only accept public key wrapped + * with X.509 certificates, but unfortunately the cost of making a + * ceritificate with public key is too expensive. + * 2. generally, public key related compution is fast, just compute it with + * thread-pool. + */ + if (session->keytype == QCRYPTO_AKCIPHER_KEY_TYPE_PRIVATE) { + if (qcrypto_akcipher_export_p8info(&session->akcipher_opts, + session->key, session->keylen, + &p8info, &p8info_len, + &local_error) != 0 || + cryptodev_lkcf_set_op_desc(&session->akcipher_opts, op_desc, + sizeof(op_desc), &local_error) != 0) { + error_report_err(local_error); + } else { + key_id = add_key(KCTL_KEY_TYPE_PKEY, "lkcf-backend-priv-key", + p8info, p8info_len, KCTL_KEY_RING); + } + } + + if (key_id < 0) { + if (!qcrypto_akcipher_supports(&session->akcipher_opts)) { + status = -VIRTIO_CRYPTO_NOTSUPP; + goto out; + } + akcipher = qcrypto_akcipher_new(&session->akcipher_opts, + session->keytype, + session->key, session->keylen, + &local_error); + if (!akcipher) { + status = -VIRTIO_CRYPTO_ERR; + goto out; + } + } + + asym_op_info = task->op_info->u.asym_op_info; + switch (op_code) { + case VIRTIO_CRYPTO_AKCIPHER_ENCRYPT: + if (key_id >= 0) { + ret = keyctl_pkey_encrypt(key_id, op_desc, + asym_op_info->src, asym_op_info->src_len, + asym_op_info->dst, asym_op_info->dst_len); + } else { + ret = qcrypto_akcipher_encrypt(akcipher, + asym_op_info->src, asym_op_info->src_len, + asym_op_info->dst, asym_op_info->dst_len, &local_error); + } + break; + + case VIRTIO_CRYPTO_AKCIPHER_DECRYPT: + if (key_id >= 0) { + ret = keyctl_pkey_decrypt(key_id, op_desc, + asym_op_info->src, asym_op_info->src_len, + asym_op_info->dst, asym_op_info->dst_len); + } else { + ret = qcrypto_akcipher_decrypt(akcipher, + asym_op_info->src, asym_op_info->src_len, + asym_op_info->dst, asym_op_info->dst_len, &local_error); + } + break; + + case VIRTIO_CRYPTO_AKCIPHER_SIGN: + if (key_id >= 0) { + ret = keyctl_pkey_sign(key_id, op_desc, + asym_op_info->src, asym_op_info->src_len, + asym_op_info->dst, asym_op_info->dst_len); + } else { + ret = qcrypto_akcipher_sign(akcipher, + asym_op_info->src, asym_op_info->src_len, + asym_op_info->dst, asym_op_info->dst_len, &local_error); + } + break; + + case VIRTIO_CRYPTO_AKCIPHER_VERIFY: + if (key_id >= 0) { + ret = keyctl_pkey_verify(key_id, op_desc, + asym_op_info->src, asym_op_info->src_len, + asym_op_info->dst, asym_op_info->dst_len); + } else { + ret = qcrypto_akcipher_verify(akcipher, + asym_op_info->src, asym_op_info->src_len, + asym_op_info->dst, asym_op_info->dst_len, &local_error); + } + break; + + default: + error_setg(&local_error, "Unknown opcode: %u", op_code); + status = -VIRTIO_CRYPTO_ERR; + goto out; + } + + if (ret < 0) { + if (!local_error) { + if (errno != EKEYREJECTED) { + error_report("Failed do operation with keyctl: %d", errno); + } + } else { + error_report_err(local_error); + } + status = op_code == VIRTIO_CRYPTO_AKCIPHER_VERIFY ? + -VIRTIO_CRYPTO_KEY_REJECTED : -VIRTIO_CRYPTO_ERR; + } else { + status = VIRTIO_CRYPTO_OK; + asym_op_info->dst_len = ret; + } + +out: + if (key_id >= 0) { + keyctl_unlink(key_id, KCTL_KEY_RING); + } + task->status = status; + + qemu_mutex_lock(&task->lkcf->rsp_mutex); + if (QSIMPLEQ_EMPTY(&task->lkcf->responses)) { + kick = true; + } + QSIMPLEQ_INSERT_TAIL(&task->lkcf->responses, task, queue); + qemu_mutex_unlock(&task->lkcf->rsp_mutex); + + if (kick) { + eventfd_write(task->lkcf->eventfd, 1); + } +} + +static void *cryptodev_lkcf_worker(void *arg) +{ + CryptoDevBackendLKCF *backend = (CryptoDevBackendLKCF *)arg; + CryptoDevLKCFTask *task; + + for (;;) { + task = NULL; + qemu_mutex_lock(&backend->mutex); + while (backend->running && QSIMPLEQ_EMPTY(&backend->requests)) { + qemu_cond_wait(&backend->cond, &backend->mutex); + } + if (backend->running) { + task = QSIMPLEQ_FIRST(&backend->requests); + QSIMPLEQ_REMOVE_HEAD(&backend->requests, queue); + } + qemu_mutex_unlock(&backend->mutex); + + /* stopped */ + if (!task) { + break; + } + cryptodev_lkcf_execute_task(task); + } + + return NULL; +} + +static int cryptodev_lkcf_operation( + CryptoDevBackend *backend, + CryptoDevBackendOpInfo *op_info, + uint32_t queue_index, + CryptoDevCompletionFunc cb, + void *opaque) +{ + CryptoDevBackendLKCF *lkcf = + CRYPTODEV_BACKEND_LKCF(backend); + CryptoDevBackendLKCFSession *sess; + enum CryptoDevBackendAlgType algtype = op_info->algtype; + CryptoDevLKCFTask *task; + + if (op_info->session_id >= MAX_SESSIONS || + lkcf->sess[op_info->session_id] == NULL) { + error_report("Cannot find a valid session id: %" PRIu64 "", + op_info->session_id); + return -VIRTIO_CRYPTO_INVSESS; + } + + sess = lkcf->sess[op_info->session_id]; + if (algtype != CRYPTODEV_BACKEND_ALG_ASYM) { + error_report("algtype not supported: %u", algtype); + return -VIRTIO_CRYPTO_NOTSUPP; + } + + task = g_new0(CryptoDevLKCFTask, 1); + task->op_info = op_info; + task->cb = cb; + task->opaque = opaque; + task->sess = sess; + task->lkcf = lkcf; + task->status = -VIRTIO_CRYPTO_ERR; + + qemu_mutex_lock(&lkcf->mutex); + QSIMPLEQ_INSERT_TAIL(&lkcf->requests, task, queue); + qemu_mutex_unlock(&lkcf->mutex); + qemu_cond_signal(&lkcf->cond); + + return VIRTIO_CRYPTO_OK; +} + +static int cryptodev_lkcf_create_asym_session( + CryptoDevBackendLKCF *lkcf, + CryptoDevBackendAsymSessionInfo *sess_info, + uint64_t *session_id) +{ + Error *local_error = NULL; + int index; + g_autofree CryptoDevBackendLKCFSession *sess = + g_new0(CryptoDevBackendLKCFSession, 1); + + switch (sess_info->algo) { + case VIRTIO_CRYPTO_AKCIPHER_RSA: + sess->akcipher_opts.alg = QCRYPTO_AKCIPHER_ALG_RSA; + if (cryptodev_lkcf_set_rsa_opt( + sess_info->u.rsa.padding_algo, sess_info->u.rsa.hash_algo, + &sess->akcipher_opts.u.rsa, &local_error) != 0) { + error_report_err(local_error); + return -VIRTIO_CRYPTO_ERR; + } + break; + + default: + error_report("Unsupported asym alg %u", sess_info->algo); + return -VIRTIO_CRYPTO_NOTSUPP; + } + + switch (sess_info->keytype) { + case VIRTIO_CRYPTO_AKCIPHER_KEY_TYPE_PUBLIC: + sess->keytype = QCRYPTO_AKCIPHER_KEY_TYPE_PUBLIC; + break; + + case VIRTIO_CRYPTO_AKCIPHER_KEY_TYPE_PRIVATE: + sess->keytype = QCRYPTO_AKCIPHER_KEY_TYPE_PRIVATE; + break; + + default: + error_report("Unknown akcipher keytype: %u", sess_info->keytype); + return -VIRTIO_CRYPTO_ERR; + } + + index = cryptodev_lkcf_get_unused_session_index(lkcf); + if (index < 0) { + error_report("Total number of sessions created exceeds %u", + MAX_SESSIONS); + return -VIRTIO_CRYPTO_ERR; + } + + sess->keylen = sess_info->keylen; + sess->key = g_malloc(sess_info->keylen); + memcpy(sess->key, sess_info->key, sess_info->keylen); + + lkcf->sess[index] = g_steal_pointer(&sess); + *session_id = index; + + return VIRTIO_CRYPTO_OK; +} + +static int cryptodev_lkcf_create_session( + CryptoDevBackend *backend, + CryptoDevBackendSessionInfo *sess_info, + uint32_t queue_index, + CryptoDevCompletionFunc cb, + void *opaque) +{ + CryptoDevBackendAsymSessionInfo *asym_sess_info; + CryptoDevBackendLKCF *lkcf = + CRYPTODEV_BACKEND_LKCF(backend); + int ret; + + switch (sess_info->op_code) { + case VIRTIO_CRYPTO_AKCIPHER_CREATE_SESSION: + asym_sess_info = &sess_info->u.asym_sess_info; + ret = cryptodev_lkcf_create_asym_session( + lkcf, asym_sess_info, &sess_info->session_id); + break; + + default: + ret = -VIRTIO_CRYPTO_NOTSUPP; + error_report("Unsupported opcode: %" PRIu32 "", + sess_info->op_code); + break; + } + if (cb) { + cb(opaque, ret); + } + return 0; +} + +static int cryptodev_lkcf_close_session(CryptoDevBackend *backend, + uint64_t session_id, + uint32_t queue_index, + CryptoDevCompletionFunc cb, + void *opaque) +{ + CryptoDevBackendLKCF *lkcf = CRYPTODEV_BACKEND_LKCF(backend); + CryptoDevBackendLKCFSession *session; + + assert(session_id < MAX_SESSIONS && lkcf->sess[session_id]); + session = lkcf->sess[session_id]; + lkcf->sess[session_id] = NULL; + + g_free(session->key); + g_free(session); + + if (cb) { + cb(opaque, VIRTIO_CRYPTO_OK); + } + return 0; +} + +static void cryptodev_lkcf_class_init(ObjectClass *oc, void *data) +{ + CryptoDevBackendClass *bc = CRYPTODEV_BACKEND_CLASS(oc); + + bc->init = cryptodev_lkcf_init; + bc->cleanup = cryptodev_lkcf_cleanup; + bc->create_session = cryptodev_lkcf_create_session; + bc->close_session = cryptodev_lkcf_close_session; + bc->do_op = cryptodev_lkcf_operation; +} + +static const TypeInfo cryptodev_builtin_info = { + .name = TYPE_CRYPTODEV_BACKEND_LKCF, + .parent = TYPE_CRYPTODEV_BACKEND, + .class_init = cryptodev_lkcf_class_init, + .instance_size = sizeof(CryptoDevBackendLKCF), +}; + +static void cryptodev_lkcf_register_types(void) +{ + type_register_static(&cryptodev_builtin_info); +} + +type_init(cryptodev_lkcf_register_types); diff --git a/backends/meson.build b/backends/meson.build index b1884a88ec..954e658b25 100644 --- a/backends/meson.build +++ b/backends/meson.build @@ -12,6 +12,9 @@ softmmu_ss.add([files( softmmu_ss.add(when: 'CONFIG_POSIX', if_true: files('rng-random.c')) softmmu_ss.add(when: 'CONFIG_POSIX', if_true: files('hostmem-file.c')) softmmu_ss.add(when: 'CONFIG_LINUX', if_true: files('hostmem-memfd.c')) +if keyutils.found() + softmmu_ss.add(keyutils, files('cryptodev-lkcf.c')) +endif if have_vhost_user softmmu_ss.add(when: 'CONFIG_VIRTIO', if_true: files('vhost-user.c')) endif diff --git a/include/sysemu/cryptodev.h b/include/sysemu/cryptodev.h index 32e9f4cf8a..cf9b3f07fe 100644 --- a/include/sysemu/cryptodev.h +++ b/include/sysemu/cryptodev.h @@ -219,6 +219,7 @@ typedef enum CryptoDevBackendOptionsType { CRYPTODEV_BACKEND_TYPE_NONE = 0, CRYPTODEV_BACKEND_TYPE_BUILTIN = 1, CRYPTODEV_BACKEND_TYPE_VHOST_USER = 2, + CRYPTODEV_BACKEND_TYPE_LKCF = 3, CRYPTODEV_BACKEND_TYPE__MAX, } CryptoDevBackendOptionsType; diff --git a/qapi/qom.json b/qapi/qom.json index 87fcad2423..d2e0244e57 100644 --- a/qapi/qom.json +++ b/qapi/qom.json @@ -876,6 +876,7 @@ 'colo-compare', 'cryptodev-backend', 'cryptodev-backend-builtin', + 'cryptodev-backend-lkcf', { 'name': 'cryptodev-vhost-user', 'if': 'CONFIG_VHOST_CRYPTO' }, 'dbus-vmstate', @@ -944,6 +945,7 @@ 'colo-compare': 'ColoCompareProperties', 'cryptodev-backend': 'CryptodevBackendProperties', 'cryptodev-backend-builtin': 'CryptodevBackendProperties', + 'cryptodev-backend-lkcf': 'CryptodevBackendProperties', 'cryptodev-vhost-user': { 'type': 'CryptodevVhostUserProperties', 'if': 'CONFIG_VHOST_CRYPTO' }, 'dbus-vmstate': 'DBusVMStateProperties', From 87853babb37759bcb144dd18925a340be8fe8244 Mon Sep 17 00:00:00 2001 From: Ani Sinha Date: Fri, 21 Oct 2022 15:21:02 +0530 Subject: [PATCH 537/705] acpi/tests/avocado/bits: initial commit of test scripts that are run by biosbits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is initial commit of cpuid, acpi and smbios python test scripts for biosbits to execute. No change has been made to them from the original code written by the biosbits author Josh Triplett. They are required to be installed into the bits iso file and then run from within the virtual machine booted off with biosbits iso. The test scripts have a ".py2" extension in order to prevent avocado from loading them. They are written in python 2.7 and are run from within bios bits. There is no need for avocado to try to load them and call out errors on python3 specific syntaxes. The original location of these tests are here: https://github.com/biosbits/bits/blob/master/python/testacpi.py https://github.com/biosbits/bits/blob/master/python/smbios.py https://github.com/biosbits/bits/blob/master/python/testcpuid.py For QEMU, we maintain a fork of the above repo here with numerious fixes: https://gitlab.com/qemu-project/biosbits-bits The acpi test for example is maintained here in the fork: https://gitlab.com/qemu-project/biosbits-bits/-/raw/master/python/testacpi.py Cc: Daniel P. Berrangé Cc: Paolo Bonzini Cc: Maydell Peter Cc: John Snow Cc: Thomas Huth Cc: Alex Bennée Cc: Igor Mammedov Cc: Michael Tsirkin Signed-off-by: Ani Sinha Reviewed-by: Alex Bennée Message-Id: <20221021095108.104843-2-ani@anisinha.ca> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- tests/avocado/acpi-bits/bits-tests/smbios.py2 | 2430 +++++++++++++++++ .../avocado/acpi-bits/bits-tests/testacpi.py2 | 283 ++ .../acpi-bits/bits-tests/testcpuid.py2 | 83 + 3 files changed, 2796 insertions(+) create mode 100644 tests/avocado/acpi-bits/bits-tests/smbios.py2 create mode 100644 tests/avocado/acpi-bits/bits-tests/testacpi.py2 create mode 100644 tests/avocado/acpi-bits/bits-tests/testcpuid.py2 diff --git a/tests/avocado/acpi-bits/bits-tests/smbios.py2 b/tests/avocado/acpi-bits/bits-tests/smbios.py2 new file mode 100644 index 0000000000..9667d0542c --- /dev/null +++ b/tests/avocado/acpi-bits/bits-tests/smbios.py2 @@ -0,0 +1,2430 @@ +# Copyright (c) 2015, Intel Corporation +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of Intel Corporation nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""SMBIOS/DMI module.""" + +import bits +import bitfields +import ctypes +import redirect +import struct +import uuid +import unpack +import ttypager +import sys + +class SMBIOS(unpack.Struct): + def __new__(cls): + if sys.platform == "BITS-EFI": + import efi + sm_ptr = efi.system_table.ConfigurationTableDict.get(efi.SMBIOS_TABLE_GUID) + else: + address = 0xF0000 + mem = bits.memory(0xF0000, 0x10000) + for offset in range(0, len(mem), 16): + signature = (ctypes.c_char * 4).from_address(address + offset).value + if signature == "_SM_": + entry_point_length = ctypes.c_ubyte.from_address(address + offset + 5).value + csum = sum(map(ord, mem[offset:offset + entry_point_length])) & 0xff + if csum == 0: + sm_ptr = address + offset + break + else: + return None + + if not sm_ptr: + return None + + sm = super(SMBIOS, cls).__new__(cls) + sm._header_memory = bits.memory(sm_ptr, 0x1f) + return sm + + def __init__(self): + super(SMBIOS, self).__init__() + u = unpack.Unpackable(self._header_memory) + self.add_field('header', Header(u)) + self._structure_memory = bits.memory(self.header.structure_table_address, self.header.structure_table_length) + u = unpack.Unpackable(self._structure_memory) + self.add_field('structures', unpack.unpack_all(u, _smbios_structures, self), unpack.format_each("\n\n{!r}")) + + def structure_type(self, num): + '''Dumps structure of given Type if present''' + try: + types_present = [self.structures[x].smbios_structure_type for x in range(len(self.structures))] + matrix = dict() + for index in range(len(types_present)): + if types_present.count(types_present[index]) == 1: + matrix[types_present[index]] = self.structures[index] + else: # if multiple structures of the same type, return a list of structures for the type number + if matrix.has_key(types_present[index]): + matrix[types_present[index]].append(self.structures[index]) + else: + matrix[types_present[index]] = [self.structures[index]] + return matrix[num] + except: + print "Failure: Type {} - not found".format(num) + +class Header(unpack.Struct): + def __new__(cls, u): + return super(Header, cls).__new__(cls) + + def __init__(self, u): + super(Header, self).__init__() + self.raw_data = u.unpack_rest() + u = unpack.Unpackable(self.raw_data) + self.add_field('anchor_string', u.unpack_one("4s")) + self.add_field('checksum', u.unpack_one("B")) + self.add_field('length', u.unpack_one("B")) + self.add_field('major_version', u.unpack_one("B")) + self.add_field('minor_version', u.unpack_one("B")) + self.add_field('max_structure_size', u.unpack_one(" len(self.strings): + return "(error: string index out of range)" + return self.strings[i - 1] + +class BIOSInformation(SmbiosBaseStructure): + smbios_structure_type = 0 + + def __init__(self, u, sm): + super(BIOSInformation, self).__init__(u, sm) + u = self.u + try: + self.add_field('vendor', u.unpack_one("B"), self.fmtstr) + self.add_field('version', u.unpack_one("B"), self.fmtstr) + self.add_field('starting_address_segment', u.unpack_one("= (2,"4"): + characteristic_bytes = 2 + else: + characteristic_bytes = self.length - 0x12 + self.add_field('characteristics_extensions', [u.unpack_one("B") for b in range(characteristic_bytes)]) + if (sm.header.major_version, minor_version_str) >= (2,"4"): + self.add_field('major_release', u.unpack_one("B")) + self.add_field('minor_release', u.unpack_one("B")) + self.add_field('ec_major_release', u.unpack_one("B")) + self.add_field('ec_minor_release', u.unpack_one("B")) + except: + self.decode_failure = True + print "Error parsing BIOSInformation" + import traceback + traceback.print_exc() + self.fini() + +class SystemInformation(SmbiosBaseStructure): + smbios_structure_type = 1 + + def __init__(self, u, sm): + super(SystemInformation, self).__init__(u, sm) + u = self.u + try: + self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr) + self.add_field('product_name', u.unpack_one("B"), self.fmtstr) + self.add_field('version', u.unpack_one("B"), self.fmtstr) + self.add_field('serial_number', u.unpack_one("B"), self.fmtstr) + if self.length > 0x8: + self.add_field('uuid', uuid.UUID(bytes_le=u.unpack_one("16s"))) + wakeup_types = { + 0: 'Reserved', + 1: 'Other', + 2: 'Unknown', + 3: 'APM Timer', + 4: 'Modem Ring', + 5: 'LAN Remote', + 6: 'Power Switch', + 7: 'PCI PME#', + 8: 'AC Power Restored' + } + self.add_field('wakeup_type', u.unpack_one("B"), unpack.format_table("{}", wakeup_types)) + if self.length > 0x19: + self.add_field('sku_number', u.unpack_one("B"), self.fmtstr) + self.add_field('family', u.unpack_one("B"), self.fmtstr) + except: + self.decode_failure = True + print "Error parsing SystemInformation" + import traceback + traceback.print_exc() + self.fini() + +_board_types = { + 1: 'Unknown', + 2: 'Other', + 3: 'Server Blade', + 4: 'Connectivity Switch', + 5: 'System Management Module', + 6: 'Processor Module', + 7: 'I/O Module', + 8: 'Memory Module', + 9: 'Daughter Board', + 0xA: 'Motherboard', + 0xB: 'Processor/Memory Module', + 0xC: 'Processor/IO Module', + 0xD: 'Interconnect Board' +} + +class BaseboardInformation(SmbiosBaseStructure): + smbios_structure_type = 2 + + def __init__(self, u, sm): + super(BaseboardInformation, self).__init__(u, sm) + u = self.u + try: + self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr) + self.add_field('product', u.unpack_one("B"), self.fmtstr) + self.add_field('version', u.unpack_one("B"), self.fmtstr) + self.add_field('serial_number', u.unpack_one("B"), self.fmtstr) + + if self.length > 0x8: + self.add_field('asset_tag', u.unpack_one("B"), self.fmtstr) + + if self.length > 0x9: + self.add_field('feature_flags', u.unpack_one("B")) + self.add_field('hosting_board', bool(bitfields.getbits(self.feature_flags, 0)), "feature_flags[0]={}") + self.add_field('requires_daughter_card', bool(bitfields.getbits(self.feature_flags, 1)), "feature_flags[1]={}") + self.add_field('removable', bool(bitfields.getbits(self.feature_flags, 2)), "feature_flags[2]={}") + self.add_field('replaceable', bool(bitfields.getbits(self.feature_flags, 3)), "feature_flags[3]={}") + self.add_field('hot_swappable', bool(bitfields.getbits(self.feature_flags, 4)), "feature_flags[4]={}") + + if self.length > 0xA: + self.add_field('location', u.unpack_one("B"), self.fmtstr) + + if self.length > 0xB: + self.add_field('chassis_handle', u.unpack_one(" 0xD: + self.add_field('board_type', u.unpack_one("B"), unpack.format_table("{}", _board_types)) + + if self.length > 0xE: + self.add_field('handle_count', u.unpack_one("B")) + if self.handle_count > 0: + self.add_field('contained_object_handles', tuple(u.unpack_one(" 9: + chassis_states = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'Safe', + 0x04: 'Warning', + 0x05: 'Critical', + 0x06: 'Non-recoverable', + } + self.add_field('bootup_state', u.unpack_one("B"), unpack.format_table("{}", chassis_states)) + self.add_field('power_supply_state', u.unpack_one("B"), unpack.format_table("{}", chassis_states)) + self.add_field('thermal_state', u.unpack_one("B"), unpack.format_table("{}", chassis_states)) + security_states = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'None', + 0x04: 'External interface locked out', + 0x05: 'External interface enabled', + } + self.add_field('security_status', u.unpack_one("B"), unpack.format_table("{}", security_states)) + if self.length > 0xd: + self.add_field('oem_defined', u.unpack_one(" 0x11: + self.add_field('height', u.unpack_one("B")) + self.add_field('num_power_cords', u.unpack_one("B")) + self.add_field('contained_element_count', u.unpack_one("B")) + self.add_field('contained_element_length', u.unpack_one("B")) + if getattr(self, 'contained_element_count', 0): + self.add_field('contained_elements', tuple(SystemEnclosureContainedElement(u, self.contained_element_length) for i in range(self.contained_element_count))) + if self.length > (0x15 + (getattr(self, 'contained_element_count', 0) * getattr(self, 'contained_element_length', 0))): + self.add_field('sku_number', u.unpack_one("B"), self.fmtstr) + except: + self.decode_failure = True + print "Error parsing SystemEnclosure" + import traceback + traceback.print_exc() + self.fini() + +class SystemEnclosureContainedElement(unpack.Struct): + def __init__(self, u, length): + super(SystemEnclosureContainedElement, self).__init__() + self.start_offset = u.offset + self.raw_data = u.unpack_raw(length) + self.u = unpack.Unpackable(self.raw_data) + u = self.u + self.add_field('contained_element_type', u.unpack_one("B")) + type_selections = { + 0: 'SMBIOS baseboard type enumeration', + 1: 'SMBIOS structure type enumeration', + } + self.add_field('type_select', bitfields.getbits(self.contained_element_type, 7), unpack.format_table("contained_element_type[7]={}", type_selections)) + self.add_field('type', bitfields.getbits(self.contained_element_type, 6, 0)) + if self.type_select == 0: + self.add_field('smbios_board_type', self.type, unpack.format_table("{}", _board_types)) + else: + self.add_field('smbios_structure_type', self.type) + self.add_field('minimum', u.unpack_one("B")) + self.add_field('maximum', u.unpack_one("B")) + if not u.at_end(): + self.add_field('data', u.unpack_rest()) + del self.u + +class ProcessorInformation(SmbiosBaseStructure): + smbios_structure_type = 4 + + def __init__(self, u, sm): + super(ProcessorInformation, self).__init__(u, sm) + u = self.u + try: + self.add_field('socket_designation', u.unpack_one("B"), self.fmtstr) + processor_types = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'Central Processor', + 0x04: 'Math Processor', + 0x05: 'DSP Processor', + 0x06: 'Video Processor', + } + self.add_field('processor_type', u.unpack_one("B"), unpack.format_table("{}", processor_types)) + self.add_field('processor_family', u.unpack_one("B")) + self.add_field('processor_manufacturer', u.unpack_one("B"), self.fmtstr) + self.add_field('processor_id', u.unpack_one(" 0x1A: + self.add_field('l1_cache_handle', u.unpack_one(" 0x20: + self.add_field('serial_number', u.unpack_one("B"), self.fmtstr) + self.add_field('asset_tag', u.unpack_one("B"), self.fmtstr) + self.add_field('part_number', u.unpack_one("B"), self.fmtstr) + if self.length > 0x24: + self.add_field('core_count', u.unpack_one("B")) + self.add_field('core_enabled', u.unpack_one("B")) + self.add_field('thread_count', u.unpack_one("B")) + self.add_field('processor_characteristics', u.unpack_one(" 0x28: + self.add_field('processor_family_2', u.unpack_one(" 0x2A: + self.add_field('core_count2', u.unpack_one(" 0x0F: + self.add_field('cache_speed', u.unpack_one("B")) + if self.length > 0x10: + _error_correction = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'None', + 0x04: 'Parity', + 0x05: 'Single-bit ECC', + 0x06: 'Multi-bit ECC' + } + self.add_field('error_correction', u.unpack_one("B"), unpack.format_table("{}", _error_correction)) + if self.length > 0x10: + _system_cache_type = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'Instruction', + 0x04: 'Data', + 0x05: 'Unified' + } + self.add_field('system_cache_type', u.unpack_one("B"), unpack.format_table("{}", _system_cache_type)) + if self.length > 0x12: + _associativity = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'Direct Mapped', + 0x04: '2-way Set-Associative', + 0x05: '4-way Set-Associative', + 0x06: 'Fully Associative', + 0x07: '8-way Set-Associative', + 0x08: '16-way Set-Associative', + 0x09: '12-way Set-Associative', + 0x0A: '24-way Set-Associative', + 0x0B: '32-way Set-Associative', + 0x0C: '48-way Set-Associative', + 0x0D: '64-way Set-Associative', + 0x0E: '20-way Set-Associative' + } + self.add_field('associativity', u.unpack_one("B"), unpack.format_table("{}", _associativity)) + + except: + self.decode_failure = True + print "Error parsing CacheInformation" + import traceback + traceback.print_exc() + self.fini() + +class PortConnectorInfo(SmbiosBaseStructure): + smbios_structure_type = 8 + + def __init__(self, u, sm): + super(PortConnectorInfo, self).__init__(u, sm) + u = self.u + try: + self.add_field('internal_reference_designator', u.unpack_one("B"), self.fmtstr) + connector_types = { + 0x00: 'None', + 0x01: 'Centronics', + 0x02: 'Mini Centronics', + 0x03: 'Proprietary', + 0x04: 'DB-25 pin male', + 0x05: 'DB-25 pin female', + 0x06: 'DB-15 pin male', + 0x07: 'DB-15 pin female', + 0x08: 'DB-9 pin male', + 0x09: 'DB-9 pin female', + 0x0A: 'RJ-11', + 0x0B: 'RJ-45', + 0x0C: '50-pin MiniSCSI', + 0x0D: 'Mini-DIN', + 0x0E: 'Micro-DIN', + 0x0F: 'PS/2', + 0x10: 'Infrared', + 0x11: 'HP-HIL', + 0x12: 'Access Bus (USB)', + 0x13: 'SSA SCSI', + 0x14: 'Circular DIN-8 male', + 0x15: 'Circular DIN-8 female', + 0x16: 'On Board IDE', + 0x17: 'On Board Floppy', + 0x18: '9-pin Dual Inline (pin 10 cut)', + 0x19: '25-pin Dual Inline (pin 26 cut)', + 0x1A: '50-pin Dual Inline', + 0x1B: '68-pin Dual Inline', + 0x1C: 'On Board Sound Input from CD-ROM', + 0x1D: 'Mini-Centronics Type-14', + 0x1E: 'Mini-Centronics Type-26', + 0x1F: 'Mini-jack (headphones)', + 0x20: 'BNC', + 0x21: '1394', + 0x22: 'SAS/SATA Plug Receptacle', + 0xA0: 'PC-98', + 0xA1: 'PC-98Hireso', + 0xA2: 'PC-H98', + 0xA3: 'PC-98Note', + 0xA4: 'PC-98Full', + 0xFF: 'Other', + } + self.add_field('internal_connector_type', u.unpack_one("B"), unpack.format_table("{}", connector_types)) + self.add_field('external_reference_designator', u.unpack_one("B"), self.fmtstr) + self.add_field('external_connector_type', u.unpack_one("B"), unpack.format_table("{}", connector_types)) + port_types = { + 0x00: 'None', + 0x01: 'Parallel Port XT/AT Compatible', + 0x02: 'Parallel Port PS/2', + 0x03: 'Parallel Port ECP', + 0x04: 'Parallel Port EPP', + 0x05: 'Parallel Port ECP/EPP', + 0x06: 'Serial Port XT/AT Compatible', + 0x07: 'Serial Port 16450 Compatible', + 0x08: 'Serial Port 16550 Compatible', + 0x09: 'Serial Port 16550A Compatible', + 0x0A: 'SCSI Port', + 0x0B: 'MIDI Port', + 0x0C: 'Joy Stick Port', + 0x0D: 'Keyboard Port', + 0x0E: 'Mouse Port', + 0x0F: 'SSA SCSI', + 0x10: 'USB', + 0x11: 'FireWire (IEEE P1394)', + 0x12: 'PCMCIA Type I2', + 0x13: 'PCMCIA Type II', + 0x14: 'PCMCIA Type III', + 0x15: 'Cardbus', + 0x16: 'Access Bus Port', + 0x17: 'SCSI II', + 0x18: 'SCSI Wide', + 0x19: 'PC-98', + 0x1A: 'PC-98-Hireso', + 0x1B: 'PC-H98', + 0x1C: 'Video Port', + 0x1D: 'Audio Port', + 0x1E: 'Modem Port', + 0x1F: 'Network Port', + 0x20: 'SATA', + 0x21: 'SAS', + 0xA0: '8251 Compatible', + 0xA1: '8251 FIFO Compatible', + 0xFF: 'Other', + } + self.add_field('port_type', u.unpack_one("B"), unpack.format_table("{}", port_types)) + except: + self.decodeFailure = True + print "Error parsing PortConnectorInfo" + import traceback + traceback.print_exc() + self.fini() + +class SystemSlots(SmbiosBaseStructure): + smbios_structure_type = 9 + + def __init__(self, u, sm): + super(SystemSlots, self).__init__(u, sm) + u = self.u + try: + self.add_field('designation', u.unpack_one("B"), self.fmtstr) + _slot_types = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'ISA', + 0x04: 'MCA', + 0x05: 'EISA', + 0x06: 'PCI', + 0x07: 'PC Card (PCMCIA)', + 0x08: 'VL-VESA', + 0x09: 'Proprietary', + 0x0A: 'Processor Card Slot', + 0x0B: 'Proprietary Memory Card Slot', + 0x0C: 'I/O Riser Card Slot', + 0x0D: 'NuBus', + 0x0E: 'PCI 66MHz Capable', + 0x0F: 'AGP', + 0x10: 'AGP 2X', + 0x11: 'AGP 4X', + 0x12: 'PCI-X', + 0x13: 'AGP 8X', + 0xA0: 'PC-98/C20', + 0xA1: 'PC-98/C24', + 0xA2: 'PC-98/E', + 0xA3: 'PC-98/Local Bus', + 0xA4: 'PC-98/Card', + 0xA5: 'PCI Express', + 0xA6: 'PCI Express x1', + 0xA7: 'PCI Express x2', + 0xA8: 'PCI Express x4', + 0xA9: 'PCI Express x8', + 0xAA: 'PCI Express x16', + 0xAB: 'PCI Express Gen 2', + 0xAC: 'PCI Express Gen 2 x1', + 0xAD: 'PCI Express Gen 2 x2', + 0xAE: 'PCI Express Gen 2 x4', + 0xAF: 'PCI Express Gen 2 x8', + 0xB0: 'PCI Express Gen 2 x16', + 0xB1: 'PCI Express Gen 3', + 0xB2: 'PCI Express Gen 3 x1', + 0xB3: 'PCI Express Gen 3 x2', + 0xB4: 'PCI Express Gen 3 x4', + 0xB5: 'PCI Express Gen 3 x8', + 0xB6: 'PCI Express Gen 3 x16', + } + self.add_field('slot_type', u.unpack_one("B"), unpack.format_table("{}", _slot_types)) + _slot_data_bus_widths = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: '8 bit', + 0x04: '16 bit', + 0x05: '32 bit', + 0x06: '64 bit', + 0x07: '128 bit', + 0x08: '1x or x1', + 0x09: '2x or x2', + 0x0A: '4x or x4', + 0x0B: '8x or x8', + 0x0C: '12x or x12', + 0x0D: '16x or x16', + 0x0E: '32x or x32', + } + self.add_field('slot_data_bus_width', u.unpack_one('B'), unpack.format_table("{}", _slot_data_bus_widths)) + _current_usages = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'Available', + 0x04: 'In use', + } + self.add_field('current_usage', u.unpack_one('B'), unpack.format_table("{}", _current_usages)) + _slot_lengths = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'Short Length', + 0x04: 'Long Length', + } + self.add_field('slot_length', u.unpack_one('B'), unpack.format_table("{}", _slot_lengths)) + self.add_field('slot_id', u.unpack_one(' 0x0C: + self.add_field('characteristics2', u.unpack_one('B')) + self.add_field('supports_PME', bool(bitfields.getbits(self.characteristics2, 0)), "characteristics2[0]={}") + self.add_field('supports_hot_plug', bool(bitfields.getbits(self.characteristics2, 1)), "characteristics2[1]={}") + self.add_field('supports_smbus', bool(bitfields.getbits(self.characteristics2, 2)), "characteristics2[2]={}") + if self.length > 0x0D: + self.add_field('segment_group_number', u.unpack_one(' 0x05: + self.add_field('flags', u.unpack_one('B')) + self.add_field('abbreviated_format', bool(bitfields.getbits(self.flags, 0)), "flags[0]={}") + if self.length > 0x6: + u.skip(15) + self.add_field('current_language', u.unpack_one('B'), self.fmtstr) + except: + self.decodeFailure = True + print "Error parsing BIOSLanguageInformation" + import traceback + traceback.print_exc() + self.fini() + +class GroupAssociations(SmbiosBaseStructure): + smbios_structure_type = 14 + + def __init__(self, u, sm): + super(GroupAssociations, self).__init__(u, sm) + u = self.u + try: + self.add_field('group_name', u.unpack_one("B"), self.fmtstr) + self.add_field('item_type', u.unpack_one('B')) + self.add_field('item_handle', u.unpack_one(' 0x14: + _log_header_formats = { + 0: 'No header', + 1: 'Type 1 log header', + xrange(2, 0x7f): 'Available for future assignment', + xrange(0x80, 0xff): 'BIOS vendor or OEM-specific format' + } + self.add_field('log_header_format', u.unpack_one("B"), unpack.format_table("{}", _log_header_formats)) + if self.length > 0x15: + self.add_field('num_supported_log_type_descriptors', u.unpack_one('B')) + if self.length > 0x16: + self.add_field('length_log_type_descriptor', u.unpack_one('B')) + if self.length != (0x17 + (self.num_supported_log_type_descriptors * self.length_log_type_descriptor)): + print "Error: structure length ({}) != 0x17 + (num_supported_log_type_descriptors ({}) * length_log_type_descriptor({}))".format(self.length, self.num_supported_log_type_descriptors, self.length_log_type_descriptor) + print "structure length = {}".format(self.length) + print "num_supported_log_type_descriptors = {}".format(self.num_supported_log_type_descriptors) + print "length_log_type_descriptor = {}".format(self.length_log_type_descriptor) + self.decodeFailure = True + self.add_field('descriptors', tuple(EventLogDescriptor.unpack(u) for i in range(self.num_supported_log_type_descriptors)), unpack.format_each("\n{!r}")) + except: + self.decodeFailure = True + print "Error parsing SystemEventLog" + import traceback + traceback.print_exc() + self.fini() + +class EventLogDescriptor(unpack.Struct): + @staticmethod + def _unpack(u): + _event_log_type_descriptors = { + 0x00: 'Reserved', + 0x01: 'Single-bit ECC memory error', + 0x02: 'Multi-bit ECC memory error', + 0x03: 'Parity memory error', + 0x04: 'Bus time-out', + 0x05: 'I/O Channel Check', + 0x06: 'Software NMI', + 0x07: 'POST Memory Resize', + 0x08: 'POST Error', + 0x09: 'PCI Parity Error', + 0x0A: 'PCI System Error', + 0x0B: 'CPU Failure', + 0x0C: 'EISA FailSafe Timer time-out', + 0x0D: 'Correctable memory log disabled', + 0x0E: 'Logging disabled for a specific Event Type - too many errors of the same type received in a short amount of time', + 0x0F: 'Reserved', + 0x10: 'System Limit Exceeded', + 0x11: 'Asynchronous hardware timer expired and issued a system reset', + 0x12: 'System configuration information', + 0x13: 'Hard-disk information', + 0x14: 'System reconfigured', + 0x15: 'Uncorrectable CPU-complex error', + 0x16: 'Log Area Reset/Cleared', + 0x17: 'System boot', + xrange(0x18, 0x7F): 'Unused, available for assignment', + xrange(0x80, 0xFE): 'Availalbe for system- and OEM-specific assignments', + 0xFF: 'End of log' + } + yield 'log_type', u.unpack_one('B'), unpack.format_table("{}", _event_log_type_descriptors) + _event_log_format = { + 0x00: 'None', + 0x01: 'Handle', + 0x02: 'Multiple-Event', + 0x03: 'Multiple-Event Handle', + 0x04: 'POST Results Bitmap', + 0x05: 'System Management Type', + 0x06: 'Multiple-Event System Management Type', + xrange(0x80, 0xFF): 'OEM assigned' + } + yield 'variable_data_format_type', u.unpack_one('B'), unpack.format_table("{}", _event_log_format) + +class PhysicalMemoryArray(SmbiosBaseStructure): + smbios_structure_type = 16 + + def __init__(self, u, sm): + super(PhysicalMemoryArray, self).__init__(u, sm) + u = self.u + try: + if self.length > 0x4: + _location_field = { + 0x01: "Other", + 0x02: "Unknown", + 0x03: "System board or motherboard", + 0x04: "ISA add-on card", + 0x05: "EISA add-on card", + 0x06: "PCI add-on card", + 0x07: "MCA add-on card", + 0x08: "PCMCIA add-on card", + 0x09: "Proprietary add-on card", + 0x0A: "NuBus", + 0xA0: "PC-98/C20 add-on card", + 0xA1: "PC-98/C24 add-on card", + 0xA2: "PC-98/E add-on card", + 0xA3: "PC-98/Local bus add-on card" + } + self.add_field('location', u.unpack_one("B"), unpack.format_table("{}", _location_field)) + if self.length > 0x05: + _use = { + 0x01: "Other", + 0x02: "Unknown", + 0x03: "System memory", + 0x04: "Video memory", + 0x05: "Flash memory", + 0x06: "Non-volatile RAM", + 0x07: "Cache memory" + } + self.add_field('use', u.unpack_one('B'), unpack.format_table("{}", _use)) + if self.length > 0x06: + _error_correction = { + 0x01: "Other", + 0x02: "Unknown", + 0x03: "None", + 0x04: "Parity", + 0x05: "Single-bit ECC", + 0x06: "Multi-bit ECC", + 0x07: "CRC" + } + self.add_field('memory_error_correction', u.unpack_one('B'), unpack.format_table("{}", _error_correction)) + if self.length > 0x07: + self.add_field('maximum_capacity', u.unpack_one(' 0x0B: + self.add_field('memory_error_information_handle', u.unpack_one(' 0x0D: + self.add_field('num_memory_devices', u.unpack_one(' 0x0F: + self.add_field('extended_maximum_capacity', u.unpack_one(' 0x4: + self.add_field('physical_memory_array_handle', u.unpack_one(" 0x6: + self.add_field('memory_error_information_handle', u.unpack_one(" 0x8: + self.add_field('total_width', u.unpack_one(" 0xA: + self.add_field('data_width', u.unpack_one(" 0xC: + self.add_field('size', u.unpack_one(" 0xE: + _form_factors = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'SIMM', + 0x04: 'SIP', + 0x05: 'Chip', + 0x06: 'DIP', + 0x07: 'ZIP', + 0x08: 'Proprietary Card', + 0x09: 'DIMM', + 0x0A: 'TSOP', + 0x0B: 'Row of chips', + 0x0C: 'RIMM', + 0x0D: 'SODIMM', + 0x0E: 'SRIMM', + 0x0F: 'FB-DIMM' + } + self.add_field('form_factor', u.unpack_one("B"), unpack.format_table("{}", _form_factors)) + if self.length > 0xF: + self.add_field('device_set', u.unpack_one("B")) + if self.length > 0x10: + self.add_field('device_locator', u.unpack_one("B"), self.fmtstr) + if self.length > 0x11: + self.add_field('bank_locator', u.unpack_one("B"), self.fmtstr) + if self.length > 0x12: + _memory_types = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'DRAM', + 0x04: 'EDRAM', + 0x05: 'VRAM', + 0x06: 'SRAM', + 0x07: 'RAM', + 0x08: 'ROM', + 0x09: 'FLASH', + 0x0A: 'EEPROM', + 0x0B: 'FEPROM', + 0x0C: 'EPROM', + 0x0D: 'CDRAM', + 0x0E: '3DRAM', + 0x0F: 'SDRAM', + 0x10: 'SGRAM', + 0x11: 'RDRAM', + 0x12: 'DDR', + 0x13: 'DDR2', + 0x14: 'DDR2 FB-DIMM', + xrange(0x15, 0x17): 'Reserved', + 0x18: 'DDR3', + 0x19: 'FBD2' + } + self.add_field('memory_type', u.unpack_one("B"), unpack.format_table("{}", _memory_types)) + if self.length > 0x13: + self.add_field('type_detail', u.unpack_one(' 0x15: + self.add_field('speed', u.unpack_one(" 0x17: + self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr) + if self.length > 0x18: + self.add_field('serial_number', u.unpack_one("B"), self.fmtstr) + if self.length > 0x19: + self.add_field('asset_tag', u.unpack_one("B"), self.fmtstr) + if self.length > 0x1A: + self.add_field('part_number', u.unpack_one("B"), self.fmtstr) + if self.length > 0x1B: + self.add_field('attributes', u.unpack_one("B")) + self.add_field('rank', bitfields.getbits(self.attributes, 3, 0), "attributes[3:0]={}") + if self.length > 0x1C: + if self.size == 0x7FFF: + self.add_field('extended_size', u.unpack_one(' 0x20: + self.add_field('configured_memory_clock_speed', u.unpack_one(" 0x22: + self.add_field('minimum_voltage', u.unpack_one(" 0x24: + self.add_field('maximum_voltage', u.unpack_one(" 0x26: + self.add_field('configured_voltage', u.unpack_one(" 0x4: + _error_types = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'OK', + 0x04: 'Bad read', + 0x05: 'Parity error', + 0x06: 'Single-bit error', + 0x07: 'Double-bit error', + 0x08: 'Multi-bit error', + 0x09: 'Nibble error', + 0x0A: 'Checksum error', + 0x0B: 'CRC error', + 0x0C: 'Corrected single-bit error', + 0x0D: 'Corrected error', + 0x0E: 'Uncorrectable error' + } + self.add_field('error_type', u.unpack_one("B"), unpack.format_table("{}", _error_types)) + if self.length > 0x5: + _error_granularity_field = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'Device level', + 0x04: 'Memory partition level' + } + self.add_field('error_granularity', u.unpack_one("B"), unpack.format_table("{}", _error_granularity_field)) + if self.length > 0x6: + _error_operation_field = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'Read', + 0x04: 'Write', + 0x05: 'Partial write' + } + self.add_field('error_operation', u.unpack_one("B"), unpack.format_table("{}", _error_operation_field)) + if self.length > 0x7: + self.add_field('vendor_syndrome', u.unpack_one(" 0xB: + self.add_field('memory_array_error_address', u.unpack_one(" 0xF: + self.add_field('device_error_address', u.unpack_one(" 0x13: + self.add_field('error_resolution', u.unpack_one(" 0x4: + self.add_field('starting_address', u.unpack_one(" 0x8: + self.add_field('ending_address', u.unpack_one(" 0xC: + self.add_field('memory_array_handle', u.unpack_one(" 0xE: + self.add_field('partition_width', u.unpack_one("B")) + if self.length > 0xF: + # valid if starting_address = FFFF FFFF + if self.starting_address == 0xFFFFFFFF: + self.add_field('extended_starting_address', u.unpack_one(" 0x17: + self.add_field('extended_ending_address', u.unpack_one(" 0x4: + self.add_field('starting_address', u.unpack_one(" 0x8: + self.add_field('ending_address', u.unpack_one(" 0xC: + self.add_field('memory_device_handle', u.unpack_one(" 0xE: + self.add_field('memory_array_mapped_address_handle', u.unpack_one(" 0x10: + self.add_field('partition_row_position', u.unpack_one("B")) + if self.length > 0x11: + self.add_field('interleave_position', u.unpack_one("B")) + if self.length > 0x12: + self.add_field('interleave_data_depth', u.unpack_one("B")) + if self.length > 0x13: + # valid if starting_address = FFFF FFFF + if self.starting_address == 0xFFFFFFFF: + self.add_field('extended_starting_address', u.unpack_one(" 0x1B: + self.add_field('extended_ending_address', u.unpack_one(" 0x4: + _pointing_device_types = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'Mouse', + 0x04: 'Track Ball', + 0x05: 'Track Point', + 0x06: 'Glide Point', + 0x07: 'Touch Pad', + 0x08: 'Touch Screen', + 0x09: 'Optical Sensor' + } + self.add_field('pointing_device_type', u.unpack_one("B"), unpack.format_table("{}", _pointing_device_types)) + if self.length > 0x5: + _interfaces = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'Serial', + 0x04: 'PS/2', + 0x05: 'Infared', + 0x06: 'HP-HIL', + 0x07: 'Bus mouse', + 0x08: 'ADB (Apple Desktop Bus)', + 0x09: 'Bus mouse DB-9', + 0x0A: 'Bus mouse micro-DIN', + 0x0B: 'USB' + } + self.add_field('interface', u.unpack_one("B"), unpack.format_table("{}", _interfaces)) + if self.length > 0x6: + self.add_field('num_buttons', u.unpack_one("B")) + except: + self.decodeFailure = True + print "Error parsing BuiltInPointingDevice" + import traceback + traceback.print_exc() + self.fini() + +class PortableBattery(SmbiosBaseStructure): + smbios_structure_type = 22 + + def __init__(self, u, sm): + super(PortableBattery, self).__init__(u, sm) + u = self.u + try: + if self.length > 0x4: + self.add_field('location', u.unpack_one("B"), self.fmtstr) + if self.length > 0x5: + self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr) + if self.length > 0x6: + self.add_field('manufacturer_date', u.unpack_one("B"), self.fmtstr) + if self.length > 0x7: + self.add_field('serial_number', u.unpack_one("B"), self.fmtstr) + if self.length > 0x8: + self.add_field('device_name', u.unpack_one("B"), self.fmtstr) + if self.length > 0x9: + _device_chemistry = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'Lead Acid', + 0x04: 'Nickel Cadmium', + 0x05: 'Nickel metal hydride', + 0x06: 'Lithium-ion', + 0x07: 'Zinc air', + 0x08: 'Lithium Polymer' + } + self.add_field('device_chemistry', u.unpack_one("B"), unpack.format_table("{}", _device_chemistry)) + if self.length > 0xA: + self.add_field('design_capacity', u.unpack_one(" 0xC: + self.add_field('design_voltage', u.unpack_one(" 0xE: + self.add_field('sbds_version_number', u.unpack_one("B"), self.fmtstr) + if self.length > 0xF: + self.add_field('max_error_battery_data', u.unpack_one("B"), self.fmtstr) + if self.length > 0x10: + if self.serial_number == 0: + self.add_field('sbds_serial_number', u.unpack_one(" 0x12: + if self.manufacturer_date == 0: + self.add_field('sbds_manufacture_date', u.unpack_one(" 0x14: + if self.device_chemistry == 0x02: + self.add_field('sbds_device_chemistry', u.unpack_one("B"), self.fmtstr) + else: + u.skip(1) + if self.length > 0x15: + self.add_field('design_capacity_multiplier', u.unpack_one("B")) + if self.length > 0x16: + self.add_field('oem_specific', u.unpack_one(" 0x4: + self.add_field('capabilities', u.unpack_one("B")) + self.add_field('contains_watchdog_timer', bool(bitfields.getbits(self.capabilities, 5)), "capabilities[5]={}") + _boot_option = { + 0b00: 'Reserved, do not use', + 0b01: 'Operating System', + 0b10: 'System utilities', + 0b11: 'Do not reboot' + } + self.add_field('boot_option_on_limit', bitfields.getbits(self.capabilities, 4, 3), unpack.format_table("capabilities[4:3]={}", _boot_option)) + self.add_field('boot_option_after_watchdog_reset', bitfields.getbits(self.capabilities, 2, 1), unpack.format_table("capabilities[2:1]={}", _boot_option)) + self.add_field('system_reset_enabled_by_user', bool(bitfields.getbits(self.capabilities, 0)), "capabilities[0]={}") + if self.length > 0x5: + self.add_field('reset_count', u.unpack_one(" 0x5: + self.add_field('reset_limit', u.unpack_one(" 0x9: + self.add_field('timer_interval', u.unpack_one(" 0xB: + self.add_field('timeout', u.unpack_one(" 0x4: + self.add_field('hardware_security_settings', u.unpack_one("B")) + _status = { + 0x00: 'Disabled', + 0x01: 'Enabled', + 0x02: 'Not Implemented', + 0x03: 'Unknown' + } + self.add_field('power_on_password_status', bitfields.getbits(self.hardware_security_settings, 7, 6), unpack.format_table("hardware_security_settings[7:6]={}", _status)) + self.add_field('keyboard_password_status', bitfields.getbits(self.hardware_security_settings, 5, 4), unpack.format_table("hardware_security_settings[5:4]={}", _status)) + self.add_field('admin_password_status', bitfields.getbits(self.hardware_security_settings, 3, 2), unpack.format_table("hardware_security_settings0[3:2]={}", _status)) + self.add_field('front_panel_reset_status', bitfields.getbits(self.hardware_security_settings, 1, 0), unpack.format_table("hardware_security_settings[1:0]={}", _status)) + except: + self.decodeFailure = True + print "Error parsing HardwareSecurity" + import traceback + traceback.print_exc() + self.fini() + +class SystemPowerControls(SmbiosBaseStructure): + smbios_structure_type = 25 + + def __init__(self, u, sm): + super(SystemPowerControls, self).__init__(u, sm) + u = self.u + try: + if self.length > 0x4: + self.add_field('next_scheduled_poweron_month', u.unpack_one("B")) + self.add_field('next_scheduled_poweron_day_of_month', u.unpack_one("B")) + self.add_field('next_scheduled_poweron_hour', u.unpack_one("B")) + self.add_field('next_scheduled_poweron_minute', u.unpack_one("B")) + self.add_field('next_scheduled_poweron_second', u.unpack_one("B")) + except: + self.decodeFailure = True + print "Error parsing SystemPowerControls" + import traceback + traceback.print_exc() + self.fini() + +class VoltageProbe(SmbiosBaseStructure): + smbios_structure_type = 26 + + def __init__(self, u, sm): + super(VoltageProbe, self).__init__(u, sm) + u = self.u + try: + if self.length > 0x4: + self.add_field('description', u.unpack_one("B"), self.fmtstr) + if self.length > 0x5: + self.add_field('location_and_status', u.unpack_one("B")) + _status = { + 0b001: 'Other', + 0b010: 'Unknown', + 0b011: 'OK', + 0b100: 'Non-critical', + 0b101: 'Critical', + 0b110: 'Non-recoverable' + } + _location = { + 0b00001: 'Other', + 0b00010: 'Unknown', + 0b00011: 'Processor', + 0b00100: 'Disk', + 0b00101: 'Peripheral Bay', + 0b00110: 'System Management Module', + 0b00111: 'Motherboard', + 0b01000: 'Memory Module', + 0b01001: 'Processor Module', + 0b01010: 'Power Unit', + 0b01011: 'Add-in Card' + } + self.add_field('status', bitfields.getbits(self.location_and_status, 7, 5), unpack.format_table("location_and_status[7:5]={}", _status)) + self.add_field('location', bitfields.getbits(self.location_and_status, 4, 0), unpack.format_table("location_and_status[4:0]={}", _location)) + if self.length > 0x6: + self.add_field('max_value', u.unpack_one(" 0x8: + self.add_field('min_value', u.unpack_one(" 0xA: + self.add_field('resolution', u.unpack_one(" 0xC: + self.add_field('tolerance', u.unpack_one(" 0xE: + self.add_field('accuracy', u.unpack_one(" 0x10: + self.add_field('oem_defined', u.unpack_one(" 0x14: + self.add_field('nominal_value', u.unpack_one(" 0x4: + self.add_field('temperature_probe_handle', u.unpack_one(" 0x6: + self.add_field('device_type_and_status', u.unpack_one("B")) + _status = { + 0b001: 'Other', + 0b010: 'Unknown', + 0b011: 'OK', + 0b100: 'Non-critical', + 0b101: 'Critical', + 0b110: 'Non-recoverable' + } + _type = { + 0b00001: 'Other', + 0b00010: 'Unknown', + 0b00011: 'Fan', + 0b00100: 'Centrifugal Blower', + 0b00101: 'Chip Fan', + 0b00110: 'Cabinet Fan', + 0b00111: 'Power Supply Fan', + 0b01000: 'Heat Pipe', + 0b01001: 'Integrated Refrigeration', + 0b10000: 'Active Cooling', + 0b10001: 'Passive Cooling' + } + self.add_field('status', bitfields.getbits(self.device_type_and_status, 7, 5), unpack.format_table("device_type_and_status[7:5]={}", _status)) + self.add_field('device_type', bitfields.getbits(self.device_type_and_status, 4, 0), unpack.format_table("device_type_and_status[4:0]={}", _type)) + if self.length > 0x7: + self.add_field('cooling_unit_group', u.unpack_one("B")) + if self.length > 0x8: + self.add_field('OEM_defined', u.unpack_one(" 0xC: + self.add_field('nominal_speed', u.unpack_one(" 0xE: + self.add_field('description', u.unpack_one("B"), self.fmtstr) + except: + self.decodeFailure = True + print "Error parsing CoolingDevice" + import traceback + traceback.print_exc() + self.fini() + +class TemperatureProbe(SmbiosBaseStructure): + smbios_structure_type = 28 + + def __init__(self, u, sm): + super(TemperatureProbe, self).__init__(u, sm) + u = self.u + try: + if self.length > 0x4: + self.add_field('description', u.unpack_one("B"), self.fmtstr) + if self.length > 0x5: + self.add_field('location_and_status', u.unpack_one("B")) + _status = { + 0b001: 'Other', + 0b010: 'Unknown', + 0b011: 'OK', + 0b100: 'Non-critical', + 0b101: 'Critical', + 0b110: 'Non-recoverable' + } + _location = { + 0b00001: 'Other', + 0b00010: 'Unknown', + 0b00011: 'Processor', + 0b00100: 'Disk', + 0b00101: 'Peripheral Bay', + 0b00110: 'System Management Module', + 0b00111: 'Motherboard', + 0b01000: 'Memory Module', + 0b01001: 'Processor Module', + 0b01010: 'Power Unit', + 0b01011: 'Add-in Card', + 0b01100: 'Front Panel Board', + 0b01101: 'Back Panel Board', + 0b01110: 'Power System Board', + 0b01111: 'Drive Back Plane' + } + self.add_field('status', bitfields.getbits(self.location_and_status, 7, 5), unpack.format_table("location_and_status[7:5]={}", _status)) + self.add_field('location', bitfields.getbits(self.location_and_status, 4, 0), unpack.format_table("location_and_status[4:0]={}", _location)) + if self.length > 0x6: + self.add_field('maximum_value', u.unpack_one(" 0x8: + self.add_field('minimum_value', u.unpack_one(" 0xA: + self.add_field('resolution', u.unpack_one(" 0xC: + self.add_field('tolerance', u.unpack_one(" 0xE: + self.add_field('accuracy', u.unpack_one(" 0x10: + self.add_field('OEM_defined', u.unpack_one(" 0x14: + self.add_field('nominal_value', u.unpack_one(" 0x4: + self.add_field('description', u.unpack_one("B"), self.fmtstr) + if self.length > 0x5: + self.add_field('location_and_status', u.unpack_one("B")) + _status = { + 0b001: 'Other', + 0b010: 'Unknown', + 0b011: 'OK', + 0b100: 'Non-critical', + 0b101: 'Critical', + 0b110: 'Non-recoverable' + } + _location = { + 0b00001: 'Other', + 0b00010: 'Unknown', + 0b00011: 'Processor', + 0b00100: 'Disk', + 0b00101: 'Peripheral Bay', + 0b00110: 'System Management Module', + 0b00111: 'Motherboard', + 0b01000: 'Memory Module', + 0b01001: 'Processor Module', + 0b01010: 'Power Unit', + 0b01011: 'Add-in Card', + 0b01100: 'Front Panel Board', + 0b01101: 'Back Panel Board', + 0b01110: 'Power System Board', + 0b01111: 'Drive Back Plane' + } + self.add_field('status', bitfields.getbits(self.location_and_status, 7, 5), unpack.format_table("location_and_status[7:5]={}", _status)) + self.add_field('location', bitfields.getbits(self.location_and_status, 4, 0), unpack.format_table("location_and_status[4:0]={}", _location)) + if self.length > 0x6: + self.add_field('maximum_value', u.unpack_one(" 0x8: + self.add_field('minimum_value', u.unpack_one(" 0xA: + self.add_field('resolution', u.unpack_one(" 0xC: + self.add_field('tolerance', u.unpack_one(" 0xE: + self.add_field('accuracy', u.unpack_one(" 0x10: + self.add_field('OEM_defined', u.unpack_one(" 0x14: + self.add_field('nominal_value', u.unpack_one(" 0x4: + self.add_field('manufacturer_name', u.unpack_one("B"), self.fmtstr) + if self.length > 0x5: + self.add_field('connections', u.unpack_one("B")) + self.add_field('outbound_connection_enabled', bool(bitfields.getbits(self.connections, 1)), "connections[1]={}") + self.add_field('inbound_connection_enabled', bool(bitfields.getbits(self.connections, 0)), "connections[0]={}") + except: + self.decodeFailure = True + print "Error parsing OutOfBandRemoteAccess" + import traceback + traceback.print_exc() + self.fini() + +class BootIntegrityServicesEntryPoint(SmbiosBaseStructure): + smbios_structure_type = 31 + +class SystemBootInformation(SmbiosBaseStructure): + smbios_structure_type = 32 + + def __init__(self, u, sm): + super(SystemBootInformation, self).__init__(u, sm) + u = self.u + try: + if self.length > 0xA: + u.skip(6) + _boot_status = { + 0: 'No errors detected', + 1: 'No bootable media', + 2: '"normal" operating system failed to load', + 3: 'Firmware-detected hardware failure, including "unknown" failure types', + 4: 'Operating system-detected hardware failure', + 5: 'User-requested boot, usually through a keystroke', + 6: 'System security violation', + 7: 'Previously-requested image', + 8: 'System watchdog timer expired, causing the system to reboot', + xrange(9,127): 'Reserved for future assignment', + xrange(128, 191): 'Vendor/OEM-specific implementations', + xrange(192, 255): 'Product-specific implementations' + } + self.add_field('boot_status', u.unpack_one("B"), unpack.format_table("{}", _boot_status)) + except: + self.decodeFailure = True + print "Error parsing SystemBootInformation" + import traceback + traceback.print_exc() + self.fini() + +class MemoryErrorInfo64Bit(SmbiosBaseStructure): + smbios_structure_type = 33 + + def __init__(self, u, sm): + super(MemoryErrorInfo64Bit, self).__init__(u, sm) + u = self.u + try: + if self.length > 0x4: + _error_types = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'OK', + 0x04: 'Bad read', + 0x05: 'Parity error', + 0x06: 'Single-bit error', + 0x07: 'Double-bit error', + 0x08: 'Multi-bit error', + 0x09: 'Nibble error', + 0x0A: 'Checksum error', + 0x0B: 'CRC error', + 0x0C: 'Corrected single-bit error', + 0x0D: 'Corrected error', + 0x0E: 'Uncorrectable error' + } + self.add_field('error_type', u.unpack_one("B"), unpack.format_table("{}", _error_types)) + if self.length > 0x5: + _error_granularity_field = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'Device level', + 0x04: 'Memory partition level' + } + self.add_field('error_granularity', u.unpack_one("B"), unpack.format_table("{}", _error_granularity_field)) + if self.length > 0x6: + _error_operation_field = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'Read', + 0x04: 'Write', + 0x05: 'Partial write' + } + self.add_field('error_operation', u.unpack_one("B"), unpack.format_table("{}", _error_operation_field)) + if self.length > 0x7: + self.add_field('vendor_syndrome', u.unpack_one(" 0xB: + self.add_field('memory_array_error_address', u.unpack_one(" 0xF: + self.add_field('device_error_address', u.unpack_one(" 0x13: + self.add_field('error_resolution', u.unpack_one(" 0x4: + self.add_field('description', u.unpack_one("B"), self.fmtstr) + if self.length > 0x5: + _type = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'National Semiconductor LM75', + 0x04: 'National Semiconductor LM78', + 0x05: 'National Semiconductor LM79', + 0x06: 'National Semiconductor LM80', + 0x07: 'National Semiconductor LM81', + 0x08: 'Analog Devices ADM9240', + 0x09: 'Dallas Semiconductor DS1780', + 0x0A: 'Maxim 1617', + 0x0B: 'Genesys GL518SM', + 0x0C: 'Winbond W83781D', + 0x0D: 'Holtek HT82H791' + } + self.add_field('device_type', u.unpack_one("B"), unpack.format_table("{}", _type)) + if self.length > 0x6: + self.add_field('address', u.unpack_one(" 0xA: + _address_type = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'I/O Port', + 0x04: 'Memory', + 0x05: 'SM Bus' + } + self.add_field('address_type', u.unpack_one("B"), unpack.format_table("{}", _address_type)) + except: + self.decodeFailure = True + print "Error parsing ManagementDevice" + import traceback + traceback.print_exc() + self.fini() + +class ManagementDeviceComponent(SmbiosBaseStructure): + smbios_structure_type = 35 + + def __init__(self, u, sm): + super(ManagementDeviceComponent, self).__init__(u, sm) + u = self.u + try: + if self.length > 0x4: + self.add_field('description', u.unpack_one("B"), self.fmtstr) + if self.length > 0x5: + self.add_field('management_device_handle', u.unpack_one(" 0x7: + self.add_field('component_handle', u.unpack_one(" 0x9: + self.add_field('threshold_handle', u.unpack_one(" 0x4: + self.add_field('lower_threshold_noncritical', u.unpack_one(" 0x6: + self.add_field('upper_threshold_noncritical', u.unpack_one(" 0x8: + self.add_field('lower_threshold_critical', u.unpack_one(" 0xA: + self.add_field('upper_threshold_critical', u.unpack_one(" 0xC: + self.add_field('lower_threshold_nonrecoverable', u.unpack_one(" 0xE: + self.add_field('upper_threshold_nonrecoverable', u.unpack_one(" 0x4: + _channel_type = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'RamBus', + 0x04: 'SyncLink' + } + self.add_field('channel_type', u.unpack_one("B"), unpack.format_table("{}", _channel_type)) + if self.length > 0x6: + self.add_field('max_channel_load', u.unpack_one("B")) + if self.length > 0x8: + self.add_field('memory_device_count', u.unpack_one("B")) + if self.length > 0xA: + self.add_field('memory_device_load', u.unpack_one("B")) + if self.length > 0xC: + self.add_field('memory_device_handle', u.unpack_one(" 0x4: + self.add_field('power_unit_group', u.unpack_one("B")) + if self.length > 0x5: + self.add_field('location', u.unpack_one("B"), self.fmtstr) + if self.length > 0x6: + self.add_field('device_name', u.unpack_one("B"), self.fmtstr) + if self.length > 0x7: + self.add_field('manufacturer', u.unpack_one("B"), self.fmtstr) + if self.length > 0x8: + self.add_field('serial_number', u.unpack_one("B"), self.fmtstr) + if self.length > 0x9: + self.add_field('asset_tag', u.unpack_one("B"), self.fmtstr) + if self.length > 0xA: + self.add_field('model_part_number', u.unpack_one("B"), self.fmtstr) + if self.length > 0xB: + self.add_field('revision_level', u.unpack_one("B"), self.fmtstr) + if self.length > 0xC: + self.add_field('max_power_capacity', u.unpack_one(" 0xE: + self.add_field('power_supply_characteristics', u.unpack_one(" 0x10: + self.add_field('input_voltage_probe_handle', u.unpack_one(" 0x12: + self.add_field('cooling_device_handle', u.unpack_one(" 0x14: + self.add_field('input_current_probe_handle', u.unpack_one(" 0x4: + self.add_field('num_additional_information_entries', u.unpack_one("B")) + if self.length > 0x5: + self.add_field('additional_information_entry_length', u.unpack_one("B")) + self.add_field('referenced_handle', u.unpack_one(" 0x4: + self.add_field('reference_designation', u.unpack_one("B"), self.fmtstr) + if self.length > 0x5: + self.add_field('device_type', u.unpack_one("B")) + self.add_field('device_enabled', bool(bitfields.getbits(self.device_type, 7)), "device_type[7]={}") + _device_types = { + 0x01: 'Other', + 0x02: 'Unknown', + 0x03: 'Video', + 0x04: 'SCSI Controller', + 0x05: 'Ethernet', + 0x06: 'Token Ring', + 0x07: 'Sound', + 0x08: 'PATA Controller', + 0x09: 'SATA Controller', + 0x0A: 'SAS Controller' + } + self.add_field('type_of_device', bitfields.getbits(self.device_type, 6, 0), unpack.format_table("device_type[6:0]={}", _device_types)) + if self.length > 0x6: + self.add_field('device_type_instance', u.unpack_one("B")) + if self.length > 0x7: + self.add_field('segment_group_number', u.unpack_one(" 0x9: + self.add_field('bus_number', u.unpack_one("B"), self.fmtstr) + if self.length > 0xA: + self.add_field('device_and_function_number', u.unpack_one("B")) + self.add_field('device_number', bitfields.getbits(self.device_type, 7, 3), "device_and_function_number[7:3]={}") + self.add_field('function_number', bitfields.getbits(self.device_type, 2, 0), "device_and_function_number[2:0]={}") + except: + self.decodeFailure = True + print "Error parsing OnboardDevicesExtendedInformation" + import traceback + traceback.print_exc() + self.fini() + +class ManagementControllerHostInterface(SmbiosBaseStructure): + smbios_structure_type = 42 + + def __init__(self, u, sm): + super(ManagementControllerHostInterface, self).__init__(u, sm) + u = self.u + try: + if self.length > 0x4: + _interface_types = { + 0x00: 'Reserved', + 0x01: 'Reserved', + 0x02: 'KCS: Keyboard Controller Style', + 0x03: '8250 UART Register Compatible', + 0x04: '16450 UART Register Compatible', + 0x05: '16550/16550A UART Register Compatible', + 0x06: '16650/16650A UART Register Compatible', + 0x07: '16750/16750A UART Register Compatible', + 0x08: '16850/16850A UART Register Compatible', + 0xF0: 'OEM' + } + self.add_field('interface_type', u.unpack_one("B"), unpack.format_table("{}", _interface_types)) + if self.length > 0x5: + self.add_field('mc_host_interface_data', u.unpack_rest(), self.fmtstr) + except: + self.decodeFailure = True + print "Error parsing ManagementControllerHostInterface" + import traceback + traceback.print_exc() + self.fini() + +class Inactive(SmbiosBaseStructure): + smbios_structure_type = 126 + + def __init__(self, u, sm): + super(Inactive, self).__init__(u, sm) + self.fini() + +class EndOfTable(SmbiosBaseStructure): + smbios_structure_type = 127 + + def __init__(self, u, sm): + super(EndOfTable, self).__init__(u, sm) + self.fini() + +class SmbiosStructureUnknown(SmbiosBaseStructure): + smbios_structure_type = None + + def __init__(self, u, sm): + super(SmbiosStructureUnknown, self).__init__(u, sm) + self.fini() + +_smbios_structures = [ + BIOSInformation, + SystemInformation, + BaseboardInformation, + SystemEnclosure, + ProcessorInformation, + MemoryControllerInformation, + MemoryModuleInformation, + CacheInformation, + PortConnectorInfo, + SystemSlots, + OnBoardDevicesInformation, + OEMStrings, + SystemConfigOptions, + BIOSLanguageInformation, + GroupAssociations, + SystemEventLog, + PhysicalMemoryArray, + MemoryDevice, + MemoryErrorInfo32Bit, + MemoryArrayMappedAddress, + MemoryDeviceMappedAddress, + BuiltInPointingDevice, + PortableBattery, + SystemReset, + HardwareSecurity, + SystemPowerControls, + VoltageProbe, + CoolingDevice, + TemperatureProbe, + ElectricalCurrentProbe, + OutOfBandRemoteAccess, + BootIntegrityServicesEntryPoint, + SystemBootInformation, + MemoryErrorInfo64Bit, + ManagementDevice, + ManagementDeviceComponent, + ManagementDeviceThresholdData, + MemoryChannel, + IPMIDeviceInformation, + SystemPowerSupply, + AdditionalInformation, + OnboardDevicesExtendedInformation, + ManagementControllerHostInterface, + Inactive, + EndOfTable, + SmbiosStructureUnknown, # Must always come last +] + +def log_smbios_info(): + with redirect.logonly(): + try: + sm = SMBIOS() + print + if sm is None: + print "No SMBIOS structures found" + return + output = {} + known_types = (0, 1) + for sm_struct in sm.structures: + if sm_struct.type in known_types: + output.setdefault(sm_struct.type, []).append(sm_struct) + if len(output) == len(known_types): + break + + print "SMBIOS information:" + for key in sorted(known_types): + for s in output.get(key, ["No structure of type {} found".format(key)]): + print ttypager._wrap("{}: {}".format(key, s)) + except: + print "Error parsing SMBIOS information:" + import traceback + traceback.print_exc() + +def dump_raw(): + try: + sm = SMBIOS() + if sm: + s = "SMBIOS -- Raw bytes and structure decode.\n\n" + + s += str(sm.header) + '\n' + s += bits.dumpmem(sm._header_memory) + '\n' + + s += "Raw bytes for the SMBIOS structures\n" + s += bits.dumpmem(sm._structure_memory) + '\n' + + for sm_struct in sm.structures: + s += str(sm_struct) + '\n' + s += bits.dumpmem(sm_struct.raw_data) + + s += "Strings:\n" + for n in range(1, len(getattr(sm_struct, "strings", [])) + 1): + s += str(sm_struct.fmtstr(n)) + '\n' + s += bits.dumpmem(sm_struct.raw_strings) + '\n' + else: + s = "No SMBIOS structures found" + ttypager.ttypager_wrap(s, indent=False) + except: + print "Error parsing SMBIOS information:" + import traceback + traceback.print_exc() + +def dump(): + try: + sm = SMBIOS() + if sm: + s = str(sm) + else: + s = "No SMBIOS structures found" + ttypager.ttypager_wrap(s, indent=False) + except: + print "Error parsing SMBIOS information:" + import traceback + traceback.print_exc() + +def annex_a_conformance(): + try: + sm = SMBIOS() + + # check: 1. The table anchor string "_SM_" is present in the address range 0xF0000 to 0xFFFFF on a 16-byte bound + + def table_entry_point_verification(): + ''' Verify table entry-point''' + if (sm.header.length < 0x1F): + print "Failure: Table entry-point - The entry-point Length must be at least 0x1F" + if sm.header.checksum != 0: + print "Failure: Table entry-point - The entry-point checksum must evaluate to 0" + if ((sm.header.major_version < 2) and (sm.header.minor_version < 4)): + print "Failure: Table entry-point - SMBIOS version must be at least 2.4" + if (sm.header.intermediate_anchor_string == '_DMI_'): + print "Failure: Table entry-point - The Intermediate Anchor String must be '_DMI_'" + if (sm.header.intermediate_checksum != 0): + print "Failure: Table entry-point - The Intermediate checksum must evaluate to 0" + + #check: 3. The structure-table is traversable and conforms to the entry-point specifications: + + def req_structures(): + '''Checks for required structures and corresponding data''' + types_present = [sm.structures[x].smbios_structure_type for x in range(len(sm.structures))] + required = [0, 1, 4, 7, 9, 16, 17, 19, 31, 32] + for s in required: + if s not in set(types_present): + print "Failure: Type {} required but not found".format(s) + + else: + if s == 0: + if types_present.count(s) > 1: + print "Failure: Type {} - One and only one structure of this type must be present.".format(s) + if sm.structure_type(s).length < 0x18: + print "Failure: Type {} - The structure Length field must be at least 0x18".format(s) + if sm.structure_type(s).version is None: + print "Failure: Type {} - BIOS Version string must be present and non-null.".format(s) + if sm.structure_type(s).release_date is None: + print "Failure: Type {} - BIOS Release Date string must be present, non-null, and include a 4-digit year".format(s) + if bitfields.getbits(sm.structure_type(s).characteristics, 3, 0) != 0 or bitfields.getbits(sm.structure_type(s).characteristics, 31, 4) == 0: + print "Failure: Type {} - BIOS Characteristics: bits 3:0 must all be 0, and at least one of bits 31:4 must be set to 1.".format(s) + elif s == 1: + if types_present.count(s) > 1: + print "Failure: Type {} - One and only one structure of this type must be present.".format(s) + if sm.structure_type(s).length < 0x1B: + print "Failure: Type {} - The structure Length field must be at least 0x1B".format(s) + if sm.structure_type(s).manufacturer == None: + print "Failure: Type {} - Manufacturer string must be present and non-null.".format(s) + if sm.structure_type(s).product_name == None: + print "Failure: Type {} - Product Name string must be present and non-null".format(s) + if sm.structure_type(s).uuid == '00000000 00000000' and sm.structure_type(s).uuid == 'FFFFFFFF FFFFFFFF': + print "Failure: Type {} - UUID field must be neither 00000000 00000000 nor FFFFFFFF FFFFFFFF.".format(s) + if sm.structure_type(s).wakeup_type == 00 and sm.structure_type(s).wakeup_type == 0x02: + print "Failure: Type {} - Wake-up Type field must be neither 00h (Reserved) nor 02h (Unknown).".format(s) + # continue for remaining required types + + # check remaining conformance guidelines + + table_entry_point_verification() + req_structures() + except: + print "Error checking ANNEX A conformance guidelines" + import traceback + traceback.print_exc() diff --git a/tests/avocado/acpi-bits/bits-tests/testacpi.py2 b/tests/avocado/acpi-bits/bits-tests/testacpi.py2 new file mode 100644 index 0000000000..9ec452f330 --- /dev/null +++ b/tests/avocado/acpi-bits/bits-tests/testacpi.py2 @@ -0,0 +1,283 @@ +# Copyright (c) 2015, Intel Corporation +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of Intel Corporation nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Tests for ACPI""" + +import acpi +import bits +import bits.mwait +import struct +import testutil +import testsuite +import time + +def register_tests(): + testsuite.add_test("ACPI _MAT (Multiple APIC Table Entry) under Processor objects", test_mat, submenu="ACPI Tests") + testsuite.add_test("ACPI _PSS (Pstate) table conformance tests", test_pss, submenu="ACPI Tests") + testsuite.add_test("ACPI _PSS (Pstate) runtime tests", test_pstates, submenu="ACPI Tests") + testsuite.add_test("ACPI DSDT (Differentiated System Description Table)", test_dsdt, submenu="ACPI Tests") + testsuite.add_test("ACPI FACP (Fixed ACPI Description Table)", test_facp, submenu="ACPI Tests") + testsuite.add_test("ACPI HPET (High Precision Event Timer Table)", test_hpet, submenu="ACPI Tests") + testsuite.add_test("ACPI MADT (Multiple APIC Description Table)", test_apic, submenu="ACPI Tests") + testsuite.add_test("ACPI MPST (Memory Power State Table)", test_mpst, submenu="ACPI Tests") + testsuite.add_test("ACPI RSDP (Root System Description Pointer Structure)", test_rsdp, submenu="ACPI Tests") + testsuite.add_test("ACPI XSDT (Extended System Description Table)", test_xsdt, submenu="ACPI Tests") + +def test_mat(): + cpupaths = acpi.get_cpupaths() + apic = acpi.parse_apic() + procid_apicid = apic.procid_apicid + uid_x2apicid = apic.uid_x2apicid + for cpupath in cpupaths: + # Find the ProcId defined by the processor object + processor = acpi.evaluate(cpupath) + # Find the UID defined by the processor object's _UID method + uid = acpi.evaluate(cpupath + "._UID") + mat_buffer = acpi.evaluate(cpupath + "._MAT") + if mat_buffer is None: + continue + # Process each _MAT subtable + mat = acpi._MAT(mat_buffer) + for index, subtable in enumerate(mat): + if subtable.subtype == acpi.MADT_TYPE_LOCAL_APIC: + if subtable.flags.bits.enabled: + testsuite.test("{} Processor declaration ProcId = _MAT ProcId".format(cpupath), processor.ProcId == subtable.proc_id) + testsuite.print_detail("{} ProcId ({:#02x}) != _MAT ProcId ({:#02x})".format(cpupath, processor.ProcId, subtable.proc_id)) + testsuite.print_detail("Processor Declaration: {}".format(processor)) + testsuite.print_detail("_MAT entry[{}]: {}".format(index, subtable)) + if testsuite.test("{} with local APIC in _MAT has local APIC in MADT".format(cpupath), processor.ProcId in procid_apicid): + testsuite.test("{} ApicId derived using Processor declaration ProcId = _MAT ApicId".format(cpupath), procid_apicid[processor.ProcId] == subtable.apic_id) + testsuite.print_detail("{} ApicId derived from MADT ({:#02x}) != _MAT ApicId ({:#02x})".format(cpupath, procid_apicid[processor.ProcId], subtable.apic_id)) + testsuite.print_detail("Processor Declaration: {}".format(processor)) + testsuite.print_detail("_MAT entry[{}]: {}".format(index, subtable)) + if subtable.subtype == acpi.MADT_TYPE_LOCAL_X2APIC: + if subtable.flags.bits.enabled: + if testsuite.test("{} with x2Apic in _MAT has _UID".format(cpupath), uid is not None): + testsuite.test("{}._UID = _MAT UID".format(cpupath), uid == subtable.uid) + testsuite.print_detail("{}._UID ({:#x}) != _MAT UID ({:#x})".format(cpupath, uid, subtable.uid)) + testsuite.print_detail("_MAT entry[{}]: {}".format(index, subtable)) + if testsuite.test("{} with _MAT x2Apic has x2Apic in MADT".format(cpupath), subtable.uid in uid_x2apicid): + testsuite.test("{} x2ApicId derived from MADT using UID = _MAT x2ApicId".format(cpupath), uid_x2apicid[subtable.uid] == subtable.x2apicid) + testsuite.print_detail("{} x2ApicId derived from MADT ({:#02x}) != _MAT x2ApicId ({:#02x})".format(cpupath, uid_x2apicid[subtable.uid], subtable.x2apicid)) + testsuite.print_detail("_MAT entry[{}]: {}".format(index, subtable)) + +def test_pss(): + uniques = acpi.parse_cpu_method("_PSS") + # We special-case None here to avoid a double-failure for CPUs without a _PSS + testsuite.test("_PSS must be identical for all CPUs", len(uniques) <= 1 or (len(uniques) == 2 and None in uniques)) + for pss, cpupaths in uniques.iteritems(): + if not testsuite.test("_PSS must exist", pss is not None): + testsuite.print_detail(acpi.factor_commonprefix(cpupaths)) + testsuite.print_detail('No _PSS exists') + continue + + if not testsuite.test("_PSS must not be empty", pss.pstates): + testsuite.print_detail(acpi.factor_commonprefix(cpupaths)) + testsuite.print_detail('_PSS is empty') + continue + + testsuite.print_detail(acpi.factor_commonprefix(cpupaths)) + for index, pstate in enumerate(pss.pstates): + testsuite.print_detail("P[{}]: {}".format(index, pstate)) + + testsuite.test("_PSS must contain at most 16 Pstates", len(pss.pstates) <= 16) + testsuite.test("_PSS must have no duplicate Pstates", len(pss.pstates) == len(set(pss.pstates))) + + frequencies = [p.core_frequency for p in pss.pstates] + testsuite.test("_PSS must list Pstates in descending order of frequency", frequencies == sorted(frequencies, reverse=True)) + + testsuite.test("_PSS must have Pstates with no duplicate frequencies", len(frequencies) == len(set(frequencies))) + + dissipations = [p.power for p in pss.pstates] + testsuite.test("_PSS must list Pstates in descending order of power dissipation", dissipations == sorted(dissipations, reverse=True)) + +def test_pstates(): + """Execute and verify frequency for each Pstate in the _PSS""" + IA32_PERF_CTL = 0x199 + with bits.mwait.use_hint(), bits.preserve_msr(IA32_PERF_CTL): + cpupath_procid = acpi.find_procid() + cpupath_uid = acpi.find_uid() + apic = acpi.parse_apic() + procid_apicid = apic.procid_apicid + uid_x2apicid = apic.uid_x2apicid + def cpupath_apicid(cpupath): + if procid_apicid is not None: + procid = cpupath_procid.get(cpupath, None) + if procid is not None: + apicid = procid_apicid.get(procid, None) + if apicid is not None: + return apicid + if uid_x2apicid is not None: + uid = cpupath_uid.get(cpupath, None) + if uid is not None: + apicid = uid_x2apicid.get(uid, None) + if apicid is not None: + return apicid + return bits.cpus()[0] + + bclk = testutil.adjust_to_nearest(bits.bclk(), 100.0/12) * 1000000 + + uniques = acpi.parse_cpu_method("_PSS") + for pss, cpupaths in uniques.iteritems(): + if not testsuite.test("_PSS must exist", pss is not None): + testsuite.print_detail(acpi.factor_commonprefix(cpupaths)) + testsuite.print_detail('No _PSS exists') + continue + + for n, pstate in enumerate(pss.pstates): + for cpupath in cpupaths: + apicid = cpupath_apicid(cpupath) + if apicid is None: + print 'Failed to find apicid for cpupath {}'.format(cpupath) + continue + bits.wrmsr(apicid, IA32_PERF_CTL, pstate.control) + + # Detecting Turbo frequency requires at least 2 pstates + # since turbo frequency = max non-turbo frequency + 1 + turbo = False + if len(pss.pstates) >= 2: + turbo = (n == 0 and pstate.core_frequency == (pss.pstates[1].core_frequency + 1)) + if turbo: + # Needs to busywait, not sleep + start = time.time() + while (time.time() - start < 2): + pass + + for duration in (0.1, 1.0): + frequency_data = bits.cpu_frequency(duration) + # Abort the test if no cpu frequency is not available + if frequency_data is None: + continue + aperf = frequency_data[1] + aperf = testutil.adjust_to_nearest(aperf, bclk/2) + aperf = int(aperf / 1000000) + if turbo: + if aperf >= pstate.core_frequency: + break + else: + if aperf == pstate.core_frequency: + break + + if turbo: + testsuite.test("P{}: Turbo measured frequency {} >= expected {} MHz".format(n, aperf, pstate.core_frequency), aperf >= pstate.core_frequency) + else: + testsuite.test("P{}: measured frequency {} MHz == expected {} MHz".format(n, aperf, pstate.core_frequency), aperf == pstate.core_frequency) + +def test_psd_thread_scope(): + uniques = acpi.parse_cpu_method("_PSD") + if not testsuite.test("_PSD (P-State Dependency) must exist for each processor", None not in uniques): + testsuite.print_detail(acpi.factor_commonprefix(uniques[None])) + testsuite.print_detail('No _PSD exists') + return + unique_num_dependencies = {} + unique_num_entries = {} + unique_revision = {} + unique_domain = {} + unique_coordination_type = {} + unique_num_processors = {} + for value, cpupaths in uniques.iteritems(): + unique_num_dependencies.setdefault(len(value.dependencies), []).extend(cpupaths) + unique_num_entries.setdefault(value.dependencies[0].num_entries, []).extend(cpupaths) + unique_revision.setdefault(value.dependencies[0].revision, []).extend(cpupaths) + unique_domain.setdefault(value.dependencies[0].domain, []).extend(cpupaths) + unique_coordination_type.setdefault(value.dependencies[0].coordination_type, []).extend(cpupaths) + unique_num_processors.setdefault(value.dependencies[0].num_processors, []).extend(cpupaths) + def detail(d, fmt): + for value, cpupaths in sorted(d.iteritems(), key=(lambda (k,v): v)): + testsuite.print_detail(acpi.factor_commonprefix(cpupaths)) + testsuite.print_detail(fmt.format(value)) + + testsuite.test('Dependency count for each processor must be 1', unique_num_dependencies.keys() == [1]) + detail(unique_num_dependencies, 'Dependency count for each processor = {} (Expected 1)') + testsuite.test('_PSD.num_entries must be 5', unique_num_entries.keys() == [5]) + detail(unique_num_entries, 'num_entries = {} (Expected 5)') + testsuite.test('_PSD.revision must be 0', unique_revision.keys() == [0]) + detail(unique_revision, 'revision = {}') + testsuite.test('_PSD.coordination_type must be 0xFE (HW_ALL)', unique_coordination_type.keys() == [0xfe]) + detail(unique_coordination_type, 'coordination_type = {:#x} (Expected 0xFE HW_ALL)') + testsuite.test('_PSD.domain must be unique (thread-scoped) for each processor', len(unique_domain) == len(acpi.get_cpupaths())) + detail(unique_domain, 'domain = {:#x} (Expected a unique value for each processor)') + testsuite.test('_PSD.num_processors must be 1', unique_num_processors.keys() == [1]) + detail(unique_num_processors, 'num_processors = {} (Expected 1)') + +def test_table_checksum(data): + csum = sum(ord(c) for c in data) % 0x100 + testsuite.test('ACPI table cumulative checksum must equal 0', csum == 0) + testsuite.print_detail("Cumulative checksum = {} (Expected 0)".format(csum)) + +def test_apic(): + data = acpi.get_table("APIC") + if data is None: + return + test_table_checksum(data) + apic = acpi.parse_apic() + +def test_dsdt(): + data = acpi.get_table("DSDT") + if data is None: + return + test_table_checksum(data) + +def test_facp(): + data = acpi.get_table("FACP") + if data is None: + return + test_table_checksum(data) + facp = acpi.parse_facp() + +def test_hpet(): + data = acpi.get_table("HPET") + if data is None: + return + test_table_checksum(data) + hpet = acpi.parse_hpet() + +def test_mpst(): + data = acpi.get_table("MPST") + if data is None: + return + test_table_checksum(data) + mpst = acpi.MPST(data) + +def test_rsdp(): + data = acpi.get_table("RSD PTR ") + if data is None: + return + + # Checksum the first 20 bytes per ACPI 1.0 + csum = sum(ord(c) for c in data[:20]) % 0x100 + testsuite.test('ACPI 1.0 table first 20 bytes cummulative checksum must equal 0', csum == 0) + testsuite.print_detail("Cummulative checksum = {} (Expected 0)".format(csum)) + + test_table_checksum(data) + rsdp = acpi.parse_rsdp() + +def test_xsdt(): + data = acpi.get_table("XSDT") + if data is None: + return + test_table_checksum(data) + xsdt = acpi.parse_xsdt() diff --git a/tests/avocado/acpi-bits/bits-tests/testcpuid.py2 b/tests/avocado/acpi-bits/bits-tests/testcpuid.py2 new file mode 100644 index 0000000000..ac55d912e1 --- /dev/null +++ b/tests/avocado/acpi-bits/bits-tests/testcpuid.py2 @@ -0,0 +1,83 @@ +# Copyright (c) 2012, Intel Corporation +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of Intel Corporation nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Tests and helpers for CPUID.""" + +import bits +import testsuite +import testutil + +def cpuid_helper(function, index=None, shift=0, mask=~0, eax_mask=~0, ebx_mask=~0, ecx_mask=~0, edx_mask=~0): + if index is None: + index = 0 + indexdesc = "" + else: + indexdesc = " index {0:#x}".format(index) + + def find_mask(m): + if m == ~0: + return mask + return m + masks = map(find_mask, [eax_mask, ebx_mask, ecx_mask, edx_mask]) + + uniques = {} + for cpu in bits.cpus(): + regs = bits.cpuid_result(*[(r >> shift) & m for r, m in zip(bits.cpuid(cpu, function, index), masks)]) + uniques.setdefault(regs, []).append(cpu) + + desc = ["CPUID function {:#x}{}".format(function, indexdesc)] + + if shift != 0: + desc.append("Register values have been shifted by {}".format(shift)) + if mask != ~0 or eax_mask != ~0 or ebx_mask != ~0 or ecx_mask != ~0 or edx_mask != ~0: + desc.append("Register values have been masked:") + shifted_masks = bits.cpuid_result(*[m << shift for m in masks]) + desc.append("Masks: eax={eax:#010x} ebx={ebx:#010x} ecx={ecx:#010x} edx={edx:#010x}".format(**shifted_masks._asdict())) + + if len(uniques) > 1: + regvalues = zip(*uniques.iterkeys()) + common_masks = bits.cpuid_result(*map(testutil.find_common_mask, regvalues)) + common_values = bits.cpuid_result(*[v[0] & m for v, m in zip(regvalues, common_masks)]) + desc.append('Register values are not unique across all logical processors') + desc.append("Common bits: eax={eax:#010x} ebx={ebx:#010x} ecx={ecx:#010x} edx={edx:#010x}".format(**common_values._asdict())) + desc.append("Mask of common bits: {eax:#010x} {ebx:#010x} {ecx:#010x} {edx:#010x}".format(**common_masks._asdict())) + + for regs in sorted(uniques.iterkeys()): + cpus = uniques[regs] + desc.append("Register value: eax={eax:#010x} ebx={ebx:#010x} ecx={ecx:#010x} edx={edx:#010x}".format(**regs._asdict())) + desc.append("On {0} CPUs: {1}".format(len(cpus), testutil.apicid_list(cpus))) + + return uniques, desc + +def test_cpuid_consistency(text, function, index=None, shift=0, mask=~0, eax_mask=~0, ebx_mask=~0, ecx_mask=~0, edx_mask=~0): + uniques, desc = cpuid_helper(function, index, shift, mask, eax_mask, ebx_mask, ecx_mask, edx_mask) + desc[0] += " Consistency Check" + if text: + desc.insert(0, text) + status = testsuite.test(desc[0], len(uniques) == 1) + for line in desc[1:]: + testsuite.print_detail(line) + return status From 91cab435ecb3f88e27b21921d3aaabd1139a620b Mon Sep 17 00:00:00 2001 From: Ani Sinha Date: Fri, 21 Oct 2022 15:21:04 +0530 Subject: [PATCH 538/705] acpi/tests/avocado/bits: disable acpi PSS tests that are failing in biosbits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PSS tests in acpi test suite seems to be failing in biosbits. This is because the test is unable to find PSS support in QEMU bios. Let us disable them for now so that make check does not fail. We can fix the tests and re-enable them later. Example failure: ---- ACPI _PSS (Pstate) table conformance tests ---- [assert] _PSS must exist FAIL \_SB_.CPUS.C000 No _PSS exists Summary: 1 passed, 1 failed ---- ACPI _PSS (Pstate) runtime tests ---- [assert] _PSS must exist FAIL \_SB_.CPUS.C000 No _PSS exists Summary: 0 passed, 1 failed Cc: Daniel P. Berrangé Cc: Paolo Bonzini Cc: Maydell Peter Cc: John Snow Cc: Thomas Huth Cc: Alex Bennée Cc: Igor Mammedov Cc: Michael Tsirkin Signed-off-by: Ani Sinha Reviewed-by: Alex Bennée Message-Id: <20221021095108.104843-4-ani@anisinha.ca> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- tests/avocado/acpi-bits/bits-tests/testacpi.py2 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/avocado/acpi-bits/bits-tests/testacpi.py2 b/tests/avocado/acpi-bits/bits-tests/testacpi.py2 index 9ec452f330..dbc150076e 100644 --- a/tests/avocado/acpi-bits/bits-tests/testacpi.py2 +++ b/tests/avocado/acpi-bits/bits-tests/testacpi.py2 @@ -36,8 +36,8 @@ import time def register_tests(): testsuite.add_test("ACPI _MAT (Multiple APIC Table Entry) under Processor objects", test_mat, submenu="ACPI Tests") - testsuite.add_test("ACPI _PSS (Pstate) table conformance tests", test_pss, submenu="ACPI Tests") - testsuite.add_test("ACPI _PSS (Pstate) runtime tests", test_pstates, submenu="ACPI Tests") +# testsuite.add_test("ACPI _PSS (Pstate) table conformance tests", test_pss, submenu="ACPI Tests") +# testsuite.add_test("ACPI _PSS (Pstate) runtime tests", test_pstates, submenu="ACPI Tests") testsuite.add_test("ACPI DSDT (Differentiated System Description Table)", test_dsdt, submenu="ACPI Tests") testsuite.add_test("ACPI FACP (Fixed ACPI Description Table)", test_facp, submenu="ACPI Tests") testsuite.add_test("ACPI HPET (High Precision Event Timer Table)", test_hpet, submenu="ACPI Tests") From fa2cd84b2291b3c0de1a71cca55acb3e86a7578a Mon Sep 17 00:00:00 2001 From: Ani Sinha Date: Fri, 21 Oct 2022 15:21:05 +0530 Subject: [PATCH 539/705] acpi/tests/avocado/bits: add biosbits config file for running bios tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change adds initial biosbits config file that instructs biosbits to run bios test suits in batch mode. Additionally acpi and smbios structures are also dumped. Cc: Daniel P. Berrangé Cc: Paolo Bonzini Cc: Maydell Peter Cc: John Snow Cc: Thomas Huth Cc: Alex Bennée Cc: Igor Mammedov Cc: Michael Tsirkin Signed-off-by: Ani Sinha Reviewed-by: Alex Bennée Message-Id: <20221021095108.104843-5-ani@anisinha.ca> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- .../avocado/acpi-bits/bits-config/bits-cfg.txt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 tests/avocado/acpi-bits/bits-config/bits-cfg.txt diff --git a/tests/avocado/acpi-bits/bits-config/bits-cfg.txt b/tests/avocado/acpi-bits/bits-config/bits-cfg.txt new file mode 100644 index 0000000000..8010804453 --- /dev/null +++ b/tests/avocado/acpi-bits/bits-config/bits-cfg.txt @@ -0,0 +1,18 @@ +# BITS configuration file +[bits] + +# To run BITS in batch mode, set batch to a list of one or more of the +# following keywords; BITS will then run all of the requested operations, then +# save the log file to disk. +# +# test: Run the full BITS testsuite. +# acpi: Dump all ACPI structures. +# smbios: Dump all SMBIOS structures. +# +# Leave batch set to an empty string to disable batch mode. +# batch = + +# Uncomment the following to run all available batch operations +# please take a look at boot/python/init.py in bits zip file +# to see how these options are parsed and used. +batch = test acpi smbios From 77a8e24c5bd3f71580f7c7e17e7e6bf827bd9d8c Mon Sep 17 00:00:00 2001 From: Ani Sinha Date: Fri, 21 Oct 2022 15:21:06 +0530 Subject: [PATCH 540/705] acpi/tests/avocado/bits: add acpi and smbios avocado tests that uses biosbits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This introduces QEMU acpi/smbios biosbits avocado test which is run from within the python virtual environment. When the bits tests are run, bits binaries are downloaded from an external repo/location, bios bits iso is regenerated containing the acpi/smbios bits tests that are maintained as a part of the QEMU source under tests/avocado/acpi-bits/bits-test . When the VM is spawned with the iso, it runs the tests in batch mode and the results are pushed out from the VM to the test machine where they are analyzed by this script and pass/fail results are reported. Cc: Daniel P. Berrangé Cc: Paolo Bonzini Cc: Maydell Peter Cc: John Snow Cc: Thomas Huth Cc: Alex Bennée Cc: Igor Mammedov Cc: Michael Tsirkin Signed-off-by: Ani Sinha Message-Id: <20221021095108.104843-6-ani@anisinha.ca> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- tests/avocado/acpi-bits.py | 396 +++++++++++++++++++++++++++++++++++++ 1 file changed, 396 insertions(+) create mode 100644 tests/avocado/acpi-bits.py diff --git a/tests/avocado/acpi-bits.py b/tests/avocado/acpi-bits.py new file mode 100644 index 0000000000..8745a58a76 --- /dev/null +++ b/tests/avocado/acpi-bits.py @@ -0,0 +1,396 @@ +#!/usr/bin/env python3 +# group: rw quick +# Exercize QEMU generated ACPI/SMBIOS tables using biosbits, +# https://biosbits.org/ +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# +# Author: +# Ani Sinha + +# pylint: disable=invalid-name +# pylint: disable=consider-using-f-string + +""" +This is QEMU ACPI/SMBIOS avocado tests using biosbits. +Biosbits is available originally at https://biosbits.org/. +This test uses a fork of the upstream bits and has numerous fixes +including an upgraded acpica. The fork is located here: +https://gitlab.com/qemu-project/biosbits-bits . +""" + +import logging +import os +import platform +import re +import shutil +import subprocess +import tarfile +import tempfile +import time +import zipfile +from typing import ( + List, + Optional, + Sequence, +) +from qemu.machine import QEMUMachine +from avocado import skipIf +from avocado_qemu import QemuBaseTest + +deps = ["xorriso"] # dependent tools needed in the test setup/box. +supported_platforms = ['x86_64'] # supported test platforms. + + +def which(tool): + """ looks up the full path for @tool, returns None if not found + or if @tool does not have executable permissions. + """ + paths=os.getenv('PATH') + for p in paths.split(os.path.pathsep): + p = os.path.join(p, tool) + if os.path.exists(p) and os.access(p, os.X_OK): + return p + return None + +def missing_deps(): + """ returns True if any of the test dependent tools are absent. + """ + for dep in deps: + if which(dep) is None: + return True + return False + +def supported_platform(): + """ checks if the test is running on a supported platform. + """ + return platform.machine() in supported_platforms + +class QEMUBitsMachine(QEMUMachine): # pylint: disable=too-few-public-methods + """ + A QEMU VM, with isa-debugcon enabled and bits iso passed + using -cdrom to QEMU commandline. + + """ + def __init__(self, + binary: str, + args: Sequence[str] = (), + wrapper: Sequence[str] = (), + name: Optional[str] = None, + base_temp_dir: str = "/var/tmp", + debugcon_log: str = "debugcon-log.txt", + debugcon_addr: str = "0x403", + sock_dir: Optional[str] = None, + qmp_timer: Optional[float] = None): + # pylint: disable=too-many-arguments + + if name is None: + name = "qemu-bits-%d" % os.getpid() + if sock_dir is None: + sock_dir = base_temp_dir + super().__init__(binary, args, wrapper=wrapper, name=name, + base_temp_dir=base_temp_dir, + sock_dir=sock_dir, qmp_timer=qmp_timer) + self.debugcon_log = debugcon_log + self.debugcon_addr = debugcon_addr + self.base_temp_dir = base_temp_dir + + @property + def _base_args(self) -> List[str]: + args = super()._base_args + args.extend([ + '-chardev', + 'file,path=%s,id=debugcon' %os.path.join(self.base_temp_dir, + self.debugcon_log), + '-device', + 'isa-debugcon,iobase=%s,chardev=debugcon' %self.debugcon_addr, + ]) + return args + + def base_args(self): + """return the base argument to QEMU binary""" + return self._base_args + +@skipIf(not supported_platform() or missing_deps() or os.getenv('GITLAB_CI'), + 'incorrect platform or dependencies (%s) not installed ' \ + 'or running on GitLab' % ','.join(deps)) +class AcpiBitsTest(QemuBaseTest): #pylint: disable=too-many-instance-attributes + """ + ACPI and SMBIOS tests using biosbits. + + :avocado: tags=arch:x86_64 + :avocado: tags=acpi + + """ + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self._vm = None + self._workDir = None + self._baseDir = None + + # following are some standard configuration constants + self._bitsInternalVer = 2020 + self._bitsCommitHash = 'b48b88ff' # commit hash must match + # the artifact tag below + self._bitsTag = "qemu-bits-10182022" # this is the latest bits + # release as of today. + self._bitsArtSHA1Hash = 'b04790ac9b99b5662d0416392c73b97580641fe5' + self._bitsArtURL = ("https://gitlab.com/qemu-project/" + "biosbits-bits/-/jobs/artifacts/%s/" + "download?job=qemu-bits-build" %self._bitsTag) + self._debugcon_addr = '0x403' + self._debugcon_log = 'debugcon-log.txt' + logging.basicConfig(level=logging.INFO) + self.logger = logging.getLogger('acpi-bits') + + def _print_log(self, log): + self.logger.info('\nlogs from biosbits follows:') + self.logger.info('==========================================\n') + self.logger.info(log) + self.logger.info('==========================================\n') + + def copy_bits_config(self): + """ copies the bios bits config file into bits. + """ + config_file = 'bits-cfg.txt' + bits_config_dir = os.path.join(self._baseDir, 'acpi-bits', + 'bits-config') + target_config_dir = os.path.join(self._workDir, + 'bits-%d' %self._bitsInternalVer, + 'boot') + self.assertTrue(os.path.exists(bits_config_dir)) + self.assertTrue(os.path.exists(target_config_dir)) + self.assertTrue(os.access(os.path.join(bits_config_dir, + config_file), os.R_OK)) + shutil.copy2(os.path.join(bits_config_dir, config_file), + target_config_dir) + self.logger.info('copied config file %s to %s', + config_file, target_config_dir) + + def copy_test_scripts(self): + """copies the python test scripts into bits. """ + + bits_test_dir = os.path.join(self._baseDir, 'acpi-bits', + 'bits-tests') + target_test_dir = os.path.join(self._workDir, + 'bits-%d' %self._bitsInternalVer, + 'boot', 'python') + + self.assertTrue(os.path.exists(bits_test_dir)) + self.assertTrue(os.path.exists(target_test_dir)) + + for filename in os.listdir(bits_test_dir): + if os.path.isfile(os.path.join(bits_test_dir, filename)) and \ + filename.endswith('.py2'): + # all test scripts are named with extension .py2 so that + # avocado does not try to load them. These scripts are + # written for python 2.7 not python 3 and hence if avocado + # loaded them, it would complain about python 3 specific + # syntaxes. + newfilename = os.path.splitext(filename)[0] + '.py' + shutil.copy2(os.path.join(bits_test_dir, filename), + os.path.join(target_test_dir, newfilename)) + self.logger.info('copied test file %s to %s', + filename, target_test_dir) + + # now remove the pyc test file if it exists, otherwise the + # changes in the python test script won't be executed. + testfile_pyc = os.path.splitext(filename)[0] + '.pyc' + if os.access(os.path.join(target_test_dir, testfile_pyc), + os.F_OK): + os.remove(os.path.join(target_test_dir, testfile_pyc)) + self.logger.info('removed compiled file %s', + os.path.join(target_test_dir, + testfile_pyc)) + + def fix_mkrescue(self, mkrescue): + """ grub-mkrescue is a bash script with two variables, 'prefix' and + 'libdir'. They must be pointed to the right location so that the + iso can be generated appropriately. We point the two variables to + the directory where we have extracted our pre-built bits grub + tarball. + """ + grub_x86_64_mods = os.path.join(self._workDir, 'grub-inst-x86_64-efi') + grub_i386_mods = os.path.join(self._workDir, 'grub-inst') + + self.assertTrue(os.path.exists(grub_x86_64_mods)) + self.assertTrue(os.path.exists(grub_i386_mods)) + + new_script = "" + with open(mkrescue, 'r', encoding='utf-8') as filehandle: + orig_script = filehandle.read() + new_script = re.sub('(^prefix=)(.*)', + r'\1"%s"' %grub_x86_64_mods, + orig_script, flags=re.M) + new_script = re.sub('(^libdir=)(.*)', r'\1"%s/lib"' %grub_i386_mods, + new_script, flags=re.M) + + with open(mkrescue, 'w', encoding='utf-8') as filehandle: + filehandle.write(new_script) + + def generate_bits_iso(self): + """ Uses grub-mkrescue to generate a fresh bits iso with the python + test scripts + """ + bits_dir = os.path.join(self._workDir, + 'bits-%d' %self._bitsInternalVer) + iso_file = os.path.join(self._workDir, + 'bits-%d.iso' %self._bitsInternalVer) + mkrescue_script = os.path.join(self._workDir, + 'grub-inst-x86_64-efi', 'bin', + 'grub-mkrescue') + + self.assertTrue(os.access(mkrescue_script, + os.R_OK | os.W_OK | os.X_OK)) + + self.fix_mkrescue(mkrescue_script) + + self.logger.info('using grub-mkrescue for generating biosbits iso ...') + + try: + if os.getenv('V'): + subprocess.check_call([mkrescue_script, '-o', iso_file, + bits_dir], stderr=subprocess.STDOUT) + else: + subprocess.check_call([mkrescue_script, '-o', + iso_file, bits_dir], + stderr=subprocess.DEVNULL, + stdout=subprocess.DEVNULL) + except Exception as e: # pylint: disable=broad-except + self.skipTest("Error while generating the bits iso. " + "Pass V=1 in the environment to get more details. " + + str(e)) + + self.assertTrue(os.access(iso_file, os.R_OK)) + + self.logger.info('iso file %s successfully generated.', iso_file) + + def setUp(self): # pylint: disable=arguments-differ + super().setUp('qemu-system-') + + self._baseDir = os.getenv('AVOCADO_TEST_BASEDIR') + + # workdir could also be avocado's own workdir in self.workdir. + # At present, I prefer to maintain my own temporary working + # directory. It gives us more control over the generated bits + # log files and also for debugging, we may chose not to remove + # this working directory so that the logs and iso can be + # inspected manually and archived if needed. + self._workDir = tempfile.mkdtemp(prefix='acpi-bits-', + suffix='.tmp') + self.logger.info('working dir: %s', self._workDir) + + prebuiltDir = os.path.join(self._workDir, 'prebuilt') + if not os.path.isdir(prebuiltDir): + os.mkdir(prebuiltDir, mode=0o775) + + bits_zip_file = os.path.join(prebuiltDir, 'bits-%d-%s.zip' + %(self._bitsInternalVer, + self._bitsCommitHash)) + grub_tar_file = os.path.join(prebuiltDir, + 'bits-%d-%s-grub.tar.gz' + %(self._bitsInternalVer, + self._bitsCommitHash)) + + bitsLocalArtLoc = self.fetch_asset(self._bitsArtURL, + asset_hash=self._bitsArtSHA1Hash) + self.logger.info("downloaded bits artifacts to %s", bitsLocalArtLoc) + + # extract the bits artifact in the temp working directory + with zipfile.ZipFile(bitsLocalArtLoc, 'r') as zref: + zref.extractall(prebuiltDir) + + # extract the bits software in the temp working directory + with zipfile.ZipFile(bits_zip_file, 'r') as zref: + zref.extractall(self._workDir) + + with tarfile.open(grub_tar_file, 'r', encoding='utf-8') as tarball: + tarball.extractall(self._workDir) + + self.copy_test_scripts() + self.copy_bits_config() + self.generate_bits_iso() + + def parse_log(self): + """parse the log generated by running bits tests and + check for failures. + """ + debugconf = os.path.join(self._workDir, self._debugcon_log) + log = "" + with open(debugconf, 'r', encoding='utf-8') as filehandle: + log = filehandle.read() + + matchiter = re.finditer(r'(.*Summary: )(\d+ passed), (\d+ failed).*', + log) + for match in matchiter: + # verify that no test cases failed. + try: + self.assertEqual(match.group(3).split()[0], '0', + 'Some bits tests seems to have failed. ' \ + 'Please check the test logs for more info.') + except AssertionError as e: + self._print_log(log) + raise e + else: + if os.getenv('V'): + self._print_log(log) + + def tearDown(self): + """ + Lets do some cleanups. + """ + if self._vm: + self.assertFalse(not self._vm.is_running) + self.logger.info('removing the work directory %s', self._workDir) + shutil.rmtree(self._workDir) + super().tearDown() + + def test_acpi_smbios_bits(self): + """The main test case implementaion.""" + + iso_file = os.path.join(self._workDir, + 'bits-%d.iso' %self._bitsInternalVer) + + self.assertTrue(os.access(iso_file, os.R_OK)) + + self._vm = QEMUBitsMachine(binary=self.qemu_bin, + base_temp_dir=self._workDir, + debugcon_log=self._debugcon_log, + debugcon_addr=self._debugcon_addr) + + self._vm.add_args('-cdrom', '%s' %iso_file) + # the vm needs to be run under icount so that TCG emulation is + # consistent in terms of timing. smilatency tests have consistent + # timing requirements. + self._vm.add_args('-icount', 'auto') + + args = " ".join(str(arg) for arg in self._vm.base_args()) + \ + " " + " ".join(str(arg) for arg in self._vm.args) + + self.logger.info("launching QEMU vm with the following arguments: %s", + args) + + self._vm.launch() + # biosbits has been configured to run all the specified test suites + # in batch mode and then automatically initiate a vm shutdown. + # sleep for maximum of one minute + max_sleep_time = time.monotonic() + 60 + while self._vm.is_running() and time.monotonic() < max_sleep_time: + time.sleep(1) + + self.assertFalse(time.monotonic() > max_sleep_time, + 'The VM seems to have failed to shutdown in time') + + self.parse_log() From a5ebaaf98c370ecdef02ea1c461743437555504e Mon Sep 17 00:00:00 2001 From: Ani Sinha Date: Fri, 21 Oct 2022 15:21:07 +0530 Subject: [PATCH 541/705] acpi/tests/avocado/bits/doc: add a doc file to describe the acpi bits test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A doc file is added under docs/devel that describes the purpose of the various test files and gives guidance to developers on where and how to make changes. Cc: Daniel P. Berrange" Cc: Paolo Bonzini Cc: Maydell Peter Cc: John Snow Cc: Thomas Huth Cc: Alex Bennée Cc: Igor Mammedov Cc: Michael Tsirkin Signed-off-by: Ani Sinha Message-Id: <20221021095108.104843-7-ani@anisinha.ca> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- docs/devel/acpi-bits.rst | 145 +++++++++++++++++++++++++++++++++++++ docs/devel/index-build.rst | 1 + 2 files changed, 146 insertions(+) create mode 100644 docs/devel/acpi-bits.rst diff --git a/docs/devel/acpi-bits.rst b/docs/devel/acpi-bits.rst new file mode 100644 index 0000000000..c9564d871a --- /dev/null +++ b/docs/devel/acpi-bits.rst @@ -0,0 +1,145 @@ +============================================================================= +ACPI/SMBIOS avocado tests using biosbits +============================================================================= + +Biosbits is a software written by Josh Triplett that can be downloaded +from https://biosbits.org/. The github codebase can be found +`here `__. It is a software that executes +the bios components such as acpi and smbios tables directly through acpica +bios interpreter (a freely available C based library written by Intel, +downloadable from https://acpica.org/ and is included with biosbits) without an +operating system getting involved in between. +There are several advantages to directly testing the bios in a real physical +machine or VM as opposed to indirectly discovering bios issues through the +operating system. For one thing, the OSes tend to hide bios problems from the +end user. The other is that we have more control of what we wanted to test +and how by directly using acpica interpreter on top of the bios on a running +system. More details on the inspiration for developing biosbits and its real +life uses can be found in [#a]_ and [#b]_. +This directory contains tests written in python using avocado framework that +exercises the QEMU bios components using biosbits and reports test failures. +For QEMU, we maintain a fork of bios bits in gitlab along with all the +dependent submodules: +https://gitlab.com/qemu-project/biosbits-bits +This fork contains numerous fixes, a newer acpica and changes specific to +running this avocado QEMU tests using bits. The author of this document +is the sole maintainer of the QEMU fork of bios bits repo. + +Under the directory ``tests/avocado/``, ``acpi-bits.py`` is a QEMU avocado +test that drives all this. + +A brief description of the various test files follows. + +Under ``tests/avocado/`` as the root we have: + +:: + + ├── acpi-bits + │ ├── bits-config + │ │ └── bits-cfg.txt + │ ├── bits-tests + │ │ ├── smbios.py2 + │ │ ├── testacpi.py2 + │ │ └── testcpuid.py2 + │ └── README + ├── acpi-bits.py + +* ``tests/avocado``: + + ``acpi-bits.py``: + This is the main python avocado test script that generates a + biosbits iso. It then spawns a QEMU VM with it, collects the log and reports + test failures. This is the script one would be interested in if they wanted + to add or change some component of the log parsing, add a new command line + to alter how QEMU is spawned etc. Test writers typically would not need to + modify this script unless they wanted to enhance or change the log parsing + for their tests. In order to enable debugging, you can set **V=1** + environment variable. This enables verbose mode for the test and also dumps + the entire log from bios bits and more information in case failure happens. + + In order to run this test, please perform the following steps from the QEMU + build directory: + :: + + $ make check-venv (needed only the first time to create the venv) + $ ./tests/venv/bin/avocado run -t acpi tests/avocado + + The above will run all acpi avocado tests including this one. + In order to run the individual tests, perform the following: + :: + + $ ./tests/venv/bin/avocado run tests/avocado/acpi-bits.py --tap - + + The above will produce output in tap format. You can omit "--tap -" in the + end and it will produce output like the following: + :: + + $ ./tests/venv/bin/avocado run tests/avocado/acpi-bits.py + Fetching asset from tests/avocado/acpi-bits.py:AcpiBitsTest.test_acpi_smbios_bits + JOB ID : eab225724da7b64c012c65705dc2fa14ab1defef + JOB LOG : /home/anisinha/avocado/job-results/job-2022-10-10T17.58-eab2257/job.log + (1/1) tests/avocado/acpi-bits.py:AcpiBitsTest.test_acpi_smbios_bits: PASS (33.09 s) + RESULTS : PASS 1 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 | CANCEL 0 + JOB TIME : 39.22 s + + You can inspect the log file for more information about the run or in order + to diagnoze issues. If you pass V=1 in the environment, more diagnostic logs + would be found in the test log. + +* ``tests/avocado/acpi-bits/bits-config``: + + This location contains biosbits configuration files that determine how the + software runs the tests. + + ``bits-config.txt``: + This is the biosbits config file that determines what tests + or actions are performed by bits. The description of the config options are + provided in the file itself. + +* ``tests/avocado/acpi-bits/bits-tests``: + + This directory contains biosbits python based tests that are run from within + the biosbits environment in the spawned VM. New additions of test cases can + be made in the appropriate test file. For example, new acpi tests can go + into testacpi.py2 and one would call testsuite.add_test() to register the new + test so that it gets executed as a part of the ACPI tests. + It might be occasionally necessary to disable some subtests or add a new + test that belongs to a test suite not already present in this directory. To + do this, please clone the bits source from + https://gitlab.com/qemu-project/biosbits-bits/-/tree/qemu-bits. + Note that this is the "qemu-bits" branch and not the "bits" branch of the + repository. "qemu-bits" is the branch where we have made all the QEMU + specific enhancements and we must use the source from this branch only. + Copy the test suite/script that needs modification (addition of new tests + or disabling them) from python directory into this directory. For + example, in order to change cpuid related tests, copy the following + file into this directory and rename it with .py2 extension: + https://gitlab.com/qemu-project/biosbits-bits/-/blob/qemu-bits/python/testcpuid.py + Then make your additions and changes here. Therefore, the steps are: + + (a) Copy unmodified test script to this directory from bits source. + (b) Add a SPDX license header. + (c) Perform modifications to the test. + + Commits (a), (b) and (c) should go under separate commits so that the original + test script and the changes we have made are separated and clear. + + The test framework will then use your modified test script to run the test. + No further changes would be needed. Please check the logs to make sure that + appropriate changes have taken effect. + + The tests have an extension .py2 in order to indicate that: + + (a) They are python2.7 based scripts and not python 3 scripts. + (b) They are run from within the bios bits VM and is not subjected to QEMU + build/test python script maintainance and dependency resolutions. + (c) They need not be loaded by avocado framework when running tests. + + +Author: Ani Sinha + +References: +----------- +.. [#a] https://blog.linuxplumbersconf.org/2011/ocw/system/presentations/867/original/bits.pdf +.. [#b] https://www.youtube.com/watch?v=36QIepyUuhg + diff --git a/docs/devel/index-build.rst b/docs/devel/index-build.rst index 1002a533a6..57e8d39d98 100644 --- a/docs/devel/index-build.rst +++ b/docs/devel/index-build.rst @@ -11,6 +11,7 @@ the basics if you are adding new files and targets to the build. build-system kconfig testing + acpi-bits qtest ci qapi-code-gen From 76f831dc6b1d843270e10b9da5de657708a063ae Mon Sep 17 00:00:00 2001 From: Ani Sinha Date: Fri, 21 Oct 2022 15:21:08 +0530 Subject: [PATCH 542/705] MAINTAINERS: add myself as the maintainer for acpi biosbits avocado tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I wrote the biosbits avocado tests for testing QEMU's ACPI/SMBIOS implementation and all the related changes including fixes in biosbits software itself. Making myself as the maintainer for QEMU's biosbits related files and test scripts. Cc: Daniel P. Berrangé Cc: Paolo Bonzini Cc: Maydell Peter Cc: John Snow Cc: Thomas Huth Cc: Alex Bennée Cc: Igor Mammedov Cc: Michael Tsirkin Signed-off-by: Ani Sinha Reviewed-by: Alex Bennée Message-Id: <20221021095108.104843-8-ani@anisinha.ca> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- MAINTAINERS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 4adf8c65db..07df572adf 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1862,6 +1862,13 @@ S: Supported F: hw/acpi/viot.c F: hw/acpi/viot.h +ACPI/AVOCADO/BIOSBITS +M: Ani Sinha +S: Supported +F: tests/avocado/acpi-bits/* +F: tests/avocado/acpi-bits.py +F: docs/devel/acpi-bits.rst + ACPI/HEST/GHES R: Dongjiu Geng L: qemu-arm@nongnu.org From 03a60ae9cac546d05b076676491ed1606f9d9066 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 2 Nov 2022 20:12:32 +1100 Subject: [PATCH 543/705] target/i386: Fix test for paging enabled If CR0.PG is unset, pg_mode will be zero, but it will also be zero for non-PAE/non-PSE page tables with CR0.WP=0. Restore the correct test for paging enabled. Fixes: 98281984a37 ("target/i386: Add MMU_PHYS_IDX and MMU_NESTED_IDX") Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1269 Reported-by: Andreas Gustafsson Signed-off-by: Richard Henderson Message-Id: <20221102091232.1092552-1-richard.henderson@linaro.org> Signed-off-by: Paolo Bonzini --- target/i386/tcg/sysemu/excp_helper.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/target/i386/tcg/sysemu/excp_helper.c b/target/i386/tcg/sysemu/excp_helper.c index d51b5d7431..405a5d414a 100644 --- a/target/i386/tcg/sysemu/excp_helper.c +++ b/target/i386/tcg/sysemu/excp_helper.c @@ -553,12 +553,12 @@ static bool get_physical_address(CPUX86State *env, vaddr addr, break; default: - in.cr3 = env->cr[3]; - in.mmu_idx = mmu_idx; - in.ptw_idx = use_stage2 ? MMU_NESTED_IDX : MMU_PHYS_IDX; - in.pg_mode = get_pg_mode(env); + if (likely(env->cr[0] & CR0_PG_MASK)) { + in.cr3 = env->cr[3]; + in.mmu_idx = mmu_idx; + in.ptw_idx = use_stage2 ? MMU_NESTED_IDX : MMU_PHYS_IDX; + in.pg_mode = get_pg_mode(env); - if (likely(in.pg_mode)) { if (in.pg_mode & PG_MODE_LMA) { /* test virtual address sign extension */ int shift = in.pg_mode & PG_MODE_LA57 ? 56 : 47; From dcd86148e23509fb2cedeb5ac38c20763b71141f Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Thu, 27 Oct 2022 08:58:37 +0200 Subject: [PATCH 544/705] linux-user/hppa: Detect glibc ABORT_INSTRUCTION and EXCP_BREAK handler The glibc on the hppa platform uses the "iitlbp %r0,(%sr0, %r0)" assembler instruction as ABORT_INSTRUCTION. If this (in userspace context) illegal assembler statement is found, dump the registers and report the failure to userspace the same way as the Linux kernel on physical hardware. For other illegal instructions report TARGET_ILL_ILLOPC instead of TARGET_ILL_ILLOPN as si_code. Additionally add the missing EXCP_BREAK exception handler which occurs when the "break x,y" assembler instruction is executed and report EXCP_ASSIST traps. Signed-off-by: Helge Deller Message-Id: Signed-off-by: Laurent Vivier --- linux-user/hppa/cpu_loop.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/linux-user/hppa/cpu_loop.c b/linux-user/hppa/cpu_loop.c index 1ef3b46191..8ab1335106 100644 --- a/linux-user/hppa/cpu_loop.c +++ b/linux-user/hppa/cpu_loop.c @@ -147,15 +147,20 @@ void cpu_loop(CPUHPPAState *env) force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_MAPERR, env->iaoq_f); break; case EXCP_ILL: - EXCP_DUMP(env, "qemu: got CPU exception 0x%x - aborting\n", trapnr); - force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPN, env->iaoq_f); + EXCP_DUMP(env, "qemu: EXCP_ILL exception %#x\n", trapnr); + force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPC, env->iaoq_f); break; case EXCP_PRIV_OPR: - EXCP_DUMP(env, "qemu: got CPU exception 0x%x - aborting\n", trapnr); - force_sig_fault(TARGET_SIGILL, TARGET_ILL_PRVOPC, env->iaoq_f); + /* check for glibc ABORT_INSTRUCTION "iitlbp %r0,(%sr0, %r0)" */ + EXCP_DUMP(env, "qemu: EXCP_PRIV_OPR exception %#x\n", trapnr); + if (env->cr[CR_IIR] == 0x04000000) { + force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPC, env->iaoq_f); + } else { + force_sig_fault(TARGET_SIGILL, TARGET_ILL_PRVOPC, env->iaoq_f); + } break; case EXCP_PRIV_REG: - EXCP_DUMP(env, "qemu: got CPU exception 0x%x - aborting\n", trapnr); + EXCP_DUMP(env, "qemu: EXCP_PRIV_REG exception %#x\n", trapnr); force_sig_fault(TARGET_SIGILL, TARGET_ILL_PRVREG, env->iaoq_f); break; case EXCP_OVERFLOW: @@ -167,6 +172,10 @@ void cpu_loop(CPUHPPAState *env) case EXCP_ASSIST: force_sig_fault(TARGET_SIGFPE, 0, env->iaoq_f); break; + case EXCP_BREAK: + EXCP_DUMP(env, "qemu: EXCP_BREAK exception %#x\n", trapnr); + force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->iaoq_f & ~3); + break; case EXCP_DEBUG: force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->iaoq_f); break; From af804f39cc7d3e0bed1c20c414cb43c1662c4465 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Tue, 25 Oct 2022 04:34:14 +0200 Subject: [PATCH 545/705] linux-user: Add close_range() syscall Signed-off-by: Helge Deller Reviewed-by: Richard Henderson Message-Id: Signed-off-by: Laurent Vivier --- linux-user/strace.list | 3 +++ linux-user/syscall.c | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/linux-user/strace.list b/linux-user/strace.list index 3df2184580..cd995e5d56 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -103,6 +103,9 @@ #ifdef TARGET_NR_close { TARGET_NR_close, "close" , "%s(%d)", NULL, NULL }, #endif +#ifdef TARGET_NR_close_range +{ TARGET_NR_close_range, "close_range" , "%s(%u,%u,%u)", NULL, NULL }, +#endif #ifdef TARGET_NR_connect { TARGET_NR_connect, "connect" , "%s(%d,%#x,%d)", NULL, NULL }, #endif diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 8402c1399d..8b18adfba8 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -364,6 +364,13 @@ _syscall3(int,sys_syslog,int,type,char*,bufp,int,len) #ifdef __NR_exit_group _syscall1(int,exit_group,int,error_code) #endif +#if defined(__NR_close_range) && defined(TARGET_NR_close_range) +#define __NR_sys_close_range __NR_close_range +_syscall3(int,sys_close_range,int,first,int,last,int,flags) +#ifndef CLOSE_RANGE_CLOEXEC +#define CLOSE_RANGE_CLOEXEC (1U << 2) +#endif +#endif #if defined(__NR_futex) _syscall6(int,sys_futex,int *,uaddr,int,op,int,val, const struct timespec *,timeout,int *,uaddr2,int,val3) @@ -8756,6 +8763,18 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1, case TARGET_NR_close: fd_trans_unregister(arg1); return get_errno(close(arg1)); +#if defined(__NR_close_range) && defined(TARGET_NR_close_range) + case TARGET_NR_close_range: + ret = get_errno(sys_close_range(arg1, arg2, arg3)); + if (ret == 0 && !(arg3 & CLOSE_RANGE_CLOEXEC)) { + abi_long fd, maxfd; + maxfd = MIN(arg2, target_fd_max); + for (fd = arg1; fd < maxfd; fd++) { + fd_trans_unregister(fd); + } + } + return ret; +#endif case TARGET_NR_brk: return do_brk(arg1); From 8b95210fcb2330dd3b682ff3a5a734881baa8bef Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Mon, 24 Oct 2022 22:45:44 +0200 Subject: [PATCH 546/705] linux-user: Add strace output for timer_settime64() syscall Add missing timer_settime64() strace output and specify format for timer_settime(). Signed-off-by: Helge Deller Message-Id: Signed-off-by: Laurent Vivier --- linux-user/strace.list | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/linux-user/strace.list b/linux-user/strace.list index cd995e5d56..3a898e2532 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -1534,7 +1534,10 @@ { TARGET_NR_timer_gettime, "timer_gettime" , NULL, NULL, NULL }, #endif #ifdef TARGET_NR_timer_settime -{ TARGET_NR_timer_settime, "timer_settime" , NULL, NULL, NULL }, +{ TARGET_NR_timer_settime, "timer_settime" , "%s(%d,%d,%p,%p)", NULL, NULL }, +#endif +#ifdef TARGET_NR_timer_settime64 +{ TARGET_NR_timer_settime64, "timer_settime64" , "%s(%d,%d,%p,%p)", NULL, NULL }, #endif #ifdef TARGET_NR_timerfd { TARGET_NR_timerfd, "timerfd" , NULL, NULL, NULL }, From 16c81dd563b94e9392a578ccf5aa762d01e8f165 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Fri, 28 Oct 2022 16:12:20 +0800 Subject: [PATCH 547/705] linux-user: always translate cmsg when recvmsg It's possible that a message contains both normal payload and ancillary data in the same message, and even if no ancillary data is available this information should be passed to the target, otherwise the target cmsghdr will be left uninitialized and the target is going to access uninitialized memory if it expects cmsg. Always call the function that translate cmsg when recvmsg, because that function should be empty-cmsg-safe (it creates an empty cmsg in the target). Signed-off-by: Icenowy Zheng Reviewed-by: Laurent Vivier Message-Id: <20221028081220.1604244-1-uwu@icenowy.me> Signed-off-by: Laurent Vivier --- linux-user/syscall.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 8b18adfba8..24b25759be 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -3353,7 +3353,8 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp, if (fd_trans_host_to_target_data(fd)) { ret = fd_trans_host_to_target_data(fd)(msg.msg_iov->iov_base, MIN(msg.msg_iov->iov_len, len)); - } else { + } + if (!is_error(ret)) { ret = host_to_target_cmsg(msgp, &msg); } if (!is_error(ret)) { From 2461e752199ca457bf0973b6c8a77dc30585809c Mon Sep 17 00:00:00 2001 From: Avihai Horon Date: Sun, 16 Oct 2022 11:57:52 +0300 Subject: [PATCH 548/705] vfio/migration: Fix wrong enum usage vfio_migration_init() initializes VFIOMigration->device_state using enum of VFIO migration protocol v2. Current implemented protocol is v1 so v1 enum should be used. Fix it. Fixes: 429c72800654 ("vfio/migration: Fix incorrect initialization value for parameters in VFIOMigration") Signed-off-by: Avihai Horon Reviewed-by: Zhang Chen Link: https://lore.kernel.org/r/20221016085752.32740-1-avihaih@nvidia.com Signed-off-by: Alex Williamson --- hw/vfio/migration.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c index 3de4252111..c74453e0b5 100644 --- a/hw/vfio/migration.c +++ b/hw/vfio/migration.c @@ -806,7 +806,7 @@ static int vfio_migration_init(VFIODevice *vbasedev, } vbasedev->migration = g_new0(VFIOMigration, 1); - vbasedev->migration->device_state = VFIO_DEVICE_STATE_RUNNING; + vbasedev->migration->device_state = VFIO_DEVICE_STATE_V1_RUNNING; vbasedev->migration->vm_running = runstate_is_running(); ret = vfio_region_setup(obj, vbasedev, &vbasedev->migration->region, From 3fc8f74b51858353356968b3d04a5cccdc547caa Mon Sep 17 00:00:00 2001 From: Xiaojuan Yang Date: Fri, 21 Oct 2022 09:53:06 +0800 Subject: [PATCH 549/705] hw/intc: Convert the memops to with_attrs in LoongArch extioi MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Converting the MemoryRegionOps read/write handlers to with_attrs in LoongArch extioi emulation. Signed-off-by: Xiaojuan Yang Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20221021015307.2570844-2-yangxiaojuan@loongson.cn> Signed-off-by: Song Gao --- hw/intc/loongarch_extioi.c | 31 +++++++++++++++++-------------- hw/intc/trace-events | 3 +-- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c index 22803969bc..72f4b0cde5 100644 --- a/hw/intc/loongarch_extioi.c +++ b/hw/intc/loongarch_extioi.c @@ -68,44 +68,45 @@ static void extioi_setirq(void *opaque, int irq, int level) extioi_update_irq(s, irq, level); } -static uint64_t extioi_readw(void *opaque, hwaddr addr, unsigned size) +static MemTxResult extioi_readw(void *opaque, hwaddr addr, uint64_t *data, + unsigned size, MemTxAttrs attrs) { LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque); unsigned long offset = addr & 0xffff; - uint32_t index, cpu, ret = 0; + uint32_t index, cpu; switch (offset) { case EXTIOI_NODETYPE_START ... EXTIOI_NODETYPE_END - 1: index = (offset - EXTIOI_NODETYPE_START) >> 2; - ret = s->nodetype[index]; + *data = s->nodetype[index]; break; case EXTIOI_IPMAP_START ... EXTIOI_IPMAP_END - 1: index = (offset - EXTIOI_IPMAP_START) >> 2; - ret = s->ipmap[index]; + *data = s->ipmap[index]; break; case EXTIOI_ENABLE_START ... EXTIOI_ENABLE_END - 1: index = (offset - EXTIOI_ENABLE_START) >> 2; - ret = s->enable[index]; + *data = s->enable[index]; break; case EXTIOI_BOUNCE_START ... EXTIOI_BOUNCE_END - 1: index = (offset - EXTIOI_BOUNCE_START) >> 2; - ret = s->bounce[index]; + *data = s->bounce[index]; break; case EXTIOI_COREISR_START ... EXTIOI_COREISR_END - 1: index = ((offset - EXTIOI_COREISR_START) & 0x1f) >> 2; cpu = ((offset - EXTIOI_COREISR_START) >> 8) & 0x3; - ret = s->coreisr[cpu][index]; + *data = s->coreisr[cpu][index]; break; case EXTIOI_COREMAP_START ... EXTIOI_COREMAP_END - 1: index = (offset - EXTIOI_COREMAP_START) >> 2; - ret = s->coremap[index]; + *data = s->coremap[index]; break; default: break; } - trace_loongarch_extioi_readw(addr, ret); - return ret; + trace_loongarch_extioi_readw(addr, *data); + return MEMTX_OK; } static inline void extioi_enable_irq(LoongArchExtIOI *s, int index,\ @@ -127,8 +128,9 @@ static inline void extioi_enable_irq(LoongArchExtIOI *s, int index,\ } } -static void extioi_writew(void *opaque, hwaddr addr, - uint64_t val, unsigned size) +static MemTxResult extioi_writew(void *opaque, hwaddr addr, + uint64_t val, unsigned size, + MemTxAttrs attrs) { LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque); int i, cpu, index, old_data, irq; @@ -231,11 +233,12 @@ static void extioi_writew(void *opaque, hwaddr addr, default: break; } + return MEMTX_OK; } static const MemoryRegionOps extioi_ops = { - .read = extioi_readw, - .write = extioi_writew, + .read_with_attrs = extioi_readw, + .write_with_attrs = extioi_writew, .impl.min_access_size = 4, .impl.max_access_size = 4, .valid.min_access_size = 4, diff --git a/hw/intc/trace-events b/hw/intc/trace-events index 0a90c1cdec..6fbc2045e6 100644 --- a/hw/intc/trace-events +++ b/hw/intc/trace-events @@ -306,6 +306,5 @@ loongarch_msi_set_irq(int irq_num) "set msi irq %d" # loongarch_extioi.c loongarch_extioi_setirq(int irq, int level) "set extirq irq %d level %d" -loongarch_extioi_readw(uint64_t addr, uint32_t val) "addr: 0x%"PRIx64 "val: 0x%x" +loongarch_extioi_readw(uint64_t addr, uint64_t val) "addr: 0x%"PRIx64 "val: 0x%" PRIx64 loongarch_extioi_writew(uint64_t addr, uint64_t val) "addr: 0x%"PRIx64 "val: 0x%" PRIx64 - From a649fffcc9589a88464474e9105798eb62023352 Mon Sep 17 00:00:00 2001 From: Xiaojuan Yang Date: Fri, 21 Oct 2022 09:53:07 +0800 Subject: [PATCH 550/705] hw/intc: Fix LoongArch extioi coreisr accessing 1. When cpu read or write extioi COREISR reg, it should access the reg belonged to itself, so the cpu index of 's->coreisr' is current cpu number. Using MemTxAttrs' requester_id to get the cpu index. 2. it need not to mask 0x1f when calculate the coreisr array index. Signed-off-by: Xiaojuan Yang Reviewed-by: Richard Henderson Message-Id: <20221021015307.2570844-3-yangxiaojuan@loongson.cn> Signed-off-by: Song Gao --- hw/intc/loongarch_extioi.c | 10 ++++++---- target/loongarch/iocsr_helper.c | 19 +++++++++++-------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c index 72f4b0cde5..4b8ec3f28a 100644 --- a/hw/intc/loongarch_extioi.c +++ b/hw/intc/loongarch_extioi.c @@ -93,8 +93,9 @@ static MemTxResult extioi_readw(void *opaque, hwaddr addr, uint64_t *data, *data = s->bounce[index]; break; case EXTIOI_COREISR_START ... EXTIOI_COREISR_END - 1: - index = ((offset - EXTIOI_COREISR_START) & 0x1f) >> 2; - cpu = ((offset - EXTIOI_COREISR_START) >> 8) & 0x3; + index = (offset - EXTIOI_COREISR_START) >> 2; + /* using attrs to get current cpu index */ + cpu = attrs.requester_id; *data = s->coreisr[cpu][index]; break; case EXTIOI_COREMAP_START ... EXTIOI_COREMAP_END - 1: @@ -185,8 +186,9 @@ static MemTxResult extioi_writew(void *opaque, hwaddr addr, s->bounce[index] = val; break; case EXTIOI_COREISR_START ... EXTIOI_COREISR_END - 1: - index = ((offset - EXTIOI_COREISR_START) & 0x1f) >> 2; - cpu = ((offset - EXTIOI_COREISR_START) >> 8) & 0x3; + index = (offset - EXTIOI_COREISR_START) >> 2; + /* using attrs to get current cpu index */ + cpu = attrs.requester_id; old_data = s->coreisr[cpu][index]; s->coreisr[cpu][index] = old_data & ~val; /* write 1 to clear interrrupt */ diff --git a/target/loongarch/iocsr_helper.c b/target/loongarch/iocsr_helper.c index 0e9c537dc7..505853e17b 100644 --- a/target/loongarch/iocsr_helper.c +++ b/target/loongarch/iocsr_helper.c @@ -14,54 +14,57 @@ #include "exec/cpu_ldst.h" #include "tcg/tcg-ldst.h" +#define GET_MEMTXATTRS(cas) \ + ((MemTxAttrs){.requester_id = env_cpu(cas)->cpu_index}) + uint64_t helper_iocsrrd_b(CPULoongArchState *env, target_ulong r_addr) { return address_space_ldub(&env->address_space_iocsr, r_addr, - MEMTXATTRS_UNSPECIFIED, NULL); + GET_MEMTXATTRS(env), NULL); } uint64_t helper_iocsrrd_h(CPULoongArchState *env, target_ulong r_addr) { return address_space_lduw(&env->address_space_iocsr, r_addr, - MEMTXATTRS_UNSPECIFIED, NULL); + GET_MEMTXATTRS(env), NULL); } uint64_t helper_iocsrrd_w(CPULoongArchState *env, target_ulong r_addr) { return address_space_ldl(&env->address_space_iocsr, r_addr, - MEMTXATTRS_UNSPECIFIED, NULL); + GET_MEMTXATTRS(env), NULL); } uint64_t helper_iocsrrd_d(CPULoongArchState *env, target_ulong r_addr) { return address_space_ldq(&env->address_space_iocsr, r_addr, - MEMTXATTRS_UNSPECIFIED, NULL); + GET_MEMTXATTRS(env), NULL); } void helper_iocsrwr_b(CPULoongArchState *env, target_ulong w_addr, target_ulong val) { address_space_stb(&env->address_space_iocsr, w_addr, - val, MEMTXATTRS_UNSPECIFIED, NULL); + val, GET_MEMTXATTRS(env), NULL); } void helper_iocsrwr_h(CPULoongArchState *env, target_ulong w_addr, target_ulong val) { address_space_stw(&env->address_space_iocsr, w_addr, - val, MEMTXATTRS_UNSPECIFIED, NULL); + val, GET_MEMTXATTRS(env), NULL); } void helper_iocsrwr_w(CPULoongArchState *env, target_ulong w_addr, target_ulong val) { address_space_stl(&env->address_space_iocsr, w_addr, - val, MEMTXATTRS_UNSPECIFIED, NULL); + val, GET_MEMTXATTRS(env), NULL); } void helper_iocsrwr_d(CPULoongArchState *env, target_ulong w_addr, target_ulong val) { address_space_stq(&env->address_space_iocsr, w_addr, - val, MEMTXATTRS_UNSPECIFIED, NULL); + val, GET_MEMTXATTRS(env), NULL); } From 021836936ef90fe1e52fe7ab7b7f2bcb9a66368a Mon Sep 17 00:00:00 2001 From: Xiaojuan Yang Date: Fri, 28 Oct 2022 09:40:05 +0800 Subject: [PATCH 551/705] hw/loongarch: Load FDT table into dram memory space Load FDT table into dram memory space, and the addr is 2 MiB. Since lowmem region starts from 0, FDT base address is located at 2 MiB to avoid NULL pointer access. Signed-off-by: Xiaojuan Yang Acked-by: Song Gao Message-Id: <20221028014007.2718352-2-yangxiaojuan@loongson.cn> Signed-off-by: Song Gao --- hw/loongarch/virt.c | 18 +++++++++++------- include/hw/loongarch/virt.h | 3 --- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index 4b595a9ea4..50e9829a94 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -159,7 +159,6 @@ static void fdt_add_pcie_node(const LoongArchMachineState *lams) 1, FDT_PCI_RANGE_MMIO, 2, base_mmio, 2, base_mmio, 2, size_mmio); g_free(nodename); - qemu_fdt_dumpdtb(ms->fdt, lams->fdt_size); } static void fdt_add_irqchip_node(LoongArchMachineState *lams) @@ -656,6 +655,7 @@ static void loongarch_init(MachineState *machine) MemoryRegion *address_space_mem = get_system_memory(); LoongArchMachineState *lams = LOONGARCH_MACHINE(machine); int i; + hwaddr fdt_base; if (!cpu_model) { cpu_model = LOONGARCH_CPU_TYPE_NAME("la464"); @@ -760,12 +760,16 @@ static void loongarch_init(MachineState *machine) lams->machine_done.notify = virt_machine_done; qemu_add_machine_init_done_notifier(&lams->machine_done); fdt_add_pcie_node(lams); - - /* load fdt */ - MemoryRegion *fdt_rom = g_new(MemoryRegion, 1); - memory_region_init_rom(fdt_rom, NULL, "fdt", VIRT_FDT_SIZE, &error_fatal); - memory_region_add_subregion(get_system_memory(), VIRT_FDT_BASE, fdt_rom); - rom_add_blob_fixed("fdt", machine->fdt, lams->fdt_size, VIRT_FDT_BASE); + /* + * Since lowmem region starts from 0, FDT base address is located + * at 2 MiB to avoid NULL pointer access. + * + * Put the FDT into the memory map as a ROM image: this will ensure + * the FDT is copied again upon reset, even if addr points into RAM. + */ + fdt_base = 2 * MiB; + qemu_fdt_dumpdtb(machine->fdt, lams->fdt_size); + rom_add_blob_fixed("fdt", machine->fdt, lams->fdt_size, fdt_base); } bool loongarch_is_acpi_enabled(LoongArchMachineState *lams) diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h index 09f1c88ee5..45c383f5a7 100644 --- a/include/hw/loongarch/virt.h +++ b/include/hw/loongarch/virt.h @@ -28,9 +28,6 @@ #define VIRT_GED_MEM_ADDR (VIRT_GED_EVT_ADDR + ACPI_GED_EVT_SEL_LEN) #define VIRT_GED_REG_ADDR (VIRT_GED_MEM_ADDR + MEMORY_HOTPLUG_IO_LEN) -#define VIRT_FDT_BASE 0x1c400000 -#define VIRT_FDT_SIZE 0x100000 - struct LoongArchMachineState { /*< private >*/ MachineState parent_obj; From ca5bf7ad0222ad4a884c90a821a22000d918c54e Mon Sep 17 00:00:00 2001 From: Xiaojuan Yang Date: Fri, 28 Oct 2022 09:40:06 +0800 Subject: [PATCH 552/705] hw/loongarch: Improve fdt for LoongArch virt machine Add new items into LoongArch FDT, including rtc and uart info. Signed-off-by: Xiaojuan Yang Reviewed-by: Song Gao Message-Id: <20221028014007.2718352-3-yangxiaojuan@loongson.cn> Signed-off-by: Song Gao --- hw/loongarch/virt.c | 31 +++++++++++++++++++++++++++++++ include/hw/pci-host/ls7a.h | 1 + 2 files changed, 32 insertions(+) diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index 50e9829a94..afc1c8ac77 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -42,6 +42,35 @@ #include "hw/display/ramfb.h" #include "hw/mem/pc-dimm.h" +static void fdt_add_rtc_node(LoongArchMachineState *lams) +{ + char *nodename; + hwaddr base = VIRT_RTC_REG_BASE; + hwaddr size = VIRT_RTC_LEN; + MachineState *ms = MACHINE(lams); + + nodename = g_strdup_printf("/rtc@%" PRIx64, base); + qemu_fdt_add_subnode(ms->fdt, nodename); + qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "loongson,ls7a-rtc"); + qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 0x0, base, size); + g_free(nodename); +} + +static void fdt_add_uart_node(LoongArchMachineState *lams) +{ + char *nodename; + hwaddr base = VIRT_UART_BASE; + hwaddr size = VIRT_UART_SIZE; + MachineState *ms = MACHINE(lams); + + nodename = g_strdup_printf("/serial@%" PRIx64, base); + qemu_fdt_add_subnode(ms->fdt, nodename); + qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "ns16550a"); + qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", 0x0, base, 0x0, size); + qemu_fdt_setprop_cell(ms->fdt, nodename, "clock-frequency", 100000000); + g_free(nodename); +} + static void create_fdt(LoongArchMachineState *lams) { MachineState *ms = MACHINE(lams); @@ -422,6 +451,7 @@ static void loongarch_devices_init(DeviceState *pch_pic, LoongArchMachineState * qdev_get_gpio_in(pch_pic, VIRT_UART_IRQ - PCH_PIC_IRQ_OFFSET), 115200, serial_hd(0), DEVICE_LITTLE_ENDIAN); + fdt_add_uart_node(lams); /* Network init */ for (i = 0; i < nb_nics; i++) { @@ -442,6 +472,7 @@ static void loongarch_devices_init(DeviceState *pch_pic, LoongArchMachineState * sysbus_create_simple("ls7a_rtc", VIRT_RTC_REG_BASE, qdev_get_gpio_in(pch_pic, VIRT_RTC_IRQ - PCH_PIC_IRQ_OFFSET)); + fdt_add_rtc_node(lams); pm_mem = g_new(MemoryRegion, 1); memory_region_init_io(pm_mem, NULL, &loongarch_virt_pm_ops, diff --git a/include/hw/pci-host/ls7a.h b/include/hw/pci-host/ls7a.h index 9bd875ca8b..df7fa55a30 100644 --- a/include/hw/pci-host/ls7a.h +++ b/include/hw/pci-host/ls7a.h @@ -37,6 +37,7 @@ #define VIRT_PCI_IRQS 48 #define VIRT_UART_IRQ (PCH_PIC_IRQ_OFFSET + 2) #define VIRT_UART_BASE 0x1fe001e0 +#define VIRT_UART_SIZE 0X100 #define VIRT_RTC_IRQ (PCH_PIC_IRQ_OFFSET + 3) #define VIRT_MISC_REG_BASE (VIRT_PCH_REG_BASE + 0x00080000) #define VIRT_RTC_REG_BASE (VIRT_MISC_REG_BASE + 0x00050100) From 3dfbb6dee57f48abdc5b51edfd4dd57869d838df Mon Sep 17 00:00:00 2001 From: Xiaojuan Yang Date: Fri, 28 Oct 2022 09:40:07 +0800 Subject: [PATCH 553/705] hw/loongarch: Add TPM device for LoongArch virt machine Add TPM device for LoongArch virt machine, including establish TPM acpi info and add TYPE_TPM_TIS_SYSBUS to dynamic_sysbus_devices list. Signed-off-by: Xiaojuan Yang Reviewed-by: Song Gao Message-Id: <20221028014007.2718352-4-yangxiaojuan@loongson.cn> Signed-off-by: Song Gao --- hw/loongarch/acpi-build.c | 51 ++++++++++++++++++++++++++++++++++++++- hw/loongarch/virt.c | 4 +++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c index 378a6d9d38..68dfb9f88a 100644 --- a/hw/loongarch/acpi-build.c +++ b/hw/loongarch/acpi-build.c @@ -31,6 +31,9 @@ #include "hw/acpi/generic_event_device.h" #include "hw/pci-host/gpex.h" +#include "sysemu/tpm.h" +#include "hw/platform-bus.h" +#include "hw/acpi/aml-build.h" #define ACPI_BUILD_ALIGN_SIZE 0x1000 #define ACPI_BUILD_TABLE_SIZE 0x20000 @@ -275,6 +278,41 @@ static void build_pci_device_aml(Aml *scope, LoongArchMachineState *lams) acpi_dsdt_add_gpex(scope, &cfg); } +#ifdef CONFIG_TPM +static void acpi_dsdt_add_tpm(Aml *scope, LoongArchMachineState *vms) +{ + PlatformBusDevice *pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev); + hwaddr pbus_base = VIRT_PLATFORM_BUS_BASEADDRESS; + SysBusDevice *sbdev = SYS_BUS_DEVICE(tpm_find()); + MemoryRegion *sbdev_mr; + hwaddr tpm_base; + + if (!sbdev) { + return; + } + + tpm_base = platform_bus_get_mmio_addr(pbus, sbdev, 0); + assert(tpm_base != -1); + + tpm_base += pbus_base; + + sbdev_mr = sysbus_mmio_get_region(sbdev, 0); + + Aml *dev = aml_device("TPM0"); + aml_append(dev, aml_name_decl("_HID", aml_string("MSFT0101"))); + aml_append(dev, aml_name_decl("_STR", aml_string("TPM 2.0 Device"))); + aml_append(dev, aml_name_decl("_UID", aml_int(0))); + + Aml *crs = aml_resource_template(); + aml_append(crs, + aml_memory32_fixed(tpm_base, + (uint32_t)memory_region_size(sbdev_mr), + AML_READ_WRITE)); + aml_append(dev, aml_name_decl("_CRS", crs)); + aml_append(scope, dev); +} +#endif + /* build DSDT */ static void build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine) @@ -289,7 +327,9 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine) build_uart_device_aml(dsdt); build_pci_device_aml(dsdt, lams); build_la_ged_aml(dsdt, machine); - +#ifdef CONFIG_TPM + acpi_dsdt_add_tpm(dsdt, lams); +#endif /* System State Package */ scope = aml_scope("\\"); pkg = aml_package(4); @@ -359,6 +399,15 @@ static void acpi_build(AcpiBuildTables *tables, MachineState *machine) lams->oem_table_id); } +#ifdef CONFIG_TPM + /* TPM info */ + if (tpm_get_version(tpm_find()) == TPM_VERSION_2_0) { + acpi_add_table(table_offsets, tables_blob); + build_tpm2(tables_blob, tables->linker, + tables->tcpalog, lams->oem_id, + lams->oem_table_id); + } +#endif /* Add tables supplied by user (if any) */ for (u = acpi_table_first(); u; u = acpi_table_next(u)) { unsigned len = acpi_table_len(u); diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index afc1c8ac77..5e4c2790bf 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -41,6 +41,7 @@ #include "hw/platform-bus.h" #include "hw/display/ramfb.h" #include "hw/mem/pc-dimm.h" +#include "sysemu/tpm.h" static void fdt_add_rtc_node(LoongArchMachineState *lams) { @@ -960,6 +961,9 @@ static void loongarch_class_init(ObjectClass *oc, void *data) object_class_property_set_description(oc, "acpi", "Enable ACPI"); machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE); +#ifdef CONFIG_TPM + machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS); +#endif } static const TypeInfo loongarch_machine_types[] = { From a6b129c8102668717370ec27490523fb1290ae5d Mon Sep 17 00:00:00 2001 From: Song Gao Date: Tue, 1 Nov 2022 11:17:15 +0800 Subject: [PATCH 554/705] target/loongarch: Add exception subcode We need subcodes to distinguish the same excode cs->exception_indexs, such as EXCCODE_ADEF/EXCCODE_ADEM. Signed-off-by: Song Gao Reviewed-by: Richard Henderson Message-ID: <20221101073210.3934280-1-gaosong@loongson.cn> --- target/loongarch/cpu.c | 7 +++-- target/loongarch/cpu.h | 58 ++++++++++++++++++++++-------------------- 2 files changed, 36 insertions(+), 29 deletions(-) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 49393d95d8..b28aaed5ba 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -220,7 +220,10 @@ static void loongarch_cpu_do_interrupt(CPUState *cs) env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA, PC, (env->pc >> 2)); } else { - env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, ECODE, cause); + env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, ECODE, + EXCODE_MCODE(cause)); + env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, ESUBCODE, + EXCODE_SUBCODE(cause)); env->CSR_PRMD = FIELD_DP64(env->CSR_PRMD, CSR_PRMD, PPLV, FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV)); env->CSR_PRMD = FIELD_DP64(env->CSR_PRMD, CSR_PRMD, PIE, @@ -257,7 +260,7 @@ static void loongarch_cpu_do_interrupt(CPUState *cs) env->pc = env->CSR_TLBRENTRY; } else { env->pc = env->CSR_EENTRY; - env->pc += cause * vec_size; + env->pc += EXCODE_MCODE(cause) * vec_size; } qemu_log_mask(CPU_LOG_INT, "%s: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index dce999aaac..dbce176564 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -75,33 +75,37 @@ FIELD(FCSR0, CAUSE, 24, 5) #define FP_DIV0 8 #define FP_INVALID 16 -#define EXCCODE_EXTERNAL_INT 64 /* plus external interrupt number */ -#define EXCCODE_INT 0 -#define EXCCODE_PIL 1 -#define EXCCODE_PIS 2 -#define EXCCODE_PIF 3 -#define EXCCODE_PME 4 -#define EXCCODE_PNR 5 -#define EXCCODE_PNX 6 -#define EXCCODE_PPI 7 -#define EXCCODE_ADEF 8 /* Different exception subcode */ -#define EXCCODE_ADEM 8 -#define EXCCODE_ALE 9 -#define EXCCODE_BCE 10 -#define EXCCODE_SYS 11 -#define EXCCODE_BRK 12 -#define EXCCODE_INE 13 -#define EXCCODE_IPE 14 -#define EXCCODE_FPD 15 -#define EXCCODE_SXD 16 -#define EXCCODE_ASXD 17 -#define EXCCODE_FPE 18 /* Different exception subcode */ -#define EXCCODE_VFPE 18 -#define EXCCODE_WPEF 19 /* Different exception subcode */ -#define EXCCODE_WPEM 19 -#define EXCCODE_BTD 20 -#define EXCCODE_BTE 21 -#define EXCCODE_DBP 26 /* Reserved subcode used for debug */ +#define EXCODE(code, subcode) ( ((subcode) << 6) | (code) ) +#define EXCODE_MCODE(code) ( (code) & 0x3f ) +#define EXCODE_SUBCODE(code) ( (code) >> 6 ) + +#define EXCCODE_EXTERNAL_INT 64 /* plus external interrupt number */ +#define EXCCODE_INT EXCODE(0, 0) +#define EXCCODE_PIL EXCODE(1, 0) +#define EXCCODE_PIS EXCODE(2, 0) +#define EXCCODE_PIF EXCODE(3, 0) +#define EXCCODE_PME EXCODE(4, 0) +#define EXCCODE_PNR EXCODE(5, 0) +#define EXCCODE_PNX EXCODE(6, 0) +#define EXCCODE_PPI EXCODE(7, 0) +#define EXCCODE_ADEF EXCODE(8, 0) /* Different exception subcode */ +#define EXCCODE_ADEM EXCODE(8, 1) +#define EXCCODE_ALE EXCODE(9, 0) +#define EXCCODE_BCE EXCODE(10, 0) +#define EXCCODE_SYS EXCODE(11, 0) +#define EXCCODE_BRK EXCODE(12, 0) +#define EXCCODE_INE EXCODE(13, 0) +#define EXCCODE_IPE EXCODE(14, 0) +#define EXCCODE_FPD EXCODE(15, 0) +#define EXCCODE_SXD EXCODE(16, 0) +#define EXCCODE_ASXD EXCODE(17, 0) +#define EXCCODE_FPE EXCODE(18, 0) /* Different exception subcode */ +#define EXCCODE_VFPE EXCODE(18, 1) +#define EXCCODE_WPEF EXCODE(19, 0) /* Different exception subcode */ +#define EXCCODE_WPEM EXCODE(19, 1) +#define EXCCODE_BTD EXCODE(20, 0) +#define EXCCODE_BTE EXCODE(21, 0) +#define EXCCODE_DBP EXCODE(26, 0) /* Reserved subcode used for debug */ /* cpucfg[0] bits */ FIELD(CPUCFG0, PRID, 0, 32) From 8752b1306002237c39b3f849ca564c9db55c8b1f Mon Sep 17 00:00:00 2001 From: Song Gao Date: Tue, 1 Nov 2022 14:53:31 +0800 Subject: [PATCH 555/705] target/loongarch: Fix raise_mmu_exception() set wrong exception_index When the address is invalid address, We should set exception_index according to MMUAccessType, and EXCCODE_ADEF need't update badinstr. Otherwise, The system enters an infinite loop. e.g: run test.c on system mode test.c: #include void (*func)(int *); int main() { int i = 8; void *ptr = (void *)0x4000000000000000; func = ptr; func(&i); return 0; } Signed-off-by: Song Gao Reviewed-by: Richard Henderson Message-ID: <20221101073210.3934280-2-gaosong@loongson.cn> --- target/loongarch/cpu.c | 1 + target/loongarch/tlb_helper.c | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index b28aaed5ba..1512664214 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -177,6 +177,7 @@ static void loongarch_cpu_do_interrupt(CPUState *cs) } QEMU_FALLTHROUGH; case EXCCODE_PIF: + case EXCCODE_ADEF: cause = cs->exception_index; update_badinstr = 0; break; diff --git a/target/loongarch/tlb_helper.c b/target/loongarch/tlb_helper.c index 610b6d123c..d2f8fb0c60 100644 --- a/target/loongarch/tlb_helper.c +++ b/target/loongarch/tlb_helper.c @@ -229,7 +229,8 @@ static void raise_mmu_exception(CPULoongArchState *env, target_ulong address, switch (tlb_error) { default: case TLBRET_BADADDR: - cs->exception_index = EXCCODE_ADEM; + cs->exception_index = access_type == MMU_INST_FETCH + ? EXCCODE_ADEF : EXCCODE_ADEM; break; case TLBRET_NOMATCH: /* No TLB match for a mapped address */ @@ -643,7 +644,7 @@ bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size, CPULoongArchState *env = &cpu->env; hwaddr physical; int prot; - int ret = TLBRET_BADADDR; + int ret; /* Data access */ ret = get_physical_address(env, &physical, &prot, address, From b4bda2006f482f778d9dbf86038ff115fe89db92 Mon Sep 17 00:00:00 2001 From: Rui Wang Date: Fri, 4 Nov 2022 12:05:16 +0800 Subject: [PATCH 556/705] target/loongarch: Adjust the layout of hardware flags bit fields Suggested-by: Richard Henderson Reviewed-by: Song Gao Signed-off-by: Rui Wang Message-Id: <20221104040517.222059-2-wangrui@loongson.cn> Signed-off-by: Song Gao --- target/loongarch/cpu.h | 9 ++++++++- target/loongarch/insn_trans/trans_privileged.c.inc | 2 +- target/loongarch/translate.c | 6 +++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index dbce176564..f482ad94fe 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -14,6 +14,7 @@ #include "qemu/timer.h" #include "exec/memory.h" #include "hw/sysbus.h" +#include "cpu-csr.h" #define IOCSRF_TEMP 0 #define IOCSRF_NODECNT 1 @@ -391,6 +392,12 @@ static inline int cpu_mmu_index(CPULoongArchState *env, bool ifetch) #endif } +/* + * LoongArch CPUs hardware flags. + */ +#define HW_FLAGS_PLV_MASK R_CSR_CRMD_PLV_MASK /* 0x03 */ +#define HW_FLAGS_CRMD_PG R_CSR_CRMD_PG_MASK /* 0x10 */ + static inline void cpu_get_tb_cpu_state(CPULoongArchState *env, target_ulong *pc, target_ulong *cs_base, @@ -398,7 +405,7 @@ static inline void cpu_get_tb_cpu_state(CPULoongArchState *env, { *pc = env->pc; *cs_base = 0; - *flags = cpu_mmu_index(env, false); + *flags = env->CSR_CRMD & (R_CSR_CRMD_PLV_MASK | R_CSR_CRMD_PG_MASK); } void loongarch_cpu_list(void); diff --git a/target/loongarch/insn_trans/trans_privileged.c.inc b/target/loongarch/insn_trans/trans_privileged.c.inc index 9c4dcbfcfb..ff3a6d95ae 100644 --- a/target/loongarch/insn_trans/trans_privileged.c.inc +++ b/target/loongarch/insn_trans/trans_privileged.c.inc @@ -159,7 +159,7 @@ static const CSRInfo csr_info[] = { static bool check_plv(DisasContext *ctx) { - if (ctx->base.tb->flags == MMU_USER_IDX) { + if (ctx->mem_idx == MMU_USER_IDX) { generate_exception(ctx, EXCCODE_IPE); return true; } diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c index 6091772349..31462b2b61 100644 --- a/target/loongarch/translate.c +++ b/target/loongarch/translate.c @@ -75,7 +75,11 @@ static void loongarch_tr_init_disas_context(DisasContextBase *dcbase, DisasContext *ctx = container_of(dcbase, DisasContext, base); ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK; - ctx->mem_idx = ctx->base.tb->flags; + if (ctx->base.tb->flags & HW_FLAGS_CRMD_PG) { + ctx->mem_idx = ctx->base.tb->flags & HW_FLAGS_PLV_MASK; + } else { + ctx->mem_idx = MMU_DA_IDX; + } /* Bound the number of insns to execute to those left on the page. */ bound = -(ctx->base.pc_first | TARGET_PAGE_MASK) / 4; From 2419978cb09e11bc53a07d4de5621424d2a6a86d Mon Sep 17 00:00:00 2001 From: Rui Wang Date: Fri, 4 Nov 2022 12:05:17 +0800 Subject: [PATCH 557/705] target/loongarch: Fix emulation of float-point disable exception We need to emulate it to generate a floating point disable exception when CSR.EUEN.FPE is zero. Reviewed-by: Richard Henderson Reviewed-by: Song Gao Signed-off-by: Rui Wang Message-Id: <20221104040517.222059-3-wangrui@loongson.cn> Signed-off-by: Song Gao --- target/loongarch/cpu.c | 2 ++ target/loongarch/cpu.h | 2 ++ .../loongarch/insn_trans/trans_farith.c.inc | 30 ++++++++++++++++ target/loongarch/insn_trans/trans_fcmp.c.inc | 11 ++++-- .../loongarch/insn_trans/trans_fmemory.c.inc | 34 +++++++++++++++---- target/loongarch/insn_trans/trans_fmov.c.inc | 29 ++++++++++++++-- 6 files changed, 97 insertions(+), 11 deletions(-) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 1512664214..46b04cbdad 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -48,6 +48,7 @@ static const char * const excp_names[] = { [EXCCODE_BRK] = "Break", [EXCCODE_INE] = "Instruction Non-Existent", [EXCCODE_IPE] = "Instruction privilege error", + [EXCCODE_FPD] = "Floating Point Disabled", [EXCCODE_FPE] = "Floating Point Exception", [EXCCODE_DBP] = "Debug breakpoint", [EXCCODE_BCE] = "Bound Check Exception", @@ -185,6 +186,7 @@ static void loongarch_cpu_do_interrupt(CPUState *cs) case EXCCODE_BRK: case EXCCODE_INE: case EXCCODE_IPE: + case EXCCODE_FPD: case EXCCODE_FPE: case EXCCODE_BCE: env->CSR_BADV = env->pc; diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index f482ad94fe..08c1f6baa1 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -397,6 +397,7 @@ static inline int cpu_mmu_index(CPULoongArchState *env, bool ifetch) */ #define HW_FLAGS_PLV_MASK R_CSR_CRMD_PLV_MASK /* 0x03 */ #define HW_FLAGS_CRMD_PG R_CSR_CRMD_PG_MASK /* 0x10 */ +#define HW_FLAGS_EUEN_FPE 0x04 static inline void cpu_get_tb_cpu_state(CPULoongArchState *env, target_ulong *pc, @@ -406,6 +407,7 @@ static inline void cpu_get_tb_cpu_state(CPULoongArchState *env, *pc = env->pc; *cs_base = 0; *flags = env->CSR_CRMD & (R_CSR_CRMD_PLV_MASK | R_CSR_CRMD_PG_MASK); + *flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, FPE) * HW_FLAGS_EUEN_FPE; } void loongarch_cpu_list(void); diff --git a/target/loongarch/insn_trans/trans_farith.c.inc b/target/loongarch/insn_trans/trans_farith.c.inc index 7bb3f41aee..e2dec75dfb 100644 --- a/target/loongarch/insn_trans/trans_farith.c.inc +++ b/target/loongarch/insn_trans/trans_farith.c.inc @@ -3,9 +3,22 @@ * Copyright (c) 2021 Loongson Technology Corporation Limited */ +#ifndef CONFIG_USER_ONLY +#define CHECK_FPE do { \ + if ((ctx->base.tb->flags & HW_FLAGS_EUEN_FPE) == 0) { \ + generate_exception(ctx, EXCCODE_FPD); \ + return false; \ + } \ +} while (0) +#else +#define CHECK_FPE +#endif + static bool gen_fff(DisasContext *ctx, arg_fff *a, void (*func)(TCGv, TCGv_env, TCGv, TCGv)) { + CHECK_FPE; + func(cpu_fpr[a->fd], cpu_env, cpu_fpr[a->fj], cpu_fpr[a->fk]); return true; } @@ -13,6 +26,8 @@ static bool gen_fff(DisasContext *ctx, arg_fff *a, static bool gen_ff(DisasContext *ctx, arg_ff *a, void (*func)(TCGv, TCGv_env, TCGv)) { + CHECK_FPE; + func(cpu_fpr[a->fd], cpu_env, cpu_fpr[a->fj]); return true; } @@ -22,6 +37,9 @@ static bool gen_muladd(DisasContext *ctx, arg_ffff *a, int flag) { TCGv_i32 tflag = tcg_constant_i32(flag); + + CHECK_FPE; + func(cpu_fpr[a->fd], cpu_env, cpu_fpr[a->fj], cpu_fpr[a->fk], cpu_fpr[a->fa], tflag); return true; @@ -29,18 +47,24 @@ static bool gen_muladd(DisasContext *ctx, arg_ffff *a, static bool trans_fcopysign_s(DisasContext *ctx, arg_fcopysign_s *a) { + CHECK_FPE; + tcg_gen_deposit_i64(cpu_fpr[a->fd], cpu_fpr[a->fk], cpu_fpr[a->fj], 0, 31); return true; } static bool trans_fcopysign_d(DisasContext *ctx, arg_fcopysign_d *a) { + CHECK_FPE; + tcg_gen_deposit_i64(cpu_fpr[a->fd], cpu_fpr[a->fk], cpu_fpr[a->fj], 0, 63); return true; } static bool trans_fabs_s(DisasContext *ctx, arg_fabs_s *a) { + CHECK_FPE; + tcg_gen_andi_i64(cpu_fpr[a->fd], cpu_fpr[a->fj], MAKE_64BIT_MASK(0, 31)); gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]); return true; @@ -48,12 +72,16 @@ static bool trans_fabs_s(DisasContext *ctx, arg_fabs_s *a) static bool trans_fabs_d(DisasContext *ctx, arg_fabs_d *a) { + CHECK_FPE; + tcg_gen_andi_i64(cpu_fpr[a->fd], cpu_fpr[a->fj], MAKE_64BIT_MASK(0, 63)); return true; } static bool trans_fneg_s(DisasContext *ctx, arg_fneg_s *a) { + CHECK_FPE; + tcg_gen_xori_i64(cpu_fpr[a->fd], cpu_fpr[a->fj], 0x80000000); gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]); return true; @@ -61,6 +89,8 @@ static bool trans_fneg_s(DisasContext *ctx, arg_fneg_s *a) static bool trans_fneg_d(DisasContext *ctx, arg_fneg_d *a) { + CHECK_FPE; + tcg_gen_xori_i64(cpu_fpr[a->fd], cpu_fpr[a->fj], 0x8000000000000000LL); return true; } diff --git a/target/loongarch/insn_trans/trans_fcmp.c.inc b/target/loongarch/insn_trans/trans_fcmp.c.inc index 93a6a2230f..2ccf646ccb 100644 --- a/target/loongarch/insn_trans/trans_fcmp.c.inc +++ b/target/loongarch/insn_trans/trans_fcmp.c.inc @@ -25,10 +25,13 @@ static uint32_t get_fcmp_flags(int cond) static bool trans_fcmp_cond_s(DisasContext *ctx, arg_fcmp_cond_s *a) { - TCGv var = tcg_temp_new(); + TCGv var; uint32_t flags; void (*fn)(TCGv, TCGv_env, TCGv, TCGv, TCGv_i32); + CHECK_FPE; + + var = tcg_temp_new(); fn = (a->fcond & 1 ? gen_helper_fcmp_s_s : gen_helper_fcmp_c_s); flags = get_fcmp_flags(a->fcond >> 1); @@ -41,9 +44,13 @@ static bool trans_fcmp_cond_s(DisasContext *ctx, arg_fcmp_cond_s *a) static bool trans_fcmp_cond_d(DisasContext *ctx, arg_fcmp_cond_d *a) { - TCGv var = tcg_temp_new(); + TCGv var; uint32_t flags; void (*fn)(TCGv, TCGv_env, TCGv, TCGv, TCGv_i32); + + CHECK_FPE; + + var = tcg_temp_new(); fn = (a->fcond & 1 ? gen_helper_fcmp_s_d : gen_helper_fcmp_c_d); flags = get_fcmp_flags(a->fcond >> 1); diff --git a/target/loongarch/insn_trans/trans_fmemory.c.inc b/target/loongarch/insn_trans/trans_fmemory.c.inc index 74ee98f63a..3025a1d3e9 100644 --- a/target/loongarch/insn_trans/trans_fmemory.c.inc +++ b/target/loongarch/insn_trans/trans_fmemory.c.inc @@ -15,6 +15,8 @@ static bool gen_fload_i(DisasContext *ctx, arg_fr_i *a, MemOp mop) TCGv addr = gpr_src(ctx, a->rj, EXT_NONE); TCGv temp = NULL; + CHECK_FPE; + if (a->imm) { temp = tcg_temp_new(); tcg_gen_addi_tl(temp, addr, a->imm); @@ -36,6 +38,8 @@ static bool gen_fstore_i(DisasContext *ctx, arg_fr_i *a, MemOp mop) TCGv addr = gpr_src(ctx, a->rj, EXT_NONE); TCGv temp = NULL; + CHECK_FPE; + if (a->imm) { temp = tcg_temp_new(); tcg_gen_addi_tl(temp, addr, a->imm); @@ -54,8 +58,11 @@ static bool gen_floadx(DisasContext *ctx, arg_frr *a, MemOp mop) { TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); - TCGv addr = tcg_temp_new(); + TCGv addr; + CHECK_FPE; + + addr = tcg_temp_new(); tcg_gen_add_tl(addr, src1, src2); tcg_gen_qemu_ld_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop); maybe_nanbox_load(cpu_fpr[a->fd], mop); @@ -68,8 +75,11 @@ static bool gen_fstorex(DisasContext *ctx, arg_frr *a, MemOp mop) { TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); - TCGv addr = tcg_temp_new(); + TCGv addr; + CHECK_FPE; + + addr = tcg_temp_new(); tcg_gen_add_tl(addr, src1, src2); tcg_gen_qemu_st_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop); tcg_temp_free(addr); @@ -81,8 +91,11 @@ static bool gen_fload_gt(DisasContext *ctx, arg_frr *a, MemOp mop) { TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); - TCGv addr = tcg_temp_new(); + TCGv addr; + CHECK_FPE; + + addr = tcg_temp_new(); gen_helper_asrtgt_d(cpu_env, src1, src2); tcg_gen_add_tl(addr, src1, src2); tcg_gen_qemu_ld_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop); @@ -96,8 +109,11 @@ static bool gen_fstore_gt(DisasContext *ctx, arg_frr *a, MemOp mop) { TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); - TCGv addr = tcg_temp_new(); + TCGv addr; + CHECK_FPE; + + addr = tcg_temp_new(); gen_helper_asrtgt_d(cpu_env, src1, src2); tcg_gen_add_tl(addr, src1, src2); tcg_gen_qemu_st_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop); @@ -110,8 +126,11 @@ static bool gen_fload_le(DisasContext *ctx, arg_frr *a, MemOp mop) { TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); - TCGv addr = tcg_temp_new(); + TCGv addr; + CHECK_FPE; + + addr = tcg_temp_new(); gen_helper_asrtle_d(cpu_env, src1, src2); tcg_gen_add_tl(addr, src1, src2); tcg_gen_qemu_ld_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop); @@ -125,8 +144,11 @@ static bool gen_fstore_le(DisasContext *ctx, arg_frr *a, MemOp mop) { TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); - TCGv addr = tcg_temp_new(); + TCGv addr; + CHECK_FPE; + + addr = tcg_temp_new(); gen_helper_asrtle_d(cpu_env, src1, src2); tcg_gen_add_tl(addr, src1, src2); tcg_gen_qemu_st_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop); diff --git a/target/loongarch/insn_trans/trans_fmov.c.inc b/target/loongarch/insn_trans/trans_fmov.c.inc index 5537e3dd35..8e5106db4e 100644 --- a/target/loongarch/insn_trans/trans_fmov.c.inc +++ b/target/loongarch/insn_trans/trans_fmov.c.inc @@ -10,8 +10,11 @@ static const uint32_t fcsr_mask[4] = { static bool trans_fsel(DisasContext *ctx, arg_fsel *a) { TCGv zero = tcg_constant_tl(0); - TCGv cond = tcg_temp_new(); + TCGv cond; + CHECK_FPE; + + cond = tcg_temp_new(); tcg_gen_ld8u_tl(cond, cpu_env, offsetof(CPULoongArchState, cf[a->ca])); tcg_gen_movcond_tl(TCG_COND_EQ, cpu_fpr[a->fd], cond, zero, cpu_fpr[a->fj], cpu_fpr[a->fk]); @@ -26,6 +29,8 @@ static bool gen_f2f(DisasContext *ctx, arg_ff *a, TCGv dest = cpu_fpr[a->fd]; TCGv src = cpu_fpr[a->fj]; + CHECK_FPE; + func(dest, src); if (nanbox) { gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]); @@ -39,6 +44,8 @@ static bool gen_r2f(DisasContext *ctx, arg_fr *a, { TCGv src = gpr_src(ctx, a->rj, EXT_NONE); + CHECK_FPE; + func(cpu_fpr[a->fd], src); return true; } @@ -48,6 +55,8 @@ static bool gen_f2r(DisasContext *ctx, arg_rf *a, { TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); + CHECK_FPE; + func(dest, cpu_fpr[a->fj]); gen_set_gpr(a->rd, dest, EXT_NONE); @@ -59,6 +68,8 @@ static bool trans_movgr2fcsr(DisasContext *ctx, arg_movgr2fcsr *a) uint32_t mask = fcsr_mask[a->fcsrd]; TCGv Rj = gpr_src(ctx, a->rj, EXT_NONE); + CHECK_FPE; + if (mask == UINT32_MAX) { tcg_gen_st32_i64(Rj, cpu_env, offsetof(CPULoongArchState, fcsr0)); } else { @@ -90,6 +101,8 @@ static bool trans_movfcsr2gr(DisasContext *ctx, arg_movfcsr2gr *a) { TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); + CHECK_FPE; + tcg_gen_ld32u_i64(dest, cpu_env, offsetof(CPULoongArchState, fcsr0)); tcg_gen_andi_i64(dest, dest, fcsr_mask[a->fcsrs]); gen_set_gpr(a->rd, dest, EXT_NONE); @@ -114,8 +127,11 @@ static void gen_movfrh2gr_s(TCGv dest, TCGv src) static bool trans_movfr2cf(DisasContext *ctx, arg_movfr2cf *a) { - TCGv t0 = tcg_temp_new(); + TCGv t0; + CHECK_FPE; + + t0 = tcg_temp_new(); tcg_gen_andi_tl(t0, cpu_fpr[a->fj], 0x1); tcg_gen_st8_tl(t0, cpu_env, offsetof(CPULoongArchState, cf[a->cd & 0x7])); tcg_temp_free(t0); @@ -125,6 +141,8 @@ static bool trans_movfr2cf(DisasContext *ctx, arg_movfr2cf *a) static bool trans_movcf2fr(DisasContext *ctx, arg_movcf2fr *a) { + CHECK_FPE; + tcg_gen_ld8u_tl(cpu_fpr[a->fd], cpu_env, offsetof(CPULoongArchState, cf[a->cj & 0x7])); return true; @@ -132,8 +150,11 @@ static bool trans_movcf2fr(DisasContext *ctx, arg_movcf2fr *a) static bool trans_movgr2cf(DisasContext *ctx, arg_movgr2cf *a) { - TCGv t0 = tcg_temp_new(); + TCGv t0; + CHECK_FPE; + + t0 = tcg_temp_new(); tcg_gen_andi_tl(t0, gpr_src(ctx, a->rj, EXT_NONE), 0x1); tcg_gen_st8_tl(t0, cpu_env, offsetof(CPULoongArchState, cf[a->cd & 0x7])); tcg_temp_free(t0); @@ -143,6 +164,8 @@ static bool trans_movgr2cf(DisasContext *ctx, arg_movgr2cf *a) static bool trans_movcf2gr(DisasContext *ctx, arg_movcf2gr *a) { + CHECK_FPE; + tcg_gen_ld8u_tl(gpr_dst(ctx, a->rd, EXT_NONE), cpu_env, offsetof(CPULoongArchState, cf[a->cj & 0x7])); return true; From 2b39abb2d6ed022c62eba2d124432d91c52a9d22 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 3 Nov 2022 13:10:40 +0000 Subject: [PATCH 558/705] hw/arm/boot: Set SME and SVE EL3 vector lengths when booting kernel When we direct boot a kernel on a CPU which emulates EL3, we need to set up the EL3 system registers as the Linux kernel documentation specifies: https://www.kernel.org/doc/Documentation/arm64/booting.rst For SVE and SME this includes: - ZCR_EL3.LEN must be initialised to the same value for all CPUs the kernel is executed on. - SMCR_EL3.LEN must be initialised to the same value for all CPUs the kernel will execute on. Although we are technically compliant with this, the "same value" we currently use by default is the reset value of 0. This will end up forcing the guest kernel's SVE and SME vector length to be only the smallest supported length. Initialize the vector length fields to their maximum possible value, which is 0xf. If the implementation doesn't actually support that vector length then the effective vector length will be constrained down to the maximum supported value at point of use. This allows the guest to use all the vector lengths the emulated CPU supports (by programming the _EL2 and _EL1 versions of these registers.) Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20221027140207.413084-2-peter.maydell@linaro.org --- hw/arm/boot.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/arm/boot.c b/hw/arm/boot.c index b106f31468..17d38260fa 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -764,10 +764,12 @@ static void do_cpu_reset(void *opaque) } if (cpu_isar_feature(aa64_sve, cpu)) { env->cp15.cptr_el[3] |= R_CPTR_EL3_EZ_MASK; + env->vfp.zcr_el[3] = 0xf; } if (cpu_isar_feature(aa64_sme, cpu)) { env->cp15.cptr_el[3] |= R_CPTR_EL3_ESM_MASK; env->cp15.scr_el3 |= SCR_ENTP2; + env->vfp.smcr_el[3] = 0xf; } /* AArch64 kernels never boot in secure mode */ assert(!info->secure_boot); From d7ef5e16a17c7dd068420c79fa9e893f15b4abaf Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 3 Nov 2022 13:10:40 +0000 Subject: [PATCH 559/705] hw/arm/boot: Set SCR_EL3.HXEn when booting kernel When we direct boot a kernel on a CPU which emulates EL3, we need to set up the EL3 system registers as the Linux kernel documentation specifies: https://www.kernel.org/doc/Documentation/arm64/booting.rst For CPUs with FEAT_HCX support this includes: - SCR_EL3.HXEn (bit 38) must be initialised to 0b1. but we forgot to do this when implementing FEAT_HCX, which would mean that a guest trying to access the HCRX_EL2 register would crash. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20221027140207.413084-3-peter.maydell@linaro.org --- hw/arm/boot.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hw/arm/boot.c b/hw/arm/boot.c index 17d38260fa..15c2bf1867 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -771,6 +771,9 @@ static void do_cpu_reset(void *opaque) env->cp15.scr_el3 |= SCR_ENTP2; env->vfp.smcr_el[3] = 0xf; } + if (cpu_isar_feature(aa64_hcx, cpu)) { + env->cp15.scr_el3 |= SCR_HXEN; + } /* AArch64 kernels never boot in secure mode */ assert(!info->secure_boot); /* This hook is only supported for AArch32 currently: From 4870f38b0babe48babdce90ac8bba11d29abaf0d Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 3 Nov 2022 13:10:41 +0000 Subject: [PATCH 560/705] target/arm: Make TLBIOS and TLBIRANGE ops trap on HCR_EL2.TTLB The HCR_EL2.TTLB bit is supposed to trap all EL1 execution of TLB maintenance instructions. However we have added new TLB insns for FEAT_TLBIOS and FEAT_TLBIRANGE, and forgot to set their accessfn to access_ttlb. Add the missing accessfns. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- target/arm/helper.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index b070a20f1a..efbdc657a2 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -6717,51 +6717,51 @@ static const ARMCPRegInfo pauth_reginfo[] = { static const ARMCPRegInfo tlbirange_reginfo[] = { { .name = "TLBI_RVAE1IS", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 1, - .access = PL1_W, .type = ARM_CP_NO_RAW, + .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, .writefn = tlbi_aa64_rvae1is_write }, { .name = "TLBI_RVAAE1IS", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 3, - .access = PL1_W, .type = ARM_CP_NO_RAW, + .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, .writefn = tlbi_aa64_rvae1is_write }, { .name = "TLBI_RVALE1IS", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 5, - .access = PL1_W, .type = ARM_CP_NO_RAW, + .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, .writefn = tlbi_aa64_rvae1is_write }, { .name = "TLBI_RVAALE1IS", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 7, - .access = PL1_W, .type = ARM_CP_NO_RAW, + .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, .writefn = tlbi_aa64_rvae1is_write }, { .name = "TLBI_RVAE1OS", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 1, - .access = PL1_W, .type = ARM_CP_NO_RAW, + .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, .writefn = tlbi_aa64_rvae1is_write }, { .name = "TLBI_RVAAE1OS", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 3, - .access = PL1_W, .type = ARM_CP_NO_RAW, + .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, .writefn = tlbi_aa64_rvae1is_write }, { .name = "TLBI_RVALE1OS", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 5, - .access = PL1_W, .type = ARM_CP_NO_RAW, + .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, .writefn = tlbi_aa64_rvae1is_write }, { .name = "TLBI_RVAALE1OS", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 7, - .access = PL1_W, .type = ARM_CP_NO_RAW, + .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, .writefn = tlbi_aa64_rvae1is_write }, { .name = "TLBI_RVAE1", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 1, - .access = PL1_W, .type = ARM_CP_NO_RAW, + .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, .writefn = tlbi_aa64_rvae1_write }, { .name = "TLBI_RVAAE1", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 3, - .access = PL1_W, .type = ARM_CP_NO_RAW, + .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, .writefn = tlbi_aa64_rvae1_write }, { .name = "TLBI_RVALE1", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 5, - .access = PL1_W, .type = ARM_CP_NO_RAW, + .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, .writefn = tlbi_aa64_rvae1_write }, { .name = "TLBI_RVAALE1", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 7, - .access = PL1_W, .type = ARM_CP_NO_RAW, + .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, .writefn = tlbi_aa64_rvae1_write }, { .name = "TLBI_RIPAS2E1IS", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 2, @@ -6832,27 +6832,27 @@ static const ARMCPRegInfo tlbirange_reginfo[] = { static const ARMCPRegInfo tlbios_reginfo[] = { { .name = "TLBI_VMALLE1OS", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 0, - .access = PL1_W, .type = ARM_CP_NO_RAW, + .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, .writefn = tlbi_aa64_vmalle1is_write }, { .name = "TLBI_VAE1OS", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 1, - .access = PL1_W, .type = ARM_CP_NO_RAW, + .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, .writefn = tlbi_aa64_vae1is_write }, { .name = "TLBI_ASIDE1OS", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 2, - .access = PL1_W, .type = ARM_CP_NO_RAW, + .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, .writefn = tlbi_aa64_vmalle1is_write }, { .name = "TLBI_VAAE1OS", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 3, - .access = PL1_W, .type = ARM_CP_NO_RAW, + .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, .writefn = tlbi_aa64_vae1is_write }, { .name = "TLBI_VALE1OS", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 5, - .access = PL1_W, .type = ARM_CP_NO_RAW, + .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, .writefn = tlbi_aa64_vae1is_write }, { .name = "TLBI_VAALE1OS", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 7, - .access = PL1_W, .type = ARM_CP_NO_RAW, + .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, .writefn = tlbi_aa64_vae1is_write }, { .name = "TLBI_ALLE2OS", .state = ARM_CP_STATE_AA64, .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 0, From 6f2d9d74416a71dedeb1a52480e8e809e2862702 Mon Sep 17 00:00:00 2001 From: Timofey Kutergin Date: Thu, 3 Nov 2022 13:10:41 +0000 Subject: [PATCH 561/705] target/arm: Fix Privileged Access Never (PAN) for aarch32 When we implemented the PAN support we theoretically wanted to support it for both AArch32 and AArch64, but in practice several bugs made it essentially unusable with an AArch32 guest. Fix all those problems: - Use CPSR.PAN to check for PAN state in aarch32 mode - throw permission fault during address translation when PAN is enabled and kernel tries to access user acessible page - ignore SCTLR_XP bit for armv7 and armv8 (conflicts with SCTLR_SPAN). Signed-off-by: Timofey Kutergin Reviewed-by: Peter Maydell Message-id: 20221027112619.2205229-1-tkutergin@gmail.com [PMM: tweak commit message] Signed-off-by: Peter Maydell --- target/arm/helper.c | 13 +++++++++++-- target/arm/ptw.c | 35 ++++++++++++++++++++++++++++++----- 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index efbdc657a2..077581187e 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -11003,6 +11003,15 @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate) } #endif +static bool arm_pan_enabled(CPUARMState *env) +{ + if (is_a64(env)) { + return env->pstate & PSTATE_PAN; + } else { + return env->uncached_cpsr & CPSR_PAN; + } +} + ARMMMUIdx arm_mmu_idx_el(CPUARMState *env, int el) { ARMMMUIdx idx; @@ -11023,7 +11032,7 @@ ARMMMUIdx arm_mmu_idx_el(CPUARMState *env, int el) } break; case 1: - if (env->pstate & PSTATE_PAN) { + if (arm_pan_enabled(env)) { idx = ARMMMUIdx_E10_1_PAN; } else { idx = ARMMMUIdx_E10_1; @@ -11032,7 +11041,7 @@ ARMMMUIdx arm_mmu_idx_el(CPUARMState *env, int el) case 2: /* Note that TGE does not apply at EL2. */ if (arm_hcr_el2_eff(env) & HCR_E2H) { - if (env->pstate & PSTATE_PAN) { + if (arm_pan_enabled(env)) { idx = ARMMMUIdx_E20_2_PAN; } else { idx = ARMMMUIdx_E20_2; diff --git a/target/arm/ptw.c b/target/arm/ptw.c index 58a7bbda50..e04dccff44 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -503,12 +503,11 @@ static bool get_level1_table_address(CPUARMState *env, ARMMMUIdx mmu_idx, * @mmu_idx: MMU index indicating required translation regime * @ap: The 3-bit access permissions (AP[2:0]) * @domain_prot: The 2-bit domain access permissions + * @is_user: TRUE if accessing from PL0 */ -static int ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx, - int ap, int domain_prot) +static int ap_to_rw_prot_is_user(CPUARMState *env, ARMMMUIdx mmu_idx, + int ap, int domain_prot, bool is_user) { - bool is_user = regime_is_user(env, mmu_idx); - if (domain_prot == 3) { return PAGE_READ | PAGE_WRITE; } @@ -552,6 +551,20 @@ static int ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx, } } +/* + * Translate section/page access permissions to page R/W protection flags + * @env: CPUARMState + * @mmu_idx: MMU index indicating required translation regime + * @ap: The 3-bit access permissions (AP[2:0]) + * @domain_prot: The 2-bit domain access permissions + */ +static int ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx, + int ap, int domain_prot) +{ + return ap_to_rw_prot_is_user(env, mmu_idx, ap, domain_prot, + regime_is_user(env, mmu_idx)); +} + /* * Translate section/page access permissions to page R/W protection flags. * @ap: The 2-bit simple AP (AP[2:1]) @@ -720,6 +733,7 @@ static bool get_phys_addr_v6(CPUARMState *env, S1Translate *ptw, hwaddr phys_addr; uint32_t dacr; bool ns; + int user_prot; /* Pagetable walk. */ /* Lookup l1 descriptor. */ @@ -831,8 +845,10 @@ static bool get_phys_addr_v6(CPUARMState *env, S1Translate *ptw, goto do_fault; } result->f.prot = simple_ap_to_rw_prot(env, mmu_idx, ap >> 1); + user_prot = simple_ap_to_rw_prot_is_user(ap >> 1, 1); } else { result->f.prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot); + user_prot = ap_to_rw_prot_is_user(env, mmu_idx, ap, domain_prot, 1); } if (result->f.prot && !xn) { result->f.prot |= PAGE_EXEC; @@ -842,6 +858,14 @@ static bool get_phys_addr_v6(CPUARMState *env, S1Translate *ptw, fi->type = ARMFault_Permission; goto do_fault; } + if (regime_is_pan(env, mmu_idx) && + !regime_is_user(env, mmu_idx) && + user_prot && + access_type != MMU_INST_FETCH) { + /* Privileged Access Never fault */ + fi->type = ARMFault_Permission; + goto do_fault; + } } if (ns) { /* The NS bit will (as required by the architecture) have no effect if @@ -2773,7 +2797,8 @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw, if (regime_using_lpae_format(env, mmu_idx)) { return get_phys_addr_lpae(env, ptw, address, access_type, false, result, fi); - } else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) { + } else if (arm_feature(env, ARM_FEATURE_V7) || + regime_sctlr(env, mmu_idx) & SCTLR_XP) { return get_phys_addr_v6(env, ptw, address, access_type, result, fi); } else { return get_phys_addr_v5(env, ptw, address, access_type, result, fi); From 302ad91209c5b01c091b8d2b7c2c8995837023df Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 3 Nov 2022 13:10:41 +0000 Subject: [PATCH 562/705] target/arm: Copy the entire vector in DO_ZIP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With odd_ofs set, we weren't copying enough data. Fixes: 09eb6d7025d1 ("target/arm: Move sve zip high_ofs into simd_data") Reported-by: Idan Horowitz Signed-off-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Message-id: 20221031054144.3574-1-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/sve_helper.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c index 3d0d2987cd..1afeadf9c8 100644 --- a/target/arm/sve_helper.c +++ b/target/arm/sve_helper.c @@ -3366,10 +3366,10 @@ void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \ /* We produce output faster than we consume input. \ Therefore we must be mindful of possible overlap. */ \ if (unlikely((vn - vd) < (uintptr_t)oprsz)) { \ - vn = memcpy(&tmp_n, vn, oprsz_2); \ + vn = memcpy(&tmp_n, vn, oprsz); \ } \ if (unlikely((vm - vd) < (uintptr_t)oprsz)) { \ - vm = memcpy(&tmp_m, vm, oprsz_2); \ + vm = memcpy(&tmp_m, vm, oprsz); \ } \ for (i = 0; i < oprsz_2; i += sizeof(TYPE)) { \ *(TYPE *)(vd + H(2 * i + 0)) = *(TYPE *)(vn + odd_ofs + H(i)); \ From 638d5dbd78ea81c943959e2f2c65c109e5278a78 Mon Sep 17 00:00:00 2001 From: Ake Koomsin Date: Tue, 1 Nov 2022 15:42:53 +0900 Subject: [PATCH 563/705] target/arm: Honor HCR_E2H and HCR_TGE in ats_write64() We need to check HCR_E2H and HCR_TGE to select the right MMU index for the correct translation regime. To check for EL2&0 translation regime: - For S1E0*, S1E1* and S12E* ops, check both HCR_E2H and HCR_TGE - For S1E2* ops, check only HCR_E2H Signed-off-by: Ake Koomsin Message-id: 20221101064250.12444-1-ake@igel.co.jp Reviewed-by: Richard Henderson Signed-off-by: Peter Maydell --- target/arm/helper.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index 077581187e..d8c8223ec3 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -3501,19 +3501,22 @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri, MMUAccessType access_type = ri->opc2 & 1 ? MMU_DATA_STORE : MMU_DATA_LOAD; ARMMMUIdx mmu_idx; int secure = arm_is_secure_below_el3(env); + uint64_t hcr_el2 = arm_hcr_el2_eff(env); + bool regime_e20 = (hcr_el2 & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE); switch (ri->opc2 & 6) { case 0: switch (ri->opc1) { case 0: /* AT S1E1R, AT S1E1W, AT S1E1RP, AT S1E1WP */ if (ri->crm == 9 && (env->pstate & PSTATE_PAN)) { - mmu_idx = ARMMMUIdx_Stage1_E1_PAN; + mmu_idx = regime_e20 ? + ARMMMUIdx_E20_2_PAN : ARMMMUIdx_Stage1_E1_PAN; } else { - mmu_idx = ARMMMUIdx_Stage1_E1; + mmu_idx = regime_e20 ? ARMMMUIdx_E20_2 : ARMMMUIdx_Stage1_E1; } break; case 4: /* AT S1E2R, AT S1E2W */ - mmu_idx = ARMMMUIdx_E2; + mmu_idx = hcr_el2 & HCR_E2H ? ARMMMUIdx_E20_2 : ARMMMUIdx_E2; break; case 6: /* AT S1E3R, AT S1E3W */ mmu_idx = ARMMMUIdx_E3; @@ -3524,13 +3527,13 @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri, } break; case 2: /* AT S1E0R, AT S1E0W */ - mmu_idx = ARMMMUIdx_Stage1_E0; + mmu_idx = regime_e20 ? ARMMMUIdx_E20_0 : ARMMMUIdx_Stage1_E0; break; case 4: /* AT S12E1R, AT S12E1W */ - mmu_idx = ARMMMUIdx_E10_1; + mmu_idx = regime_e20 ? ARMMMUIdx_E20_2 : ARMMMUIdx_E10_1; break; case 6: /* AT S12E0R, AT S12E0W */ - mmu_idx = ARMMMUIdx_E10_0; + mmu_idx = regime_e20 ? ARMMMUIdx_E20_0 : ARMMMUIdx_E10_0; break; default: g_assert_not_reached(); From cead7fa4c06087c86c67c5ce815cc1ff0bfeac3a Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 2 Nov 2022 16:47:06 +1100 Subject: [PATCH 564/705] target/arm: Two fixes for secure ptw MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reversed the sense of non-secure in get_phys_addr_lpae, and failed to initialize attrs.secure for ARMMMUIdx_Phys_S. Fixes: 48da29e4 ("target/arm: Add ptw_idx to S1Translate") Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1293 Signed-off-by: Richard Henderson Tested-by: Philippe Mathieu-Daudé Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- target/arm/ptw.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/target/arm/ptw.c b/target/arm/ptw.c index e04dccff44..3745ac9723 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -1381,7 +1381,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw, descaddr |= (address >> (stride * (4 - level))) & indexmask; descaddr &= ~7ULL; nstable = extract32(tableattrs, 4, 1); - if (!nstable) { + if (nstable) { /* * Stage2_S -> Stage2 or Phys_S -> Phys_NS * Assert that the non-secure idx are even, and relative order. @@ -2695,6 +2695,13 @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw, bool is_secure = ptw->in_secure; ARMMMUIdx s1_mmu_idx; + /* + * The page table entries may downgrade secure to non-secure, but + * cannot upgrade an non-secure translation regime's attributes + * to secure. + */ + result->f.attrs.secure = is_secure; + switch (mmu_idx) { case ARMMMUIdx_Phys_S: case ARMMMUIdx_Phys_NS: @@ -2736,12 +2743,6 @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw, break; } - /* - * The page table entries may downgrade secure to non-secure, but - * cannot upgrade an non-secure translation regime's attributes - * to secure. - */ - result->f.attrs.secure = is_secure; result->f.attrs.user = regime_is_user(env, mmu_idx); /* From 58379af7102616531bf8ca499121e33b034fe9e4 Mon Sep 17 00:00:00 2001 From: Han Han Date: Tue, 1 Nov 2022 09:46:47 +0800 Subject: [PATCH 565/705] qapi: virtio: Fix the introduced version The items of qapi/virtio.json are introduced at a5ebce38576. They will be in the version 7.2 not 7.1. Signed-off-by: Han Han Reviewed-by: Laurent Vivier Message-Id: <20221101014647.3000801-1-hhan@redhat.com> Signed-off-by: Laurent Vivier --- qapi/virtio.json | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/qapi/virtio.json b/qapi/virtio.json index e47a8fb2e0..872c7e3623 100644 --- a/qapi/virtio.json +++ b/qapi/virtio.json @@ -15,7 +15,7 @@ # # @name: Name of the VirtIODevice # -# Since: 7.1 +# Since: 7.2 # ## { 'struct': 'VirtioInfo', @@ -32,7 +32,7 @@ # # Returns: List of gathered VirtIODevices # -# Since: 7.1 +# Since: 7.2 # # Example: # @@ -97,7 +97,7 @@ # # @log-size: vhost_dev log_size # -# Since: 7.1 +# Since: 7.2 # ## @@ -167,7 +167,7 @@ # Present if the given VirtIODevice has an active vhost # device. # -# Since: 7.1 +# Since: 7.2 # ## @@ -206,7 +206,7 @@ # # Returns: VirtioStatus of the virtio device # -# Since: 7.1 +# Since: 7.2 # # Examples: # @@ -452,7 +452,7 @@ # # @unknown-statuses: Virtio device statuses bitmap that have not been decoded # -# Since: 7.1 +# Since: 7.2 ## { 'struct': 'VirtioDeviceStatus', @@ -471,7 +471,7 @@ # @unknown-protocols: Vhost user device protocol features bitmap that # have not been decoded # -# Since: 7.1 +# Since: 7.2 ## { 'struct': 'VhostDeviceProtocols', @@ -492,7 +492,7 @@ # @unknown-dev-features: Virtio device features bitmap that have not # been decoded # -# Since: 7.1 +# Since: 7.2 ## { 'struct': 'VirtioDeviceFeatures', @@ -535,7 +535,7 @@ # # @signalled-used-valid: VirtQueue signalled_used_valid flag # -# Since: 7.1 +# Since: 7.2 # ## @@ -576,7 +576,7 @@ # shadow_avail_idx will not be displayed in the case where # the selected VirtIODevice has a running vhost device. # -# Since: 7.1 +# Since: 7.2 # # Examples: # @@ -666,7 +666,7 @@ # # @used-size: vhost_virtqueue used_size # -# Since: 7.1 +# Since: 7.2 # ## @@ -699,7 +699,7 @@ # # Returns: VirtVhostQueueStatus of the vhost_virtqueue # -# Since: 7.1 +# Since: 7.2 # # Examples: # @@ -767,7 +767,7 @@ # # @flags: List of descriptor flags # -# Since: 7.1 +# Since: 7.2 # ## @@ -787,7 +787,7 @@ # # @ring: VRingAvail ring[] entry at provided index # -# Since: 7.1 +# Since: 7.2 # ## @@ -805,7 +805,7 @@ # # @idx: VRingUsed index # -# Since: 7.1 +# Since: 7.2 # ## @@ -829,7 +829,7 @@ # # @used: VRingUsed info # -# Since: 7.1 +# Since: 7.2 # ## @@ -857,7 +857,7 @@ # # Returns: VirtioQueueElement information # -# Since: 7.1 +# Since: 7.2 # # Examples: # From 1e458f11273c315ee2045f6e632b8dfb5f2b1544 Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Sun, 30 Oct 2022 11:59:44 +0100 Subject: [PATCH 566/705] Fix some typos in documentation and comments Most of them were found and fixed using codespell. Signed-off-by: Stefan Weil Reviewed-by: Peter Maydell Reviewed-by: Thomas Huth Reviewed-by: Stefan Hajnoczi Message-Id: <20221030105944.311940-1-sw@weilnetz.de> Signed-off-by: Laurent Vivier --- docs/devel/testing.rst | 2 +- docs/system/arm/cpu-features.rst | 2 +- docs/system/loongarch/loongson3.rst | 2 +- docs/tools/virtiofsd.rst | 2 +- include/exec/memory.h | 2 +- qapi/qom.json | 2 +- qemu-options.hx | 10 +++++----- qga/qapi-schema.json | 2 +- tests/qtest/libqtest.h | 2 +- 9 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/devel/testing.rst b/docs/devel/testing.rst index fbb98faabe..e10c47b5a7 100644 --- a/docs/devel/testing.rst +++ b/docs/devel/testing.rst @@ -99,7 +99,7 @@ successfully on various hosts. The following list shows some best practices: * If your test cases uses the blkdebug feature, use relative path to pass the config and image file paths in the command line as Windows absolute path contains the delimiter ":" which will confuse the blkdebug parser. -* Use double quotes in your extra QEMU commmand line in your test cases +* Use double quotes in your extra QEMU command line in your test cases instead of single quotes, as Windows does not drop single quotes when passing the command line to QEMU. * Windows opens a file in text mode by default, while a POSIX compliant diff --git a/docs/system/arm/cpu-features.rst b/docs/system/arm/cpu-features.rst index c2c01ec7d2..00c444042f 100644 --- a/docs/system/arm/cpu-features.rst +++ b/docs/system/arm/cpu-features.rst @@ -433,7 +433,7 @@ additional constraints on the set of vector lengths supported by SME. SME User-mode Default Vector Length Property -------------------------------------------- -For qemu-aarch64, the cpu propery ``sme-default-vector-length=N`` is +For qemu-aarch64, the cpu property ``sme-default-vector-length=N`` is defined to mirror the Linux kernel parameter file ``/proc/sys/abi/sme_default_vector_length``. The default length, ``N``, is in units of bytes and must be between 16 and 8192. diff --git a/docs/system/loongarch/loongson3.rst b/docs/system/loongarch/loongson3.rst index 1bdab44e27..489ea20f8f 100644 --- a/docs/system/loongarch/loongson3.rst +++ b/docs/system/loongarch/loongson3.rst @@ -41,7 +41,7 @@ can be accessed by following steps. $ qemu-system-loongarch64 -machine virt -m 4G -cpu la464-loongarch-cpu \ -smp 1 -bios QEMU_EFI.fd -kernel vmlinuz.efi -initrd initrd.img \ - -append "root=/dev/ram rdinit=/sbin/init consol e=ttyS0,115200" \ + -append "root=/dev/ram rdinit=/sbin/init console=ttyS0,115200" \ --nographic Note: The running speed may be a little slow, as the performance of our diff --git a/docs/tools/virtiofsd.rst b/docs/tools/virtiofsd.rst index 5f5ac9dd56..995a754a7b 100644 --- a/docs/tools/virtiofsd.rst +++ b/docs/tools/virtiofsd.rst @@ -232,7 +232,7 @@ e.g.: ``:ok:server::security.:`` - will pass 'securty.' xattr's in listxattr from the server + will pass 'security.' xattr's in listxattr from the server and ignore following rules. ``:ok:all:::`` diff --git a/include/exec/memory.h b/include/exec/memory.h index bfb1de8eea..a751c111bd 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -1970,7 +1970,7 @@ void memory_region_clear_dirty_bitmap(MemoryRegion *mr, hwaddr start, * querying the same page multiple times, which is especially useful for * display updates where the scanlines often are not page aligned. * - * The dirty bitmap region which gets copyed into the snapshot (and + * The dirty bitmap region which gets copied into the snapshot (and * cleared afterwards) can be larger than requested. The boundaries * are rounded up/down so complete bitmap longs (covering 64 pages on * 64bit hosts) can be copied over into the bitmap snapshot. Which diff --git a/qapi/qom.json b/qapi/qom.json index 87fcad2423..4db956f07e 100644 --- a/qapi/qom.json +++ b/qapi/qom.json @@ -589,7 +589,7 @@ # # @size: size of the memory region in bytes # -# @x-use-canonical-path-for-ramblock-id: if true, the canoncial path is used +# @x-use-canonical-path-for-ramblock-id: if true, the canonical path is used # for ramblock-id. Disable this for 4.0 # machine types or older to allow # migration with newer QEMU versions. diff --git a/qemu-options.hx b/qemu-options.hx index 911d82afa5..dbdf9c301b 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1051,7 +1051,7 @@ SRST details on the external interface. ``-device isa-ipmi-kcs,bmc=id[,ioport=val][,irq=val]`` - Add a KCS IPMI interafce on the ISA bus. This also adds a + Add a KCS IPMI interface on the ISA bus. This also adds a corresponding ACPI and SMBIOS entries, if appropriate. ``bmc=id`` @@ -1071,7 +1071,7 @@ SRST is 0xe4 and the default interrupt is 5. ``-device pci-ipmi-kcs,bmc=id`` - Add a KCS IPMI interafce on the PCI bus. + Add a KCS IPMI interface on the PCI bus. ``bmc=id`` The BMC to connect to, one of ipmi-bmc-sim or ipmi-bmc-extern above. @@ -5283,8 +5283,8 @@ SRST read the colo-compare git log. ``-object cryptodev-backend-builtin,id=id[,queues=queues]`` - Creates a cryptodev backend which executes crypto opreation from - the QEMU cipher APIS. The id parameter is a unique ID that will + Creates a cryptodev backend which executes crypto operations from + the QEMU cipher APIs. The id parameter is a unique ID that will be used to reference this cryptodev backend from the ``virtio-crypto`` device. The queues parameter is optional, which specify the queue number of cryptodev backend, the default @@ -5551,7 +5551,7 @@ SRST file=/etc/qemu/vnc.allow Finally the ``/etc/qemu/vnc.allow`` file would contain the list - of x509 distingished names that are permitted access + of x509 distinguished names that are permitted access :: diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json index 026a56f76c..796434ed34 100644 --- a/qga/qapi-schema.json +++ b/qga/qapi-schema.json @@ -392,7 +392,7 @@ ## # @guest-file-flush: # -# Write file changes bufferred in userspace to disk/kernel buffers +# Write file changes buffered in userspace to disk/kernel buffers # # @handle: filehandle returned by guest-file-open # diff --git a/tests/qtest/libqtest.h b/tests/qtest/libqtest.h index 91a5f7edd9..fcf1c3c3b3 100644 --- a/tests/qtest/libqtest.h +++ b/tests/qtest/libqtest.h @@ -736,7 +736,7 @@ bool qtest_has_device(const char *device); * qtest_qmp_device_add_qdict: * @qts: QTestState instance to operate on * @drv: Name of the device that should be added - * @arguments: QDict with properties for the device to intialize + * @arguments: QDict with properties for the device to initialize * * Generic hot-plugging test via the device_add QMP command with properties * supplied in form of QDict. Use NULL for empty properties list. From ba24456b93a205b728475d5f0880f3ec495e383a Mon Sep 17 00:00:00 2001 From: Chuck Zmudzinski Date: Mon, 31 Oct 2022 17:35:52 -0400 Subject: [PATCH 567/705] xen/pt: fix syntax error that causes FTBFS in some configurations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When Qemu is built with --enable-xen and --disable-xen-pci-passthrough and the target os is linux, the build fails with: meson.build:3477:2: ERROR: File xen_pt_stub.c does not exist. Fixes: 582ea95f5f93 ("meson: convert hw/xen") Signed-off-by: Chuck Zmudzinski Reviewed-by: Philippe Mathieu-Daudé Message-Id: <5f1342a13c09af77b1a7b0aeaba5955bcea89731.1667242033.git.brchuckz@aol.com> Signed-off-by: Laurent Vivier --- hw/xen/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/xen/meson.build b/hw/xen/meson.build index 08dc1f6857..ae0ace3046 100644 --- a/hw/xen/meson.build +++ b/hw/xen/meson.build @@ -18,7 +18,7 @@ if have_xen_pci_passthrough 'xen_pt_msi.c', )) else - xen_specific_ss.add('xen_pt_stub.c') + xen_specific_ss.add(files('xen_pt_stub.c')) endif specific_ss.add_all(when: ['CONFIG_XEN', xen], if_true: xen_specific_ss) From 0f208a9747a700a4b63afc87d58da0c87f37e214 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Wed, 26 Oct 2022 01:50:04 +0200 Subject: [PATCH 568/705] target/m68k: Rename qregs.def -> qregs.h.inc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We use the .h.inc extension to include C headers. To be consistent with the rest of the codebase, rename the C headers using the .def extension. IDE/tools using our .editorconfig / .gitattributes will leverage this consistency. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Laurent Vivier Reviewed-by: Alex Bennée Message-Id: <20221025235006.7215-2-philmd@linaro.org> Signed-off-by: Laurent Vivier --- target/m68k/{qregs.def => qregs.h.inc} | 0 target/m68k/translate.c | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename target/m68k/{qregs.def => qregs.h.inc} (100%) diff --git a/target/m68k/qregs.def b/target/m68k/qregs.h.inc similarity index 100% rename from target/m68k/qregs.def rename to target/m68k/qregs.h.inc diff --git a/target/m68k/translate.c b/target/m68k/translate.c index 5cbde4be34..18418312b1 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c @@ -39,7 +39,7 @@ #define DEFO32(name, offset) static TCGv QREG_##name; #define DEFO64(name, offset) static TCGv_i64 QREG_##name; -#include "qregs.def" +#include "qregs.h.inc" #undef DEFO32 #undef DEFO64 @@ -75,7 +75,7 @@ void m68k_tcg_init(void) #define DEFO64(name, offset) \ QREG_##name = tcg_global_mem_new_i64(cpu_env, \ offsetof(CPUM68KState, offset), #name); -#include "qregs.def" +#include "qregs.h.inc" #undef DEFO32 #undef DEFO64 From 9cef8d99266cca7189237287dcd18b0a91c9aae7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Wed, 26 Oct 2022 01:50:05 +0200 Subject: [PATCH 569/705] target/s390x: Rename insn-data/format.def -> insn-data/format.h.inc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We use the .h.inc extension to include C headers. To be consistent with the rest of the codebase, rename the C headers using the .def extension. IDE/tools using our .editorconfig / .gitattributes will leverage this consistency. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Thomas Huth Reviewed-by: Alex Bennée Message-Id: <20221025235006.7215-3-philmd@linaro.org> Signed-off-by: Laurent Vivier --- target/s390x/tcg/{insn-data.def => insn-data.h.inc} | 2 +- .../s390x/tcg/{insn-format.def => insn-format.h.inc} | 0 target/s390x/tcg/translate.c | 10 +++++----- 3 files changed, 6 insertions(+), 6 deletions(-) rename target/s390x/tcg/{insn-data.def => insn-data.h.inc} (99%) rename target/s390x/tcg/{insn-format.def => insn-format.h.inc} (100%) diff --git a/target/s390x/tcg/insn-data.def b/target/s390x/tcg/insn-data.h.inc similarity index 99% rename from target/s390x/tcg/insn-data.def rename to target/s390x/tcg/insn-data.h.inc index 6382ceabfc..7e952bdfc8 100644 --- a/target/s390x/tcg/insn-data.def +++ b/target/s390x/tcg/insn-data.h.inc @@ -8,7 +8,7 @@ * * OPC = (op << 8) | op2 where op is the major, op2 the minor opcode * NAME = name of the opcode, used internally - * FMT = format of the opcode (defined in insn-format.def) + * FMT = format of the opcode (defined in insn-format.h.inc) * FAC = facility the opcode is available in (defined in DisasFacility) * I1 = func in1_xx fills o->in1 * I2 = func in2_xx fills o->in2 diff --git a/target/s390x/tcg/insn-format.def b/target/s390x/tcg/insn-format.h.inc similarity index 100% rename from target/s390x/tcg/insn-format.def rename to target/s390x/tcg/insn-format.h.inc diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c index 03efccdf9f..2fbdab7252 100644 --- a/target/s390x/tcg/translate.c +++ b/target/s390x/tcg/translate.c @@ -1011,7 +1011,7 @@ static void free_compare(DisasCompare *c) #define F6(N, X1, X2, X3, X4, X5, X6) F0(N) typedef enum { -#include "insn-format.def" +#include "insn-format.h.inc" } DisasFormat; #undef F0 @@ -1076,7 +1076,7 @@ typedef struct DisasFormatInfo { #define F6(N, X1, X2, X3, X4, X5, X6) { { X1, X2, X3, X4, X5, X6 } }, static const DisasFormatInfo format_info[] = { -#include "insn-format.def" +#include "insn-format.h.inc" }; #undef F0 @@ -6143,7 +6143,7 @@ static void in2_insn(DisasContext *s, DisasOps *o) #define E(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D, FL) insn_ ## NM, enum DisasInsnEnum { -#include "insn-data.def" +#include "insn-data.h.inc" }; #undef E @@ -6223,7 +6223,7 @@ enum DisasInsnEnum { #define FAC_MIE3 S390_FEAT_MISC_INSTRUCTION_EXT3 /* miscellaneous-instruction-extensions facility 3 */ static const DisasInsn insn_info[] = { -#include "insn-data.def" +#include "insn-data.h.inc" }; #undef E @@ -6233,7 +6233,7 @@ static const DisasInsn insn_info[] = { static const DisasInsn *lookup_opc(uint16_t opc) { switch (opc) { -#include "insn-data.def" +#include "insn-data.h.inc" default: return NULL; } From 5d756c82c9eb288f9e19bbc711c99e6b6bda9f0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Wed, 26 Oct 2022 01:50:06 +0200 Subject: [PATCH 570/705] target/tricore: Rename csfr.def -> csfr.h.inc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We use the .h.inc extension to include C headers. To be consistent with the rest of the codebase, rename the C headers using the .def extension. IDE/tools using our .editorconfig / .gitattributes will leverage this consistency. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Bastian Koppelmann Reviewed-by: Alex Bennée Message-Id: <20221025235006.7215-4-philmd@linaro.org> Signed-off-by: Laurent Vivier --- target/tricore/{csfr.def => csfr.h.inc} | 0 target/tricore/translate.c | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename target/tricore/{csfr.def => csfr.h.inc} (100%) diff --git a/target/tricore/csfr.def b/target/tricore/csfr.h.inc similarity index 100% rename from target/tricore/csfr.def rename to target/tricore/csfr.h.inc diff --git a/target/tricore/translate.c b/target/tricore/translate.c index c5b7bfbf20..df9e46c649 100644 --- a/target/tricore/translate.c +++ b/target/tricore/translate.c @@ -388,7 +388,7 @@ static inline void gen_mfcr(DisasContext *ctx, TCGv ret, int32_t offset) gen_helper_psw_read(ret, cpu_env); } else { switch (offset) { -#include "csfr.def" +#include "csfr.h.inc" } } } @@ -418,7 +418,7 @@ static inline void gen_mtcr(DisasContext *ctx, TCGv r1, gen_helper_psw_write(cpu_env, r1); } else { switch (offset) { -#include "csfr.def" +#include "csfr.h.inc" } } } else { From 5a820d5d07cb101752c731799a326648a5aa185a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Thu, 3 Nov 2022 10:23:29 +0000 Subject: [PATCH 571/705] tests/unit: simpler variable sequence for test-io-channel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This avoids some compilers complaining about a potentially un-initialised [src|dst]argv. In retrospect using GString was overkill for what we are constructing. Signed-off-by: Alex Bennée Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Laurent Vivier Message-Id: <20221103102329.2581508-1-alex.bennee@linaro.org> Signed-off-by: Laurent Vivier --- tests/unit/test-io-channel-command.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/tests/unit/test-io-channel-command.c b/tests/unit/test-io-channel-command.c index 43e29c8cfb..19f72eab96 100644 --- a/tests/unit/test-io-channel-command.c +++ b/tests/unit/test-io-channel-command.c @@ -33,19 +33,13 @@ static void test_io_channel_command_fifo(bool async) { g_autofree gchar *tmpdir = g_dir_make_tmp("qemu-test-io-channel.XXXXXX", NULL); g_autofree gchar *fifo = g_strdup_printf("%s/%s", tmpdir, TEST_FIFO); - g_autoptr(GString) srcargs = g_string_new(socat); - g_autoptr(GString) dstargs = g_string_new(socat); - g_auto(GStrv) srcargv; - g_auto(GStrv) dstargv; + g_autofree gchar *srcargs = g_strdup_printf("%s - PIPE:%s,wronly", socat, fifo); + g_autofree gchar *dstargs = g_strdup_printf("%s PIPE:%s,rdonly -", socat, fifo); + g_auto(GStrv) srcargv = g_strsplit(srcargs, " ", -1); + g_auto(GStrv) dstargv = g_strsplit(dstargs, " ", -1); QIOChannel *src, *dst; QIOChannelTest *test; - g_string_append_printf(srcargs, " - PIPE:%s,wronly", fifo); - g_string_append_printf(dstargs, " PIPE:%s,rdonly -", fifo); - - srcargv = g_strsplit(srcargs->str, " ", -1); - dstargv = g_strsplit(dstargs->str, " ", -1); - src = QIO_CHANNEL(qio_channel_command_new_spawn((const char **) srcargv, O_WRONLY, &error_abort)); From 4f76b3d9bb1a5b16166217b46a5f50b3a7c2f5a8 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 19 Oct 2022 18:20:13 +0800 Subject: [PATCH 572/705] util/main-loop: Fix maximum number of wait objects for win32 The maximum number of wait objects for win32 should be MAXIMUM_WAIT_OBJECTS, not MAXIMUM_WAIT_OBJECTS + 1. Signed-off-by: Bin Meng Message-Id: <20221019102015.2441622-1-bmeng.cn@gmail.com> Signed-off-by: Paolo Bonzini --- util/main-loop.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/util/main-loop.c b/util/main-loop.c index f00a25451b..de38876064 100644 --- a/util/main-loop.c +++ b/util/main-loop.c @@ -363,10 +363,10 @@ void qemu_del_polling_cb(PollingFunc *func, void *opaque) /* Wait objects support */ typedef struct WaitObjects { int num; - int revents[MAXIMUM_WAIT_OBJECTS + 1]; - HANDLE events[MAXIMUM_WAIT_OBJECTS + 1]; - WaitObjectFunc *func[MAXIMUM_WAIT_OBJECTS + 1]; - void *opaque[MAXIMUM_WAIT_OBJECTS + 1]; + int revents[MAXIMUM_WAIT_OBJECTS]; + HANDLE events[MAXIMUM_WAIT_OBJECTS]; + WaitObjectFunc *func[MAXIMUM_WAIT_OBJECTS]; + void *opaque[MAXIMUM_WAIT_OBJECTS]; } WaitObjects; static WaitObjects wait_objects = {0}; @@ -395,7 +395,7 @@ void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque) if (w->events[i] == handle) { found = 1; } - if (found) { + if (found && i < (MAXIMUM_WAIT_OBJECTS - 1)) { w->events[i] = w->events[i + 1]; w->func[i] = w->func[i + 1]; w->opaque[i] = w->opaque[i + 1]; From d393b0a176068c41cc08f41c245721ed9ca91d30 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 19 Oct 2022 18:20:14 +0800 Subject: [PATCH 573/705] util/main-loop: Avoid adding the same HANDLE twice Fix the logic in qemu_add_wait_object() to avoid adding the same HANDLE twice, as the behavior is undefined when passing an array that contains same HANDLEs to WaitForMultipleObjects() API. Signed-off-by: Bin Meng Message-Id: <20221019102015.2441622-2-bmeng.cn@gmail.com> Signed-off-by: Paolo Bonzini --- include/qemu/main-loop.h | 2 ++ util/main-loop.c | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h index aac707d073..3c9a9a982d 100644 --- a/include/qemu/main-loop.h +++ b/include/qemu/main-loop.h @@ -157,6 +157,8 @@ typedef void WaitObjectFunc(void *opaque); * in the main loop's calls to WaitForMultipleObjects. When the handle * is in a signaled state, QEMU will call @func. * + * If the same HANDLE is added twice, this function returns -1. + * * @handle: The Windows handle to be observed. * @func: A function to be called when @handle is in a signaled state. * @opaque: A pointer-size value that is passed to @func. diff --git a/util/main-loop.c b/util/main-loop.c index de38876064..10fa74c6e3 100644 --- a/util/main-loop.c +++ b/util/main-loop.c @@ -373,10 +373,20 @@ static WaitObjects wait_objects = {0}; int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque) { + int i; WaitObjects *w = &wait_objects; + if (w->num >= MAXIMUM_WAIT_OBJECTS) { return -1; } + + for (i = 0; i < w->num; i++) { + /* check if the same handle is added twice */ + if (w->events[i] == handle) { + return -1; + } + } + w->events[w->num] = handle; w->func[w->num] = func; w->opaque[w->num] = opaque; From e0d034bb243cf0bac2416e00af810c4ca7821762 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 19 Oct 2022 18:20:15 +0800 Subject: [PATCH 574/705] util/aio-win32: Correct the event array size in aio_poll() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit WaitForMultipleObjects() can only wait for MAXIMUM_WAIT_OBJECTS object handles. Correct the event array size in aio_poll() and add a assert() to ensure it does not cause out of bound access. Signed-off-by: Bin Meng Reviewed-by: Stefan Weil Reviewed-by: Marc-André Lureau Reviewed-by: Daniel P. Berrangé Message-Id: <20221019102015.2441622-3-bmeng.cn@gmail.com> Signed-off-by: Paolo Bonzini --- util/aio-win32.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/util/aio-win32.c b/util/aio-win32.c index 44003d645e..80cfe012ad 100644 --- a/util/aio-win32.c +++ b/util/aio-win32.c @@ -326,9 +326,9 @@ void aio_dispatch(AioContext *ctx) bool aio_poll(AioContext *ctx, bool blocking) { AioHandler *node; - HANDLE events[MAXIMUM_WAIT_OBJECTS + 1]; + HANDLE events[MAXIMUM_WAIT_OBJECTS]; bool progress, have_select_revents, first; - int count; + unsigned count; int timeout; /* @@ -369,6 +369,7 @@ bool aio_poll(AioContext *ctx, bool blocking) QLIST_FOREACH_RCU(node, &ctx->aio_handlers, node) { if (!node->deleted && node->io_notify && aio_node_check(ctx, node->is_external)) { + assert(count < MAXIMUM_WAIT_OBJECTS); events[count++] = event_notifier_get_handle(node->e); } } From 75ac231c67cdb13f0609943fab5499963858b587 Mon Sep 17 00:00:00 2001 From: TaiseiIto Date: Tue, 13 Sep 2022 12:06:00 +0000 Subject: [PATCH 575/705] gdb-xml: Fix size of EFER register on i386 architecture when debugged by GDB Before this commit, there were contradictory descriptions about size of EFER register. Line 113 says the size is 8 bytes. Line 129 says the size is 4 bytes. As a result, when GDB is debugging an OS running on QEMU, the GDB cannot read 'g' packets correctly. This 'g' packet transmits values of each registers of machine emulated by QEMU to GDB. QEMU, the packet sender, assign 4 bytes for EFER in 'g' packet based on the line 113. GDB, the packet receiver, extract 8 bytes for EFER in 'g' packet based on the line 129. Therefore, all registers located behind EFER in 'g' packet has been shifted 4 bytes in GDB. After this commit, GDB can read 'g' packets correctly. Signed-off-by: TaiseiIto Message-Id: Signed-off-by: Paolo Bonzini --- gdb-xml/i386-32bit.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gdb-xml/i386-32bit.xml b/gdb-xml/i386-32bit.xml index 872fcea9c2..7a66a02b67 100644 --- a/gdb-xml/i386-32bit.xml +++ b/gdb-xml/i386-32bit.xml @@ -110,7 +110,7 @@ - + From 8a0afbb2a4f7da5e6a542787ea90eb240e7ac65d Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Wed, 2 Nov 2022 21:22:58 +0100 Subject: [PATCH 576/705] Fix broken configure with -Wunused-parameter The configure script fails because it tries to compile small C programs with a main function which is declared with arguments argc and argv although those arguments are unused. Running `configure -extra-cflags=-Wunused-parameter` triggers the problem. configure for a native build does abort but shows the error in config.log. A cross build configure for Windows with Debian stable aborts with an error. Avoiding unused arguments fixes this. Signed-off-by: Stefan Weil Message-Id: <20221102202258.456359-1-sw@weilnetz.de> Signed-off-by: Paolo Bonzini --- configure | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/configure b/configure index 4275f5419f..66928692b0 100755 --- a/configure +++ b/configure @@ -1258,7 +1258,7 @@ if test "$stack_protector" != "no"; then cat > $TMPC << EOF int main(int argc, char *argv[]) { - char arr[64], *p = arr, *c = argv[0]; + char arr[64], *p = arr, *c = argv[argc - 1]; while (*c) { *p++ = *c++; } @@ -1607,7 +1607,7 @@ fi if test "$safe_stack" = "yes"; then cat > $TMPC << EOF -int main(int argc, char *argv[]) +int main(void) { #if ! __has_feature(safe_stack) #error SafeStack Disabled @@ -1629,7 +1629,7 @@ EOF fi else cat > $TMPC << EOF -int main(int argc, char *argv[]) +int main(void) { #if defined(__has_feature) #if __has_feature(safe_stack) @@ -1675,7 +1675,7 @@ static const int Z = 1; #define TAUT(X) ((X) == Z) #define PAREN(X, Y) (X == Y) #define ID(X) (X) -int main(int argc, char *argv[]) +int main(void) { int x = 0, y = 0; x = ID(x); From b5d3dac17077c4c7d9a90b4c76123ea80ac037da Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 3 Nov 2022 18:19:18 +0100 Subject: [PATCH 577/705] meson: avoid unused arguments of main() in compiler tests meson.build has one test where "main" is declared unnecessarily with argc and argv arguments, but does not use them. Because the test needs -Werror too, HAVE_BROKEN_SIZE_MAX is defined incorrectly. Fix the test and, for consistency, remove argc and argv whenever they are not needed. Signed-off-by: Paolo Bonzini --- meson.build | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/meson.build b/meson.build index 1d448272ab..cf3e517e56 100644 --- a/meson.build +++ b/meson.build @@ -2165,7 +2165,7 @@ config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + ''' config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + ''' #include - int main(int argc, char *argv[]) { + int main(void) { return mlockall(MCL_FUTURE); }''')) @@ -2210,7 +2210,7 @@ config_host_data.set('HAVE_FSXATTR', cc.links(''' config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles(''' #include #include - int main(int argc, char *argv[]) { + int main(void) { return printf("%zu", SIZE_MAX); }''', args: ['-Werror'])) @@ -2327,7 +2327,7 @@ config_host_data.set('CONFIG_AVX2_OPT', get_option('avx2') \ __m256i x = *(__m256i *)a; return _mm256_testz_si256(x, x); } - int main(int argc, char *argv[]) { return bar(argv[0]); } + int main(int argc, char *argv[]) { return bar(argv[argc - 1]); } '''), error_message: 'AVX2 not available').allowed()) config_host_data.set('CONFIG_AVX512F_OPT', get_option('avx512f') \ @@ -2341,7 +2341,7 @@ config_host_data.set('CONFIG_AVX512F_OPT', get_option('avx512f') \ __m512i x = *(__m512i *)a; return _mm512_test_epi64_mask(x, x); } - int main(int argc, char *argv[]) { return bar(argv[0]); } + int main(int argc, char *argv[]) { return bar(argv[argc - 1]); } '''), error_message: 'AVX512F not available').allowed()) have_pvrdma = get_option('pvrdma') \ From efa3901e14a6428ef775332a6df958fb5b27af32 Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Thu, 3 Nov 2022 09:38:15 +0100 Subject: [PATCH 578/705] Add missing include statement for global xml_builtin This fixes some compiler warnings with compiler flag -Wmissing-variable-declarations (tested with clang): aarch64_be-linux-user-gdbstub-xml.c:564:19: warning: no previous extern declaration for non-static variable 'xml_builtin' [-Wmissing-variable-declarations] aarch64-linux-user-gdbstub-xml.c:564:19: warning: no previous extern declaration for non-static variable 'xml_builtin' [-Wmissing-variable-declarations] aarch64-softmmu-gdbstub-xml.c:1763:19: warning: no previous extern declaration for non-static variable 'xml_builtin' [-Wmissing-variable-declarations] Signed-off-by: Stefan Weil Signed-off-by: Paolo Bonzini --- scripts/feature_to_c.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/feature_to_c.sh b/scripts/feature_to_c.sh index b1169899c1..c1f67c8f6a 100644 --- a/scripts/feature_to_c.sh +++ b/scripts/feature_to_c.sh @@ -56,6 +56,7 @@ for input; do done echo +echo '#include "exec/gdbstub.h"' echo "const char *const xml_builtin[][2] = {" for input; do From 2106106d80489fb9b10cd3ccfaec811988e797cb Mon Sep 17 00:00:00 2001 From: Claudio Fontana Date: Thu, 29 Sep 2022 11:30:31 +0200 Subject: [PATCH 579/705] module: removed unused function argument "mayfail" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mayfail is always passed as false for every invocation throughout the program. It controls whether to printf or not to printf an error on g_module_open failure. Remove this unused argument. Signed-off-by: Claudio Fontana Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20220929093035.4231-2-cfontana@suse.de> Signed-off-by: Paolo Bonzini --- include/qemu/module.h | 8 ++++---- softmmu/qtest.c | 2 +- util/module.c | 20 +++++++++----------- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/include/qemu/module.h b/include/qemu/module.h index bd73607104..8c012bbe03 100644 --- a/include/qemu/module.h +++ b/include/qemu/module.h @@ -61,15 +61,15 @@ typedef enum { #define fuzz_target_init(function) module_init(function, \ MODULE_INIT_FUZZ_TARGET) #define migration_init(function) module_init(function, MODULE_INIT_MIGRATION) -#define block_module_load_one(lib) module_load_one("block-", lib, false) -#define ui_module_load_one(lib) module_load_one("ui-", lib, false) -#define audio_module_load_one(lib) module_load_one("audio-", lib, false) +#define block_module_load_one(lib) module_load_one("block-", lib) +#define ui_module_load_one(lib) module_load_one("ui-", lib) +#define audio_module_load_one(lib) module_load_one("audio-", lib) void register_module_init(void (*fn)(void), module_init_type type); void register_dso_module_init(void (*fn)(void), module_init_type type); void module_call_init(module_init_type type); -bool module_load_one(const char *prefix, const char *lib_name, bool mayfail); +bool module_load_one(const char *prefix, const char *lib_name); void module_load_qom_one(const char *type); void module_load_qom_all(void); void module_allow_arch(const char *arch); diff --git a/softmmu/qtest.c b/softmmu/qtest.c index afea7693d0..ff74c5d709 100644 --- a/softmmu/qtest.c +++ b/softmmu/qtest.c @@ -756,7 +756,7 @@ static void qtest_process_command(CharBackend *chr, gchar **words) g_assert(words[1] && words[2]); qtest_send_prefix(chr); - if (module_load_one(words[1], words[2], false)) { + if (module_load_one(words[1], words[2])) { qtest_sendf(chr, "OK\n"); } else { qtest_sendf(chr, "FAIL\n"); diff --git a/util/module.c b/util/module.c index 8ddb0e18f5..8563edd626 100644 --- a/util/module.c +++ b/util/module.c @@ -144,7 +144,7 @@ static bool module_check_arch(const QemuModinfo *modinfo) return true; } -static int module_load_file(const char *fname, bool mayfail, bool export_symbols) +static int module_load_file(const char *fname, bool export_symbols) { GModule *g_module; void (*sym)(void); @@ -172,10 +172,8 @@ static int module_load_file(const char *fname, bool mayfail, bool export_symbols } g_module = g_module_open(fname, flags); if (!g_module) { - if (!mayfail) { - fprintf(stderr, "Failed to open module: %s\n", - g_module_error()); - } + fprintf(stderr, "Failed to open module: %s\n", + g_module_error()); ret = -EINVAL; goto out; } @@ -208,7 +206,7 @@ out: } #endif -bool module_load_one(const char *prefix, const char *lib_name, bool mayfail) +bool module_load_one(const char *prefix, const char *lib_name) { bool success = false; @@ -256,7 +254,7 @@ bool module_load_one(const char *prefix, const char *lib_name, bool mayfail) if (strcmp(modinfo->name, module_name) == 0) { /* we depend on other module(s) */ for (sl = modinfo->deps; *sl != NULL; sl++) { - module_load_one("", *sl, false); + module_load_one("", *sl); } } else { for (sl = modinfo->deps; *sl != NULL; sl++) { @@ -287,7 +285,7 @@ bool module_load_one(const char *prefix, const char *lib_name, bool mayfail) for (i = 0; i < n_dirs; i++) { fname = g_strdup_printf("%s/%s%s", dirs[i], module_name, CONFIG_HOST_DSOSUF); - ret = module_load_file(fname, mayfail, export_symbols); + ret = module_load_file(fname, export_symbols); g_free(fname); fname = NULL; /* Try loading until loaded a module file */ @@ -333,7 +331,7 @@ void module_load_qom_one(const char *type) } for (sl = modinfo->objs; *sl != NULL; sl++) { if (strcmp(type, *sl) == 0) { - module_load_one("", modinfo->name, false); + module_load_one("", modinfo->name); } } } @@ -354,7 +352,7 @@ void module_load_qom_all(void) if (!module_check_arch(modinfo)) { continue; } - module_load_one("", modinfo->name, false); + module_load_one("", modinfo->name); } module_loaded_qom_all = true; } @@ -370,7 +368,7 @@ void qemu_load_module_for_opts(const char *group) } for (sl = modinfo->opts; *sl != NULL; sl++) { if (strcmp(group, *sl) == 0) { - module_load_one("", modinfo->name, false); + module_load_one("", modinfo->name); } } } From dbc0e80553c067f56cb236d9de2cd0d50f3c6131 Mon Sep 17 00:00:00 2001 From: Claudio Fontana Date: Thu, 29 Sep 2022 11:30:32 +0200 Subject: [PATCH 580/705] module: rename module_load_one to module_load MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Claudio Fontana Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20220929093035.4231-3-cfontana@suse.de> Signed-off-by: Paolo Bonzini --- audio/audio.c | 2 +- block.c | 4 ++-- block/dmg.c | 4 ++-- hw/core/qdev.c | 2 +- include/qemu/module.h | 10 +++++----- qom/object.c | 4 ++-- softmmu/qtest.c | 2 +- ui/console.c | 6 +++--- util/module.c | 14 +++++++------- 9 files changed, 24 insertions(+), 24 deletions(-) diff --git a/audio/audio.c b/audio/audio.c index cc664271eb..379f19dc89 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -80,7 +80,7 @@ audio_driver *audio_driver_lookup(const char *name) } } - audio_module_load_one(name); + audio_module_load(name); QLIST_FOREACH(d, &audio_drivers, next) { if (strcmp(name, d->name) == 0) { return d; diff --git a/block.c b/block.c index 3bd594eb2a..ddd743c447 100644 --- a/block.c +++ b/block.c @@ -464,7 +464,7 @@ BlockDriver *bdrv_find_format(const char *format_name) /* The driver isn't registered, maybe we need to load a module */ for (i = 0; i < (int)ARRAY_SIZE(block_driver_modules); ++i) { if (!strcmp(block_driver_modules[i].format_name, format_name)) { - block_module_load_one(block_driver_modules[i].library_name); + block_module_load(block_driver_modules[i].library_name); break; } } @@ -981,7 +981,7 @@ BlockDriver *bdrv_find_protocol(const char *filename, for (i = 0; i < (int)ARRAY_SIZE(block_driver_modules); ++i) { if (block_driver_modules[i].protocol_name && !strcmp(block_driver_modules[i].protocol_name, protocol)) { - block_module_load_one(block_driver_modules[i].library_name); + block_module_load(block_driver_modules[i].library_name); break; } } diff --git a/block/dmg.c b/block/dmg.c index 422136276a..b5a93b086b 100644 --- a/block/dmg.c +++ b/block/dmg.c @@ -445,8 +445,8 @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags, return ret; } - block_module_load_one("dmg-bz2"); - block_module_load_one("dmg-lzfse"); + block_module_load("dmg-bz2"); + block_module_load("dmg-lzfse"); s->n_chunks = 0; s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL; diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 0806d8fcaa..25dfc08468 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -148,7 +148,7 @@ bool qdev_set_parent_bus(DeviceState *dev, BusState *bus, Error **errp) DeviceState *qdev_new(const char *name) { if (!object_class_by_name(name)) { - module_load_qom_one(name); + module_load_qom(name); } return DEVICE(object_new(name)); } diff --git a/include/qemu/module.h b/include/qemu/module.h index 8c012bbe03..b7911ce791 100644 --- a/include/qemu/module.h +++ b/include/qemu/module.h @@ -61,16 +61,16 @@ typedef enum { #define fuzz_target_init(function) module_init(function, \ MODULE_INIT_FUZZ_TARGET) #define migration_init(function) module_init(function, MODULE_INIT_MIGRATION) -#define block_module_load_one(lib) module_load_one("block-", lib) -#define ui_module_load_one(lib) module_load_one("ui-", lib) -#define audio_module_load_one(lib) module_load_one("audio-", lib) +#define block_module_load(lib) module_load("block-", lib) +#define ui_module_load(lib) module_load("ui-", lib) +#define audio_module_load(lib) module_load("audio-", lib) void register_module_init(void (*fn)(void), module_init_type type); void register_dso_module_init(void (*fn)(void), module_init_type type); void module_call_init(module_init_type type); -bool module_load_one(const char *prefix, const char *lib_name); -void module_load_qom_one(const char *type); +bool module_load(const char *prefix, const char *lib_name); +void module_load_qom(const char *type); void module_load_qom_all(void); void module_allow_arch(const char *arch); diff --git a/qom/object.c b/qom/object.c index e5cef30f6d..aba942bdf3 100644 --- a/qom/object.c +++ b/qom/object.c @@ -526,7 +526,7 @@ void object_initialize(void *data, size_t size, const char *typename) #ifdef CONFIG_MODULES if (!type) { - module_load_qom_one(typename); + module_load_qom(typename); type = type_get_by_name(typename); } #endif @@ -1033,7 +1033,7 @@ ObjectClass *module_object_class_by_name(const char *typename) oc = object_class_by_name(typename); #ifdef CONFIG_MODULES if (!oc) { - module_load_qom_one(typename); + module_load_qom(typename); oc = object_class_by_name(typename); } #endif diff --git a/softmmu/qtest.c b/softmmu/qtest.c index ff74c5d709..7743545651 100644 --- a/softmmu/qtest.c +++ b/softmmu/qtest.c @@ -756,7 +756,7 @@ static void qtest_process_command(CharBackend *chr, gchar **words) g_assert(words[1] && words[2]); qtest_send_prefix(chr); - if (module_load_one(words[1], words[2])) { + if (module_load(words[1], words[2])) { qtest_sendf(chr, "OK\n"); } else { qtest_sendf(chr, "FAIL\n"); diff --git a/ui/console.c b/ui/console.c index 65c117874c..44dfb0f52b 100644 --- a/ui/console.c +++ b/ui/console.c @@ -2632,7 +2632,7 @@ bool qemu_display_find_default(DisplayOptions *opts) for (i = 0; i < (int)ARRAY_SIZE(prio); i++) { if (dpys[prio[i]] == NULL) { - ui_module_load_one(DisplayType_str(prio[i])); + ui_module_load(DisplayType_str(prio[i])); } if (dpys[prio[i]] == NULL) { continue; @@ -2650,7 +2650,7 @@ void qemu_display_early_init(DisplayOptions *opts) return; } if (dpys[opts->type] == NULL) { - ui_module_load_one(DisplayType_str(opts->type)); + ui_module_load(DisplayType_str(opts->type)); } if (dpys[opts->type] == NULL) { error_report("Display '%s' is not available.", @@ -2680,7 +2680,7 @@ void qemu_display_help(void) printf("none\n"); for (idx = DISPLAY_TYPE_NONE; idx < DISPLAY_TYPE__MAX; idx++) { if (!dpys[idx]) { - ui_module_load_one(DisplayType_str(idx)); + ui_module_load(DisplayType_str(idx)); } if (dpys[idx]) { printf("%s\n", DisplayType_str(dpys[idx]->type)); diff --git a/util/module.c b/util/module.c index 8563edd626..ad89cd50dc 100644 --- a/util/module.c +++ b/util/module.c @@ -206,7 +206,7 @@ out: } #endif -bool module_load_one(const char *prefix, const char *lib_name) +bool module_load(const char *prefix, const char *lib_name) { bool success = false; @@ -254,7 +254,7 @@ bool module_load_one(const char *prefix, const char *lib_name) if (strcmp(modinfo->name, module_name) == 0) { /* we depend on other module(s) */ for (sl = modinfo->deps; *sl != NULL; sl++) { - module_load_one("", *sl); + module_load("", *sl); } } else { for (sl = modinfo->deps; *sl != NULL; sl++) { @@ -312,7 +312,7 @@ bool module_load_one(const char *prefix, const char *lib_name) static bool module_loaded_qom_all; -void module_load_qom_one(const char *type) +void module_load_qom(const char *type) { const QemuModinfo *modinfo; const char **sl; @@ -331,7 +331,7 @@ void module_load_qom_one(const char *type) } for (sl = modinfo->objs; *sl != NULL; sl++) { if (strcmp(type, *sl) == 0) { - module_load_one("", modinfo->name); + module_load("", modinfo->name); } } } @@ -352,7 +352,7 @@ void module_load_qom_all(void) if (!module_check_arch(modinfo)) { continue; } - module_load_one("", modinfo->name); + module_load("", modinfo->name); } module_loaded_qom_all = true; } @@ -368,7 +368,7 @@ void qemu_load_module_for_opts(const char *group) } for (sl = modinfo->opts; *sl != NULL; sl++) { if (strcmp(group, *sl) == 0) { - module_load_one("", modinfo->name); + module_load("", modinfo->name); } } } @@ -378,7 +378,7 @@ void qemu_load_module_for_opts(const char *group) void module_allow_arch(const char *arch) {} void qemu_load_module_for_opts(const char *group) {} -void module_load_qom_one(const char *type) {} +void module_load_qom(const char *type) {} void module_load_qom_all(void) {} #endif From c551fb0b53db5d9a1f0116e8cce12f994605c9ea Mon Sep 17 00:00:00 2001 From: Claudio Fontana Date: Thu, 29 Sep 2022 11:30:33 +0200 Subject: [PATCH 581/705] module: add Error arguments to module_load and module_load_qom improve error handling during module load, by changing: bool module_load(const char *prefix, const char *lib_name); void module_load_qom(const char *type); to: int module_load(const char *prefix, const char *name, Error **errp); int module_load_qom(const char *type, Error **errp); where the return value is: -1 on module load error, and errp is set with the error 0 on module or one of its dependencies are not installed 1 on module load success 2 on module load success (module already loaded or built-in) module_load_qom_one has been introduced in: commit 28457744c345 ("module: qom module support"), which built on top of module_load_one, but discarded the bool return value. Restore it. Adapt all callers to emit errors, or ignore them, or fail hard, as appropriate in each context. Replace the previous emission of errors via fprintf in _some_ error conditions with Error and error_report, so as to emit to the appropriate target. A memory leak is also fixed as part of the module_load changes. audio: when attempting to load an audio module, report module load errors. Note that still for some callers, a single issue may generate multiple error reports, and this could be improved further. Regarding the audio code itself, audio_add() seems to ignore errors, and this should probably be improved. block: when attempting to load a block module, report module load errors. For the code paths that already use the Error API, take advantage of those to report module load errors into the Error parameter. For the other code paths, we currently emit the error, but this could be improved further by adding Error parameters to all possible code paths. console: when attempting to load a display module, report module load errors. qdev: when creating a new qdev Device object (DeviceState), report load errors. If a module cannot be loaded to create that device, now abort execution (if no CONFIG_MODULE) or exit (if CONFIG_MODULE). qom/object.c: when initializing a QOM object, or looking up class_by_name, report module load errors. qtest: when processing the "module_load" qtest command, report errors in the load of the module. Signed-off-by: Claudio Fontana Reviewed-by: Richard Henderson Message-Id: <20220929093035.4231-4-cfontana@suse.de> Signed-off-by: Paolo Bonzini --- audio/audio.c | 16 ++-- block.c | 20 +++- block/dmg.c | 14 ++- hw/core/qdev.c | 17 +++- include/qemu/module.h | 37 +++++++- qom/object.c | 18 +++- softmmu/qtest.c | 8 +- ui/console.c | 18 +++- util/module.c | 209 +++++++++++++++++++++++------------------- 9 files changed, 234 insertions(+), 123 deletions(-) diff --git a/audio/audio.c b/audio/audio.c index 379f19dc89..065602ce1b 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -73,20 +73,24 @@ void audio_driver_register(audio_driver *drv) audio_driver *audio_driver_lookup(const char *name) { struct audio_driver *d; + Error *local_err = NULL; + int rv; QLIST_FOREACH(d, &audio_drivers, next) { if (strcmp(name, d->name) == 0) { return d; } } - - audio_module_load(name); - QLIST_FOREACH(d, &audio_drivers, next) { - if (strcmp(name, d->name) == 0) { - return d; + rv = audio_module_load(name, &local_err); + if (rv > 0) { + QLIST_FOREACH(d, &audio_drivers, next) { + if (strcmp(name, d->name) == 0) { + return d; + } } + } else if (rv < 0) { + error_report_err(local_err); } - return NULL; } diff --git a/block.c b/block.c index ddd743c447..c5e20c0bea 100644 --- a/block.c +++ b/block.c @@ -464,12 +464,18 @@ BlockDriver *bdrv_find_format(const char *format_name) /* The driver isn't registered, maybe we need to load a module */ for (i = 0; i < (int)ARRAY_SIZE(block_driver_modules); ++i) { if (!strcmp(block_driver_modules[i].format_name, format_name)) { - block_module_load(block_driver_modules[i].library_name); + Error *local_err = NULL; + int rv = block_module_load(block_driver_modules[i].library_name, + &local_err); + if (rv > 0) { + return bdrv_do_find_format(format_name); + } else if (rv < 0) { + error_report_err(local_err); + } break; } } - - return bdrv_do_find_format(format_name); + return NULL; } static int bdrv_format_is_whitelisted(const char *format_name, bool read_only) @@ -981,12 +987,16 @@ BlockDriver *bdrv_find_protocol(const char *filename, for (i = 0; i < (int)ARRAY_SIZE(block_driver_modules); ++i) { if (block_driver_modules[i].protocol_name && !strcmp(block_driver_modules[i].protocol_name, protocol)) { - block_module_load(block_driver_modules[i].library_name); + int rv = block_module_load(block_driver_modules[i].library_name, errp); + if (rv > 0) { + drv1 = bdrv_do_find_protocol(protocol); + } else if (rv < 0) { + return NULL; + } break; } } - drv1 = bdrv_do_find_protocol(protocol); if (!drv1) { error_setg(errp, "Unknown protocol '%s'", protocol); } diff --git a/block/dmg.c b/block/dmg.c index b5a93b086b..ba8ec344d4 100644 --- a/block/dmg.c +++ b/block/dmg.c @@ -444,9 +444,17 @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags, if (ret < 0) { return ret; } - - block_module_load("dmg-bz2"); - block_module_load("dmg-lzfse"); + /* + * NB: if uncompress submodules are absent, + * ie block_module_load return value == 0, the function pointers + * dmg_uncompress_bz2 and dmg_uncompress_lzfse will be NULL. + */ + if (block_module_load("dmg-bz2", errp) < 0) { + return -EINVAL; + } + if (block_module_load("dmg-lzfse", errp) < 0) { + return -EINVAL; + } s->n_chunks = 0; s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL; diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 25dfc08468..0145501904 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -147,8 +147,21 @@ bool qdev_set_parent_bus(DeviceState *dev, BusState *bus, Error **errp) DeviceState *qdev_new(const char *name) { - if (!object_class_by_name(name)) { - module_load_qom(name); + ObjectClass *oc = object_class_by_name(name); +#ifdef CONFIG_MODULES + if (!oc) { + int rv = module_load_qom(name, &error_fatal); + if (rv > 0) { + oc = object_class_by_name(name); + } else { + error_report("could not find a module for type '%s'", name); + exit(1); + } + } +#endif + if (!oc) { + error_report("unknown type '%s'", name); + abort(); } return DEVICE(object_new(name)); } diff --git a/include/qemu/module.h b/include/qemu/module.h index b7911ce791..c37ce74b16 100644 --- a/include/qemu/module.h +++ b/include/qemu/module.h @@ -61,16 +61,43 @@ typedef enum { #define fuzz_target_init(function) module_init(function, \ MODULE_INIT_FUZZ_TARGET) #define migration_init(function) module_init(function, MODULE_INIT_MIGRATION) -#define block_module_load(lib) module_load("block-", lib) -#define ui_module_load(lib) module_load("ui-", lib) -#define audio_module_load(lib) module_load("audio-", lib) +#define block_module_load(lib, errp) module_load("block-", lib, errp) +#define ui_module_load(lib, errp) module_load("ui-", lib, errp) +#define audio_module_load(lib, errp) module_load("audio-", lib, errp) void register_module_init(void (*fn)(void), module_init_type type); void register_dso_module_init(void (*fn)(void), module_init_type type); void module_call_init(module_init_type type); -bool module_load(const char *prefix, const char *lib_name); -void module_load_qom(const char *type); + +/* + * module_load: attempt to load a module from a set of directories + * + * directories searched are: + * - getenv("QEMU_MODULE_DIR") + * - get_relocated_path(CONFIG_QEMU_MODDIR); + * - /var/run/qemu/${version_dir} + * + * prefix: a subsystem prefix, or the empty string ("audio-", ..., "") + * name: name of the module + * errp: error to set in case the module is found, but load failed. + * + * Return value: -1 on error (errp set if not NULL). + * 0 if module or one of its dependencies are not installed, + * 1 if the module is found and loaded, + * 2 if the module is already loaded, or module is built-in. + */ +int module_load(const char *prefix, const char *name, Error **errp); + +/* + * module_load_qom: attempt to load a module to provide a QOM type + * + * type: the type to be provided + * errp: error to set. + * + * Return value: as per module_load. + */ +int module_load_qom(const char *type, Error **errp); void module_load_qom_all(void); void module_allow_arch(const char *arch); diff --git a/qom/object.c b/qom/object.c index aba942bdf3..e25f1e96db 100644 --- a/qom/object.c +++ b/qom/object.c @@ -526,8 +526,13 @@ void object_initialize(void *data, size_t size, const char *typename) #ifdef CONFIG_MODULES if (!type) { - module_load_qom(typename); - type = type_get_by_name(typename); + int rv = module_load_qom(typename, &error_fatal); + if (rv > 0) { + type = type_get_by_name(typename); + } else { + error_report("missing object type '%s'", typename); + exit(1); + } } #endif if (!type) { @@ -1033,8 +1038,13 @@ ObjectClass *module_object_class_by_name(const char *typename) oc = object_class_by_name(typename); #ifdef CONFIG_MODULES if (!oc) { - module_load_qom(typename); - oc = object_class_by_name(typename); + Error *local_err = NULL; + int rv = module_load_qom(typename, &local_err); + if (rv > 0) { + oc = object_class_by_name(typename); + } else if (rv < 0) { + error_report_err(local_err); + } } #endif return oc; diff --git a/softmmu/qtest.c b/softmmu/qtest.c index 7743545651..d3e0ab4eda 100644 --- a/softmmu/qtest.c +++ b/softmmu/qtest.c @@ -753,12 +753,18 @@ static void qtest_process_command(CharBackend *chr, gchar **words) qtest_sendf(chr, "OK %"PRIi64"\n", (int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); } else if (strcmp(words[0], "module_load") == 0) { + Error *local_err = NULL; + int rv; g_assert(words[1] && words[2]); qtest_send_prefix(chr); - if (module_load(words[1], words[2])) { + rv = module_load(words[1], words[2], &local_err); + if (rv > 0) { qtest_sendf(chr, "OK\n"); } else { + if (rv < 0) { + error_report_err(local_err); + } qtest_sendf(chr, "FAIL\n"); } } else if (qtest_enabled() && strcmp(words[0], "clock_set") == 0) { diff --git a/ui/console.c b/ui/console.c index 44dfb0f52b..3c0d9b061a 100644 --- a/ui/console.c +++ b/ui/console.c @@ -2632,7 +2632,11 @@ bool qemu_display_find_default(DisplayOptions *opts) for (i = 0; i < (int)ARRAY_SIZE(prio); i++) { if (dpys[prio[i]] == NULL) { - ui_module_load(DisplayType_str(prio[i])); + Error *local_err = NULL; + int rv = ui_module_load(DisplayType_str(prio[i]), &local_err); + if (rv < 0) { + error_report_err(local_err); + } } if (dpys[prio[i]] == NULL) { continue; @@ -2650,7 +2654,11 @@ void qemu_display_early_init(DisplayOptions *opts) return; } if (dpys[opts->type] == NULL) { - ui_module_load(DisplayType_str(opts->type)); + Error *local_err = NULL; + int rv = ui_module_load(DisplayType_str(opts->type), &local_err); + if (rv < 0) { + error_report_err(local_err); + } } if (dpys[opts->type] == NULL) { error_report("Display '%s' is not available.", @@ -2680,7 +2688,11 @@ void qemu_display_help(void) printf("none\n"); for (idx = DISPLAY_TYPE_NONE; idx < DISPLAY_TYPE__MAX; idx++) { if (!dpys[idx]) { - ui_module_load(DisplayType_str(idx)); + Error *local_err = NULL; + int rv = ui_module_load(DisplayType_str(idx), &local_err); + if (rv < 0) { + error_report_err(local_err); + } } if (dpys[idx]) { printf("%s\n", DisplayType_str(dpys[idx]->type)); diff --git a/util/module.c b/util/module.c index ad89cd50dc..32e263163c 100644 --- a/util/module.c +++ b/util/module.c @@ -21,6 +21,7 @@ #include "qemu/module.h" #include "qemu/cutils.h" #include "qemu/config-file.h" +#include "qapi/error.h" #ifdef CONFIG_MODULE_UPGRADES #include "qemu-version.h" #endif @@ -144,25 +145,22 @@ static bool module_check_arch(const QemuModinfo *modinfo) return true; } -static int module_load_file(const char *fname, bool export_symbols) +/* + * module_load_dso: attempt to load an existing dso file + * + * fname: full pathname of the file to load + * export_symbols: if true, add the symbols to the global name space + * errp: error to set. + * + * Return value: true on success, false on error, and errp will be set. + */ +static bool module_load_dso(const char *fname, bool export_symbols, + Error **errp) { GModule *g_module; void (*sym)(void); - const char *dsosuf = CONFIG_HOST_DSOSUF; - int len = strlen(fname); - int suf_len = strlen(dsosuf); ModuleEntry *e, *next; - int ret, flags; - - if (len <= suf_len || strcmp(&fname[len - suf_len], dsosuf)) { - /* wrong suffix */ - ret = -EINVAL; - goto out; - } - if (access(fname, F_OK)) { - ret = -ENOENT; - goto out; - } + int flags; assert(QTAILQ_EMPTY(&dso_init_list)); @@ -172,46 +170,38 @@ static int module_load_file(const char *fname, bool export_symbols) } g_module = g_module_open(fname, flags); if (!g_module) { - fprintf(stderr, "Failed to open module: %s\n", - g_module_error()); - ret = -EINVAL; - goto out; + error_setg(errp, "failed to open module: %s", g_module_error()); + return false; } if (!g_module_symbol(g_module, DSO_STAMP_FUN_STR, (gpointer *)&sym)) { - fprintf(stderr, "Failed to initialize module: %s\n", - fname); - /* Print some info if this is a QEMU module (but from different build), - * this will make debugging user problems easier. */ + error_setg(errp, "failed to initialize module: %s", fname); + /* + * Print some info if this is a QEMU module (but from different build), + * this will make debugging user problems easier. + */ if (g_module_symbol(g_module, "qemu_module_dummy", (gpointer *)&sym)) { - fprintf(stderr, - "Note: only modules from the same build can be loaded.\n"); + error_append_hint(errp, + "Only modules from the same build can be loaded.\n"); } g_module_close(g_module); - ret = -EINVAL; - } else { - QTAILQ_FOREACH(e, &dso_init_list, node) { - e->init(); - register_module_init(e->init, e->type); - } - ret = 0; + return false; } + QTAILQ_FOREACH(e, &dso_init_list, node) { + e->init(); + register_module_init(e->init, e->type); + } trace_module_load_module(fname); QTAILQ_FOREACH_SAFE(e, &dso_init_list, node, next) { QTAILQ_REMOVE(&dso_init_list, e, node); g_free(e); } -out: - return ret; + return true; } -#endif -bool module_load(const char *prefix, const char *lib_name) +int module_load(const char *prefix, const char *name, Error **errp) { - bool success = false; - -#ifdef CONFIG_MODULES - char *fname = NULL; + int rv = -1; #ifdef CONFIG_MODULE_UPGRADES char *version_dir; #endif @@ -219,54 +209,29 @@ bool module_load(const char *prefix, const char *lib_name) char *dirs[5]; char *module_name; int i = 0, n_dirs = 0; - int ret; bool export_symbols = false; static GHashTable *loaded_modules; const QemuModinfo *modinfo; const char **sl; if (!g_module_supported()) { - fprintf(stderr, "Module is not supported by system.\n"); - return false; + error_setg(errp, "%s", "this platform does not support GLib modules"); + return -1; } if (!loaded_modules) { loaded_modules = g_hash_table_new(g_str_hash, g_str_equal); } - module_name = g_strdup_printf("%s%s", prefix, lib_name); + /* allocate all resources managed by the out: label here */ + module_name = g_strdup_printf("%s%s", prefix, name); if (g_hash_table_contains(loaded_modules, module_name)) { g_free(module_name); - return true; + return 2; /* module already loaded */ } g_hash_table_add(loaded_modules, module_name); - for (modinfo = module_info; modinfo->name != NULL; modinfo++) { - if (modinfo->arch) { - if (strcmp(modinfo->name, module_name) == 0) { - if (!module_check_arch(modinfo)) { - return false; - } - } - } - if (modinfo->deps) { - if (strcmp(modinfo->name, module_name) == 0) { - /* we depend on other module(s) */ - for (sl = modinfo->deps; *sl != NULL; sl++) { - module_load("", *sl); - } - } else { - for (sl = modinfo->deps; *sl != NULL; sl++) { - if (strcmp(module_name, *sl) == 0) { - /* another module depends on us */ - export_symbols = true; - } - } - } - } - } - search_dir = getenv("QEMU_MODULE_DIR"); if (search_dir != NULL) { dirs[n_dirs++] = g_strdup_printf("%s", search_dir); @@ -279,46 +244,87 @@ bool module_load(const char *prefix, const char *lib_name) '_'); dirs[n_dirs++] = g_strdup_printf("/var/run/qemu/%s", version_dir); #endif - assert(n_dirs <= ARRAY_SIZE(dirs)); - for (i = 0; i < n_dirs; i++) { - fname = g_strdup_printf("%s/%s%s", - dirs[i], module_name, CONFIG_HOST_DSOSUF); - ret = module_load_file(fname, export_symbols); - g_free(fname); - fname = NULL; - /* Try loading until loaded a module file */ - if (!ret) { - success = true; - break; + /* end of resources managed by the out: label */ + + for (modinfo = module_info; modinfo->name != NULL; modinfo++) { + if (modinfo->arch) { + if (strcmp(modinfo->name, module_name) == 0) { + if (!module_check_arch(modinfo)) { + error_setg(errp, "module arch does not match: " + "expected '%s', got '%s'", module_arch, modinfo->arch); + goto out; + } + } + } + if (modinfo->deps) { + if (strcmp(modinfo->name, module_name) == 0) { + /* we depend on other module(s) */ + for (sl = modinfo->deps; *sl != NULL; sl++) { + int subrv = module_load("", *sl, errp); + if (subrv <= 0) { + rv = subrv; + goto out; + } + } + } else { + for (sl = modinfo->deps; *sl != NULL; sl++) { + if (strcmp(module_name, *sl) == 0) { + /* another module depends on us */ + export_symbols = true; + } + } + } } } - if (!success) { + for (i = 0; i < n_dirs; i++) { + char *fname = g_strdup_printf("%s/%s%s", + dirs[i], module_name, CONFIG_HOST_DSOSUF); + int ret = access(fname, F_OK); + if (ret != 0 && (errno == ENOENT || errno == ENOTDIR)) { + /* + * if we don't find the module in this dir, try the next one. + * If we don't find it in any dir, that can be fine too: user + * did not install the module. We will return 0 in this case + * with no error set. + */ + g_free(fname); + continue; + } else if (ret != 0) { + /* most common is EACCES here */ + error_setg_errno(errp, errno, "error trying to access %s", fname); + } else if (module_load_dso(fname, export_symbols, errp)) { + rv = 1; /* module successfully loaded */ + } + g_free(fname); + goto out; + } + rv = 0; /* module not found */ + +out: + if (rv <= 0) { g_hash_table_remove(loaded_modules, module_name); g_free(module_name); } - for (i = 0; i < n_dirs; i++) { g_free(dirs[i]); } - -#endif - return success; + return rv; } -#ifdef CONFIG_MODULES - static bool module_loaded_qom_all; -void module_load_qom(const char *type) +int module_load_qom(const char *type, Error **errp) { const QemuModinfo *modinfo; const char **sl; + int rv = 0; if (!type) { - return; + error_setg(errp, "%s", "type is NULL"); + return -1; } trace_module_lookup_object_type(type); @@ -331,15 +337,24 @@ void module_load_qom(const char *type) } for (sl = modinfo->objs; *sl != NULL; sl++) { if (strcmp(type, *sl) == 0) { - module_load("", modinfo->name); + if (rv > 0) { + error_setg(errp, "multiple modules providing '%s'", type); + return -1; + } + rv = module_load("", modinfo->name, errp); + if (rv < 0) { + return rv; + } } } } + return rv; } void module_load_qom_all(void) { const QemuModinfo *modinfo; + Error *local_err = NULL; if (module_loaded_qom_all) { return; @@ -352,7 +367,9 @@ void module_load_qom_all(void) if (!module_check_arch(modinfo)) { continue; } - module_load("", modinfo->name); + if (module_load("", modinfo->name, &local_err) < 0) { + error_report_err(local_err); + } } module_loaded_qom_all = true; } @@ -368,7 +385,10 @@ void qemu_load_module_for_opts(const char *group) } for (sl = modinfo->opts; *sl != NULL; sl++) { if (strcmp(group, *sl) == 0) { - module_load("", modinfo->name); + Error *local_err = NULL; + if (module_load("", modinfo->name, &local_err) < 0) { + error_report_err(local_err); + } } } } @@ -378,7 +398,8 @@ void qemu_load_module_for_opts(const char *group) void module_allow_arch(const char *arch) {} void qemu_load_module_for_opts(const char *group) {} -void module_load_qom(const char *type) {} +int module_load(const char *prefix, const char *name, Error **errp) { return 2; } +int module_load_qom(const char *type, Error **errp) { return 2; } void module_load_qom_all(void) {} #endif From 971974f0a9745a5163e1c825d38da03118054ae2 Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Thu, 29 Sep 2022 11:30:34 +0200 Subject: [PATCH 582/705] dmg: warn when opening dmg images containing blocks of unknown type Signed-off-by: Kevin Wolf Signed-off-by: Claudio Fontana Reviewed-by: Richard Henderson Message-Id: <20220929093035.4231-5-cfontana@suse.de> Signed-off-by: Paolo Bonzini --- block/dmg.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/block/dmg.c b/block/dmg.c index ba8ec344d4..675e840ca5 100644 --- a/block/dmg.c +++ b/block/dmg.c @@ -254,6 +254,25 @@ static int dmg_read_mish_block(BDRVDMGState *s, DmgHeaderState *ds, for (i = s->n_chunks; i < s->n_chunks + chunk_count; i++) { s->types[i] = buff_read_uint32(buffer, offset); if (!dmg_is_known_block_type(s->types[i])) { + switch (s->types[i]) { + case UDBZ: + warn_report_once("dmg-bzip2 module is missing, accessing bzip2 " + "compressed blocks will result in I/O errors"); + break; + case ULFO: + warn_report_once("dmg-lzfse module is missing, accessing lzfse " + "compressed blocks will result in I/O errors"); + break; + case UDCM: + case UDLE: + /* Comments and last entry can be ignored without problems */ + break; + default: + warn_report_once("Image contains chunks of unknown type %x, " + "accessing them will result in I/O errors", + s->types[i]); + break; + } chunk_count--; i--; offset += 40; From 5141e9a23fc9a890d66a5700920a5ffd8885121f Mon Sep 17 00:00:00 2001 From: Claudio Fontana Date: Thu, 29 Sep 2022 11:30:35 +0200 Subject: [PATCH 583/705] accel: abort if we fail to load the accelerator plugin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit if QEMU is configured with modules enabled, it is possible that the load of an accelerator module will fail. Exit in this case, relying on module_object_class_by_name to report the specific load error if any. Signed-off-by: Claudio Fontana Reviewed-by: Richard Henderson [claudio: changed abort() to exit(1)] Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Markus Armbruster Message-Id: <20220929093035.4231-6-cfontana@suse.de> Signed-off-by: Paolo Bonzini --- accel/accel-softmmu.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/accel/accel-softmmu.c b/accel/accel-softmmu.c index 67276e4f52..f9cdafb148 100644 --- a/accel/accel-softmmu.c +++ b/accel/accel-softmmu.c @@ -66,6 +66,7 @@ void accel_init_ops_interfaces(AccelClass *ac) { const char *ac_name; char *ops_name; + ObjectClass *oc; AccelOpsClass *ops; ac_name = object_class_get_name(OBJECT_CLASS(ac)); @@ -73,8 +74,13 @@ void accel_init_ops_interfaces(AccelClass *ac) ops_name = g_strdup_printf("%s" ACCEL_OPS_SUFFIX, ac_name); ops = ACCEL_OPS_CLASS(module_object_class_by_name(ops_name)); + oc = module_object_class_by_name(ops_name); + if (!oc) { + error_report("fatal: could not load module for type '%s'", ops_name); + exit(1); + } g_free(ops_name); - + ops = ACCEL_OPS_CLASS(oc); /* * all accelerators need to define ops, providing at least a mandatory * non-NULL create_vcpu_thread operation. From 897c0da96f936217e3e2a04c77486ca93c2f1dea Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Thu, 3 Nov 2022 10:50:17 +0900 Subject: [PATCH 584/705] tests/qtest/libqos/e1000e: Refer common PCI ID definitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is yet another minor cleanup to ease understanding and future refactoring of the tests. Signed-off-by: Akihiko Odaki Message-Id: <20221103015017.19947-1-akihiko.odaki@daynix.com> Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Thomas Huth --- tests/qtest/libqos/e1000e.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/qtest/libqos/e1000e.c b/tests/qtest/libqos/e1000e.c index ed47e34044..5f80035859 100644 --- a/tests/qtest/libqos/e1000e.c +++ b/tests/qtest/libqos/e1000e.c @@ -18,6 +18,7 @@ #include "qemu/osdep.h" #include "hw/net/e1000_regs.h" +#include "hw/pci/pci_ids.h" #include "../libqtest.h" #include "pci-pc.h" #include "qemu/sockets.h" @@ -217,8 +218,8 @@ static void *e1000e_pci_create(void *pci_bus, QGuestAllocator *alloc, static void e1000e_register_nodes(void) { QPCIAddress addr = { - .vendor_id = 0x8086, - .device_id = 0x10D3, + .vendor_id = PCI_VENDOR_ID_INTEL, + .device_id = E1000_DEV_ID_82574L, }; /* FIXME: every test using this node needs to setup a -netdev socket,id=hs0 From ff4f45811fb2ca8f17ef78361128b03dbb679185 Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Thu, 3 Nov 2022 11:54:51 +0900 Subject: [PATCH 585/705] tests/qtest/libqos/e1000e: Set E1000_CTRL_SLU The later device status check depends on E1000_STATUS_LU, which is enabled by E1000_CTRL_SLU. Though E1000_STATUS_LU is not implemented and E1000_STATUS_LU is always available in the current implementation, be a bit nicer and set E1000_CTRL_SLU just in case the bit is implemented in the future. Signed-off-by: Akihiko Odaki Message-Id: <20221103025451.27446-1-akihiko.odaki@daynix.com> Signed-off-by: Thomas Huth --- tests/qtest/libqos/e1000e.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/qtest/libqos/e1000e.c b/tests/qtest/libqos/e1000e.c index 5f80035859..4fd0bd5311 100644 --- a/tests/qtest/libqos/e1000e.c +++ b/tests/qtest/libqos/e1000e.c @@ -122,7 +122,7 @@ static void e1000e_pci_start_hw(QOSGraphObject *obj) /* Reset the device */ val = e1000e_macreg_read(&d->e1000e, E1000_CTRL); - e1000e_macreg_write(&d->e1000e, E1000_CTRL, val | E1000_CTRL_RST); + e1000e_macreg_write(&d->e1000e, E1000_CTRL, val | E1000_CTRL_RST | E1000_CTRL_SLU); /* Enable and configure MSI-X */ qpci_msix_enable(&d->pci_dev); From dfa644b231a55e50571b99bc65a2fff530e6913c Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Thu, 3 Nov 2022 18:54:16 +0900 Subject: [PATCH 586/705] tests/qtest/e1000e-test: Use e1000_regs.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The register definitions in tests/qtest/e1000e-test.c had names different from hw/net/e1000_regs.h, which made it hard to understand what test codes corresponds to the implementation. Use hw/net/e1000_regs.h from tests/qtest/libqos/e1000e.c to remove these duplications. Signed-off-by: Akihiko Odaki Message-Id: <20221103095416.110162-1-akihiko.odaki@daynix.com> Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Thomas Huth --- tests/qtest/e1000e-test.c | 66 ++++++--------------------------------- 1 file changed, 10 insertions(+), 56 deletions(-) diff --git a/tests/qtest/e1000e-test.c b/tests/qtest/e1000e-test.c index 4cdd8238f2..08adc5226d 100644 --- a/tests/qtest/e1000e-test.c +++ b/tests/qtest/e1000e-test.c @@ -33,34 +33,11 @@ #include "qemu/bitops.h" #include "libqos/libqos-malloc.h" #include "libqos/e1000e.h" +#include "hw/net/e1000_regs.h" static void e1000e_send_verify(QE1000E *d, int *test_sockets, QGuestAllocator *alloc) { - struct { - uint64_t buffer_addr; - union { - uint32_t data; - struct { - uint16_t length; - uint8_t cso; - uint8_t cmd; - } flags; - } lower; - union { - uint32_t data; - struct { - uint8_t status; - uint8_t css; - uint16_t special; - } fields; - } upper; - } descr; - - static const uint32_t dtyp_data = BIT(20); - static const uint32_t dtyp_ext = BIT(29); - static const uint32_t dcmd_rs = BIT(27); - static const uint32_t dcmd_eop = BIT(24); - static const uint32_t dsta_dd = BIT(0); + struct e1000_tx_desc descr; static const int data_len = 64; char buffer[64]; int ret; @@ -73,10 +50,10 @@ static void e1000e_send_verify(QE1000E *d, int *test_sockets, QGuestAllocator *a /* Prepare TX descriptor */ memset(&descr, 0, sizeof(descr)); descr.buffer_addr = cpu_to_le64(data); - descr.lower.data = cpu_to_le32(dcmd_rs | - dcmd_eop | - dtyp_ext | - dtyp_data | + descr.lower.data = cpu_to_le32(E1000_TXD_CMD_RS | + E1000_TXD_CMD_EOP | + E1000_TXD_CMD_DEXT | + E1000_TXD_DTYP_D | data_len); /* Put descriptor to the ring */ @@ -86,7 +63,8 @@ static void e1000e_send_verify(QE1000E *d, int *test_sockets, QGuestAllocator *a e1000e_wait_isr(d, E1000E_TX0_MSG_ID); /* Check DD bit */ - g_assert_cmphex(le32_to_cpu(descr.upper.data) & dsta_dd, ==, dsta_dd); + g_assert_cmphex(le32_to_cpu(descr.upper.data) & E1000_TXD_STAT_DD, ==, + E1000_TXD_STAT_DD); /* Check data sent to the backend */ ret = recv(test_sockets[0], &recv_len, sizeof(recv_len), 0); @@ -101,31 +79,7 @@ static void e1000e_send_verify(QE1000E *d, int *test_sockets, QGuestAllocator *a static void e1000e_receive_verify(QE1000E *d, int *test_sockets, QGuestAllocator *alloc) { - union { - struct { - uint64_t buffer_addr; - uint64_t reserved; - } read; - struct { - struct { - uint32_t mrq; - union { - uint32_t rss; - struct { - uint16_t ip_id; - uint16_t csum; - } csum_ip; - } hi_dword; - } lower; - struct { - uint32_t status_error; - uint16_t length; - uint16_t vlan; - } upper; - } wb; - } descr; - - static const uint32_t esta_dd = BIT(0); + union e1000_rx_desc_extended descr; char test[] = "TEST"; int len = htonl(sizeof(test)); @@ -162,7 +116,7 @@ static void e1000e_receive_verify(QE1000E *d, int *test_sockets, QGuestAllocator /* Check DD bit */ g_assert_cmphex(le32_to_cpu(descr.wb.upper.status_error) & - esta_dd, ==, esta_dd); + E1000_RXD_STAT_DD, ==, E1000_RXD_STAT_DD); /* Check data sent to the backend */ memread(data, buffer, sizeof(buffer)); From 5ebafa16433e424127738d694c653101cc3133dd Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Thu, 3 Nov 2022 17:34:25 +0900 Subject: [PATCH 587/705] tests/qtest/libqos/e1000e: Use E1000_STATUS_ASDV_1000 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nemonics E1000_STATUS_LAN_INIT_DONE and E1000_STATUS_ASDV_1000 have the same value, and E1000_STATUS_ASDV_1000 should be used here because E1000_STATUS_ASDV_1000 represents the auto-detected speed tested here while E1000_STATUS_LAN_INIT_DONE is a value used for a different purpose with a variant of e1000e family different from the one implemented in QEMU. Signed-off-by: Akihiko Odaki Message-Id: <20221103083425.100590-1-akihiko.odaki@daynix.com> Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Thomas Huth --- tests/qtest/libqos/e1000e.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/qtest/libqos/e1000e.c b/tests/qtest/libqos/e1000e.c index 4fd0bd5311..05af6f2118 100644 --- a/tests/qtest/libqos/e1000e.c +++ b/tests/qtest/libqos/e1000e.c @@ -130,8 +130,8 @@ static void e1000e_pci_start_hw(QOSGraphObject *obj) /* Check the device status - link and speed */ val = e1000e_macreg_read(&d->e1000e, E1000_STATUS); - g_assert_cmphex(val & (E1000_STATUS_LU | E1000_STATUS_LAN_INIT_DONE), - ==, E1000_STATUS_LU | E1000_STATUS_LAN_INIT_DONE); + g_assert_cmphex(val & (E1000_STATUS_LU | E1000_STATUS_ASDV_1000), + ==, E1000_STATUS_LU | E1000_STATUS_ASDV_1000); /* Initialize TX/RX logic */ e1000e_macreg_write(&d->e1000e, E1000_RCTL, 0); From 624ee20cb9742bb536a778b9585c916b243e78f2 Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Sat, 5 Nov 2022 14:30:10 +0900 Subject: [PATCH 588/705] tests/qtest/libqos/e1000e: Use IVAR shift definitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There were still some constants defined in e1000_regs.h. Signed-off-by: Akihiko Odaki Message-Id: <20221105053010.38037-1-akihiko.odaki@daynix.com> Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Thomas Huth --- tests/qtest/libqos/e1000e.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/qtest/libqos/e1000e.c b/tests/qtest/libqos/e1000e.c index 05af6f2118..80b3e3db90 100644 --- a/tests/qtest/libqos/e1000e.c +++ b/tests/qtest/libqos/e1000e.c @@ -30,9 +30,9 @@ #include "e1000e.h" #define E1000E_IVAR_TEST_CFG \ - (E1000E_RX0_MSG_ID | E1000_IVAR_INT_ALLOC_VALID | \ - ((E1000E_TX0_MSG_ID | E1000_IVAR_INT_ALLOC_VALID) << 8) | \ - ((E1000E_OTHER_MSG_ID | E1000_IVAR_INT_ALLOC_VALID) << 16) | \ + (((E1000E_RX0_MSG_ID | E1000_IVAR_INT_ALLOC_VALID) << E1000_IVAR_RXQ0_SHIFT) | \ + ((E1000E_TX0_MSG_ID | E1000_IVAR_INT_ALLOC_VALID) << E1000_IVAR_TXQ0_SHIFT) | \ + ((E1000E_OTHER_MSG_ID | E1000_IVAR_INT_ALLOC_VALID) << E1000_IVAR_OTHER_SHIFT) | \ E1000_IVAR_TX_INT_EVERY_WB) #define E1000E_RING_LEN (0x1000) From d46e6bba55f858b829251e2f4bd7b150cdb5b1d6 Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Sat, 5 Nov 2022 12:55:25 +0100 Subject: [PATCH 589/705] tests/qtest: Fix two format strings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stefan Weil Message-Id: <20221105115525.623059-1-sw@weilnetz.de> Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Thomas Huth --- tests/qtest/migration-test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c index d2eb107f0c..f574331b7b 100644 --- a/tests/qtest/migration-test.c +++ b/tests/qtest/migration-test.c @@ -2188,7 +2188,7 @@ static void calc_dirty_rate(QTestState *who, uint64_t calc_time) qobject_unref(qmp_command(who, "{ 'execute': 'calc-dirty-rate'," "'arguments': { " - "'calc-time': %ld," + "'calc-time': %" PRIu64 "," "'mode': 'dirty-ring' }}", calc_time)); } @@ -2203,7 +2203,7 @@ static void dirtylimit_set_all(QTestState *who, uint64_t dirtyrate) qobject_unref(qmp_command(who, "{ 'execute': 'set-vcpu-dirty-limit'," "'arguments': { " - "'dirty-rate': %ld } }", + "'dirty-rate': %" PRIu64 " } }", dirtyrate)); } From d1695f1839769b62e25086187afc58185f49ba2f Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Tue, 1 Nov 2022 11:50:21 +0800 Subject: [PATCH 590/705] tests/qtest: migration-test: Enable TLS PSK tests for win32 Since commit f1018ea0a30f ("tests: avoid DOS line endings in PSK file"), the bug of the helper test_tls_psk_init_common() that caused TLS PSK tests to fail on Windows was fixed. Let's enable these tests on win32. Signed-off-by: Bin Meng Message-Id: <20221101035021.729669-1-bin.meng@windriver.com> Signed-off-by: Thomas Huth --- tests/qtest/migration-test.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c index f574331b7b..442998d9eb 100644 --- a/tests/qtest/migration-test.c +++ b/tests/qtest/migration-test.c @@ -1402,7 +1402,6 @@ static void test_precopy_unix_dirty_ring(void) } #ifdef CONFIG_GNUTLS -#ifndef _WIN32 static void test_precopy_unix_tls_psk(void) { g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs); @@ -1415,7 +1414,6 @@ static void test_precopy_unix_tls_psk(void) test_precopy_common(&args); } -#endif /* _WIN32 */ #ifdef CONFIG_TASN1 static void test_precopy_unix_tls_x509_default_host(void) @@ -1524,7 +1522,6 @@ static void test_precopy_tcp_plain(void) } #ifdef CONFIG_GNUTLS -#ifndef _WIN32 static void test_precopy_tcp_tls_psk_match(void) { MigrateCommon args = { @@ -1535,7 +1532,6 @@ static void test_precopy_tcp_tls_psk_match(void) test_precopy_common(&args); } -#endif /* _WIN32 */ static void test_precopy_tcp_tls_psk_mismatch(void) { @@ -1933,7 +1929,6 @@ static void test_multifd_tcp_zstd(void) #endif #ifdef CONFIG_GNUTLS -#ifndef _WIN32 static void * test_migrate_multifd_tcp_tls_psk_start_match(QTestState *from, QTestState *to) @@ -1941,7 +1936,6 @@ test_migrate_multifd_tcp_tls_psk_start_match(QTestState *from, test_migrate_precopy_tcp_multifd_start_common(from, to, "none"); return test_migrate_tls_psk_start_match(from, to); } -#endif /* _WIN32 */ static void * test_migrate_multifd_tcp_tls_psk_start_mismatch(QTestState *from, @@ -1993,7 +1987,6 @@ test_migrate_multifd_tls_x509_start_reject_anon_client(QTestState *from, } #endif /* CONFIG_TASN1 */ -#ifndef _WIN32 static void test_multifd_tcp_tls_psk_match(void) { MigrateCommon args = { @@ -2003,7 +1996,6 @@ static void test_multifd_tcp_tls_psk_match(void) }; test_precopy_common(&args); } -#endif /* _WIN32 */ static void test_multifd_tcp_tls_psk_mismatch(void) { @@ -2505,10 +2497,8 @@ int main(int argc, char **argv) qtest_add_func("/migration/precopy/unix/plain", test_precopy_unix_plain); qtest_add_func("/migration/precopy/unix/xbzrle", test_precopy_unix_xbzrle); #ifdef CONFIG_GNUTLS -#ifndef _WIN32 qtest_add_func("/migration/precopy/unix/tls/psk", test_precopy_unix_tls_psk); -#endif if (has_uffd) { /* @@ -2534,10 +2524,8 @@ int main(int argc, char **argv) qtest_add_func("/migration/precopy/tcp/plain", test_precopy_tcp_plain); #ifdef CONFIG_GNUTLS -#ifndef _WIN32 qtest_add_func("/migration/precopy/tcp/tls/psk/match", test_precopy_tcp_tls_psk_match); -#endif qtest_add_func("/migration/precopy/tcp/tls/psk/mismatch", test_precopy_tcp_tls_psk_mismatch); #ifdef CONFIG_TASN1 @@ -2581,10 +2569,8 @@ int main(int argc, char **argv) test_multifd_tcp_zstd); #endif #ifdef CONFIG_GNUTLS -#ifndef _WIN32 qtest_add_func("/migration/multifd/tcp/tls/psk/match", test_multifd_tcp_tls_psk_match); -#endif qtest_add_func("/migration/multifd/tcp/tls/psk/mismatch", test_multifd_tcp_tls_psk_mismatch); #ifdef CONFIG_TASN1 From 765de32d87db65abf443d6a5d7097d42fc6e48de Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Fri, 4 Nov 2022 07:36:59 -0400 Subject: [PATCH 591/705] gitlab-ci: increase clang-user timeout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The clang-user test exceeds the 1 hour timeout occassionally. Philippe Mathieu-Daudé has pointed out that the number of tcg tests has increased since QEMU 7.1. The execution time therefore probably reflects a legitimate increase in tests rather than a performance regression. Bump the timeout to prevent CI failures. Suggested-by: Thomas Huth Signed-off-by: Stefan Hajnoczi Reviewed-by: Thomas Huth Message-Id: <20221104113659.427690-1-stefanha@redhat.com> Signed-off-by: Thomas Huth --- .gitlab-ci.d/buildtest.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.d/buildtest.yml b/.gitlab-ci.d/buildtest.yml index 6c05c46397..7173749c52 100644 --- a/.gitlab-ci.d/buildtest.yml +++ b/.gitlab-ci.d/buildtest.yml @@ -327,6 +327,7 @@ clang-user: extends: .native_build_job_template needs: job: amd64-debian-user-cross-container + timeout: 70m variables: IMAGE: debian-all-test-cross CONFIGURE_ARGS: --cc=clang --cxx=clang++ --disable-system From f53b033e4cd2e7706df3cca04f3bf3c5ffc6b08c Mon Sep 17 00:00:00 2001 From: Peter Jin Date: Thu, 27 Oct 2022 23:23:41 +0200 Subject: [PATCH 592/705] s390x/css: revert SCSW ctrl/flag bits on error Revert the control and flag bits in the subchannel status word in case the SSCH operation fails with non-zero CC (ditto for CSCH and HSCH). According to POPS, the control and flag bits are only changed if SSCH, CSCH, and HSCH return CC 0, and no other action should be taken otherwise. In order to simulate that after the fact, the bits need to be reverted on non-zero CC. While the do_subchannel_work logic for virtual (virtio) devices will return condition code 0, passthrough (vfio) devices may encounter errors from either the host kernel or real hardware that need to be accounted for after this point. This includes restoring the state of the Subchannel Status Word to reflect the subchannel, as these bits would not be set in the event of a non-zero condition code from the affected instructions. Experimentation has shown that a failure on a START SUBCHANNEL (SSCH) to a passthrough device would leave the subchannel with the START PENDING activity control bit set, thus blocking subsequent SSCH operations in css_do_ssch() until some form of error recovery was undertaken since no interrupt would be expected. Signed-off-by: Peter Jin Message-Id: <20221027212341.2904795-1-pjin@linux.ibm.com> Reviewed-by: Eric Farman Reviewed-by: Matthew Rosato [thuth: Updated the commit description to Eric's suggestion] Signed-off-by: Thomas Huth --- hw/s390x/css.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/hw/s390x/css.c b/hw/s390x/css.c index 7d9523f811..95d1b3a3ce 100644 --- a/hw/s390x/css.c +++ b/hw/s390x/css.c @@ -1522,21 +1522,37 @@ IOInstEnding css_do_xsch(SubchDev *sch) IOInstEnding css_do_csch(SubchDev *sch) { SCHIB *schib = &sch->curr_status; + uint16_t old_scsw_ctrl; + IOInstEnding ccode; if (~(schib->pmcw.flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) { return IOINST_CC_NOT_OPERATIONAL; } + /* + * Save the current scsw.ctrl in case CSCH fails and we need + * to revert the scsw to the status quo ante. + */ + old_scsw_ctrl = schib->scsw.ctrl; + /* Trigger the clear function. */ schib->scsw.ctrl &= ~(SCSW_CTRL_MASK_FCTL | SCSW_CTRL_MASK_ACTL); schib->scsw.ctrl |= SCSW_FCTL_CLEAR_FUNC | SCSW_ACTL_CLEAR_PEND; - return do_subchannel_work(sch); + ccode = do_subchannel_work(sch); + + if (ccode != IOINST_CC_EXPECTED) { + schib->scsw.ctrl = old_scsw_ctrl; + } + + return ccode; } IOInstEnding css_do_hsch(SubchDev *sch) { SCHIB *schib = &sch->curr_status; + uint16_t old_scsw_ctrl; + IOInstEnding ccode; if (~(schib->pmcw.flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) { return IOINST_CC_NOT_OPERATIONAL; @@ -1553,6 +1569,12 @@ IOInstEnding css_do_hsch(SubchDev *sch) return IOINST_CC_BUSY; } + /* + * Save the current scsw.ctrl in case HSCH fails and we need + * to revert the scsw to the status quo ante. + */ + old_scsw_ctrl = schib->scsw.ctrl; + /* Trigger the halt function. */ schib->scsw.ctrl |= SCSW_FCTL_HALT_FUNC; schib->scsw.ctrl &= ~SCSW_FCTL_START_FUNC; @@ -1564,7 +1586,13 @@ IOInstEnding css_do_hsch(SubchDev *sch) } schib->scsw.ctrl |= SCSW_ACTL_HALT_PEND; - return do_subchannel_work(sch); + ccode = do_subchannel_work(sch); + + if (ccode != IOINST_CC_EXPECTED) { + schib->scsw.ctrl = old_scsw_ctrl; + } + + return ccode; } static void css_update_chnmon(SubchDev *sch) @@ -1605,6 +1633,8 @@ static void css_update_chnmon(SubchDev *sch) IOInstEnding css_do_ssch(SubchDev *sch, ORB *orb) { SCHIB *schib = &sch->curr_status; + uint16_t old_scsw_ctrl, old_scsw_flags; + IOInstEnding ccode; if (~(schib->pmcw.flags) & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA)) { return IOINST_CC_NOT_OPERATIONAL; @@ -1626,11 +1656,26 @@ IOInstEnding css_do_ssch(SubchDev *sch, ORB *orb) } sch->orb = *orb; sch->channel_prog = orb->cpa; + + /* + * Save the current scsw.ctrl and scsw.flags in case SSCH fails and we need + * to revert the scsw to the status quo ante. + */ + old_scsw_ctrl = schib->scsw.ctrl; + old_scsw_flags = schib->scsw.flags; + /* Trigger the start function. */ schib->scsw.ctrl |= (SCSW_FCTL_START_FUNC | SCSW_ACTL_START_PEND); schib->scsw.flags &= ~SCSW_FLAGS_MASK_PNO; - return do_subchannel_work(sch); + ccode = do_subchannel_work(sch); + + if (ccode != IOINST_CC_EXPECTED) { + schib->scsw.ctrl = old_scsw_ctrl; + schib->scsw.flags = old_scsw_flags; + } + + return ccode; } static void copy_irb_to_guest(IRB *dest, const IRB *src, const PMCW *pmcw, From 4a8d21ba50fc8625c3bd51dab903872952f95718 Mon Sep 17 00:00:00 2001 From: Matthew Rosato Date: Fri, 28 Oct 2022 15:47:56 -0400 Subject: [PATCH 593/705] s390x/pci: RPCIT second pass when mappings exhausted If we encounter a new mapping while the number of available DMA entries in vfio is 0, we are currently skipping that mapping which is a problem if we manage to free up DMA space after that within the same RPCIT -- we will return to the guest with CC0 and have not mapped everything within the specified range. This issue was uncovered while testing changes to the s390 linux kernel iommu/dma code, where a different usage pattern was employed (new mappings start at the end of the aperture and work back towards the front, making us far more likely to encounter new mappings before invalidated mappings during a global refresh). Fix this by tracking whether any mappings were skipped due to vfio DMA limit hitting 0; when this occurs, we still continue the range and unmap/map anything we can - then we must re-run the range again to pickup anything that was missed. This must occur in a loop until all requests are satisfied (success) or we detect that we are still unable to complete all mappings (return ZPCI_RPCIT_ST_INSUFF_RES). Link: https://lore.kernel.org/linux-s390/20221019144435.369902-1-schnelle@linux.ibm.com/ Fixes: 37fa32de70 ("s390x/pci: Honor DMA limits set by vfio") Reported-by: Niklas Schnelle Signed-off-by: Matthew Rosato Message-Id: <20221028194758.204007-2-mjrosato@linux.ibm.com> Reviewed-by: Eric Farman Signed-off-by: Thomas Huth --- hw/s390x/s390-pci-inst.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c index 20a9bcc7af..7cc4bcf850 100644 --- a/hw/s390x/s390-pci-inst.c +++ b/hw/s390x/s390-pci-inst.c @@ -677,8 +677,9 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra) S390PCIBusDevice *pbdev; S390PCIIOMMU *iommu; S390IOTLBEntry entry; - hwaddr start, end; + hwaddr start, end, sstart; uint32_t dma_avail; + bool again; if (env->psw.mask & PSW_MASK_PSTATE) { s390_program_interrupt(env, PGM_PRIVILEGED, ra); @@ -691,7 +692,7 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra) } fh = env->regs[r1] >> 32; - start = env->regs[r2]; + sstart = start = env->regs[r2]; end = start + env->regs[r2 + 1]; pbdev = s390_pci_find_dev_by_fh(s390_get_phb(), fh); @@ -732,6 +733,9 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra) goto err; } + retry: + start = sstart; + again = false; while (start < end) { error = s390_guest_io_table_walk(iommu->g_iota, start, &entry); if (error) { @@ -739,13 +743,24 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra) } start += entry.len; - while (entry.iova < start && entry.iova < end && - (dma_avail > 0 || entry.perm == IOMMU_NONE)) { - dma_avail = s390_pci_update_iotlb(iommu, &entry); - entry.iova += TARGET_PAGE_SIZE; - entry.translated_addr += TARGET_PAGE_SIZE; + while (entry.iova < start && entry.iova < end) { + if (dma_avail > 0 || entry.perm == IOMMU_NONE) { + dma_avail = s390_pci_update_iotlb(iommu, &entry); + entry.iova += TARGET_PAGE_SIZE; + entry.translated_addr += TARGET_PAGE_SIZE; + } else { + /* + * We are unable to make a new mapping at this time, continue + * on and hopefully free up more space. Then attempt another + * pass. + */ + again = true; + break; + } } } + if (again && dma_avail > 0) + goto retry; err: if (error) { pbdev->state = ZPCI_FS_ERROR; From 1fd396e32288bbf536483c74b68cb3ee86005a9f Mon Sep 17 00:00:00 2001 From: Pierre Morel Date: Thu, 3 Nov 2022 18:01:40 +0100 Subject: [PATCH 594/705] s390x: Register TYPE_S390_CCW_MACHINE properties as class properties Currently, when running 'qemu-system-s390x -M s390-ccw-virtio,help' the s390x-specific properties are not listed anymore. This happens because since commit d8fb7d0969 ("vl: switch -M parsing to keyval") the properties have to be defined at the class level and not at the instance level anymore. Fix it on s390x now, too, by moving the registration of the properties to the class level" Fixes: d8fb7d0969 ("vl: switch -M parsing to keyval") Signed-off-by: Pierre Morel Message-Id: <20221103170150.20789-2-pmorel@linux.ibm.com> [thuth: Add patch description] Signed-off-by: Thomas Huth --- hw/s390x/s390-virtio-ccw.c | 131 +++++++++++++++++++++---------------- 1 file changed, 74 insertions(+), 57 deletions(-) diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index 806de32034..196773c833 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -43,6 +43,7 @@ #include "sysemu/sysemu.h" #include "hw/s390x/pv.h" #include "migration/blocker.h" +#include "qapi/visitor.h" static Error *pv_mig_blocker; @@ -589,38 +590,6 @@ static ram_addr_t s390_fixup_ram_size(ram_addr_t sz) return newsz; } -static void ccw_machine_class_init(ObjectClass *oc, void *data) -{ - MachineClass *mc = MACHINE_CLASS(oc); - NMIClass *nc = NMI_CLASS(oc); - HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc); - S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc); - - s390mc->ri_allowed = true; - s390mc->cpu_model_allowed = true; - s390mc->css_migration_enabled = true; - s390mc->hpage_1m_allowed = true; - mc->init = ccw_init; - mc->reset = s390_machine_reset; - mc->block_default_type = IF_VIRTIO; - mc->no_cdrom = 1; - mc->no_floppy = 1; - mc->no_parallel = 1; - mc->no_sdcard = 1; - mc->max_cpus = S390_MAX_CPUS; - mc->has_hotpluggable_cpus = true; - assert(!mc->get_hotplug_handler); - mc->get_hotplug_handler = s390_get_hotplug_handler; - mc->cpu_index_to_instance_props = s390_cpu_index_to_props; - mc->possible_cpu_arch_ids = s390_possible_cpu_arch_ids; - /* it is overridden with 'host' cpu *in kvm_arch_init* */ - mc->default_cpu_type = S390_CPU_TYPE_NAME("qemu"); - hc->plug = s390_machine_device_plug; - hc->unplug_request = s390_machine_device_unplug_request; - nc->nmi_monitor_handler = s390_nmi; - mc->default_ram_id = "s390.ram"; -} - static inline bool machine_get_aes_key_wrap(Object *obj, Error **errp) { S390CcwMachineState *ms = S390_CCW_MACHINE(obj); @@ -710,19 +679,29 @@ bool hpage_1m_allowed(void) return get_machine_class()->hpage_1m_allowed; } -static char *machine_get_loadparm(Object *obj, Error **errp) +static void machine_get_loadparm(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) { S390CcwMachineState *ms = S390_CCW_MACHINE(obj); + char *str = g_strndup((char *) ms->loadparm, sizeof(ms->loadparm)); - /* make a NUL-terminated string */ - return g_strndup((char *) ms->loadparm, sizeof(ms->loadparm)); + visit_type_str(v, name, &str, errp); + g_free(str); } -static void machine_set_loadparm(Object *obj, const char *val, Error **errp) +static void machine_set_loadparm(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) { S390CcwMachineState *ms = S390_CCW_MACHINE(obj); + char *val; int i; + if (!visit_type_str(v, name, &val, errp)) { + return; + } + for (i = 0; i < sizeof(ms->loadparm) && val[i]; i++) { uint8_t c = qemu_toupper(val[i]); /* mimic HMC */ @@ -740,34 +719,72 @@ static void machine_set_loadparm(Object *obj, const char *val, Error **errp) ms->loadparm[i] = ' '; /* pad right with spaces */ } } -static inline void s390_machine_initfn(Object *obj) -{ - object_property_add_bool(obj, "aes-key-wrap", - machine_get_aes_key_wrap, - machine_set_aes_key_wrap); - object_property_set_description(obj, "aes-key-wrap", - "enable/disable AES key wrapping using the CPACF wrapping key"); - object_property_set_bool(obj, "aes-key-wrap", true, NULL); - object_property_add_bool(obj, "dea-key-wrap", - machine_get_dea_key_wrap, - machine_set_dea_key_wrap); - object_property_set_description(obj, "dea-key-wrap", +static void ccw_machine_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + NMIClass *nc = NMI_CLASS(oc); + HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc); + S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc); + + s390mc->ri_allowed = true; + s390mc->cpu_model_allowed = true; + s390mc->css_migration_enabled = true; + s390mc->hpage_1m_allowed = true; + mc->init = ccw_init; + mc->reset = s390_machine_reset; + mc->block_default_type = IF_VIRTIO; + mc->no_cdrom = 1; + mc->no_floppy = 1; + mc->no_parallel = 1; + mc->no_sdcard = 1; + mc->max_cpus = S390_MAX_CPUS; + mc->has_hotpluggable_cpus = true; + assert(!mc->get_hotplug_handler); + mc->get_hotplug_handler = s390_get_hotplug_handler; + mc->cpu_index_to_instance_props = s390_cpu_index_to_props; + mc->possible_cpu_arch_ids = s390_possible_cpu_arch_ids; + /* it is overridden with 'host' cpu *in kvm_arch_init* */ + mc->default_cpu_type = S390_CPU_TYPE_NAME("qemu"); + hc->plug = s390_machine_device_plug; + hc->unplug_request = s390_machine_device_unplug_request; + nc->nmi_monitor_handler = s390_nmi; + mc->default_ram_id = "s390.ram"; + + object_class_property_add_bool(oc, "aes-key-wrap", + machine_get_aes_key_wrap, + machine_set_aes_key_wrap); + object_class_property_set_description(oc, "aes-key-wrap", + "enable/disable AES key wrapping using the CPACF wrapping key"); + + object_class_property_add_bool(oc, "dea-key-wrap", + machine_get_dea_key_wrap, + machine_set_dea_key_wrap); + object_class_property_set_description(oc, "dea-key-wrap", "enable/disable DEA key wrapping using the CPACF wrapping key"); - object_property_set_bool(obj, "dea-key-wrap", true, NULL); - object_property_add_str(obj, "loadparm", - machine_get_loadparm, machine_set_loadparm); - object_property_set_description(obj, "loadparm", + + object_class_property_add(oc, "loadparm", "loadparm", + machine_get_loadparm, machine_set_loadparm, + NULL, NULL); + object_class_property_set_description(oc, "loadparm", "Up to 8 chars in set of [A-Za-z0-9. ] (lower case chars converted" " to upper case) to pass to machine loader, boot manager," " and guest kernel"); - object_property_add_bool(obj, "zpcii-disable", - machine_get_zpcii_disable, - machine_set_zpcii_disable); - object_property_set_description(obj, "zpcii-disable", + object_class_property_add_bool(oc, "zpcii-disable", + machine_get_zpcii_disable, + machine_set_zpcii_disable); + object_class_property_set_description(oc, "zpcii-disable", "disable zPCI interpretation facilties"); - object_property_set_bool(obj, "zpcii-disable", false, NULL); +} + +static inline void s390_machine_initfn(Object *obj) +{ + S390CcwMachineState *ms = S390_CCW_MACHINE(obj); + + ms->aes_key_wrap = true; + ms->dea_key_wrap = true; + ms->zpcii_disable = false; } static const TypeInfo ccw_machine_info = { From 6393b29966fce3c0e47746a9646ae439e7fd0728 Mon Sep 17 00:00:00 2001 From: Pierre Morel Date: Thu, 3 Nov 2022 18:01:41 +0100 Subject: [PATCH 595/705] s390x/cpu topology: add max_threads machine class attribute The S390 CPU topology accepts the smp.threads argument while in reality it does not effectively allow multthreading. Let's keep this behavior for machines older than 7.2 and refuse to use threads in newer machines until multithreading is really exposed to the guest by the machine. Signed-off-by: Pierre Morel Message-Id: <20221103170150.20789-3-pmorel@linux.ibm.com> [thuth: Small fixes to the commit description] Signed-off-by: Thomas Huth --- hw/s390x/s390-virtio-ccw.c | 11 +++++++++++ include/hw/s390x/s390-virtio-ccw.h | 1 + 2 files changed, 12 insertions(+) diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index 196773c833..560ddbb6fb 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -85,8 +85,15 @@ out: static void s390_init_cpus(MachineState *machine) { MachineClass *mc = MACHINE_GET_CLASS(machine); + S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc); int i; + if (machine->smp.threads > s390mc->max_threads) { + error_report("S390 does not support more than %d threads.", + s390mc->max_threads); + exit(1); + } + /* initialize possible_cpus */ mc->possible_cpu_arch_ids(machine); @@ -731,6 +738,7 @@ static void ccw_machine_class_init(ObjectClass *oc, void *data) s390mc->cpu_model_allowed = true; s390mc->css_migration_enabled = true; s390mc->hpage_1m_allowed = true; + s390mc->max_threads = 1; mc->init = ccw_init; mc->reset = s390_machine_reset; mc->block_default_type = IF_VIRTIO; @@ -859,8 +867,11 @@ static void ccw_machine_7_1_instance_options(MachineState *machine) static void ccw_machine_7_1_class_options(MachineClass *mc) { + S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc); + ccw_machine_7_2_class_options(mc); compat_props_add(mc->compat_props, hw_compat_7_1, hw_compat_7_1_len); + s390mc->max_threads = S390_MAX_CPUS; } DEFINE_CCW_MACHINE(7_1, "7.1", false); diff --git a/include/hw/s390x/s390-virtio-ccw.h b/include/hw/s390x/s390-virtio-ccw.h index 8a0090a071..4f8a39abda 100644 --- a/include/hw/s390x/s390-virtio-ccw.h +++ b/include/hw/s390x/s390-virtio-ccw.h @@ -40,6 +40,7 @@ struct S390CcwMachineClass { bool cpu_model_allowed; bool css_migration_enabled; bool hpage_1m_allowed; + int max_threads; }; /* runtime-instrumentation allowed by the machine */ From c8885b8839dfe39ee7b02dedcbf79af9087c9079 Mon Sep 17 00:00:00 2001 From: Rui Wang Date: Mon, 7 Nov 2022 10:45:25 +0800 Subject: [PATCH 596/705] target/loongarch: Separate the hardware flags into MMU index and PLV Regarding the patchset v3 has been merged into main line, and not approved, this patch updates to patchset v4. Fixes: b4bda200 ("target/loongarch: Adjust the layout of hardware flags bit fields") Link: https://lists.nongnu.org/archive/html/qemu-devel/2022-11/msg00808.html Reviewed-by: Richard Henderson Signed-off-by: Rui Wang Message-Id: <20221107024526.702297-2-wangrui@loongson.cn> Signed-off-by: Song Gao --- target/loongarch/cpu.h | 18 +++++++++--------- .../insn_trans/trans_privileged.c.inc | 4 ++-- target/loongarch/tlb_helper.c | 4 ++-- target/loongarch/translate.c | 5 +++-- target/loongarch/translate.h | 3 ++- 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index 08c1f6baa1..e15c633b0b 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -374,21 +374,21 @@ struct LoongArchCPUClass { * 0 for kernel mode, 3 for user mode. * Define an extra index for DA(direct addressing) mode. */ -#define MMU_KERNEL_IDX 0 -#define MMU_USER_IDX 3 -#define MMU_DA_IDX 4 +#define MMU_PLV_KERNEL 0 +#define MMU_PLV_USER 3 +#define MMU_IDX_KERNEL MMU_PLV_KERNEL +#define MMU_IDX_USER MMU_PLV_USER +#define MMU_IDX_DA 4 static inline int cpu_mmu_index(CPULoongArchState *env, bool ifetch) { #ifdef CONFIG_USER_ONLY - return MMU_USER_IDX; + return MMU_IDX_USER; #else - uint8_t pg = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG); - - if (!pg) { - return MMU_DA_IDX; + if (FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG)) { + return FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV); } - return FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV); + return MMU_IDX_DA; #endif } diff --git a/target/loongarch/insn_trans/trans_privileged.c.inc b/target/loongarch/insn_trans/trans_privileged.c.inc index ff3a6d95ae..40f82becb0 100644 --- a/target/loongarch/insn_trans/trans_privileged.c.inc +++ b/target/loongarch/insn_trans/trans_privileged.c.inc @@ -159,7 +159,7 @@ static const CSRInfo csr_info[] = { static bool check_plv(DisasContext *ctx) { - if (ctx->mem_idx == MMU_USER_IDX) { + if (ctx->plv == MMU_PLV_USER) { generate_exception(ctx, EXCCODE_IPE); return true; } @@ -335,7 +335,7 @@ TRANS(iocsrwr_d, gen_iocsrwr, gen_helper_iocsrwr_d) static void check_mmu_idx(DisasContext *ctx) { - if (ctx->mem_idx != MMU_DA_IDX) { + if (ctx->mem_idx != MMU_IDX_DA) { tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next + 4); ctx->base.is_jmp = DISAS_EXIT; } diff --git a/target/loongarch/tlb_helper.c b/target/loongarch/tlb_helper.c index d2f8fb0c60..c6d1de50fe 100644 --- a/target/loongarch/tlb_helper.c +++ b/target/loongarch/tlb_helper.c @@ -170,8 +170,8 @@ static int get_physical_address(CPULoongArchState *env, hwaddr *physical, int *prot, target_ulong address, MMUAccessType access_type, int mmu_idx) { - int user_mode = mmu_idx == MMU_USER_IDX; - int kernel_mode = mmu_idx == MMU_KERNEL_IDX; + int user_mode = mmu_idx == MMU_IDX_USER; + int kernel_mode = mmu_idx == MMU_IDX_KERNEL; uint32_t plv, base_c, base_v; int64_t addr_high; uint8_t da = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, DA); diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c index 31462b2b61..38ced69803 100644 --- a/target/loongarch/translate.c +++ b/target/loongarch/translate.c @@ -75,10 +75,11 @@ static void loongarch_tr_init_disas_context(DisasContextBase *dcbase, DisasContext *ctx = container_of(dcbase, DisasContext, base); ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK; + ctx->plv = ctx->base.tb->flags & HW_FLAGS_PLV_MASK; if (ctx->base.tb->flags & HW_FLAGS_CRMD_PG) { - ctx->mem_idx = ctx->base.tb->flags & HW_FLAGS_PLV_MASK; + ctx->mem_idx = ctx->plv; } else { - ctx->mem_idx = MMU_DA_IDX; + ctx->mem_idx = MMU_IDX_DA; } /* Bound the number of insns to execute to those left on the page. */ diff --git a/target/loongarch/translate.h b/target/loongarch/translate.h index 9cc12512d1..6d2e382e8b 100644 --- a/target/loongarch/translate.h +++ b/target/loongarch/translate.h @@ -29,7 +29,8 @@ typedef struct DisasContext { DisasContextBase base; target_ulong page_start; uint32_t opcode; - int mem_idx; + uint16_t mem_idx; + uint16_t plv; TCGv zero; /* Space for 3 operands plus 1 extra for address computation. */ TCGv temp[4]; From e913bace61c539a88feb489b424554ebb2d5d3a3 Mon Sep 17 00:00:00 2001 From: Rui Wang Date: Mon, 7 Nov 2022 10:45:26 +0800 Subject: [PATCH 597/705] target/loongarch: Fix return value of CHECK_FPE Regarding the patchset v3 has been merged into main line, and not approved, this patch updates to patchset v4. Fixes: 2419978c ("target/loongarch: Fix emulation of float-point disable exception") Link: https://lists.nongnu.org/archive/html/qemu-devel/2022-11/msg00808.html Reviewed-by: Richard Henderson Signed-off-by: Rui Wang Message-Id: <20221107024526.702297-3-wangrui@loongson.cn> Signed-off-by: Song Gao --- target/loongarch/insn_trans/trans_farith.c.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/loongarch/insn_trans/trans_farith.c.inc b/target/loongarch/insn_trans/trans_farith.c.inc index e2dec75dfb..7081fbb89b 100644 --- a/target/loongarch/insn_trans/trans_farith.c.inc +++ b/target/loongarch/insn_trans/trans_farith.c.inc @@ -7,7 +7,7 @@ #define CHECK_FPE do { \ if ((ctx->base.tb->flags & HW_FLAGS_EUEN_FPE) == 0) { \ generate_exception(ctx, EXCCODE_FPD); \ - return false; \ + return true; \ } \ } while (0) #else From 3cd0c8992f1c399191772e15177e2a57a9be8051 Mon Sep 17 00:00:00 2001 From: Miguel Luis Date: Tue, 11 Oct 2022 18:17:27 +0000 Subject: [PATCH 598/705] tests/acpi: virt: allow acpi MADT and FADT changes Step 3 from bios-tables-test.c documented procedure. Signed-off-by: Miguel Luis Message-Id: <20221011181730.10885-2-miguel.luis@oracle.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Acked-by: Ani Sinha --- tests/qtest/bios-tables-test-allowed-diff.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h index dfb8523c8b..8dc50f7a8a 100644 --- a/tests/qtest/bios-tables-test-allowed-diff.h +++ b/tests/qtest/bios-tables-test-allowed-diff.h @@ -1 +1,7 @@ /* List of comma-separated changed AML files to ignore */ +"tests/data/acpi/virt/FACP", +"tests/data/acpi/virt/FACP.numamem", +"tests/data/acpi/virt/FACP.memhp", +"tests/data/acpi/virt/APIC", +"tests/data/acpi/virt/APIC.memhp", +"tests/data/acpi/virt/APIC.numamem", From 4496d1d3ebe998f94dfd7b47a22c1522da61dfa4 Mon Sep 17 00:00:00 2001 From: Miguel Luis Date: Tue, 11 Oct 2022 18:17:28 +0000 Subject: [PATCH 599/705] acpi: fadt: support revision 6.0 of the ACPI specification Update the Fixed ACPI Description Table (FADT) to revision 6.0 of the ACPI specification adding the field "Hypervisor Vendor Identity". This field's description states the following: "64-bit identifier of hypervisor vendor. All bytes in this field are considered part of the vendor identity. These identifiers are defined independently by the vendors themselves, usually following the name of the hypervisor product. Version information should NOT be included in this field - this shall simply denote the vendor's name or identifier. Version information can be communicated through a supplemental vendor-specific hypervisor API. Firmware implementers would place zero bytes into this field, denoting that no hypervisor is present in the actual firmware." Signed-off-by: Miguel Luis Reviewed-by: Ani Sinha Message-Id: <20221011181730.10885-3-miguel.luis@oracle.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 13 ++++++++++--- hw/arm/virt-acpi-build.c | 10 +++++----- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index e6bfac95c7..42feb4d4d7 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -2070,7 +2070,7 @@ void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms, acpi_table_end(linker, &table); } -/* build rev1/rev3/rev5.1 FADT */ +/* build rev1/rev3/rev5.1/rev6.0 FADT */ void build_fadt(GArray *tbl, BIOSLinker *linker, const AcpiFadtData *f, const char *oem_id, const char *oem_table_id) { @@ -2193,8 +2193,15 @@ void build_fadt(GArray *tbl, BIOSLinker *linker, const AcpiFadtData *f, /* SLEEP_STATUS_REG */ build_append_gas_from_struct(tbl, &f->sleep_sts); - /* TODO: extra fields need to be added to support revisions above rev5 */ - assert(f->rev == 5); + if (f->rev == 5) { + goto done; + } + + /* Hypervisor Vendor Identity */ + build_append_padded_str(tbl, "QEMU", 8, '\0'); + + /* TODO: extra fields need to be added to support revisions above rev6 */ + assert(f->rev == 6); done: acpi_table_end(linker, &table); diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 13c6e3e468..e5377744f3 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -808,13 +808,13 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) } /* FADT */ -static void build_fadt_rev5(GArray *table_data, BIOSLinker *linker, +static void build_fadt_rev6(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms, unsigned dsdt_tbl_offset) { - /* ACPI v5.1 */ + /* ACPI v6.0 */ AcpiFadtData fadt = { - .rev = 5, - .minor_ver = 1, + .rev = 6, + .minor_ver = 0, .flags = 1 << ACPI_FADT_F_HW_REDUCED_ACPI, .xdsdt_tbl_offset = &dsdt_tbl_offset, }; @@ -944,7 +944,7 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables) /* FADT MADT PPTT GTDT MCFG SPCR DBG2 pointed to by RSDT */ acpi_add_table(table_offsets, tables_blob); - build_fadt_rev5(tables_blob, tables->linker, vms, dsdt); + build_fadt_rev6(tables_blob, tables->linker, vms, dsdt); acpi_add_table(table_offsets, tables_blob); build_madt(tables_blob, tables->linker, vms); From 7fe4c35ceae7e366649e88e1d17ad892b4b4c04f Mon Sep 17 00:00:00 2001 From: Miguel Luis Date: Tue, 11 Oct 2022 18:17:29 +0000 Subject: [PATCH 600/705] acpi: arm/virt: madt: bump to revision 4 accordingly to ACPI 6.0 Errata A MADT has been updated with the GIC Structures from ACPI 6.0 Errata A and so MADT revision and GICC Structure must be updated also. Fixes: 37f33084ed2e ("acpi: arm/virt: madt: use build_append_int_noprefix() API to compose MADT table") Signed-off-by: Miguel Luis Reviewed-by: Ani Sinha Message-Id: <20221011181730.10885-4-miguel.luis@oracle.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/arm/virt-acpi-build.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index e5377744f3..da9e41e72b 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -685,7 +685,7 @@ build_dbg2(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) }; /* - * ACPI spec, Revision 5.1 Errata A + * ACPI spec, Revision 6.0 Errata A * 5.2.12 Multiple APIC Description Table (MADT) */ static void build_append_gicr(GArray *table_data, uint64_t base, uint32_t size) @@ -704,7 +704,7 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) int i; VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms); const MemMapEntry *memmap = vms->memmap; - AcpiTable table = { .sig = "APIC", .rev = 3, .oem_id = vms->oem_id, + AcpiTable table = { .sig = "APIC", .rev = 4, .oem_id = vms->oem_id, .oem_table_id = vms->oem_table_id }; acpi_table_begin(&table, table_data); @@ -739,7 +739,7 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) /* 5.2.12.14 GIC Structure */ build_append_int_noprefix(table_data, 0xB, 1); /* Type */ - build_append_int_noprefix(table_data, 76, 1); /* Length */ + build_append_int_noprefix(table_data, 80, 1); /* Length */ build_append_int_noprefix(table_data, 0, 2); /* Reserved */ build_append_int_noprefix(table_data, i, 4); /* GIC ID */ build_append_int_noprefix(table_data, i, 4); /* ACPI Processor UID */ @@ -759,6 +759,10 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) build_append_int_noprefix(table_data, 0, 8); /* GICR Base Address*/ /* MPIDR */ build_append_int_noprefix(table_data, armcpu->mp_affinity, 8); + /* Processor Power Efficiency Class */ + build_append_int_noprefix(table_data, 0, 1); + /* Reserved */ + build_append_int_noprefix(table_data, 0, 3); } if (vms->gic_version != VIRT_GIC_VERSION_2) { @@ -770,12 +774,6 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) } if (its_class_name() && !vmc->no_its) { - /* - * FIXME: Structure is from Revision 6.0 where 'GIC Structure' - * has additional fields on top of implemented 5.1 Errata A, - * to make it consistent with v6.0 we need to bump everything - * to v6.0 - */ /* * ACPI spec, Revision 6.0 Errata A * (original 6.0 definition has invalid Length) From 535824f596d2e767a8824dde43ec11b6dfa9286a Mon Sep 17 00:00:00 2001 From: Miguel Luis Date: Tue, 11 Oct 2022 18:17:30 +0000 Subject: [PATCH 601/705] tests/acpi: virt: update ACPI MADT and FADT binaries Step 6 & 7 of the bios-tables-test.c documented procedure. Differences between disassembled ASL files for MADT: @@ -11,9 +11,9 @@ */ [000h 0000 4] Signature : "APIC" [Multiple APIC Description Table (MADT)] -[004h 0004 4] Table Length : 000000A8 -[008h 0008 1] Revision : 03 -[009h 0009 1] Checksum : 50 +[004h 0004 4] Table Length : 000000AC +[008h 0008 1] Revision : 04 +[009h 0009 1] Checksum : 47 [00Ah 0010 6] Oem ID : "BOCHS " [010h 0016 8] Oem Table ID : "BXPC " [018h 0024 4] Oem Revision : 00000001 @@ -34,7 +34,7 @@ [041h 0065 3] Reserved : 000000 [044h 0068 1] Subtable Type : 0B [Generic Interrupt Controller] -[045h 0069 1] Length : 4C +[045h 0069 1] Length : 50 [046h 0070 2] Reserved : 0000 [048h 0072 4] CPU Interface Number : 00000000 [04Ch 0076 4] Processor UID : 00000000 @@ -51,28 +51,29 @@ [07Ch 0124 4] Virtual GIC Interrupt : 00000000 [080h 0128 8] Redistributor Base Address : 0000000000000000 [088h 0136 8] ARM MPIDR : 0000000000000000 -/**** ACPI subtable terminates early - may be older version (dump table) */ +[090h 0144 1] Efficiency Class : 00 +[091h 0145 3] Reserved : 000000 -[090h 0144 1] Subtable Type : 0D [Generic MSI Frame] -[091h 0145 1] Length : 18 -[092h 0146 2] Reserved : 0000 -[094h 0148 4] MSI Frame ID : 00000000 -[098h 0152 8] Base Address : 0000000008020000 -[0A0h 0160 4] Flags (decoded below) : 00000001 +[094h 0148 1] Subtable Type : 0D [Generic MSI Frame] +[095h 0149 1] Length : 18 +[096h 0150 2] Reserved : 0000 +[098h 0152 4] MSI Frame ID : 00000000 +[09Ch 0156 8] Base Address : 0000000008020000 +[0A4h 0164 4] Flags (decoded below) : 00000001 Select SPI : 1 -[0A4h 0164 2] SPI Count : 0040 -[0A6h 0166 2] SPI Base : 0050 +[0A8h 0168 2] SPI Count : 0040 +[0AAh 0170 2] SPI Base : 0050 -Raw Table Data: Length 168 (0xA8) +Raw Table Data: Length 172 (0xAC) - 0000: 41 50 49 43 A8 00 00 00 03 50 42 4F 43 48 53 20 // APIC.....PBOCHS + 0000: 41 50 49 43 AC 00 00 00 04 47 42 4F 43 48 53 20 // APIC.....GBOCHS 0010: 42 58 50 43 20 20 20 20 01 00 00 00 42 58 50 43 // BXPC ....BXPC 0020: 01 00 00 00 00 00 00 00 00 00 00 00 0C 18 00 00 // ................ 0030: 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 00 // ................ - 0040: 02 00 00 00 0B 4C 00 00 00 00 00 00 00 00 00 00 // .....L.......... + 0040: 02 00 00 00 0B 50 00 00 00 00 00 00 00 00 00 00 // .....P.......... 0050: 01 00 00 00 00 00 00 00 17 00 00 00 00 00 00 00 // ................ 0060: 00 00 00 00 00 00 01 08 00 00 00 00 00 00 04 08 // ................ 0070: 00 00 00 00 00 00 03 08 00 00 00 00 00 00 00 00 // ................ 0080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................ - 0090: 0D 18 00 00 00 00 00 00 00 00 02 08 00 00 00 00 // ................ - 00A0: 01 00 00 00 40 00 50 00 // ....@.P. + 0090: 00 00 00 00 0D 18 00 00 00 00 00 00 00 00 02 08 // ................ + 00A0: 00 00 00 00 01 00 00 00 40 00 50 00 // ........@.P. Differences between disassembled ASL files for FADT: @@ -11,9 +11,9 @@ */ [000h 0000 4] Signature : "FACP" [Fixed ACPI Description Table (FADT)] -[004h 0004 4] Table Length : 0000010C -[008h 0008 1] Revision : 05 -[009h 0009 1] Checksum : 55 +[004h 0004 4] Table Length : 00000114 +[008h 0008 1] Revision : 06 +[009h 0009 1] Checksum : 15 [00Ah 0010 6] Oem ID : "BOCHS " [010h 0016 8] Oem Table ID : "BXPC " [018h 0024 4] Oem Revision : 00000001 @@ -99,7 +99,7 @@ PSCI Compliant : 1 Must use HVC for PSCI : 1 -[083h 0131 1] FADT Minor Revision : 01 +[083h 0131 1] FADT Minor Revision : 00 [084h 0132 8] FACS Address : 0000000000000000 [08Ch 0140 8] DSDT Address : 0000000000000000 [094h 0148 12] PM1A Event Block : [Generic Address Structure] @@ -173,11 +173,11 @@ [103h 0259 1] Encoded Access Width : 00 [Undefined/Legacy] [104h 0260 8] Address : 0000000000000000 -/**** ACPI table terminates in the middle of a data structure! (dump table) */ +[10Ch 0268 8] Hypervisor ID : 00000000554D4551 -Raw Table Data: Length 268 (0x10C) +Raw Table Data: Length 276 (0x114) - 0000: 46 41 43 50 0C 01 00 00 05 55 42 4F 43 48 53 20 // FACP.....UBOCHS + 0000: 46 41 43 50 14 01 00 00 06 15 42 4F 43 48 53 20 // FACP......BOCHS 0010: 42 58 50 43 20 20 20 20 01 00 00 00 42 58 50 43 // BXPC ....BXPC 0020: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................ 0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................ @@ -185,7 +185,7 @@ Raw Table Data: Length 268 (0x10C) 0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................ 0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................ 0070: 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................ - 0080: 00 03 00 01 00 00 00 00 00 00 00 00 00 00 00 00 // ................ + 0080: 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................ 0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................ 00A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................ 00B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................ @@ -193,4 +193,5 @@ Raw Table Data: Length 268 (0x10C) 00D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................ 00E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................ 00F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................ - 0100: 00 00 00 00 00 00 00 00 00 00 00 00 // ............ + 0100: 00 00 00 00 00 00 00 00 00 00 00 00 51 45 4D 55 // ............QEMU + 0110: 00 00 00 00 // .... Signed-off-by: Miguel Luis Message-Id: <20221011181730.10885-5-miguel.luis@oracle.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Acked-by: Ani Sinha --- tests/data/acpi/virt/APIC | Bin 168 -> 172 bytes tests/data/acpi/virt/APIC.memhp | Bin 168 -> 172 bytes tests/data/acpi/virt/APIC.numamem | Bin 168 -> 172 bytes tests/data/acpi/virt/FACP | Bin 268 -> 276 bytes tests/data/acpi/virt/FACP.memhp | Bin 268 -> 276 bytes tests/data/acpi/virt/FACP.numamem | Bin 268 -> 276 bytes tests/qtest/bios-tables-test-allowed-diff.h | 6 ------ 7 files changed, 6 deletions(-) diff --git a/tests/data/acpi/virt/APIC b/tests/data/acpi/virt/APIC index 023f15f12e74fb9a3a6d3d9dc994541016947d6a..179d274770a23209b949c90a929525e22368568b 100644 GIT binary patch delta 26 hcmZ3%xQ3C-F~HM#4FdxMi~B?_YsP?yZeA06WB^*d2KE2| delta 26 icmZ3(xPp<(F~HM#1p@;EbHGF{Yet`mZeA0oNB{s@&<6Sd diff --git a/tests/data/acpi/virt/APIC.memhp b/tests/data/acpi/virt/APIC.memhp index 023f15f12e74fb9a3a6d3d9dc994541016947d6a..179d274770a23209b949c90a929525e22368568b 100644 GIT binary patch delta 26 hcmZ3%xQ3C-F~HM#4FdxMi~B?_YsP?yZeA06WB^*d2KE2| delta 26 icmZ3(xPp<(F~HM#1p@;EbHGF{Yet`mZeA0oNB{s@&<6Sd diff --git a/tests/data/acpi/virt/APIC.numamem b/tests/data/acpi/virt/APIC.numamem index 023f15f12e74fb9a3a6d3d9dc994541016947d6a..179d274770a23209b949c90a929525e22368568b 100644 GIT binary patch delta 26 hcmZ3%xQ3C-F~HM#4FdxMi~B?_YsP?yZeA06WB^*d2KE2| delta 26 icmZ3(xPp<(F~HM#1p@;EbHGF{Yet`mZeA0oNB{s@&<6Sd diff --git a/tests/data/acpi/virt/FACP b/tests/data/acpi/virt/FACP index 1f764220f8533c427168e80ccf298604826a00b4..ac05c35a69451519bd1152c54d1e741af36390f5 100644 GIT binary patch delta 33 ncmeBSn!?28=I9(C!pOkDCOVO;a^j?_i3a=}fv&!x3_t(?fr|$^ delta 26 hcmbQj)WgK(=I9*2!^ptE8ak1yl96%Z#OjF#yZ}u&1~C8t diff --git a/tests/data/acpi/virt/FACP.memhp b/tests/data/acpi/virt/FACP.memhp index 1f764220f8533c427168e80ccf298604826a00b4..ac05c35a69451519bd1152c54d1e741af36390f5 100644 GIT binary patch delta 33 ncmeBSn!?28=I9(C!pOkDCOVO;a^j?_i3a=}fv&!x3_t(?fr|$^ delta 26 hcmbQj)WgK(=I9*2!^ptE8ak1yl96%Z#OjF#yZ}u&1~C8t diff --git a/tests/data/acpi/virt/FACP.numamem b/tests/data/acpi/virt/FACP.numamem index 1f764220f8533c427168e80ccf298604826a00b4..ac05c35a69451519bd1152c54d1e741af36390f5 100644 GIT binary patch delta 33 ncmeBSn!?28=I9(C!pOkDCOVO;a^j?_i3a=}fv&!x3_t(?fr|$^ delta 26 hcmbQj)WgK(=I9*2!^ptE8ak1yl96%Z#OjF#yZ}u&1~C8t diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h index 8dc50f7a8a..dfb8523c8b 100644 --- a/tests/qtest/bios-tables-test-allowed-diff.h +++ b/tests/qtest/bios-tables-test-allowed-diff.h @@ -1,7 +1 @@ /* List of comma-separated changed AML files to ignore */ -"tests/data/acpi/virt/FACP", -"tests/data/acpi/virt/FACP.numamem", -"tests/data/acpi/virt/FACP.memhp", -"tests/data/acpi/virt/APIC", -"tests/data/acpi/virt/APIC.memhp", -"tests/data/acpi/virt/APIC.numamem", From 5fb52f6cc8f621f2e51d181d81401d14e4d45102 Mon Sep 17 00:00:00 2001 From: Huai-Cheng Kuo Date: Fri, 14 Oct 2022 16:10:41 +0100 Subject: [PATCH 602/705] hw/pci: PCIe Data Object Exchange emulation Emulation of PCIe Data Object Exchange (DOE) PCIE Base Specification r6.0 6.3 Data Object Exchange Supports multiple DOE PCIe Extended Capabilities for a single PCIe device. For each capability, a static array of DOEProtocol should be passed to pcie_doe_init(). The protocols in that array will be registered under the DOE capability structure. For each protocol, vendor ID, type, and corresponding callback function (handle_request()) should be implemented. This callback function represents how the DOE request for corresponding protocol will be handled. pcie_doe_{read/write}_config() must be appended to corresponding PCI device's config_read/write() handler to enable DOE access. In pcie_doe_read_config(), false will be returned if pci_config_read() offset is not within DOE capability range. In pcie_doe_write_config(), the function will have no affect if the address is not within the related DOE PCIE extended capability. Signed-off-by: Huai-Cheng Kuo Signed-off-by: Chris Browy Signed-off-by: Jonathan Cameron Message-Id: <20221014151045.24781-2-Jonathan.Cameron@huawei.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- MAINTAINERS | 7 + hw/pci/meson.build | 1 + hw/pci/pcie_doe.c | 367 +++++++++++++++++++++++++++++++++++++ include/hw/pci/pci_ids.h | 3 + include/hw/pci/pcie.h | 1 + include/hw/pci/pcie_doe.h | 123 +++++++++++++ include/hw/pci/pcie_regs.h | 4 + 7 files changed, 506 insertions(+) create mode 100644 hw/pci/pcie_doe.c create mode 100644 include/hw/pci/pcie_doe.h diff --git a/MAINTAINERS b/MAINTAINERS index 07df572adf..8b7d49b089 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1835,6 +1835,13 @@ F: qapi/pci.json F: docs/pci* F: docs/specs/*pci* +PCIE DOE +M: Huai-Cheng Kuo +M: Chris Browy +S: Supported +F: include/hw/pci/pcie_doe.h +F: hw/pci/pcie_doe.c + ACPI/SMBIOS M: Michael S. Tsirkin M: Igor Mammedov diff --git a/hw/pci/meson.build b/hw/pci/meson.build index bcc9c75919..5aff7ed1c6 100644 --- a/hw/pci/meson.build +++ b/hw/pci/meson.build @@ -13,6 +13,7 @@ pci_ss.add(files( # allow plugging PCIe devices into PCI buses, include them even if # CONFIG_PCI_EXPRESS=n. pci_ss.add(files('pcie.c', 'pcie_aer.c')) +pci_ss.add(files('pcie_doe.c')) softmmu_ss.add(when: 'CONFIG_PCI_EXPRESS', if_true: files('pcie_port.c', 'pcie_host.c')) softmmu_ss.add_all(when: 'CONFIG_PCI', if_true: pci_ss) diff --git a/hw/pci/pcie_doe.c b/hw/pci/pcie_doe.c new file mode 100644 index 0000000000..2210f86968 --- /dev/null +++ b/hw/pci/pcie_doe.c @@ -0,0 +1,367 @@ +/* + * PCIe Data Object Exchange + * + * Copyright (C) 2021 Avery Design Systems, Inc. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "qemu/error-report.h" +#include "qapi/error.h" +#include "qemu/range.h" +#include "hw/pci/pci.h" +#include "hw/pci/pcie.h" +#include "hw/pci/pcie_doe.h" +#include "hw/pci/msi.h" +#include "hw/pci/msix.h" + +#define DWORD_BYTE 4 + +typedef struct DoeDiscoveryReq { + DOEHeader header; + uint8_t index; + uint8_t reserved[3]; +} QEMU_PACKED DoeDiscoveryReq; + +typedef struct DoeDiscoveryRsp { + DOEHeader header; + uint16_t vendor_id; + uint8_t data_obj_type; + uint8_t next_index; +} QEMU_PACKED DoeDiscoveryRsp; + +static bool pcie_doe_discovery(DOECap *doe_cap) +{ + DoeDiscoveryReq *req = pcie_doe_get_write_mbox_ptr(doe_cap); + DoeDiscoveryRsp rsp; + uint8_t index = req->index; + DOEProtocol *prot; + + /* Discard request if length does not match DoeDiscoveryReq */ + if (pcie_doe_get_obj_len(req) < + DIV_ROUND_UP(sizeof(DoeDiscoveryReq), DWORD_BYTE)) { + return false; + } + + rsp.header = (DOEHeader) { + .vendor_id = PCI_VENDOR_ID_PCI_SIG, + .data_obj_type = PCI_SIG_DOE_DISCOVERY, + .length = DIV_ROUND_UP(sizeof(DoeDiscoveryRsp), DWORD_BYTE), + }; + + /* Point to the requested protocol, index 0 must be Discovery */ + if (index == 0) { + rsp.vendor_id = PCI_VENDOR_ID_PCI_SIG; + rsp.data_obj_type = PCI_SIG_DOE_DISCOVERY; + } else { + if (index < doe_cap->protocol_num) { + prot = &doe_cap->protocols[index - 1]; + rsp.vendor_id = prot->vendor_id; + rsp.data_obj_type = prot->data_obj_type; + } else { + rsp.vendor_id = 0xFFFF; + rsp.data_obj_type = 0xFF; + } + } + + if (index + 1 == doe_cap->protocol_num) { + rsp.next_index = 0; + } else { + rsp.next_index = index + 1; + } + + pcie_doe_set_rsp(doe_cap, &rsp); + + return true; +} + +static void pcie_doe_reset_mbox(DOECap *st) +{ + st->read_mbox_idx = 0; + st->read_mbox_len = 0; + st->write_mbox_len = 0; + + memset(st->read_mbox, 0, PCI_DOE_DW_SIZE_MAX * DWORD_BYTE); + memset(st->write_mbox, 0, PCI_DOE_DW_SIZE_MAX * DWORD_BYTE); +} + +void pcie_doe_init(PCIDevice *dev, DOECap *doe_cap, uint16_t offset, + DOEProtocol *protocols, bool intr, uint16_t vec) +{ + pcie_add_capability(dev, PCI_EXT_CAP_ID_DOE, 0x1, offset, + PCI_DOE_SIZEOF); + + doe_cap->pdev = dev; + doe_cap->offset = offset; + + if (intr && (msi_present(dev) || msix_present(dev))) { + doe_cap->cap.intr = intr; + doe_cap->cap.vec = vec; + } + + doe_cap->write_mbox = g_malloc0(PCI_DOE_DW_SIZE_MAX * DWORD_BYTE); + doe_cap->read_mbox = g_malloc0(PCI_DOE_DW_SIZE_MAX * DWORD_BYTE); + + pcie_doe_reset_mbox(doe_cap); + + doe_cap->protocols = protocols; + for (; protocols->vendor_id; protocols++) { + doe_cap->protocol_num++; + } + assert(doe_cap->protocol_num < PCI_DOE_PROTOCOL_NUM_MAX); + + /* Increment to allow for the discovery protocol */ + doe_cap->protocol_num++; +} + +void pcie_doe_fini(DOECap *doe_cap) +{ + g_free(doe_cap->read_mbox); + g_free(doe_cap->write_mbox); + g_free(doe_cap); +} + +uint32_t pcie_doe_build_protocol(DOEProtocol *p) +{ + return DATA_OBJ_BUILD_HEADER1(p->vendor_id, p->data_obj_type); +} + +void *pcie_doe_get_write_mbox_ptr(DOECap *doe_cap) +{ + return doe_cap->write_mbox; +} + +/* + * Copy the response to read mailbox buffer + * This might be called in self-defined handle_request() if a DOE response is + * required in the corresponding protocol + */ +void pcie_doe_set_rsp(DOECap *doe_cap, void *rsp) +{ + uint32_t len = pcie_doe_get_obj_len(rsp); + + memcpy(doe_cap->read_mbox + doe_cap->read_mbox_len, rsp, len * DWORD_BYTE); + doe_cap->read_mbox_len += len; +} + +uint32_t pcie_doe_get_obj_len(void *obj) +{ + uint32_t len; + + if (!obj) { + return 0; + } + + /* Only lower 18 bits are valid */ + len = DATA_OBJ_LEN_MASK(((DOEHeader *)obj)->length); + + /* PCIe r6.0 Table 6.29: a value of 00000h indicates 2^18 DW */ + return (len) ? len : PCI_DOE_DW_SIZE_MAX; +} + +static void pcie_doe_irq_assert(DOECap *doe_cap) +{ + PCIDevice *dev = doe_cap->pdev; + + if (doe_cap->cap.intr && doe_cap->ctrl.intr) { + if (doe_cap->status.intr) { + return; + } + doe_cap->status.intr = 1; + + if (msix_enabled(dev)) { + msix_notify(dev, doe_cap->cap.vec); + } else if (msi_enabled(dev)) { + msi_notify(dev, doe_cap->cap.vec); + } + } +} + +static void pcie_doe_set_ready(DOECap *doe_cap, bool rdy) +{ + doe_cap->status.ready = rdy; + + if (rdy) { + pcie_doe_irq_assert(doe_cap); + } +} + +static void pcie_doe_set_error(DOECap *doe_cap, bool err) +{ + doe_cap->status.error = err; + + if (err) { + pcie_doe_irq_assert(doe_cap); + } +} + +/* + * Check incoming request in write_mbox for protocol format + */ +static void pcie_doe_prepare_rsp(DOECap *doe_cap) +{ + bool success = false; + int p; + bool (*handle_request)(DOECap *) = NULL; + + if (doe_cap->status.error) { + return; + } + + if (doe_cap->write_mbox[0] == + DATA_OBJ_BUILD_HEADER1(PCI_VENDOR_ID_PCI_SIG, PCI_SIG_DOE_DISCOVERY)) { + handle_request = pcie_doe_discovery; + } else { + for (p = 0; p < doe_cap->protocol_num - 1; p++) { + if (doe_cap->write_mbox[0] == + pcie_doe_build_protocol(&doe_cap->protocols[p])) { + handle_request = doe_cap->protocols[p].handle_request; + break; + } + } + } + + /* + * PCIe r6 DOE 6.30.1: + * If the number of DW transferred does not match the + * indicated Length for a data object, then the + * data object must be silently discarded. + */ + if (handle_request && (doe_cap->write_mbox_len == + pcie_doe_get_obj_len(pcie_doe_get_write_mbox_ptr(doe_cap)))) { + success = handle_request(doe_cap); + } + + if (success) { + pcie_doe_set_ready(doe_cap, 1); + } else { + pcie_doe_reset_mbox(doe_cap); + } +} + +/* + * Read from DOE config space. + * Return false if the address not within DOE_CAP range. + */ +bool pcie_doe_read_config(DOECap *doe_cap, uint32_t addr, int size, + uint32_t *buf) +{ + uint32_t shift; + uint16_t doe_offset = doe_cap->offset; + + if (!range_covers_byte(doe_offset + PCI_EXP_DOE_CAP, + PCI_DOE_SIZEOF - 4, addr)) { + return false; + } + + addr -= doe_offset; + *buf = 0; + + if (range_covers_byte(PCI_EXP_DOE_CAP, DWORD_BYTE, addr)) { + *buf = FIELD_DP32(*buf, PCI_DOE_CAP_REG, INTR_SUPP, + doe_cap->cap.intr); + *buf = FIELD_DP32(*buf, PCI_DOE_CAP_REG, DOE_INTR_MSG_NUM, + doe_cap->cap.vec); + } else if (range_covers_byte(PCI_EXP_DOE_CTRL, DWORD_BYTE, addr)) { + /* Must return ABORT=0 and GO=0 */ + *buf = FIELD_DP32(*buf, PCI_DOE_CAP_CONTROL, DOE_INTR_EN, + doe_cap->ctrl.intr); + } else if (range_covers_byte(PCI_EXP_DOE_STATUS, DWORD_BYTE, addr)) { + *buf = FIELD_DP32(*buf, PCI_DOE_CAP_STATUS, DOE_BUSY, + doe_cap->status.busy); + *buf = FIELD_DP32(*buf, PCI_DOE_CAP_STATUS, DOE_INTR_STATUS, + doe_cap->status.intr); + *buf = FIELD_DP32(*buf, PCI_DOE_CAP_STATUS, DOE_ERROR, + doe_cap->status.error); + *buf = FIELD_DP32(*buf, PCI_DOE_CAP_STATUS, DATA_OBJ_RDY, + doe_cap->status.ready); + /* Mailbox should be DW accessed */ + } else if (addr == PCI_EXP_DOE_RD_DATA_MBOX && size == DWORD_BYTE) { + if (doe_cap->status.ready && !doe_cap->status.error) { + *buf = doe_cap->read_mbox[doe_cap->read_mbox_idx]; + } + } + + /* Process Alignment */ + shift = addr % DWORD_BYTE; + *buf = extract32(*buf, shift * 8, size * 8); + + return true; +} + +/* + * Write to DOE config space. + * Return if the address not within DOE_CAP range or receives an abort + */ +void pcie_doe_write_config(DOECap *doe_cap, + uint32_t addr, uint32_t val, int size) +{ + uint16_t doe_offset = doe_cap->offset; + uint32_t shift; + + if (!range_covers_byte(doe_offset + PCI_EXP_DOE_CAP, + PCI_DOE_SIZEOF - 4, addr)) { + return; + } + + /* Process Alignment */ + shift = addr % DWORD_BYTE; + addr -= (doe_offset + shift); + val = deposit32(val, shift * 8, size * 8, val); + + switch (addr) { + case PCI_EXP_DOE_CTRL: + if (FIELD_EX32(val, PCI_DOE_CAP_CONTROL, DOE_ABORT)) { + pcie_doe_set_ready(doe_cap, 0); + pcie_doe_set_error(doe_cap, 0); + pcie_doe_reset_mbox(doe_cap); + return; + } + + if (FIELD_EX32(val, PCI_DOE_CAP_CONTROL, DOE_GO)) { + pcie_doe_prepare_rsp(doe_cap); + } + + if (FIELD_EX32(val, PCI_DOE_CAP_CONTROL, DOE_INTR_EN)) { + doe_cap->ctrl.intr = 1; + /* Clear interrupt bit located within the first byte */ + } else if (shift == 0) { + doe_cap->ctrl.intr = 0; + } + break; + case PCI_EXP_DOE_STATUS: + if (FIELD_EX32(val, PCI_DOE_CAP_STATUS, DOE_INTR_STATUS)) { + doe_cap->status.intr = 0; + } + break; + case PCI_EXP_DOE_RD_DATA_MBOX: + /* Mailbox should be DW accessed */ + if (size != DWORD_BYTE) { + return; + } + doe_cap->read_mbox_idx++; + if (doe_cap->read_mbox_idx == doe_cap->read_mbox_len) { + pcie_doe_reset_mbox(doe_cap); + pcie_doe_set_ready(doe_cap, 0); + } else if (doe_cap->read_mbox_idx > doe_cap->read_mbox_len) { + /* Underflow */ + pcie_doe_set_error(doe_cap, 1); + } + break; + case PCI_EXP_DOE_WR_DATA_MBOX: + /* Mailbox should be DW accessed */ + if (size != DWORD_BYTE) { + return; + } + doe_cap->write_mbox[doe_cap->write_mbox_len] = val; + doe_cap->write_mbox_len++; + break; + case PCI_EXP_DOE_CAP: + /* fallthrough */ + default: + break; + } +} diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h index d5ddea558b..bc9f834fd1 100644 --- a/include/hw/pci/pci_ids.h +++ b/include/hw/pci/pci_ids.h @@ -157,6 +157,9 @@ /* Vendors and devices. Sort key: vendor first, device next. */ +/* Ref: PCIe r6.0 Table 6-32 */ +#define PCI_VENDOR_ID_PCI_SIG 0x0001 + #define PCI_VENDOR_ID_LSI_LOGIC 0x1000 #define PCI_DEVICE_ID_LSI_53C810 0x0001 #define PCI_DEVICE_ID_LSI_53C895A 0x0012 diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h index 798a262a0a..698d3de851 100644 --- a/include/hw/pci/pcie.h +++ b/include/hw/pci/pcie.h @@ -26,6 +26,7 @@ #include "hw/pci/pcie_aer.h" #include "hw/pci/pcie_sriov.h" #include "hw/hotplug.h" +#include "hw/pci/pcie_doe.h" typedef enum { /* for attention and power indicator */ diff --git a/include/hw/pci/pcie_doe.h b/include/hw/pci/pcie_doe.h new file mode 100644 index 0000000000..ba4d8b03bd --- /dev/null +++ b/include/hw/pci/pcie_doe.h @@ -0,0 +1,123 @@ +/* + * PCIe Data Object Exchange + * + * Copyright (C) 2021 Avery Design Systems, Inc. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef PCIE_DOE_H +#define PCIE_DOE_H + +#include "qemu/range.h" +#include "qemu/typedefs.h" +#include "hw/register.h" + +/* + * Reference: + * PCIe r6.0 - 7.9.24 Data Object Exchange Extended Capability + */ +/* Capabilities Register - r6.0 7.9.24.2 */ +#define PCI_EXP_DOE_CAP 0x04 +REG32(PCI_DOE_CAP_REG, 0) + FIELD(PCI_DOE_CAP_REG, INTR_SUPP, 0, 1) + FIELD(PCI_DOE_CAP_REG, DOE_INTR_MSG_NUM, 1, 11) + +/* Control Register - r6.0 7.9.24.3 */ +#define PCI_EXP_DOE_CTRL 0x08 +REG32(PCI_DOE_CAP_CONTROL, 0) + FIELD(PCI_DOE_CAP_CONTROL, DOE_ABORT, 0, 1) + FIELD(PCI_DOE_CAP_CONTROL, DOE_INTR_EN, 1, 1) + FIELD(PCI_DOE_CAP_CONTROL, DOE_GO, 31, 1) + +/* Status Register - r6.0 7.9.24.4 */ +#define PCI_EXP_DOE_STATUS 0x0c +REG32(PCI_DOE_CAP_STATUS, 0) + FIELD(PCI_DOE_CAP_STATUS, DOE_BUSY, 0, 1) + FIELD(PCI_DOE_CAP_STATUS, DOE_INTR_STATUS, 1, 1) + FIELD(PCI_DOE_CAP_STATUS, DOE_ERROR, 2, 1) + FIELD(PCI_DOE_CAP_STATUS, DATA_OBJ_RDY, 31, 1) + +/* Write Data Mailbox Register - r6.0 7.9.24.5 */ +#define PCI_EXP_DOE_WR_DATA_MBOX 0x10 + +/* Read Data Mailbox Register - 7.9.xx.6 */ +#define PCI_EXP_DOE_RD_DATA_MBOX 0x14 + +/* PCI-SIG defined Data Object Types - r6.0 Table 6-32 */ +#define PCI_SIG_DOE_DISCOVERY 0x00 + +#define PCI_DOE_DW_SIZE_MAX (1 << 18) +#define PCI_DOE_PROTOCOL_NUM_MAX 256 + +#define DATA_OBJ_BUILD_HEADER1(v, p) (((p) << 16) | (v)) +#define DATA_OBJ_LEN_MASK(len) ((len) & (PCI_DOE_DW_SIZE_MAX - 1)) + +typedef struct DOEHeader DOEHeader; +typedef struct DOEProtocol DOEProtocol; +typedef struct DOECap DOECap; + +struct DOEHeader { + uint16_t vendor_id; + uint8_t data_obj_type; + uint8_t reserved; + uint32_t length; +} QEMU_PACKED; + +/* Protocol infos and rsp function callback */ +struct DOEProtocol { + uint16_t vendor_id; + uint8_t data_obj_type; + bool (*handle_request)(DOECap *); +}; + +struct DOECap { + /* Owner */ + PCIDevice *pdev; + + uint16_t offset; + + struct { + bool intr; + uint16_t vec; + } cap; + + struct { + bool abort; + bool intr; + bool go; + } ctrl; + + struct { + bool busy; + bool intr; + bool error; + bool ready; + } status; + + uint32_t *write_mbox; + uint32_t *read_mbox; + + /* Mailbox position indicator */ + uint32_t read_mbox_idx; + uint32_t read_mbox_len; + uint32_t write_mbox_len; + + /* Protocols and its callback response */ + DOEProtocol *protocols; + uint16_t protocol_num; +}; + +void pcie_doe_init(PCIDevice *pdev, DOECap *doe_cap, uint16_t offset, + DOEProtocol *protocols, bool intr, uint16_t vec); +void pcie_doe_fini(DOECap *doe_cap); +bool pcie_doe_read_config(DOECap *doe_cap, uint32_t addr, int size, + uint32_t *buf); +void pcie_doe_write_config(DOECap *doe_cap, uint32_t addr, + uint32_t val, int size); +uint32_t pcie_doe_build_protocol(DOEProtocol *p); +void *pcie_doe_get_write_mbox_ptr(DOECap *doe_cap); +void pcie_doe_set_rsp(DOECap *doe_cap, void *rsp); +uint32_t pcie_doe_get_obj_len(void *obj); +#endif /* PCIE_DOE_H */ diff --git a/include/hw/pci/pcie_regs.h b/include/hw/pci/pcie_regs.h index 1db86b0ec4..963dc2e170 100644 --- a/include/hw/pci/pcie_regs.h +++ b/include/hw/pci/pcie_regs.h @@ -179,4 +179,8 @@ typedef enum PCIExpLinkWidth { #define PCI_ACS_VER 0x1 #define PCI_ACS_SIZEOF 8 +/* DOE Capability Register Fields */ +#define PCI_DOE_VER 0x1 +#define PCI_DOE_SIZEOF 24 + #endif /* QEMU_PCIE_REGS_H */ From 23325c8df4318e5f4388dc2e53e6b7c8c3996880 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 14 Oct 2022 16:10:42 +0100 Subject: [PATCH 603/705] hw/mem/cxl-type3: Add MSIX support This will be used by several upcoming patch sets so break it out such that it doesn't matter which one lands first. Signed-off-by: Jonathan Cameron Message-Id: <20221014151045.24781-3-Jonathan.Cameron@huawei.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/mem/cxl_type3.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c index a71bf1afeb..568c9d62f5 100644 --- a/hw/mem/cxl_type3.c +++ b/hw/mem/cxl_type3.c @@ -13,6 +13,7 @@ #include "qemu/rcu.h" #include "sysemu/hostmem.h" #include "hw/cxl/cxl.h" +#include "hw/pci/msix.h" /* * Null value of all Fs suggested by IEEE RA guidelines for use of @@ -146,6 +147,8 @@ static void ct3_realize(PCIDevice *pci_dev, Error **errp) ComponentRegisters *regs = &cxl_cstate->crb; MemoryRegion *mr = ®s->component_registers; uint8_t *pci_conf = pci_dev->config; + unsigned short msix_num = 1; + int i; if (!cxl_setup_memory(ct3d, errp)) { return; @@ -180,6 +183,12 @@ static void ct3_realize(PCIDevice *pci_dev, Error **errp) PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64, &ct3d->cxl_dstate.device_registers); + + /* MSI(-X) Initailization */ + msix_init_exclusive_bar(pci_dev, msix_num, 4, NULL); + for (i = 0; i < msix_num; i++) { + msix_vector_use(pci_dev, i); + } } static void ct3_exit(PCIDevice *pci_dev) From aba578bdace5303a441f8a37aad781b5cb06f38c Mon Sep 17 00:00:00 2001 From: Huai-Cheng Kuo Date: Fri, 14 Oct 2022 16:10:43 +0100 Subject: [PATCH 604/705] hw/cxl/cdat: CXL CDAT Data Object Exchange implementation The Data Object Exchange implementation of CXL Coherent Device Attribute Table (CDAT). This implementation is referring to "Coherent Device Attribute Table Specification, Rev. 1.03, July. 2022" and "Compute Express Link Specification, Rev. 3.0, July. 2022" This patch adds core support that will be shared by both end-points and switch port emulation. Signed-off-by: Huai-Cheng Kuo Signed-off-by: Chris Browy Signed-off-by: Jonathan Cameron Message-Id: <20221014151045.24781-4-Jonathan.Cameron@huawei.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/cxl/cxl-cdat.c | 224 +++++++++++++++++++++++++++++++++ hw/cxl/meson.build | 1 + include/hw/cxl/cxl_cdat.h | 165 ++++++++++++++++++++++++ include/hw/cxl/cxl_component.h | 7 ++ include/hw/cxl/cxl_device.h | 3 + include/hw/cxl/cxl_pci.h | 1 + 6 files changed, 401 insertions(+) create mode 100644 hw/cxl/cxl-cdat.c create mode 100644 include/hw/cxl/cxl_cdat.h diff --git a/hw/cxl/cxl-cdat.c b/hw/cxl/cxl-cdat.c new file mode 100644 index 0000000000..3653aa56f0 --- /dev/null +++ b/hw/cxl/cxl-cdat.c @@ -0,0 +1,224 @@ +/* + * CXL CDAT Structure + * + * Copyright (C) 2021 Avery Design Systems, Inc. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "hw/pci/pci.h" +#include "hw/cxl/cxl.h" +#include "qapi/error.h" +#include "qemu/error-report.h" + +static void cdat_len_check(CDATSubHeader *hdr, Error **errp) +{ + assert(hdr->length); + assert(hdr->reserved == 0); + + switch (hdr->type) { + case CDAT_TYPE_DSMAS: + assert(hdr->length == sizeof(CDATDsmas)); + break; + case CDAT_TYPE_DSLBIS: + assert(hdr->length == sizeof(CDATDslbis)); + break; + case CDAT_TYPE_DSMSCIS: + assert(hdr->length == sizeof(CDATDsmscis)); + break; + case CDAT_TYPE_DSIS: + assert(hdr->length == sizeof(CDATDsis)); + break; + case CDAT_TYPE_DSEMTS: + assert(hdr->length == sizeof(CDATDsemts)); + break; + case CDAT_TYPE_SSLBIS: + assert(hdr->length >= sizeof(CDATSslbisHeader)); + assert((hdr->length - sizeof(CDATSslbisHeader)) % + sizeof(CDATSslbe) == 0); + break; + default: + error_setg(errp, "Type %d is reserved", hdr->type); + } +} + +static void ct3_build_cdat(CDATObject *cdat, Error **errp) +{ + g_autofree CDATTableHeader *cdat_header = NULL; + g_autofree CDATEntry *cdat_st = NULL; + uint8_t sum = 0; + int ent, i; + + /* Use default table if fopen == NULL */ + assert(cdat->build_cdat_table); + + cdat_header = g_malloc0(sizeof(*cdat_header)); + if (!cdat_header) { + error_setg(errp, "Failed to allocate CDAT header"); + return; + } + + cdat->built_buf_len = cdat->build_cdat_table(&cdat->built_buf, cdat->private); + + if (!cdat->built_buf_len) { + /* Build later as not all data available yet */ + cdat->to_update = true; + return; + } + cdat->to_update = false; + + cdat_st = g_malloc0(sizeof(*cdat_st) * (cdat->built_buf_len + 1)); + if (!cdat_st) { + error_setg(errp, "Failed to allocate CDAT entry array"); + return; + } + + /* Entry 0 for CDAT header, starts with Entry 1 */ + for (ent = 1; ent < cdat->built_buf_len + 1; ent++) { + CDATSubHeader *hdr = cdat->built_buf[ent - 1]; + uint8_t *buf = (uint8_t *)cdat->built_buf[ent - 1]; + + cdat_st[ent].base = hdr; + cdat_st[ent].length = hdr->length; + + cdat_header->length += hdr->length; + for (i = 0; i < hdr->length; i++) { + sum += buf[i]; + } + } + + /* CDAT header */ + cdat_header->revision = CXL_CDAT_REV; + /* For now, no runtime updates */ + cdat_header->sequence = 0; + cdat_header->length += sizeof(CDATTableHeader); + sum += cdat_header->revision + cdat_header->sequence + + cdat_header->length; + /* Sum of all bytes including checksum must be 0 */ + cdat_header->checksum = ~sum + 1; + + cdat_st[0].base = g_steal_pointer(&cdat_header); + cdat_st[0].length = sizeof(*cdat_header); + cdat->entry_len = 1 + cdat->built_buf_len; + cdat->entry = g_steal_pointer(&cdat_st); +} + +static void ct3_load_cdat(CDATObject *cdat, Error **errp) +{ + g_autofree CDATEntry *cdat_st = NULL; + uint8_t sum = 0; + int num_ent; + int i = 0, ent = 1, file_size = 0; + CDATSubHeader *hdr; + FILE *fp = NULL; + + /* Read CDAT file and create its cache */ + fp = fopen(cdat->filename, "r"); + if (!fp) { + error_setg(errp, "CDAT: Unable to open file"); + return; + } + + fseek(fp, 0, SEEK_END); + file_size = ftell(fp); + fseek(fp, 0, SEEK_SET); + cdat->buf = g_malloc0(file_size); + + if (fread(cdat->buf, file_size, 1, fp) == 0) { + error_setg(errp, "CDAT: File read failed"); + return; + } + + fclose(fp); + + if (file_size < sizeof(CDATTableHeader)) { + error_setg(errp, "CDAT: File too short"); + return; + } + i = sizeof(CDATTableHeader); + num_ent = 1; + while (i < file_size) { + hdr = (CDATSubHeader *)(cdat->buf + i); + cdat_len_check(hdr, errp); + i += hdr->length; + num_ent++; + } + if (i != file_size) { + error_setg(errp, "CDAT: File length missmatch"); + return; + } + + cdat_st = g_malloc0(sizeof(*cdat_st) * num_ent); + if (!cdat_st) { + error_setg(errp, "CDAT: Failed to allocate entry array"); + return; + } + + /* Set CDAT header, Entry = 0 */ + cdat_st[0].base = cdat->buf; + cdat_st[0].length = sizeof(CDATTableHeader); + i = 0; + + while (i < cdat_st[0].length) { + sum += cdat->buf[i++]; + } + + /* Read CDAT structures */ + while (i < file_size) { + hdr = (CDATSubHeader *)(cdat->buf + i); + cdat_len_check(hdr, errp); + + cdat_st[ent].base = hdr; + cdat_st[ent].length = hdr->length; + + while (cdat->buf + i < + (uint8_t *)cdat_st[ent].base + cdat_st[ent].length) { + assert(i < file_size); + sum += cdat->buf[i++]; + } + + ent++; + } + + if (sum != 0) { + warn_report("CDAT: Found checksum mismatch in %s", cdat->filename); + } + cdat->entry_len = num_ent; + cdat->entry = g_steal_pointer(&cdat_st); +} + +void cxl_doe_cdat_init(CXLComponentState *cxl_cstate, Error **errp) +{ + CDATObject *cdat = &cxl_cstate->cdat; + + if (cdat->filename) { + ct3_load_cdat(cdat, errp); + } else { + ct3_build_cdat(cdat, errp); + } +} + +void cxl_doe_cdat_update(CXLComponentState *cxl_cstate, Error **errp) +{ + CDATObject *cdat = &cxl_cstate->cdat; + + if (cdat->to_update) { + ct3_build_cdat(cdat, errp); + } +} + +void cxl_doe_cdat_release(CXLComponentState *cxl_cstate) +{ + CDATObject *cdat = &cxl_cstate->cdat; + + free(cdat->entry); + if (cdat->built_buf) { + cdat->free_cdat_table(cdat->built_buf, cdat->built_buf_len, + cdat->private); + } + if (cdat->buf) { + free(cdat->buf); + } +} diff --git a/hw/cxl/meson.build b/hw/cxl/meson.build index f117b99949..cfa95ffd40 100644 --- a/hw/cxl/meson.build +++ b/hw/cxl/meson.build @@ -4,6 +4,7 @@ softmmu_ss.add(when: 'CONFIG_CXL', 'cxl-device-utils.c', 'cxl-mailbox-utils.c', 'cxl-host.c', + 'cxl-cdat.c', ), if_false: files( 'cxl-host-stubs.c', diff --git a/include/hw/cxl/cxl_cdat.h b/include/hw/cxl/cxl_cdat.h new file mode 100644 index 0000000000..52c232e912 --- /dev/null +++ b/include/hw/cxl/cxl_cdat.h @@ -0,0 +1,165 @@ +/* + * CXL CDAT Structure + * + * Copyright (C) 2021 Avery Design Systems, Inc. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef CXL_CDAT_H +#define CXL_CDAT_H + +#include "hw/cxl/cxl_pci.h" + +/* + * Reference: + * Coherent Device Attribute Table (CDAT) Specification, Rev. 1.03, July. 2022 + * Compute Express Link (CXL) Specification, Rev. 3.0, Aug. 2022 + */ +/* Table Access DOE - CXL r3.0 8.1.11 */ +#define CXL_DOE_TABLE_ACCESS 2 +#define CXL_DOE_PROTOCOL_CDAT ((CXL_DOE_TABLE_ACCESS << 16) | CXL_VENDOR_ID) + +/* Read Entry - CXL r3.0 8.1.11.1 */ +#define CXL_DOE_TAB_TYPE_CDAT 0 +#define CXL_DOE_TAB_ENT_MAX 0xFFFF + +/* Read Entry Request - CXL r3.0 8.1.11.1 Table 8-13 */ +#define CXL_DOE_TAB_REQ 0 +typedef struct CDATReq { + DOEHeader header; + uint8_t req_code; + uint8_t table_type; + uint16_t entry_handle; +} QEMU_PACKED CDATReq; + +/* Read Entry Response - CXL r3.0 8.1.11.1 Table 8-14 */ +#define CXL_DOE_TAB_RSP 0 +typedef struct CDATRsp { + DOEHeader header; + uint8_t rsp_code; + uint8_t table_type; + uint16_t entry_handle; +} QEMU_PACKED CDATRsp; + +/* CDAT Table Format - CDAT Table 1 */ +#define CXL_CDAT_REV 2 +typedef struct CDATTableHeader { + uint32_t length; + uint8_t revision; + uint8_t checksum; + uint8_t reserved[6]; + uint32_t sequence; +} QEMU_PACKED CDATTableHeader; + +/* CDAT Structure Types - CDAT Table 2 */ +typedef enum { + CDAT_TYPE_DSMAS = 0, + CDAT_TYPE_DSLBIS = 1, + CDAT_TYPE_DSMSCIS = 2, + CDAT_TYPE_DSIS = 3, + CDAT_TYPE_DSEMTS = 4, + CDAT_TYPE_SSLBIS = 5, +} CDATType; + +typedef struct CDATSubHeader { + uint8_t type; + uint8_t reserved; + uint16_t length; +} CDATSubHeader; + +/* Device Scoped Memory Affinity Structure - CDAT Table 3 */ +typedef struct CDATDsmas { + CDATSubHeader header; + uint8_t DSMADhandle; + uint8_t flags; +#define CDAT_DSMAS_FLAG_NV (1 << 2) +#define CDAT_DSMAS_FLAG_SHAREABLE (1 << 3) +#define CDAT_DSMAS_FLAG_HW_COHERENT (1 << 4) +#define CDAT_DSMAS_FLAG_DYNAMIC_CAP (1 << 5) + uint16_t reserved; + uint64_t DPA_base; + uint64_t DPA_length; +} QEMU_PACKED CDATDsmas; + +/* Device Scoped Latency and Bandwidth Information Structure - CDAT Table 5 */ +typedef struct CDATDslbis { + CDATSubHeader header; + uint8_t handle; + /* Definitions of these fields refer directly to HMAT fields */ + uint8_t flags; + uint8_t data_type; + uint8_t reserved; + uint64_t entry_base_unit; + uint16_t entry[3]; + uint16_t reserved2; +} QEMU_PACKED CDATDslbis; + +/* Device Scoped Memory Side Cache Information Structure - CDAT Table 6 */ +typedef struct CDATDsmscis { + CDATSubHeader header; + uint8_t DSMAS_handle; + uint8_t reserved[3]; + uint64_t memory_side_cache_size; + uint32_t cache_attributes; +} QEMU_PACKED CDATDsmscis; + +/* Device Scoped Initiator Structure - CDAT Table 7 */ +typedef struct CDATDsis { + CDATSubHeader header; + uint8_t flags; + uint8_t handle; + uint16_t reserved; +} QEMU_PACKED CDATDsis; + +/* Device Scoped EFI Memory Type Structure - CDAT Table 8 */ +typedef struct CDATDsemts { + CDATSubHeader header; + uint8_t DSMAS_handle; + uint8_t EFI_memory_type_attr; + uint16_t reserved; + uint64_t DPA_offset; + uint64_t DPA_length; +} QEMU_PACKED CDATDsemts; + +/* Switch Scoped Latency and Bandwidth Information Structure - CDAT Table 9 */ +typedef struct CDATSslbisHeader { + CDATSubHeader header; + uint8_t data_type; + uint8_t reserved[3]; + uint64_t entry_base_unit; +} QEMU_PACKED CDATSslbisHeader; + +/* Switch Scoped Latency and Bandwidth Entry - CDAT Table 10 */ +typedef struct CDATSslbe { + uint16_t port_x_id; + uint16_t port_y_id; + uint16_t latency_bandwidth; + uint16_t reserved; +} QEMU_PACKED CDATSslbe; + +typedef struct CDATSslbis { + CDATSslbisHeader sslbis_header; + CDATSslbe sslbe[]; +} QEMU_PACKED CDATSslbis; + +typedef struct CDATEntry { + void *base; + uint32_t length; +} CDATEntry; + +typedef struct CDATObject { + CDATEntry *entry; + int entry_len; + + int (*build_cdat_table)(CDATSubHeader ***cdat_table, void *priv); + void (*free_cdat_table)(CDATSubHeader **cdat_table, int num, void *priv); + bool to_update; + void *private; + char *filename; + uint8_t *buf; + struct CDATSubHeader **built_buf; + int built_buf_len; +} CDATObject; +#endif /* CXL_CDAT_H */ diff --git a/include/hw/cxl/cxl_component.h b/include/hw/cxl/cxl_component.h index 94ec2f07d7..34075cfb72 100644 --- a/include/hw/cxl/cxl_component.h +++ b/include/hw/cxl/cxl_component.h @@ -19,6 +19,7 @@ #include "qemu/range.h" #include "qemu/typedefs.h" #include "hw/register.h" +#include "qapi/error.h" enum reg_type { CXL2_DEVICE, @@ -184,6 +185,8 @@ typedef struct cxl_component { struct PCIDevice *pdev; }; }; + + CDATObject cdat; } CXLComponentState; void cxl_component_register_block_init(Object *obj, @@ -220,4 +223,8 @@ static inline hwaddr cxl_decode_ig(int ig) CXLComponentState *cxl_get_hb_cstate(PCIHostState *hb); +void cxl_doe_cdat_init(CXLComponentState *cxl_cstate, Error **errp); +void cxl_doe_cdat_release(CXLComponentState *cxl_cstate); +void cxl_doe_cdat_update(CXLComponentState *cxl_cstate, Error **errp); + #endif diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h index e4d221cdb3..449b0edfe9 100644 --- a/include/hw/cxl/cxl_device.h +++ b/include/hw/cxl/cxl_device.h @@ -243,6 +243,9 @@ struct CXLType3Dev { AddressSpace hostmem_as; CXLComponentState cxl_cstate; CXLDeviceState cxl_dstate; + + /* DOE */ + DOECap doe_cdat; }; #define TYPE_CXL_TYPE3 "cxl-type3" diff --git a/include/hw/cxl/cxl_pci.h b/include/hw/cxl/cxl_pci.h index 01cf002096..3cb79eca1e 100644 --- a/include/hw/cxl/cxl_pci.h +++ b/include/hw/cxl/cxl_pci.h @@ -13,6 +13,7 @@ #include "qemu/compiler.h" #include "hw/pci/pci.h" #include "hw/pci/pcie.h" +#include "hw/cxl/cxl_cdat.h" #define CXL_VENDOR_ID 0x1e98 From f5ee7413d5928930604f73675fe89f21fbabc8b3 Mon Sep 17 00:00:00 2001 From: Huai-Cheng Kuo Date: Fri, 14 Oct 2022 16:10:44 +0100 Subject: [PATCH 605/705] hw/mem/cxl-type3: Add CXL CDAT Data Object Exchange The CDAT can be specified in two ways. One is to add ",cdat=" in "-device cxl-type3"'s command option. The file is required to provide the whole CDAT table in binary mode. The other is to use the default that provides some 'reasonable' numbers based on type of memory and size. The DOE capability supporting CDAT is added to hw/mem/cxl_type3.c with capability offset 0x190. The config read/write to this capability range can be generated in the OS to request the CDAT data. Signed-off-by: Huai-Cheng Kuo Signed-off-by: Chris Browy Signed-off-by: Jonathan Cameron Message-Id: <20221014151045.24781-5-Jonathan.Cameron@huawei.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/mem/cxl_type3.c | 255 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 255 insertions(+) diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c index 568c9d62f5..255590201a 100644 --- a/hw/mem/cxl_type3.c +++ b/hw/mem/cxl_type3.c @@ -12,9 +12,246 @@ #include "qemu/range.h" #include "qemu/rcu.h" #include "sysemu/hostmem.h" +#include "sysemu/numa.h" #include "hw/cxl/cxl.h" #include "hw/pci/msix.h" +#define DWORD_BYTE 4 + +/* Default CDAT entries for a memory region */ +enum { + CT3_CDAT_DSMAS, + CT3_CDAT_DSLBIS0, + CT3_CDAT_DSLBIS1, + CT3_CDAT_DSLBIS2, + CT3_CDAT_DSLBIS3, + CT3_CDAT_DSEMTS, + CT3_CDAT_NUM_ENTRIES +}; + +static int ct3_build_cdat_entries_for_mr(CDATSubHeader **cdat_table, + int dsmad_handle, MemoryRegion *mr) +{ + g_autofree CDATDsmas *dsmas = NULL; + g_autofree CDATDslbis *dslbis0 = NULL; + g_autofree CDATDslbis *dslbis1 = NULL; + g_autofree CDATDslbis *dslbis2 = NULL; + g_autofree CDATDslbis *dslbis3 = NULL; + g_autofree CDATDsemts *dsemts = NULL; + + dsmas = g_malloc(sizeof(*dsmas)); + if (!dsmas) { + return -ENOMEM; + } + *dsmas = (CDATDsmas) { + .header = { + .type = CDAT_TYPE_DSMAS, + .length = sizeof(*dsmas), + }, + .DSMADhandle = dsmad_handle, + .flags = CDAT_DSMAS_FLAG_NV, + .DPA_base = 0, + .DPA_length = int128_get64(mr->size), + }; + + /* For now, no memory side cache, plausiblish numbers */ + dslbis0 = g_malloc(sizeof(*dslbis0)); + if (!dslbis0) { + return -ENOMEM; + } + *dslbis0 = (CDATDslbis) { + .header = { + .type = CDAT_TYPE_DSLBIS, + .length = sizeof(*dslbis0), + }, + .handle = dsmad_handle, + .flags = HMAT_LB_MEM_MEMORY, + .data_type = HMAT_LB_DATA_READ_LATENCY, + .entry_base_unit = 10000, /* 10ns base */ + .entry[0] = 15, /* 150ns */ + }; + + dslbis1 = g_malloc(sizeof(*dslbis1)); + if (!dslbis1) { + return -ENOMEM; + } + *dslbis1 = (CDATDslbis) { + .header = { + .type = CDAT_TYPE_DSLBIS, + .length = sizeof(*dslbis1), + }, + .handle = dsmad_handle, + .flags = HMAT_LB_MEM_MEMORY, + .data_type = HMAT_LB_DATA_WRITE_LATENCY, + .entry_base_unit = 10000, + .entry[0] = 25, /* 250ns */ + }; + + dslbis2 = g_malloc(sizeof(*dslbis2)); + if (!dslbis2) { + return -ENOMEM; + } + *dslbis2 = (CDATDslbis) { + .header = { + .type = CDAT_TYPE_DSLBIS, + .length = sizeof(*dslbis2), + }, + .handle = dsmad_handle, + .flags = HMAT_LB_MEM_MEMORY, + .data_type = HMAT_LB_DATA_READ_BANDWIDTH, + .entry_base_unit = 1000, /* GB/s */ + .entry[0] = 16, + }; + + dslbis3 = g_malloc(sizeof(*dslbis3)); + if (!dslbis3) { + return -ENOMEM; + } + *dslbis3 = (CDATDslbis) { + .header = { + .type = CDAT_TYPE_DSLBIS, + .length = sizeof(*dslbis3), + }, + .handle = dsmad_handle, + .flags = HMAT_LB_MEM_MEMORY, + .data_type = HMAT_LB_DATA_WRITE_BANDWIDTH, + .entry_base_unit = 1000, /* GB/s */ + .entry[0] = 16, + }; + + dsemts = g_malloc(sizeof(*dsemts)); + if (!dsemts) { + return -ENOMEM; + } + *dsemts = (CDATDsemts) { + .header = { + .type = CDAT_TYPE_DSEMTS, + .length = sizeof(*dsemts), + }, + .DSMAS_handle = dsmad_handle, + /* Reserved - the non volatile from DSMAS matters */ + .EFI_memory_type_attr = 2, + .DPA_offset = 0, + .DPA_length = int128_get64(mr->size), + }; + + /* Header always at start of structure */ + cdat_table[CT3_CDAT_DSMAS] = g_steal_pointer(&dsmas); + cdat_table[CT3_CDAT_DSLBIS0] = g_steal_pointer(&dslbis0); + cdat_table[CT3_CDAT_DSLBIS1] = g_steal_pointer(&dslbis1); + cdat_table[CT3_CDAT_DSLBIS2] = g_steal_pointer(&dslbis2); + cdat_table[CT3_CDAT_DSLBIS3] = g_steal_pointer(&dslbis3); + cdat_table[CT3_CDAT_DSEMTS] = g_steal_pointer(&dsemts); + + return 0; +} + +static int ct3_build_cdat_table(CDATSubHeader ***cdat_table, void *priv) +{ + g_autofree CDATSubHeader **table = NULL; + MemoryRegion *nonvolatile_mr; + CXLType3Dev *ct3d = priv; + int dsmad_handle = 0; + int rc; + + if (!ct3d->hostmem) { + return 0; + } + + nonvolatile_mr = host_memory_backend_get_memory(ct3d->hostmem); + if (!nonvolatile_mr) { + return -EINVAL; + } + + table = g_malloc0(CT3_CDAT_NUM_ENTRIES * sizeof(*table)); + if (!table) { + return -ENOMEM; + } + + rc = ct3_build_cdat_entries_for_mr(table, dsmad_handle++, nonvolatile_mr); + if (rc < 0) { + return rc; + } + + *cdat_table = g_steal_pointer(&table); + + return CT3_CDAT_NUM_ENTRIES; +} + +static void ct3_free_cdat_table(CDATSubHeader **cdat_table, int num, void *priv) +{ + int i; + + for (i = 0; i < num; i++) { + g_free(cdat_table[i]); + } + g_free(cdat_table); +} + +static bool cxl_doe_cdat_rsp(DOECap *doe_cap) +{ + CDATObject *cdat = &CXL_TYPE3(doe_cap->pdev)->cxl_cstate.cdat; + uint16_t ent; + void *base; + uint32_t len; + CDATReq *req = pcie_doe_get_write_mbox_ptr(doe_cap); + CDATRsp rsp; + + assert(cdat->entry_len); + + /* Discard if request length mismatched */ + if (pcie_doe_get_obj_len(req) < + DIV_ROUND_UP(sizeof(CDATReq), DWORD_BYTE)) { + return false; + } + + ent = req->entry_handle; + base = cdat->entry[ent].base; + len = cdat->entry[ent].length; + + rsp = (CDATRsp) { + .header = { + .vendor_id = CXL_VENDOR_ID, + .data_obj_type = CXL_DOE_TABLE_ACCESS, + .reserved = 0x0, + .length = DIV_ROUND_UP((sizeof(rsp) + len), DWORD_BYTE), + }, + .rsp_code = CXL_DOE_TAB_RSP, + .table_type = CXL_DOE_TAB_TYPE_CDAT, + .entry_handle = (ent < cdat->entry_len - 1) ? + ent + 1 : CXL_DOE_TAB_ENT_MAX, + }; + + memcpy(doe_cap->read_mbox, &rsp, sizeof(rsp)); + memcpy(doe_cap->read_mbox + DIV_ROUND_UP(sizeof(rsp), DWORD_BYTE), + base, len); + + doe_cap->read_mbox_len += rsp.header.length; + + return true; +} + +static uint32_t ct3d_config_read(PCIDevice *pci_dev, uint32_t addr, int size) +{ + CXLType3Dev *ct3d = CXL_TYPE3(pci_dev); + uint32_t val; + + if (pcie_doe_read_config(&ct3d->doe_cdat, addr, size, &val)) { + return val; + } + + return pci_default_read_config(pci_dev, addr, size); +} + +static void ct3d_config_write(PCIDevice *pci_dev, uint32_t addr, uint32_t val, + int size) +{ + CXLType3Dev *ct3d = CXL_TYPE3(pci_dev); + + pcie_doe_write_config(&ct3d->doe_cdat, addr, val, size); + pci_default_write_config(pci_dev, addr, val, size); +} + /* * Null value of all Fs suggested by IEEE RA guidelines for use of * EU, OUI and CID @@ -140,6 +377,11 @@ static bool cxl_setup_memory(CXLType3Dev *ct3d, Error **errp) return true; } +static DOEProtocol doe_cdat_prot[] = { + { CXL_VENDOR_ID, CXL_DOE_TABLE_ACCESS, cxl_doe_cdat_rsp }, + { } +}; + static void ct3_realize(PCIDevice *pci_dev, Error **errp) { CXLType3Dev *ct3d = CXL_TYPE3(pci_dev); @@ -189,6 +431,14 @@ static void ct3_realize(PCIDevice *pci_dev, Error **errp) for (i = 0; i < msix_num; i++) { msix_vector_use(pci_dev, i); } + + /* DOE Initailization */ + pcie_doe_init(pci_dev, &ct3d->doe_cdat, 0x190, doe_cdat_prot, true, 0); + + cxl_cstate->cdat.build_cdat_table = ct3_build_cdat_table; + cxl_cstate->cdat.free_cdat_table = ct3_free_cdat_table; + cxl_cstate->cdat.private = ct3d; + cxl_doe_cdat_init(cxl_cstate, errp); } static void ct3_exit(PCIDevice *pci_dev) @@ -197,6 +447,7 @@ static void ct3_exit(PCIDevice *pci_dev) CXLComponentState *cxl_cstate = &ct3d->cxl_cstate; ComponentRegisters *regs = &cxl_cstate->crb; + cxl_doe_cdat_release(cxl_cstate); g_free(regs->special_ops); address_space_destroy(&ct3d->hostmem_as); } @@ -296,6 +547,7 @@ static Property ct3_props[] = { DEFINE_PROP_LINK("lsa", CXLType3Dev, lsa, TYPE_MEMORY_BACKEND, HostMemoryBackend *), DEFINE_PROP_UINT64("sn", CXLType3Dev, sn, UI64_NULL), + DEFINE_PROP_STRING("cdat", CXLType3Dev, cxl_cstate.cdat.filename), DEFINE_PROP_END_OF_LIST(), }; @@ -361,6 +613,9 @@ static void ct3_class_init(ObjectClass *oc, void *data) pc->device_id = 0xd93; /* LVF for now */ pc->revision = 1; + pc->config_write = ct3d_config_write; + pc->config_read = ct3d_config_read; + set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); dc->desc = "CXL PMEM Device (Type 3)"; dc->reset = ct3d_reset; From 882877fc359d24e1563065c5c3887096317ca1ae Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 14 Oct 2022 16:10:45 +0100 Subject: [PATCH 606/705] hw/pci-bridge/cxl-upstream: Add a CDAT table access DOE This Data Object Exchange Mailbox allows software to query the latency and bandwidth between ports on the switch. For now only provide information on routes between the upstream port and each downstream port (not p2p). Signed-off-by: Jonathan Cameron -- Changes since v8: Mostly to match the type 3 equivalent - Move enum out of function and give it a more descriptive namespace. Message-Id: <20221014151045.24781-6-Jonathan.Cameron@huawei.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/pci-bridge/cxl_upstream.c | 195 ++++++++++++++++++++++++++++++++++- include/hw/cxl/cxl_cdat.h | 1 + 2 files changed, 195 insertions(+), 1 deletion(-) diff --git a/hw/pci-bridge/cxl_upstream.c b/hw/pci-bridge/cxl_upstream.c index a83a3e81e4..9b8b57df9d 100644 --- a/hw/pci-bridge/cxl_upstream.c +++ b/hw/pci-bridge/cxl_upstream.c @@ -10,11 +10,12 @@ #include "qemu/osdep.h" #include "qemu/log.h" +#include "hw/qdev-properties.h" #include "hw/pci/msi.h" #include "hw/pci/pcie.h" #include "hw/pci/pcie_port.h" -#define CXL_UPSTREAM_PORT_MSI_NR_VECTOR 1 +#define CXL_UPSTREAM_PORT_MSI_NR_VECTOR 2 #define CXL_UPSTREAM_PORT_MSI_OFFSET 0x70 #define CXL_UPSTREAM_PORT_PCIE_CAP_OFFSET 0x90 @@ -28,6 +29,7 @@ typedef struct CXLUpstreamPort { /*< public >*/ CXLComponentState cxl_cstate; + DOECap doe_cdat; } CXLUpstreamPort; CXLComponentState *cxl_usp_to_cstate(CXLUpstreamPort *usp) @@ -60,6 +62,9 @@ static void cxl_usp_dvsec_write_config(PCIDevice *dev, uint32_t addr, static void cxl_usp_write_config(PCIDevice *d, uint32_t address, uint32_t val, int len) { + CXLUpstreamPort *usp = CXL_USP(d); + + pcie_doe_write_config(&usp->doe_cdat, address, val, len); pci_bridge_write_config(d, address, val, len); pcie_cap_flr_write_config(d, address, val, len); pcie_aer_write_config(d, address, val, len); @@ -67,6 +72,18 @@ static void cxl_usp_write_config(PCIDevice *d, uint32_t address, cxl_usp_dvsec_write_config(d, address, val, len); } +static uint32_t cxl_usp_read_config(PCIDevice *d, uint32_t address, int len) +{ + CXLUpstreamPort *usp = CXL_USP(d); + uint32_t val; + + if (pcie_doe_read_config(&usp->doe_cdat, address, len, &val)) { + return val; + } + + return pci_default_read_config(d, address, len); +} + static void latch_registers(CXLUpstreamPort *usp) { uint32_t *reg_state = usp->cxl_cstate.crb.cache_mem_registers; @@ -119,6 +136,167 @@ static void build_dvsecs(CXLComponentState *cxl) REG_LOC_DVSEC_REVID, dvsec); } +static bool cxl_doe_cdat_rsp(DOECap *doe_cap) +{ + CDATObject *cdat = &CXL_USP(doe_cap->pdev)->cxl_cstate.cdat; + uint16_t ent; + void *base; + uint32_t len; + CDATReq *req = pcie_doe_get_write_mbox_ptr(doe_cap); + CDATRsp rsp; + + cxl_doe_cdat_update(&CXL_USP(doe_cap->pdev)->cxl_cstate, &error_fatal); + assert(cdat->entry_len); + + /* Discard if request length mismatched */ + if (pcie_doe_get_obj_len(req) < + DIV_ROUND_UP(sizeof(CDATReq), sizeof(uint32_t))) { + return false; + } + + ent = req->entry_handle; + base = cdat->entry[ent].base; + len = cdat->entry[ent].length; + + rsp = (CDATRsp) { + .header = { + .vendor_id = CXL_VENDOR_ID, + .data_obj_type = CXL_DOE_TABLE_ACCESS, + .reserved = 0x0, + .length = DIV_ROUND_UP((sizeof(rsp) + len), sizeof(uint32_t)), + }, + .rsp_code = CXL_DOE_TAB_RSP, + .table_type = CXL_DOE_TAB_TYPE_CDAT, + .entry_handle = (ent < cdat->entry_len - 1) ? + ent + 1 : CXL_DOE_TAB_ENT_MAX, + }; + + memcpy(doe_cap->read_mbox, &rsp, sizeof(rsp)); + memcpy(doe_cap->read_mbox + DIV_ROUND_UP(sizeof(rsp), sizeof(uint32_t)), + base, len); + + doe_cap->read_mbox_len += rsp.header.length; + + return true; +} + +static DOEProtocol doe_cdat_prot[] = { + { CXL_VENDOR_ID, CXL_DOE_TABLE_ACCESS, cxl_doe_cdat_rsp }, + { } +}; + +enum { + CXL_USP_CDAT_SSLBIS_LAT, + CXL_USP_CDAT_SSLBIS_BW, + CXL_USP_CDAT_NUM_ENTRIES +}; + +static int build_cdat_table(CDATSubHeader ***cdat_table, void *priv) +{ + g_autofree CDATSslbis *sslbis_latency = NULL; + g_autofree CDATSslbis *sslbis_bandwidth = NULL; + CXLUpstreamPort *us = CXL_USP(priv); + PCIBus *bus = &PCI_BRIDGE(us)->sec_bus; + int devfn, sslbis_size, i; + int count = 0; + uint16_t port_ids[256]; + + for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) { + PCIDevice *d = bus->devices[devfn]; + PCIEPort *port; + + if (!d || !pci_is_express(d) || !d->exp.exp_cap) { + continue; + } + + /* + * Whilst the PCI express spec doesn't allow anything other than + * downstream ports on this bus, let us be a little paranoid + */ + if (!object_dynamic_cast(OBJECT(d), TYPE_PCIE_PORT)) { + continue; + } + + port = PCIE_PORT(d); + port_ids[count] = port->port; + count++; + } + + /* May not yet have any ports - try again later */ + if (count == 0) { + return 0; + } + + sslbis_size = sizeof(CDATSslbis) + sizeof(*sslbis_latency->sslbe) * count; + sslbis_latency = g_malloc(sslbis_size); + if (!sslbis_latency) { + return -ENOMEM; + } + *sslbis_latency = (CDATSslbis) { + .sslbis_header = { + .header = { + .type = CDAT_TYPE_SSLBIS, + .length = sslbis_size, + }, + .data_type = HMATLB_DATA_TYPE_ACCESS_LATENCY, + .entry_base_unit = 10000, + }, + }; + + for (i = 0; i < count; i++) { + sslbis_latency->sslbe[i] = (CDATSslbe) { + .port_x_id = CDAT_PORT_ID_USP, + .port_y_id = port_ids[i], + .latency_bandwidth = 15, /* 150ns */ + }; + } + + sslbis_bandwidth = g_malloc(sslbis_size); + if (!sslbis_bandwidth) { + return 0; + } + *sslbis_bandwidth = (CDATSslbis) { + .sslbis_header = { + .header = { + .type = CDAT_TYPE_SSLBIS, + .length = sslbis_size, + }, + .data_type = HMATLB_DATA_TYPE_ACCESS_BANDWIDTH, + .entry_base_unit = 1000, + }, + }; + + for (i = 0; i < count; i++) { + sslbis_bandwidth->sslbe[i] = (CDATSslbe) { + .port_x_id = CDAT_PORT_ID_USP, + .port_y_id = port_ids[i], + .latency_bandwidth = 16, /* 16 GB/s */ + }; + } + + *cdat_table = g_malloc0(sizeof(*cdat_table) * CXL_USP_CDAT_NUM_ENTRIES); + if (!*cdat_table) { + return -ENOMEM; + } + + /* Header always at start of structure */ + (*cdat_table)[CXL_USP_CDAT_SSLBIS_LAT] = g_steal_pointer(&sslbis_latency); + (*cdat_table)[CXL_USP_CDAT_SSLBIS_BW] = g_steal_pointer(&sslbis_bandwidth); + + return CXL_USP_CDAT_NUM_ENTRIES; +} + +static void free_default_cdat_table(CDATSubHeader **cdat_table, int num, + void *priv) +{ + int i; + + for (i = 0; i < num; i++) { + g_free(cdat_table[i]); + } + g_free(cdat_table); +} + static void cxl_usp_realize(PCIDevice *d, Error **errp) { PCIEPort *p = PCIE_PORT(d); @@ -161,6 +339,14 @@ static void cxl_usp_realize(PCIDevice *d, Error **errp) PCI_BASE_ADDRESS_MEM_TYPE_64, component_bar); + pcie_doe_init(d, &usp->doe_cdat, cxl_cstate->dvsec_offset, doe_cdat_prot, + true, 1); + + cxl_cstate->cdat.build_cdat_table = build_cdat_table; + cxl_cstate->cdat.free_cdat_table = free_default_cdat_table; + cxl_cstate->cdat.private = d; + cxl_doe_cdat_init(cxl_cstate, errp); + return; err_cap: @@ -179,6 +365,11 @@ static void cxl_usp_exitfn(PCIDevice *d) pci_bridge_exitfn(d); } +static Property cxl_upstream_props[] = { + DEFINE_PROP_STRING("cdat", CXLUpstreamPort, cxl_cstate.cdat.filename), + DEFINE_PROP_END_OF_LIST() +}; + static void cxl_upstream_class_init(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); @@ -186,6 +377,7 @@ static void cxl_upstream_class_init(ObjectClass *oc, void *data) k->is_bridge = true; k->config_write = cxl_usp_write_config; + k->config_read = cxl_usp_read_config; k->realize = cxl_usp_realize; k->exit = cxl_usp_exitfn; k->vendor_id = 0x19e5; /* Huawei */ @@ -194,6 +386,7 @@ static void cxl_upstream_class_init(ObjectClass *oc, void *data) set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); dc->desc = "CXL Switch Upstream Port"; dc->reset = cxl_usp_reset; + device_class_set_props(dc, cxl_upstream_props); } static const TypeInfo cxl_usp_info = { diff --git a/include/hw/cxl/cxl_cdat.h b/include/hw/cxl/cxl_cdat.h index 52c232e912..e9eda00142 100644 --- a/include/hw/cxl/cxl_cdat.h +++ b/include/hw/cxl/cxl_cdat.h @@ -131,6 +131,7 @@ typedef struct CDATSslbisHeader { uint64_t entry_base_unit; } QEMU_PACKED CDATSslbisHeader; +#define CDAT_PORT_ID_USP 0x100 /* Switch Scoped Latency and Bandwidth Entry - CDAT Table 10 */ typedef struct CDATSslbe { uint16_t port_x_id; From e72cfabf4ef2f0031e5d0b8129fb1533d383654d Mon Sep 17 00:00:00 2001 From: Eric Auger Date: Wed, 12 Oct 2022 12:34:48 -0400 Subject: [PATCH 607/705] hw/virtio/virtio-iommu-pci: Enforce the device is plugged on the root bus In theory the virtio-iommu-pci could be plugged anywhere in the PCIe topology and as long as the dt/acpi info are properly built this should work. However at the moment we fail to do that because the virtio-iommu-pci BDF is not computed at plug time and in that case vms->virtio_iommu_bdf gets an incorrect value. For instance if the virtio-iommu-pci is plugged onto a pcie root port and the virtio-iommu protects a virtio-block-pci device the guest does not boot. So let's do not pretend we do support this case and fail the initialize() if we detect the virtio-iommu-pci is plugged anywhere else than on the root bus. Anyway this ability is not needed. Signed-off-by: Eric Auger Message-Id: <20221012163448.121368-1-eric.auger@redhat.com> Reviewed-by: Jean-Philippe Brucker Tested-by: Jean-Philippe Brucker Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/virtio/virtio-iommu-pci.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/hw/virtio/virtio-iommu-pci.c b/hw/virtio/virtio-iommu-pci.c index 79ea8334f0..7ef2f9dcdb 100644 --- a/hw/virtio/virtio-iommu-pci.c +++ b/hw/virtio/virtio-iommu-pci.c @@ -17,6 +17,7 @@ #include "hw/qdev-properties-system.h" #include "qapi/error.h" #include "hw/boards.h" +#include "hw/pci/pci_bus.h" #include "qom/object.h" typedef struct VirtIOIOMMUPCI VirtIOIOMMUPCI; @@ -44,6 +45,7 @@ static Property virtio_iommu_pci_properties[] = { static void virtio_iommu_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) { VirtIOIOMMUPCI *dev = VIRTIO_IOMMU_PCI(vpci_dev); + PCIBus *pbus = pci_get_bus(&vpci_dev->pci_dev); DeviceState *vdev = DEVICE(&dev->vdev); VirtIOIOMMU *s = VIRTIO_IOMMU(vdev); @@ -57,11 +59,17 @@ static void virtio_iommu_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) s->reserved_regions[i].type != VIRTIO_IOMMU_RESV_MEM_T_MSI) { error_setg(errp, "reserved region %d has an invalid type", i); error_append_hint(errp, "Valid values are 0 and 1\n"); + return; } } + if (!pci_bus_is_root(pbus)) { + error_setg(errp, "virtio-iommu-pci must be plugged on the root bus"); + return; + } + object_property_set_link(OBJECT(dev), "primary-bus", - OBJECT(pci_get_bus(&vpci_dev->pci_dev)), - &error_abort); + OBJECT(pbus), &error_abort); + virtio_pci_force_virtio_1(vpci_dev); qdev_realize(vdev, BUS(&vpci_dev->bus), errp); } From 3b43302c71854b263a4653b708699ce074082158 Mon Sep 17 00:00:00 2001 From: Xuan Zhuo Date: Mon, 17 Oct 2022 17:25:44 +0800 Subject: [PATCH 608/705] virtio: introduce __virtio_queue_reset() Separate the logic of vq reset. This logic will be called directly later. Signed-off-by: Xuan Zhuo Acked-by: Jason Wang Message-Id: <20221017092558.111082-2-xuanzhuo@linux.alibaba.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/virtio/virtio.c | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 808446b4c9..6f42fcadd7 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -2464,6 +2464,26 @@ static enum virtio_device_endian virtio_current_cpu_endian(void) } } +static void __virtio_queue_reset(VirtIODevice *vdev, uint32_t i) +{ + vdev->vq[i].vring.desc = 0; + vdev->vq[i].vring.avail = 0; + vdev->vq[i].vring.used = 0; + vdev->vq[i].last_avail_idx = 0; + vdev->vq[i].shadow_avail_idx = 0; + vdev->vq[i].used_idx = 0; + vdev->vq[i].last_avail_wrap_counter = true; + vdev->vq[i].shadow_avail_wrap_counter = true; + vdev->vq[i].used_wrap_counter = true; + virtio_queue_set_vector(vdev, i, VIRTIO_NO_VECTOR); + vdev->vq[i].signalled_used = 0; + vdev->vq[i].signalled_used_valid = false; + vdev->vq[i].notification = true; + vdev->vq[i].vring.num = vdev->vq[i].vring.num_default; + vdev->vq[i].inuse = 0; + virtio_virtqueue_reset_region_cache(&vdev->vq[i]); +} + void virtio_reset(void *opaque) { VirtIODevice *vdev = opaque; @@ -2495,22 +2515,7 @@ void virtio_reset(void *opaque) virtio_notify_vector(vdev, vdev->config_vector); for(i = 0; i < VIRTIO_QUEUE_MAX; i++) { - vdev->vq[i].vring.desc = 0; - vdev->vq[i].vring.avail = 0; - vdev->vq[i].vring.used = 0; - vdev->vq[i].last_avail_idx = 0; - vdev->vq[i].shadow_avail_idx = 0; - vdev->vq[i].used_idx = 0; - vdev->vq[i].last_avail_wrap_counter = true; - vdev->vq[i].shadow_avail_wrap_counter = true; - vdev->vq[i].used_wrap_counter = true; - virtio_queue_set_vector(vdev, i, VIRTIO_NO_VECTOR); - vdev->vq[i].signalled_used = 0; - vdev->vq[i].signalled_used_valid = false; - vdev->vq[i].notification = true; - vdev->vq[i].vring.num = vdev->vq[i].vring.num_default; - vdev->vq[i].inuse = 0; - virtio_virtqueue_reset_region_cache(&vdev->vq[i]); + __virtio_queue_reset(vdev, i); } } From b3a8d6f431730858162feb2dfcee85d0f3484992 Mon Sep 17 00:00:00 2001 From: Xuan Zhuo Date: Mon, 17 Oct 2022 17:25:45 +0800 Subject: [PATCH 609/705] virtio: introduce virtio_queue_reset() Introduce a new interface function virtio_queue_reset() to implement reset for vq. Add a new callback to VirtioDeviceClass for queue reset operation for each child device. Signed-off-by: Xuan Zhuo Acked-by: Jason Wang Message-Id: <20221017092558.111082-3-xuanzhuo@linux.alibaba.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/virtio/virtio.c | 11 +++++++++++ include/hw/virtio/virtio.h | 2 ++ 2 files changed, 13 insertions(+) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 6f42fcadd7..cf5f9ca387 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -2484,6 +2484,17 @@ static void __virtio_queue_reset(VirtIODevice *vdev, uint32_t i) virtio_virtqueue_reset_region_cache(&vdev->vq[i]); } +void virtio_queue_reset(VirtIODevice *vdev, uint32_t queue_index) +{ + VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); + + if (k->queue_reset) { + k->queue_reset(vdev, queue_index); + } + + __virtio_queue_reset(vdev, queue_index); +} + void virtio_reset(void *opaque) { VirtIODevice *vdev = opaque; diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index f41b4a7e64..74d76c1dbc 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -148,6 +148,7 @@ struct VirtioDeviceClass { void (*set_config)(VirtIODevice *vdev, const uint8_t *config); void (*reset)(VirtIODevice *vdev); void (*set_status)(VirtIODevice *vdev, uint8_t val); + void (*queue_reset)(VirtIODevice *vdev, uint32_t queue_index); /* For transitional devices, this is a bitmap of features * that are only exposed on the legacy interface but not * the modern one. @@ -286,6 +287,7 @@ int virtio_queue_set_host_notifier_mr(VirtIODevice *vdev, int n, MemoryRegion *mr, bool assign); int virtio_set_status(VirtIODevice *vdev, uint8_t val); void virtio_reset(void *opaque); +void virtio_queue_reset(VirtIODevice *vdev, uint32_t queue_index); void virtio_update_irq(VirtIODevice *vdev); int virtio_set_features(VirtIODevice *vdev, uint64_t val); From 3c37f8b8d1e5f524c9d04d3e1d8125334e93e2eb Mon Sep 17 00:00:00 2001 From: Kangjie Xu Date: Mon, 17 Oct 2022 17:25:46 +0800 Subject: [PATCH 610/705] virtio: introduce virtio_queue_enable() Introduce the interface queue_enable() in VirtioDeviceClass and the fucntion virtio_queue_enable() in virtio, it can be called when VIRTIO_PCI_COMMON_Q_ENABLE is written and related virtqueue can be started. It only supports the devices of virtio 1 or later. The not-supported devices can only start the virtqueue when DRIVER_OK. Signed-off-by: Kangjie Xu Signed-off-by: Xuan Zhuo Acked-by: Jason Wang Message-Id: <20221017092558.111082-4-xuanzhuo@linux.alibaba.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/virtio/virtio.c | 14 ++++++++++++++ include/hw/virtio/virtio.h | 2 ++ 2 files changed, 16 insertions(+) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index cf5f9ca387..9683b2e158 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -2495,6 +2495,20 @@ void virtio_queue_reset(VirtIODevice *vdev, uint32_t queue_index) __virtio_queue_reset(vdev, queue_index); } +void virtio_queue_enable(VirtIODevice *vdev, uint32_t queue_index) +{ + VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); + + if (!virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) { + error_report("queue_enable is only suppported in devices of virtio " + "1.0 or later."); + } + + if (k->queue_enable) { + k->queue_enable(vdev, queue_index); + } +} + void virtio_reset(void *opaque) { VirtIODevice *vdev = opaque; diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 74d76c1dbc..b00b3fcf31 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -149,6 +149,7 @@ struct VirtioDeviceClass { void (*reset)(VirtIODevice *vdev); void (*set_status)(VirtIODevice *vdev, uint8_t val); void (*queue_reset)(VirtIODevice *vdev, uint32_t queue_index); + void (*queue_enable)(VirtIODevice *vdev, uint32_t queue_index); /* For transitional devices, this is a bitmap of features * that are only exposed on the legacy interface but not * the modern one. @@ -288,6 +289,7 @@ int virtio_queue_set_host_notifier_mr(VirtIODevice *vdev, int n, int virtio_set_status(VirtIODevice *vdev, uint8_t val); void virtio_reset(void *opaque); void virtio_queue_reset(VirtIODevice *vdev, uint32_t queue_index); +void virtio_queue_enable(VirtIODevice *vdev, uint32_t queue_index); void virtio_update_irq(VirtIODevice *vdev); int virtio_set_features(VirtIODevice *vdev, uint64_t val); From 69e1c14aa22284f933a6ea134b96d5cb5a88a94d Mon Sep 17 00:00:00 2001 From: Kangjie Xu Date: Mon, 17 Oct 2022 17:25:47 +0800 Subject: [PATCH 611/705] virtio: core: vq reset feature negotation support A a new command line parameter "queue_reset" is added. Meanwhile, the vq reset feature is disabled for pre-7.2 machines. Signed-off-by: Kangjie Xu Signed-off-by: Xuan Zhuo Acked-by: Jason Wang Message-Id: <20221017092558.111082-5-xuanzhuo@linux.alibaba.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/core/machine.c | 4 +++- include/hw/virtio/virtio.h | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/hw/core/machine.c b/hw/core/machine.c index aa520e74a8..907fa78ff0 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -40,7 +40,9 @@ #include "hw/virtio/virtio-pci.h" #include "qom/object_interfaces.h" -GlobalProperty hw_compat_7_1[] = {}; +GlobalProperty hw_compat_7_1[] = { + { "virtio-device", "queue_reset", "false" }, +}; const size_t hw_compat_7_1_len = G_N_ELEMENTS(hw_compat_7_1); GlobalProperty hw_compat_7_0[] = { diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index b00b3fcf31..1423dba379 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -313,7 +313,9 @@ typedef struct VirtIORNGConf VirtIORNGConf; DEFINE_PROP_BIT64("iommu_platform", _state, _field, \ VIRTIO_F_IOMMU_PLATFORM, false), \ DEFINE_PROP_BIT64("packed", _state, _field, \ - VIRTIO_F_RING_PACKED, false) + VIRTIO_F_RING_PACKED, false), \ + DEFINE_PROP_BIT64("queue_reset", _state, _field, \ + VIRTIO_F_RING_RESET, true) hwaddr virtio_queue_get_desc_addr(VirtIODevice *vdev, int n); bool virtio_queue_enabled_legacy(VirtIODevice *vdev, int n); From 805d782d284cba013707d5edf38b04047b21d4b5 Mon Sep 17 00:00:00 2001 From: Xuan Zhuo Date: Mon, 17 Oct 2022 17:25:48 +0800 Subject: [PATCH 612/705] virtio-pci: support queue reset PCI devices support vq reset. Based on this function, the driver can adjust the size of the ring, and quickly recycle the buffer in the ring. The migration of the virtio devices will not happen during a reset operation. This is becuase the global iothread lock is held. Migration thread also needs the lock. As a result, when migration of virtio devices starts, the 'reset' status of VirtIOPCIQueue will always be 0. Thus, we do not need to add it in vmstate_virtio_pci_modern_queue_state. Signed-off-by: Xuan Zhuo Signed-off-by: Kangjie Xu Acked-by: Jason Wang Message-Id: <20221017092558.111082-6-xuanzhuo@linux.alibaba.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/virtio/virtio-pci.c | 15 +++++++++++++++ include/hw/virtio/virtio-pci.h | 5 +++++ 2 files changed, 20 insertions(+) diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 34db51e241..d4f2ffe986 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -1251,6 +1251,9 @@ static uint64_t virtio_pci_common_read(void *opaque, hwaddr addr, case VIRTIO_PCI_COMMON_Q_USEDHI: val = proxy->vqs[vdev->queue_sel].used[1]; break; + case VIRTIO_PCI_COMMON_Q_RESET: + val = proxy->vqs[vdev->queue_sel].reset; + break; default: val = 0; } @@ -1338,6 +1341,7 @@ static void virtio_pci_common_write(void *opaque, hwaddr addr, ((uint64_t)proxy->vqs[vdev->queue_sel].used[1]) << 32 | proxy->vqs[vdev->queue_sel].used[0]); proxy->vqs[vdev->queue_sel].enabled = 1; + proxy->vqs[vdev->queue_sel].reset = 0; } else { virtio_error(vdev, "wrong value for queue_enable %"PRIx64, val); } @@ -1360,6 +1364,16 @@ static void virtio_pci_common_write(void *opaque, hwaddr addr, case VIRTIO_PCI_COMMON_Q_USEDHI: proxy->vqs[vdev->queue_sel].used[1] = val; break; + case VIRTIO_PCI_COMMON_Q_RESET: + if (val == 1) { + proxy->vqs[vdev->queue_sel].reset = 1; + + virtio_queue_reset(vdev, vdev->queue_sel); + + proxy->vqs[vdev->queue_sel].reset = 0; + proxy->vqs[vdev->queue_sel].enabled = 0; + } + break; default: break; } @@ -1954,6 +1968,7 @@ static void virtio_pci_reset(DeviceState *qdev) for (i = 0; i < VIRTIO_QUEUE_MAX; i++) { proxy->vqs[i].enabled = 0; + proxy->vqs[i].reset = 0; proxy->vqs[i].num = 0; proxy->vqs[i].desc[0] = proxy->vqs[i].desc[1] = 0; proxy->vqs[i].avail[0] = proxy->vqs[i].avail[1] = 0; diff --git a/include/hw/virtio/virtio-pci.h b/include/hw/virtio/virtio-pci.h index 2446dcd9ae..938799e8f6 100644 --- a/include/hw/virtio/virtio-pci.h +++ b/include/hw/virtio/virtio-pci.h @@ -117,6 +117,11 @@ typedef struct VirtIOPCIRegion { typedef struct VirtIOPCIQueue { uint16_t num; bool enabled; + /* + * No need to migrate the reset status, because it is always 0 + * when the migration starts. + */ + bool reset; uint32_t desc[2]; uint32_t avail[2]; uint32_t used[2]; From d1060e3dc5444755c8bc056908275c2d715c6608 Mon Sep 17 00:00:00 2001 From: Kangjie Xu Date: Mon, 17 Oct 2022 17:25:49 +0800 Subject: [PATCH 613/705] virtio-pci: support queue enable PCI devices support device specific vq enable. Based on this function, the driver can re-enable the virtqueue after the virtqueue is reset. Signed-off-by: Kangjie Xu Signed-off-by: Xuan Zhuo Acked-by: Jason Wang Message-Id: <20221017092558.111082-7-xuanzhuo@linux.alibaba.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/virtio/virtio-pci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index d4f2ffe986..855718d586 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -1342,6 +1342,7 @@ static void virtio_pci_common_write(void *opaque, hwaddr addr, proxy->vqs[vdev->queue_sel].used[0]); proxy->vqs[vdev->queue_sel].enabled = 1; proxy->vqs[vdev->queue_sel].reset = 0; + virtio_queue_enable(vdev, vdev->queue_sel); } else { virtio_error(vdev, "wrong value for queue_enable %"PRIx64, val); } From ff48b62809fc3d50e335965c6cb69bec20a495f3 Mon Sep 17 00:00:00 2001 From: Kangjie Xu Date: Mon, 17 Oct 2022 17:25:50 +0800 Subject: [PATCH 614/705] vhost: expose vhost_virtqueue_start() Expose vhost_virtqueue_start(), we need to use it when restarting a virtqueue. Signed-off-by: Kangjie Xu Signed-off-by: Xuan Zhuo Acked-by: Jason Wang Message-Id: <20221017092558.111082-8-xuanzhuo@linux.alibaba.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/virtio/vhost.c | 8 ++++---- include/hw/virtio/vhost.h | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c index 5185c15295..788d0a0679 100644 --- a/hw/virtio/vhost.c +++ b/hw/virtio/vhost.c @@ -1081,10 +1081,10 @@ out: return ret; } -static int vhost_virtqueue_start(struct vhost_dev *dev, - struct VirtIODevice *vdev, - struct vhost_virtqueue *vq, - unsigned idx) +int vhost_virtqueue_start(struct vhost_dev *dev, + struct VirtIODevice *vdev, + struct vhost_virtqueue *vq, + unsigned idx) { BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); VirtioBusState *vbus = VIRTIO_BUS(qbus); diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h index d7eb557885..0054a695dc 100644 --- a/include/hw/virtio/vhost.h +++ b/include/hw/virtio/vhost.h @@ -297,6 +297,9 @@ int vhost_net_set_backend(struct vhost_dev *hdev, int vhost_device_iotlb_miss(struct vhost_dev *dev, uint64_t iova, int write); +int vhost_virtqueue_start(struct vhost_dev *dev, struct VirtIODevice *vdev, + struct vhost_virtqueue *vq, unsigned idx); + void vhost_dev_reset_inflight(struct vhost_inflight *inflight); void vhost_dev_free_inflight(struct vhost_inflight *inflight); void vhost_dev_save_inflight(struct vhost_inflight *inflight, QEMUFile *f); From e1f101d9f60c81b5186098b6dfd196b2730f2070 Mon Sep 17 00:00:00 2001 From: Kangjie Xu Date: Mon, 17 Oct 2022 17:25:51 +0800 Subject: [PATCH 615/705] vhost: expose vhost_virtqueue_stop() Expose vhost_virtqueue_stop(), we need to use it when resetting a virtqueue. Signed-off-by: Kangjie Xu Signed-off-by: Xuan Zhuo Acked-by: Jason Wang Message-Id: <20221017092558.111082-9-xuanzhuo@linux.alibaba.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/virtio/vhost.c | 8 ++++---- include/hw/virtio/vhost.h | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c index 788d0a0679..d1c4c20b8c 100644 --- a/hw/virtio/vhost.c +++ b/hw/virtio/vhost.c @@ -1201,10 +1201,10 @@ fail_alloc_desc: return r; } -static void vhost_virtqueue_stop(struct vhost_dev *dev, - struct VirtIODevice *vdev, - struct vhost_virtqueue *vq, - unsigned idx) +void vhost_virtqueue_stop(struct vhost_dev *dev, + struct VirtIODevice *vdev, + struct vhost_virtqueue *vq, + unsigned idx) { int vhost_vq_index = dev->vhost_ops->vhost_get_vq_index(dev, idx); struct vhost_vring_state state = { diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h index 0054a695dc..353252ac3e 100644 --- a/include/hw/virtio/vhost.h +++ b/include/hw/virtio/vhost.h @@ -299,6 +299,8 @@ int vhost_device_iotlb_miss(struct vhost_dev *dev, uint64_t iova, int write); int vhost_virtqueue_start(struct vhost_dev *dev, struct VirtIODevice *vdev, struct vhost_virtqueue *vq, unsigned idx); +void vhost_virtqueue_stop(struct vhost_dev *dev, struct VirtIODevice *vdev, + struct vhost_virtqueue *vq, unsigned idx); void vhost_dev_reset_inflight(struct vhost_inflight *inflight); void vhost_dev_free_inflight(struct vhost_inflight *inflight); From c2daa08e1713c4799487bae6daf5d41e024ff736 Mon Sep 17 00:00:00 2001 From: Kangjie Xu Date: Mon, 17 Oct 2022 17:25:52 +0800 Subject: [PATCH 616/705] vhost-net: vhost-kernel: introduce vhost_net_virtqueue_reset() Introduce vhost_virtqueue_reset(), which can reset the specific virtqueue in the device. Then it will unmap vrings and the desc of the virtqueue. Here we do not reuse the vhost_net_stop_one() or vhost_dev_stop(), because they work at queue pair level. We do not use vhost_virtqueue_stop() because it may stop the device in the backend. This patch only considers the case of vhost-kernel, when NetClientDriver is NET_CLIENT_DRIVER_TAP. Furthermore, we do not need net->nc->info->poll() because it enables userspace datapath and we want to stop all datapaths for this reset virtqueue here. Signed-off-by: Kangjie Xu Signed-off-by: Xuan Zhuo Acked-by: Jason Wang Message-Id: <20221017092558.111082-10-xuanzhuo@linux.alibaba.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/net/vhost_net-stub.c | 6 ++++++ hw/net/vhost_net.c | 25 +++++++++++++++++++++++++ include/net/vhost_net.h | 2 ++ 3 files changed, 33 insertions(+) diff --git a/hw/net/vhost_net-stub.c b/hw/net/vhost_net-stub.c index 89d71cfb8e..2d745e359c 100644 --- a/hw/net/vhost_net-stub.c +++ b/hw/net/vhost_net-stub.c @@ -101,3 +101,9 @@ int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu) { return 0; } + +void vhost_net_virtqueue_reset(VirtIODevice *vdev, NetClientState *nc, + int vq_index) +{ + +} diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c index d28f8b974b..8beecb4d22 100644 --- a/hw/net/vhost_net.c +++ b/hw/net/vhost_net.c @@ -531,3 +531,28 @@ int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu) return vhost_ops->vhost_net_set_mtu(&net->dev, mtu); } + +void vhost_net_virtqueue_reset(VirtIODevice *vdev, NetClientState *nc, + int vq_index) +{ + VHostNetState *net = get_vhost_net(nc->peer); + const VhostOps *vhost_ops = net->dev.vhost_ops; + struct vhost_vring_file file = { .fd = -1 }; + int idx; + + /* should only be called after backend is connected */ + assert(vhost_ops); + + idx = vhost_ops->vhost_get_vq_index(&net->dev, vq_index); + + if (net->nc->info->type == NET_CLIENT_DRIVER_TAP) { + file.index = idx; + int r = vhost_net_set_backend(&net->dev, &file); + assert(r >= 0); + } + + vhost_virtqueue_stop(&net->dev, + vdev, + net->dev.vqs + idx, + net->dev.vq_index + idx); +} diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h index 387e913e4e..85d85a4957 100644 --- a/include/net/vhost_net.h +++ b/include/net/vhost_net.h @@ -48,4 +48,6 @@ uint64_t vhost_net_get_acked_features(VHostNetState *net); int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu); +void vhost_net_virtqueue_reset(VirtIODevice *vdev, NetClientState *nc, + int vq_index); #endif From 10f8a115a862045a836932c5d519a848dda5d461 Mon Sep 17 00:00:00 2001 From: Kangjie Xu Date: Mon, 17 Oct 2022 17:25:53 +0800 Subject: [PATCH 617/705] vhost-net: vhost-kernel: introduce vhost_net_virtqueue_restart() Introduce vhost_net_virtqueue_restart(), which can restart the specific virtqueue when the vhost net started running before. If it fails to restart the virtqueue, the device will be stopped. Here we do not reuse vhost_net_start_one() or vhost_dev_start() because they work at queue pair level. The mem table and features do not change, so we can call the vhost_virtqueue_start() to restart a specific queue. This patch only considers the case of vhost-kernel, when NetClientDriver is NET_CLIENT_DRIVER_TAP. Signed-off-by: Kangjie Xu Signed-off-by: Xuan Zhuo Acked-by: Jason Wang Message-Id: <20221017092558.111082-11-xuanzhuo@linux.alibaba.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/net/vhost_net-stub.c | 6 +++++ hw/net/vhost_net.c | 53 +++++++++++++++++++++++++++++++++++++++++ include/net/vhost_net.h | 2 ++ 3 files changed, 61 insertions(+) diff --git a/hw/net/vhost_net-stub.c b/hw/net/vhost_net-stub.c index 2d745e359c..9f7daae99c 100644 --- a/hw/net/vhost_net-stub.c +++ b/hw/net/vhost_net-stub.c @@ -107,3 +107,9 @@ void vhost_net_virtqueue_reset(VirtIODevice *vdev, NetClientState *nc, { } + +int vhost_net_virtqueue_restart(VirtIODevice *vdev, NetClientState *nc, + int vq_index) +{ + return 0; +} diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c index 8beecb4d22..d2926e2ed6 100644 --- a/hw/net/vhost_net.c +++ b/hw/net/vhost_net.c @@ -34,6 +34,7 @@ #include "standard-headers/linux/virtio_ring.h" #include "hw/virtio/vhost.h" #include "hw/virtio/virtio-bus.h" +#include "linux-headers/linux/vhost.h" /* Features supported by host kernel. */ @@ -556,3 +557,55 @@ void vhost_net_virtqueue_reset(VirtIODevice *vdev, NetClientState *nc, net->dev.vqs + idx, net->dev.vq_index + idx); } + +int vhost_net_virtqueue_restart(VirtIODevice *vdev, NetClientState *nc, + int vq_index) +{ + VHostNetState *net = get_vhost_net(nc->peer); + const VhostOps *vhost_ops = net->dev.vhost_ops; + struct vhost_vring_file file = { }; + int idx, r; + + if (!net->dev.started) { + return -EBUSY; + } + + /* should only be called after backend is connected */ + assert(vhost_ops); + + idx = vhost_ops->vhost_get_vq_index(&net->dev, vq_index); + + r = vhost_virtqueue_start(&net->dev, + vdev, + net->dev.vqs + idx, + net->dev.vq_index + idx); + if (r < 0) { + goto err_start; + } + + if (net->nc->info->type == NET_CLIENT_DRIVER_TAP) { + file.index = idx; + file.fd = net->backend; + r = vhost_net_set_backend(&net->dev, &file); + if (r < 0) { + r = -errno; + goto err_start; + } + } + + return 0; + +err_start: + error_report("Error when restarting the queue."); + + if (net->nc->info->type == NET_CLIENT_DRIVER_TAP) { + file.fd = VHOST_FILE_UNBIND; + file.index = idx; + int r = vhost_net_set_backend(&net->dev, &file); + assert(r >= 0); + } + + vhost_dev_stop(&net->dev, vdev); + + return r; +} diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h index 85d85a4957..40b9a40074 100644 --- a/include/net/vhost_net.h +++ b/include/net/vhost_net.h @@ -50,4 +50,6 @@ int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu); void vhost_net_virtqueue_reset(VirtIODevice *vdev, NetClientState *nc, int vq_index); +int vhost_net_virtqueue_restart(VirtIODevice *vdev, NetClientState *nc, + int vq_index); #endif From 4fdf69ab691e513280a3b5529de997d95a29f358 Mon Sep 17 00:00:00 2001 From: Kangjie Xu Date: Mon, 17 Oct 2022 17:25:54 +0800 Subject: [PATCH 618/705] virtio-net: introduce flush_or_purge_queued_packets() Introduce the fucntion flush_or_purge_queued_packets(), it will be used in device reset and virtqueue reset. Therefore, we extract the common logic as a new function. Signed-off-by: Kangjie Xu Signed-off-by: Xuan Zhuo Acked-by: Jason Wang Message-Id: <20221017092558.111082-12-xuanzhuo@linux.alibaba.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/net/virtio-net.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index b6903aea54..038a6fba7c 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -124,6 +124,16 @@ static int vq2q(int queue_index) return queue_index / 2; } +static void flush_or_purge_queued_packets(NetClientState *nc) +{ + if (!nc->peer) { + return; + } + + qemu_flush_or_purge_queued_packets(nc->peer, true); + assert(!virtio_net_get_subqueue(nc)->async_tx.elem); +} + /* TODO * - we could suppress RX interrupt if we were so inclined. */ @@ -566,12 +576,7 @@ static void virtio_net_reset(VirtIODevice *vdev) /* Flush any async TX */ for (i = 0; i < n->max_queue_pairs; i++) { - NetClientState *nc = qemu_get_subqueue(n->nic, i); - - if (nc->peer) { - qemu_flush_or_purge_queued_packets(nc->peer, true); - assert(!virtio_net_get_subqueue(nc)->async_tx.elem); - } + flush_or_purge_queued_packets(qemu_get_subqueue(n->nic, i)); } } From 7dc6be52f4ead25e7da8fb758900bdcb527996f7 Mon Sep 17 00:00:00 2001 From: Xuan Zhuo Date: Mon, 17 Oct 2022 17:25:55 +0800 Subject: [PATCH 619/705] virtio-net: support queue reset virtio-net and vhost-kernel implement queue reset. Queued packets in the corresponding queue pair are flushed or purged. For virtio-net, userspace datapath will be disabled later in __virtio_queue_reset(). It will set addr of vring to 0 and idx to 0. Thus, virtio_net_receive() and virtio_net_flush_tx() will not receive or send packets. For vhost-net, the datapath will be disabled in vhost_net_virtqueue_reset(). Signed-off-by: Xuan Zhuo Signed-off-by: Kangjie Xu Acked-by: Jason Wang Message-Id: <20221017092558.111082-13-xuanzhuo@linux.alibaba.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/net/virtio-net.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 038a6fba7c..34fb4b1423 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -546,6 +546,23 @@ static RxFilterInfo *virtio_net_query_rxfilter(NetClientState *nc) return info; } +static void virtio_net_queue_reset(VirtIODevice *vdev, uint32_t queue_index) +{ + VirtIONet *n = VIRTIO_NET(vdev); + NetClientState *nc = qemu_get_subqueue(n->nic, vq2q(queue_index)); + + if (!nc->peer) { + return; + } + + if (get_vhost_net(nc->peer) && + nc->peer->info->type == NET_CLIENT_DRIVER_TAP) { + vhost_net_virtqueue_reset(vdev, nc, queue_index); + } + + flush_or_purge_queued_packets(nc); +} + static void virtio_net_reset(VirtIODevice *vdev) { VirtIONet *n = VIRTIO_NET(vdev); @@ -3827,6 +3844,7 @@ static void virtio_net_class_init(ObjectClass *klass, void *data) vdc->set_features = virtio_net_set_features; vdc->bad_features = virtio_net_bad_features; vdc->reset = virtio_net_reset; + vdc->queue_reset = virtio_net_queue_reset; vdc->set_status = virtio_net_set_status; vdc->guest_notifier_mask = virtio_net_guest_notifier_mask; vdc->guest_notifier_pending = virtio_net_guest_notifier_pending; From 7f863302bdb8c2d231e3d0927e0355e3c10d0cfb Mon Sep 17 00:00:00 2001 From: Kangjie Xu Date: Mon, 17 Oct 2022 17:25:56 +0800 Subject: [PATCH 620/705] virtio-net: support queue_enable Support queue_enable in vhost-kernel scenario. It can be called when a vq reset operation has been performed and the vq is restared. It should be noted that we can restart the vq when the vhost has already started. When launching a new vhost device, the vhost is not started and all vqs are not initalized until VIRTIO_PCI_COMMON_STATUS is written. Thus, we should use vhost_started to differentiate the two cases: vq reset and device start. Currently it only supports vhost-kernel. Signed-off-by: Kangjie Xu Signed-off-by: Xuan Zhuo Acked-by: Jason Wang Message-Id: <20221017092558.111082-14-xuanzhuo@linux.alibaba.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/net/virtio-net.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 34fb4b1423..e68daf51bb 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -563,6 +563,26 @@ static void virtio_net_queue_reset(VirtIODevice *vdev, uint32_t queue_index) flush_or_purge_queued_packets(nc); } +static void virtio_net_queue_enable(VirtIODevice *vdev, uint32_t queue_index) +{ + VirtIONet *n = VIRTIO_NET(vdev); + NetClientState *nc = qemu_get_subqueue(n->nic, vq2q(queue_index)); + int r; + + if (!nc->peer || !vdev->vhost_started) { + return; + } + + if (get_vhost_net(nc->peer) && + nc->peer->info->type == NET_CLIENT_DRIVER_TAP) { + r = vhost_net_virtqueue_restart(vdev, nc, queue_index); + if (r < 0) { + error_report("unable to restart vhost net virtqueue: %d, " + "when resetting the queue", queue_index); + } + } +} + static void virtio_net_reset(VirtIODevice *vdev) { VirtIONet *n = VIRTIO_NET(vdev); @@ -3845,6 +3865,7 @@ static void virtio_net_class_init(ObjectClass *klass, void *data) vdc->bad_features = virtio_net_bad_features; vdc->reset = virtio_net_reset; vdc->queue_reset = virtio_net_queue_reset; + vdc->queue_enable = virtio_net_queue_enable; vdc->set_status = virtio_net_set_status; vdc->guest_notifier_mask = virtio_net_guest_notifier_mask; vdc->guest_notifier_pending = virtio_net_guest_notifier_pending; From 2a3552baafb60082088174806b3a50f1c9dbc53a Mon Sep 17 00:00:00 2001 From: Kangjie Xu Date: Mon, 17 Oct 2022 17:25:57 +0800 Subject: [PATCH 621/705] vhost: vhost-kernel: enable vq reset feature Add virtqueue reset feature for vhost-kernel. Signed-off-by: Kangjie Xu Signed-off-by: Xuan Zhuo Acked-by: Jason Wang Message-Id: <20221017092558.111082-15-xuanzhuo@linux.alibaba.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/net/vhost_net.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c index d2926e2ed6..53b2fac4f6 100644 --- a/hw/net/vhost_net.c +++ b/hw/net/vhost_net.c @@ -47,6 +47,7 @@ static const int kernel_feature_bits[] = { VIRTIO_NET_F_MTU, VIRTIO_F_IOMMU_PLATFORM, VIRTIO_F_RING_PACKED, + VIRTIO_F_RING_RESET, VIRTIO_NET_F_HASH_REPORT, VHOST_INVALID_FEATURE_BIT }; From 93a97dc5200a95e63b99cb625f20b7ae802ba413 Mon Sep 17 00:00:00 2001 From: Xuan Zhuo Date: Mon, 17 Oct 2022 17:25:58 +0800 Subject: [PATCH 622/705] virtio-net: enable vq reset feature Add virtqueue reset feature for virtio-net Signed-off-by: Xuan Zhuo Message-Id: <20221017092558.111082-16-xuanzhuo@linux.alibaba.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/net/virtio-net.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index e68daf51bb..8b32339b76 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -788,6 +788,7 @@ static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features, } if (!get_vhost_net(nc->peer)) { + virtio_add_feature(&features, VIRTIO_F_RING_RESET); return features; } From 9ea02e8f13068d5f902c4bce909de2997fd77e41 Mon Sep 17 00:00:00 2001 From: David Daney Date: Fri, 14 Oct 2022 18:09:47 +0200 Subject: [PATCH 623/705] virtio-rng-pci: Allow setting nvectors, so we can use MSI-X MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Most other virtio-pci devices allow MSI-X, let's have it for rng too. Signed-off-by: David Daney Reviewed-by: Marcin Nowakowski Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20221014160947.66105-1-philmd@fungible.com> Reviewed-by: Stefan Hajnoczi Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/virtio/virtio-rng-pci.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/hw/virtio/virtio-rng-pci.c b/hw/virtio/virtio-rng-pci.c index 151ece6f94..6e76f8b57b 100644 --- a/hw/virtio/virtio-rng-pci.c +++ b/hw/virtio/virtio-rng-pci.c @@ -13,6 +13,7 @@ #include "hw/virtio/virtio-pci.h" #include "hw/virtio/virtio-rng.h" +#include "hw/qdev-properties.h" #include "qapi/error.h" #include "qemu/module.h" #include "qom/object.h" @@ -31,11 +32,23 @@ struct VirtIORngPCI { VirtIORNG vdev; }; +static Property virtio_rng_properties[] = { + DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, + VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true), + DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, + DEV_NVECTORS_UNSPECIFIED), + DEFINE_PROP_END_OF_LIST(), +}; + static void virtio_rng_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) { VirtIORngPCI *vrng = VIRTIO_RNG_PCI(vpci_dev); DeviceState *vdev = DEVICE(&vrng->vdev); + if (vpci_dev->nvectors == DEV_NVECTORS_UNSPECIFIED) { + vpci_dev->nvectors = 2; + } + if (!qdev_realize(vdev, BUS(&vpci_dev->bus), errp)) { return; } @@ -54,6 +67,7 @@ static void virtio_rng_pci_class_init(ObjectClass *klass, void *data) pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_RNG; pcidev_k->revision = VIRTIO_PCI_ABI_VERSION; pcidev_k->class_id = PCI_CLASS_OTHERS; + device_class_set_props(dc, virtio_rng_properties); } static void virtio_rng_initfn(Object *obj) From bd437c960f2b071f7e8ba9bd34af8e2537cd6627 Mon Sep 17 00:00:00 2001 From: Yajun Wu Date: Tue, 18 Oct 2022 10:36:51 +0800 Subject: [PATCH 624/705] vhost-user: Fix out of order vring host notification handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit vhost backend sends host notification for every VQ. If backend creates VQs in parallel, the VHOST_USER_SLAVE_VRING_HOST_NOTIFIER_MSG may arrive to QEMU in different order than incremental queue index order. For example VQ 1's message arrive earlier than VQ 0's: After alloc VhostUserHostNotifier for VQ 1. GPtrArray becomes [ nil, VQ1 pointer ] After alloc VhostUserHostNotifier for VQ 0. GPtrArray becomes [ VQ0 pointer, nil, VQ1 pointer ] This is wrong. fetch_notifier will return NULL for VQ 1 in vhost_user_get_vring_base, causes host notifier miss removal(leak). The fix is to remove current element from GPtrArray, make the right position for element to insert. Fixes: 503e355465 ("virtio/vhost-user: dynamically assign VhostUserHostNotifiers") Signed-off-by: Yajun Wu Acked-by: Parav Pandit Message-Id: <20221018023651.1359420-1-yajunw@nvidia.com> Reviewed-by: Alex Bennée Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/virtio/vhost-user.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c index 03415b6c95..d256ce589b 100644 --- a/hw/virtio/vhost-user.c +++ b/hw/virtio/vhost-user.c @@ -1543,6 +1543,11 @@ static VhostUserHostNotifier *fetch_or_create_notifier(VhostUserState *u, n = g_ptr_array_index(u->notifiers, idx); if (!n) { + /* + * In case notification arrive out-of-order, + * make room for current index. + */ + g_ptr_array_remove_index(u->notifiers, idx); n = g_new0(VhostUserHostNotifier, 1); n->idx = idx; g_ptr_array_insert(u->notifiers, idx, n); From cfead31326409dad187024de1bf7b40d7a86737e Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Mon, 17 Oct 2022 12:21:36 +0200 Subject: [PATCH 625/705] acpi: pc: vga: use AcpiDevAmlIf interface to build VGA device descriptors NB: We do not expect any functional change in any ACPI tables with this change. It's only a refactoring. NB2: Some targets (or1k) do not support acpi and CONFIG_ACPI is off for them. However, modules are reused between all architectures so CONFIG_ACPI is on. For those architectures, dummy stub function definitions help to resolve symbols. This change uses more of these and so it adds a couple of dummy stub definitions so that symbols for those can be resolved. Signed-off-by: Igor Mammedov Message-Id: <20221017102146.2254096-2-imammedo@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Ani Sinha CC: Bernhard Beschow Signed-off-by: Ani Sinha Message-Id: <20221107152744.868434-1-ani@anisinha.ca> --- hw/acpi/aml-build-stub.c | 10 ++++++++++ hw/display/acpi-vga-stub.c | 7 +++++++ hw/display/acpi-vga.c | 26 ++++++++++++++++++++++++++ hw/display/meson.build | 17 +++++++++++++++++ hw/display/vga-pci.c | 4 ++++ hw/display/vga_int.h | 2 ++ hw/i386/acpi-build.c | 26 +------------------------- 7 files changed, 67 insertions(+), 25 deletions(-) create mode 100644 hw/display/acpi-vga-stub.c create mode 100644 hw/display/acpi-vga.c diff --git a/hw/acpi/aml-build-stub.c b/hw/acpi/aml-build-stub.c index 8d8ad1a314..89a8fec4af 100644 --- a/hw/acpi/aml-build-stub.c +++ b/hw/acpi/aml-build-stub.c @@ -26,6 +26,16 @@ void aml_append(Aml *parent_ctx, Aml *child) { } +Aml *aml_return(Aml *val) +{ + return NULL; +} + +Aml *aml_method(const char *name, int arg_count, AmlSerializeFlag sflag) +{ + return NULL; +} + Aml *aml_resource_template(void) { return NULL; diff --git a/hw/display/acpi-vga-stub.c b/hw/display/acpi-vga-stub.c new file mode 100644 index 0000000000..a9b0ecf76d --- /dev/null +++ b/hw/display/acpi-vga-stub.c @@ -0,0 +1,7 @@ +#include "qemu/osdep.h" +#include "hw/acpi/acpi_aml_interface.h" +#include "vga_int.h" + +void build_vga_aml(AcpiDevAmlIf *adev, Aml *scope) +{ +} diff --git a/hw/display/acpi-vga.c b/hw/display/acpi-vga.c new file mode 100644 index 0000000000..f0e9ef1fcf --- /dev/null +++ b/hw/display/acpi-vga.c @@ -0,0 +1,26 @@ +#include "qemu/osdep.h" +#include "hw/acpi/acpi_aml_interface.h" +#include "hw/pci/pci.h" +#include "vga_int.h" + +void build_vga_aml(AcpiDevAmlIf *adev, Aml *scope) +{ + int s3d = 0; + Aml *method; + + if (object_dynamic_cast(OBJECT(adev), "qxl-vga")) { + s3d = 3; + } + + method = aml_method("_S1D", 0, AML_NOTSERIALIZED); + aml_append(method, aml_return(aml_int(0))); + aml_append(scope, method); + + method = aml_method("_S2D", 0, AML_NOTSERIALIZED); + aml_append(method, aml_return(aml_int(0))); + aml_append(scope, method); + + method = aml_method("_S3D", 0, AML_NOTSERIALIZED); + aml_append(method, aml_return(aml_int(s3d))); + aml_append(scope, method); +} diff --git a/hw/display/meson.build b/hw/display/meson.build index adc53dd8b6..7a725ed80e 100644 --- a/hw/display/meson.build +++ b/hw/display/meson.build @@ -38,10 +38,21 @@ softmmu_ss.add(when: 'CONFIG_NEXTCUBE', if_true: files('next-fb.c')) specific_ss.add(when: 'CONFIG_VGA', if_true: files('vga.c')) +if (config_all_devices.has_key('CONFIG_VGA_CIRRUS') or + config_all_devices.has_key('CONFIG_VGA_PCI') or + config_all_devices.has_key('CONFIG_VMWARE_VGA') or + config_all_devices.has_key('CONFIG_ATI_VGA') + ) + softmmu_ss.add(when: 'CONFIG_ACPI', if_true: files('acpi-vga.c'), + if_false: files('acpi-vga-stub.c')) +endif + if config_all_devices.has_key('CONFIG_QXL') qxl_ss = ss.source_set() qxl_ss.add(when: 'CONFIG_QXL', if_true: [files('qxl.c', 'qxl-logger.c', 'qxl-render.c'), pixman, spice]) + qxl_ss.add(when: 'CONFIG_ACPI', if_true: files('acpi-vga.c'), + if_false: files('acpi-vga-stub.c')) hw_display_modules += {'qxl': qxl_ss} endif @@ -52,6 +63,7 @@ softmmu_ss.add(when: 'CONFIG_ARTIST', if_true: files('artist.c')) softmmu_ss.add(when: [pixman, 'CONFIG_ATI_VGA'], if_true: files('ati.c', 'ati_2d.c', 'ati_dbg.c')) + if config_all_devices.has_key('CONFIG_VIRTIO_GPU') virtio_gpu_ss = ss.source_set() virtio_gpu_ss.add(when: 'CONFIG_VIRTIO_GPU', @@ -87,14 +99,19 @@ if config_all_devices.has_key('CONFIG_VIRTIO_VGA') if_true: [files('virtio-vga.c'), pixman]) virtio_vga_ss.add(when: 'CONFIG_VHOST_USER_VGA', if_true: files('vhost-user-vga.c')) + virtio_vga_ss.add(when: 'CONFIG_ACPI', if_true: files('acpi-vga.c'), + if_false: files('acpi-vga-stub.c')) hw_display_modules += {'virtio-vga': virtio_vga_ss} virtio_vga_gl_ss = ss.source_set() virtio_vga_gl_ss.add(when: ['CONFIG_VIRTIO_VGA', virgl, opengl], if_true: [files('virtio-vga-gl.c'), pixman]) + virtio_vga_gl_ss.add(when: 'CONFIG_ACPI', if_true: files('acpi-vga.c'), + if_false: files('acpi-vga-stub.c')) hw_display_modules += {'virtio-vga-gl': virtio_vga_gl_ss} endif specific_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_lcdc.c')) +softmmu_ss.add(when: 'CONFIG_ALL', if_true: files('acpi-vga-stub.c')) modules += { 'hw-display': hw_display_modules } diff --git a/hw/display/vga-pci.c b/hw/display/vga-pci.c index 3e5bc259f7..9a91de7ed1 100644 --- a/hw/display/vga-pci.c +++ b/hw/display/vga-pci.c @@ -35,6 +35,7 @@ #include "hw/loader.h" #include "hw/display/edid.h" #include "qom/object.h" +#include "hw/acpi/acpi_aml_interface.h" enum vga_pci_flags { PCI_VGA_FLAG_ENABLE_MMIO = 1, @@ -354,11 +355,13 @@ static void vga_pci_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + AcpiDevAmlIfClass *adevc = ACPI_DEV_AML_IF_CLASS(klass); k->vendor_id = PCI_VENDOR_ID_QEMU; k->device_id = PCI_DEVICE_ID_QEMU_VGA; dc->vmsd = &vmstate_vga_pci; set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories); + adevc->build_dev_aml = build_vga_aml; } static const TypeInfo vga_pci_type_info = { @@ -369,6 +372,7 @@ static const TypeInfo vga_pci_type_info = { .class_init = vga_pci_class_init, .interfaces = (InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, + { TYPE_ACPI_DEV_AML_IF }, { }, }, }; diff --git a/hw/display/vga_int.h b/hw/display/vga_int.h index 305e700014..330406ad9c 100644 --- a/hw/display/vga_int.h +++ b/hw/display/vga_int.h @@ -30,6 +30,7 @@ #include "ui/console.h" #include "hw/display/bochs-vbe.h" +#include "hw/acpi/acpi_aml_interface.h" #define ST01_V_RETRACE 0x08 #define ST01_DISP_ENABLE 0x01 @@ -195,4 +196,5 @@ void pci_std_vga_mmio_region_init(VGACommonState *s, MemoryRegion *subs, bool qext, bool edid); +void build_vga_aml(AcpiDevAmlIf *adev, Aml *scope); #endif diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 4f54b61904..26932b4e2c 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -430,7 +430,6 @@ static void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus, bool hotpluggbale_slot = false; bool bridge_in_acpi = false; bool cold_plugged_bridge = false; - bool is_vga = false; if (pdev) { pc = PCI_DEVICE_GET_CLASS(pdev); @@ -440,8 +439,6 @@ static void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus, continue; } - is_vga = pc->class_id == PCI_CLASS_DISPLAY_VGA; - /* * Cold plugged bridges aren't themselves hot-pluggable. * Hotplugged bridges *are* hot-pluggable. @@ -489,28 +486,7 @@ static void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus, aml_append(dev, aml_pci_device_dsm()); } - if (is_vga) { - /* add VGA specific AML methods */ - int s3d; - - if (object_dynamic_cast(OBJECT(pdev), "qxl-vga")) { - s3d = 3; - } else { - s3d = 0; - } - - method = aml_method("_S1D", 0, AML_NOTSERIALIZED); - aml_append(method, aml_return(aml_int(0))); - aml_append(dev, method); - - method = aml_method("_S2D", 0, AML_NOTSERIALIZED); - aml_append(method, aml_return(aml_int(0))); - aml_append(dev, method); - - method = aml_method("_S3D", 0, AML_NOTSERIALIZED); - aml_append(method, aml_return(aml_int(s3d))); - aml_append(dev, method); - } + call_dev_aml_func(DEVICE(pdev), dev); bridge_in_acpi = cold_plugged_bridge && pcihp_bridge_en; if (bridge_in_acpi) { From ab886c7c883fa628dbb9f9b788ea855ea00f6d0a Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Mon, 17 Oct 2022 12:21:37 +0200 Subject: [PATCH 626/705] tests: acpi: whitelist DSDT before generating PCI-ISA bridge AML automatically Signed-off-by: Igor Mammedov Message-Id: <20221017102146.2254096-3-imammedo@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- tests/qtest/bios-tables-test-allowed-diff.h | 34 +++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h index dfb8523c8b..570b17478e 100644 --- a/tests/qtest/bios-tables-test-allowed-diff.h +++ b/tests/qtest/bios-tables-test-allowed-diff.h @@ -1 +1,35 @@ /* List of comma-separated changed AML files to ignore */ +"tests/data/acpi/pc/DSDT", +"tests/data/acpi/pc/DSDT.acpierst", +"tests/data/acpi/pc/DSDT.acpihmat", +"tests/data/acpi/pc/DSDT.bridge", +"tests/data/acpi/pc/DSDT.cphp", +"tests/data/acpi/pc/DSDT.dimmpxm", +"tests/data/acpi/pc/DSDT.hpbridge", +"tests/data/acpi/pc/DSDT.hpbrroot", +"tests/data/acpi/pc/DSDT.ipmikcs", +"tests/data/acpi/pc/DSDT.memhp", +"tests/data/acpi/pc/DSDT.nohpet", +"tests/data/acpi/pc/DSDT.numamem", +"tests/data/acpi/pc/DSDT.roothp", +"tests/data/acpi/q35/DSDT", +"tests/data/acpi/q35/DSDT.acpierst", +"tests/data/acpi/q35/DSDT.acpihmat", +"tests/data/acpi/q35/DSDT.applesmc", +"tests/data/acpi/q35/DSDT.bridge", +"tests/data/acpi/q35/DSDT.cphp", +"tests/data/acpi/q35/DSDT.cxl", +"tests/data/acpi/q35/DSDT.dimmpxm", +"tests/data/acpi/q35/DSDT.ipmibt", +"tests/data/acpi/q35/DSDT.ipmismbus", +"tests/data/acpi/q35/DSDT.ivrs", +"tests/data/acpi/q35/DSDT.memhp", +"tests/data/acpi/q35/DSDT.mmio64", +"tests/data/acpi/q35/DSDT.multi-bridge", +"tests/data/acpi/q35/DSDT.nohpet", +"tests/data/acpi/q35/DSDT.numamem", +"tests/data/acpi/q35/DSDT.pvpanic-isa", +"tests/data/acpi/q35/DSDT.tis.tpm12", +"tests/data/acpi/q35/DSDT.tis.tpm2", +"tests/data/acpi/q35/DSDT.viot", +"tests/data/acpi/q35/DSDT.xapic", From 47a373faa6b272d12c8b166f7a0c45c867589005 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Mon, 17 Oct 2022 12:21:38 +0200 Subject: [PATCH 627/705] acpi: pc/q35: drop ad-hoc PCI-ISA bridge AML routines and let bus ennumeration generate AML PCI-ISA bridges that are built in PIIX/Q35 are building its own AML using AcpiDevAmlIf interface. Now build_append_pci_bus_devices() gained AcpiDevAmlIf interface support to get AML of devices atached to PCI slots. So drop ad-hoc build_q35_isa_bridge()/build_piix4_isa_bridge() and let PCI bus enumeration to include PCI-ISA bridge AML when it's enumerated by build_append_pci_bus_devices(). AML change is mostly contextual, which moves whole ISA hierarchy directly under PCI host bridge instead of it being described as separate \SB.PCI0.ISA block. Note: If bus/slot that hosts ISA bridge has BSEL set, it will gain new ASUN and _DMS entries (i.e. acpi-index support, but it should not cause any functional change and that is fine from PCI Firmware spec point of view), potentially it's possible to suppress that by adding a flag to PCIDevice but I don't see a reason to do that yet, I'd rather treat bridge just as any other PCI device if it's possible. Signed-off-by: Igor Mammedov Message-Id: <20221017102146.2254096-4-imammedo@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-build.c | 75 -------------------------------------------- hw/isa/lpc_ich9.c | 23 ++++++++++++++ hw/isa/piix3.c | 17 +++++++++- 3 files changed, 39 insertions(+), 76 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 26932b4e2c..e1483bb11a 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -435,10 +435,6 @@ static void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus, pc = PCI_DEVICE_GET_CLASS(pdev); dc = DEVICE_GET_CLASS(pdev); - if (pc->class_id == PCI_CLASS_BRIDGE_ISA) { - continue; - } - /* * Cold plugged bridges aren't themselves hot-pluggable. * Hotplugged bridges *are* hot-pluggable. @@ -1006,7 +1002,6 @@ static void build_piix4_pci0_int(Aml *table) { Aml *dev; Aml *crs; - Aml *field; Aml *method; uint32_t irqs; Aml *sb_scope = aml_scope("_SB"); @@ -1015,13 +1010,6 @@ static void build_piix4_pci0_int(Aml *table) aml_append(pci0_scope, build_prt(true)); aml_append(sb_scope, pci0_scope); - field = aml_field("PCI0.ISA.P40C", AML_BYTE_ACC, AML_NOLOCK, AML_PRESERVE); - aml_append(field, aml_named_field("PRQ0", 8)); - aml_append(field, aml_named_field("PRQ1", 8)); - aml_append(field, aml_named_field("PRQ2", 8)); - aml_append(field, aml_named_field("PRQ3", 8)); - aml_append(sb_scope, field); - aml_append(sb_scope, build_irq_status_method()); aml_append(sb_scope, build_iqcr_method(true)); @@ -1125,7 +1113,6 @@ static Aml *build_q35_routing_table(const char *str) static void build_q35_pci0_int(Aml *table) { - Aml *field; Aml *method; Aml *sb_scope = aml_scope("_SB"); Aml *pci0_scope = aml_scope("PCI0"); @@ -1162,18 +1149,6 @@ static void build_q35_pci0_int(Aml *table) aml_append(pci0_scope, method); aml_append(sb_scope, pci0_scope); - field = aml_field("PCI0.ISA.PIRQ", AML_BYTE_ACC, AML_NOLOCK, AML_PRESERVE); - aml_append(field, aml_named_field("PRQA", 8)); - aml_append(field, aml_named_field("PRQB", 8)); - aml_append(field, aml_named_field("PRQC", 8)); - aml_append(field, aml_named_field("PRQD", 8)); - aml_append(field, aml_reserved_field(0x20)); - aml_append(field, aml_named_field("PRQE", 8)); - aml_append(field, aml_named_field("PRQF", 8)); - aml_append(field, aml_named_field("PRQG", 8)); - aml_append(field, aml_named_field("PRQH", 8)); - aml_append(sb_scope, field); - aml_append(sb_scope, build_irq_status_method()); aml_append(sb_scope, build_iqcr_method(false)); @@ -1238,54 +1213,6 @@ static Aml *build_q35_dram_controller(const AcpiMcfgInfo *mcfg) return dev; } -static void build_q35_isa_bridge(Aml *table) -{ - Aml *dev; - Aml *scope; - Object *obj; - bool ambiguous; - - /* - * temporarily fish out isa bridge, build_q35_isa_bridge() will be dropped - * once PCI is converted to AcpiDevAmlIf and would be ble to generate - * AML for bridge itself - */ - obj = object_resolve_path_type("", TYPE_ICH9_LPC_DEVICE, &ambiguous); - assert(obj && !ambiguous); - - scope = aml_scope("_SB.PCI0"); - dev = aml_device("ISA"); - aml_append(dev, aml_name_decl("_ADR", aml_int(0x001F0000))); - - call_dev_aml_func(DEVICE(obj), dev); - aml_append(scope, dev); - aml_append(table, scope); -} - -static void build_piix4_isa_bridge(Aml *table) -{ - Aml *dev; - Aml *scope; - Object *obj; - bool ambiguous; - - /* - * temporarily fish out isa bridge, build_piix4_isa_bridge() will be dropped - * once PCI is converted to AcpiDevAmlIf and would be ble to generate - * AML for bridge itself - */ - obj = object_resolve_path_type("", TYPE_PIIX3_PCI_DEVICE, &ambiguous); - assert(obj && !ambiguous); - - scope = aml_scope("_SB.PCI0"); - dev = aml_device("ISA"); - aml_append(dev, aml_name_decl("_ADR", aml_int(0x00010000))); - - call_dev_aml_func(DEVICE(obj), dev); - aml_append(scope, dev); - aml_append(table, scope); -} - static void build_x86_acpi_pci_hotplug(Aml *table, uint64_t pcihp_addr) { Aml *scope; @@ -1465,7 +1392,6 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, aml_append(sb_scope, dev); aml_append(dsdt, sb_scope); - build_piix4_isa_bridge(dsdt); if (pm->pcihp_bridge_en || pm->pcihp_root_en) { build_x86_acpi_pci_hotplug(dsdt, pm->pcihp_io_base); } @@ -1510,7 +1436,6 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, aml_append(dsdt, sb_scope); - build_q35_isa_bridge(dsdt); if (pm->pcihp_bridge_en) { build_x86_acpi_pci_hotplug(dsdt, pm->pcihp_io_base); } diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index 8694e58b21..0b0a83e080 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -809,6 +809,7 @@ static void ich9_send_gpe(AcpiDeviceIf *adev, AcpiEventStatusBits ev) static void build_ich9_isa_aml(AcpiDevAmlIf *adev, Aml *scope) { + Aml *field; BusChild *kid; ICH9LPCState *s = ICH9_LPC_DEVICE(adev); BusState *bus = BUS(s->isa_bus); @@ -816,6 +817,28 @@ static void build_ich9_isa_aml(AcpiDevAmlIf *adev, Aml *scope) /* ICH9 PCI to ISA irq remapping */ aml_append(scope, aml_operation_region("PIRQ", AML_PCI_CONFIG, aml_int(0x60), 0x0C)); + /* Fields declarion has to happen *after* operation region */ + field = aml_field("PIRQ", AML_BYTE_ACC, AML_NOLOCK, AML_PRESERVE); + aml_append(field, aml_named_field("PRQA", 8)); + aml_append(field, aml_named_field("PRQB", 8)); + aml_append(field, aml_named_field("PRQC", 8)); + aml_append(field, aml_named_field("PRQD", 8)); + aml_append(field, aml_reserved_field(0x20)); + aml_append(field, aml_named_field("PRQE", 8)); + aml_append(field, aml_named_field("PRQF", 8)); + aml_append(field, aml_named_field("PRQG", 8)); + aml_append(field, aml_named_field("PRQH", 8)); + aml_append(scope, field); + + /* hack: put fields into _SB scope for LNKx to find them */ + aml_append(scope, aml_alias("PRQA", "\\_SB.PRQA")); + aml_append(scope, aml_alias("PRQB", "\\_SB.PRQB")); + aml_append(scope, aml_alias("PRQC", "\\_SB.PRQC")); + aml_append(scope, aml_alias("PRQD", "\\_SB.PRQD")); + aml_append(scope, aml_alias("PRQE", "\\_SB.PRQE")); + aml_append(scope, aml_alias("PRQF", "\\_SB.PRQF")); + aml_append(scope, aml_alias("PRQG", "\\_SB.PRQG")); + aml_append(scope, aml_alias("PRQH", "\\_SB.PRQH")); QTAILQ_FOREACH(kid, &bus->children, sibling) { call_dev_aml_func(DEVICE(kid->child), scope); diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c index 808fd4eadf..f9b4af5c05 100644 --- a/hw/isa/piix3.c +++ b/hw/isa/piix3.c @@ -316,12 +316,27 @@ static void pci_piix3_realize(PCIDevice *dev, Error **errp) static void build_pci_isa_aml(AcpiDevAmlIf *adev, Aml *scope) { + Aml *field; BusChild *kid; BusState *bus = qdev_get_child_bus(DEVICE(adev), "isa.0"); /* PIIX PCI to ISA irq remapping */ aml_append(scope, aml_operation_region("P40C", AML_PCI_CONFIG, - aml_int(0x60), 0x04)); + aml_int(0x60), 0x04)); + /* Fields declarion has to happen *after* operation region */ + field = aml_field("P40C", AML_BYTE_ACC, AML_NOLOCK, AML_PRESERVE); + aml_append(field, aml_named_field("PRQ0", 8)); + aml_append(field, aml_named_field("PRQ1", 8)); + aml_append(field, aml_named_field("PRQ2", 8)); + aml_append(field, aml_named_field("PRQ3", 8)); + aml_append(scope, field); + + /* hack: put fields into _SB scope for LNKx to find them */ + aml_append(scope, aml_alias("PRQ0", "\\_SB.PRQ0")); + aml_append(scope, aml_alias("PRQ1", "\\_SB.PRQ1")); + aml_append(scope, aml_alias("PRQ2", "\\_SB.PRQ2")); + aml_append(scope, aml_alias("PRQ3", "\\_SB.PRQ3")); + QTAILQ_FOREACH(kid, &bus->children, sibling) { call_dev_aml_func(DEVICE(kid->child), scope); } From fd4f2ae8ec829c83cc63ad047be61f93c4807905 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Mon, 17 Oct 2022 12:21:39 +0200 Subject: [PATCH 628/705] tests: acpi: update expected DSDT after ISA bridge is moved directly under PCI host bridge example of the change for PC machine with hotplug disabled on root buss (no BSEL case): - Field (PCI0.ISA.P40C, ByteAcc, NoLock, Preserve) + Field (S08.P40C, ByteAcc, NoLock, Preserve) === - Scope (_SB.PCI0) - { - Device (ISA) - { - Name (_ADR, 0x00010000) // _ADR: Address - OperationRegion (P40C, PCI_Config, 0x60, 0x04) ... - } - } - Scope (_SB) === + Device (S08) + { + Name (_ADR, 0x00010000) // _ADR: Address + OperationRegion (P40C, PCI_Config, 0x60, 0x04) ... + } + Device (S10) { Name (_ADR, 0x00020000) // _ADR: Address with hotplug enabled on root bus (i.e. bus has BSEL configured), a following addtional entries will be seen: + Name (ASUN, One) + Method (_DSM, 4, Serialized) // _DSM: Device-Specific Method + { + Local0 = Package (0x02) + { + BSEL, + ASUN + } + Return (PDSM (Arg0, Arg1, Arg2, Arg3, Local0)) + } similar changes are expected for Q35 modulo: - Field (PCI0.ISA.PIRQ, ByteAcc, NoLock, Preserve) + Field (SF8.PIRQ, ByteAcc, NoLock, Preserve) and bridge address Signed-off-by: Igor Mammedov Message-Id: <20221017102146.2254096-5-imammedo@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- tests/data/acpi/pc/DSDT | Bin 6422 -> 6496 bytes tests/data/acpi/pc/DSDT.acpierst | Bin 6382 -> 6456 bytes tests/data/acpi/pc/DSDT.acpihmat | Bin 7747 -> 7821 bytes tests/data/acpi/pc/DSDT.bridge | Bin 9496 -> 9570 bytes tests/data/acpi/pc/DSDT.cphp | Bin 6886 -> 6960 bytes tests/data/acpi/pc/DSDT.dimmpxm | Bin 8076 -> 8150 bytes tests/data/acpi/pc/DSDT.hpbridge | Bin 6382 -> 6456 bytes tests/data/acpi/pc/DSDT.hpbrroot | Bin 3069 -> 3107 bytes tests/data/acpi/pc/DSDT.ipmikcs | Bin 6494 -> 6568 bytes tests/data/acpi/pc/DSDT.memhp | Bin 7781 -> 7855 bytes tests/data/acpi/pc/DSDT.nohpet | Bin 6280 -> 6354 bytes tests/data/acpi/pc/DSDT.numamem | Bin 6428 -> 6502 bytes tests/data/acpi/pc/DSDT.roothp | Bin 6656 -> 6694 bytes tests/data/acpi/q35/DSDT | Bin 8320 -> 8418 bytes tests/data/acpi/q35/DSDT.acpierst | Bin 8337 -> 8435 bytes tests/data/acpi/q35/DSDT.acpihmat | Bin 9645 -> 9743 bytes tests/data/acpi/q35/DSDT.applesmc | Bin 8366 -> 8464 bytes tests/data/acpi/q35/DSDT.bridge | Bin 11449 -> 11547 bytes tests/data/acpi/q35/DSDT.cphp | Bin 8784 -> 8882 bytes tests/data/acpi/q35/DSDT.cxl | Bin 9646 -> 9744 bytes tests/data/acpi/q35/DSDT.dimmpxm | Bin 9974 -> 10072 bytes tests/data/acpi/q35/DSDT.ipmibt | Bin 8395 -> 8493 bytes tests/data/acpi/q35/DSDT.ipmismbus | Bin 8409 -> 8507 bytes tests/data/acpi/q35/DSDT.ivrs | Bin 8337 -> 8435 bytes tests/data/acpi/q35/DSDT.memhp | Bin 9679 -> 9777 bytes tests/data/acpi/q35/DSDT.mmio64 | Bin 9450 -> 9548 bytes tests/data/acpi/q35/DSDT.multi-bridge | Bin 8640 -> 8738 bytes tests/data/acpi/q35/DSDT.nohpet | Bin 8178 -> 8276 bytes tests/data/acpi/q35/DSDT.numamem | Bin 8326 -> 8424 bytes tests/data/acpi/q35/DSDT.pvpanic-isa | Bin 8421 -> 8519 bytes tests/data/acpi/q35/DSDT.tis.tpm12 | Bin 8926 -> 9024 bytes tests/data/acpi/q35/DSDT.tis.tpm2 | Bin 8952 -> 9050 bytes tests/data/acpi/q35/DSDT.viot | Bin 9429 -> 9527 bytes tests/data/acpi/q35/DSDT.xapic | Bin 35683 -> 35781 bytes tests/qtest/bios-tables-test-allowed-diff.h | 34 -------------------- 35 files changed, 34 deletions(-) diff --git a/tests/data/acpi/pc/DSDT b/tests/data/acpi/pc/DSDT index da2a3e5c0551ac2d1d8a0a40b92d3235d5757475..5b4624cb68c78eab6e356987974b9bee6c9a1785 100644 GIT binary patch delta 186 zcmbPc^uUPACD?X0~rcpfw+cnt|5qP1m_xoxW;g<@y1 z*H+9`A=tnoo+IATC5Q*8hk?T}IMk1EG9$lSa&$w0iGec{R{|GHbfXlA%@`0AXuts^ u3_*kuh%n}00}00HfeZz)KwLvO*AT=tf^&^PTw^%bc;l`-#?AY94Y&c&fia{2 delta 139 zcmdmC^v;mWCD5QBe2m+6GZ&v8Hvqa2Cba+n diff --git a/tests/data/acpi/pc/DSDT.acpihmat b/tests/data/acpi/pc/DSDT.acpihmat index 884d4871a2a0b87db2c0dd7e6f32486ba9b7e424..b84f3b47c37e427b927c36036307db6e83a843e5 100644 GIT binary patch delta 186 zcmX?X(`(D+66_MvE62dV_;w;!$7W3?Uq&VmlgSm#8#eo~MDTIB+=_`0c8VA9xjA`* zkgb@jLa>2FJV(5vOArrG4+Do|aHt>S5r{D6 d*gTObf{)90XAH;^0oR?AKMUAyHWv=#1^^j}CO`lH diff --git a/tests/data/acpi/pc/DSDT.bridge b/tests/data/acpi/pc/DSDT.bridge index 31a79aa47673c14f7e564475c39bd38c872f8165..6771620078086e42b445474b16797094e0d0a801 100644 GIT binary patch delta 167 zcmbQ?^~j6MCDs+4|a+d=$$#a zh1ZVBRblcxKBMI5h5!=-XC|%$E|%y4h=U+z4&0K_yA{5gXktt3D021c#e2SmmnUX0*2^@ z022deCawf7md$f`@)$Qx^kZc5Gn@R7af4cPql!K=NE=8CNEu^5P@n+^kT3)hMj*nN eWAj8NZBFj~O2!zFEdp(olaF)TZRX(%69)iL9VOrZ diff --git a/tests/data/acpi/pc/DSDT.cphp b/tests/data/acpi/pc/DSDT.cphp index 8b0cae4dbfbd083a43751a7c94dc5c76f89084a7..298fa1592676b3a2089b08eff5f764e04391b961 100644 GIT binary patch delta 186 zcmaE6y1|UgCDM2jDA0fdNEm_$BM@QC dv3VlXZ!Rw1oiQLw1YCDcp2lmt`4)c|Hvml~Cp`cF diff --git a/tests/data/acpi/pc/DSDT.dimmpxm b/tests/data/acpi/pc/DSDT.dimmpxm index 38865fb66747a6ee1cf2066b925be6eba064625a..9fcadb266b92fc4942621f0fd919703723de2fd9 100644 GIT binary patch delta 186 zcmeCNzh=+n66_LkO`d^)v2G$)$7W3?Uq&VmlgSm#8#eo~Eac~MxfK&1>=ZBHb93@f zVOud*g%sG`pd(gxBpdAE?{=7~%T`MG>|#(>Nd QaNRlCM#y$^gGd-R0In+{5&!@I diff --git a/tests/data/acpi/pc/DSDT.hpbridge b/tests/data/acpi/pc/DSDT.hpbridge index abcd6d9d309a8f9a9080edc64df7a6c195b5885f..99461b771eec2043263b5bc3c109a08969a99af9 100644 GIT binary patch delta 186 zcmaE7xWkCcCD z*H+9`A=tnoo+IATC5Q*8hk?T}IMk1EG9$lSa&$w0iGec{R{|GHbfXlA%@`0AXuts^ u3_*kuh%n}00}00HfeZz)KwLvO*AT=tf^&^PTw^%bc;l`-#?AY94Y&c&fia{2 delta 139 zcmdmC^v;mWCD5QBe2m+6GZ&v8Hvqa2Cba+n diff --git a/tests/data/acpi/pc/DSDT.hpbrroot b/tests/data/acpi/pc/DSDT.hpbrroot index dd2c8c0c8c5bf9895eb524e094d5597515b4803e..b10b17cb1111f6b5d61da4aa1c754f2921a4ac1c 100644 GIT binary patch delta 184 zcmew>zF30GCDzdQxrQLF5sWJsXawRL!}x*58+YX~PCmeG3jp{LFk1is delta 146 zcmZ21@mHM7CD b!Xf3s8UwOGz=0KF2Y0Z60mO>QPr2;?&p0K@ diff --git a/tests/data/acpi/pc/DSDT.ipmikcs b/tests/data/acpi/pc/DSDT.ipmikcs index e819ce69461a36b6fab5e2ffeba90dfe558724a7..aff3e9bbe1fdbf783c49d07a49c2e16317a2871e 100644 GIT binary patch delta 166 zcmca-w8EInCDNTMOeP;--mrNZi#8{h&%K!VV5fKimwS^> z^V*8}sstNY#B;ILlD;p&NTvYjp1D5jk~rnZf4_);06GVOD_EY delta 139 zcmZ2se9wr>CD=ZBHb93?~ zAzLw5ge4FGUoCS(8r diff --git a/tests/data/acpi/pc/DSDT.nohpet b/tests/data/acpi/pc/DSDT.nohpet index b413d9f31d483eca02f45ad09af2f556581ec381..ceee7722ceed8a7e8f61a37805a4c855f47244a8 100644 GIT binary patch delta 186 zcmeA$ykyAb66_LkNrHia@z+GIj?J1(zKl#BCX*|eH*EG}najcDaw{f2*ePDX=jPzdQxrQLF5u9rT;u^!b#v6C#F>W^Cjo=0V7wI#4 delta 139 zcmca)*kQ=!66_MvA;G}FST>QXL&Hr{FFx2QKET=2AiBv@!ZX-0o+IATC5Q*8fFZge zz{J3ri7SDNWit;?9^=M|evC|hW|JQ>ZcvMERMBS!X#;5iDPs%>3N+vV5{4kc2t*ij dY@Wz8mxIf9XAH;^0oR?AEx2tr*YJjM0|5S~C4B$@ diff --git a/tests/data/acpi/pc/DSDT.numamem b/tests/data/acpi/pc/DSDT.numamem index 9e701b2983f9ec45af9c26d801545c2b5d112a10..e03f4d07b86018d12def37b5397ba9673548e2b7 100644 GIT binary patch delta 186 zcmbPZ^vsCMCD=ZBHb8~Vh zudSG?La>2FJV(5vOArrG4+Do|aHt>SE4NhlZP^UVN}qe1Nm3L3ER+glDj0JV(5vOArrG0Yh{{ zfQf-K6ITKk%jN|MhTC?t0ACn407khWt^fc4 diff --git a/tests/data/acpi/pc/DSDT.roothp b/tests/data/acpi/pc/DSDT.roothp index 8c3956c9ecc63133cc800f1d2d07a1392a35d548..418cc92e4c061ad21e1d281e0b5e6114e283b7d3 100644 GIT binary patch delta 190 zcmZoLS!TlJ66_M9CdI(Oczz;R$7W3?Uq&VmlgSm#8#eo~Xmi$kJ&TDCc8V8pdKTd9 zX%OAS9c*9_&k^tF62uVQX#vE)Q!5BS|xgZvZYY68Wg1AO7u3(@Mh;Izz2O4kOmB+Yw3U3Y%00)~hY5)KL delta 133 zcmZ2x(qO{n66_MfAjQDIs56nPL&!~1FFx2QKET=2AiBv@!ZX-$@;z?x&AvRjj2kEV zF*5m?O@7F@K`pvbMV}d@2&f=Fz{J3rF(4?=fCESvf(RoJVa&04B9k_!l>3PokdXrZ X$04S22OAi~bHqEk1a02Qo67?Lm(C@O diff --git a/tests/data/acpi/q35/DSDT b/tests/data/acpi/q35/DSDT index 3870958969b1c0e29f9dd26a1256359e90897d3e..ea35dc5eba8433a8dcb54815f19ed6239f2534e7 100644 GIT binary patch delta 229 zcmZp0eB{XG66_N4NP&TYal=L~Z^q4;ObLukO<|i)Gq2>^yg{gmm&-vRCO+6HUcf_s zvWfn@qf&T;eCUFg{@y LVGD5f3t<2Npb9~@ delta 105 zcmaFl*x<^yg{gmm&;KxCO+6HUcggf zvWfn@qf&T;eCUFg{@y LVGD5f3t<2NiwZ%W delta 105 zcmezDIMI>ICDzkclgSizm9#U~;37emz@2P@rRs9!MXE z1>!ovxlSOiGo0%T;<~`OE+DQeoa+kWy1}__Ag(){>ki_2z_}jLO(xz>F7cCF7@x3< Lumw2#g)jgB@by6W delta 105 zcmeD8S?kT^66_MPR+WK)@&86HZ$=?!LB053r}zM8PlMjLMxfVi%3t}BS^2IsngxbASSJBaH6=Xyjp=>+>a$8T<76k=o- LVGD5f3t<2NSgJs! delta 105 zcmbQ>w9b*sCD`qwz*AZ$=?U5xw|er}zM8PlMWkdGooOW>Z*-%TJ~K!eP)Yn`PkH^#34+bMoGdXQ?E-Erli$eMvWu_jCF_L^qjuJGsP9Zee^P UC?XKx>=(iirx$E!5D#Jk0QJE|ng9R* delta 116 zcmbOowKI~-CDW-i$)df_m}6PVoWGo(9oPZUUacj+5iH#V0H1yxJVX zn8?V~7rA*m(@H+x=te7jW{@hNiulPD+WMOl1e^yg?|4pUXiZCO+6HUcf_s zGLMq2LUfaZbg-L6JV(5vOArqOgFHiYLx5*cAQM*t7f*Df!Q@6E{d%^5pg_kMJ&-;S z3&eGTbDcn3XE@gx#C3slT|it{IM)@#b%S%=KwNh?*B!+5fO9>fn@qf&T;eCUFg{@y LVGD5f3t<2N)oDPt delta 104 zcmdnwdclRuCD9IB?@_R27hwx<_6uPE E08AJii~s-t diff --git a/tests/data/acpi/q35/DSDT.cxl b/tests/data/acpi/q35/DSDT.cxl index 20d0fb64ea52b2f4979105c934aadb6f416e2b71..aeea64d1cecad0ad011870ed5e04bfea1ae62510 100644 GIT binary patch delta 229 zcmZ4IJ;8^|CD^yg{f>h|5VSCO+6HUcgIn zvWIHCLUfaZbg-L6JV(5vOArqOgFHiYLx5*cAQM*t7f*Df!Q@6E{d%^5pg_kMJ&-;S z3&eGTbDcn3XE@gx#C3slT|it{IM)@#b%S%=KwNh?*B!+5fO9>fn@qf&T;eCUFg{@y LVGD5f3t<2N6HY-N delta 105 zcmbQ>v(B5#CD^yg}%PFqeZuOnk6Yynu)N zjvk#fw=B)t~-e90q1%|H+i!7dKzwSVbo`2 M7hwx<_6uPE0Ka}f-~a#s delta 106 zcmZ4MblQ>2CDWkdGooOW>Z*-%TJ~K!eP)Yn`PkH^#34%?$Tz)JuApHVvER)~J*|LkU1vvYK GFaQ91ARZV1 diff --git a/tests/data/acpi/q35/DSDT.ipmismbus b/tests/data/acpi/q35/DSDT.ipmismbus index 479df48cd37af888317d63eac8f565f370201490..f6e124137721312722c820b5c084a143492945c9 100644 GIT binary patch delta 229 zcmccVxZ8=#CDB&|h3F;+>0mdDc#e2SmmnSn26=|)h5*l?KqjsPE}rN{gUO9T`t@u9L4l4jdLVru z7KrNv=Q@G7&Ty_Xi0cC9x`4Q@aIPze>jvk#fw=B)t~-e90q1%|H<@@lxx`OyVSK_a L!WQ7{7s3DlR3kxi delta 123 zcmdn(bkmW`CD^yg{gmm&;KxCO+6HUcggf zvWfn@qf&T;eCUFg{@y LVGD5f3t<2NiwZ%W delta 105 zcmezDIMI>ICDq3sap6WTZ^q4;ObLukO<|i)Gq2>^yg}%q5SN2OOnk6Yynu)N z0mdDc#e2SmmnSn26=|)h5*l?KqjsPE}rN{gUO9T`t@u9L4l4jdLVru z7KrNv=Q@G7&Ty_Xi0cC9x`4Q@aIPze>jvk#fw=B)t~-e90q1%|H<@@lxx`OyVSK_a L!WQ7{7s3DlsQW?J delta 105 zcmdn!bKaZFCDCT+h3F;+>0mdDc#e2SmmnSn26=|)h5*l?KqjsPE}rN{gUO9T`t@u9L4l4jdLVru z7KrNv=Q@G7&Ty_Xi0cC9x`4Q@aIPze>jvk#fw=B)t~-e90q1%|H<@@lxx`OyVSK_a L!WQ7{7s3Dl&Zt5L delta 123 zcmX@(^~#gWCDs diff --git a/tests/data/acpi/q35/DSDT.multi-bridge b/tests/data/acpi/q35/DSDT.multi-bridge index 88bf47ab1805e4ef1dd8039933c5aa8144da37ac..7c14ce3a986fa06e88f3adc088faae54bdd2d8e4 100644 GIT binary patch delta 250 zcmX@$yvT*iCD72TNs~6 Yi%11H`-L#X=>;2F#)Ft3mI0Ur05;)9wEzGB delta 144 zcmZ4Fa=@9(CD0mdDc#e2SmmnSn26=|)h5*l?KqjsPE}rN{gUO9T`t@u9L4l4jdLVru z7KrNv=Q@G7&Ty_Xi0cC9x`4Q@aIPze>jvk#fw=B)t~-e90q1%|H<@@lxx`OyVSK_a L!WQ7{7s3Dl^Up#w delta 123 zcmccO@X4ObCDzkclgSizm9#U~;37emz@2P@rRs9!MXE z1>!ovxlSOiGo0%T;<~`OE+DQeoa+kWy1}__Ag(){>ki_2z_}jLO(xz>F7cCF7@x3< Lumw2#g)jgBaBM+- delta 123 zcmaFi*yhOP66_Mvroh0!_+}%QH=~BLpk92iQ+$B4r$Ka+n}BDqV?0N^qe~DE1A{z6 zbVGn=P#_am0vFHZZ}P7zkclgSizm9#VDd8|{d%^5pg_kMJ&-;S z3&eGTbDcn3XE@gx#C3slT|it{IM)@#b%S%=KwNh?*B!+5fO9>fn}DXdhHY+P^kifg LVGD5f3t<2NL%%?L delta 106 zcmX@^^wg2dCDp7Q#e69k)hx%^mSK>7vTSSG)bvt<`y3vl)e GVE_Qr;2#kH diff --git a/tests/data/acpi/q35/DSDT.tis.tpm12 b/tests/data/acpi/q35/DSDT.tis.tpm12 index 253a66e65818d1df67b13d4b70f68add78adff98..7a213e3db230064cedf3a30b83b11128286eaeba 100644 GIT binary patch delta 230 zcmccTdccj#CDjvk#fw=B)t~-e90q1%|H#w+=1o&=lVKifA M7hwx<_6uPE0Ky4DCIA2c delta 124 zcmX@$cF&c|CDB_D5eqm@20NFzwozkclgSizm9#VDeiL{d%^5pg_kMJ&-;S z3&eGTbDcn3XE@gx#C3slT|it{IM)@#b%S%=KwNh?*B!+5fO9>fo4nLQ0(>{OFa|KQ Mi?9Va`-Lz703b9$$p8QV delta 124 zcmccR_QRFSCD`LUfaZbg-L6JV(5vOArqOgFHiYLx5*cAQM*t7f*Df!Q@6E{d%^5pg_kMJ&-;S z3&eGTbDcn3XE@gx#C3slT|it{IM)@#b%S%=KwNh?*B!+5fO9>fn@qf&T;eCUFg{@y LVGD5f3t<2NOvpiI delta 123 zcmdn)b=8y0CD>FfuiTZ9dJsl5g_{q0|a42ZfmUV5fKi z5BbUR-L?wRO%Bq*ZWi$z@s2J*JPZu-4ABh%o)o$2v3CN7s?myqOc1_s6-8@aq0HJkF_Dp}FLLvCrj>lW(T!I6%piRrJ(G31^fxC6rdDwI YvBZE36mVmie7@6`U4$*b*)N0v04#(g#Q*>R diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h index 570b17478e..dfb8523c8b 100644 --- a/tests/qtest/bios-tables-test-allowed-diff.h +++ b/tests/qtest/bios-tables-test-allowed-diff.h @@ -1,35 +1 @@ /* List of comma-separated changed AML files to ignore */ -"tests/data/acpi/pc/DSDT", -"tests/data/acpi/pc/DSDT.acpierst", -"tests/data/acpi/pc/DSDT.acpihmat", -"tests/data/acpi/pc/DSDT.bridge", -"tests/data/acpi/pc/DSDT.cphp", -"tests/data/acpi/pc/DSDT.dimmpxm", -"tests/data/acpi/pc/DSDT.hpbridge", -"tests/data/acpi/pc/DSDT.hpbrroot", -"tests/data/acpi/pc/DSDT.ipmikcs", -"tests/data/acpi/pc/DSDT.memhp", -"tests/data/acpi/pc/DSDT.nohpet", -"tests/data/acpi/pc/DSDT.numamem", -"tests/data/acpi/pc/DSDT.roothp", -"tests/data/acpi/q35/DSDT", -"tests/data/acpi/q35/DSDT.acpierst", -"tests/data/acpi/q35/DSDT.acpihmat", -"tests/data/acpi/q35/DSDT.applesmc", -"tests/data/acpi/q35/DSDT.bridge", -"tests/data/acpi/q35/DSDT.cphp", -"tests/data/acpi/q35/DSDT.cxl", -"tests/data/acpi/q35/DSDT.dimmpxm", -"tests/data/acpi/q35/DSDT.ipmibt", -"tests/data/acpi/q35/DSDT.ipmismbus", -"tests/data/acpi/q35/DSDT.ivrs", -"tests/data/acpi/q35/DSDT.memhp", -"tests/data/acpi/q35/DSDT.mmio64", -"tests/data/acpi/q35/DSDT.multi-bridge", -"tests/data/acpi/q35/DSDT.nohpet", -"tests/data/acpi/q35/DSDT.numamem", -"tests/data/acpi/q35/DSDT.pvpanic-isa", -"tests/data/acpi/q35/DSDT.tis.tpm12", -"tests/data/acpi/q35/DSDT.tis.tpm2", -"tests/data/acpi/q35/DSDT.viot", -"tests/data/acpi/q35/DSDT.xapic", From ffb745909bcdd676c62532e301875f66ab505973 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Mon, 17 Oct 2022 12:21:40 +0200 Subject: [PATCH 629/705] tests: acpi: whitelist DSDT before generating ICH9_SMB AML automatically Signed-off-by: Igor Mammedov Message-Id: <20221017102146.2254096-6-imammedo@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- tests/qtest/bios-tables-test-allowed-diff.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h index dfb8523c8b..fd5852776c 100644 --- a/tests/qtest/bios-tables-test-allowed-diff.h +++ b/tests/qtest/bios-tables-test-allowed-diff.h @@ -1 +1,22 @@ /* List of comma-separated changed AML files to ignore */ +"tests/data/acpi/q35/DSDT", +"tests/data/acpi/q35/DSDT.acpierst", +"tests/data/acpi/q35/DSDT.acpihmat", +"tests/data/acpi/q35/DSDT.applesmc", +"tests/data/acpi/q35/DSDT.bridge", +"tests/data/acpi/q35/DSDT.cphp", +"tests/data/acpi/q35/DSDT.cxl", +"tests/data/acpi/q35/DSDT.dimmpxm", +"tests/data/acpi/q35/DSDT.ipmibt", +"tests/data/acpi/q35/DSDT.ipmismbus", +"tests/data/acpi/q35/DSDT.ivrs", +"tests/data/acpi/q35/DSDT.memhp", +"tests/data/acpi/q35/DSDT.mmio64", +"tests/data/acpi/q35/DSDT.multi-bridge", +"tests/data/acpi/q35/DSDT.nohpet", +"tests/data/acpi/q35/DSDT.numamem", +"tests/data/acpi/q35/DSDT.pvpanic-isa", +"tests/data/acpi/q35/DSDT.tis.tpm12", +"tests/data/acpi/q35/DSDT.tis.tpm2", +"tests/data/acpi/q35/DSDT.viot", +"tests/data/acpi/q35/DSDT.xapic", From 5dbad0af10ff7d4f83db7f4ddd872d85332ebecc Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Mon, 17 Oct 2022 12:21:41 +0200 Subject: [PATCH 630/705] acpi: add get_dev_aml_func() helper It will be used in followup commits to figure out if device has it's own, device specific AML block. Signed-off-by: Igor Mammedov Message-Id: <20221017102146.2254096-7-imammedo@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Ani Sinha --- include/hw/acpi/acpi_aml_interface.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/include/hw/acpi/acpi_aml_interface.h b/include/hw/acpi/acpi_aml_interface.h index ab76f0e55d..436da069d6 100644 --- a/include/hw/acpi/acpi_aml_interface.h +++ b/include/hw/acpi/acpi_aml_interface.h @@ -29,11 +29,20 @@ struct AcpiDevAmlIfClass { dev_aml_fn build_dev_aml; }; -static inline void call_dev_aml_func(DeviceState *dev, Aml *scope) +static inline dev_aml_fn get_dev_aml_func(DeviceState *dev) { if (object_dynamic_cast(OBJECT(dev), TYPE_ACPI_DEV_AML_IF)) { AcpiDevAmlIfClass *klass = ACPI_DEV_AML_IF_GET_CLASS(dev); - klass->build_dev_aml(ACPI_DEV_AML_IF(dev), scope); + return klass->build_dev_aml; + } + return NULL; +} + +static inline void call_dev_aml_func(DeviceState *dev, Aml *scope) +{ + dev_aml_fn fn = get_dev_aml_func(dev); + if (fn) { + fn(ACPI_DEV_AML_IF(dev), scope); } } From 6d2146147b4e21017313de0f1fc7972ce6a7a7c6 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Mon, 17 Oct 2022 12:21:42 +0200 Subject: [PATCH 631/705] acpi: enumerate SMB bridge automatically along with other PCI devices to make that happen (bridge sits at _ADR: 0x001F0003), relax PCI enumeration logic to include devices with *function* > 0 if device has something to say about itself (i.e. has build_dev_aml callback set). Signed-off-by: Igor Mammedov Message-Id: <20221017102146.2254096-8-imammedo@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-build.c | 27 +++------------------------ 1 file changed, 3 insertions(+), 24 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index e1483bb11a..916343d8d6 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -448,9 +448,10 @@ static void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus, /* * allow describing coldplugged bridges in ACPI even if they are not * on function 0, as they are not unpluggable, for all other devices - * generate description only for function 0 per slot + * generate description only for function 0 per slot, and for other + * functions if device on function provides its own AML */ - if (func && !bridge_in_acpi) { + if (func && !bridge_in_acpi && !get_dev_aml_func(DEVICE(pdev))) { continue; } } else { @@ -1319,25 +1320,6 @@ static Aml *build_q35_osc_method(bool enable_native_pcie_hotplug) return method; } -static void build_smb0(Aml *table, int devnr, int func) -{ - Aml *scope = aml_scope("_SB.PCI0"); - Aml *dev = aml_device("SMB0"); - bool ambiguous; - Object *obj; - /* - * temporarily fish out device hosting SMBUS, build_smb0 will be gone once - * PCI enumeration will be switched to call_dev_aml_func() - */ - obj = object_resolve_path_type("", TYPE_ICH9_SMB_DEVICE, &ambiguous); - assert(obj && !ambiguous); - - aml_append(dev, aml_name_decl("_ADR", aml_int(devnr << 16 | func))); - call_dev_aml_func(DEVICE(obj), dev); - aml_append(scope, dev); - aml_append(table, scope); -} - static void build_acpi0017(Aml *table) { Aml *dev, *scope, *method; @@ -1440,9 +1422,6 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, build_x86_acpi_pci_hotplug(dsdt, pm->pcihp_io_base); } build_q35_pci0_int(dsdt); - if (pcms->smbus) { - build_smb0(dsdt, ICH9_SMB_DEV, ICH9_SMB_FUNC); - } } if (misc->has_hpet) { From 5aaa1e10069d2285670c404b3d6654859e34b322 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Mon, 17 Oct 2022 12:21:43 +0200 Subject: [PATCH 632/705] tests: acpi: update expected blobs Expected change in q35 tests: @@ -2797,14 +2797,6 @@ DefinitionBlock ("", "DSDT", 1, "BOCHS ", "BXPC ", 0x00000001) } } - Scope (_SB.PCI0) - { - Device (SMB0) - { - Name (_ADR, 0x001F0003) // _ADR: Address - } - } - Scope (_SB) { Device (HPET) @@ -3282,6 +3274,11 @@ DefinitionBlock ("", "DSDT", 1, "BOCHS ", "BXPC ", 0x00000001) } } + Device (SFB) + { + Name (_ADR, 0x001F0003) // _ADR: Address + } + Method (PCNT, 0, NotSerialized) { } Also for ipmismbus test, child 'Device (MI1)' of SMB0 will be moved along with it Signed-off-by: Igor Mammedov Message-Id: <20221017102146.2254096-9-imammedo@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- tests/data/acpi/q35/DSDT | Bin 8418 -> 8407 bytes tests/data/acpi/q35/DSDT.acpierst | Bin 8435 -> 8424 bytes tests/data/acpi/q35/DSDT.acpihmat | Bin 9743 -> 9732 bytes tests/data/acpi/q35/DSDT.applesmc | Bin 8464 -> 8453 bytes tests/data/acpi/q35/DSDT.bridge | Bin 11547 -> 11536 bytes tests/data/acpi/q35/DSDT.cphp | Bin 8882 -> 8871 bytes tests/data/acpi/q35/DSDT.cxl | Bin 9744 -> 9733 bytes tests/data/acpi/q35/DSDT.dimmpxm | Bin 10072 -> 10061 bytes tests/data/acpi/q35/DSDT.ipmibt | Bin 8493 -> 8482 bytes tests/data/acpi/q35/DSDT.ipmismbus | Bin 8507 -> 8495 bytes tests/data/acpi/q35/DSDT.ivrs | Bin 8435 -> 8424 bytes tests/data/acpi/q35/DSDT.memhp | Bin 9777 -> 9766 bytes tests/data/acpi/q35/DSDT.mmio64 | Bin 9548 -> 9537 bytes tests/data/acpi/q35/DSDT.multi-bridge | Bin 8738 -> 8727 bytes tests/data/acpi/q35/DSDT.nohpet | Bin 8276 -> 8265 bytes tests/data/acpi/q35/DSDT.numamem | Bin 8424 -> 8413 bytes tests/data/acpi/q35/DSDT.pvpanic-isa | Bin 8519 -> 8508 bytes tests/data/acpi/q35/DSDT.tis.tpm12 | Bin 9024 -> 9013 bytes tests/data/acpi/q35/DSDT.tis.tpm2 | Bin 9050 -> 9039 bytes tests/data/acpi/q35/DSDT.viot | Bin 9527 -> 9516 bytes tests/data/acpi/q35/DSDT.xapic | Bin 35781 -> 35770 bytes tests/qtest/bios-tables-test-allowed-diff.h | 21 -------------------- 22 files changed, 21 deletions(-) diff --git a/tests/data/acpi/q35/DSDT b/tests/data/acpi/q35/DSDT index ea35dc5eba8433a8dcb54815f19ed6239f2534e7..c8a2b5df26608f10c75ab8f2f9e404fda987891b 100644 GIT binary patch delta 65 zcmaFlc-@i9CDqdhx+d@d3`B2GLFY!M;ug9Py4WK|IV1@(i2B eCDyZXIVi+{R0w#;Z@wV+o{?RIEx_3?gaH6HQWQi0 diff --git a/tests/data/acpi/q35/DSDT.acpierst b/tests/data/acpi/q35/DSDT.acpierst index 146269c68c68238a8be3aa67e049a85c0b8edc66..eb63e439b92424e4c50b7e5f1df92da54ecfc6ea 100644 GIT binary patch delta 64 zcmezD_`;FPCD=(iS0Ek8rTL1t6 delta 75 zcmaFi_}P)mCDG$Ds33dtLS7Tsc%-P7rCm}7Z7a!~tAK>h15Z%Nd?CWH}5%1^{#KX)W&#+ls d;tn^LgF*~Qg@A|r=D*7C8QDeH0-XIq7y!*W69)hQ diff --git a/tests/data/acpi/q35/DSDT.applesmc b/tests/data/acpi/q35/DSDT.applesmc index ff25d82ba24b5e792b9d87958aa1b162bc9e0de2..286a4ecec273ca0e2fe2d65f80e8566a68a2f794 100644 GIT binary patch delta 65 zcmbQ>)au0L66_Mfs>r~=D6x@?Phzu)#5y)Ef906?V5fKicje7*$Yf1OQ7T6vzMo delta 86 zcmbObH9LySCD diff --git a/tests/data/acpi/q35/DSDT.cxl b/tests/data/acpi/q35/DSDT.cxl index aeea64d1cecad0ad011870ed5e04bfea1ae62510..96594c00b3b0e0a4933d6d851d927487ad4d18eb 100644 GIT binary patch delta 65 zcmbQ>)9SZ;;Xupw*Phzu)#4c_wXXTjqV5fKiZ>7yYlm(e2qMP`G-JIe% U;vHRrc$gXF8AR9uoc%%=03WdrZ2$lO delta 76 zcmZqmnc&0a66_KppvJ(!xMCw0pMPD(K#6#`z0o9`$KGO>%W1vvYKFaQA0rV=jz diff --git a/tests/data/acpi/q35/DSDT.dimmpxm b/tests/data/acpi/q35/DSDT.dimmpxm index ed11aefa4a56a8408bd4e0de83bf2373e6025449..e2a3ecf7d90c8c411550505c3b70bf8d19ba4bc9 100644 GIT binary patch delta 65 zcmccNch--~CDcf*g%CD- diff --git a/tests/data/acpi/q35/DSDT.ipmibt b/tests/data/acpi/q35/DSDT.ipmibt index d9d1e75c987acd42be4576688621be07b21f0e7b..427272b95692099edc47f569e41fbb3ba69f6b60 100644 GIT binary patch delta 65 zcmZ4Mw8)9eCDNWHeZmlVqzCz3vl)eVE_Q=2@;q9 diff --git a/tests/data/acpi/q35/DSDT.ipmismbus b/tests/data/acpi/q35/DSDT.ipmismbus index f6e124137721312722c820b5c084a143492945c9..794779e75aaf33902de834caaa6b0763c4513615 100644 GIT binary patch delta 61 zcmdn(wBCu!CD-Q+$B4r$Ka+J6o`?lfmTU3W=M=CDyZX aIVi+{Bn3R=H(!u@&&V#q7U1j`!T=(iS0Ek8rTL1t6 delta 75 zcmaFi_}P)mCDq3sap6WTJ_%`Qz4&0K_yA{5gXkvyU|%N#j(A6xARcB0d4|p6 e692fl928_H_NNMXJi*)3vl)eVE_Q{`4Z;< diff --git a/tests/data/acpi/q35/DSDT.mmio64 b/tests/data/acpi/q35/DSDT.mmio64 index afc260ebf4d91a2a9f7be5ff21968e99b1f9c5d1..a77aa37ca0bb407abbef134e8dce4461070856a2 100644 GIT binary patch delta 64 zcmX@(boA`s>oZ>m+ T9bJNWm>J|5MA!nH{X!T3EYS}} delta 75 zcmX@;b;gU!CD>_Ld&VC^b0K(`I2mk;8 diff --git a/tests/data/acpi/q35/DSDT.multi-bridge b/tests/data/acpi/q35/DSDT.multi-bridge index 7c14ce3a986fa06e88f3adc088faae54bdd2d8e4..43469e6c89813025b902534ed61d39ad940ff7bb 100644 GIT binary patch delta 85 zcmZ4FGTnvCCD!;w2TKaK`a9>3jo0872^N^ delta 72 zcmbR4vdD$YCDpMqMP`G-JIe% U;vHRrc$gXF8AR9uoc%%=04azMg8%>k delta 76 zcmX@_H(!%`&&V#q7U1j`!T5Yqqv delta 76 zcmdnvbli!{CD diff --git a/tests/data/acpi/q35/DSDT.tis.tpm2 b/tests/data/acpi/q35/DSDT.tis.tpm2 index b55e828c6397f80c14de82f371fa34553008a875..47417f47f7e25576f31207cb0b752b8c086a4480 100644 GIT binary patch delta 65 zcmccRcHWK4CD+CD1vvYKFaQ7tbrWF# diff --git a/tests/data/acpi/q35/DSDT.viot b/tests/data/acpi/q35/DSDT.viot index a8a93fe70d8e98ec0e66278b45d36393b75740ec..574b8a0094c556cd8555b7a4e1b92b2d5f64750a 100644 GIT binary patch delta 65 zcmdn)wZ@CfCD)ooUx}CN7s?myliE3=E8aH*)bwY&MaYSjgq57!x1t6ffYZu=#xFdq#=qCjMYI Xr+AKdN0%TTW(Ii%5w-wlzYqoh?b#EU delta 78 zcmdlro$2UwCN7s?myn~~3=E8E8@c!-q^0%ZgPr07oIMSqoA`r$oeVhQ9bJNWm>J|5 gHj7J4D&%rdhyke(@Q~lUx$`|Ey9ir=vtI}U0BHvmS^xk5 diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h index fd5852776c..dfb8523c8b 100644 --- a/tests/qtest/bios-tables-test-allowed-diff.h +++ b/tests/qtest/bios-tables-test-allowed-diff.h @@ -1,22 +1 @@ /* List of comma-separated changed AML files to ignore */ -"tests/data/acpi/q35/DSDT", -"tests/data/acpi/q35/DSDT.acpierst", -"tests/data/acpi/q35/DSDT.acpihmat", -"tests/data/acpi/q35/DSDT.applesmc", -"tests/data/acpi/q35/DSDT.bridge", -"tests/data/acpi/q35/DSDT.cphp", -"tests/data/acpi/q35/DSDT.cxl", -"tests/data/acpi/q35/DSDT.dimmpxm", -"tests/data/acpi/q35/DSDT.ipmibt", -"tests/data/acpi/q35/DSDT.ipmismbus", -"tests/data/acpi/q35/DSDT.ivrs", -"tests/data/acpi/q35/DSDT.memhp", -"tests/data/acpi/q35/DSDT.mmio64", -"tests/data/acpi/q35/DSDT.multi-bridge", -"tests/data/acpi/q35/DSDT.nohpet", -"tests/data/acpi/q35/DSDT.numamem", -"tests/data/acpi/q35/DSDT.pvpanic-isa", -"tests/data/acpi/q35/DSDT.tis.tpm12", -"tests/data/acpi/q35/DSDT.tis.tpm2", -"tests/data/acpi/q35/DSDT.viot", -"tests/data/acpi/q35/DSDT.xapic", From 11787b28b0e216e4b1cd9d1f76c4544a6c674f17 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Mon, 17 Oct 2022 12:21:44 +0200 Subject: [PATCH 633/705] tests: acpi: pc/q35 whitelist DSDT before \_GPE cleanup Signed-off-by: Igor Mammedov Message-Id: <20221017102146.2254096-10-imammedo@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- tests/qtest/bios-tables-test-allowed-diff.h | 34 +++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h index dfb8523c8b..725a1dc798 100644 --- a/tests/qtest/bios-tables-test-allowed-diff.h +++ b/tests/qtest/bios-tables-test-allowed-diff.h @@ -1 +1,35 @@ /* List of comma-separated changed AML files to ignore */ +"tests/data/acpi/pc/DSDT", +"tests/data/acpi/pc/DSDT.bridge", +"tests/data/acpi/pc/DSDT.ipmikcs", +"tests/data/acpi/pc/DSDT.cphp", +"tests/data/acpi/pc/DSDT.memhp", +"tests/data/acpi/pc/DSDT.numamem", +"tests/data/acpi/pc/DSDT.nohpet", +"tests/data/acpi/pc/DSDT.dimmpxm", +"tests/data/acpi/pc/DSDT.acpihmat", +"tests/data/acpi/pc/DSDT.acpierst", +"tests/data/acpi/pc/DSDT.roothp", +"tests/data/acpi/pc/DSDT.hpbridge", +"tests/data/acpi/pc/DSDT.hpbrroot", +"tests/data/acpi/q35/DSDT", +"tests/data/acpi/q35/DSDT.tis.tpm2", +"tests/data/acpi/q35/DSDT.tis.tpm12", +"tests/data/acpi/q35/DSDT.bridge", +"tests/data/acpi/q35/DSDT.multi-bridge", +"tests/data/acpi/q35/DSDT.mmio64", +"tests/data/acpi/q35/DSDT.ipmibt", +"tests/data/acpi/q35/DSDT.cphp", +"tests/data/acpi/q35/DSDT.memhp", +"tests/data/acpi/q35/DSDT.numamem", +"tests/data/acpi/q35/DSDT.nohpet", +"tests/data/acpi/q35/DSDT.dimmpxm", +"tests/data/acpi/q35/DSDT.acpihmat", +"tests/data/acpi/q35/DSDT.acpierst", +"tests/data/acpi/q35/DSDT.applesmc", +"tests/data/acpi/q35/DSDT.pvpanic-isa", +"tests/data/acpi/q35/DSDT.ivrs", +"tests/data/acpi/q35/DSDT.viot", +"tests/data/acpi/q35/DSDT.cxl", +"tests/data/acpi/q35/DSDT.ipmismbus", +"tests/data/acpi/q35/DSDT.xapic", From d12dbd44e42fa0e851d62e0804f78bab5bd148d5 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Mon, 17 Oct 2022 12:21:45 +0200 Subject: [PATCH 634/705] acpi: pc/35: sanitize _GPE declaration order Move _GPE block declaration before it gets referenced by other hotplug handlers. While at it move PCI hotplug (_E01) handler after PCI tree description to avoid forward reference to to not yet declared methods/devices. PS: Forward 'usage' usualy is fine as long as it's hidden within method, however 'iasl' may print warnings. So be nice to iasl/guest OS and do things in proper order. PS2: Also follow up patches will move some of hotplug code from PCI tree to _E01 and that also requires PCI Device nodes build first, before Scope can reuse that from global context. Signed-off-by: Igor Mammedov Message-Id: <20221017102146.2254096-11-imammedo@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-build.c | 47 +++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 916343d8d6..960305462c 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -1434,6 +1434,18 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, aml_append(dsdt, sb_scope); } + scope = aml_scope("_GPE"); + { + aml_append(scope, aml_name_decl("_HID", aml_string("ACPI0006"))); + if (machine->nvdimms_state->is_enabled) { + method = aml_method("_E04", 0, AML_NOTSERIALIZED); + aml_append(method, aml_notify(aml_name("\\_SB.NVDR"), + aml_int(0x80))); + aml_append(scope, method); + } + } + aml_append(dsdt, scope); + if (pcmc->legacy_cpu_hotplug) { build_legacy_cpu_hotplug_aml(dsdt, machine, pm->cpu_hp_io_base); } else { @@ -1452,28 +1464,6 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, pcms->memhp_io_base); } - scope = aml_scope("_GPE"); - { - aml_append(scope, aml_name_decl("_HID", aml_string("ACPI0006"))); - - if (pm->pcihp_bridge_en || pm->pcihp_root_en) { - method = aml_method("_E01", 0, AML_NOTSERIALIZED); - aml_append(method, - aml_acquire(aml_name("\\_SB.PCI0.BLCK"), 0xFFFF)); - aml_append(method, aml_call0("\\_SB.PCI0.PCNT")); - aml_append(method, aml_release(aml_name("\\_SB.PCI0.BLCK"))); - aml_append(scope, method); - } - - if (machine->nvdimms_state->is_enabled) { - method = aml_method("_E04", 0, AML_NOTSERIALIZED); - aml_append(method, aml_notify(aml_name("\\_SB.NVDR"), - aml_int(0x80))); - aml_append(scope, method); - } - } - aml_append(dsdt, scope); - crs_range_set_init(&crs_range_set); bus = PC_MACHINE(machine)->bus; if (bus) { @@ -1752,6 +1742,19 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, } aml_append(dsdt, sb_scope); + if (pm->pcihp_bridge_en || pm->pcihp_root_en) { + scope = aml_scope("_GPE"); + { + method = aml_method("_E01", 0, AML_NOTSERIALIZED); + aml_append(method, + aml_acquire(aml_name("\\_SB.PCI0.BLCK"), 0xFFFF)); + aml_append(method, aml_call0("\\_SB.PCI0.PCNT")); + aml_append(method, aml_release(aml_name("\\_SB.PCI0.BLCK"))); + aml_append(scope, method); + } + aml_append(dsdt, scope); + } + /* copy AML table into ACPI tables blob and patch header there */ g_array_append_vals(table_data, dsdt->buf->data, dsdt->buf->len); acpi_table_end(linker, &table); From 0193d693a9c9323770c865f87942d8d4c0cbd8ff Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Mon, 17 Oct 2022 12:21:46 +0200 Subject: [PATCH 635/705] tests: acpi: update expected blobs Expected changes are: 1) Moving _GPE scope declaration achec of all _E0x methods + Scope (_GPE) + { + Name (_HID, "ACPI0006" /* GPE Block Device */) // _HID: Hardware ID + } + Scope (_SB) { Device (\_SB.PCI0.PRES) ============ \_SB.CPUS.CSCN () } - Scope (_GPE) - { - Name (_HID, "ACPI0006" /* GPE Block Device */) // _HID: Hardware ID - } 2) Moving _E01 handler after PCI0 scope is defined - Scope (_GPE) - { - Name (_HID, "ACPI0006" /* GPE Block Device */) // _HID: Hardware ID - Method (_E01, 0, NotSerialized) // _Exx: Edge-Triggered GPE - { - Acquire (\_SB.PCI0.BLCK, 0xFFFF) - \_SB.PCI0.PCNT () - Release (\_SB.PCI0.BLCK) - } - } - Scope (\_SB.PCI0) { Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings ============= } } } + + Scope (_GPE) + { + Method (_E01, 0, NotSerialized) // _Exx: Edge-Triggered GPE + { + Acquire (\_SB.PCI0.BLCK, 0xFFFF) + \_SB.PCI0.PCNT () + Release (\_SB.PCI0.BLCK) + } + } } Signed-off-by: Igor Mammedov Message-Id: <20221017102146.2254096-12-imammedo@redhat.com> --- tests/data/acpi/pc/DSDT | Bin 6496 -> 6501 bytes tests/data/acpi/pc/DSDT.acpierst | Bin 6456 -> 6461 bytes tests/data/acpi/pc/DSDT.acpihmat | Bin 7821 -> 7826 bytes tests/data/acpi/pc/DSDT.bridge | Bin 9570 -> 9575 bytes tests/data/acpi/pc/DSDT.cphp | Bin 6960 -> 6965 bytes tests/data/acpi/pc/DSDT.dimmpxm | Bin 8150 -> 8155 bytes tests/data/acpi/pc/DSDT.hpbridge | Bin 6456 -> 6461 bytes tests/data/acpi/pc/DSDT.hpbrroot | Bin 3107 -> 3107 bytes tests/data/acpi/pc/DSDT.ipmikcs | Bin 6568 -> 6573 bytes tests/data/acpi/pc/DSDT.memhp | Bin 7855 -> 7860 bytes tests/data/acpi/pc/DSDT.nohpet | Bin 6354 -> 6359 bytes tests/data/acpi/pc/DSDT.numamem | Bin 6502 -> 6507 bytes tests/data/acpi/pc/DSDT.roothp | Bin 6694 -> 6699 bytes tests/data/acpi/q35/DSDT | Bin 8407 -> 8412 bytes tests/data/acpi/q35/DSDT.acpierst | Bin 8424 -> 8429 bytes tests/data/acpi/q35/DSDT.acpihmat | Bin 9732 -> 9737 bytes tests/data/acpi/q35/DSDT.applesmc | Bin 8453 -> 8458 bytes tests/data/acpi/q35/DSDT.bridge | Bin 11536 -> 11541 bytes tests/data/acpi/q35/DSDT.cphp | Bin 8871 -> 8876 bytes tests/data/acpi/q35/DSDT.cxl | Bin 9733 -> 9738 bytes tests/data/acpi/q35/DSDT.dimmpxm | Bin 10061 -> 10066 bytes tests/data/acpi/q35/DSDT.ipmibt | Bin 8482 -> 8487 bytes tests/data/acpi/q35/DSDT.ipmismbus | Bin 8495 -> 8500 bytes tests/data/acpi/q35/DSDT.ivrs | Bin 8424 -> 8429 bytes tests/data/acpi/q35/DSDT.memhp | Bin 9766 -> 9771 bytes tests/data/acpi/q35/DSDT.mmio64 | Bin 9537 -> 9542 bytes tests/data/acpi/q35/DSDT.multi-bridge | Bin 8727 -> 8732 bytes tests/data/acpi/q35/DSDT.nohpet | Bin 8265 -> 8270 bytes tests/data/acpi/q35/DSDT.numamem | Bin 8413 -> 8418 bytes tests/data/acpi/q35/DSDT.pvpanic-isa | Bin 8508 -> 8513 bytes tests/data/acpi/q35/DSDT.tis.tpm12 | Bin 9013 -> 9018 bytes tests/data/acpi/q35/DSDT.tis.tpm2 | Bin 9039 -> 9044 bytes tests/data/acpi/q35/DSDT.viot | Bin 9516 -> 9521 bytes tests/data/acpi/q35/DSDT.xapic | Bin 35770 -> 35775 bytes tests/qtest/bios-tables-test-allowed-diff.h | 34 -------------------- 35 files changed, 34 deletions(-) diff --git a/tests/data/acpi/pc/DSDT b/tests/data/acpi/pc/DSDT index 5b4624cb68c78eab6e356987974b9bee6c9a1785..f1cf7fab349bd26e0f0fa461c715534c1426fbf5 100644 GIT binary patch delta 60 zcmaE0^wfyUCDCX=Uu}Tiy diff --git a/tests/data/acpi/pc/DSDT.acpierst b/tests/data/acpi/pc/DSDT.acpierst index 99461b771eec2043263b5bc3c109a08969a99af9..5cb477625e96f5526f0c7703ba3b443a0b35eefd 100644 GIT binary patch delta 60 zcmdmCwAYBsCD1oq7x2P diff --git a/tests/data/acpi/pc/DSDT.acpihmat b/tests/data/acpi/pc/DSDT.acpihmat index b84f3b47c37e427b927c36036307db6e83a843e5..76e8bef36fdb667447ad0320d35604031aae2c93 100644 GIT binary patch delta 46 zcmeCRon*`966_K(NsfVmaqdR0HLQ#xlRxqaZ{Esk#ktv@-;bY7z&_qRz;!YUzZC#I C&J4u> delta 55 zcmbPa+iT0^66_MvE62dV_;w@L8rIFHSuHt5{aNDO16(=cJv?1_9i0O_4Gav-7$!%^ LS#4(K_vZ%yzRnKP diff --git a/tests/data/acpi/pc/DSDT.bridge b/tests/data/acpi/pc/DSDT.bridge index 6771620078086e42b445474b16797094e0d0a801..c94c1b54b3ac3085c02307d9564b258e791fcf1e 100644 GIT binary patch delta 60 zcmaFl_1ufgCD@$5#fHLSuS@$Lbx9Pu8WF1(J;0iFg124Vg)v(z|z@HxgQ?nI5 diff --git a/tests/data/acpi/pc/DSDT.hpbridge b/tests/data/acpi/pc/DSDT.hpbridge index 99461b771eec2043263b5bc3c109a08969a99af9..5cb477625e96f5526f0c7703ba3b443a0b35eefd 100644 GIT binary patch delta 60 zcmdmCwAYBsCD1oq7x2P diff --git a/tests/data/acpi/pc/DSDT.hpbrroot b/tests/data/acpi/pc/DSDT.hpbrroot index b10b17cb1111f6b5d61da4aa1c754f2921a4ac1c..ff04ad360beb60571d48bd1e477a4e58e5ee9337 100644 GIT binary patch delta 37 scmZ21u~=e5CX290ynBEvN4$rp3$LSdfTw|hf!XGC7Cx5ET^uu+0mthKGXMYp delta 38 tcmZ21u~=e5Cd=kJ79JK6k$Cq2SB`iOPZwTC=KxOw0|PUL&7B;xm;uwt3P}I} diff --git a/tests/data/acpi/pc/DSDT.ipmikcs b/tests/data/acpi/pc/DSDT.ipmikcs index aff3e9bbe1fdbf783c49d07a49c2e16317a2871e..83eec58a52b5844a02003665494f63a4ea0b26a7 100644 GIT binary patch delta 60 zcmZ2syw;e@CD(+U9a*$_bh delta 55 zcmZ2$yuz5vCDCX=UxO5J{ diff --git a/tests/data/acpi/pc/DSDT.numamem b/tests/data/acpi/pc/DSDT.numamem index e03f4d07b86018d12def37b5397ba9673548e2b7..1cecaa64e9ef29b5096ae1ba4882e2c8e080f0ea 100644 GIT binary patch delta 60 zcmaE6^xBBaCDFn`uA2{E diff --git a/tests/data/acpi/q35/DSDT b/tests/data/acpi/q35/DSDT index c8a2b5df26608f10c75ab8f2f9e404fda987891b..8e989819a5f8c470a8933bf9b7af7b988048cce6 100644 GIT binary patch delta 60 zcmccac*l{;CDF$5%p`l2 OnN7eRBt7}Kj1>Sj$q~x{ delta 55 zcmccPc-@i9CDF$5%q07a OnN7eRBt7}Kj1>SepAoMB delta 55 zcmaFs_`;FPCDGa`p33dtLRAXRZ+`N%%js&B~q7?u+ C+70gj delta 55 zcmeD5Y4PE533dr#QDb0WWZuX%M`H7C2}@2T=?833dtLQeR`WAsL@ITFGm@$Lbx9Pu8WF1(J;0iFg124dzAI9^lFm@8Rjf>*yTdX<%Sr#xS`^ L$!ha7xogY-;e!y; diff --git a/tests/data/acpi/q35/DSDT.cxl b/tests/data/acpi/q35/DSDT.cxl index 96594c00b3b0e0a4933d6d851d927487ad4d18eb..cecc1caaab81db8559781d23e45d8c615dc73740 100644 GIT binary patch delta 60 zcmZqm>GI)n33dtLQe$9Xe7})vj)bsCynBEvN4$rp3$LSdfTw|hf!XFI5_~M1nPizc O*#zuC(vy$NSOEaxZV#OR delta 55 zcmeD3Y4zc933dr#RbyaawBN`zM`H7C2_6cgc^-CD(^b diff --git a/tests/data/acpi/q35/DSDT.ipmibt b/tests/data/acpi/q35/DSDT.ipmibt index 427272b95692099edc47f569e41fbb3ba69f6b60..c4f8212c63be2a1d579d6ebc9ac41d4bd5be414b 100644 GIT binary patch delta 60 zcmZ4FwA_iyCDt_cgbxq^ delta 55 zcmZ4Pw8)9eCD8ITFGm@$Lbx9Pu8WF1(J;0iFg124F$5%q07a OnN7eRBt7}Kj1>SepAoMB delta 55 zcmaFs_`;FPCDCDxc;90_5Oc=rHTj(87G7hXr_08ax01GCLbB=}f1Gs%jw OvI*FOq$eMju>t_l9uGeN delta 55 zcmbQ^GTnvCCD LXtnv6j2J5bsWcBX diff --git a/tests/data/acpi/q35/DSDT.nohpet b/tests/data/acpi/q35/DSDT.nohpet index e17b252b03b290ba39601afffbee66159a57bfb1..9c2ec9f2c96f6bdf536c28559fd804523134cf2c 100644 GIT binary patch delta 61 zcmX@SZBN3SZ delta 55 zcmaFlc-N83CD*CD7gb)S* delta 55 zcmX@;w8x3dCDt_xEDwVK delta 54 zcmdnxw$+WxCD; diff --git a/tests/data/acpi/q35/DSDT.viot b/tests/data/acpi/q35/DSDT.viot index 574b8a0094c556cd8555b7a4e1b92b2d5f64750a..6927d1cc96565f0e1e4c7f19fd709635873db912 100644 GIT binary patch delta 60 zcmZ4Ewb6^qCD Date: Mon, 24 Oct 2022 17:42:33 +0200 Subject: [PATCH 636/705] hw/acpi/erst.c: Fix memory handling issues - Fix memset argument order: The second argument is the value, the length goes last. - Fix an integer overflow reported by Alexander Bulekov. Both issues allow the guest to overrun the host buffer allocated for the ERST memory device. Cc: Eric DeVolder Cc: qemu-stable@nongnu.org Fixes: f7e26ffa590 ("ACPI ERST: support for ACPI ERST feature") Tested-by: Alexander Bulekov Signed-off-by: Christian A. Ehrhardt Message-Id: <20221024154233.1043347-1-lk@c--e.de> Fixes: https://gitlab.com/qemu-project/qemu/-/issues/1268 Reviewed-by: Alexander Bulekov Reviewed-by: Eric DeVolder Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/erst.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/acpi/erst.c b/hw/acpi/erst.c index df856b2669..aefcc03ad6 100644 --- a/hw/acpi/erst.c +++ b/hw/acpi/erst.c @@ -635,7 +635,7 @@ static unsigned read_erst_record(ERSTDeviceState *s) if (record_length < UEFI_CPER_RECORD_MIN_SIZE) { rc = STATUS_FAILED; } - if ((s->record_offset + record_length) > exchange_length) { + if (record_length > exchange_length - s->record_offset) { rc = STATUS_FAILED; } /* If all is ok, copy the record to the exchange buffer */ @@ -684,7 +684,7 @@ static unsigned write_erst_record(ERSTDeviceState *s) if (record_length < UEFI_CPER_RECORD_MIN_SIZE) { return STATUS_FAILED; } - if ((s->record_offset + record_length) > exchange_length) { + if (record_length > exchange_length - s->record_offset) { return STATUS_FAILED; } @@ -716,7 +716,7 @@ static unsigned write_erst_record(ERSTDeviceState *s) if (nvram) { /* Write the record into the slot */ memcpy(nvram, exchange, record_length); - memset(nvram + record_length, exchange_length - record_length, 0xFF); + memset(nvram + record_length, 0xFF, exchange_length - record_length); /* If a new record, increment the record_count */ if (!record_found) { uint32_t record_count; From 3b3112501d65a36782b6cd1dafee8a3e8e56fd6a Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 20 Oct 2022 14:04:58 +0200 Subject: [PATCH 637/705] MAINTAINERS: Add qapi/virtio.json to section "virtio" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Michael S. Tsirkin Signed-off-by: Markus Armbruster Message-Id: <20221020120458.80709-1-armbru@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Philippe Mathieu-Daudé --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 8b7d49b089..28cc70c25f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2017,6 +2017,7 @@ S: Supported F: hw/*/virtio* F: hw/virtio/Makefile.objs F: hw/virtio/trace-events +F: qapi/virtio.json F: net/vhost-user.c F: include/hw/virtio/ From 15377f6e79cc6aa08dbafe82607e0bda13ca44b5 Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Mon, 29 Aug 2022 17:35:24 +0900 Subject: [PATCH 638/705] msix: Assert that specified vector is in range There were several different ways to deal with the situation where the vector specified for a msix function is out of bound: - early return a function and keep progresssing - propagate the error to the caller - mark msix unusable - assert it is in bound - just ignore An out-of-bound vector should not be specified if the device implementation is correct so let msix functions always assert that the specified vector is in range. An exceptional case is virtio-pci, which allows the guest to configure vectors. For virtio-pci, it is more appropriate to introduce its own checks because it is sometimes too late to check the vector range in msix functions. Signed-off-by: Akihiko Odaki Message-Id: <20220829083524.143640-1-akihiko.odaki@daynix.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Yuval Shaia Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
--- hw/net/e1000e.c | 15 ++------- hw/net/rocker/rocker.c | 23 ++------------ hw/net/vmxnet3.c | 27 +++------------- hw/nvme/ctrl.c | 5 +-- hw/pci/msix.c | 24 ++++++-------- hw/rdma/vmw/pvrdma_main.c | 7 +--- hw/remote/vfio-user-obj.c | 9 +----- hw/virtio/virtio-pci.c | 67 ++++++++++++++++++++++++++++----------- include/hw/pci/msix.h | 4 +-- 9 files changed, 74 insertions(+), 107 deletions(-) diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c index ac96f7665a..7523e9f5d2 100644 --- a/hw/net/e1000e.c +++ b/hw/net/e1000e.c @@ -276,25 +276,18 @@ e1000e_unuse_msix_vectors(E1000EState *s, int num_vectors) } } -static bool +static void e1000e_use_msix_vectors(E1000EState *s, int num_vectors) { int i; for (i = 0; i < num_vectors; i++) { - int res = msix_vector_use(PCI_DEVICE(s), i); - if (res < 0) { - trace_e1000e_msix_use_vector_fail(i, res); - e1000e_unuse_msix_vectors(s, i); - return false; - } + msix_vector_use(PCI_DEVICE(s), i); } - return true; } static void e1000e_init_msix(E1000EState *s) { - PCIDevice *d = PCI_DEVICE(s); int res = msix_init(PCI_DEVICE(s), E1000E_MSIX_VEC_NUM, &s->msix, E1000E_MSIX_IDX, E1000E_MSIX_TABLE, @@ -305,9 +298,7 @@ e1000e_init_msix(E1000EState *s) if (res < 0) { trace_e1000e_msix_init_fail(res); } else { - if (!e1000e_use_msix_vectors(s, E1000E_MSIX_VEC_NUM)) { - msix_uninit(d, &s->msix, &s->msix); - } + e1000e_use_msix_vectors(s, E1000E_MSIX_VEC_NUM); } } diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c index d8f3f16fe8..281d43e6cf 100644 --- a/hw/net/rocker/rocker.c +++ b/hw/net/rocker/rocker.c @@ -1212,24 +1212,14 @@ static void rocker_msix_vectors_unuse(Rocker *r, } } -static int rocker_msix_vectors_use(Rocker *r, - unsigned int num_vectors) +static void rocker_msix_vectors_use(Rocker *r, unsigned int num_vectors) { PCIDevice *dev = PCI_DEVICE(r); - int err; int i; for (i = 0; i < num_vectors; i++) { - err = msix_vector_use(dev, i); - if (err) { - goto rollback; - } + msix_vector_use(dev, i); } - return 0; - -rollback: - rocker_msix_vectors_unuse(r, i); - return err; } static int rocker_msix_init(Rocker *r, Error **errp) @@ -1247,16 +1237,9 @@ static int rocker_msix_init(Rocker *r, Error **errp) return err; } - err = rocker_msix_vectors_use(r, ROCKER_MSIX_VEC_COUNT(r->fp_ports)); - if (err) { - goto err_msix_vectors_use; - } + rocker_msix_vectors_use(r, ROCKER_MSIX_VEC_COUNT(r->fp_ports)); return 0; - -err_msix_vectors_use: - msix_uninit(dev, &r->msix_bar, &r->msix_bar); - return err; } static void rocker_msix_uninit(Rocker *r) diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index 0b7acf7f89..d2ab527ef4 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -2110,20 +2110,14 @@ vmxnet3_unuse_msix_vectors(VMXNET3State *s, int num_vectors) } } -static bool +static void vmxnet3_use_msix_vectors(VMXNET3State *s, int num_vectors) { PCIDevice *d = PCI_DEVICE(s); int i; for (i = 0; i < num_vectors; i++) { - int res = msix_vector_use(d, i); - if (0 > res) { - VMW_WRPRN("Failed to use MSI-X vector %d, error %d", i, res); - vmxnet3_unuse_msix_vectors(s, i); - return false; - } + msix_vector_use(d, i); } - return true; } static bool @@ -2141,13 +2135,8 @@ vmxnet3_init_msix(VMXNET3State *s) VMW_WRPRN("Failed to initialize MSI-X, error %d", res); s->msix_used = false; } else { - if (!vmxnet3_use_msix_vectors(s, VMXNET3_MAX_INTRS)) { - VMW_WRPRN("Failed to use MSI-X vectors, error %d", res); - msix_uninit(d, &s->msix_bar, &s->msix_bar); - s->msix_used = false; - } else { - s->msix_used = true; - } + vmxnet3_use_msix_vectors(s, VMXNET3_MAX_INTRS); + s->msix_used = true; } return s->msix_used; } @@ -2412,19 +2401,13 @@ static const VMStateDescription vmstate_vmxnet3_rxq_descr = { static int vmxnet3_post_load(void *opaque, int version_id) { VMXNET3State *s = opaque; - PCIDevice *d = PCI_DEVICE(s); net_tx_pkt_init(&s->tx_pkt, PCI_DEVICE(s), s->max_tx_frags, s->peer_has_vhdr); net_rx_pkt_init(&s->rx_pkt, s->peer_has_vhdr); if (s->msix_used) { - if (!vmxnet3_use_msix_vectors(s, VMXNET3_MAX_INTRS)) { - VMW_WRPRN("Failed to re-use MSI-X vectors"); - msix_uninit(d, &s->msix_bar, &s->msix_bar); - s->msix_used = false; - return -1; - } + vmxnet3_use_msix_vectors(s, VMXNET3_MAX_INTRS); } if (!vmxnet3_validate_queues(s)) { diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c index 87aeba0564..d38fdd990e 100644 --- a/hw/nvme/ctrl.c +++ b/hw/nvme/ctrl.c @@ -4744,11 +4744,8 @@ static void nvme_init_cq(NvmeCQueue *cq, NvmeCtrl *n, uint64_t dma_addr, uint16_t cqid, uint16_t vector, uint16_t size, uint16_t irq_enabled) { - int ret; - if (msix_enabled(&n->parent_obj)) { - ret = msix_vector_use(&n->parent_obj, vector); - assert(ret == 0); + msix_vector_use(&n->parent_obj, vector); } cq->ctrl = n; cq->cqid = cqid; diff --git a/hw/pci/msix.c b/hw/pci/msix.c index 1e381a9813..9e70fcd6fa 100644 --- a/hw/pci/msix.c +++ b/hw/pci/msix.c @@ -136,17 +136,12 @@ static void msix_handle_mask_update(PCIDevice *dev, int vector, bool was_masked) } } -void msix_set_mask(PCIDevice *dev, int vector, bool mask, Error **errp) +void msix_set_mask(PCIDevice *dev, int vector, bool mask) { - ERRP_GUARD(); unsigned offset; bool was_masked; - if (vector > dev->msix_entries_nr) { - error_setg(errp, "msix: vector %d not allocated. max vector is %d", - vector, dev->msix_entries_nr); - return; - } + assert(vector < dev->msix_entries_nr); offset = vector * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_VECTOR_CTRL; @@ -522,7 +517,9 @@ void msix_notify(PCIDevice *dev, unsigned vector) { MSIMessage msg; - if (vector >= dev->msix_entries_nr || !dev->msix_entry_used[vector]) { + assert(vector < dev->msix_entries_nr); + + if (!dev->msix_entry_used[vector]) { return; } @@ -558,20 +555,17 @@ void msix_reset(PCIDevice *dev) * don't want to follow the spec suggestion can declare all vectors as used. */ /* Mark vector as used. */ -int msix_vector_use(PCIDevice *dev, unsigned vector) +void msix_vector_use(PCIDevice *dev, unsigned vector) { - if (vector >= dev->msix_entries_nr) { - return -EINVAL; - } - + assert(vector < dev->msix_entries_nr); dev->msix_entry_used[vector]++; - return 0; } /* Mark vector as unused. */ void msix_vector_unuse(PCIDevice *dev, unsigned vector) { - if (vector >= dev->msix_entries_nr || !dev->msix_entry_used[vector]) { + assert(vector < dev->msix_entries_nr); + if (!dev->msix_entry_used[vector]) { return; } if (--dev->msix_entry_used[vector]) { diff --git a/hw/rdma/vmw/pvrdma_main.c b/hw/rdma/vmw/pvrdma_main.c index 58db0b8e3b..4fc6712025 100644 --- a/hw/rdma/vmw/pvrdma_main.c +++ b/hw/rdma/vmw/pvrdma_main.c @@ -307,12 +307,7 @@ static int init_msix(PCIDevice *pdev) } for (i = 0; i < RDMA_MAX_INTRS; i++) { - rc = msix_vector_use(PCI_DEVICE(dev), i); - if (rc < 0) { - rdma_error_report("Fail mark MSI-X vector %d", i); - uninit_msix(pdev, i); - return rc; - } + msix_vector_use(PCI_DEVICE(dev), i); } return 0; diff --git a/hw/remote/vfio-user-obj.c b/hw/remote/vfio-user-obj.c index c6cc53acf2..4e36bb8bcf 100644 --- a/hw/remote/vfio-user-obj.c +++ b/hw/remote/vfio-user-obj.c @@ -602,17 +602,10 @@ static void vfu_msix_irq_state(vfu_ctx_t *vfu_ctx, uint32_t start, uint32_t count, bool mask) { VfuObject *o = vfu_get_private(vfu_ctx); - Error *err = NULL; uint32_t vector; for (vector = start; vector < count; vector++) { - msix_set_mask(o->pci_dev, vector, mask, &err); - if (err) { - VFU_OBJECT_ERROR(o, "vfu: %s: %s", o->device, - error_get_pretty(err)); - error_free(err); - err = NULL; - } + msix_set_mask(o->pci_dev, vector, mask); } } diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 855718d586..a1c9dfa7bb 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -71,9 +71,11 @@ static void virtio_pci_notify(DeviceState *d, uint16_t vector) { VirtIOPCIProxy *proxy = to_virtio_pci_proxy_fast(d); - if (msix_enabled(&proxy->pci_dev)) - msix_notify(&proxy->pci_dev, vector); - else { + if (msix_enabled(&proxy->pci_dev)) { + if (vector != VIRTIO_NO_VECTOR) { + msix_notify(&proxy->pci_dev, vector); + } + } else { VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); pci_set_irq(&proxy->pci_dev, qatomic_read(&vdev->isr) & 1); } @@ -175,6 +177,7 @@ static int virtio_pci_load_config(DeviceState *d, QEMUFile *f) { VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d); VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + uint16_t vector; int ret; ret = pci_device_load(&proxy->pci_dev, f); @@ -184,12 +187,17 @@ static int virtio_pci_load_config(DeviceState *d, QEMUFile *f) msix_unuse_all_vectors(&proxy->pci_dev); msix_load(&proxy->pci_dev, f); if (msix_present(&proxy->pci_dev)) { - qemu_get_be16s(f, &vdev->config_vector); + qemu_get_be16s(f, &vector); + + if (vector != VIRTIO_NO_VECTOR && vector >= proxy->nvectors) { + return -EINVAL; + } } else { - vdev->config_vector = VIRTIO_NO_VECTOR; + vector = VIRTIO_NO_VECTOR; } - if (vdev->config_vector != VIRTIO_NO_VECTOR) { - return msix_vector_use(&proxy->pci_dev, vdev->config_vector); + vdev->config_vector = vector; + if (vector != VIRTIO_NO_VECTOR) { + msix_vector_use(&proxy->pci_dev, vector); } return 0; } @@ -202,12 +210,15 @@ static int virtio_pci_load_queue(DeviceState *d, int n, QEMUFile *f) uint16_t vector; if (msix_present(&proxy->pci_dev)) { qemu_get_be16s(f, &vector); + if (vector != VIRTIO_NO_VECTOR && vector >= proxy->nvectors) { + return -EINVAL; + } } else { vector = VIRTIO_NO_VECTOR; } virtio_queue_set_vector(vdev, n, vector); if (vector != VIRTIO_NO_VECTOR) { - return msix_vector_use(&proxy->pci_dev, vector); + msix_vector_use(&proxy->pci_dev, vector); } return 0; @@ -299,6 +310,7 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val) { VirtIOPCIProxy *proxy = opaque; VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + uint16_t vector; hwaddr pa; switch (addr) { @@ -352,18 +364,28 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val) } break; case VIRTIO_MSI_CONFIG_VECTOR: - msix_vector_unuse(&proxy->pci_dev, vdev->config_vector); + if (vdev->config_vector != VIRTIO_NO_VECTOR) { + msix_vector_unuse(&proxy->pci_dev, vdev->config_vector); + } /* Make it possible for guest to discover an error took place. */ - if (msix_vector_use(&proxy->pci_dev, val) < 0) + if (val < proxy->nvectors) { + msix_vector_use(&proxy->pci_dev, val); + } else { val = VIRTIO_NO_VECTOR; + } vdev->config_vector = val; break; case VIRTIO_MSI_QUEUE_VECTOR: - msix_vector_unuse(&proxy->pci_dev, - virtio_queue_vector(vdev, vdev->queue_sel)); + vector = virtio_queue_vector(vdev, vdev->queue_sel); + if (vector != VIRTIO_NO_VECTOR) { + msix_vector_unuse(&proxy->pci_dev, vector); + } /* Make it possible for guest to discover an error took place. */ - if (msix_vector_use(&proxy->pci_dev, val) < 0) + if (val < proxy->nvectors) { + msix_vector_use(&proxy->pci_dev, val); + } else { val = VIRTIO_NO_VECTOR; + } virtio_queue_set_vector(vdev, vdev->queue_sel, val); break; default: @@ -1266,6 +1288,7 @@ static void virtio_pci_common_write(void *opaque, hwaddr addr, { VirtIOPCIProxy *proxy = opaque; VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + uint16_t vector; if (vdev == NULL) { return; @@ -1287,9 +1310,13 @@ static void virtio_pci_common_write(void *opaque, hwaddr addr, } break; case VIRTIO_PCI_COMMON_MSIX: - msix_vector_unuse(&proxy->pci_dev, vdev->config_vector); + if (vdev->config_vector != VIRTIO_NO_VECTOR) { + msix_vector_unuse(&proxy->pci_dev, vdev->config_vector); + } /* Make it possible for guest to discover an error took place. */ - if (msix_vector_use(&proxy->pci_dev, val) < 0) { + if (val < proxy->nvectors) { + msix_vector_use(&proxy->pci_dev, val); + } else { val = VIRTIO_NO_VECTOR; } vdev->config_vector = val; @@ -1321,10 +1348,14 @@ static void virtio_pci_common_write(void *opaque, hwaddr addr, proxy->vqs[vdev->queue_sel].num); break; case VIRTIO_PCI_COMMON_Q_MSIX: - msix_vector_unuse(&proxy->pci_dev, - virtio_queue_vector(vdev, vdev->queue_sel)); + vector = virtio_queue_vector(vdev, vdev->queue_sel); + if (vector != VIRTIO_NO_VECTOR) { + msix_vector_unuse(&proxy->pci_dev, vector); + } /* Make it possible for guest to discover an error took place. */ - if (msix_vector_use(&proxy->pci_dev, val) < 0) { + if (val < proxy->nvectors) { + msix_vector_use(&proxy->pci_dev, val); + } else { val = VIRTIO_NO_VECTOR; } virtio_queue_set_vector(vdev, vdev->queue_sel, val); diff --git a/include/hw/pci/msix.h b/include/hw/pci/msix.h index 4f1cda0ebe..0e6f257e45 100644 --- a/include/hw/pci/msix.h +++ b/include/hw/pci/msix.h @@ -33,10 +33,10 @@ bool msix_is_masked(PCIDevice *dev, unsigned vector); void msix_set_pending(PCIDevice *dev, unsigned vector); void msix_clr_pending(PCIDevice *dev, int vector); -int msix_vector_use(PCIDevice *dev, unsigned vector); +void msix_vector_use(PCIDevice *dev, unsigned vector); void msix_vector_unuse(PCIDevice *dev, unsigned vector); void msix_unuse_all_vectors(PCIDevice *dev); -void msix_set_mask(PCIDevice *dev, int vector, bool mask, Error **errp); +void msix_set_mask(PCIDevice *dev, int vector, bool mask); void msix_notify(PCIDevice *dev, unsigned vector); From 2486dd045794d65598fbca9fd1224c27b9732dce Mon Sep 17 00:00:00 2001 From: Gregory Price Date: Wed, 26 Oct 2022 16:59:13 -0400 Subject: [PATCH 639/705] hw/i386/pc.c: CXL Fixed Memory Window should not reserve e820 in bios Early-boot e820 records will be inserted by the bios/efi/early boot software and be reported to the kernel via insert_resource. Later, when CXL drivers iterate through the regions again, they will insert another resource and make the RESERVED memory area a child. This RESERVED memory area causes the memory region to become unusable, and as a result attempting to create memory regions with `cxl create-region ...` Will fail due to the RESERVED area intersecting with the CXL window. During boot the following traceback is observed: 0xffffffff81101650 in insert_resource_expand_to_fit () 0xffffffff83d964c5 in e820__reserve_resources_late () 0xffffffff83e03210 in pcibios_resource_survey () 0xffffffff83e04f4a in pcibios_init () Which produces a call to reserve the CFMWS area: (gdb) p *new $54 = {start = 0x290000000, end = 0x2cfffffff, name = "Reserved", flags = 0x200, desc = 0x7, parent = 0x0, sibling = 0x0, child = 0x0} Later the Kernel parses ACPI tables and reserves the exact same area as the CXL Fixed Memory Window: 0xffffffff811016a4 in insert_resource_conflict () insert_resource () 0xffffffff81a81389 in cxl_parse_cfmws () 0xffffffff818c4a81 in call_handler () acpi_parse_entries_array () (gdb) p/x *new $59 = {start = 0x290000000, end = 0x2cfffffff, name = "CXL Window 0", flags = 0x200, desc = 0x0, parent = 0x0, sibling = 0x0, child = 0x0} This produces the following output in /proc/iomem: 590000000-68fffffff : CXL Window 0 590000000-68fffffff : Reserved This reserved area causes `get_free_mem_region()` to fail due to a check against `__region_intersects()`. Due to this reserved area, the intersect check will only ever return REGION_INTERSECTS, which causes `cxl create-region` to always fail. Signed-off-by: Gregory Price Message-Id: <20221026205912.8579-1-gregory.price@memverge.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Acked-by: Jonathan Cameron --- hw/i386/pc.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index ef14da5094..546b703cb4 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1061,7 +1061,6 @@ void pc_memory_init(PCMachineState *pcms, hwaddr cxl_size = MiB; cxl_base = pc_get_cxl_range_start(pcms); - e820_add_entry(cxl_base, cxl_size, E820_RESERVED); memory_region_init(mr, OBJECT(machine), "cxl_host_reg", cxl_size); memory_region_add_subregion(system_memory, cxl_base, mr); cxl_resv_end = cxl_base + cxl_size; @@ -1077,7 +1076,6 @@ void pc_memory_init(PCMachineState *pcms, memory_region_init_io(&fw->mr, OBJECT(machine), &cfmws_ops, fw, "cxl-fixed-memory-region", fw->size); memory_region_add_subregion(system_memory, fw->base, &fw->mr); - e820_add_entry(fw->base, fw->size, E820_RESERVED); cxl_fmw_base += fw->size; cxl_resv_end = cxl_fmw_base; } From 6f56d6de99a0f7c71f4a60fff585bbc0561e43c9 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Fri, 28 Oct 2022 12:34:17 +0200 Subject: [PATCH 640/705] hw/i386/acpi-build: Remove unused struct MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ammends commit b23046abe78f48498a423b802d6d86ba0172d57f 'pc: acpi-build: simplify PCI bus tree generation'. Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20221026133110.91828-2-shentey@gmail.com> Message-Id: <20221028103419.93398-2-shentey@gmail.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-build.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 960305462c..1ebf14b899 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -121,13 +121,6 @@ typedef struct AcpiMiscInfo { unsigned dsdt_size; } AcpiMiscInfo; -typedef struct AcpiBuildPciBusHotplugState { - GArray *device_table; - GArray *notify_table; - struct AcpiBuildPciBusHotplugState *parent; - bool pcihp_bridge_en; -} AcpiBuildPciBusHotplugState; - typedef struct FwCfgTPMConfig { uint32_t tpmppi_address; uint8_t tpm_version; From bbaa5c41fad29e9f6b4f1975103d530dc1391772 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Fri, 28 Oct 2022 12:34:18 +0200 Subject: [PATCH 641/705] hw/i386/acpi-build: Resolve redundant attribute MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The is_piix4 attribute is set once in one location and read once in another. Doing both in one location allows for removing the attribute altogether. Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20221026133110.91828-3-shentey@gmail.com> Message-Id: <20221028103419.93398-3-shentey@gmail.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-build.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 1ebf14b899..73d8a59737 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -112,7 +112,6 @@ typedef struct AcpiPmInfo { } AcpiPmInfo; typedef struct AcpiMiscInfo { - bool is_piix4; bool has_hpet; #ifdef CONFIG_TPM TPMVersion tpm_version; @@ -281,17 +280,6 @@ static void acpi_get_pm_info(MachineState *machine, AcpiPmInfo *pm) static void acpi_get_misc_info(AcpiMiscInfo *info) { - Object *piix = object_resolve_type_unambiguous(TYPE_PIIX4_PM); - Object *lpc = object_resolve_type_unambiguous(TYPE_ICH9_LPC_DEVICE); - assert(!!piix != !!lpc); - - if (piix) { - info->is_piix4 = true; - } - if (lpc) { - info->is_piix4 = false; - } - info->has_hpet = hpet_find(); #ifdef CONFIG_TPM info->tpm_version = tpm_get_version(tpm_find()); @@ -1334,6 +1322,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm, AcpiMiscInfo *misc, Range *pci_hole, Range *pci_hole64, MachineState *machine) { + Object *piix = object_resolve_type_unambiguous(TYPE_PIIX4_PM); + Object *lpc = object_resolve_type_unambiguous(TYPE_ICH9_LPC_DEVICE); CrsRangeEntry *entry; Aml *dsdt, *sb_scope, *scope, *dev, *method, *field, *pkg, *crs; CrsRangeSet crs_range_set; @@ -1354,11 +1344,13 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, AcpiTable table = { .sig = "DSDT", .rev = 1, .oem_id = x86ms->oem_id, .oem_table_id = x86ms->oem_table_id }; + assert(!!piix != !!lpc); + acpi_table_begin(&table, table_data); dsdt = init_aml_allocator(); build_dbg_aml(dsdt); - if (misc->is_piix4) { + if (piix) { sb_scope = aml_scope("_SB"); dev = aml_device("PCI0"); aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A03"))); @@ -1371,7 +1363,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, build_x86_acpi_pci_hotplug(dsdt, pm->pcihp_io_base); } build_piix4_pci0_int(dsdt); - } else { + } else if (lpc) { sb_scope = aml_scope("_SB"); dev = aml_device("PCI0"); aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08"))); From b496a17d45406e3ba943c8949784091cf01e4a6d Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Fri, 28 Oct 2022 12:34:19 +0200 Subject: [PATCH 642/705] hw/i386/acpi-build: Resolve north rather than south bridges The code currently assumes Q35 iff ICH9 and i440fx iff PIIX. Now that more AML generation has been moved into the south bridges and since the machines define themselves primarily through their north bridges, let's switch to resolving the north bridges for AML generation instead. This also allows for easier experimentation with different south bridges in the "pc" machine, e.g. with PIIX4 and VT82xx. Signed-off-by: Bernhard Beschow Message-Id: <20221028103419.93398-4-shentey@gmail.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-build.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 73d8a59737..d9eaa5fc4d 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -60,6 +60,7 @@ #include "hw/i386/fw_cfg.h" #include "hw/i386/ich9.h" #include "hw/pci/pci_bus.h" +#include "hw/pci-host/i440fx.h" #include "hw/pci-host/q35.h" #include "hw/i386/x86-iommu.h" @@ -1322,8 +1323,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm, AcpiMiscInfo *misc, Range *pci_hole, Range *pci_hole64, MachineState *machine) { - Object *piix = object_resolve_type_unambiguous(TYPE_PIIX4_PM); - Object *lpc = object_resolve_type_unambiguous(TYPE_ICH9_LPC_DEVICE); + Object *i440fx = object_resolve_type_unambiguous(TYPE_I440FX_PCI_HOST_BRIDGE); + Object *q35 = object_resolve_type_unambiguous(TYPE_Q35_HOST_DEVICE); CrsRangeEntry *entry; Aml *dsdt, *sb_scope, *scope, *dev, *method, *field, *pkg, *crs; CrsRangeSet crs_range_set; @@ -1344,13 +1345,13 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, AcpiTable table = { .sig = "DSDT", .rev = 1, .oem_id = x86ms->oem_id, .oem_table_id = x86ms->oem_table_id }; - assert(!!piix != !!lpc); + assert(!!i440fx != !!q35); acpi_table_begin(&table, table_data); dsdt = init_aml_allocator(); build_dbg_aml(dsdt); - if (piix) { + if (i440fx) { sb_scope = aml_scope("_SB"); dev = aml_device("PCI0"); aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A03"))); @@ -1363,7 +1364,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, build_x86_acpi_pci_hotplug(dsdt, pm->pcihp_io_base); } build_piix4_pci0_int(dsdt); - } else if (lpc) { + } else if (q35) { sb_scope = aml_scope("_SB"); dev = aml_device("PCI0"); aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08"))); From 83bcae9820c38d48c7ff9eb5839ed826531fb3f2 Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Thu, 27 Oct 2022 11:00:30 +0100 Subject: [PATCH 643/705] hmat acpi: Don't require initiator value in -numa The "Memory Proximity Domain Attributes" structure of the ACPI HMAT has a "Processor Proximity Domain Valid" flag that is currently always set because Qemu -numa requires an initiator=X value when hmat=on. Unsetting this flag allows to create more complex memory topologies by having multiple best initiators for a single memory target. This patch allows -numa without initiator=X when hmat=on by keeping the default value MAX_NODES in numa_state->nodes[i].initiator. All places reading numa_state->nodes[i].initiator already check whether it's different from MAX_NODES before using it. Tested with qemu-system-x86_64 -accel kvm \ -machine pc,hmat=on \ -drive if=pflash,format=raw,file=./OVMF.fd \ -drive media=disk,format=qcow2,file=efi.qcow2 \ -smp 4 \ -m 3G \ -object memory-backend-ram,size=1G,id=ram0 \ -object memory-backend-ram,size=1G,id=ram1 \ -object memory-backend-ram,size=1G,id=ram2 \ -numa node,nodeid=0,memdev=ram0,cpus=0-1 \ -numa node,nodeid=1,memdev=ram1,cpus=2-3 \ -numa node,nodeid=2,memdev=ram2 \ -numa hmat-lb,initiator=0,target=0,hierarchy=memory,data-type=access-latency,latency=10 \ -numa hmat-lb,initiator=0,target=0,hierarchy=memory,data-type=access-bandwidth,bandwidth=10485760 \ -numa hmat-lb,initiator=0,target=1,hierarchy=memory,data-type=access-latency,latency=20 \ -numa hmat-lb,initiator=0,target=1,hierarchy=memory,data-type=access-bandwidth,bandwidth=5242880 \ -numa hmat-lb,initiator=0,target=2,hierarchy=memory,data-type=access-latency,latency=30 \ -numa hmat-lb,initiator=0,target=2,hierarchy=memory,data-type=access-bandwidth,bandwidth=1048576 \ -numa hmat-lb,initiator=1,target=0,hierarchy=memory,data-type=access-latency,latency=20 \ -numa hmat-lb,initiator=1,target=0,hierarchy=memory,data-type=access-bandwidth,bandwidth=5242880 \ -numa hmat-lb,initiator=1,target=1,hierarchy=memory,data-type=access-latency,latency=10 \ -numa hmat-lb,initiator=1,target=1,hierarchy=memory,data-type=access-bandwidth,bandwidth=10485760 \ -numa hmat-lb,initiator=1,target=2,hierarchy=memory,data-type=access-latency,latency=30 \ -numa hmat-lb,initiator=1,target=2,hierarchy=memory,data-type=access-bandwidth,bandwidth=1048576 which reports NUMA node2 at same distance from both node0 and node1 as seen in lstopo: Machine (2966MB total) + Package P#0 NUMANode P#2 (979MB) Group0 NUMANode P#0 (980MB) Core P#0 + PU P#0 Core P#1 + PU P#1 Group0 NUMANode P#1 (1007MB) Core P#2 + PU P#2 Core P#3 + PU P#3 Before this patch, we had to add ",initiator=X" to "-numa node,nodeid=2,memdev=ram2". The lstopo output difference between initiator=1 and no initiator is: @@ -1,10 +1,10 @@ Machine (2966MB total) + Package P#0 + NUMANode P#2 (979MB) Group0 NUMANode P#0 (980MB) Core P#0 + PU P#0 Core P#1 + PU P#1 Group0 NUMANode P#1 (1007MB) - NUMANode P#2 (979MB) Core P#2 + PU P#2 Core P#3 + PU P#3 Corresponding changes in the HMAT MPDA structure: @@ -49,10 +49,10 @@ [078h 0120 2] Structure Type : 0000 [Memory Proximity Domain Attributes] [07Ah 0122 2] Reserved : 0000 [07Ch 0124 4] Length : 00000028 -[080h 0128 2] Flags (decoded below) : 0001 - Processor Proximity Domain Valid : 1 +[080h 0128 2] Flags (decoded below) : 0000 + Processor Proximity Domain Valid : 0 [082h 0130 2] Reserved1 : 0000 -[084h 0132 4] Attached Initiator Proximity Domain : 00000001 +[084h 0132 4] Attached Initiator Proximity Domain : 00000080 [088h 0136 4] Memory Proximity Domain : 00000002 [08Ch 0140 4] Reserved2 : 00000000 [090h 0144 8] Reserved3 : 0000000000000000 Final HMAT SLLB structures: [0A0h 0160 2] Structure Type : 0001 [System Locality Latency and Bandwidth Information] [0A2h 0162 2] Reserved : 0000 [0A4h 0164 4] Length : 00000040 [0A8h 0168 1] Flags (decoded below) : 00 Memory Hierarchy : 0 [0A9h 0169 1] Data Type : 00 [0AAh 0170 2] Reserved1 : 0000 [0ACh 0172 4] Initiator Proximity Domains # : 00000002 [0B0h 0176 4] Target Proximity Domains # : 00000003 [0B4h 0180 4] Reserved2 : 00000000 [0B8h 0184 8] Entry Base Unit : 0000000000002710 [0C0h 0192 4] Initiator Proximity Domain List : 00000000 [0C4h 0196 4] Initiator Proximity Domain List : 00000001 [0C8h 0200 4] Target Proximity Domain List : 00000000 [0CCh 0204 4] Target Proximity Domain List : 00000001 [0D0h 0208 4] Target Proximity Domain List : 00000002 [0D4h 0212 2] Entry : 0001 [0D6h 0214 2] Entry : 0002 [0D8h 0216 2] Entry : 0003 [0DAh 0218 2] Entry : 0002 [0DCh 0220 2] Entry : 0001 [0DEh 0222 2] Entry : 0003 [0E0h 0224 2] Structure Type : 0001 [System Locality Latency and Bandwidth Information] [0E2h 0226 2] Reserved : 0000 [0E4h 0228 4] Length : 00000040 [0E8h 0232 1] Flags (decoded below) : 00 Memory Hierarchy : 0 [0E9h 0233 1] Data Type : 03 [0EAh 0234 2] Reserved1 : 0000 [0ECh 0236 4] Initiator Proximity Domains # : 00000002 [0F0h 0240 4] Target Proximity Domains # : 00000003 [0F4h 0244 4] Reserved2 : 00000000 [0F8h 0248 8] Entry Base Unit : 0000000000000001 [100h 0256 4] Initiator Proximity Domain List : 00000000 [104h 0260 4] Initiator Proximity Domain List : 00000001 [108h 0264 4] Target Proximity Domain List : 00000000 [10Ch 0268 4] Target Proximity Domain List : 00000001 [110h 0272 4] Target Proximity Domain List : 00000002 [114h 0276 2] Entry : 000A [116h 0278 2] Entry : 0005 [118h 0280 2] Entry : 0001 [11Ah 0282 2] Entry : 0005 [11Ch 0284 2] Entry : 000A [11Eh 0286 2] Entry : 0001 Signed-off-by: Brice Goglin Signed-off-by: Hesham Almatary Reviewed-by: Jingqi Liu Message-Id: <20221027100037.251-2-hesham.almatary@huawei.com> Tested-by: Yicong Yang Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/core/machine.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/hw/core/machine.c b/hw/core/machine.c index 907fa78ff0..8d34caa31d 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -1178,9 +1178,7 @@ static void numa_validate_initiator(NumaState *numa_state) for (i = 0; i < numa_state->num_nodes; i++) { if (numa_info[i].initiator == MAX_NODES) { - error_report("The initiator of NUMA node %d is missing, use " - "'-numa node,initiator' option to declare it", i); - exit(1); + continue; } if (!numa_info[numa_info[i].initiator].present) { From e7cb1ce2492ec9b51f8cc5d2829b62ed8e51d3cb Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Thu, 27 Oct 2022 11:00:31 +0100 Subject: [PATCH 644/705] tests: acpi: add and whitelist *.hmat-noinitiator expected blobs .. which will be used by follow up hmat-noinitiator test-case. Signed-off-by: Brice Goglin Signed-off-by: Hesham Almatary Message-Id: <20221027100037.251-3-hesham.almatary@huawei.com> Tested-by: Yicong Yang Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- tests/data/acpi/q35/APIC.acpihmat-noinitiator | 0 tests/data/acpi/q35/DSDT.acpihmat-noinitiator | 0 tests/data/acpi/q35/HMAT.acpihmat-noinitiator | 0 tests/data/acpi/q35/SRAT.acpihmat-noinitiator | 0 tests/qtest/bios-tables-test-allowed-diff.h | 4 ++++ 5 files changed, 4 insertions(+) create mode 100644 tests/data/acpi/q35/APIC.acpihmat-noinitiator create mode 100644 tests/data/acpi/q35/DSDT.acpihmat-noinitiator create mode 100644 tests/data/acpi/q35/HMAT.acpihmat-noinitiator create mode 100644 tests/data/acpi/q35/SRAT.acpihmat-noinitiator diff --git a/tests/data/acpi/q35/APIC.acpihmat-noinitiator b/tests/data/acpi/q35/APIC.acpihmat-noinitiator new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/data/acpi/q35/DSDT.acpihmat-noinitiator b/tests/data/acpi/q35/DSDT.acpihmat-noinitiator new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/data/acpi/q35/HMAT.acpihmat-noinitiator b/tests/data/acpi/q35/HMAT.acpihmat-noinitiator new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/data/acpi/q35/SRAT.acpihmat-noinitiator b/tests/data/acpi/q35/SRAT.acpihmat-noinitiator new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h index dfb8523c8b..245fa66bcc 100644 --- a/tests/qtest/bios-tables-test-allowed-diff.h +++ b/tests/qtest/bios-tables-test-allowed-diff.h @@ -1 +1,5 @@ /* List of comma-separated changed AML files to ignore */ +"tests/data/acpi/q35/APIC.acpihmat-noinitiator", +"tests/data/acpi/q35/DSDT.acpihmat-noinitiator", +"tests/data/acpi/q35/HMAT.acpihmat-noinitiator", +"tests/data/acpi/q35/SRAT.acpihmat-noinitiator", From a046f1d7455dc0f9adb57e3f0e4a1827ee5fbe92 Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Thu, 27 Oct 2022 11:00:32 +0100 Subject: [PATCH 645/705] tests: acpi: q35: add test for hmat nodes without initiators expected HMAT: [000h 0000 4] Signature : "HMAT" [Heterogeneous Memory Attributes Table] [004h 0004 4] Table Length : 00000120 [008h 0008 1] Revision : 02 [009h 0009 1] Checksum : 4F [00Ah 0010 6] Oem ID : "BOCHS " [010h 0016 8] Oem Table ID : "BXPC " [018h 0024 4] Oem Revision : 00000001 [01Ch 0028 4] Asl Compiler ID : "BXPC" [020h 0032 4] Asl Compiler Revision : 00000001 [024h 0036 4] Reserved : 00000000 [028h 0040 2] Structure Type : 0000 [Memory Proximity Domain Attributes] [02Ah 0042 2] Reserved : 0000 [02Ch 0044 4] Length : 00000028 [030h 0048 2] Flags (decoded below) : 0001 Processor Proximity Domain Valid : 1 [032h 0050 2] Reserved1 : 0000 [034h 0052 4] Attached Initiator Proximity Domain : 00000000 [038h 0056 4] Memory Proximity Domain : 00000000 [03Ch 0060 4] Reserved2 : 00000000 [040h 0064 8] Reserved3 : 0000000000000000 [048h 0072 8] Reserved4 : 0000000000000000 [050h 0080 2] Structure Type : 0000 [Memory Proximity Domain Attributes] [052h 0082 2] Reserved : 0000 [054h 0084 4] Length : 00000028 [058h 0088 2] Flags (decoded below) : 0001 Processor Proximity Domain Valid : 1 [05Ah 0090 2] Reserved1 : 0000 [05Ch 0092 4] Attached Initiator Proximity Domain : 00000001 [060h 0096 4] Memory Proximity Domain : 00000001 [064h 0100 4] Reserved2 : 00000000 [068h 0104 8] Reserved3 : 0000000000000000 [070h 0112 8] Reserved4 : 0000000000000000 [078h 0120 2] Structure Type : 0000 [Memory Proximity Domain Attributes] [07Ah 0122 2] Reserved : 0000 [07Ch 0124 4] Length : 00000028 [080h 0128 2] Flags (decoded below) : 0000 Processor Proximity Domain Valid : 0 [082h 0130 2] Reserved1 : 0000 [084h 0132 4] Attached Initiator Proximity Domain : 00000080 [088h 0136 4] Memory Proximity Domain : 00000002 [08Ch 0140 4] Reserved2 : 00000000 [090h 0144 8] Reserved3 : 0000000000000000 [098h 0152 8] Reserved4 : 0000000000000000 [0A0h 0160 2] Structure Type : 0001 [System Locality Latency and Bandwidth Information] [0A2h 0162 2] Reserved : 0000 [0A4h 0164 4] Length : 00000040 [0A8h 0168 1] Flags (decoded below) : 00 Memory Hierarchy : 0 [0A9h 0169 1] Data Type : 00 [0AAh 0170 2] Reserved1 : 0000 [0ACh 0172 4] Initiator Proximity Domains # : 00000002 [0B0h 0176 4] Target Proximity Domains # : 00000003 [0B4h 0180 4] Reserved2 : 00000000 [0B8h 0184 8] Entry Base Unit : 0000000000002710 [0C0h 0192 4] Initiator Proximity Domain List : 00000000 [0C4h 0196 4] Initiator Proximity Domain List : 00000001 [0C8h 0200 4] Target Proximity Domain List : 00000000 [0CCh 0204 4] Target Proximity Domain List : 00000001 [0D0h 0208 4] Target Proximity Domain List : 00000002 [0D4h 0212 2] Entry : 0001 [0D6h 0214 2] Entry : 0002 [0D8h 0216 2] Entry : 0003 [0DAh 0218 2] Entry : 0002 [0DCh 0220 2] Entry : 0001 [0DEh 0222 2] Entry : 0003 [0E0h 0224 2] Structure Type : 0001 [System Locality Latency and Bandwidth Information] [0E2h 0226 2] Reserved : 0000 [0E4h 0228 4] Length : 00000040 [0E8h 0232 1] Flags (decoded below) : 00 Memory Hierarchy : 0 [0E9h 0233 1] Data Type : 03 [0EAh 0234 2] Reserved1 : 0000 [0ECh 0236 4] Initiator Proximity Domains # : 00000002 [0F0h 0240 4] Target Proximity Domains # : 00000003 [0F4h 0244 4] Reserved2 : 00000000 [0F8h 0248 8] Entry Base Unit : 0000000000000001 [100h 0256 4] Initiator Proximity Domain List : 00000000 [104h 0260 4] Initiator Proximity Domain List : 00000001 [108h 0264 4] Target Proximity Domain List : 00000000 [10Ch 0268 4] Target Proximity Domain List : 00000001 [110h 0272 4] Target Proximity Domain List : 00000002 [114h 0276 2] Entry : 000A [116h 0278 2] Entry : 0005 [118h 0280 2] Entry : 0001 [11Ah 0282 2] Entry : 0005 [11Ch 0284 2] Entry : 000A [11Eh 0286 2] Entry : 0001 Raw Table Data: Length 288 (0x120) 0000: 48 4D 41 54 20 01 00 00 02 4F 42 4F 43 48 53 20 // HMAT ....OBOCHS 0010: 42 58 50 43 20 20 20 20 01 00 00 00 42 58 50 43 // BXPC ....BXPC 0020: 01 00 00 00 00 00 00 00 00 00 00 00 28 00 00 00 // ............(... 0030: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................ 0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................ 0050: 00 00 00 00 28 00 00 00 01 00 00 00 01 00 00 00 // ....(........... 0060: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................ 0070: 00 00 00 00 00 00 00 00 00 00 00 00 28 00 00 00 // ............(... 0080: 00 00 00 00 80 00 00 00 02 00 00 00 00 00 00 00 // ................ 0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................ 00A0: 01 00 00 00 40 00 00 00 00 00 00 00 02 00 00 00 // ....@........... 00B0: 03 00 00 00 00 00 00 00 10 27 00 00 00 00 00 00 // .........'...... 00C0: 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 // ................ 00D0: 02 00 00 00 01 00 02 00 03 00 02 00 01 00 03 00 // ................ 00E0: 01 00 00 00 40 00 00 00 00 03 00 00 02 00 00 00 // ....@........... 00F0: 03 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 // ................ 0100: 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 // ................ 0110: 02 00 00 00 0A 00 05 00 01 00 05 00 0A 00 01 00 // ................ Signed-off-by: Brice Goglin Signed-off-by: Hesham Almatary Message-Id: <20221027100037.251-4-hesham.almatary@huawei.com> Tested-by: Yicong Yang Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- tests/qtest/bios-tables-test.c | 50 ++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c index e6096e7f73..02fe59fbf8 100644 --- a/tests/qtest/bios-tables-test.c +++ b/tests/qtest/bios-tables-test.c @@ -1461,6 +1461,54 @@ static void test_acpi_piix4_tcg_acpi_hmat(void) test_acpi_tcg_acpi_hmat(MACHINE_PC); } +static void test_acpi_q35_tcg_acpi_hmat_noinitiator(void) +{ + test_data data; + + memset(&data, 0, sizeof(data)); + data.machine = MACHINE_Q35; + data.variant = ".acpihmat-noinitiator"; + test_acpi_one(" -machine hmat=on" + " -smp 4,sockets=2" + " -m 128M" + " -object memory-backend-ram,size=32M,id=ram0" + " -object memory-backend-ram,size=32M,id=ram1" + " -object memory-backend-ram,size=64M,id=ram2" + " -numa node,nodeid=0,memdev=ram0" + " -numa node,nodeid=1,memdev=ram1" + " -numa node,nodeid=2,memdev=ram2" + " -numa cpu,node-id=0,socket-id=0" + " -numa cpu,node-id=0,socket-id=0" + " -numa cpu,node-id=1,socket-id=1" + " -numa cpu,node-id=1,socket-id=1" + " -numa hmat-lb,initiator=0,target=0,hierarchy=memory," + "data-type=access-latency,latency=10" + " -numa hmat-lb,initiator=0,target=0,hierarchy=memory," + "data-type=access-bandwidth,bandwidth=10485760" + " -numa hmat-lb,initiator=0,target=1,hierarchy=memory," + "data-type=access-latency,latency=20" + " -numa hmat-lb,initiator=0,target=1,hierarchy=memory," + "data-type=access-bandwidth,bandwidth=5242880" + " -numa hmat-lb,initiator=0,target=2,hierarchy=memory," + "data-type=access-latency,latency=30" + " -numa hmat-lb,initiator=0,target=2,hierarchy=memory," + "data-type=access-bandwidth,bandwidth=1048576" + " -numa hmat-lb,initiator=1,target=0,hierarchy=memory," + "data-type=access-latency,latency=20" + " -numa hmat-lb,initiator=1,target=0,hierarchy=memory," + "data-type=access-bandwidth,bandwidth=5242880" + " -numa hmat-lb,initiator=1,target=1,hierarchy=memory," + "data-type=access-latency,latency=10" + " -numa hmat-lb,initiator=1,target=1,hierarchy=memory," + "data-type=access-bandwidth,bandwidth=10485760" + " -numa hmat-lb,initiator=1,target=2,hierarchy=memory," + "data-type=access-latency,latency=30" + " -numa hmat-lb,initiator=1,target=2,hierarchy=memory," + "data-type=access-bandwidth,bandwidth=1048576", + &data); + free_test_data(&data); +} + #ifdef CONFIG_POSIX static void test_acpi_erst(const char *machine) { @@ -1824,6 +1872,8 @@ int main(int argc, char *argv[]) qtest_add_func("acpi/q35/nohpet", test_acpi_q35_tcg_nohpet); qtest_add_func("acpi/q35/dimmpxm", test_acpi_q35_tcg_dimm_pxm); qtest_add_func("acpi/q35/acpihmat", test_acpi_q35_tcg_acpi_hmat); + qtest_add_func("acpi/q35/acpihmat-noinitiator", + test_acpi_q35_tcg_acpi_hmat_noinitiator); #ifdef CONFIG_POSIX qtest_add_func("acpi/q35/acpierst", test_acpi_q35_acpi_erst); #endif From 84c35b5ff24fa054fe06396ea8690ba5030bac69 Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Thu, 27 Oct 2022 11:00:33 +0100 Subject: [PATCH 646/705] tests: acpi: q35: update expected blobs *.hmat-noinitiators expected HMAT: [000h 0000 4] Signature : "HMAT" [Heterogeneous Memory Attributes Table] [004h 0004 4] Table Length : 00000120 [008h 0008 1] Revision : 02 [009h 0009 1] Checksum : 4F [00Ah 0010 6] Oem ID : "BOCHS " [010h 0016 8] Oem Table ID : "BXPC " [018h 0024 4] Oem Revision : 00000001 [01Ch 0028 4] Asl Compiler ID : "BXPC" [020h 0032 4] Asl Compiler Revision : 00000001 [024h 0036 4] Reserved : 00000000 [028h 0040 2] Structure Type : 0000 [Memory Proximity Domain Attributes] [02Ah 0042 2] Reserved : 0000 [02Ch 0044 4] Length : 00000028 [030h 0048 2] Flags (decoded below) : 0001 Processor Proximity Domain Valid : 1 [032h 0050 2] Reserved1 : 0000 [034h 0052 4] Attached Initiator Proximity Domain : 00000000 [038h 0056 4] Memory Proximity Domain : 00000000 [03Ch 0060 4] Reserved2 : 00000000 [040h 0064 8] Reserved3 : 0000000000000000 [048h 0072 8] Reserved4 : 0000000000000000 [050h 0080 2] Structure Type : 0000 [Memory Proximity Domain Attributes] [052h 0082 2] Reserved : 0000 [054h 0084 4] Length : 00000028 [058h 0088 2] Flags (decoded below) : 0001 Processor Proximity Domain Valid : 1 [05Ah 0090 2] Reserved1 : 0000 [05Ch 0092 4] Attached Initiator Proximity Domain : 00000001 [060h 0096 4] Memory Proximity Domain : 00000001 [064h 0100 4] Reserved2 : 00000000 [068h 0104 8] Reserved3 : 0000000000000000 [070h 0112 8] Reserved4 : 0000000000000000 [078h 0120 2] Structure Type : 0000 [Memory Proximity Domain Attributes] [07Ah 0122 2] Reserved : 0000 [07Ch 0124 4] Length : 00000028 [080h 0128 2] Flags (decoded below) : 0000 Processor Proximity Domain Valid : 0 [082h 0130 2] Reserved1 : 0000 [084h 0132 4] Attached Initiator Proximity Domain : 00000080 [088h 0136 4] Memory Proximity Domain : 00000002 [08Ch 0140 4] Reserved2 : 00000000 [090h 0144 8] Reserved3 : 0000000000000000 [098h 0152 8] Reserved4 : 0000000000000000 [0A0h 0160 2] Structure Type : 0001 [System Locality Latency and Bandwidth Information] [0A2h 0162 2] Reserved : 0000 [0A4h 0164 4] Length : 00000040 [0A8h 0168 1] Flags (decoded below) : 00 Memory Hierarchy : 0 [0A9h 0169 1] Data Type : 00 [0AAh 0170 2] Reserved1 : 0000 [0ACh 0172 4] Initiator Proximity Domains # : 00000002 [0B0h 0176 4] Target Proximity Domains # : 00000003 [0B4h 0180 4] Reserved2 : 00000000 [0B8h 0184 8] Entry Base Unit : 0000000000002710 [0C0h 0192 4] Initiator Proximity Domain List : 00000000 [0C4h 0196 4] Initiator Proximity Domain List : 00000001 [0C8h 0200 4] Target Proximity Domain List : 00000000 [0CCh 0204 4] Target Proximity Domain List : 00000001 [0D0h 0208 4] Target Proximity Domain List : 00000002 [0D4h 0212 2] Entry : 0001 [0D6h 0214 2] Entry : 0002 [0D8h 0216 2] Entry : 0003 [0DAh 0218 2] Entry : 0002 [0DCh 0220 2] Entry : 0001 [0DEh 0222 2] Entry : 0003 [0E0h 0224 2] Structure Type : 0001 [System Locality Latency and Bandwidth Information] [0E2h 0226 2] Reserved : 0000 [0E4h 0228 4] Length : 00000040 [0E8h 0232 1] Flags (decoded below) : 00 Memory Hierarchy : 0 [0E9h 0233 1] Data Type : 03 [0EAh 0234 2] Reserved1 : 0000 [0ECh 0236 4] Initiator Proximity Domains # : 00000002 [0F0h 0240 4] Target Proximity Domains # : 00000003 [0F4h 0244 4] Reserved2 : 00000000 [0F8h 0248 8] Entry Base Unit : 0000000000000001 [100h 0256 4] Initiator Proximity Domain List : 00000000 [104h 0260 4] Initiator Proximity Domain List : 00000001 [108h 0264 4] Target Proximity Domain List : 00000000 [10Ch 0268 4] Target Proximity Domain List : 00000001 [110h 0272 4] Target Proximity Domain List : 00000002 [114h 0276 2] Entry : 000A [116h 0278 2] Entry : 0005 [118h 0280 2] Entry : 0001 [11Ah 0282 2] Entry : 0005 [11Ch 0284 2] Entry : 000A [11Eh 0286 2] Entry : 0001 Raw Table Data: Length 288 (0x120) 0000: 48 4D 41 54 20 01 00 00 02 4F 42 4F 43 48 53 20 // HMAT ....OBOCHS 0010: 42 58 50 43 20 20 20 20 01 00 00 00 42 58 50 43 // BXPC ....BXPC 0020: 01 00 00 00 00 00 00 00 00 00 00 00 28 00 00 00 // ............(... 0030: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................ 0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................ 0050: 00 00 00 00 28 00 00 00 01 00 00 00 01 00 00 00 // ....(........... 0060: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................ 0070: 00 00 00 00 00 00 00 00 00 00 00 00 28 00 00 00 // ............(... 0080: 00 00 00 00 80 00 00 00 02 00 00 00 00 00 00 00 // ................ 0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................ 00A0: 01 00 00 00 40 00 00 00 00 00 00 00 02 00 00 00 // ....@........... 00B0: 03 00 00 00 00 00 00 00 10 27 00 00 00 00 00 00 // .........'...... 00C0: 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 // ................ 00D0: 02 00 00 00 01 00 02 00 03 00 02 00 01 00 03 00 // ................ 00E0: 01 00 00 00 40 00 00 00 00 03 00 00 02 00 00 00 // ....@........... 00F0: 03 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 // ................ 0100: 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 // ................ 0110: 02 00 00 00 0A 00 05 00 01 00 05 00 0A 00 01 00 // ................ Signed-off-by: Brice Goglin Signed-off-by: Hesham Almatary Message-Id: <20221027100037.251-5-hesham.almatary@huawei.com> Tested-by: Yicong Yang Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- tests/data/acpi/q35/APIC.acpihmat-noinitiator | Bin 0 -> 144 bytes tests/data/acpi/q35/DSDT.acpihmat-noinitiator | Bin 0 -> 8691 bytes tests/data/acpi/q35/HMAT.acpihmat-noinitiator | Bin 0 -> 288 bytes tests/data/acpi/q35/SRAT.acpihmat-noinitiator | Bin 0 -> 312 bytes tests/qtest/bios-tables-test-allowed-diff.h | 4 ---- 5 files changed, 4 deletions(-) diff --git a/tests/data/acpi/q35/APIC.acpihmat-noinitiator b/tests/data/acpi/q35/APIC.acpihmat-noinitiator index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..d904d4a70ddecbb79a83a267af8e26f925e9f4c6 100644 GIT binary patch literal 144 zcmZ<^@N}NQz`(%h?d0$55v<@85#X!<1dKp25F11@Fg*ANra6G>KwJ(+MhMNs1fiLk tK{O)|Nb|r~o3y%?)O;u>A)b0RWi;3;_TD literal 0 HcmV?d00001 diff --git a/tests/data/acpi/q35/DSDT.acpihmat-noinitiator b/tests/data/acpi/q35/DSDT.acpihmat-noinitiator index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..8efa1c5ded52b8a9dfbb6945a3c75cdc6ef9b277 100644 GIT binary patch literal 8691 zcmb7KOKcm*8J^)wtL0K!QMBb(EXGODM~Z}!okvkL4Y|vgCDIg0#VKfjq~x@c6CjHu z2I2$;6d6bypPH}^dSn6x=&e2VS_8ebH{TkdryhFAH7Md!)bF3!p=U@6sB~D)H~WA8 zKi@v)+uf1h^4s4%$r!&~xZ+h>*~04$FN;6U7^61*y4Bb<*4gt5D)avH_CbPPmRi9@MdTKWxtvC#28bJdL!rMRxmEF*;-h(&waAQm_rAL{{DP;c=%V@WbQ5I zu4kSjnIy5Z*YH|xo_yfgR_7y^fQSCgEH-|&v)3wK#zFnNW5;k*33!EE@iKN4>a`|M zK9n>9UZK8O%QmY1>)8%3tb1!L^Gw4lUXFC0B6N5d>`+8-i|;bZ(fJW|AF#}`d2psh zQLcbCy)d?yDa|) zjz?GuWyTT&TQbUORJ{_*I9>emV26;q{~D*`>w4dctEkazH_~hG?xmBlBxGp0^JU8iN}v<#h=sS{AwIcw;gHFVCJIstW^wxQED zblRp)KwW3j(3v!JCQY4yx=zQ?=@>d4QzxLVGiB&Z89Gy@PC#AfoS}2h&^c%71k`oT z8#?C=o%5znKwYP6=yVO8uBj7H*STQmTrhMlm^uMp*9GEhK_NW{WGWo(E-jeYYN2GHfXWrgKmnCb7^sXDOc8c=P(XD)VW2WrFkzrtC>f{>6-+WvK&2A~Dq{r`2C9XUfyz+9 zBm)IhI$@wPRxn|pS|}N)3>8c=P(Y;<1}b9(69%ef{>6-+WvK&2A~Dq{r`2C9XUfyz+9Bm)IhI$@wP zRxn|pS|}N)3>8c=P(Y;<1}b9(69%eofdc6U3aA?>pk|;N69%d=$v`zG8K}mDfoe<`sKz7%)tF?U8WRSpF=3z@ zlMGa2l7VVW7^udCfoe=LP>o3jsxe`pK}hNGz0Y zEu6F$Kb>Q)3thk3Vz;Sn?}?sy`k+A(UQ^(u zZmZei_jbZDP#o&8UsNIenqr9h; z_e6Pbth{$bc`q#QkBPVOt?K_i_P$o$7v=r2^8OL!{jhv-ynO5!<%?SRq9|V+D_=aK zd@(Fv8ZRF|M){Ifz9h<*#>$tDC|?T8m&eN|j#0j>l`o6(<+1YRBg&V<@|E%OGsh@j z(aKju`N~-N$`R!&C?BKgXuP~D%d5!)j|RBi<;O|0FOv|rJbviD4%3a_#`c1l4$lh{ z>15y3bQAYw+DwOsh>3KvZ)&=U`)tunhbN1Pbh2-1x{3QHW2VF7#zZ>VH#ObFeQ?4| zhi8z9bh2-1x{2%hq?ry6CKKso-_&#y*Xfd(4o@o+>13ao&aGMULw(VzG>UC?`Eg8n z^kKfUS823s3{Tz^Cm-#o&Hx74hK^>-be6#jpNIEjy5IEqMldt z@pV54%66367k4w21XdREvz@1|Js;DL1!<(Ef$?sPCt$td znZfuDQW@CuSQ41nv%YrF%hcke{CI`9xGNb%YGds~4}PBZmRo4*2!2 zis`|19NlJ$`@NjzL+lJzi5N9`D478!p`+@5QOx{(3k&=-Y>=^K~$7 z|M2OFLr2#}uzi;X*=INV7}l3B4PTfD6ITyT@wOceCXNhtf_HP97SW0^xr#;!x7apa z7TYM$S(z?wA{WMUb8Gr>uFZN^T5acu<2?OxnaGcW7wk?sHh~=(@1@WiZKl!h8{mh*&-2<%^790Bk*`NHanv7 z@y;EQ?;;j}#`9rv9p#H+=}m}NqqC!WzUU}l<}BtE%#Ph+Zk2@-A5bI zWMXc;oV5RPH^m~Dy76~N8(!v*oJS6~(9az)uJ5t?ku$<6tg12gomlgfHZB&R7ibSDaewjnG<5c#D_!;EQ$%W`Slh&vzDm(! zBX;9%oXp70KY5KNbhk=N#&``(wsN_yTqW=9|Fo5RSpu9f&hTi{TJaecebHD|jf>Ri z?7w=pReBt}Og2|-Zba-Jxm=FgoL=?tTDno7jYk{bVsP}0BDG7jDbuE6C9uths?Z`> z7{LNTZv;Jp{s{U6Lnovb!P01NiC}pI%LFSUhzH_JYXu*Y<$n%DanI0^3!fZL*(b`p z$9jz8qQ1_qDTsu$Ku56B2^LV1vSe6~XK)NR@ ze?R(u)Uqz@iOj3smD-3CNAz^gqv)e3vo5%T^GvhtjYgA19eV5$sRI@;Ze3uUhBMzP r6~eO{Wy>s+Xn6HDbALtmd*5h`F{Xf2gTDAYef7HO|cqz literal 0 HcmV?d00001 diff --git a/tests/data/acpi/q35/HMAT.acpihmat-noinitiator b/tests/data/acpi/q35/HMAT.acpihmat-noinitiator index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..6494d11b9fff54f8c403ec9e4893fdff72bde9c9 100644 GIT binary patch literal 288 zcmaJ)F%Ezr5IZ0&Og@24pP{g@7)*5VIX>Ms;S4dxCU-4Odz5uKq7kt*)m-+N&Mij( zmQa%w6GZ=3|IM0X_Ak#IabYaQ2iTvR&x~t&7@Gj;A7o|>w!;|gr;lRa*AB0!)_xEV I&r86*0dKzu0RR91 literal 0 HcmV?d00001 diff --git a/tests/data/acpi/q35/SRAT.acpihmat-noinitiator b/tests/data/acpi/q35/SRAT.acpihmat-noinitiator index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..a11d3119ab3538d9cf821a4fe0fccb0f1dc96359 100644 GIT binary patch literal 312 zcmWFzatyIxWME)?>E!S15v<@85#X!<1VAAM5F12;FdPVA@EK9%8JW=d%*cF34Y)~A u1{YiayE>qSVDJGh4QBww88zTMCa6LfjpA-b4Y)81R2_^)QwNnLKmh Date: Thu, 27 Oct 2022 11:00:34 +0100 Subject: [PATCH 647/705] tests: Add HMAT AArch64/virt empty table files Signed-off-by: Hesham Almatary Message-Id: <20221027100037.251-6-hesham.almatary@huawei.com> Tested-by: Yicong Yang Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- tests/data/acpi/virt/APIC.acpihmatvirt | 0 tests/data/acpi/virt/DSDT.acpihmatvirt | 0 tests/data/acpi/virt/HMAT.acpihmatvirt | 0 tests/data/acpi/virt/PPTT.acpihmatvirt | 0 tests/data/acpi/virt/SRAT.acpihmatvirt | 0 tests/qtest/bios-tables-test-allowed-diff.h | 5 +++++ 6 files changed, 5 insertions(+) create mode 100644 tests/data/acpi/virt/APIC.acpihmatvirt create mode 100644 tests/data/acpi/virt/DSDT.acpihmatvirt create mode 100644 tests/data/acpi/virt/HMAT.acpihmatvirt create mode 100644 tests/data/acpi/virt/PPTT.acpihmatvirt create mode 100644 tests/data/acpi/virt/SRAT.acpihmatvirt diff --git a/tests/data/acpi/virt/APIC.acpihmatvirt b/tests/data/acpi/virt/APIC.acpihmatvirt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/data/acpi/virt/DSDT.acpihmatvirt b/tests/data/acpi/virt/DSDT.acpihmatvirt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/data/acpi/virt/HMAT.acpihmatvirt b/tests/data/acpi/virt/HMAT.acpihmatvirt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/data/acpi/virt/PPTT.acpihmatvirt b/tests/data/acpi/virt/PPTT.acpihmatvirt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/data/acpi/virt/SRAT.acpihmatvirt b/tests/data/acpi/virt/SRAT.acpihmatvirt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h index dfb8523c8b..4f849715bd 100644 --- a/tests/qtest/bios-tables-test-allowed-diff.h +++ b/tests/qtest/bios-tables-test-allowed-diff.h @@ -1 +1,6 @@ /* List of comma-separated changed AML files to ignore */ +"tests/data/acpi/virt/APIC.acpihmatvirt", +"tests/data/acpi/virt/DSDT.acpihmatvirt", +"tests/data/acpi/virt/HMAT.acpihmatvirt", +"tests/data/acpi/virt/PPTT.acpihmatvirt", +"tests/data/acpi/virt/SRAT.acpihmatvirt", From 7cbd3fd3d21239d632f0ac8ef6d08c6608d534d8 Mon Sep 17 00:00:00 2001 From: Xiang Chen Date: Thu, 27 Oct 2022 11:00:35 +0100 Subject: [PATCH 648/705] hw/arm/virt: Enable HMAT on arm virt machine Since the patchset ("Build ACPI Heterogeneous Memory Attribute Table (HMAT)"), HMAT is supported, but only x86 is enabled. Enable HMAT on arm virt machine. Signed-off-by: Xiang Chen Signed-off-by: Hesham Almatary Reviewed-by: Igor Mammedov Message-Id: <20221027100037.251-7-hesham.almatary@huawei.com> Tested-by: Yicong Yang Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/arm/Kconfig | 1 + hw/arm/virt-acpi-build.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index 15fa79afd3..17fcde8e1c 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -30,6 +30,7 @@ config ARM_VIRT select ACPI_VIOT select VIRTIO_MEM_SUPPORTED select ACPI_CXL + select ACPI_HMAT config CHEETAH bool diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index da9e41e72b..4156111d49 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -42,6 +42,7 @@ #include "hw/acpi/memory_hotplug.h" #include "hw/acpi/generic_event_device.h" #include "hw/acpi/tpm.h" +#include "hw/acpi/hmat.h" #include "hw/pci/pcie_host.h" #include "hw/pci/pci.h" #include "hw/pci/pci_bus.h" @@ -987,6 +988,12 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables) build_slit(tables_blob, tables->linker, ms, vms->oem_id, vms->oem_table_id); } + + if (ms->numa_state->hmat_enabled) { + acpi_add_table(table_offsets, tables_blob); + build_hmat(tables_blob, tables->linker, ms->numa_state, + vms->oem_id, vms->oem_table_id); + } } if (ms->nvdimms_state->is_enabled) { From b077b070aeefceed4c84490206e39114bf7c9bb3 Mon Sep 17 00:00:00 2001 From: Hesham Almatary Date: Thu, 27 Oct 2022 11:00:36 +0100 Subject: [PATCH 649/705] tests: acpi: aarch64/virt: add a test for hmat nodes with no initiators This patch imitates the "tests: acpi: q35: add test for hmat nodes without initiators" commit to test numa nodes with different HMAT attributes, but on AArch64/virt. Tested with: qemu-system-aarch64 -accel tcg \ -machine virt,hmat=on,gic-version=3 -cpu cortex-a57 \ -bios qemu-efi-aarch64/QEMU_EFI.fd \ -kernel Image -append "root=/dev/vda2 console=ttyAMA0" \ -drive if=virtio,file=aarch64.qcow2,format=qcow2,id=hd \ -device virtio-rng-pci \ -net user,hostfwd=tcp::10022-:22 -net nic \ -device intel-hda -device hda-duplex -nographic \ -smp 4 \ -m 3G \ -object memory-backend-ram,size=1G,id=ram0 \ -object memory-backend-ram,size=1G,id=ram1 \ -object memory-backend-ram,size=1G,id=ram2 \ -numa node,nodeid=0,memdev=ram0,cpus=0-1 \ -numa node,nodeid=1,memdev=ram1,cpus=2-3 \ -numa node,nodeid=2,memdev=ram2 \ -numa hmat-lb,initiator=0,target=0,hierarchy=memory,data-type=access-latency,latency=10 \ -numa hmat-lb,initiator=0,target=0,hierarchy=memory,data-type=access-bandwidth,bandwidth=10485760 \ -numa hmat-lb,initiator=0,target=1,hierarchy=memory,data-type=access-latency,latency=20 \ -numa hmat-lb,initiator=0,target=1,hierarchy=memory,data-type=access-bandwidth,bandwidth=5242880 \ -numa hmat-lb,initiator=0,target=2,hierarchy=memory,data-type=access-latency,latency=30 \ -numa hmat-lb,initiator=0,target=2,hierarchy=memory,data-type=access-bandwidth,bandwidth=1048576 \ -numa hmat-lb,initiator=1,target=0,hierarchy=memory,data-type=access-latency,latency=20 \ -numa hmat-lb,initiator=1,target=0,hierarchy=memory,data-type=access-bandwidth,bandwidth=5242880 \ -numa hmat-lb,initiator=1,target=1,hierarchy=memory,data-type=access-latency,latency=10 \ -numa hmat-lb,initiator=1,target=1,hierarchy=memory,data-type=access-bandwidth,bandwidth=10485760 \ -numa hmat-lb,initiator=1,target=2,hierarchy=memory,data-type=access-latency,latency=30 \ -numa hmat-lb,initiator=1,target=2,hierarchy=memory,data-type=access-bandwidth,bandwidth=1048576 Signed-off-by: Hesham Almatary Message-Id: <20221027100037.251-8-hesham.almatary@huawei.com> Tested-by: Yicong Yang Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- tests/qtest/bios-tables-test.c | 59 ++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c index 02fe59fbf8..e805b3efec 100644 --- a/tests/qtest/bios-tables-test.c +++ b/tests/qtest/bios-tables-test.c @@ -1461,6 +1461,63 @@ static void test_acpi_piix4_tcg_acpi_hmat(void) test_acpi_tcg_acpi_hmat(MACHINE_PC); } +static void test_acpi_virt_tcg_acpi_hmat(void) +{ + test_data data = { + .machine = "virt", + .tcg_only = true, + .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", + .uefi_fl2 = "pc-bios/edk2-arm-vars.fd", + .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2", + .ram_start = 0x40000000ULL, + .scan_len = 128ULL * 1024 * 1024, + }; + + data.variant = ".acpihmatvirt"; + + test_acpi_one(" -machine hmat=on" + " -cpu cortex-a57" + " -smp 4,sockets=2" + " -m 256M" + " -object memory-backend-ram,size=64M,id=ram0" + " -object memory-backend-ram,size=64M,id=ram1" + " -object memory-backend-ram,size=128M,id=ram2" + " -numa node,nodeid=0,memdev=ram0" + " -numa node,nodeid=1,memdev=ram1" + " -numa node,nodeid=2,memdev=ram2" + " -numa cpu,node-id=0,socket-id=0" + " -numa cpu,node-id=0,socket-id=0" + " -numa cpu,node-id=1,socket-id=1" + " -numa cpu,node-id=1,socket-id=1" + " -numa hmat-lb,initiator=0,target=0,hierarchy=memory," + "data-type=access-latency,latency=10" + " -numa hmat-lb,initiator=0,target=0,hierarchy=memory," + "data-type=access-bandwidth,bandwidth=10485760" + " -numa hmat-lb,initiator=0,target=1,hierarchy=memory," + "data-type=access-latency,latency=20" + " -numa hmat-lb,initiator=0,target=1,hierarchy=memory," + "data-type=access-bandwidth,bandwidth=5242880" + " -numa hmat-lb,initiator=0,target=2,hierarchy=memory," + "data-type=access-latency,latency=30" + " -numa hmat-lb,initiator=0,target=2,hierarchy=memory," + "data-type=access-bandwidth,bandwidth=1048576" + " -numa hmat-lb,initiator=1,target=0,hierarchy=memory," + "data-type=access-latency,latency=20" + " -numa hmat-lb,initiator=1,target=0,hierarchy=memory," + "data-type=access-bandwidth,bandwidth=5242880" + " -numa hmat-lb,initiator=1,target=1,hierarchy=memory," + "data-type=access-latency,latency=10" + " -numa hmat-lb,initiator=1,target=1,hierarchy=memory," + "data-type=access-bandwidth,bandwidth=10485760" + " -numa hmat-lb,initiator=1,target=2,hierarchy=memory," + "data-type=access-latency,latency=30" + " -numa hmat-lb,initiator=1,target=2,hierarchy=memory," + "data-type=access-bandwidth,bandwidth=1048576", + &data); + + free_test_data(&data); +} + static void test_acpi_q35_tcg_acpi_hmat_noinitiator(void) { test_data data; @@ -1914,6 +1971,8 @@ int main(int argc, char *argv[]) } else if (strcmp(arch, "aarch64") == 0) { if (has_tcg) { qtest_add_func("acpi/virt", test_acpi_virt_tcg); + qtest_add_func("acpi/virt/acpihmatvirt", + test_acpi_virt_tcg_acpi_hmat); qtest_add_func("acpi/virt/numamem", test_acpi_virt_tcg_numamem); qtest_add_func("acpi/virt/memhp", test_acpi_virt_tcg_memhp); qtest_add_func("acpi/virt/pxb", test_acpi_virt_tcg_pxb); From be3afe8151e8db8dba02cad9d846aaad908bd711 Mon Sep 17 00:00:00 2001 From: Hesham Almatary Date: Thu, 27 Oct 2022 11:00:37 +0100 Subject: [PATCH 650/705] tests: virt: Update expected *.acpihmatvirt tables * Expected ACPI Data Table [HMAT] [000h 0000 4] Signature : "HMAT" [Heterogeneous Memory Attributes Table] [004h 0004 4] Table Length : 00000120 [008h 0008 1] Revision : 02 [009h 0009 1] Checksum : 4F [00Ah 0010 6] Oem ID : "BOCHS " [010h 0016 8] Oem Table ID : "BXPC " [018h 0024 4] Oem Revision : 00000001 [01Ch 0028 4] Asl Compiler ID : "BXPC" [020h 0032 4] Asl Compiler Revision : 00000001 [024h 0036 4] Reserved : 00000000 [028h 0040 2] Structure Type : 0000 [Memory Proximity Domain Attributes] [02Ah 0042 2] Reserved : 0000 [02Ch 0044 4] Length : 00000028 [030h 0048 2] Flags (decoded below) : 0001 Processor Proximity Domain Valid : 1 [032h 0050 2] Reserved1 : 0000 [034h 0052 4] Processor Proximity Domain : 00000000 [038h 0056 4] Memory Proximity Domain : 00000000 [03Ch 0060 4] Reserved2 : 00000000 [040h 0064 8] Reserved3 : 0000000000000000 [048h 0072 8] Reserved4 : 0000000000000000 [050h 0080 2] Structure Type : 0000 [Memory Proximity Domain Attributes] [052h 0082 2] Reserved : 0000 [054h 0084 4] Length : 00000028 [058h 0088 2] Flags (decoded below) : 0001 Processor Proximity Domain Valid : 1 [05Ah 0090 2] Reserved1 : 0000 [05Ch 0092 4] Processor Proximity Domain : 00000001 [060h 0096 4] Memory Proximity Domain : 00000001 [064h 0100 4] Reserved2 : 00000000 [068h 0104 8] Reserved3 : 0000000000000000 [070h 0112 8] Reserved4 : 0000000000000000 [078h 0120 2] Structure Type : 0000 [Memory Proximity Domain Attributes] [07Ah 0122 2] Reserved : 0000 [07Ch 0124 4] Length : 00000028 [080h 0128 2] Flags (decoded below) : 0000 Processor Proximity Domain Valid : 0 [082h 0130 2] Reserved1 : 0000 [084h 0132 4] Processor Proximity Domain : 00000080 [088h 0136 4] Memory Proximity Domain : 00000002 [08Ch 0140 4] Reserved2 : 00000000 [040h 0064 8] Reserved3 : 0000000000000000 [048h 0072 8] Reserved4 : 0000000000000000 [050h 0080 2] Structure Type : 0000 [Memory Proximity Domain Attributes] [052h 0082 2] Reserved : 0000 [054h 0084 4] Length : 00000028 [058h 0088 2] Flags (decoded below) : 0001 Processor Proximity Domain Valid : 1 [05Ah 0090 2] Reserved1 : 0000 [05Ch 0092 4] Processor Proximity Domain : 00000001 [060h 0096 4] Memory Proximity Domain : 00000001 [064h 0100 4] Reserved2 : 00000000 [068h 0104 8] Reserved3 : 0000000000000000 [070h 0112 8] Reserved4 : 0000000000000000 [078h 0120 2] Structure Type : 0000 [Memory Proximity Domain Attributes] [07Ah 0122 2] Reserved : 0000 [07Ch 0124 4] Length : 00000028 [080h 0128 2] Flags (decoded below) : 0000 Processor Proximity Domain Valid : 0 [082h 0130 2] Reserved1 : 0000 [084h 0132 4] Processor Proximity Domain : 00000080 [088h 0136 4] Memory Proximity Domain : 00000002 [08Ch 0140 4] Reserved2 : 00000000 [090h 0144 8] Reserved3 : 0000000000000000 [098h 0152 8] Reserved4 : 0000000000000000 [0A0h 0160 2] Structure Type : 0001 [System Locality Latency and Bandwidth Information] [0A2h 0162 2] Reserved : 0000 [0A4h 0164 4] Length : 00000040 [0A8h 0168 1] Flags (decoded below) : 00 Memory Hierarchy : 0 [0A9h 0169 1] Data Type : 00 [0AAh 0170 2] Reserved1 : 0000 [0ACh 0172 4] Initiator Proximity Domains # : 00000002 [0B0h 0176 4] Target Proximity Domains # : 00000003 [0B4h 0180 4] Reserved2 : 00000000 [0B8h 0184 8] Entry Base Unit : 0000000000002710 [0C0h 0192 4] Initiator Proximity Domain List : 00000000 [0C4h 0196 4] Initiator Proximity Domain List : 00000001 [0C8h 0200 4] Target Proximity Domain List : 00000000 [0CCh 0204 4] Target Proximity Domain List : 00000001 [0D0h 0208 4] Target Proximity Domain List : 00000002 [0D4h 0212 2] Entry : 0001 [0D6h 0214 2] Entry : 0002 [0D8h 0216 2] Entry : 0003 [0DAh 0218 2] Entry : 0002 [0DCh 0220 2] Entry : 0001 [0DEh 0222 2] Entry : 0003 [0E0h 0224 2] Structure Type : 0001 [System Locality Latency and Bandwidth Information] [0E2h 0226 2] Reserved : 0000 [0E4h 0228 4] Length : 00000040 [0E8h 0232 1] Flags (decoded below) : 00 Memory Hierarchy : 0 [0E9h 0233 1] Data Type : 03 [0EAh 0234 2] Reserved1 : 0000 [0ECh 0236 4] Initiator Proximity Domains # : 00000002 [0F0h 0240 4] Target Proximity Domains # : 00000003 [0F4h 0244 4] Reserved2 : 00000000 [0F8h 0248 8] Entry Base Unit : 0000000000000001 [100h 0256 4] Initiator Proximity Domain List : 00000000 [104h 0260 4] Initiator Proximity Domain List : 00000001 [108h 0264 4] Target Proximity Domain List : 00000000 [10Ch 0268 4] Target Proximity Domain List : 00000001 [110h 0272 4] Target Proximity Domain List : 00000002 [114h 0276 2] Entry : 000A [116h 0278 2] Entry : 0005 [118h 0280 2] Entry : 0001 [11Ah 0282 2] Entry : 0005 [11Ch 0284 2] Entry : 000A [11Eh 0286 2] Entry : 0001 Raw Table Data: Length 288 (0x120) 0000: 48 4D 41 54 20 01 00 00 02 4F 42 4F 43 48 53 20 // HMAT ....OBOCHS 0010: 42 58 50 43 20 20 20 20 01 00 00 00 42 58 50 43 // BXPC ....BXPC 0020: 01 00 00 00 00 00 00 00 00 00 00 00 28 00 00 00 // ............(... 0030: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................ 0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................ 0050: 00 00 00 00 28 00 00 00 01 00 00 00 01 00 00 00 // ....(........... 0060: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................ 0070: 00 00 00 00 00 00 00 00 00 00 00 00 28 00 00 00 // ............(... 0080: 00 00 00 00 80 00 00 00 02 00 00 00 00 00 00 00 // ................ 0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................ 00A0: 01 00 00 00 40 00 00 00 00 00 00 00 02 00 00 00 // ....@........... 00B0: 03 00 00 00 00 00 00 00 10 27 00 00 00 00 00 00 // .........'...... 00C0: 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 // ................ 00D0: 02 00 00 00 01 00 02 00 03 00 02 00 01 00 03 00 // ................ 00E0: 01 00 00 00 40 00 00 00 00 03 00 00 02 00 00 00 // ....@........... 00F0: 03 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 // ................ 0100: 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 // ................ 0110: 02 00 00 00 0A 00 05 00 01 00 05 00 0A 00 01 00 // ................ Signed-off-by: Hesham Almatary Message-Id: <20221027100037.251-9-hesham.almatary@huawei.com> Tested-by: Yicong Yang Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- tests/data/acpi/virt/APIC.acpihmatvirt | Bin 0 -> 412 bytes tests/data/acpi/virt/DSDT.acpihmatvirt | Bin 0 -> 5282 bytes tests/data/acpi/virt/HMAT.acpihmatvirt | Bin 0 -> 288 bytes tests/data/acpi/virt/PPTT.acpihmatvirt | Bin 0 -> 196 bytes tests/data/acpi/virt/SRAT.acpihmatvirt | Bin 0 -> 240 bytes tests/qtest/bios-tables-test-allowed-diff.h | 5 ----- 6 files changed, 5 deletions(-) diff --git a/tests/data/acpi/virt/APIC.acpihmatvirt b/tests/data/acpi/virt/APIC.acpihmatvirt index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..68200204c6f8f2706c9896dbbccc5ecbec130d26 100644 GIT binary patch literal 412 zcmbVIK?;B{46AboK|SknPton7CkI~qlV9+$HnL1S&Om7znov5&HC&a5J^dDz-T5O1 zr%*}2(TQ#(lZMPFX(J~Q?hmh|tV;Vf^*Z}MYiU3pa#)Z{^LPim$itl|>ZN(`63DA{ TK>f{wm+13f&GQ#zP7>t?q5KK~ literal 0 HcmV?d00001 diff --git a/tests/data/acpi/virt/DSDT.acpihmatvirt b/tests/data/acpi/virt/DSDT.acpihmatvirt index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..aee6ba017cd730948bfa93e91551eb10a6809293 100644 GIT binary patch literal 5282 zcmZvg%WoT16o>EFlh__VVmr?J;S@^6vl`n?la{u`9y^IkoET5iAUTpNArK{-N>oUt zLJCD*Gs*9?XQYhh%)RHE`;Cv|<7xWM-JeTJ z#SR)f-lo6Q_^|6O(Pk;7^s#=;f4^ZJ4E)BRe?05CuA3Zewwu|y*KJdS;>pWu{bKsqaRW zWnH4^F|BBIecxL*;161zJz8y*a{b-9lcr>^ZW%u zu9+M80>hRVNnl(<#0#5|#QSFy2LmT&Edn9n-+Lg$%h)vl3$# z7`Krj*J(~-%md>NGUPfPlNgJ@cn=wJo#rLR5-`?~A=ha^V!Q&3Ix^%sElP~bz-S;t zuG4XeaRnG2FsgE$mL$gOz-S^vuG0yL@g^`@$dK!FQewOfjCEwlbvh+6t^#8N8FHOY zOAHqno5+ysbVg!Sfzd{WT&J@V;~FsTB15jzIf-!{81ExPuG4vmu?mbWWXN^8ATe$N zqXUeZT&If?;}$Tsks;Sw=DW&MZS}EQQZD^9>F5jfKz&57N<)IiqubjZ-}>A+DyHr9aHux?wyVss zMaLCY%;@t@jDl(u#3`t$V%E+KhnCVgG%t*F7ER2Vu^^A8Mxo9melVB1Br`XRbY?V_ zS|EKzni^zMs57Ih#DmOe1#zV_qp5L|NmGMN3Uwx}D7cCpWJW8ngUo0uwM?O9kVzqW zjxf)WAT#nDF`3cgDMZgv=1EN{ttXmFEf#uGh@J`NnP8p??nxnfCYfiFc~VP;o)n^I zig{8yZSG!hOH$mELiBW)r^7s{g+osY(KF3F)66r?Jt;)b4D-w|PipzllS1^&GS4jY z%yLf((KE+9bIg-kMD(N(J;#{m81o$Co)n@d{hTp19#nCjc~VP>o)n^Ifq52~XMuZC zh@M5}S!ABnf}$sd=sC_j$C>9i_oNU#>E|bSmY65CtmsK0dQLFU3FbM$Jt;)bN#;4p zJgLP+PYTgx#fK=R#H~KkyoLbw>X~ zRep_j=5}l*oJZegRgC_f(>ByQ>l^xXWvIIdw)}ATpZ-}!+wdxlSQ+X8%tlQMZ9^Kh z)U&rBCm24`V|ojsi=96ISS9_vZdWC}-QJcet)~V%zGpu>R9kxA31(ML zC!e20^UUeI9(<@L>+@%aKjqAMeUZx9VdT?A)L9{JS$angx;l2R<+Ezk54v>C)g1Sw`xCqeba%>Y7q>PzVzO{N^X|8-i2UdwN7EtM7qt$Vwv hhdQ`_nm>7R-_iZv)9!w+;T-jkXY>Jno;-6c^*?7DCOrTE literal 0 HcmV?d00001 diff --git a/tests/data/acpi/virt/HMAT.acpihmatvirt b/tests/data/acpi/virt/HMAT.acpihmatvirt index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..6494d11b9fff54f8c403ec9e4893fdff72bde9c9 100644 GIT binary patch literal 288 zcmaJ)F%Ezr5IZ0&Og@24pP{g@7)*5VIX>Ms;S4dxCU-4Odz5uKq7kt*)m-+N&Mij( zmQa%w6GZ=3|IM0X_Ak#IabYaQ2iTvR&x~t&7@Gj;A7o|>w!;|gr;lRa*AB0!)_xEV I&r86*0dKzu0RR91 literal 0 HcmV?d00001 diff --git a/tests/data/acpi/virt/PPTT.acpihmatvirt b/tests/data/acpi/virt/PPTT.acpihmatvirt index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..710dba5e793cf36df94087666db58af5f8d03684 100644 GIT binary patch literal 196 zcmWFt2njjDz`(#X&&l7}BUr&HBEVSz2pEB4AU23*5Mf{d(;zks0L4H+1wuhcpcogB gWr0HsZU&Nh$YLOEC0O)!0L7SK;!rz4V$4u60KkX}0RR91 literal 0 HcmV?d00001 diff --git a/tests/data/acpi/virt/SRAT.acpihmatvirt b/tests/data/acpi/virt/SRAT.acpihmatvirt index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..691ef56e34bc84509270db316d908f5979c209bb 100644 GIT binary patch literal 240 zcmWFzat!&vz`($~%E{l^BUr&HBEVSz2pEB4AU22wVHjW*g0Wzt5D{c`%t9a@6A&ZR rfLP2(B8(b94g@$rX%;9A*9GD;YQW53aKWz*WFHuKKxqyrjba`E3*rd@ literal 0 HcmV?d00001 diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h index 4f849715bd..dfb8523c8b 100644 --- a/tests/qtest/bios-tables-test-allowed-diff.h +++ b/tests/qtest/bios-tables-test-allowed-diff.h @@ -1,6 +1 @@ /* List of comma-separated changed AML files to ignore */ -"tests/data/acpi/virt/APIC.acpihmatvirt", -"tests/data/acpi/virt/DSDT.acpihmatvirt", -"tests/data/acpi/virt/HMAT.acpihmatvirt", -"tests/data/acpi/virt/PPTT.acpihmatvirt", -"tests/data/acpi/virt/SRAT.acpihmatvirt", From baa44bce87fe53ef5c95d39e634b3bace014d235 Mon Sep 17 00:00:00 2001 From: Cindy Lu Date: Mon, 31 Oct 2022 11:10:19 +0800 Subject: [PATCH 651/705] vfio: move implement of vfio_get_xlat_addr() to memory.c - Move the implement vfio_get_xlat_addr to softmmu/memory.c, and change the name to memory_get_xlat_addr(). So we can use this function on other devices, such as vDPA device. - Add a new function vfio_get_xlat_addr in vfio/common.c, and it will check whether the memory is backed by a discard manager. then device can have its own warning. Signed-off-by: Cindy Lu Message-Id: <20221031031020.1405111-2-lulu@redhat.com> Acked-by: Alex Williamson Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/vfio/common.c | 66 +++------------------------------------ include/exec/memory.h | 4 +++ softmmu/memory.c | 72 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 61 deletions(-) diff --git a/hw/vfio/common.c b/hw/vfio/common.c index 6b5d8c0bf6..130e5d1dc7 100644 --- a/hw/vfio/common.c +++ b/hw/vfio/common.c @@ -578,45 +578,11 @@ static bool vfio_listener_skipped_section(MemoryRegionSection *section) static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr, ram_addr_t *ram_addr, bool *read_only) { - MemoryRegion *mr; - hwaddr xlat; - hwaddr len = iotlb->addr_mask + 1; - bool writable = iotlb->perm & IOMMU_WO; - - /* - * The IOMMU TLB entry we have just covers translation through - * this IOMMU to its immediate target. We need to translate - * it the rest of the way through to memory. - */ - mr = address_space_translate(&address_space_memory, - iotlb->translated_addr, - &xlat, &len, writable, - MEMTXATTRS_UNSPECIFIED); - if (!memory_region_is_ram(mr)) { - error_report("iommu map to non memory area %"HWADDR_PRIx"", - xlat); - return false; - } else if (memory_region_has_ram_discard_manager(mr)) { - RamDiscardManager *rdm = memory_region_get_ram_discard_manager(mr); - MemoryRegionSection tmp = { - .mr = mr, - .offset_within_region = xlat, - .size = int128_make64(len), - }; - - /* - * Malicious VMs can map memory into the IOMMU, which is expected - * to remain discarded. vfio will pin all pages, populating memory. - * Disallow that. vmstate priorities make sure any RamDiscardManager - * were already restored before IOMMUs are restored. - */ - if (!ram_discard_manager_is_populated(rdm, &tmp)) { - error_report("iommu map to discarded memory (e.g., unplugged via" - " virtio-mem): %"HWADDR_PRIx"", - iotlb->translated_addr); - return false; - } + bool ret, mr_has_discard_manager; + ret = memory_get_xlat_addr(iotlb, vaddr, ram_addr, read_only, + &mr_has_discard_manager); + if (ret && mr_has_discard_manager) { /* * Malicious VMs might trigger discarding of IOMMU-mapped memory. The * pages will remain pinned inside vfio until unmapped, resulting in a @@ -635,29 +601,7 @@ static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr, " intended via an IOMMU. It's possible to mitigate " " by setting/adjusting RLIMIT_MEMLOCK."); } - - /* - * Translation truncates length to the IOMMU page size, - * check that it did not truncate too much. - */ - if (len & iotlb->addr_mask) { - error_report("iommu has granularity incompatible with target AS"); - return false; - } - - if (vaddr) { - *vaddr = memory_region_get_ram_ptr(mr) + xlat; - } - - if (ram_addr) { - *ram_addr = memory_region_get_ram_addr(mr) + xlat; - } - - if (read_only) { - *read_only = !writable || mr->readonly; - } - - return true; + return ret; } static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb) diff --git a/include/exec/memory.h b/include/exec/memory.h index bfb1de8eea..d1e79c39dc 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -713,6 +713,10 @@ void ram_discard_manager_register_listener(RamDiscardManager *rdm, void ram_discard_manager_unregister_listener(RamDiscardManager *rdm, RamDiscardListener *rdl); +bool memory_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr, + ram_addr_t *ram_addr, bool *read_only, + bool *mr_has_discard_manager); + typedef struct CoalescedMemoryRange CoalescedMemoryRange; typedef struct MemoryRegionIoeventfd MemoryRegionIoeventfd; diff --git a/softmmu/memory.c b/softmmu/memory.c index 7ba2048836..bc0be3f62c 100644 --- a/softmmu/memory.c +++ b/softmmu/memory.c @@ -33,6 +33,7 @@ #include "qemu/accel.h" #include "hw/boards.h" #include "migration/vmstate.h" +#include "exec/address-spaces.h" //#define DEBUG_UNASSIGNED @@ -2121,6 +2122,77 @@ void ram_discard_manager_unregister_listener(RamDiscardManager *rdm, rdmc->unregister_listener(rdm, rdl); } +/* Called with rcu_read_lock held. */ +bool memory_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr, + ram_addr_t *ram_addr, bool *read_only, + bool *mr_has_discard_manager) +{ + MemoryRegion *mr; + hwaddr xlat; + hwaddr len = iotlb->addr_mask + 1; + bool writable = iotlb->perm & IOMMU_WO; + + if (mr_has_discard_manager) { + *mr_has_discard_manager = false; + } + /* + * The IOMMU TLB entry we have just covers translation through + * this IOMMU to its immediate target. We need to translate + * it the rest of the way through to memory. + */ + mr = address_space_translate(&address_space_memory, iotlb->translated_addr, + &xlat, &len, writable, MEMTXATTRS_UNSPECIFIED); + if (!memory_region_is_ram(mr)) { + error_report("iommu map to non memory area %" HWADDR_PRIx "", xlat); + return false; + } else if (memory_region_has_ram_discard_manager(mr)) { + RamDiscardManager *rdm = memory_region_get_ram_discard_manager(mr); + MemoryRegionSection tmp = { + .mr = mr, + .offset_within_region = xlat, + .size = int128_make64(len), + }; + if (mr_has_discard_manager) { + *mr_has_discard_manager = true; + } + /* + * Malicious VMs can map memory into the IOMMU, which is expected + * to remain discarded. vfio will pin all pages, populating memory. + * Disallow that. vmstate priorities make sure any RamDiscardManager + * were already restored before IOMMUs are restored. + */ + if (!ram_discard_manager_is_populated(rdm, &tmp)) { + error_report("iommu map to discarded memory (e.g., unplugged via" + " virtio-mem): %" HWADDR_PRIx "", + iotlb->translated_addr); + return false; + } + } + + /* + * Translation truncates length to the IOMMU page size, + * check that it did not truncate too much. + */ + if (len & iotlb->addr_mask) { + error_report("iommu has granularity incompatible with target AS"); + return false; + } + + if (vaddr) { + *vaddr = memory_region_get_ram_ptr(mr) + xlat; + } + + if (ram_addr) { + *ram_addr = memory_region_get_ram_addr(mr) + xlat; + } + + if (read_only) { + *read_only = !writable || mr->readonly; + } + + return true; +} + void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client) { uint8_t mask = 1 << client; From fb1d084b4488aef990b5bafab08ecc20197fd749 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Fri, 28 Oct 2022 14:14:33 +0800 Subject: [PATCH 652/705] intel-iommu: don't warn guest errors when getting rid2pasid entry We use to warn on wrong rid2pasid entry. But this error could be triggered by the guest and could happens during initialization. So let's don't warn in this case. Reviewed-by: Peter Xu Signed-off-by: Jason Wang Message-Id: <20221028061436.30093-2-jasowang@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Yi Liu --- hw/i386/intel_iommu.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 6524c2ee32..271de995be 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -1554,8 +1554,10 @@ static bool vtd_dev_pt_enabled(IntelIOMMUState *s, VTDContextEntry *ce) if (s->root_scalable) { ret = vtd_ce_get_rid2pasid_entry(s, ce, &pe); if (ret) { - error_report_once("%s: vtd_ce_get_rid2pasid_entry error: %"PRId32, - __func__, ret); + /* + * This error is guest triggerable. We should assumt PT + * not enabled for safety. + */ return false; } return (VTD_PE_GET_TYPE(&pe) == VTD_SM_PASID_ENTRY_PT); @@ -1569,14 +1571,12 @@ static bool vtd_as_pt_enabled(VTDAddressSpace *as) { IntelIOMMUState *s; VTDContextEntry ce; - int ret; assert(as); s = as->iommu_state; - ret = vtd_dev_to_context_entry(s, pci_bus_num(as->bus), - as->devfn, &ce); - if (ret) { + if (vtd_dev_to_context_entry(s, pci_bus_num(as->bus), as->devfn, + &ce)) { /* * Possibly failed to parse the context entry for some reason * (e.g., during init, or any guest configuration errors on From da8d439c8048f685e0333ae468b7520b82925e75 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Fri, 28 Oct 2022 14:14:34 +0800 Subject: [PATCH 653/705] intel-iommu: drop VTDBus We introduce VTDBus structure as an intermediate step for searching the address space. This works well with SID based matching/lookup. But when we want to support SID plus PASID based address space lookup, this intermediate steps turns out to be a burden. So the patch simply drops the VTDBus structure and use the PCIBus and devfn as the key for the g_hash_table(). This simplifies the codes and the future PASID extension. To prevent being slower for past vtd_find_as_from_bus_num() callers, a vtd_as cache indexed by the bus number is introduced to store the last recent search result of a vtd_as belongs to a specific bus. Reviewed-by: Peter Xu Signed-off-by: Jason Wang Message-Id: <20221028061436.30093-3-jasowang@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Yi Liu --- hw/i386/intel_iommu.c | 234 +++++++++++++++++----------------- include/hw/i386/intel_iommu.h | 11 +- 2 files changed, 118 insertions(+), 127 deletions(-) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 271de995be..3d426bb326 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -61,6 +61,16 @@ } \ } +/* + * PCI bus number (or SID) is not reliable since the device is usaully + * initalized before guest can configure the PCI bridge + * (SECONDARY_BUS_NUMBER). + */ +struct vtd_as_key { + PCIBus *bus; + uint8_t devfn; +}; + static void vtd_address_space_refresh_all(IntelIOMMUState *s); static void vtd_address_space_unmap(VTDAddressSpace *as, IOMMUNotifier *n); @@ -210,6 +220,27 @@ static guint vtd_uint64_hash(gconstpointer v) return (guint)*(const uint64_t *)v; } +static gboolean vtd_as_equal(gconstpointer v1, gconstpointer v2) +{ + const struct vtd_as_key *key1 = v1; + const struct vtd_as_key *key2 = v2; + + return (key1->bus == key2->bus) && (key1->devfn == key2->devfn); +} + +/* + * Note that we use pointer to PCIBus as the key, so hashing/shifting + * based on the pointer value is intended. Note that we deal with + * collisions through vtd_as_equal(). + */ +static guint vtd_as_hash(gconstpointer v) +{ + const struct vtd_as_key *key = v; + guint value = (guint)(uintptr_t)key->bus; + + return (guint)(value << 8 | key->devfn); +} + static gboolean vtd_hash_remove_by_domain(gpointer key, gpointer value, gpointer user_data) { @@ -248,22 +279,14 @@ static gboolean vtd_hash_remove_by_page(gpointer key, gpointer value, static void vtd_reset_context_cache_locked(IntelIOMMUState *s) { VTDAddressSpace *vtd_as; - VTDBus *vtd_bus; - GHashTableIter bus_it; - uint32_t devfn_it; + GHashTableIter as_it; trace_vtd_context_cache_reset(); - g_hash_table_iter_init(&bus_it, s->vtd_as_by_busptr); + g_hash_table_iter_init(&as_it, s->vtd_address_spaces); - while (g_hash_table_iter_next (&bus_it, NULL, (void**)&vtd_bus)) { - for (devfn_it = 0; devfn_it < PCI_DEVFN_MAX; ++devfn_it) { - vtd_as = vtd_bus->dev_as[devfn_it]; - if (!vtd_as) { - continue; - } - vtd_as->context_cache_entry.context_cache_gen = 0; - } + while (g_hash_table_iter_next(&as_it, NULL, (void **)&vtd_as)) { + vtd_as->context_cache_entry.context_cache_gen = 0; } s->context_cache_gen = 1; } @@ -993,32 +1016,6 @@ static bool vtd_slpte_nonzero_rsvd(uint64_t slpte, uint32_t level) return slpte & rsvd_mask; } -/* Find the VTD address space associated with a given bus number */ -static VTDBus *vtd_find_as_from_bus_num(IntelIOMMUState *s, uint8_t bus_num) -{ - VTDBus *vtd_bus = s->vtd_as_by_bus_num[bus_num]; - GHashTableIter iter; - - if (vtd_bus) { - return vtd_bus; - } - - /* - * Iterate over the registered buses to find the one which - * currently holds this bus number and update the bus_num - * lookup table. - */ - g_hash_table_iter_init(&iter, s->vtd_as_by_busptr); - while (g_hash_table_iter_next(&iter, NULL, (void **)&vtd_bus)) { - if (pci_bus_num(vtd_bus->bus) == bus_num) { - s->vtd_as_by_bus_num[bus_num] = vtd_bus; - return vtd_bus; - } - } - - return NULL; -} - /* Given the @iova, get relevant @slptep. @slpte_level will be the last level * of the translation, can be used for deciding the size of large page. */ @@ -1632,26 +1629,15 @@ static bool vtd_switch_address_space(VTDAddressSpace *as) static void vtd_switch_address_space_all(IntelIOMMUState *s) { + VTDAddressSpace *vtd_as; GHashTableIter iter; - VTDBus *vtd_bus; - int i; - g_hash_table_iter_init(&iter, s->vtd_as_by_busptr); - while (g_hash_table_iter_next(&iter, NULL, (void **)&vtd_bus)) { - for (i = 0; i < PCI_DEVFN_MAX; i++) { - if (!vtd_bus->dev_as[i]) { - continue; - } - vtd_switch_address_space(vtd_bus->dev_as[i]); - } + g_hash_table_iter_init(&iter, s->vtd_address_spaces); + while (g_hash_table_iter_next(&iter, NULL, (void **)&vtd_as)) { + vtd_switch_address_space(vtd_as); } } -static inline uint16_t vtd_make_source_id(uint8_t bus_num, uint8_t devfn) -{ - return ((bus_num & 0xffUL) << 8) | (devfn & 0xffUL); -} - static const bool vtd_qualified_faults[] = { [VTD_FR_RESERVED] = false, [VTD_FR_ROOT_ENTRY_P] = false, @@ -1686,18 +1672,37 @@ static inline bool vtd_is_interrupt_addr(hwaddr addr) return VTD_INTERRUPT_ADDR_FIRST <= addr && addr <= VTD_INTERRUPT_ADDR_LAST; } +static gboolean vtd_find_as_by_sid(gpointer key, gpointer value, + gpointer user_data) +{ + struct vtd_as_key *as_key = (struct vtd_as_key *)key; + uint16_t target_sid = *(uint16_t *)user_data; + uint16_t sid = PCI_BUILD_BDF(pci_bus_num(as_key->bus), as_key->devfn); + return sid == target_sid; +} + +static VTDAddressSpace *vtd_get_as_by_sid(IntelIOMMUState *s, uint16_t sid) +{ + uint8_t bus_num = PCI_BUS_NUM(sid); + VTDAddressSpace *vtd_as = s->vtd_as_cache[bus_num]; + + if (vtd_as && + (sid == PCI_BUILD_BDF(pci_bus_num(vtd_as->bus), vtd_as->devfn))) { + return vtd_as; + } + + vtd_as = g_hash_table_find(s->vtd_address_spaces, vtd_find_as_by_sid, &sid); + s->vtd_as_cache[bus_num] = vtd_as; + + return vtd_as; +} + static void vtd_pt_enable_fast_path(IntelIOMMUState *s, uint16_t source_id) { - VTDBus *vtd_bus; VTDAddressSpace *vtd_as; bool success = false; - vtd_bus = vtd_find_as_from_bus_num(s, VTD_SID_TO_BUS(source_id)); - if (!vtd_bus) { - goto out; - } - - vtd_as = vtd_bus->dev_as[VTD_SID_TO_DEVFN(source_id)]; + vtd_as = vtd_get_as_by_sid(s, source_id); if (!vtd_as) { goto out; } @@ -1733,7 +1738,7 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus, VTDContextCacheEntry *cc_entry; uint64_t slpte, page_mask; uint32_t level; - uint16_t source_id = vtd_make_source_id(bus_num, devfn); + uint16_t source_id = PCI_BUILD_BDF(bus_num, devfn); int ret_fr; bool is_fpd_set = false; bool reads = true; @@ -1905,11 +1910,10 @@ static void vtd_context_device_invalidate(IntelIOMMUState *s, uint16_t source_id, uint16_t func_mask) { + GHashTableIter as_it; uint16_t mask; - VTDBus *vtd_bus; VTDAddressSpace *vtd_as; uint8_t bus_n, devfn; - uint16_t devfn_it; trace_vtd_inv_desc_cc_devices(source_id, func_mask); @@ -1932,32 +1936,31 @@ static void vtd_context_device_invalidate(IntelIOMMUState *s, mask = ~mask; bus_n = VTD_SID_TO_BUS(source_id); - vtd_bus = vtd_find_as_from_bus_num(s, bus_n); - if (vtd_bus) { - devfn = VTD_SID_TO_DEVFN(source_id); - for (devfn_it = 0; devfn_it < PCI_DEVFN_MAX; ++devfn_it) { - vtd_as = vtd_bus->dev_as[devfn_it]; - if (vtd_as && ((devfn_it & mask) == (devfn & mask))) { - trace_vtd_inv_desc_cc_device(bus_n, VTD_PCI_SLOT(devfn_it), - VTD_PCI_FUNC(devfn_it)); - vtd_iommu_lock(s); - vtd_as->context_cache_entry.context_cache_gen = 0; - vtd_iommu_unlock(s); - /* - * Do switch address space when needed, in case if the - * device passthrough bit is switched. - */ - vtd_switch_address_space(vtd_as); - /* - * So a device is moving out of (or moving into) a - * domain, resync the shadow page table. - * This won't bring bad even if we have no such - * notifier registered - the IOMMU notification - * framework will skip MAP notifications if that - * happened. - */ - vtd_sync_shadow_page_table(vtd_as); - } + devfn = VTD_SID_TO_DEVFN(source_id); + + g_hash_table_iter_init(&as_it, s->vtd_address_spaces); + while (g_hash_table_iter_next(&as_it, NULL, (void **)&vtd_as)) { + if ((pci_bus_num(vtd_as->bus) == bus_n) && + (vtd_as->devfn & mask) == (devfn & mask)) { + trace_vtd_inv_desc_cc_device(bus_n, VTD_PCI_SLOT(vtd_as->devfn), + VTD_PCI_FUNC(vtd_as->devfn)); + vtd_iommu_lock(s); + vtd_as->context_cache_entry.context_cache_gen = 0; + vtd_iommu_unlock(s); + /* + * Do switch address space when needed, in case if the + * device passthrough bit is switched. + */ + vtd_switch_address_space(vtd_as); + /* + * So a device is moving out of (or moving into) a + * domain, resync the shadow page table. + * This won't bring bad even if we have no such + * notifier registered - the IOMMU notification + * framework will skip MAP notifications if that + * happened. + */ + vtd_sync_shadow_page_table(vtd_as); } } } @@ -2473,18 +2476,13 @@ static bool vtd_process_device_iotlb_desc(IntelIOMMUState *s, { VTDAddressSpace *vtd_dev_as; IOMMUTLBEvent event; - struct VTDBus *vtd_bus; hwaddr addr; uint64_t sz; uint16_t sid; - uint8_t devfn; bool size; - uint8_t bus_num; addr = VTD_INV_DESC_DEVICE_IOTLB_ADDR(inv_desc->hi); sid = VTD_INV_DESC_DEVICE_IOTLB_SID(inv_desc->lo); - devfn = sid & 0xff; - bus_num = sid >> 8; size = VTD_INV_DESC_DEVICE_IOTLB_SIZE(inv_desc->hi); if ((inv_desc->lo & VTD_INV_DESC_DEVICE_IOTLB_RSVD_LO) || @@ -2495,12 +2493,11 @@ static bool vtd_process_device_iotlb_desc(IntelIOMMUState *s, return false; } - vtd_bus = vtd_find_as_from_bus_num(s, bus_num); - if (!vtd_bus) { - goto done; - } - - vtd_dev_as = vtd_bus->dev_as[devfn]; + /* + * Using sid is OK since the guest should have finished the + * initialization of both the bus and device. + */ + vtd_dev_as = vtd_get_as_by_sid(s, sid); if (!vtd_dev_as) { goto done; } @@ -3427,27 +3424,27 @@ static const MemoryRegionOps vtd_mem_ir_ops = { VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn) { - uintptr_t key = (uintptr_t)bus; - VTDBus *vtd_bus = g_hash_table_lookup(s->vtd_as_by_busptr, &key); + /* + * We can't simply use sid here since the bus number might not be + * initialized by the guest. + */ + struct vtd_as_key key = { + .bus = bus, + .devfn = devfn, + }; VTDAddressSpace *vtd_dev_as; char name[128]; - if (!vtd_bus) { - uintptr_t *new_key = g_malloc(sizeof(*new_key)); - *new_key = (uintptr_t)bus; - /* No corresponding free() */ - vtd_bus = g_malloc0(sizeof(VTDBus) + sizeof(VTDAddressSpace *) * \ - PCI_DEVFN_MAX); - vtd_bus->bus = bus; - g_hash_table_insert(s->vtd_as_by_busptr, new_key, vtd_bus); - } - - vtd_dev_as = vtd_bus->dev_as[devfn]; - + vtd_dev_as = g_hash_table_lookup(s->vtd_address_spaces, &key); if (!vtd_dev_as) { + struct vtd_as_key *new_key = g_malloc(sizeof(*new_key)); + + new_key->bus = bus; + new_key->devfn = devfn; + snprintf(name, sizeof(name), "vtd-%02x.%x", PCI_SLOT(devfn), PCI_FUNC(devfn)); - vtd_bus->dev_as[devfn] = vtd_dev_as = g_new0(VTDAddressSpace, 1); + vtd_dev_as = g_new0(VTDAddressSpace, 1); vtd_dev_as->bus = bus; vtd_dev_as->devfn = (uint8_t)devfn; @@ -3503,6 +3500,8 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn) &vtd_dev_as->nodmar, 0); vtd_switch_address_space(vtd_dev_as); + + g_hash_table_insert(s->vtd_address_spaces, new_key, vtd_dev_as); } return vtd_dev_as; } @@ -3881,7 +3880,6 @@ static void vtd_realize(DeviceState *dev, Error **errp) QLIST_INIT(&s->vtd_as_with_notifiers); qemu_mutex_init(&s->iommu_lock); - memset(s->vtd_as_by_bus_num, 0, sizeof(s->vtd_as_by_bus_num)); memory_region_init_io(&s->csrmem, OBJECT(s), &vtd_mem_ops, s, "intel_iommu", DMAR_REG_SIZE); @@ -3903,8 +3901,8 @@ static void vtd_realize(DeviceState *dev, Error **errp) /* No corresponding destroy */ s->iotlb = g_hash_table_new_full(vtd_uint64_hash, vtd_uint64_equal, g_free, g_free); - s->vtd_as_by_busptr = g_hash_table_new_full(vtd_uint64_hash, vtd_uint64_equal, - g_free, g_free); + s->vtd_address_spaces = g_hash_table_new_full(vtd_as_hash, vtd_as_equal, + g_free, g_free); vtd_init(s); sysbus_mmio_map(SYS_BUS_DEVICE(s), 0, Q35_HOST_BRIDGE_IOMMU_ADDR); pci_setup_iommu(bus, vtd_host_dma_iommu, dev); diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h index 67653b0f9b..e49fff2a6c 100644 --- a/include/hw/i386/intel_iommu.h +++ b/include/hw/i386/intel_iommu.h @@ -58,7 +58,6 @@ typedef struct VTDContextEntry VTDContextEntry; typedef struct VTDContextCacheEntry VTDContextCacheEntry; typedef struct VTDAddressSpace VTDAddressSpace; typedef struct VTDIOTLBEntry VTDIOTLBEntry; -typedef struct VTDBus VTDBus; typedef union VTD_IR_TableEntry VTD_IR_TableEntry; typedef union VTD_IR_MSIAddress VTD_IR_MSIAddress; typedef struct VTDPASIDDirEntry VTDPASIDDirEntry; @@ -111,12 +110,6 @@ struct VTDAddressSpace { IOVATree *iova_tree; /* Traces mapped IOVA ranges */ }; -struct VTDBus { - PCIBus* bus; /* A reference to the bus to provide translation for */ - /* A table of VTDAddressSpace objects indexed by devfn */ - VTDAddressSpace *dev_as[]; -}; - struct VTDIOTLBEntry { uint64_t gfn; uint16_t domain_id; @@ -253,8 +246,8 @@ struct IntelIOMMUState { uint32_t context_cache_gen; /* Should be in [1,MAX] */ GHashTable *iotlb; /* IOTLB */ - GHashTable *vtd_as_by_busptr; /* VTDBus objects indexed by PCIBus* reference */ - VTDBus *vtd_as_by_bus_num[VTD_PCI_BUS_MAX]; /* VTDBus objects indexed by bus number */ + GHashTable *vtd_address_spaces; /* VTD address spaces */ + VTDAddressSpace *vtd_as_cache[VTD_PCI_BUS_MAX]; /* VTD address space cache */ /* list of registered notifiers */ QLIST_HEAD(, VTDAddressSpace) vtd_as_with_notifiers; From 940e55278611bad4e179e77952da6a36a37562b0 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Fri, 28 Oct 2022 14:14:35 +0800 Subject: [PATCH 654/705] intel-iommu: convert VTD_PE_GET_FPD_ERR() to be a function We used to have a macro for VTD_PE_GET_FPD_ERR() but it has an internal goto which prevents it from being reused. This patch convert that macro to a dedicated function and let the caller to decide what to do (e.g using goto or not). This makes sure it can be re-used for other function that requires fault reporting. Reviewed-by: Peter Xu Signed-off-by: Jason Wang Message-Id: <20221028061436.30093-4-jasowang@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Yi Liu --- hw/i386/intel_iommu.c | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 3d426bb326..259f720c7c 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -49,17 +49,6 @@ /* pe operations */ #define VTD_PE_GET_TYPE(pe) ((pe)->val[0] & VTD_SM_PASID_ENTRY_PGTT) #define VTD_PE_GET_LEVEL(pe) (2 + (((pe)->val[0] >> 2) & VTD_SM_PASID_ENTRY_AW)) -#define VTD_PE_GET_FPD_ERR(ret_fr, is_fpd_set, s, source_id, addr, is_write) {\ - if (ret_fr) { \ - ret_fr = -ret_fr; \ - if (is_fpd_set && vtd_is_qualified_fault(ret_fr)) { \ - trace_vtd_fault_disabled(); \ - } else { \ - vtd_report_dmar_fault(s, source_id, addr, ret_fr, is_write); \ - } \ - goto error; \ - } \ -} /* * PCI bus number (or SID) is not reliable since the device is usaully @@ -1716,6 +1705,19 @@ out: trace_vtd_pt_enable_fast_path(source_id, success); } +static void vtd_report_fault(IntelIOMMUState *s, + int err, bool is_fpd_set, + uint16_t source_id, + hwaddr addr, + bool is_write) +{ + if (is_fpd_set && vtd_is_qualified_fault(err)) { + trace_vtd_fault_disabled(); + } else { + vtd_report_dmar_fault(s, source_id, addr, err, is_write); + } +} + /* Map dev to context-entry then do a paging-structures walk to do a iommu * translation. * @@ -1776,7 +1778,11 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus, is_fpd_set = ce.lo & VTD_CONTEXT_ENTRY_FPD; if (!is_fpd_set && s->root_scalable) { ret_fr = vtd_ce_get_pasid_fpd(s, &ce, &is_fpd_set); - VTD_PE_GET_FPD_ERR(ret_fr, is_fpd_set, s, source_id, addr, is_write); + if (ret_fr) { + vtd_report_fault(s, -ret_fr, is_fpd_set, + source_id, addr, is_write); + goto error; + } } } else { ret_fr = vtd_dev_to_context_entry(s, bus_num, devfn, &ce); @@ -1784,7 +1790,11 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus, if (!ret_fr && !is_fpd_set && s->root_scalable) { ret_fr = vtd_ce_get_pasid_fpd(s, &ce, &is_fpd_set); } - VTD_PE_GET_FPD_ERR(ret_fr, is_fpd_set, s, source_id, addr, is_write); + if (ret_fr) { + vtd_report_fault(s, -ret_fr, is_fpd_set, + source_id, addr, is_write); + goto error; + } /* Update context-cache */ trace_vtd_iotlb_cc_update(bus_num, devfn, ce.hi, ce.lo, cc_entry->context_cache_gen, @@ -1820,7 +1830,11 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus, ret_fr = vtd_iova_to_slpte(s, &ce, addr, is_write, &slpte, &level, &reads, &writes, s->aw_bits); - VTD_PE_GET_FPD_ERR(ret_fr, is_fpd_set, s, source_id, addr, is_write); + if (ret_fr) { + vtd_report_fault(s, -ret_fr, is_fpd_set, source_id, + addr, is_write); + goto error; + } page_mask = vtd_slpt_level_page_mask(level); access_flags = IOMMU_ACCESS_FLAG(reads, writes); From 1b2b12376c8a513a0c7b5e3b8ea702038d3d7db5 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Fri, 28 Oct 2022 14:14:36 +0800 Subject: [PATCH 655/705] intel-iommu: PASID support This patch introduce ECAP_PASID via "x-pasid-mode". Based on the existing support for scalable mode, we need to implement the following missing parts: 1) tag VTDAddressSpace with PASID and support IOMMU/DMA translation with PASID 2) tag IOTLB with PASID 3) PASID cache and its flush 4) PASID based IOTLB invalidation For simplicity PASID cache is not implemented so we can simply implement the PASID cache flush as a no and leave it to be implemented in the future. For PASID based IOTLB invalidation, since we haven't had L1 stage support, the PASID based IOTLB invalidation is not implemented yet. For PASID based device IOTLB invalidation, it requires the support for vhost so we forbid enabling device IOTLB when PASID is enabled now. Those work could be done in the future. Note that though PASID based IOMMU translation is ready but no device can issue PASID DMA right now. In this case, PCI_NO_PASID is used as PASID to identify the address without PASID. vtd_find_add_as() has been extended to provision address space with PASID which could be utilized by the future extension of PCI core to allow device model to use PASID based DMA translation. This feature would be useful for: 1) prototyping PASID support for devices like virtio 2) future vPASID work 3) future PRS and vSVA work Reviewed-by: Peter Xu Signed-off-by: Jason Wang Message-Id: <20221028061436.30093-5-jasowang@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/intel_iommu.c | 418 +++++++++++++++++++++++++-------- hw/i386/intel_iommu_internal.h | 16 +- hw/i386/trace-events | 2 + include/hw/i386/intel_iommu.h | 7 +- include/hw/pci/pci_bus.h | 2 + 5 files changed, 341 insertions(+), 104 deletions(-) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 259f720c7c..a08ee85edf 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -58,6 +58,14 @@ struct vtd_as_key { PCIBus *bus; uint8_t devfn; + uint32_t pasid; +}; + +struct vtd_iotlb_key { + uint64_t gfn; + uint32_t pasid; + uint32_t level; + uint16_t sid; }; static void vtd_address_space_refresh_all(IntelIOMMUState *s); @@ -199,14 +207,24 @@ static inline gboolean vtd_as_has_map_notifier(VTDAddressSpace *as) } /* GHashTable functions */ -static gboolean vtd_uint64_equal(gconstpointer v1, gconstpointer v2) +static gboolean vtd_iotlb_equal(gconstpointer v1, gconstpointer v2) { - return *((const uint64_t *)v1) == *((const uint64_t *)v2); + const struct vtd_iotlb_key *key1 = v1; + const struct vtd_iotlb_key *key2 = v2; + + return key1->sid == key2->sid && + key1->pasid == key2->pasid && + key1->level == key2->level && + key1->gfn == key2->gfn; } -static guint vtd_uint64_hash(gconstpointer v) +static guint vtd_iotlb_hash(gconstpointer v) { - return (guint)*(const uint64_t *)v; + const struct vtd_iotlb_key *key = v; + + return key->gfn | ((key->sid) << VTD_IOTLB_SID_SHIFT) | + (key->level) << VTD_IOTLB_LVL_SHIFT | + (key->pasid) << VTD_IOTLB_PASID_SHIFT; } static gboolean vtd_as_equal(gconstpointer v1, gconstpointer v2) @@ -214,7 +232,8 @@ static gboolean vtd_as_equal(gconstpointer v1, gconstpointer v2) const struct vtd_as_key *key1 = v1; const struct vtd_as_key *key2 = v2; - return (key1->bus == key2->bus) && (key1->devfn == key2->devfn); + return (key1->bus == key2->bus) && (key1->devfn == key2->devfn) && + (key1->pasid == key2->pasid); } /* @@ -302,13 +321,6 @@ static void vtd_reset_caches(IntelIOMMUState *s) vtd_iommu_unlock(s); } -static uint64_t vtd_get_iotlb_key(uint64_t gfn, uint16_t source_id, - uint32_t level) -{ - return gfn | ((uint64_t)(source_id) << VTD_IOTLB_SID_SHIFT) | - ((uint64_t)(level) << VTD_IOTLB_LVL_SHIFT); -} - static uint64_t vtd_get_iotlb_gfn(hwaddr addr, uint32_t level) { return (addr & vtd_slpt_level_page_mask(level)) >> VTD_PAGE_SHIFT_4K; @@ -316,15 +328,17 @@ static uint64_t vtd_get_iotlb_gfn(hwaddr addr, uint32_t level) /* Must be called with IOMMU lock held */ static VTDIOTLBEntry *vtd_lookup_iotlb(IntelIOMMUState *s, uint16_t source_id, - hwaddr addr) + uint32_t pasid, hwaddr addr) { + struct vtd_iotlb_key key; VTDIOTLBEntry *entry; - uint64_t key; int level; for (level = VTD_SL_PT_LEVEL; level < VTD_SL_PML4_LEVEL; level++) { - key = vtd_get_iotlb_key(vtd_get_iotlb_gfn(addr, level), - source_id, level); + key.gfn = vtd_get_iotlb_gfn(addr, level); + key.level = level; + key.sid = source_id; + key.pasid = pasid; entry = g_hash_table_lookup(s->iotlb, &key); if (entry) { goto out; @@ -338,10 +352,11 @@ out: /* Must be with IOMMU lock held */ static void vtd_update_iotlb(IntelIOMMUState *s, uint16_t source_id, uint16_t domain_id, hwaddr addr, uint64_t slpte, - uint8_t access_flags, uint32_t level) + uint8_t access_flags, uint32_t level, + uint32_t pasid) { VTDIOTLBEntry *entry = g_malloc(sizeof(*entry)); - uint64_t *key = g_malloc(sizeof(*key)); + struct vtd_iotlb_key *key = g_malloc(sizeof(*key)); uint64_t gfn = vtd_get_iotlb_gfn(addr, level); trace_vtd_iotlb_page_update(source_id, addr, slpte, domain_id); @@ -355,7 +370,13 @@ static void vtd_update_iotlb(IntelIOMMUState *s, uint16_t source_id, entry->slpte = slpte; entry->access_flags = access_flags; entry->mask = vtd_slpt_level_page_mask(level); - *key = vtd_get_iotlb_key(gfn, source_id, level); + entry->pasid = pasid; + + key->gfn = gfn; + key->sid = source_id; + key->level = level; + key->pasid = pasid; + g_hash_table_replace(s->iotlb, key, entry); } @@ -448,7 +469,8 @@ static void vtd_set_frcd_and_update_ppf(IntelIOMMUState *s, uint16_t index) /* Must not update F field now, should be done later */ static void vtd_record_frcd(IntelIOMMUState *s, uint16_t index, uint16_t source_id, hwaddr addr, - VTDFaultReason fault, bool is_write) + VTDFaultReason fault, bool is_write, + bool is_pasid, uint32_t pasid) { uint64_t hi = 0, lo; hwaddr frcd_reg_addr = DMAR_FRCD_REG_OFFSET + (((uint64_t)index) << 4); @@ -456,7 +478,8 @@ static void vtd_record_frcd(IntelIOMMUState *s, uint16_t index, assert(index < DMAR_FRCD_REG_NR); lo = VTD_FRCD_FI(addr); - hi = VTD_FRCD_SID(source_id) | VTD_FRCD_FR(fault); + hi = VTD_FRCD_SID(source_id) | VTD_FRCD_FR(fault) | + VTD_FRCD_PV(pasid) | VTD_FRCD_PP(is_pasid); if (!is_write) { hi |= VTD_FRCD_T; } @@ -487,7 +510,8 @@ static bool vtd_try_collapse_fault(IntelIOMMUState *s, uint16_t source_id) /* Log and report an DMAR (address translation) fault to software */ static void vtd_report_dmar_fault(IntelIOMMUState *s, uint16_t source_id, hwaddr addr, VTDFaultReason fault, - bool is_write) + bool is_write, bool is_pasid, + uint32_t pasid) { uint32_t fsts_reg = vtd_get_long_raw(s, DMAR_FSTS_REG); @@ -514,7 +538,8 @@ static void vtd_report_dmar_fault(IntelIOMMUState *s, uint16_t source_id, return; } - vtd_record_frcd(s, s->next_frcd_reg, source_id, addr, fault, is_write); + vtd_record_frcd(s, s->next_frcd_reg, source_id, addr, fault, + is_write, is_pasid, pasid); if (fsts_reg & VTD_FSTS_PPF) { error_report_once("There are pending faults already, " @@ -819,13 +844,15 @@ static int vtd_get_pe_from_pasid_table(IntelIOMMUState *s, static int vtd_ce_get_rid2pasid_entry(IntelIOMMUState *s, VTDContextEntry *ce, - VTDPASIDEntry *pe) + VTDPASIDEntry *pe, + uint32_t pasid) { - uint32_t pasid; dma_addr_t pasid_dir_base; int ret = 0; - pasid = VTD_CE_GET_RID2PASID(ce); + if (pasid == PCI_NO_PASID) { + pasid = VTD_CE_GET_RID2PASID(ce); + } pasid_dir_base = VTD_CE_GET_PASID_DIR_TABLE(ce); ret = vtd_get_pe_from_pasid_table(s, pasid_dir_base, pasid, pe); @@ -834,15 +861,17 @@ static int vtd_ce_get_rid2pasid_entry(IntelIOMMUState *s, static int vtd_ce_get_pasid_fpd(IntelIOMMUState *s, VTDContextEntry *ce, - bool *pe_fpd_set) + bool *pe_fpd_set, + uint32_t pasid) { int ret; - uint32_t pasid; dma_addr_t pasid_dir_base; VTDPASIDDirEntry pdire; VTDPASIDEntry pe; - pasid = VTD_CE_GET_RID2PASID(ce); + if (pasid == PCI_NO_PASID) { + pasid = VTD_CE_GET_RID2PASID(ce); + } pasid_dir_base = VTD_CE_GET_PASID_DIR_TABLE(ce); /* @@ -888,12 +917,13 @@ static inline uint32_t vtd_ce_get_level(VTDContextEntry *ce) } static uint32_t vtd_get_iova_level(IntelIOMMUState *s, - VTDContextEntry *ce) + VTDContextEntry *ce, + uint32_t pasid) { VTDPASIDEntry pe; if (s->root_scalable) { - vtd_ce_get_rid2pasid_entry(s, ce, &pe); + vtd_ce_get_rid2pasid_entry(s, ce, &pe, pasid); return VTD_PE_GET_LEVEL(&pe); } @@ -906,12 +936,13 @@ static inline uint32_t vtd_ce_get_agaw(VTDContextEntry *ce) } static uint32_t vtd_get_iova_agaw(IntelIOMMUState *s, - VTDContextEntry *ce) + VTDContextEntry *ce, + uint32_t pasid) { VTDPASIDEntry pe; if (s->root_scalable) { - vtd_ce_get_rid2pasid_entry(s, ce, &pe); + vtd_ce_get_rid2pasid_entry(s, ce, &pe, pasid); return 30 + ((pe.val[0] >> 2) & VTD_SM_PASID_ENTRY_AW) * 9; } @@ -953,31 +984,33 @@ static inline bool vtd_ce_type_check(X86IOMMUState *x86_iommu, } static inline uint64_t vtd_iova_limit(IntelIOMMUState *s, - VTDContextEntry *ce, uint8_t aw) + VTDContextEntry *ce, uint8_t aw, + uint32_t pasid) { - uint32_t ce_agaw = vtd_get_iova_agaw(s, ce); + uint32_t ce_agaw = vtd_get_iova_agaw(s, ce, pasid); return 1ULL << MIN(ce_agaw, aw); } /* Return true if IOVA passes range check, otherwise false. */ static inline bool vtd_iova_range_check(IntelIOMMUState *s, uint64_t iova, VTDContextEntry *ce, - uint8_t aw) + uint8_t aw, uint32_t pasid) { /* * Check if @iova is above 2^X-1, where X is the minimum of MGAW * in CAP_REG and AW in context-entry. */ - return !(iova & ~(vtd_iova_limit(s, ce, aw) - 1)); + return !(iova & ~(vtd_iova_limit(s, ce, aw, pasid) - 1)); } static dma_addr_t vtd_get_iova_pgtbl_base(IntelIOMMUState *s, - VTDContextEntry *ce) + VTDContextEntry *ce, + uint32_t pasid) { VTDPASIDEntry pe; if (s->root_scalable) { - vtd_ce_get_rid2pasid_entry(s, ce, &pe); + vtd_ce_get_rid2pasid_entry(s, ce, &pe, pasid); return pe.val[0] & VTD_SM_PASID_ENTRY_SLPTPTR; } @@ -1011,18 +1044,19 @@ static bool vtd_slpte_nonzero_rsvd(uint64_t slpte, uint32_t level) static int vtd_iova_to_slpte(IntelIOMMUState *s, VTDContextEntry *ce, uint64_t iova, bool is_write, uint64_t *slptep, uint32_t *slpte_level, - bool *reads, bool *writes, uint8_t aw_bits) + bool *reads, bool *writes, uint8_t aw_bits, + uint32_t pasid) { - dma_addr_t addr = vtd_get_iova_pgtbl_base(s, ce); - uint32_t level = vtd_get_iova_level(s, ce); + dma_addr_t addr = vtd_get_iova_pgtbl_base(s, ce, pasid); + uint32_t level = vtd_get_iova_level(s, ce, pasid); uint32_t offset; uint64_t slpte; uint64_t access_right_check; uint64_t xlat, size; - if (!vtd_iova_range_check(s, iova, ce, aw_bits)) { - error_report_once("%s: detected IOVA overflow (iova=0x%" PRIx64 ")", - __func__, iova); + if (!vtd_iova_range_check(s, iova, ce, aw_bits, pasid)) { + error_report_once("%s: detected IOVA overflow (iova=0x%" PRIx64 "," + "pasid=0x%" PRIx32 ")", __func__, iova, pasid); return -VTD_FR_ADDR_BEYOND_MGAW; } @@ -1035,8 +1069,9 @@ static int vtd_iova_to_slpte(IntelIOMMUState *s, VTDContextEntry *ce, if (slpte == (uint64_t)-1) { error_report_once("%s: detected read error on DMAR slpte " - "(iova=0x%" PRIx64 ")", __func__, iova); - if (level == vtd_get_iova_level(s, ce)) { + "(iova=0x%" PRIx64 ", pasid=0x%" PRIx32 ")", + __func__, iova, pasid); + if (level == vtd_get_iova_level(s, ce, pasid)) { /* Invalid programming of context-entry */ return -VTD_FR_CONTEXT_ENTRY_INV; } else { @@ -1048,15 +1083,16 @@ static int vtd_iova_to_slpte(IntelIOMMUState *s, VTDContextEntry *ce, if (!(slpte & access_right_check)) { error_report_once("%s: detected slpte permission error " "(iova=0x%" PRIx64 ", level=0x%" PRIx32 ", " - "slpte=0x%" PRIx64 ", write=%d)", __func__, - iova, level, slpte, is_write); + "slpte=0x%" PRIx64 ", write=%d, pasid=0x%" + PRIx32 ")", __func__, iova, level, + slpte, is_write, pasid); return is_write ? -VTD_FR_WRITE : -VTD_FR_READ; } if (vtd_slpte_nonzero_rsvd(slpte, level)) { error_report_once("%s: detected splte reserve non-zero " "iova=0x%" PRIx64 ", level=0x%" PRIx32 - "slpte=0x%" PRIx64 ")", __func__, iova, - level, slpte); + "slpte=0x%" PRIx64 ", pasid=0x%" PRIX32 ")", + __func__, iova, level, slpte, pasid); return -VTD_FR_PAGING_ENTRY_RSVD; } @@ -1084,9 +1120,10 @@ static int vtd_iova_to_slpte(IntelIOMMUState *s, VTDContextEntry *ce, error_report_once("%s: xlat address is in interrupt range " "(iova=0x%" PRIx64 ", level=0x%" PRIx32 ", " "slpte=0x%" PRIx64 ", write=%d, " - "xlat=0x%" PRIx64 ", size=0x%" PRIx64 ")", + "xlat=0x%" PRIx64 ", size=0x%" PRIx64 ", " + "pasid=0x%" PRIx32 ")", __func__, iova, level, slpte, is_write, - xlat, size); + xlat, size, pasid); return s->scalable_mode ? -VTD_FR_SM_INTERRUPT_ADDR : -VTD_FR_INTERRUPT_ADDR; } @@ -1300,18 +1337,19 @@ next: */ static int vtd_page_walk(IntelIOMMUState *s, VTDContextEntry *ce, uint64_t start, uint64_t end, - vtd_page_walk_info *info) + vtd_page_walk_info *info, + uint32_t pasid) { - dma_addr_t addr = vtd_get_iova_pgtbl_base(s, ce); - uint32_t level = vtd_get_iova_level(s, ce); + dma_addr_t addr = vtd_get_iova_pgtbl_base(s, ce, pasid); + uint32_t level = vtd_get_iova_level(s, ce, pasid); - if (!vtd_iova_range_check(s, start, ce, info->aw)) { + if (!vtd_iova_range_check(s, start, ce, info->aw, pasid)) { return -VTD_FR_ADDR_BEYOND_MGAW; } - if (!vtd_iova_range_check(s, end, ce, info->aw)) { + if (!vtd_iova_range_check(s, end, ce, info->aw, pasid)) { /* Fix end so that it reaches the maximum */ - end = vtd_iova_limit(s, ce, info->aw); + end = vtd_iova_limit(s, ce, info->aw, pasid); } return vtd_page_walk_level(addr, start, end, level, true, true, info); @@ -1379,7 +1417,7 @@ static int vtd_ce_rid2pasid_check(IntelIOMMUState *s, * has valid rid2pasid setting, which includes valid * rid2pasid field and corresponding pasid entry setting */ - return vtd_ce_get_rid2pasid_entry(s, ce, &pe); + return vtd_ce_get_rid2pasid_entry(s, ce, &pe, PCI_NO_PASID); } /* Map a device to its corresponding domain (context-entry) */ @@ -1462,12 +1500,13 @@ static int vtd_sync_shadow_page_hook(IOMMUTLBEvent *event, } static uint16_t vtd_get_domain_id(IntelIOMMUState *s, - VTDContextEntry *ce) + VTDContextEntry *ce, + uint32_t pasid) { VTDPASIDEntry pe; if (s->root_scalable) { - vtd_ce_get_rid2pasid_entry(s, ce, &pe); + vtd_ce_get_rid2pasid_entry(s, ce, &pe, pasid); return VTD_SM_PASID_ENTRY_DID(pe.val[1]); } @@ -1485,10 +1524,10 @@ static int vtd_sync_shadow_page_table_range(VTDAddressSpace *vtd_as, .notify_unmap = true, .aw = s->aw_bits, .as = vtd_as, - .domain_id = vtd_get_domain_id(s, ce), + .domain_id = vtd_get_domain_id(s, ce, vtd_as->pasid), }; - return vtd_page_walk(s, ce, addr, addr + size, &info); + return vtd_page_walk(s, ce, addr, addr + size, &info, vtd_as->pasid); } static int vtd_sync_shadow_page_table(VTDAddressSpace *vtd_as) @@ -1532,13 +1571,14 @@ static int vtd_sync_shadow_page_table(VTDAddressSpace *vtd_as) * 1st-level translation or 2nd-level translation, it depends * on PGTT setting. */ -static bool vtd_dev_pt_enabled(IntelIOMMUState *s, VTDContextEntry *ce) +static bool vtd_dev_pt_enabled(IntelIOMMUState *s, VTDContextEntry *ce, + uint32_t pasid) { VTDPASIDEntry pe; int ret; if (s->root_scalable) { - ret = vtd_ce_get_rid2pasid_entry(s, ce, &pe); + ret = vtd_ce_get_rid2pasid_entry(s, ce, &pe, pasid); if (ret) { /* * This error is guest triggerable. We should assumt PT @@ -1572,19 +1612,20 @@ static bool vtd_as_pt_enabled(VTDAddressSpace *as) return false; } - return vtd_dev_pt_enabled(s, &ce); + return vtd_dev_pt_enabled(s, &ce, as->pasid); } /* Return whether the device is using IOMMU translation. */ static bool vtd_switch_address_space(VTDAddressSpace *as) { - bool use_iommu; + bool use_iommu, pt; /* Whether we need to take the BQL on our own */ bool take_bql = !qemu_mutex_iothread_locked(); assert(as); use_iommu = as->iommu_state->dmar_enabled && !vtd_as_pt_enabled(as); + pt = as->iommu_state->dmar_enabled && vtd_as_pt_enabled(as); trace_vtd_switch_address_space(pci_bus_num(as->bus), VTD_PCI_SLOT(as->devfn), @@ -1604,11 +1645,53 @@ static bool vtd_switch_address_space(VTDAddressSpace *as) if (use_iommu) { memory_region_set_enabled(&as->nodmar, false); memory_region_set_enabled(MEMORY_REGION(&as->iommu), true); + /* + * vt-d spec v3.4 3.14: + * + * """ + * Requests-with-PASID with input address in range 0xFEEx_xxxx + * are translated normally like any other request-with-PASID + * through DMA-remapping hardware. + * """ + * + * Need to disable ir for as with PASID. + */ + if (as->pasid != PCI_NO_PASID) { + memory_region_set_enabled(&as->iommu_ir, false); + } else { + memory_region_set_enabled(&as->iommu_ir, true); + } } else { memory_region_set_enabled(MEMORY_REGION(&as->iommu), false); memory_region_set_enabled(&as->nodmar, true); } + /* + * vtd-spec v3.4 3.14: + * + * """ + * Requests-with-PASID with input address in range 0xFEEx_xxxx are + * translated normally like any other request-with-PASID through + * DMA-remapping hardware. However, if such a request is processed + * using pass-through translation, it will be blocked as described + * in the paragraph below. + * + * Software must not program paging-structure entries to remap any + * address to the interrupt address range. Untranslated requests + * and translation requests that result in an address in the + * interrupt range will be blocked with condition code LGN.4 or + * SGN.8. + * """ + * + * We enable per as memory region (iommu_ir_fault) for catching + * the tranlsation for interrupt range through PASID + PT. + */ + if (pt && as->pasid != PCI_NO_PASID) { + memory_region_set_enabled(&as->iommu_ir_fault, true); + } else { + memory_region_set_enabled(&as->iommu_ir_fault, false); + } + if (take_bql) { qemu_mutex_unlock_iothread(); } @@ -1709,12 +1792,15 @@ static void vtd_report_fault(IntelIOMMUState *s, int err, bool is_fpd_set, uint16_t source_id, hwaddr addr, - bool is_write) + bool is_write, + bool is_pasid, + uint32_t pasid) { if (is_fpd_set && vtd_is_qualified_fault(err)) { trace_vtd_fault_disabled(); } else { - vtd_report_dmar_fault(s, source_id, addr, err, is_write); + vtd_report_dmar_fault(s, source_id, addr, err, is_write, + is_pasid, pasid); } } @@ -1739,13 +1825,14 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus, uint8_t bus_num = pci_bus_num(bus); VTDContextCacheEntry *cc_entry; uint64_t slpte, page_mask; - uint32_t level; + uint32_t level, pasid = vtd_as->pasid; uint16_t source_id = PCI_BUILD_BDF(bus_num, devfn); int ret_fr; bool is_fpd_set = false; bool reads = true; bool writes = true; uint8_t access_flags; + bool rid2pasid = (pasid == PCI_NO_PASID) && s->root_scalable; VTDIOTLBEntry *iotlb_entry; /* @@ -1758,15 +1845,17 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus, cc_entry = &vtd_as->context_cache_entry; - /* Try to fetch slpte form IOTLB */ - iotlb_entry = vtd_lookup_iotlb(s, source_id, addr); - if (iotlb_entry) { - trace_vtd_iotlb_page_hit(source_id, addr, iotlb_entry->slpte, - iotlb_entry->domain_id); - slpte = iotlb_entry->slpte; - access_flags = iotlb_entry->access_flags; - page_mask = iotlb_entry->mask; - goto out; + /* Try to fetch slpte form IOTLB, we don't need RID2PASID logic */ + if (!rid2pasid) { + iotlb_entry = vtd_lookup_iotlb(s, source_id, pasid, addr); + if (iotlb_entry) { + trace_vtd_iotlb_page_hit(source_id, addr, iotlb_entry->slpte, + iotlb_entry->domain_id); + slpte = iotlb_entry->slpte; + access_flags = iotlb_entry->access_flags; + page_mask = iotlb_entry->mask; + goto out; + } } /* Try to fetch context-entry from cache first */ @@ -1777,10 +1866,11 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus, ce = cc_entry->context_entry; is_fpd_set = ce.lo & VTD_CONTEXT_ENTRY_FPD; if (!is_fpd_set && s->root_scalable) { - ret_fr = vtd_ce_get_pasid_fpd(s, &ce, &is_fpd_set); + ret_fr = vtd_ce_get_pasid_fpd(s, &ce, &is_fpd_set, pasid); if (ret_fr) { vtd_report_fault(s, -ret_fr, is_fpd_set, - source_id, addr, is_write); + source_id, addr, is_write, + false, 0); goto error; } } @@ -1788,11 +1878,12 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus, ret_fr = vtd_dev_to_context_entry(s, bus_num, devfn, &ce); is_fpd_set = ce.lo & VTD_CONTEXT_ENTRY_FPD; if (!ret_fr && !is_fpd_set && s->root_scalable) { - ret_fr = vtd_ce_get_pasid_fpd(s, &ce, &is_fpd_set); + ret_fr = vtd_ce_get_pasid_fpd(s, &ce, &is_fpd_set, pasid); } if (ret_fr) { vtd_report_fault(s, -ret_fr, is_fpd_set, - source_id, addr, is_write); + source_id, addr, is_write, + false, 0); goto error; } /* Update context-cache */ @@ -1803,11 +1894,15 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus, cc_entry->context_cache_gen = s->context_cache_gen; } + if (rid2pasid) { + pasid = VTD_CE_GET_RID2PASID(&ce); + } + /* * We don't need to translate for pass-through context entries. * Also, let's ignore IOTLB caching as well for PT devices. */ - if (vtd_dev_pt_enabled(s, &ce)) { + if (vtd_dev_pt_enabled(s, &ce, pasid)) { entry->iova = addr & VTD_PAGE_MASK_4K; entry->translated_addr = entry->iova; entry->addr_mask = ~VTD_PAGE_MASK_4K; @@ -1828,18 +1923,31 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus, return true; } + /* Try to fetch slpte form IOTLB for RID2PASID slow path */ + if (rid2pasid) { + iotlb_entry = vtd_lookup_iotlb(s, source_id, pasid, addr); + if (iotlb_entry) { + trace_vtd_iotlb_page_hit(source_id, addr, iotlb_entry->slpte, + iotlb_entry->domain_id); + slpte = iotlb_entry->slpte; + access_flags = iotlb_entry->access_flags; + page_mask = iotlb_entry->mask; + goto out; + } + } + ret_fr = vtd_iova_to_slpte(s, &ce, addr, is_write, &slpte, &level, - &reads, &writes, s->aw_bits); + &reads, &writes, s->aw_bits, pasid); if (ret_fr) { vtd_report_fault(s, -ret_fr, is_fpd_set, source_id, - addr, is_write); + addr, is_write, pasid != PCI_NO_PASID, pasid); goto error; } page_mask = vtd_slpt_level_page_mask(level); access_flags = IOMMU_ACCESS_FLAG(reads, writes); - vtd_update_iotlb(s, source_id, vtd_get_domain_id(s, &ce), addr, slpte, - access_flags, level); + vtd_update_iotlb(s, source_id, vtd_get_domain_id(s, &ce, pasid), + addr, slpte, access_flags, level, pasid); out: vtd_iommu_unlock(s); entry->iova = addr & page_mask; @@ -2031,7 +2139,7 @@ static void vtd_iotlb_domain_invalidate(IntelIOMMUState *s, uint16_t domain_id) QLIST_FOREACH(vtd_as, &s->vtd_as_with_notifiers, next) { if (!vtd_dev_to_context_entry(s, pci_bus_num(vtd_as->bus), vtd_as->devfn, &ce) && - domain_id == vtd_get_domain_id(s, &ce)) { + domain_id == vtd_get_domain_id(s, &ce, vtd_as->pasid)) { vtd_sync_shadow_page_table(vtd_as); } } @@ -2039,7 +2147,7 @@ static void vtd_iotlb_domain_invalidate(IntelIOMMUState *s, uint16_t domain_id) static void vtd_iotlb_page_invalidate_notify(IntelIOMMUState *s, uint16_t domain_id, hwaddr addr, - uint8_t am) + uint8_t am, uint32_t pasid) { VTDAddressSpace *vtd_as; VTDContextEntry ce; @@ -2047,9 +2155,12 @@ static void vtd_iotlb_page_invalidate_notify(IntelIOMMUState *s, hwaddr size = (1 << am) * VTD_PAGE_SIZE; QLIST_FOREACH(vtd_as, &(s->vtd_as_with_notifiers), next) { + if (pasid != PCI_NO_PASID && pasid != vtd_as->pasid) { + continue; + } ret = vtd_dev_to_context_entry(s, pci_bus_num(vtd_as->bus), vtd_as->devfn, &ce); - if (!ret && domain_id == vtd_get_domain_id(s, &ce)) { + if (!ret && domain_id == vtd_get_domain_id(s, &ce, vtd_as->pasid)) { if (vtd_as_has_map_notifier(vtd_as)) { /* * As long as we have MAP notifications registered in @@ -2093,7 +2204,7 @@ static void vtd_iotlb_page_invalidate(IntelIOMMUState *s, uint16_t domain_id, vtd_iommu_lock(s); g_hash_table_foreach_remove(s->iotlb, vtd_hash_remove_by_page, &info); vtd_iommu_unlock(s); - vtd_iotlb_page_invalidate_notify(s, domain_id, addr, am); + vtd_iotlb_page_invalidate_notify(s, domain_id, addr, am, PCI_NO_PASID); } /* Flush IOTLB @@ -3162,6 +3273,7 @@ static Property vtd_properties[] = { DEFINE_PROP_BOOL("caching-mode", IntelIOMMUState, caching_mode, FALSE), DEFINE_PROP_BOOL("x-scalable-mode", IntelIOMMUState, scalable_mode, FALSE), DEFINE_PROP_BOOL("snoop-control", IntelIOMMUState, snoop_control, false), + DEFINE_PROP_BOOL("x-pasid-mode", IntelIOMMUState, pasid, false), DEFINE_PROP_BOOL("dma-drain", IntelIOMMUState, dma_drain, true), DEFINE_PROP_BOOL("dma-translation", IntelIOMMUState, dma_translation, true), DEFINE_PROP_END_OF_LIST(), @@ -3436,7 +3548,64 @@ static const MemoryRegionOps vtd_mem_ir_ops = { }, }; -VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn) +static void vtd_report_ir_illegal_access(VTDAddressSpace *vtd_as, + hwaddr addr, bool is_write) +{ + IntelIOMMUState *s = vtd_as->iommu_state; + uint8_t bus_n = pci_bus_num(vtd_as->bus); + uint16_t sid = PCI_BUILD_BDF(bus_n, vtd_as->devfn); + bool is_fpd_set = false; + VTDContextEntry ce; + + assert(vtd_as->pasid != PCI_NO_PASID); + + /* Try out best to fetch FPD, we can't do anything more */ + if (vtd_dev_to_context_entry(s, bus_n, vtd_as->devfn, &ce) == 0) { + is_fpd_set = ce.lo & VTD_CONTEXT_ENTRY_FPD; + if (!is_fpd_set && s->root_scalable) { + vtd_ce_get_pasid_fpd(s, &ce, &is_fpd_set, vtd_as->pasid); + } + } + + vtd_report_fault(s, VTD_FR_SM_INTERRUPT_ADDR, + is_fpd_set, sid, addr, is_write, + true, vtd_as->pasid); +} + +static MemTxResult vtd_mem_ir_fault_read(void *opaque, hwaddr addr, + uint64_t *data, unsigned size, + MemTxAttrs attrs) +{ + vtd_report_ir_illegal_access(opaque, addr, false); + + return MEMTX_ERROR; +} + +static MemTxResult vtd_mem_ir_fault_write(void *opaque, hwaddr addr, + uint64_t value, unsigned size, + MemTxAttrs attrs) +{ + vtd_report_ir_illegal_access(opaque, addr, true); + + return MEMTX_ERROR; +} + +static const MemoryRegionOps vtd_mem_ir_fault_ops = { + .read_with_attrs = vtd_mem_ir_fault_read, + .write_with_attrs = vtd_mem_ir_fault_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 8, + }, + .valid = { + .min_access_size = 1, + .max_access_size = 8, + }, +}; + +VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, + int devfn, unsigned int pasid) { /* * We can't simply use sid here since the bus number might not be @@ -3445,6 +3614,7 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn) struct vtd_as_key key = { .bus = bus, .devfn = devfn, + .pasid = pasid, }; VTDAddressSpace *vtd_dev_as; char name[128]; @@ -3455,13 +3625,21 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn) new_key->bus = bus; new_key->devfn = devfn; + new_key->pasid = pasid; + + if (pasid == PCI_NO_PASID) { + snprintf(name, sizeof(name), "vtd-%02x.%x", PCI_SLOT(devfn), + PCI_FUNC(devfn)); + } else { + snprintf(name, sizeof(name), "vtd-%02x.%x-pasid-%x", PCI_SLOT(devfn), + PCI_FUNC(devfn), pasid); + } - snprintf(name, sizeof(name), "vtd-%02x.%x", PCI_SLOT(devfn), - PCI_FUNC(devfn)); vtd_dev_as = g_new0(VTDAddressSpace, 1); vtd_dev_as->bus = bus; vtd_dev_as->devfn = (uint8_t)devfn; + vtd_dev_as->pasid = pasid; vtd_dev_as->iommu_state = s; vtd_dev_as->context_cache_entry.context_cache_gen = 0; vtd_dev_as->iova_tree = iova_tree_new(); @@ -3502,6 +3680,24 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn) VTD_INTERRUPT_ADDR_FIRST, &vtd_dev_as->iommu_ir, 1); + /* + * This region is used for catching fault to access interrupt + * range via passthrough + PASID. See also + * vtd_switch_address_space(). We can't use alias since we + * need to know the sid which is valid for MSI who uses + * bus_master_as (see msi_send_message()). + */ + memory_region_init_io(&vtd_dev_as->iommu_ir_fault, OBJECT(s), + &vtd_mem_ir_fault_ops, vtd_dev_as, "vtd-no-ir", + VTD_INTERRUPT_ADDR_SIZE); + /* + * Hook to root since when PT is enabled vtd_dev_as->iommu + * will be disabled. + */ + memory_region_add_subregion_overlap(MEMORY_REGION(&vtd_dev_as->root), + VTD_INTERRUPT_ADDR_FIRST, + &vtd_dev_as->iommu_ir_fault, 2); + /* * Hook both the containers under the root container, we * switch between DMAR & noDMAR by enable/disable @@ -3622,7 +3818,7 @@ static void vtd_iommu_replay(IOMMUMemoryRegion *iommu_mr, IOMMUNotifier *n) "legacy mode", bus_n, PCI_SLOT(vtd_as->devfn), PCI_FUNC(vtd_as->devfn), - vtd_get_domain_id(s, &ce), + vtd_get_domain_id(s, &ce, vtd_as->pasid), ce.hi, ce.lo); if (vtd_as_has_map_notifier(vtd_as)) { /* This is required only for MAP typed notifiers */ @@ -3632,10 +3828,10 @@ static void vtd_iommu_replay(IOMMUMemoryRegion *iommu_mr, IOMMUNotifier *n) .notify_unmap = false, .aw = s->aw_bits, .as = vtd_as, - .domain_id = vtd_get_domain_id(s, &ce), + .domain_id = vtd_get_domain_id(s, &ce, vtd_as->pasid), }; - vtd_page_walk(s, &ce, 0, ~0ULL, &info); + vtd_page_walk(s, &ce, 0, ~0ULL, &info, vtd_as->pasid); } } else { trace_vtd_replay_ce_invalid(bus_n, PCI_SLOT(vtd_as->devfn), @@ -3735,6 +3931,10 @@ static void vtd_init(IntelIOMMUState *s) s->ecap |= VTD_ECAP_SC; } + if (s->pasid) { + s->ecap |= VTD_ECAP_PASID; + } + vtd_reset_caches(s); /* Define registers with default values and bit semantics */ @@ -3808,7 +4008,7 @@ static AddressSpace *vtd_host_dma_iommu(PCIBus *bus, void *opaque, int devfn) assert(0 <= devfn && devfn < PCI_DEVFN_MAX); - vtd_as = vtd_find_add_as(s, bus, devfn); + vtd_as = vtd_find_add_as(s, bus, devfn, PCI_NO_PASID); return &vtd_as->as; } @@ -3851,6 +4051,11 @@ static bool vtd_decide_config(IntelIOMMUState *s, Error **errp) return false; } + if (s->pasid && !s->scalable_mode) { + error_setg(errp, "Need to set scalable mode for PASID"); + return false; + } + return true; } @@ -3887,6 +4092,17 @@ static void vtd_realize(DeviceState *dev, Error **errp) X86MachineState *x86ms = X86_MACHINE(ms); PCIBus *bus = pcms->bus; IntelIOMMUState *s = INTEL_IOMMU_DEVICE(dev); + X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(s); + + if (s->pasid && x86_iommu->dt_supported) { + /* + * PASID-based-Device-TLB Invalidate Descriptor is not + * implemented and it requires support from vhost layer which + * needs to be implemented in the future. + */ + error_setg(errp, "PASID based device IOTLB is not supported"); + return; + } if (!vtd_decide_config(s, errp)) { return; @@ -3913,7 +4129,7 @@ static void vtd_realize(DeviceState *dev, Error **errp) sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->csrmem); /* No corresponding destroy */ - s->iotlb = g_hash_table_new_full(vtd_uint64_hash, vtd_uint64_equal, + s->iotlb = g_hash_table_new_full(vtd_iotlb_hash, vtd_iotlb_equal, g_free, g_free); s->vtd_address_spaces = g_hash_table_new_full(vtd_as_hash, vtd_as_equal, g_free, g_free); diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h index 930ce61feb..f090e61e11 100644 --- a/hw/i386/intel_iommu_internal.h +++ b/hw/i386/intel_iommu_internal.h @@ -114,8 +114,9 @@ VTD_INTERRUPT_ADDR_FIRST + 1) /* The shift of source_id in the key of IOTLB hash table */ -#define VTD_IOTLB_SID_SHIFT 36 -#define VTD_IOTLB_LVL_SHIFT 52 +#define VTD_IOTLB_SID_SHIFT 20 +#define VTD_IOTLB_LVL_SHIFT 28 +#define VTD_IOTLB_PASID_SHIFT 30 #define VTD_IOTLB_MAX_SIZE 1024 /* Max size of the hash table */ /* IOTLB_REG */ @@ -191,6 +192,7 @@ #define VTD_ECAP_SC (1ULL << 7) #define VTD_ECAP_MHMV (15ULL << 20) #define VTD_ECAP_SRS (1ULL << 31) +#define VTD_ECAP_PASID (1ULL << 40) #define VTD_ECAP_SMTS (1ULL << 43) #define VTD_ECAP_SLTS (1ULL << 46) @@ -211,6 +213,8 @@ #define VTD_CAP_DRAIN_READ (1ULL << 55) #define VTD_CAP_DRAIN (VTD_CAP_DRAIN_READ | VTD_CAP_DRAIN_WRITE) #define VTD_CAP_CM (1ULL << 7) +#define VTD_PASID_ID_SHIFT 20 +#define VTD_PASID_ID_MASK ((1ULL << VTD_PASID_ID_SHIFT) - 1) /* Supported Adjusted Guest Address Widths */ #define VTD_CAP_SAGAW_SHIFT 8 @@ -262,6 +266,8 @@ #define VTD_FRCD_SID(val) ((val) & VTD_FRCD_SID_MASK) /* For the low 64-bit of 128-bit */ #define VTD_FRCD_FI(val) ((val) & ~0xfffULL) +#define VTD_FRCD_PV(val) (((val) & 0xffffULL) << 40) +#define VTD_FRCD_PP(val) (((val) & 0x1) << 31) /* DMA Remapping Fault Conditions */ typedef enum VTDFaultReason { @@ -379,6 +385,11 @@ typedef union VTDInvDesc VTDInvDesc; #define VTD_INV_DESC_IOTLB_AM(val) ((val) & 0x3fULL) #define VTD_INV_DESC_IOTLB_RSVD_LO 0xffffffff0000ff00ULL #define VTD_INV_DESC_IOTLB_RSVD_HI 0xf80ULL +#define VTD_INV_DESC_IOTLB_PASID_PASID (2ULL << 4) +#define VTD_INV_DESC_IOTLB_PASID_PAGE (3ULL << 4) +#define VTD_INV_DESC_IOTLB_PASID(val) (((val) >> 32) & VTD_PASID_ID_MASK) +#define VTD_INV_DESC_IOTLB_PASID_RSVD_LO 0xfff00000000001c0ULL +#define VTD_INV_DESC_IOTLB_PASID_RSVD_HI 0xf80ULL /* Mask for Device IOTLB Invalidate Descriptor */ #define VTD_INV_DESC_DEVICE_IOTLB_ADDR(val) ((val) & 0xfffffffffffff000ULL) @@ -413,6 +424,7 @@ typedef union VTDInvDesc VTDInvDesc; /* Information about page-selective IOTLB invalidate */ struct VTDIOTLBPageInvInfo { uint16_t domain_id; + uint32_t pasid; uint64_t addr; uint8_t mask; }; diff --git a/hw/i386/trace-events b/hw/i386/trace-events index e49814dd64..04fd71bfc4 100644 --- a/hw/i386/trace-events +++ b/hw/i386/trace-events @@ -12,6 +12,8 @@ vtd_inv_desc_cc_devices(uint16_t sid, uint16_t fmask) "context invalidate device vtd_inv_desc_iotlb_global(void) "iotlb invalidate global" vtd_inv_desc_iotlb_domain(uint16_t domain) "iotlb invalidate whole domain 0x%"PRIx16 vtd_inv_desc_iotlb_pages(uint16_t domain, uint64_t addr, uint8_t mask) "iotlb invalidate domain 0x%"PRIx16" addr 0x%"PRIx64" mask 0x%"PRIx8 +vtd_inv_desc_iotlb_pasid_pages(uint16_t domain, uint64_t addr, uint8_t mask, uint32_t pasid) "iotlb invalidate domain 0x%"PRIx16" addr 0x%"PRIx64" mask 0x%"PRIx8" pasid 0x%"PRIx32 +vtd_inv_desc_iotlb_pasid(uint16_t domain, uint32_t pasid) "iotlb invalidate domain 0x%"PRIx16" pasid 0x%"PRIx32 vtd_inv_desc_wait_sw(uint64_t addr, uint32_t data) "wait invalidate status write addr 0x%"PRIx64" data 0x%"PRIx32 vtd_inv_desc_wait_irq(const char *msg) "%s" vtd_inv_desc_wait_write_fail(uint64_t hi, uint64_t lo) "write fail for wait desc hi 0x%"PRIx64" lo 0x%"PRIx64 diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h index e49fff2a6c..46d973e629 100644 --- a/include/hw/i386/intel_iommu.h +++ b/include/hw/i386/intel_iommu.h @@ -97,11 +97,13 @@ struct VTDPASIDEntry { struct VTDAddressSpace { PCIBus *bus; uint8_t devfn; + uint32_t pasid; AddressSpace as; IOMMUMemoryRegion iommu; MemoryRegion root; /* The root container of the device */ MemoryRegion nodmar; /* The alias of shared nodmar MR */ MemoryRegion iommu_ir; /* Interrupt region: 0xfeeXXXXX */ + MemoryRegion iommu_ir_fault; /* Interrupt region for catching fault */ IntelIOMMUState *iommu_state; VTDContextCacheEntry context_cache_entry; QLIST_ENTRY(VTDAddressSpace) next; @@ -113,6 +115,7 @@ struct VTDAddressSpace { struct VTDIOTLBEntry { uint64_t gfn; uint16_t domain_id; + uint32_t pasid; uint64_t slpte; uint64_t mask; uint8_t access_flags; @@ -261,6 +264,7 @@ struct IntelIOMMUState { uint8_t aw_bits; /* Host/IOVA address width (in bits) */ bool dma_drain; /* Whether DMA r/w draining enabled */ bool dma_translation; /* Whether DMA translation supported */ + bool pasid; /* Whether to support PASID */ /* * Protects IOMMU states in general. Currently it protects the @@ -272,6 +276,7 @@ struct IntelIOMMUState { /* Find the VTD Address space associated with the given bus pointer, * create a new one if none exists */ -VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn); +VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, + int devfn, unsigned int pasid); #endif diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h index eb94e7e85c..5653175957 100644 --- a/include/hw/pci/pci_bus.h +++ b/include/hw/pci/pci_bus.h @@ -28,6 +28,8 @@ enum PCIBusFlags { PCI_BUS_CXL = 0x0004, }; +#define PCI_NO_PASID UINT32_MAX + struct PCIBus { BusState qbus; enum PCIBusFlags flags; From 8b67fe00652b2640f3f841a7b102f6bcf82483a3 Mon Sep 17 00:00:00 2001 From: Yajun Wu Date: Mon, 17 Oct 2022 14:44:51 +0800 Subject: [PATCH 656/705] vhost: Change the sequence of device start This patch is part of adding vhost-user vhost_dev_start support. The motivation is to improve backend configuration speed and reduce live migration VM downtime. Moving the device start routines after finishing all the necessary device and VQ configuration, further aligning to the virtio specification for "device initialization sequence". Following patch will add vhost-user vhost_dev_start support. Signed-off-by: Yajun Wu Acked-by: Parav Pandit Message-Id: <20221017064452.1226514-2-yajunw@nvidia.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/block/vhost-user-blk.c | 18 +++++++++++------- hw/net/vhost_net.c | 11 +++++------ 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c index 13bf5cc47a..28409c90f7 100644 --- a/hw/block/vhost-user-blk.c +++ b/hw/block/vhost-user-blk.c @@ -168,13 +168,6 @@ static int vhost_user_blk_start(VirtIODevice *vdev, Error **errp) goto err_guest_notifiers; } - ret = vhost_dev_start(&s->dev, vdev); - if (ret < 0) { - error_setg_errno(errp, -ret, "Error starting vhost"); - goto err_guest_notifiers; - } - s->started_vu = true; - /* guest_notifier_mask/pending not used yet, so just unmask * everything here. virtio-pci will do the right thing by * enabling/disabling irqfd. @@ -183,9 +176,20 @@ static int vhost_user_blk_start(VirtIODevice *vdev, Error **errp) vhost_virtqueue_mask(&s->dev, vdev, i, false); } + s->dev.vq_index_end = s->dev.nvqs; + ret = vhost_dev_start(&s->dev, vdev); + if (ret < 0) { + error_setg_errno(errp, -ret, "Error starting vhost"); + goto err_guest_notifiers; + } + s->started_vu = true; + return ret; err_guest_notifiers: + for (i = 0; i < s->dev.nvqs; i++) { + vhost_virtqueue_mask(&s->dev, vdev, i, true); + } k->set_guest_notifiers(qbus->parent, s->dev.nvqs, false); err_host_notifiers: vhost_dev_disable_notifiers(&s->dev, vdev); diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c index 53b2fac4f6..feda448878 100644 --- a/hw/net/vhost_net.c +++ b/hw/net/vhost_net.c @@ -389,21 +389,20 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs, } else { peer = qemu_get_peer(ncs, n->max_queue_pairs); } - r = vhost_net_start_one(get_vhost_net(peer), dev); - - if (r < 0) { - goto err_start; - } if (peer->vring_enable) { /* restore vring enable state */ r = vhost_set_vring_enable(peer, peer->vring_enable); if (r < 0) { - vhost_net_stop_one(get_vhost_net(peer), dev); goto err_start; } } + + r = vhost_net_start_one(get_vhost_net(peer), dev); + if (r < 0) { + goto err_start; + } } return 0; From 923b8921d210763359e96246a58658ac0db6c645 Mon Sep 17 00:00:00 2001 From: Yajun Wu Date: Mon, 17 Oct 2022 14:44:52 +0800 Subject: [PATCH 657/705] vhost-user: Support vhost_dev_start The motivation of adding vhost-user vhost_dev_start support is to improve backend configuration speed and reduce live migration VM downtime. Today VQ configuration is issued one by one. For virtio net with multi-queue support, backend needs to update RSS (Receive side scaling) on every rx queue enable. Updating RSS is time-consuming (typical time like 7ms). Implement already defined vhost status and message in the vhost specification [1]. (a) VHOST_USER_PROTOCOL_F_STATUS (b) VHOST_USER_SET_STATUS (c) VHOST_USER_GET_STATUS Send message VHOST_USER_SET_STATUS with VIRTIO_CONFIG_S_DRIVER_OK for device start and reset(0) for device stop. On reception of the DRIVER_OK message, backend can apply the needed setting only once (instead of incremental) and also utilize parallelism on enabling queues. This improves QEMU's live migration downtime with vhost user backend implementation by great margin, specially for the large number of VQs of 64 from 800 msec to 250 msec. [1] https://qemu-project.gitlab.io/qemu/interop/vhost-user.html Signed-off-by: Yajun Wu Acked-by: Parav Pandit Message-Id: <20221017064452.1226514-3-yajunw@nvidia.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/virtio/vhost-user.c | 74 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c index d256ce589b..abe23d4ebe 100644 --- a/hw/virtio/vhost-user.c +++ b/hw/virtio/vhost-user.c @@ -81,6 +81,7 @@ enum VhostUserProtocolFeature { VHOST_USER_PROTOCOL_F_RESET_DEVICE = 13, /* Feature 14 reserved for VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS. */ VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS = 15, + VHOST_USER_PROTOCOL_F_STATUS = 16, VHOST_USER_PROTOCOL_F_MAX }; @@ -126,6 +127,8 @@ typedef enum VhostUserRequest { VHOST_USER_GET_MAX_MEM_SLOTS = 36, VHOST_USER_ADD_MEM_REG = 37, VHOST_USER_REM_MEM_REG = 38, + VHOST_USER_SET_STATUS = 39, + VHOST_USER_GET_STATUS = 40, VHOST_USER_MAX } VhostUserRequest; @@ -1452,6 +1455,43 @@ static int vhost_user_set_u64(struct vhost_dev *dev, int request, uint64_t u64, return 0; } +static int vhost_user_set_status(struct vhost_dev *dev, uint8_t status) +{ + return vhost_user_set_u64(dev, VHOST_USER_SET_STATUS, status, false); +} + +static int vhost_user_get_status(struct vhost_dev *dev, uint8_t *status) +{ + uint64_t value; + int ret; + + ret = vhost_user_get_u64(dev, VHOST_USER_GET_STATUS, &value); + if (ret < 0) { + return ret; + } + *status = value; + + return 0; +} + +static int vhost_user_add_status(struct vhost_dev *dev, uint8_t status) +{ + uint8_t s; + int ret; + + ret = vhost_user_get_status(dev, &s); + if (ret < 0) { + return ret; + } + + if ((s & status) == status) { + return 0; + } + s |= status; + + return vhost_user_set_status(dev, s); +} + static int vhost_user_set_features(struct vhost_dev *dev, uint64_t features) { @@ -1460,6 +1500,7 @@ static int vhost_user_set_features(struct vhost_dev *dev, * backend is actually logging changes */ bool log_enabled = features & (0x1ULL << VHOST_F_LOG_ALL); + int ret; /* * We need to include any extra backend only feature bits that @@ -1467,9 +1508,18 @@ static int vhost_user_set_features(struct vhost_dev *dev, * VHOST_USER_F_PROTOCOL_FEATURES bit for enabling protocol * features. */ - return vhost_user_set_u64(dev, VHOST_USER_SET_FEATURES, + ret = vhost_user_set_u64(dev, VHOST_USER_SET_FEATURES, features | dev->backend_features, log_enabled); + + if (virtio_has_feature(dev->protocol_features, + VHOST_USER_PROTOCOL_F_STATUS)) { + if (!ret) { + return vhost_user_add_status(dev, VIRTIO_CONFIG_S_FEATURES_OK); + } + } + + return ret; } static int vhost_user_set_protocol_features(struct vhost_dev *dev, @@ -2620,6 +2670,27 @@ void vhost_user_cleanup(VhostUserState *user) user->chr = NULL; } +static int vhost_user_dev_start(struct vhost_dev *dev, bool started) +{ + if (!virtio_has_feature(dev->protocol_features, + VHOST_USER_PROTOCOL_F_STATUS)) { + return 0; + } + + /* Set device status only for last queue pair */ + if (dev->vq_index + dev->nvqs != dev->vq_index_end) { + return 0; + } + + if (started) { + return vhost_user_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE | + VIRTIO_CONFIG_S_DRIVER | + VIRTIO_CONFIG_S_DRIVER_OK); + } else { + return vhost_user_set_status(dev, 0); + } +} + const VhostOps user_ops = { .backend_type = VHOST_BACKEND_TYPE_USER, .vhost_backend_init = vhost_user_backend_init, @@ -2654,4 +2725,5 @@ const VhostOps user_ops = { .vhost_backend_mem_section_filter = vhost_user_mem_section_filter, .vhost_get_inflight_fd = vhost_user_get_inflight_fd, .vhost_set_inflight_fd = vhost_user_set_inflight_fd, + .vhost_dev_start = vhost_user_dev_start, }; From 05e27d74c7dc5318367521f020bf0d4a32228dcc Mon Sep 17 00:00:00 2001 From: Julia Suvorova Date: Tue, 11 Oct 2022 13:17:27 +0200 Subject: [PATCH 658/705] hw/smbios: add core_count2 to smbios table type 4 In order to use the increased number of cpus, we need to bring smbios tables in line with the SMBIOS 3.0 specification. This allows us to introduce core_count2 which acts as a duplicate of core_count if we have fewer cores than 256, and contains the actual core number per socket if we have more. core_enabled2 and thread_count2 fields work the same way. Signed-off-by: Julia Suvorova Reviewed-by: Igor Mammedov Message-Id: <20220731162141.178443-2-jusual@redhat.com> Message-Id: <20221011111731.101412-2-jusual@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/smbios/smbios.c | 19 ++++++++++++++++--- hw/smbios/smbios_build.h | 9 +++++++-- include/hw/firmware/smbios.h | 12 ++++++++++++ 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c index 51437ca09f..b4243de735 100644 --- a/hw/smbios/smbios.c +++ b/hw/smbios/smbios.c @@ -711,8 +711,14 @@ static void smbios_build_type_3_table(void) static void smbios_build_type_4_table(MachineState *ms, unsigned instance) { char sock_str[128]; + size_t tbl_len = SMBIOS_TYPE_4_LEN_V28; - SMBIOS_BUILD_TABLE_PRE(4, T4_BASE + instance, true); /* required */ + if (smbios_ep_type == SMBIOS_ENTRY_POINT_TYPE_64) { + tbl_len = SMBIOS_TYPE_4_LEN_V30; + } + + SMBIOS_BUILD_TABLE_PRE_SIZE(4, T4_BASE + instance, + true, tbl_len); /* required */ snprintf(sock_str, sizeof(sock_str), "%s%2x", type4.sock_pfx, instance); SMBIOS_TABLE_SET_STR(4, socket_designation_str, sock_str); @@ -739,8 +745,15 @@ static void smbios_build_type_4_table(MachineState *ms, unsigned instance) SMBIOS_TABLE_SET_STR(4, serial_number_str, type4.serial); SMBIOS_TABLE_SET_STR(4, asset_tag_number_str, type4.asset); SMBIOS_TABLE_SET_STR(4, part_number_str, type4.part); - t->core_count = t->core_enabled = ms->smp.cores; - t->thread_count = ms->smp.threads; + + t->core_count = (ms->smp.cores > 255) ? 0xFF : ms->smp.cores; + t->core_enabled = t->core_count; + + t->core_count2 = t->core_enabled2 = cpu_to_le16(ms->smp.cores); + + t->thread_count = (ms->smp.threads > 255) ? 0xFF : ms->smp.threads; + t->thread_count2 = cpu_to_le16(ms->smp.threads); + t->processor_characteristics = cpu_to_le16(0x02); /* Unknown */ t->processor_family2 = cpu_to_le16(0x01); /* Other */ diff --git a/hw/smbios/smbios_build.h b/hw/smbios/smbios_build.h index 56b5a1e3f3..351660024e 100644 --- a/hw/smbios/smbios_build.h +++ b/hw/smbios/smbios_build.h @@ -27,6 +27,11 @@ extern unsigned smbios_table_max; extern unsigned smbios_table_cnt; #define SMBIOS_BUILD_TABLE_PRE(tbl_type, tbl_handle, tbl_required) \ + SMBIOS_BUILD_TABLE_PRE_SIZE(tbl_type, tbl_handle, tbl_required, \ + sizeof(struct smbios_type_##tbl_type))\ + +#define SMBIOS_BUILD_TABLE_PRE_SIZE(tbl_type, tbl_handle, \ + tbl_required, tbl_len) \ struct smbios_type_##tbl_type *t; \ size_t t_off; /* table offset into smbios_tables */ \ int str_index = 0; \ @@ -39,12 +44,12 @@ extern unsigned smbios_table_cnt; /* use offset of table t within smbios_tables */ \ /* (pointer must be updated after each realloc) */ \ t_off = smbios_tables_len; \ - smbios_tables_len += sizeof(*t); \ + smbios_tables_len += tbl_len; \ smbios_tables = g_realloc(smbios_tables, smbios_tables_len); \ t = (struct smbios_type_##tbl_type *)(smbios_tables + t_off); \ \ t->header.type = tbl_type; \ - t->header.length = sizeof(*t); \ + t->header.length = tbl_len; \ t->header.handle = cpu_to_le16(tbl_handle); \ } while (0) diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h index e7d386f7c8..7f3259a630 100644 --- a/include/hw/firmware/smbios.h +++ b/include/hw/firmware/smbios.h @@ -18,6 +18,8 @@ #define SMBIOS_MAX_TYPE 127 +#define offsetofend(TYPE, MEMBER) \ + (offsetof(TYPE, MEMBER) + sizeof_field(TYPE, MEMBER)) /* memory area description, used by type 19 table */ struct smbios_phys_mem_area { @@ -187,8 +189,18 @@ struct smbios_type_4 { uint8_t thread_count; uint16_t processor_characteristics; uint16_t processor_family2; + /* SMBIOS spec 3.0.0, Table 21 */ + uint16_t core_count2; + uint16_t core_enabled2; + uint16_t thread_count2; } QEMU_PACKED; +typedef enum smbios_type_4_len_ver { + SMBIOS_TYPE_4_LEN_V28 = offsetofend(struct smbios_type_4, + processor_family2), + SMBIOS_TYPE_4_LEN_V30 = offsetofend(struct smbios_type_4, thread_count2), +} smbios_type_4_len_ver; + /* SMBIOS type 8 - Port Connector Information */ struct smbios_type_8 { struct smbios_structure_header header; From 33bff4a85a2e4ad94899ecb15b6a91c8b64a6dcf Mon Sep 17 00:00:00 2001 From: Julia Suvorova Date: Tue, 11 Oct 2022 13:17:28 +0200 Subject: [PATCH 659/705] bios-tables-test: teach test to use smbios 3.0 tables Introduce the 64-bit entry point. Since we no longer have a total number of structures, stop checking for the new ones at the EOF structure (type 127). Signed-off-by: Julia Suvorova Reviewed-by: Igor Mammedov Message-Id: <20220731162141.178443-3-jusual@redhat.com> Message-Id: <20221011111731.101412-3-jusual@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- tests/qtest/bios-tables-test.c | 100 +++++++++++++++++++++++++-------- 1 file changed, 76 insertions(+), 24 deletions(-) diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c index e805b3efec..aa91b0fca5 100644 --- a/tests/qtest/bios-tables-test.c +++ b/tests/qtest/bios-tables-test.c @@ -88,8 +88,8 @@ typedef struct { uint64_t rsdp_addr; uint8_t rsdp_table[36 /* ACPI 2.0+ RSDP size */]; GArray *tables; - uint32_t smbios_ep_addr; - struct smbios_21_entry_point smbios_ep_table; + uint64_t smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE__MAX]; + SmbiosEntryPoint smbios_ep_table; uint16_t smbios_cpu_max_speed; uint16_t smbios_cpu_curr_speed; uint8_t *required_struct_types; @@ -533,10 +533,9 @@ static void test_acpi_asl(test_data *data) free_test_data(&exp_data); } -static bool smbios_ep_table_ok(test_data *data) +static bool smbios_ep2_table_ok(test_data *data, uint32_t addr) { - struct smbios_21_entry_point *ep_table = &data->smbios_ep_table; - uint32_t addr = data->smbios_ep_addr; + struct smbios_21_entry_point *ep_table = &data->smbios_ep_table.ep21; qtest_memread(data->qts, addr, ep_table, sizeof(*ep_table)); if (memcmp(ep_table->anchor_string, "_SM_", 4)) { @@ -559,13 +558,29 @@ static bool smbios_ep_table_ok(test_data *data) return true; } -static void test_smbios_entry_point(test_data *data) +static bool smbios_ep3_table_ok(test_data *data, uint64_t addr) +{ + struct smbios_30_entry_point *ep_table = &data->smbios_ep_table.ep30; + + qtest_memread(data->qts, addr, ep_table, sizeof(*ep_table)); + if (memcmp(ep_table->anchor_string, "_SM3_", 5)) { + return false; + } + + if (acpi_calc_checksum((uint8_t *)ep_table, sizeof *ep_table)) { + return false; + } + + return true; +} + +static SmbiosEntryPointType test_smbios_entry_point(test_data *data) { uint32_t off; /* find smbios entry point structure */ for (off = 0xf0000; off < 0x100000; off += 0x10) { - uint8_t sig[] = "_SM_"; + uint8_t sig[] = "_SM_", sig3[] = "_SM3_"; int i; for (i = 0; i < sizeof sig - 1; ++i) { @@ -574,14 +589,30 @@ static void test_smbios_entry_point(test_data *data) if (!memcmp(sig, "_SM_", sizeof sig)) { /* signature match, but is this a valid entry point? */ - data->smbios_ep_addr = off; - if (smbios_ep_table_ok(data)) { + if (smbios_ep2_table_ok(data, off)) { + data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_32] = off; + } + } + + for (i = 0; i < sizeof sig3 - 1; ++i) { + sig3[i] = qtest_readb(data->qts, off + i); + } + + if (!memcmp(sig3, "_SM3_", sizeof sig3)) { + if (smbios_ep3_table_ok(data, off)) { + data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_64] = off; + /* found 64-bit entry point, no need to look for 32-bit one */ break; } } } - g_assert_cmphex(off, <, 0x100000); + /* found at least one entry point */ + g_assert_true(data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_32] || + data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_64]); + + return data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_64] ? + SMBIOS_ENTRY_POINT_TYPE_64 : SMBIOS_ENTRY_POINT_TYPE_32; } static inline bool smbios_single_instance(uint8_t type) @@ -625,16 +656,23 @@ static bool smbios_cpu_test(test_data *data, uint32_t addr) return true; } -static void test_smbios_structs(test_data *data) +static void test_smbios_structs(test_data *data, SmbiosEntryPointType ep_type) { DECLARE_BITMAP(struct_bitmap, SMBIOS_MAX_TYPE+1) = { 0 }; - struct smbios_21_entry_point *ep_table = &data->smbios_ep_table; - uint32_t addr = le32_to_cpu(ep_table->structure_table_address); - int i, len, max_len = 0; + + SmbiosEntryPoint *ep_table = &data->smbios_ep_table; + int i = 0, len, max_len = 0; uint8_t type, prv, crt; + uint64_t addr; + + if (ep_type == SMBIOS_ENTRY_POINT_TYPE_32) { + addr = le32_to_cpu(ep_table->ep21.structure_table_address); + } else { + addr = le64_to_cpu(ep_table->ep30.structure_table_address); + } /* walk the smbios tables */ - for (i = 0; i < le16_to_cpu(ep_table->number_of_structures); i++) { + do { /* grab type and formatted area length from struct header */ type = qtest_readb(data->qts, addr); @@ -660,19 +698,33 @@ static void test_smbios_structs(test_data *data) } /* keep track of max. struct size */ - if (max_len < len) { + if (ep_type == SMBIOS_ENTRY_POINT_TYPE_32 && max_len < len) { max_len = len; - g_assert_cmpuint(max_len, <=, ep_table->max_structure_size); + g_assert_cmpuint(max_len, <=, ep_table->ep21.max_structure_size); } /* start of next structure */ addr += len; - } - /* total table length and max struct size must match entry point values */ - g_assert_cmpuint(le16_to_cpu(ep_table->structure_table_length), ==, - addr - le32_to_cpu(ep_table->structure_table_address)); - g_assert_cmpuint(le16_to_cpu(ep_table->max_structure_size), ==, max_len); + /* + * Until all structures have been scanned (ep21) + * or an EOF structure is found (ep30) + */ + } while (ep_type == SMBIOS_ENTRY_POINT_TYPE_32 ? + ++i < le16_to_cpu(ep_table->ep21.number_of_structures) : + type != 127); + + if (ep_type == SMBIOS_ENTRY_POINT_TYPE_32) { + /* + * Total table length and max struct size + * must match entry point values + */ + g_assert_cmpuint(le16_to_cpu(ep_table->ep21.structure_table_length), ==, + addr - le32_to_cpu(ep_table->ep21.structure_table_address)); + + g_assert_cmpuint(le16_to_cpu(ep_table->ep21.max_structure_size), ==, + max_len); + } /* required struct types must all be present */ for (i = 0; i < data->required_struct_types_len; i++) { @@ -756,8 +808,8 @@ static void test_acpi_one(const char *params, test_data *data) * https://bugs.launchpad.net/qemu/+bug/1821884 */ if (!use_uefi) { - test_smbios_entry_point(data); - test_smbios_structs(data); + SmbiosEntryPointType ep_type = test_smbios_entry_point(data); + test_smbios_structs(data, ep_type); } qtest_quit(data->qts); From 159a0da5b0bd660f8a70bca4e3c2bd4c863eaf1a Mon Sep 17 00:00:00 2001 From: Julia Suvorova Date: Tue, 11 Oct 2022 13:17:29 +0200 Subject: [PATCH 660/705] tests/acpi: allow changes for core_count2 test Signed-off-by: Julia Suvorova Message-Id: <20220731162141.178443-4-jusual@redhat.com> Message-Id: <20221011111731.101412-4-jusual@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Acked-by: Igor Mammedov --- tests/data/acpi/q35/APIC.core-count2 | 0 tests/data/acpi/q35/DSDT.core-count2 | 0 tests/data/acpi/q35/FACP.core-count2 | 0 tests/qtest/bios-tables-test-allowed-diff.h | 3 +++ 4 files changed, 3 insertions(+) create mode 100644 tests/data/acpi/q35/APIC.core-count2 create mode 100644 tests/data/acpi/q35/DSDT.core-count2 create mode 100644 tests/data/acpi/q35/FACP.core-count2 diff --git a/tests/data/acpi/q35/APIC.core-count2 b/tests/data/acpi/q35/APIC.core-count2 new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/data/acpi/q35/DSDT.core-count2 b/tests/data/acpi/q35/DSDT.core-count2 new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/data/acpi/q35/FACP.core-count2 b/tests/data/acpi/q35/FACP.core-count2 new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h index dfb8523c8b..e81dc67a2e 100644 --- a/tests/qtest/bios-tables-test-allowed-diff.h +++ b/tests/qtest/bios-tables-test-allowed-diff.h @@ -1 +1,4 @@ /* List of comma-separated changed AML files to ignore */ +"tests/data/acpi/q35/APIC.core-count2", +"tests/data/acpi/q35/DSDT.core-count2", +"tests/data/acpi/q35/FACP.core-count2", From 2d80b33843c71dbe5c250d712a1ccafafb2b3520 Mon Sep 17 00:00:00 2001 From: Julia Suvorova Date: Tue, 11 Oct 2022 13:17:30 +0200 Subject: [PATCH 661/705] bios-tables-test: add test for number of cores > 255 The new test is run with a large number of cpus and checks if the core_count field in smbios_cpu_test (structure type 4) is correct. Choose q35 as it allows to run with -smp > 255. Signed-off-by: Julia Suvorova Message-Id: <20220731162141.178443-5-jusual@redhat.com> Message-Id: <20221011111731.101412-5-jusual@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Igor Mammedov --- tests/qtest/bios-tables-test.c | 58 ++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c index aa91b0fca5..395d441212 100644 --- a/tests/qtest/bios-tables-test.c +++ b/tests/qtest/bios-tables-test.c @@ -92,6 +92,8 @@ typedef struct { SmbiosEntryPoint smbios_ep_table; uint16_t smbios_cpu_max_speed; uint16_t smbios_cpu_curr_speed; + uint8_t smbios_core_count; + uint16_t smbios_core_count2; uint8_t *required_struct_types; int required_struct_types_len; QTestState *qts; @@ -631,29 +633,42 @@ static inline bool smbios_single_instance(uint8_t type) } } -static bool smbios_cpu_test(test_data *data, uint32_t addr) +static void smbios_cpu_test(test_data *data, uint32_t addr, + SmbiosEntryPointType ep_type) { - uint16_t expect_speed[2]; - uint16_t real; + uint8_t core_count, expected_core_count = data->smbios_core_count; + uint16_t speed, expected_speed[2]; + uint16_t core_count2, expected_core_count2 = data->smbios_core_count2; int offset[2]; int i; /* Check CPU speed for backward compatibility */ offset[0] = offsetof(struct smbios_type_4, max_speed); offset[1] = offsetof(struct smbios_type_4, current_speed); - expect_speed[0] = data->smbios_cpu_max_speed ? : 2000; - expect_speed[1] = data->smbios_cpu_curr_speed ? : 2000; + expected_speed[0] = data->smbios_cpu_max_speed ? : 2000; + expected_speed[1] = data->smbios_cpu_curr_speed ? : 2000; for (i = 0; i < 2; i++) { - real = qtest_readw(data->qts, addr + offset[i]); - if (real != expect_speed[i]) { - fprintf(stderr, "Unexpected SMBIOS CPU speed: real %u expect %u\n", - real, expect_speed[i]); - return false; - } + speed = qtest_readw(data->qts, addr + offset[i]); + g_assert_cmpuint(speed, ==, expected_speed[i]); } - return true; + core_count = qtest_readb(data->qts, + addr + offsetof(struct smbios_type_4, core_count)); + + if (expected_core_count) { + g_assert_cmpuint(core_count, ==, expected_core_count); + } + + if (ep_type == SMBIOS_ENTRY_POINT_TYPE_64) { + core_count2 = qtest_readw(data->qts, + addr + offsetof(struct smbios_type_4, core_count2)); + + /* Core Count has reached its limit, checking Core Count 2 */ + if (expected_core_count == 0xFF && expected_core_count2) { + g_assert_cmpuint(core_count2, ==, expected_core_count2); + } + } } static void test_smbios_structs(test_data *data, SmbiosEntryPointType ep_type) @@ -686,7 +701,7 @@ static void test_smbios_structs(test_data *data, SmbiosEntryPointType ep_type) set_bit(type, struct_bitmap); if (type == 4) { - g_assert(smbios_cpu_test(data, addr)); + smbios_cpu_test(data, addr, ep_type); } /* seek to end of unformatted string area of this struct ("\0\0") */ @@ -908,6 +923,21 @@ static void test_acpi_q35_tcg(void) free_test_data(&data); } +static void test_acpi_q35_tcg_core_count2(void) +{ + test_data data = { + .machine = MACHINE_Q35, + .variant = ".core-count2", + .required_struct_types = base_required_struct_types, + .required_struct_types_len = ARRAY_SIZE(base_required_struct_types), + .smbios_core_count = 0xFF, + .smbios_core_count2 = 275, + }; + + test_acpi_one("-machine smbios-entry-point-type=64 -smp 275", &data); + free_test_data(&data); +} + static void test_acpi_q35_tcg_bridge(void) { test_data data; @@ -1994,6 +2024,8 @@ int main(int argc, char *argv[]) if (has_kvm) { qtest_add_func("acpi/q35/kvm/xapic", test_acpi_q35_kvm_xapic); qtest_add_func("acpi/q35/kvm/dmar", test_acpi_q35_kvm_dmar); + qtest_add_func("acpi/q35/core-count2", + test_acpi_q35_tcg_core_count2); } qtest_add_func("acpi/q35/viot", test_acpi_q35_viot); #ifdef CONFIG_POSIX From b22fbc5bcb6bd2412889f2c48a29c86880a30552 Mon Sep 17 00:00:00 2001 From: Julia Suvorova Date: Tue, 11 Oct 2022 13:17:31 +0200 Subject: [PATCH 662/705] tests/acpi: update tables for new core count test Changes in the tables (for 275 cores): FACP: + Use APIC Cluster Model (V4) : 1 APIC: +[02Ch 0044 1] Subtable Type : 00 [Processor Local APIC] +[02Dh 0045 1] Length : 08 +[02Eh 0046 1] Processor ID : 00 +[02Fh 0047 1] Local Apic ID : 00 +[030h 0048 4] Flags (decoded below) : 00000001 + Processor Enabled : 1 ... + +[81Ch 2076 1] Subtable Type : 00 [Processor Local APIC] +[81Dh 2077 1] Length : 08 +[81Eh 2078 1] Processor ID : FE +[81Fh 2079 1] Local Apic ID : FE +[820h 2080 4] Flags (decoded below) : 00000001 + Processor Enabled : 1 + Runtime Online Capable : 0 + +[824h 2084 1] Subtable Type : 09 [Processor Local x2APIC] +[825h 2085 1] Length : 10 +[826h 2086 2] Reserved : 0000 +[828h 2088 4] Processor x2Apic ID : 000000FF +[82Ch 2092 4] Flags (decoded below) : 00000001 + Processor Enabled : 1 +[830h 2096 4] Processor UID : 000000FF ... DSDT: + Processor (C001, 0x01, 0x00000000, 0x00) + { + Method (_STA, 0, Serialized) // _STA: Status + { + Return (CSTA (One)) + } + + Name (_MAT, Buffer (0x08) // _MAT: Multiple APIC Table Entry + { + 0x00, 0x08, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00 // ........ + }) + Method (_EJ0, 1, NotSerialized) // _EJx: Eject Device, x=0-9 + { + CEJ0 (One) + } + + Method (_OST, 3, Serialized) // _OST: OSPM Status Indication + { + COST (One, Arg0, Arg1, Arg2) + } + } ... + Processor (C0FE, 0xFE, 0x00000000, 0x00) + { + Method (_STA, 0, Serialized) // _STA: Status + { + Return (CSTA (0xFE)) + } + + Name (_MAT, Buffer (0x08) // _MAT: Multiple APIC Table Entry + { + 0x00, 0x08, 0xFE, 0xFE, 0x01, 0x00, 0x00, 0x00 // ........ + }) + Method (_EJ0, 1, NotSerialized) // _EJx: Eject Device, x=0-9 + { + CEJ0 (0xFE) + } + + Method (_OST, 3, Serialized) // _OST: OSPM Status Indication + { + COST (0xFE, Arg0, Arg1, Arg2) + } + } + + Device (C0FF) + { + Name (_HID, "ACPI0007" /* Processor Device */) // _HID: Hardware ID + Name (_UID, 0xFF) // _UID: Unique ID + Method (_STA, 0, Serialized) // _STA: Status + { + Return (CSTA (0xFF)) + } + + Name (_MAT, Buffer (0x10) // _MAT: Multiple APIC Table Entry + { + /* 0000 */ 0x09, 0x10, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, // ........ + /* 0008 */ 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00 // ........ + }) + Method (_EJ0, 1, NotSerialized) // _EJx: Eject Device, x=0-9 + { + CEJ0 (0xFF) + } + + Method (_OST, 3, Serialized) // _OST: OSPM Status Indication + { + COST (0xFF, Arg0, Arg1, Arg2) + } + } + ... Signed-off-by: Julia Suvorova Message-Id: <20220731162141.178443-6-jusual@redhat.com> Message-Id: <20221011111731.101412-6-jusual@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- tests/data/acpi/q35/APIC.core-count2 | Bin 0 -> 2478 bytes tests/data/acpi/q35/DSDT.core-count2 | Bin 0 -> 32552 bytes tests/data/acpi/q35/FACP.core-count2 | Bin 0 -> 244 bytes tests/qtest/bios-tables-test-allowed-diff.h | 3 --- 4 files changed, 3 deletions(-) diff --git a/tests/data/acpi/q35/APIC.core-count2 b/tests/data/acpi/q35/APIC.core-count2 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..a255082ef5bc39f0d92d3e372b91f09dd6d0d9a1 100644 GIT binary patch literal 2478 zcmXZeWl$AS7=Youz=a#M-K}6ZwgLuNAQ;$~*xjvQcY@uCVs{~Sf`WpLVt2Rbe!ORA z_B`J^b9R56*&pj2=M2p(=#;b`y@>U1KQZ2 ztu5Nwq0xx;_UPb%CKH;?XtAKxijI!xf-7uzGc@Q3Gq% z#9Fnmc5SRv2fe+~#|M4+PE2*{()H?L{rcFT0s8r&zdtr?h>aRyuWjcwXs+qT%Q9ky?e9Xepgju;w>ojPIX&e)|3 zcI}GYx?%V37#4;-dSK6<*sB-z?u~u=VBfyjuOIgBj{^qaz=1eu5Dp%ULx$kcp*U<9 z4j+yqM&QViIBFD*9*twh;MlP^ZXAvuj}s=~#ECd*5{8FkL5Yu4b}wYY8_u3wKEHsHpMxM>q^-i%we;MT3UZ5u{MiV+Y2>;Le@6 zYZva`jeGXs-o3bQAMW3e2M*xDgLvo=9zKjmj^NRwcZnq0$#t4H*R2JA|@r_&6{}Z z7A7ZSN($b-jd$+g-Me`29^Su?4<6vdhnSj*j~?OU$C#FePoCh@r}*p{K7WocUf|1@ z`05qDevNP5;M=$O?j62=j~_nZ$B+2w6Mp`TU%ueiulVg7e*ca?e&Ela`0E$`{*8bB z;NQQPo-UeQHSM3S%%ZeJ#vXl>ElNA87Nwn3i_*@jMQIn+qO_}OQQA$lDDAE~Lr49*wAgf6Z7ljNgG@%F cu9Hk={TGbMqHkcbS~Dh#{`5cn(qE|k2lzA_5C8xG literal 0 HcmV?d00001 diff --git a/tests/data/acpi/q35/DSDT.core-count2 b/tests/data/acpi/q35/DSDT.core-count2 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..ca309f6569f1f4016cf7e67117b208d57fbc7365 100644 GIT binary patch literal 32552 zcmb8&cYKpo7YFbsooSl3X(=0_g1ASzTX$w#pry10)S_(xmEnj2Dk2I+5phDrJqp&n z_g36napT^5Z=Ag6JkL$;?>V=AKCk@IoRi-BJ?ExvZu8`!Pqa1Kw(SX)^;J&Sp|{khWK0jqoLPdoPo_%n%4zGto9 zxr?dNzPat)HPMz(#O^V#xv4oA36@e{k(SoNQN9r;54J2nKREpFrp=o-Kj?&3V4)S5 zP`ooQlb6`Oq&d>s=E+^}_j%iw1~`e({gX@RL$suQNo#BzJ*ZFmeHrwqauNv#W8>%( z;ikqGPwob18Yhu()8xjI=7#7#CGDQ@gvfZScx-bdHZHAw3}>4+CuZ@8#6r((i;ebe z`0hTdc!v

2DNU3I5Qj#&#BmbDE>Ajd{J%te!bmqA=ZKbtbH?-eIeq2Yy5KQ=ha} z9^1HT@RyB4ABi;fb@pbjne9vK>r8NwWh)M`Ec)QFrqh(gJ=3k8>3(`_Hd~9kJY9>s z7J7WyR#&2HMWc$?MZqH11kZ$qJxYn8DT4#=Xos{A_eXe!-T_L&nde?7rMS*~*E;iE>&$nr zlTut~foq)wu5}i;*GVa^GvHchz_reRd!3ZxItyLvEOf22(7jGdah*l3br!kSS>#?P zrMS)ku5}J@t#g2Tos{A_i(Tt1cCEA6y-rGTodaF#9Ozo-K=(Q+#dQvHt#goTorB!# zq!ial+nDp5Wj`wocCB-;d!3ZxI)}K{ImETjA?|fjit8L|&kU(&!lCxeuzIo^>dcJj zlxIfO*kP`j!(20mxo1*}Gl#oo4tLEQ?w(00&K%*IIl?t_gnK5XICBfv%q?6qw{Xv- z6ladKXC|NHN7^%!&+#LjnaL+^N_l2-CmH3cIm%UYl)EOSPE9Xupdr{m>slMAw7r>n zD5k<{1Eqw@I!QVu$)dD@I^*nbB9FzhlKpw8s53ORfl``W8f~D?*yIKZLwN&rhNd=9 zN~xRV2I`De8P_B=xnuIo|?1xhwJpN@;SPw1GNf?U}TJ!cg8oouPJ3-asi$u9G%UXRJMwHc%MK8>lnXp2-_1 zrO9>D2I`EpXVL}=LwN&rhT1cE1Ens8XYvM0X>y&kfjVRD znY4kzP~JeDq4rGPKq*bGlQvLitUZ%9P#DS^s58`_$r~u8$#v2O>WsB#(gq4cc>{HZ z+B10rr8K!t+CZJL_DtG9VJL5)&QNCr4b&NG&*Tl1(&Rd6 z19isQGid{bp}c`QL+zQofl``WCvBk4SbHXIpfHp-P-mz;lQ&RGlk21n)ER5fqzx2? z@&@V*wP*4MN@;SPw1GNf?U}TJ!cg8oouT$j-asi$u9G%UXRJMwHc%MK8>lnXp2-_1 zrO9>D2I`EpXVL}=LwN&rhT1cE1En;%PTD}7vGz>bKw&6vpw3WxCU2mWCf7+Ds591{ zNgF5({%+yn(_@+CX6@ZJ;odH&B?#8z{`A4V1FvSC=+W%IGU*KbX9MQc7Qj zWXdy>k1cJWlqDZq+CV8wKDNApQkr~hc>|@Cj#CWlpe@wu_4n8>R{Qt`>Dny52^9}$ zm_)Dtdvg}~mdvvHd^vr-+~SIcNs*Qu+ICxlh55eRQ?jfa`%uC{YbD?3%cPGDiAA$~ z1r|pHwFKL{CuGw;A4(oG@fSG9NW4_KwQ!Jcz$y7wPCD&S7Ci@B^lWM^w2BKlTH8Wa zAGgrlGAUGC*b!}LwH9;iTVmf+zy~yVM5M*e2Y0l#w0c&~Qax~azF$=ji|U^LP(2LQ z!*=yB^@r8N#r;c z%EwjtI$1vJKa{V7@^yCkI#IsvU&`01^7XQO_J1f}59RCa^7W#8{lAp2r}7#6bR^3M zobt&h5Bk-Be%zgdlkWS9v+N&vy5XN|#mOIIU!j|$-xmzdxvyW&__-`{bM#Au!8!N! z%Najs1Kb?_W?^v7ef@IA&rPwLqhB`+&bhB&&iFYP=;r8m5QB5>>z6aWuLrp~`o+ZH zocsFajPKLIZjOFiF*xTwHy3F1ItS`w-umWPTk_k_Lr-~pV7`4xeREr*MZbA(_$Sw* zL)QV$2TX}IMN67nq8%m0Rrb!4;Cng~d{@`8oxVV4uYXlfr`6L*$7B1f-uzWPUDnxM ze(Qr@GW%$Aq%DmPuNV6Am(xoS#w~iWMhDc3JL;O9uVY>)(%cXX2CJ;VsblDyn%_*Q z_f6X+J$b;rxh2+`Y}ZFm64Y*9qqeoetV>^!xnnOSk1DWR*mkV@;k&LsP3K($YA^Lx`D};*sf**4Ts+8XgU`mC$kPhNcE@!s0vIyH^a!nr6Q>Kpi<39zN1ZsIlgg{}CLk{-r{TXC%VAIq`oe`}6a|J!h^`rnpg)&F)J ztNyp=SoOaH$EyDwIadAe#IfpsXO30>yKt=f4^mvN`Y+{J^c5<0)qe%Ys{cxk zRsU5StNyDwR{hs-topCzSoOav$EyF`I9C1d&avu$4~|v;dvdJ$--~0_|K1c=sQyD7 ztNz0rtNtS#tNx=LtNvpgtN!C0tN!aaR{hs=tom=@SoJ@SW7Yq7j#d8?I9B~Pa;*Aq z;#l=Rkz>_=GsTsv|4AIH{#!U!{kL+g`fuY{^*@c5*~)&DY%RsSb)tolERW7Yq1j#d9BbFBJb!LjQ96pmH@ zD>+vEpUSc7|1^$O|EF`T`agqX)&H3stNzcTxK{PQieuIPYK~R^Jshk4&*oV5zlLMg z|2Z71{?FxD^?x46s{ivjR{dYVvFiUqj#d8`ajg2km}AxdB^;~%FXdSE-%D{w^}m*5 z)&Dwe^n>kkf-@>u#|5lDw|F?0h`oEoH)&CtFtN!ogSoMDw$EyFk zIadAO!?EiBUXE4&_i?QHzn^2({{tMW{vYI6^}n9ti0c0#j#d8;bFBJ*gk#nJqa3UL zALCf{|2W60|0g(B{XfaE>i;Q@RsT0oJjbg47dTe^Z=g7; z`hSsQ)&ENztNvf+SoQx3$EyEVIad9@#i-jtRsWxItor|qW7YrX z9IO7n;8^wlCC94&uQ*oyf6cM#{~L}~|KD<~`u~n&)&KVt$5sD7aIE_Okz>{WPaLcM zf96>A{|m>e|6e&){r|?X>VFf*s{h|PR{j6MvFiU%j#dAEajg3Pn`71gKOC$6H*-w= z`+H{5+aSv$rTqIpCmuVY6>ySfC$t1k((Q!Sz)6Ok&>}d=v=dqdCs}qv%itv2PG}vR zcd3Hjp;UwQqXgQn|*oj(CfD?W}z@I6! z6SbZqJ1Lu8T%SefNQH9R$4uKL17Fnfi#0yUN#0E_tP)md@30>E34Xbj@DO~z*? zjPL6#Zp`GDaR054M^Ys8>lfD#inKY3?DSThqI zKHX|vlmD!qPS2VdxdZ6V&cqB^)Lyc@lU{=M4qhYgr5B+yF7M6h>GEx+LYF7{`+V{-&4vjiI)}T%XsX_i6d)e{nvY>)4jdi?L?Sp3}Z8 zmO)cX?KcKoQ|X|4YO2R$PtEO62P1+WU_3Tc&rBJ;(atsUbO(I&JmsXN*^WQu_|oVQ zWwIY%nwHAx%rz;|QK6KSPUj5TOHFpMQ)E=aWJ@TZ}tT$FOP6rsbBQu2f3x6ju_$&Zp>OHn#8KuUQa<>kqq@=(gtQjAU% zkWxNK`T0`HM=4)RaXN88N_4z5^<7X1K^i$yN+VGksiiobI3cA`AdMO&rBNu2N=aqG5>qMx$@$MI z_&i>MQi+yIw=|_KLE3Ul+0&LNZKU(Va|bCy;j9NlH7Rw3C)%JDbwZ zAnm-fly*jGXD!8dF{NEV+GQ6h?Sj%SDXCn&oO8XFqW{X4+Bt(kDFsmqYN@o;?5Px_ zQv1~(KGT(=RH~)2GE*u8sjN))REAQSmdeXbsT`#8aw(OgRIa6p3R9{8siHzk6)06` zsj||PDnY8Olu{*1m0GH*GNmezs;Z<^g;JH4s;f<@8l>uKDOICXt)-e8Q>p=}rbbFN zDAj1Gw$_wtL8`5lQY}igS_#kDT6{TIZ6yD90b^~d*-K4Y|O1o((vb!nm z4$|(sOKEqMcGpsL4^!F$q&@bK(jF-7p{3ZKrnDzWd+sTvJyF_IOYyx-X)loW+Dl4% zp|n>@stE3FN_&H}_uf+48>PLqR2niRIu$MTOcx4CDTGo;OJ!kGqO;IaQaCInJ~=dX z{3)!Z@`x$X31}%PV*i(Ae9q+aJX2CcOBGR5qI1tuQZy=i;!`$LQdCQoF;k+`l~PhH zCM7=mG9|^dR24TRI^!%Q#p!G#deH_)L-<6>loZ!eb)6~E$!003u1-pPPGm}|(^5^n zDbaamDXG3*N_=`_N~+gVZG$N_fYi_+r3RE5v=ka=O5;EpH%?09P#UMD@OV=i57PMY zQW}racr8UHn9>B0CQOjh1e7LdDcWdCbV6S05pQgiQX@)@T8cH9QWHo`O;Tz?sYy%m ziKa9Wq=^%yG!dnVDXB8pY)Z`_H8)GC8Kq_|l}<9HNgz#{B&A6xP0~_Xiz&5$)Y2lQ z7L;1FRNiVzbgEzKYuDN;rB;+$wN%k&N^~Y>N@{D9QX5KbTB@9EN|QmFJXuPUQJSo! zswt*41*9ocq%;MkDO#$YYD!ZoH zUn%X2(!N>>?Pp5+fwbR#QrZut{j?NrH>Gxv+S{enj#9gpBGXK18c5ToNog8N)3g-b z-<0+TY5)DDv_DGwYbkbsDIEaP0S8Fw0F(~UQoO^IIzZ~^kWvRq9Vw|Q*l9|gAa!<1 zsS~A6EtPheQWr>FT~g{osY^>`(@kkQNYkfFX*x>NwNyUClxBc5V}_Jwpfp2E6*Em~ zCP*`9N@*raGqqHCpeY>)(t!s`=|GeY)Kb+!rgRWU2OT7(gHSq1OVtOP(!n4de6W-b zM(JQJ)yy)bSs=}tC8b#?&C*isY*U&I((Kt%nvK$IErsTo(j1WH%#qR@l;&tDJlB-w zf;4xol;)x|S4)vYOz9Ai4xzs*^S$*kPu07)Xa5 zCZ)qrI!sIP!%gXMkPbgwN{6F#cuJ}cCQK;-QX(Ox1WE}ll^$VAM}Tz15mGt=r6aUd zcBCmC3DS{AO6f?Hj?_~5JX4wn(!6<6nupRnEmh1nrTHMupD(5PD9zVWc(ML<^Xq1lDQq3`@bPPzx93!P;P&!6S zwF^yYAxH}sN@*cV3$+wF)|8F~>DXhXbSz58YAL+Ploo-sXpxi_p|nU#k>gD1IFODz zPD;n2bexu=i%n@UNQ)OsX)#KRwG=zvl#U1K_~WH?JW9uFDSm<}odD7aCrIf8luk%V zHNhpOv;?FjOQf^}r6pP_U1~~8L0Y<0N=s2%s-?1SQ|bn(yIV@#D0OS8e3>aN18LbZ zDJ?^3nU*R}G^Gbc$y%yeVM;4NTCqY(D^OaYrP@C{uDbSg@xYAJG>DV+w=X{Sl)G?Y%$QuK6FIvu3bPnXi^D4njQ z*cqmD21sX|A*C}=IzvnGGfnACkj^|)N@t>UW=g6Jo@GjBfppecQaTHzv$RyY%9K`t zv}%=?OJ%D~X*EczS4(L%N~^V0-eXEVAocV}sRyMVEmfRtN@s&~_SsT88>O?g zRJq2K)_}BTjg;1)v_?x+=a|wtAf0oLl+Hov94%F!Yf9&WbndxQIv1sLwN!JSDV+z> zdFM&#Je1DUQtkPsbUsMupD(5JQ955sp$kmu0+24aKuQ;&bb*$_7n;(AAYFK&lrBW+ zLM=ruGNp?^y67S)U4+s_T8dt5N*9B4@x@ZQ7^RD~6uZQfE&=J1OQduON|$IUeyJ&4 z3eu&QO6gLRE=@_HV6Q3lg4Ek9rCyYJwN$#+l-7c@cCD1wqO?{^W$R379Z2ieNogHQ z>$FsUnJHZc(q)%P=`xfq(^5sBDfNNW*C(Yul=`$(dATWF4$|e9OX+fyF4t1k6{d6r zNLO4Tr7KXnLQB_n&)m2iu3Z<*GRC~24T@BLJS4-(? zl&;oN=o(YH2Bd4Qk#b6{6{TCX zRB@Xr-3HQaw@K+Xly1{f$M-z}xPQMy}8p?gf}9+2+2M@sjg zbdQ$8_nOkZAl-YflN)Ko${-7y62-1TOO6ftA9!yD*;CfS957PSeQd*DFdM%YcWJ(W#^w2|6 zdI+V5v{d%6DLo9*!w*a8VU!-$Qu!mM^ax0gJR+q>P=}|3J zK4waff%Mp8QhE%f$Fx-SxG6mj(&LXy>2Z`E*HZNprt}0zPdp)|Cs2AqOEpiL(vu)P z`J|MdMCnN_)jnlPPl5E*Q&M^grKhwMdfJqp2I=XirSvpPPirasj43?>(lgIU=^2!s z(Ng4DQ+gJpXP=eQvnV~QrRZ~}^c+afJtw8-PFvFAAieR1 zl-@w;4K0P~3~3#GTT6nWc}-UjLIx25zpN^ff^ z`i?2R1JXP1Na-Dv-qBL*T~m4&q<7zy(z__VtEKpRrt}_2@4Y9b_fUE-CB=g8o6`Fr zz5l+H-bd+uEtP&?N*{pq!3R?M0HqJKRQ91MeF)NrA4=&%ls?o_`A4So5lA0>B&Cl~ z`bbL^ADhz0AbtF?ls-o3V=YyFVoINY^vNeu`UIseI}*PQ2I2odBeql;qfb_)|Qu+d=FSHc;(v-dg>B}#r z^d(APYAO7cDSZXfS6@l#E0n&{Qsiq>`WmFKzn0S1D1EJ^=r^YH4M^X7Bc*Rp`bJB! zZ%yf2kiPv^O5dXNt(M~7nbLP4efOP|zC-D|loStsZ%W^T^!@iz`W~h4wN(0pDg6M_ z4?jrh2b6x$QrVBD^dm?={wSp%QTkC!7Re3^bbn^u++VG z7XQID`;SH^|GadyW&h=9-)7hU^4;vnbOp+sfMso_(ya3>{*SE9SYfkWA)3X1#jU>z z^cUXfFE*wAEEJ`#8eD*D@CRxo`FDAERv`6XtSHk}O8c$iaaZxUt9VouzQrmu3#xda zN?E^E(%e8_ILu9B&$@GVxMSx_Yts#Nt`CCgnU%UvZ)RpDE#LbISs z7F4P3w@S9VO18U7wyMInScPUmm29X|({B~8yNcIc#jC3DEmomfP{j*XYWuB{m4au9D}jlBcThEmomfP$dtl#QLq0@2-;X zu9B~+@GVxMSx_Y(s`R_J&>zNhJ@Xg1s}!gze2Z0R7E~$FRZ9EcUjptb0e6*vs=~Ke zg=RsO095IJe<^fVDRfsUR8{yEtI#Z{QV3Q0-(QN{Rf^nIic}T8#VRxlsuXdR;^A}| z2D+p~M=V%osf$POB^mfnb_N;;I@f5huPtm}kYZe}?~WCDR+^u8Vtc=*%R+fJ`8Uyb zIo4(Wf{0Q+Xa;irBJ#vM&^Ef1a<*w0Uzb52b%;mg^GIUb;%M^A5dbUFG`B zdb+l>^IML!e$SOV&}FBU<~X!iQa5k*I%(=7=X52D?nnl$Q+;djRjfmF=?v$p7<@lm z4udZE(H8RMI+x(EFNaZ*Rg&eQ>shyVkIQJTZ*FmZR@?|ZNc~(|!?f1>*ZVy~=u#fr zO{4Oy`7^wVz;61>(B8dsd}>7f7)^>bPNu)9S;lik z$AQd1CSSlK5ZZDY|Lxd7LkWKs+q-jHgTW5x(&Fvi+qVX5oP@q&9;=v~(x^pO%BG+! z8I*HCzZ(v3jqAaq_|hN^EtArGoqT1GAjclQJ{DceYf_j$MEFD0Ytdy;CdD|8^M^YA zQ18v6k0G@xiZ~6Y(lDoyR2tzlno6Ub#!_jF(|9V4b6S^5>o~1XrF0dcit*tnE!nx; zdV0F^$Q3wW>mj~@b)HVE)AG#NmqjKvrsnW(J#?9te&%dS-;{27 zM+fXVV_VuHscv$q4qq$ArW00zes3OadAOZ|)_7QbbBbPo8!z`($~*~#D8BUr&HBEVSz2pEB4AU24G0Y(N+hD|^Y6El!tgNU*~X%LSC z$X0-fGcm9T0LA|E|L2FOWMD92VqjR>!otAF!NBm72Obk1 YBHITON2VDSAnpK(F*YFF1LDH~0O^Si0RR91 literal 0 HcmV?d00001 diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h index e81dc67a2e..dfb8523c8b 100644 --- a/tests/qtest/bios-tables-test-allowed-diff.h +++ b/tests/qtest/bios-tables-test-allowed-diff.h @@ -1,4 +1 @@ /* List of comma-separated changed AML files to ignore */ -"tests/data/acpi/q35/APIC.core-count2", -"tests/data/acpi/q35/DSDT.core-count2", -"tests/data/acpi/q35/FACP.core-count2", From 259d69c00b67c02a67f3bdbeeea71c2c0af76c35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Mon, 7 Nov 2022 12:14:07 +0000 Subject: [PATCH 663/705] hw/virtio: introduce virtio_device_should_start MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous fix to virtio_device_started revealed a problem in its use by both the core and the device code. The core code should be able to handle the device "starting" while the VM isn't running to handle the restoration of migration state. To solve this duel use introduce a new helper for use by the vhost-user backends who all use it to feed a should_start variable. We can also pick up a change vhost_user_blk_set_status while we are at it which follows the same pattern. Fixes: 9f6bcfd99f (hw/virtio: move vm_running check to virtio_device_started) Signed-off-by: Alex Bennée Cc: "Michael S. Tsirkin" Message-Id: <20221107121407.1010913-1-alex.bennee@linaro.org> --- hw/block/vhost-user-blk.c | 6 +----- hw/virtio/vhost-user-fs.c | 2 +- hw/virtio/vhost-user-gpio.c | 2 +- hw/virtio/vhost-user-i2c.c | 2 +- hw/virtio/vhost-user-rng.c | 2 +- hw/virtio/vhost-user-vsock.c | 2 +- hw/virtio/vhost-vsock.c | 2 +- include/hw/virtio/virtio.h | 18 ++++++++++++++++++ 8 files changed, 25 insertions(+), 11 deletions(-) diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c index 28409c90f7..16ad400889 100644 --- a/hw/block/vhost-user-blk.c +++ b/hw/block/vhost-user-blk.c @@ -226,14 +226,10 @@ static void vhost_user_blk_stop(VirtIODevice *vdev) static void vhost_user_blk_set_status(VirtIODevice *vdev, uint8_t status) { VHostUserBlk *s = VHOST_USER_BLK(vdev); - bool should_start = virtio_device_started(vdev, status); + bool should_start = virtio_device_should_start(vdev, status); Error *local_err = NULL; int ret; - if (!vdev->vm_running) { - should_start = false; - } - if (!s->connected) { return; } diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c index ad0f91c607..1c40f42045 100644 --- a/hw/virtio/vhost-user-fs.c +++ b/hw/virtio/vhost-user-fs.c @@ -123,7 +123,7 @@ static void vuf_stop(VirtIODevice *vdev) static void vuf_set_status(VirtIODevice *vdev, uint8_t status) { VHostUserFS *fs = VHOST_USER_FS(vdev); - bool should_start = virtio_device_started(vdev, status); + bool should_start = virtio_device_should_start(vdev, status); if (vhost_dev_is_started(&fs->vhost_dev) == should_start) { return; diff --git a/hw/virtio/vhost-user-gpio.c b/hw/virtio/vhost-user-gpio.c index 8b40fe450c..677d1c7730 100644 --- a/hw/virtio/vhost-user-gpio.c +++ b/hw/virtio/vhost-user-gpio.c @@ -152,7 +152,7 @@ static void vu_gpio_stop(VirtIODevice *vdev) static void vu_gpio_set_status(VirtIODevice *vdev, uint8_t status) { VHostUserGPIO *gpio = VHOST_USER_GPIO(vdev); - bool should_start = virtio_device_started(vdev, status); + bool should_start = virtio_device_should_start(vdev, status); trace_virtio_gpio_set_status(status); diff --git a/hw/virtio/vhost-user-i2c.c b/hw/virtio/vhost-user-i2c.c index bc58b6c0d1..864eba695e 100644 --- a/hw/virtio/vhost-user-i2c.c +++ b/hw/virtio/vhost-user-i2c.c @@ -93,7 +93,7 @@ static void vu_i2c_stop(VirtIODevice *vdev) static void vu_i2c_set_status(VirtIODevice *vdev, uint8_t status) { VHostUserI2C *i2c = VHOST_USER_I2C(vdev); - bool should_start = virtio_device_started(vdev, status); + bool should_start = virtio_device_should_start(vdev, status); if (vhost_dev_is_started(&i2c->vhost_dev) == should_start) { return; diff --git a/hw/virtio/vhost-user-rng.c b/hw/virtio/vhost-user-rng.c index bc1f36c5ac..8b47287875 100644 --- a/hw/virtio/vhost-user-rng.c +++ b/hw/virtio/vhost-user-rng.c @@ -90,7 +90,7 @@ static void vu_rng_stop(VirtIODevice *vdev) static void vu_rng_set_status(VirtIODevice *vdev, uint8_t status) { VHostUserRNG *rng = VHOST_USER_RNG(vdev); - bool should_start = virtio_device_started(vdev, status); + bool should_start = virtio_device_should_start(vdev, status); if (vhost_dev_is_started(&rng->vhost_dev) == should_start) { return; diff --git a/hw/virtio/vhost-user-vsock.c b/hw/virtio/vhost-user-vsock.c index 7b67e29d83..9431b9792c 100644 --- a/hw/virtio/vhost-user-vsock.c +++ b/hw/virtio/vhost-user-vsock.c @@ -55,7 +55,7 @@ const VhostDevConfigOps vsock_ops = { static void vuv_set_status(VirtIODevice *vdev, uint8_t status) { VHostVSockCommon *vvc = VHOST_VSOCK_COMMON(vdev); - bool should_start = virtio_device_started(vdev, status); + bool should_start = virtio_device_should_start(vdev, status); if (vhost_dev_is_started(&vvc->vhost_dev) == should_start) { return; diff --git a/hw/virtio/vhost-vsock.c b/hw/virtio/vhost-vsock.c index 7dc3c73931..aa16d584ee 100644 --- a/hw/virtio/vhost-vsock.c +++ b/hw/virtio/vhost-vsock.c @@ -70,7 +70,7 @@ static int vhost_vsock_set_running(VirtIODevice *vdev, int start) static void vhost_vsock_set_status(VirtIODevice *vdev, uint8_t status) { VHostVSockCommon *vvc = VHOST_VSOCK_COMMON(vdev); - bool should_start = virtio_device_started(vdev, status); + bool should_start = virtio_device_should_start(vdev, status); int ret; if (vhost_dev_is_started(&vvc->vhost_dev) == should_start) { diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 1423dba379..141a253a2c 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -395,6 +395,24 @@ static inline bool virtio_device_started(VirtIODevice *vdev, uint8_t status) return vdev->started; } + return status & VIRTIO_CONFIG_S_DRIVER_OK; +} + +/** + * virtio_device_should_start() - check if device startable + * @vdev - the VirtIO device + * @status - the devices status bits + * + * This is similar to virtio_device_started() but also encapsulates a + * check on the VM status which would prevent a device starting + * anyway. + */ +static inline bool virtio_device_should_start(VirtIODevice *vdev, uint8_t status) +{ + if (vdev->use_started) { + return vdev->started; + } + if (!vdev->vm_running) { return false; } From 1ef47f40dce3d5b176ddf76d57b5bfa2efb0b3c6 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 7 Nov 2022 09:52:16 -0500 Subject: [PATCH 664/705] checkpatch: better pattern for inline comments checkpatch is unhappy about this line: WARNING: Block comments use a leading /* on a separate line #50: FILE: hw/acpi/nvdimm.c:1074: + aml_equal(aml_sizeof(pckg), aml_int(1)) /* 1 element? */)); but there's nothing wrong with it - the check is just too simplistic. It will also miss lines which mix inline and block comments. Instead, let's strip all inline comments from a line and then check for block comments. Signed-off-by: Michael S. Tsirkin --- scripts/checkpatch.pl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index e3e3b43076..bc7d4780ec 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1681,8 +1681,10 @@ sub process { # Block comment styles # Block comments use /* on a line of its own - if ($rawline !~ m@^\+.*/\*.*\*/[ \t)}]*$@ && #inline /*...*/ - $rawline =~ m@^\+.*/\*\*?+[ \t]*[^ \t]@) { # /* or /** non-blank + my $commentline = $rawline; + while ($commentline =~ s@^(\+.*)/\*.*\*/@$1@o) { # remove inline #inline /*...*/ + } + if ($commentline =~ m@^\+.*/\*\*?+[ \t]*[^ \t]@) { # /* or /** non-blank WARN("Block comments use a leading /* on a separate line\n" . $herecurr); } From 479b350ebf08248eb7729a02a07ddfe7a7c65e44 Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Fri, 4 Nov 2022 13:00:58 +0100 Subject: [PATCH 665/705] util/log: Make the per-thread flag immutable Per-thread logging was implemented under the assumption that once enabled, it is not possible to switch back to single file logging. This isn't enforced though and it is possible to go through the global file opening sequence in per-thread mode. The code isn't ready for this and produces unexpected results as detailed below. Start QEMU in system emulation mode with `-D ./qemu.log.%d -d tid` and then change the log level from the monitor to something that doesn't have tid, e.g. `log cpu_reset`. The value of log_flags is zero and per_thread is set to false : the rest of the code then assumes it is running in the global log case and opens a file named `qemu.log.%d`, which is obviously not an expected behavior. Enforce the immutability of the flag early in qemu_set_log_internal() so that its value is correct for all subsequent users. Fixes: 4e51069d6793 ("util/log: Support per-thread log files") Cc: richard.henderson@linaro.org Signed-off-by: Greg Kurz Reviewed-by: Richard Henderson Message-id: 20221104120059.678470-2-groug@kaod.org Signed-off-by: Stefan Hajnoczi --- util/log.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/util/log.c b/util/log.c index 39866bdaf2..b7d2b6e09c 100644 --- a/util/log.c +++ b/util/log.c @@ -206,6 +206,11 @@ static bool qemu_set_log_internal(const char *filename, bool changed_name, QEMU_LOCK_GUARD(&global_mutex); logfile = global_file; + /* The per-thread flag is immutable. */ + if (log_per_thread) { + log_flags |= LOG_PER_THREAD; + } + per_thread = log_flags & LOG_PER_THREAD; if (changed_name) { From 524fc737431d240f9d9f10aaf381003092868bac Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Fri, 4 Nov 2022 13:00:59 +0100 Subject: [PATCH 666/705] util/log: Ignore per-thread flag if global file already there If QEMU is started with `-D qemu.log.%d` without any `-d` option, doing `log all` in the monitor fails with: Filename template with '%d' required for 'tid' It is confusing since '%d' was actually passed. This happens because QEMU caches the log file name with %d converted to getpid() since `tid` wasn't required. This name isn't suitable for a subsequent enablement of per-thread logs. There's little cause to change the behavior as `-d tid` is mostly used at user-only startup. Drop the per-thread from the requested flags in this case : `log all` will thus enable everything except `tid` instead of failing. This is preferable over forcing the user to enable each log item individually. With this patch, `tid` is now truely immutable : it can only be set or unset from the command line and never changed afterwards. Fixes: 4e51069d6793 ("util/log: Support per-thread log files") Cc: richard.henderson@linaro.org Signed-off-by: Greg Kurz Reviewed-by: Richard Henderson Message-id: 20221104120059.678470-3-groug@kaod.org Signed-off-by: Stefan Hajnoczi --- util/log.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/util/log.c b/util/log.c index b7d2b6e09c..c2198badf2 100644 --- a/util/log.c +++ b/util/log.c @@ -209,6 +209,10 @@ static bool qemu_set_log_internal(const char *filename, bool changed_name, /* The per-thread flag is immutable. */ if (log_per_thread) { log_flags |= LOG_PER_THREAD; + } else { + if (global_filename) { + log_flags &= ~LOG_PER_THREAD; + } } per_thread = log_flags & LOG_PER_THREAD; From 8063db0fc8256e3f6b9b33c246bd926f3a2dbb12 Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Mon, 31 Oct 2022 13:25:29 +0000 Subject: [PATCH 667/705] target/mips: Set CP0St_{KX, SX, UX} for Loongson-2F MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As per an unpublished document, in later reversion of chips CP0St_{KX, SX, UX} is not writeable and hardcoded to 1. Without those bits set, kernel is unable to access XKPHYS address segment. So just set them up on CPU reset. Signed-off-by: Jiaxun Yang Acked-by: Richard Henderson Message-Id: <20221031132531.18122-2-jiaxun.yang@flygoat.com> Signed-off-by: Philippe Mathieu-Daudé --- target/mips/cpu.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/target/mips/cpu.c b/target/mips/cpu.c index e997c1b9cb..7a565466cb 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c @@ -302,6 +302,12 @@ static void mips_cpu_reset(DeviceState *dev) env->CP0_EntryHi_ASID_mask = (env->CP0_Config5 & (1 << CP0C5_MI)) ? 0x0 : (env->CP0_Config4 & (1 << CP0C4_AE)) ? 0x3ff : 0xff; env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL); + if (env->insn_flags & INSN_LOONGSON2F) { + /* Loongson-2F has those bits hardcoded to 1 */ + env->CP0_Status |= (1 << CP0St_KX) | (1 << CP0St_SX) | + (1 << CP0St_UX); + } + /* * Vectored interrupts not implemented, timer on int 7, * no performance counters. From 0e8b3010afa7507f42754ebec16bbd4dfdb3a660 Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Mon, 31 Oct 2022 13:25:30 +0000 Subject: [PATCH 668/705] target/mips: Cast offset field of Octeon BBIT to int16_t MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As per "Cavium Networks OCTEON Plus CN50XX Hardware Reference Manual" offset field is signed 16 bit value. However arg_BBIT.offset is unsigned. We need to cast it as signed to do address calculation. Signed-off-by: Jiaxun Yang Acked-by: Richard Henderson Acked-by: Pavel Dovgalyuk Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20221031132531.18122-3-jiaxun.yang@flygoat.com> Signed-off-by: Philippe Mathieu-Daudé --- target/mips/tcg/octeon.decode | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/mips/tcg/octeon.decode b/target/mips/tcg/octeon.decode index 8929ad088e..0c787cb498 100644 --- a/target/mips/tcg/octeon.decode +++ b/target/mips/tcg/octeon.decode @@ -12,7 +12,7 @@ # BBIT132 111110 ..... ..... ................ %bbit_p 28:1 16:5 -BBIT 11 set:1 . 10 rs:5 ..... offset:16 p=%bbit_p +BBIT 11 set:1 . 10 rs:5 ..... offset:s16 p=%bbit_p # Arithmetic # BADDU rd, rs, rt From 4525ea7e0caa4aa6317204cd977179dea972cf6d Mon Sep 17 00:00:00 2001 From: Pavel Dovgalyuk Date: Tue, 1 Nov 2022 08:29:44 +0300 Subject: [PATCH 669/705] target/mips: Enable LBX/LWX/* instructions for Octeon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch changes condition and function name for enabling indexed load instructions for Octeon vCPUs. Octeons do not have DSP extension, but implement LBX-and-others. Signed-off-by: Pavel Dovgalyuk Reviewed-by: Philippe Mathieu-Daudé Message-Id: <166728058455.229236.13834649461181619195.stgit@pasha-ThinkPad-X280> Signed-off-by: Philippe Mathieu-Daudé --- target/mips/tcg/translate.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c index 2f2d707a12..4c4bd0823d 100644 --- a/target/mips/tcg/translate.c +++ b/target/mips/tcg/translate.c @@ -12173,12 +12173,16 @@ enum { #include "nanomips_translate.c.inc" /* MIPSDSP functions. */ -static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc, - int rd, int base, int offset) + +/* Indexed load is not for DSP only */ +static void gen_mips_lx(DisasContext *ctx, uint32_t opc, + int rd, int base, int offset) { TCGv t0; - check_dsp(ctx); + if (!(ctx->insn_flags & INSN_OCTEON)) { + check_dsp(ctx); + } t0 = tcg_temp_new(); if (base == 0) { @@ -14523,7 +14527,7 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) case OPC_LBUX: case OPC_LHX: case OPC_LWX: - gen_mipsdsp_ld(ctx, op2, rd, rs, rt); + gen_mips_lx(ctx, op2, rd, rs, rt); break; default: /* Invalid */ MIPS_INVAL("MASK LX"); From 4bfc895383ed65b83d55a8ae5738a166c1cc48f1 Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Mon, 31 Oct 2022 13:25:31 +0000 Subject: [PATCH 670/705] target/mips: Disable DSP ASE for Octeon68XX MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I don't have access to Octeon68XX hardware but according to my investigation Octeon never had DSP ASE support. As per "Cavium Networks OCTEON Plus CN50XX Hardware Reference Manual" CP0C3_DSPP is reserved bit and read as 0. Also I do have access to a Ubiquiti Edgerouter 4 which has Octeon CN7130 processor and I can confirm CP0C3_DSPP is read as 0 on that processor. Further more, in linux kernel: arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h cpu_has_dsp is overridden as 0. So I believe we shouldn't emulate DSP in QEMU as well. Signed-off-by: Jiaxun Yang Acked-by: Richard Henderson Reviewed-by: Pavel Dovgalyuk Message-Id: <20221031132531.18122-4-jiaxun.yang@flygoat.com> Signed-off-by: Philippe Mathieu-Daudé --- target/mips/cpu-defs.c.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/mips/cpu-defs.c.inc b/target/mips/cpu-defs.c.inc index 7f53c94ec8..480e60aeec 100644 --- a/target/mips/cpu-defs.c.inc +++ b/target/mips/cpu-defs.c.inc @@ -934,7 +934,7 @@ const mips_def_t mips_defs[] = (1 << CP0C1_DS) | (4 << CP0C1_DL) | (1 << CP0C1_DA) | (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), .CP0_Config2 = MIPS_CONFIG2, - .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_LPA) | (1 << CP0C3_DSPP) , + .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_LPA), .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M) | (0x3c << CP0C4_KScrExist) | (1U << CP0C4_MMUExtDef) | (3U << CP0C4_MMUSizeExt), @@ -946,7 +946,7 @@ const mips_def_t mips_defs[] = .CP0_Status_rw_bitmask = 0x12F8FFFF, .SEGBITS = 42, .PABITS = 49, - .insn_flags = CPU_MIPS64R2 | INSN_OCTEON | ASE_DSP, + .insn_flags = CPU_MIPS64R2 | INSN_OCTEON, .mmu_type = MMU_TYPE_R4000, }, From 2a2105a26219695c72bfc7cab9b7d37754fc0920 Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Wed, 2 Nov 2022 16:57:18 +0000 Subject: [PATCH 671/705] target/mips: Don't check COP1X for 64 bit FP mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some implementations (i.e. Loongson-2F) may decide to implement a 64 bit FPU without implementing COP1X instructions. As the eligibility of 64 bit FP instructions is already determined by CP0St_FR, there is no need to check for COP1X again. Signed-off-by: Jiaxun Yang Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20221102165719.190378-1-jiaxun.yang@flygoat.com> [PMD: Add missing trailing parenthesis (buildfix)] Signed-off-by: Philippe Mathieu-Daudé --- target/mips/tcg/translate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c index 4c4bd0823d..624e6b7786 100644 --- a/target/mips/tcg/translate.c +++ b/target/mips/tcg/translate.c @@ -1545,7 +1545,7 @@ void check_cop1x(DisasContext *ctx) */ void check_cp1_64bitmode(DisasContext *ctx) { - if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) { + if (unlikely(~ctx->hflags & MIPS_HFLAG_F64)) { gen_reserved_instruction(ctx); } } From 04849c94fe50ce6fc621933eda2321dc6a3280a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Tue, 1 Nov 2022 12:44:54 +0100 Subject: [PATCH 672/705] disas/nanomips: Fix invalid PRId64 format calling img_format() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix warnings such: disas/nanomips.c:3251:64: warning: format specifies type 'char *' but the argument has type 'int64' (aka 'long long') [-Wformat] return img_format("CACHE 0x%" PRIx64 ", %s(%s)", op_value, s_value, rs); ~~ ^~~~~~~ %lld To avoid crashes such (kernel from commit f375ad6a0d): $ qemu-system-mipsel -cpu I7200 -d in_asm -kernel generic_nano32r6el_page4k ... ---------------- IN: __bzero 0x805c6084: 20c4 6950 ADDU r13, a0, a2 0x805c6088: 9089 ADDIU a0, 1 Process 70261 stopped * thread #6, stop reason = EXC_BAD_ACCESS (code=1, address=0xfffffffffffffff0) frame #0: 0x00000001bfe38864 libsystem_platform.dylib`_platform_strlen + 4 libsystem_platform.dylib`: -> 0x1bfe38864 <+4>: ldr q0, [x1] 0x1bfe38868 <+8>: adr x3, #-0xc8 ; ___lldb_unnamed_symbol314 0x1bfe3886c <+12>: ldr q2, [x3], #0x10 0x1bfe38870 <+16>: and x2, x0, #0xf Target 0: (qemu-system-mipsel) stopped. (lldb) bt * thread #6, stop reason = EXC_BAD_ACCESS (code=1, address=0xfffffffffffffff0) * frame #0: 0x00000001bfe38864 libsystem_platform.dylib`_platform_strlen + 4 frame #1: 0x00000001bfce76a0 libsystem_c.dylib`__vfprintf + 4544 frame #2: 0x00000001bfd158b4 libsystem_c.dylib`_vasprintf + 280 frame #3: 0x0000000101c22fb0 libglib-2.0.0.dylib`g_vasprintf + 28 frame #4: 0x0000000101bfb7d8 libglib-2.0.0.dylib`g_strdup_vprintf + 32 frame #5: 0x000000010000fb70 qemu-system-mipsel`img_format(format=) at nanomips.c:103:14 [opt] frame #6: 0x0000000100018868 qemu-system-mipsel`SB_S9_(instruction=, info=) at nanomips.c:12616:12 [opt] frame #7: 0x000000010000f90c qemu-system-mipsel`print_insn_nanomips at nanomips.c:589:28 [opt] Fixes: 4066c152b3 ("disas/nanomips: Remove IMMEDIATE functions") Reported-by: Stefan Weil Reviewed-by: Stefan Weil Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20221101114458.25756-2-philmd@linaro.org> --- disas/nanomips.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/disas/nanomips.c b/disas/nanomips.c index 9647f1a8e3..6466c80dc5 100644 --- a/disas/nanomips.c +++ b/disas/nanomips.c @@ -3252,7 +3252,8 @@ static char *CACHE(uint64 instruction, Dis_info *info) const char *rs = GPR(rs_value, info); - return img_format("CACHE 0x%" PRIx64 ", %s(%s)", op_value, s_value, rs); + return img_format("CACHE 0x%" PRIx64 ", %" PRId64 "(%s)", + op_value, s_value, rs); } @@ -3274,7 +3275,8 @@ static char *CACHEE(uint64 instruction, Dis_info *info) const char *rs = GPR(rs_value, info); - return img_format("CACHEE 0x%" PRIx64 ", %s(%s)", op_value, s_value, rs); + return img_format("CACHEE 0x%" PRIx64 ", %" PRId64 "(%s)", + op_value, s_value, rs); } @@ -5173,7 +5175,7 @@ static char *DADDIU_48_(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value, info); - return img_format("DADDIU %s, %s", rt, s_value); + return img_format("DADDIU %s, %" PRId64, rt, s_value); } @@ -11859,7 +11861,7 @@ static char *PREF_S9_(uint64 instruction, Dis_info *info) const char *rs = GPR(rs_value, info); - return img_format("PREF 0x%" PRIx64 ", %s(%s)", + return img_format("PREF 0x%" PRIx64 ", %" PRId64 "(%s)", hint_value, s_value, rs); } @@ -11905,7 +11907,8 @@ static char *PREFE(uint64 instruction, Dis_info *info) const char *rs = GPR(rs_value, info); - return img_format("PREFE 0x%" PRIx64 ", %s(%s)", hint_value, s_value, rs); + return img_format("PREFE 0x%" PRIx64 ", %" PRId64 "(%s)", + hint_value, s_value, rs); } @@ -12079,7 +12082,7 @@ static char *REPL_PH(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value, info); - return img_format("REPL.PH %s, %s", rt, s_value); + return img_format("REPL.PH %s, %" PRId64, rt, s_value); } @@ -12613,7 +12616,7 @@ static char *SB_S9_(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value, info); const char *rs = GPR(rs_value, info); - return img_format("SB %s, %s(%s)", rt, s_value, rs); + return img_format("SB %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -12659,7 +12662,7 @@ static char *SBE(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value, info); const char *rs = GPR(rs_value, info); - return img_format("SBE %s, %s(%s)", rt, s_value, rs); + return img_format("SBE %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -12706,7 +12709,7 @@ static char *SC(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value, info); const char *rs = GPR(rs_value, info); - return img_format("SC %s, %s(%s)", rt, s_value, rs); + return img_format("SC %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -12729,7 +12732,7 @@ static char *SCD(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value, info); const char *rs = GPR(rs_value, info); - return img_format("SCD %s, %s(%s)", rt, s_value, rs); + return img_format("SCD %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -12776,7 +12779,7 @@ static char *SCE(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value, info); const char *rs = GPR(rs_value, info); - return img_format("SCE %s, %s(%s)", rt, s_value, rs); + return img_format("SCE %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -12868,7 +12871,7 @@ static char *SD_S9_(uint64 instruction, Dis_info *info) const char *rt = GPR(rt_value, info); const char *rs = GPR(rs_value, info); - return img_format("SD %s, %s(%s)", rt, s_value, rs); + return img_format("SD %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -12973,7 +12976,7 @@ static char *SDC1_S9_(uint64 instruction, Dis_info *info) const char *ft = FPR(ft_value, info); const char *rs = GPR(rs_value, info); - return img_format("SDC1 %s, %s(%s)", ft, s_value, rs); + return img_format("SDC1 %s, %" PRId64 "(%s)", ft, s_value, rs); } @@ -13066,7 +13069,8 @@ static char *SDC2(uint64 instruction, Dis_info *info) const char *rs = GPR(rs_value, info); - return img_format("SDC2 CP%" PRIu64 ", %s(%s)", cs_value, s_value, rs); + return img_format("SDC2 CP%" PRIu64 ", %" PRId64 "(%s)", + cs_value, s_value, rs); } @@ -13091,7 +13095,8 @@ static char *SDM(uint64 instruction, Dis_info *info) const char *rs = GPR(rs_value, info); uint64 count3 = encode_count3_from_count(count3_value); - return img_format("SDM %s, %s(%s), 0x%" PRIx64, rt, s_value, rs, count3); + return img_format("SDM %s, %" PRId64 "(%s), 0x%" PRIx64, + rt, s_value, rs, count3); } From 50fc0945b6448903c0b696d373b004881ed37e1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Tue, 1 Nov 2022 12:44:55 +0100 Subject: [PATCH 673/705] disas/nanomips: Fix invalid PRIx64 format calling img_format() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix: disas/nanomips.c:12231:62: warning: format specifies type 'char *' but the argument has type 'uint64' (aka 'unsigned long long') [-Wformat] return img_format("RESTOREF 0x%" PRIx64 ", %s", u_value, count_value); ~~ ^~~~~~~~~~~ %llu Fixes: 4066c152b3 ("disas/nanomips: Remove IMMEDIATE functions") Reported-by: Stefan Weil Reviewed-by: Stefan Weil Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20221101114458.25756-3-philmd@linaro.org> --- disas/nanomips.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/disas/nanomips.c b/disas/nanomips.c index 6466c80dc5..e4b21e7c45 100644 --- a/disas/nanomips.c +++ b/disas/nanomips.c @@ -12235,7 +12235,8 @@ static char *RESTOREF(uint64 instruction, Dis_info *info) uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3__s3(instruction); - return img_format("RESTOREF 0x%" PRIx64 ", %s", u_value, count_value); + return img_format("RESTOREF 0x%" PRIx64 ", 0x%" PRIx64, + u_value, count_value); } From d03a008e82b58593a6da7a79e6341a7a3a45da43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Tue, 1 Nov 2022 12:44:56 +0100 Subject: [PATCH 674/705] disas/nanomips: Use G_GNUC_PRINTF to avoid invalid string formats MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Suggested-by: Stefan Weil Reviewed-by: Stefan Weil Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20221101114458.25756-4-philmd@linaro.org> --- disas/nanomips.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/disas/nanomips.c b/disas/nanomips.c index e4b21e7c45..3f45447292 100644 --- a/disas/nanomips.c +++ b/disas/nanomips.c @@ -95,7 +95,7 @@ typedef struct Pool { #define IMGASSERTONCE(test) -static char *img_format(const char *format, ...) +static char * G_GNUC_PRINTF(1, 2) img_format(const char *format, ...) { char *buffer; va_list args; From e9ebb6677b2c07690f8e6e05602a0efcd19d3f2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Tue, 1 Nov 2022 12:44:57 +0100 Subject: [PATCH 675/705] disas/nanomips: Remove headers already included by "qemu/osdep.h" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Stefan Weil Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20221101114458.25756-5-philmd@linaro.org> --- disas/nanomips.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/disas/nanomips.c b/disas/nanomips.c index 3f45447292..821d4f8832 100644 --- a/disas/nanomips.c +++ b/disas/nanomips.c @@ -30,10 +30,6 @@ #include "qemu/osdep.h" #include "disas/dis-asm.h" -#include -#include -#include - typedef int64_t int64; typedef uint64_t uint64; typedef uint32_t uint32; From 24449fc0f55ba99d4dbc6b3ab7ed495f43591c51 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 7 Nov 2022 08:28:47 +1100 Subject: [PATCH 676/705] disas/nanomips: Move setjmp into nanomips_dis MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reduce the number of local variables within the scope of the setjmp by moving it to the existing helper. The actual length returned from Disassemble is not used, because we have already determined the length while reading bytes. Fixes: nanomips.c: In function ‘print_insn_nanomips’: nanomips.c:21925:14: error: variable ‘insn1’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Werror=clobbered] nanomips.c:21925:25: error: variable ‘insn2’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Werror=clobbered] nanomips.c:21925:36: error: variable ‘insn3’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Werror=clobbered] nanomips.c:21926:22: error: variable ‘buf’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Werror=clobbered] Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson Message-Id: <20221106212852.152384-2-richard.henderson@linaro.org> --- disas/nanomips.c | 42 +++++++++++++++++------------------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/disas/nanomips.c b/disas/nanomips.c index 821d4f8832..83a39a878c 100644 --- a/disas/nanomips.c +++ b/disas/nanomips.c @@ -21907,22 +21907,24 @@ static const Pool MAJOR[2] = { 0x0 }, /* P16 */ }; -static int nanomips_dis(char **buf, - Dis_info *info, - unsigned short one, - unsigned short two, - unsigned short three) +static bool nanomips_dis(char **buf, Dis_info *info, + unsigned short one, + unsigned short two, + unsigned short three) { uint16 bits[3] = {one, two, three}; - TABLE_ENTRY_TYPE type; - int size = Disassemble(bits, buf, &type, MAJOR, 2, info); - return size; + + /* Handle runtime errors. */ + if (unlikely(sigsetjmp(info->buf, 0) != 0)) { + return false; + } + return Disassemble(bits, buf, &type, MAJOR, ARRAY_SIZE(MAJOR), info) >= 0; } int print_insn_nanomips(bfd_vma memaddr, struct disassemble_info *info) { - int status; + int status, length; bfd_byte buffer[2]; uint16_t insn1 = 0, insn2 = 0, insn3 = 0; g_autofree char *buf = NULL; @@ -21952,6 +21954,7 @@ int print_insn_nanomips(bfd_vma memaddr, struct disassemble_info *info) } else { insn1 = bfd_getl16(buffer); } + length = 2; (*info->fprintf_func)(info->stream, "%04x ", insn1); /* Handle 32-bit opcodes. */ @@ -21967,6 +21970,7 @@ int print_insn_nanomips(bfd_vma memaddr, struct disassemble_info *info) } else { insn2 = bfd_getl16(buffer); } + length = 4; (*info->fprintf_func)(info->stream, "%04x ", insn2); } else { (*info->fprintf_func)(info->stream, " "); @@ -21984,27 +21988,15 @@ int print_insn_nanomips(bfd_vma memaddr, struct disassemble_info *info) } else { insn3 = bfd_getl16(buffer); } + length = 6; (*info->fprintf_func)(info->stream, "%04x ", insn3); } else { (*info->fprintf_func)(info->stream, " "); } - /* Handle runtime errors. */ - if (sigsetjmp(disassm_info.buf, 0) != 0) { - info->insn_type = dis_noninsn; - return insn3 ? 6 : insn2 ? 4 : 2; + if (nanomips_dis(&buf, &disassm_info, insn1, insn2, insn3)) { + (*info->fprintf_func) (info->stream, "%s", buf); } - int length = nanomips_dis(&buf, &disassm_info, insn1, insn2, insn3); - - /* FIXME: Should probably use a hash table on the major opcode here. */ - - (*info->fprintf_func) (info->stream, "%s", buf); - if (length > 0) { - return length / 8; - } - - info->insn_type = dis_noninsn; - - return insn3 ? 6 : insn2 ? 4 : 2; + return length; } From ad120616edfe405e283a924fa3302b78605616d6 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 7 Nov 2022 08:28:48 +1100 Subject: [PATCH 677/705] disas/nanomips: Merge insn{1,2,3} into words[3] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since Disassemble wants the data in this format, collect it that way. This allows using a loop to print the bytes. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson Message-Id: <20221106212852.152384-3-richard.henderson@linaro.org> --- disas/nanomips.c | 44 +++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/disas/nanomips.c b/disas/nanomips.c index 83a39a878c..e462256760 100644 --- a/disas/nanomips.c +++ b/disas/nanomips.c @@ -21907,26 +21907,22 @@ static const Pool MAJOR[2] = { 0x0 }, /* P16 */ }; -static bool nanomips_dis(char **buf, Dis_info *info, - unsigned short one, - unsigned short two, - unsigned short three) +static bool nanomips_dis(const uint16_t *data, char **buf, Dis_info *info) { - uint16 bits[3] = {one, two, three}; TABLE_ENTRY_TYPE type; /* Handle runtime errors. */ if (unlikely(sigsetjmp(info->buf, 0) != 0)) { return false; } - return Disassemble(bits, buf, &type, MAJOR, ARRAY_SIZE(MAJOR), info) >= 0; + return Disassemble(data, buf, &type, MAJOR, ARRAY_SIZE(MAJOR), info) >= 0; } int print_insn_nanomips(bfd_vma memaddr, struct disassemble_info *info) { int status, length; bfd_byte buffer[2]; - uint16_t insn1 = 0, insn2 = 0, insn3 = 0; + uint16_t words[3] = { }; g_autofree char *buf = NULL; info->bytes_per_chunk = 2; @@ -21950,15 +21946,14 @@ int print_insn_nanomips(bfd_vma memaddr, struct disassemble_info *info) } if (info->endian == BFD_ENDIAN_BIG) { - insn1 = bfd_getb16(buffer); + words[0] = bfd_getb16(buffer); } else { - insn1 = bfd_getl16(buffer); + words[0] = bfd_getl16(buffer); } length = 2; - (*info->fprintf_func)(info->stream, "%04x ", insn1); /* Handle 32-bit opcodes. */ - if ((insn1 & 0x1000) == 0) { + if ((words[0] & 0x1000) == 0) { status = (*info->read_memory_func)(memaddr + 2, buffer, 2, info); if (status != 0) { (*info->memory_error_func)(status, memaddr + 2, info); @@ -21966,17 +21961,15 @@ int print_insn_nanomips(bfd_vma memaddr, struct disassemble_info *info) } if (info->endian == BFD_ENDIAN_BIG) { - insn2 = bfd_getb16(buffer); + words[1] = bfd_getb16(buffer); } else { - insn2 = bfd_getl16(buffer); + words[1] = bfd_getl16(buffer); } length = 4; - (*info->fprintf_func)(info->stream, "%04x ", insn2); - } else { - (*info->fprintf_func)(info->stream, " "); } + /* Handle 48-bit opcodes. */ - if ((insn1 >> 10) == 0x18) { + if ((words[0] >> 10) == 0x18) { status = (*info->read_memory_func)(memaddr + 4, buffer, 2, info); if (status != 0) { (*info->memory_error_func)(status, memaddr + 4, info); @@ -21984,17 +21977,22 @@ int print_insn_nanomips(bfd_vma memaddr, struct disassemble_info *info) } if (info->endian == BFD_ENDIAN_BIG) { - insn3 = bfd_getb16(buffer); + words[2] = bfd_getb16(buffer); } else { - insn3 = bfd_getl16(buffer); + words[2] = bfd_getl16(buffer); } length = 6; - (*info->fprintf_func)(info->stream, "%04x ", insn3); - } else { - (*info->fprintf_func)(info->stream, " "); } - if (nanomips_dis(&buf, &disassm_info, insn1, insn2, insn3)) { + for (int i = 0; i < ARRAY_SIZE(words); i++) { + if (i * 2 < length) { + (*info->fprintf_func)(info->stream, "%04x ", words[i]); + } else { + (*info->fprintf_func)(info->stream, " "); + } + } + + if (nanomips_dis(words, &buf, &disassm_info)) { (*info->fprintf_func) (info->stream, "%s", buf); } From 1414e3f5657a9f0c66495eb347ffd00df7978b4c Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sun, 6 Nov 2022 13:37:32 +1100 Subject: [PATCH 678/705] disas/nanomips: Split out read_u16 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split out a helper function for reading a uint16_t with the correct endianness. Signed-off-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20221106023735.5277-4-richard.henderson@linaro.org> --- disas/nanomips.c | 48 +++++++++++++++++++----------------------------- 1 file changed, 19 insertions(+), 29 deletions(-) diff --git a/disas/nanomips.c b/disas/nanomips.c index e462256760..3b998118e3 100644 --- a/disas/nanomips.c +++ b/disas/nanomips.c @@ -21918,10 +21918,24 @@ static bool nanomips_dis(const uint16_t *data, char **buf, Dis_info *info) return Disassemble(data, buf, &type, MAJOR, ARRAY_SIZE(MAJOR), info) >= 0; } +static bool read_u16(uint16_t *ret, bfd_vma memaddr, + struct disassemble_info *info) +{ + int status = (*info->read_memory_func)(memaddr, (bfd_byte *)ret, 2, info); + if (status != 0) { + (*info->memory_error_func)(status, memaddr, info); + return false; + } + + if ((info->endian == BFD_ENDIAN_BIG) != HOST_BIG_ENDIAN) { + bswap16s(ret); + } + return true; +} + int print_insn_nanomips(bfd_vma memaddr, struct disassemble_info *info) { - int status, length; - bfd_byte buffer[2]; + int length; uint16_t words[3] = { }; g_autofree char *buf = NULL; @@ -21939,48 +21953,24 @@ int print_insn_nanomips(bfd_vma memaddr, struct disassemble_info *info) disassm_info.fprintf_func = info->fprintf_func; disassm_info.stream = info->stream; - status = (*info->read_memory_func)(memaddr, buffer, 2, info); - if (status != 0) { - (*info->memory_error_func)(status, memaddr, info); + if (!read_u16(&words[0], memaddr, info)) { return -1; } - - if (info->endian == BFD_ENDIAN_BIG) { - words[0] = bfd_getb16(buffer); - } else { - words[0] = bfd_getl16(buffer); - } length = 2; /* Handle 32-bit opcodes. */ if ((words[0] & 0x1000) == 0) { - status = (*info->read_memory_func)(memaddr + 2, buffer, 2, info); - if (status != 0) { - (*info->memory_error_func)(status, memaddr + 2, info); + if (!read_u16(&words[1], memaddr + 2, info)) { return -1; } - - if (info->endian == BFD_ENDIAN_BIG) { - words[1] = bfd_getb16(buffer); - } else { - words[1] = bfd_getl16(buffer); - } length = 4; } /* Handle 48-bit opcodes. */ if ((words[0] >> 10) == 0x18) { - status = (*info->read_memory_func)(memaddr + 4, buffer, 2, info); - if (status != 0) { - (*info->memory_error_func)(status, memaddr + 4, info); + if (!read_u16(&words[1], memaddr + 4, info)) { return -1; } - - if (info->endian == BFD_ENDIAN_BIG) { - words[2] = bfd_getb16(buffer); - } else { - words[2] = bfd_getl16(buffer); - } length = 6; } From bb3daca71b58d11a13bc5979d1eb3c90b79452bc Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sun, 6 Nov 2022 13:37:33 +1100 Subject: [PATCH 679/705] disas/nanomips: Tidy read for 48-bit opcodes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no point in looking for a 48-bit opcode if we've not read the second word for a 32-bit opcode. Signed-off-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20221106023735.5277-5-richard.henderson@linaro.org> --- disas/nanomips.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/disas/nanomips.c b/disas/nanomips.c index 3b998118e3..a0253598dd 100644 --- a/disas/nanomips.c +++ b/disas/nanomips.c @@ -21964,14 +21964,14 @@ int print_insn_nanomips(bfd_vma memaddr, struct disassemble_info *info) return -1; } length = 4; - } - /* Handle 48-bit opcodes. */ - if ((words[0] >> 10) == 0x18) { - if (!read_u16(&words[1], memaddr + 4, info)) { - return -1; + /* Handle 48-bit opcodes. */ + if ((words[0] >> 10) == 0x18) { + if (!read_u16(&words[1], memaddr + 4, info)) { + return -1; + } + length = 6; } - length = 6; } for (int i = 0; i < ARRAY_SIZE(words); i++) { From 30dd5ff892d2f51025a5fd6be55f44d9506c7df8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sun, 30 Oct 2022 23:38:49 +0100 Subject: [PATCH 680/705] MAINTAINERS: Inherit from nanoMIPS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 6 months ago Stefan Pejic stepped in as nanoMIPS maintainer (see commit a 8e0e23445a "target/mips: Undeprecate nanoMIPS ISA support in QEMU"), however today his email is bouncing: ** Message blocked ** Your message to stefan.pejic@syrmia.com has been blocked. See technical details below for more information. The response from the remote server was: 550 5.4.1 Recipient address rejected: Access denied. AS(201806281) [DBAEUR03FT030.eop-EUR03.prod.protection.outlook.com] To avoid unmaintained code, I feel forced to merge this code back with the generic MIPS section. Historical references: - https://lore.kernel.org/qemu-devel/TY0PR03MB679726901BD6C6BE40114A2FE2A79@TY0PR03MB6797.apcprd03.prod.outlook.com/ - https://lore.kernel.org/qemu-devel/b858a20e97b74e7b90a94948314d0008@MTKMBS62N2.mediatek.inc/ Cc: Vince Del Vecchio Reviewed-by: Richard Henderson Message-Id: <49f41916-687f-b9e5-2de7-9c658fe0d4c7@linaro.org> Tested-by: Thomas Huth Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20221101114458.25756-6-philmd@linaro.org> --- MAINTAINERS | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 4adf8c65db..86bcd07a31 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -237,16 +237,10 @@ R: Jiaxun Yang R: Aleksandar Rikalo S: Odd Fixes F: target/mips/ -F: disas/mips.c +F: disas/*mips.c F: docs/system/cpu-models-mips.rst.inc F: tests/tcg/mips/ -MIPS TCG CPUs (nanoMIPS ISA) -M: Stefan Pejic -S: Maintained -F: disas/nanomips.* -F: target/mips/tcg/*nanomips* - NiosII TCG CPUs M: Chris Wulff M: Marek Vasut From 57702891376d4636b5eab4a89145152a0342c987 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Mon, 7 Nov 2022 17:13:48 +0100 Subject: [PATCH 681/705] Revert "s390x/s390-virtio-ccw: add zpcii-disable machine property" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 59d1ce44396e3ad2330dc3261ff3da7ad3a16184. The "zpcii-disable" machine property is redundant with the "interpret" zPCI device property. Remove it for clarification. Signed-off-by: Cédric Le Goater Message-Id: <20221107161349.1032730-2-clg@kaod.org> Reviewed-by: Matthew Rosato Signed-off-by: Thomas Huth --- hw/s390x/s390-pci-kvm.c | 4 +--- hw/s390x/s390-virtio-ccw.c | 24 ------------------------ include/hw/s390x/s390-virtio-ccw.h | 1 - qemu-options.hx | 8 +------- util/qemu-config.c | 4 ---- 5 files changed, 2 insertions(+), 39 deletions(-) diff --git a/hw/s390x/s390-pci-kvm.c b/hw/s390x/s390-pci-kvm.c index 5eb7fd12e2..9134fe185f 100644 --- a/hw/s390x/s390-pci-kvm.c +++ b/hw/s390x/s390-pci-kvm.c @@ -22,9 +22,7 @@ bool s390_pci_kvm_interp_allowed(void) { - return (kvm_s390_get_zpci_op() && !s390_is_pv() && - !object_property_get_bool(OBJECT(qdev_get_machine()), - "zpcii-disable", NULL)); + return kvm_s390_get_zpci_op() && !s390_is_pv(); } int s390_pci_kvm_aif_enable(S390PCIBusDevice *pbdev, ZpciFib *fib, bool assist) diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index 560ddbb6fb..bb98d40792 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -627,21 +627,6 @@ static inline void machine_set_dea_key_wrap(Object *obj, bool value, ms->dea_key_wrap = value; } -static inline bool machine_get_zpcii_disable(Object *obj, Error **errp) -{ - S390CcwMachineState *ms = S390_CCW_MACHINE(obj); - - return ms->zpcii_disable; -} - -static inline void machine_set_zpcii_disable(Object *obj, bool value, - Error **errp) -{ - S390CcwMachineState *ms = S390_CCW_MACHINE(obj); - - ms->zpcii_disable = value; -} - static S390CcwMachineClass *current_mc; /* @@ -778,12 +763,6 @@ static void ccw_machine_class_init(ObjectClass *oc, void *data) "Up to 8 chars in set of [A-Za-z0-9. ] (lower case chars converted" " to upper case) to pass to machine loader, boot manager," " and guest kernel"); - - object_class_property_add_bool(oc, "zpcii-disable", - machine_get_zpcii_disable, - machine_set_zpcii_disable); - object_class_property_set_description(oc, "zpcii-disable", - "disable zPCI interpretation facilties"); } static inline void s390_machine_initfn(Object *obj) @@ -792,7 +771,6 @@ static inline void s390_machine_initfn(Object *obj) ms->aes_key_wrap = true; ms->dea_key_wrap = true; - ms->zpcii_disable = false; } static const TypeInfo ccw_machine_info = { @@ -857,12 +835,10 @@ DEFINE_CCW_MACHINE(7_2, "7.2", true); static void ccw_machine_7_1_instance_options(MachineState *machine) { static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V7_1 }; - S390CcwMachineState *ms = S390_CCW_MACHINE(machine); ccw_machine_7_2_instance_options(machine); s390_cpudef_featoff_greater(16, 1, S390_FEAT_PAIE); s390_set_qemu_cpu_model(0x8561, 15, 1, qemu_cpu_feat); - ms->zpcii_disable = true; } static void ccw_machine_7_1_class_options(MachineClass *mc) diff --git a/include/hw/s390x/s390-virtio-ccw.h b/include/hw/s390x/s390-virtio-ccw.h index 4f8a39abda..9bba21a916 100644 --- a/include/hw/s390x/s390-virtio-ccw.h +++ b/include/hw/s390x/s390-virtio-ccw.h @@ -27,7 +27,6 @@ struct S390CcwMachineState { bool aes_key_wrap; bool dea_key_wrap; bool pv; - bool zpcii_disable; uint8_t loadparm[8]; }; diff --git a/qemu-options.hx b/qemu-options.hx index dbdf9c301b..8b8a4a5d01 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -37,8 +37,7 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \ " memory-encryption=@var{} memory encryption object to use (default=none)\n" " hmat=on|off controls ACPI HMAT support (default=off)\n" " memory-backend='backend-id' specifies explicitly provided backend for main RAM (default=none)\n" - " cxl-fmw.0.targets.0=firsttarget,cxl-fmw.0.targets.1=secondtarget,cxl-fmw.0.size=size[,cxl-fmw.0.interleave-granularity=granularity]\n" - " zpcii-disable=on|off disables zPCI interpretation facilities (default=off)\n", + " cxl-fmw.0.targets.0=firsttarget,cxl-fmw.0.targets.1=secondtarget,cxl-fmw.0.size=size[,cxl-fmw.0.interleave-granularity=granularity]\n", QEMU_ARCH_ALL) SRST ``-machine [type=]name[,prop=value[,...]]`` @@ -158,11 +157,6 @@ SRST :: -machine cxl-fmw.0.targets.0=cxl.0,cxl-fmw.0.targets.1=cxl.1,cxl-fmw.0.size=128G,cxl-fmw.0.interleave-granularity=512k - - ``zpcii-disable=on|off`` - Disables zPCI interpretation facilties on s390-ccw hosts. - This feature can be used to disable hardware virtual assists - related to zPCI devices. The default is off. ERST DEF("M", HAS_ARG, QEMU_OPTION_M, diff --git a/util/qemu-config.c b/util/qemu-config.c index 5325f6bf80..433488aa56 100644 --- a/util/qemu-config.c +++ b/util/qemu-config.c @@ -236,10 +236,6 @@ static QemuOptsList machine_opts = { .help = "Up to 8 chars in set of [A-Za-z0-9. ](lower case chars" " converted to upper case) to pass to machine" " loader, boot manager, and guest kernel", - },{ - .name = "zpcii-disable", - .type = QEMU_OPT_BOOL, - .help = "disable zPCI interpretation facilities", }, { /* End of list */ } } From d3d1a406127f7da482eafbdc871c120c2770bb91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Mon, 7 Nov 2022 17:13:49 +0100 Subject: [PATCH 682/705] s390x/s390-virtio-ccw: Switch off zPCI enhancements on older machines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit zPCI enhancement features (interpretation and forward assist) were recently introduced to improve performance on PCI passthrough devices. To maintain the same behaviour on older Z machines, deactivate the features with the associated properties. Signed-off-by: Cédric Le Goater Message-Id: <20221107161349.1032730-3-clg@kaod.org> Reviewed-by: Matthew Rosato Signed-off-by: Thomas Huth --- hw/s390x/s390-virtio-ccw.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index bb98d40792..7d80bc1837 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -844,9 +844,14 @@ static void ccw_machine_7_1_instance_options(MachineState *machine) static void ccw_machine_7_1_class_options(MachineClass *mc) { S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc); + static GlobalProperty compat[] = { + { TYPE_S390_PCI_DEVICE, "interpret", "off", }, + { TYPE_S390_PCI_DEVICE, "forwarding-assist", "off", }, + }; ccw_machine_7_2_class_options(mc); compat_props_add(mc->compat_props, hw_compat_7_1, hw_compat_7_1_len); + compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat)); s390mc->max_threads = S390_MAX_CPUS; } DEFINE_CCW_MACHINE(7_1, "7.1", false); From ef99aa2a31d6189f9eb39114f1752b1b980c766b Mon Sep 17 00:00:00 2001 From: Amarjargal Gundjalam Date: Tue, 25 Oct 2022 22:28:08 +0800 Subject: [PATCH 683/705] ui: fix tab indentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The TABs should be replaced with spaces, to make sure that we have a consistent coding style with an indentation of 4 spaces everywhere. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/370 Reviewed-by: Daniel P. Berrangé Signed-off-by: Amarjargal Gundjalam Message-Id: <9a0d0718aafaa52029fad76a149f3200b6bba0dd.1666707782.git.amarjargal16@gmail.com> Reviewed-by: Thomas Huth Signed-off-by: Thomas Huth --- ui/vgafont.h | 9214 +++++++++++++++++----------------- ui/vnc-enc-zywrle-template.c | 20 +- ui/vnc-enc-zywrle.h | 16 +- ui/vnc_keysym.h | 2 +- 4 files changed, 4626 insertions(+), 4626 deletions(-) diff --git a/ui/vgafont.h b/ui/vgafont.h index 3606dd7338..7e1fc473f7 100644 --- a/ui/vgafont.h +++ b/ui/vgafont.h @@ -1,4611 +1,4611 @@ static const uint8_t vgafont16[256 * 16] = { - /* 0 0x00 '^@' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 1 0x01 '^A' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x81, /* 10000001 */ - 0xa5, /* 10100101 */ - 0x81, /* 10000001 */ - 0x81, /* 10000001 */ - 0xbd, /* 10111101 */ - 0x99, /* 10011001 */ - 0x81, /* 10000001 */ - 0x81, /* 10000001 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 2 0x02 '^B' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0xff, /* 11111111 */ - 0xdb, /* 11011011 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xc3, /* 11000011 */ - 0xe7, /* 11100111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 3 0x03 '^C' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x6c, /* 01101100 */ - 0xfe, /* 11111110 */ - 0xfe, /* 11111110 */ - 0xfe, /* 11111110 */ - 0xfe, /* 11111110 */ - 0x7c, /* 01111100 */ - 0x38, /* 00111000 */ - 0x10, /* 00010000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 4 0x04 '^D' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x7c, /* 01111100 */ - 0xfe, /* 11111110 */ - 0x7c, /* 01111100 */ - 0x38, /* 00111000 */ - 0x10, /* 00010000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 5 0x05 '^E' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x3c, /* 00111100 */ - 0xe7, /* 11100111 */ - 0xe7, /* 11100111 */ - 0xe7, /* 11100111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 6 0x06 '^F' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x7e, /* 01111110 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 7 0x07 '^G' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 8 0x08 '^H' */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xe7, /* 11100111 */ - 0xc3, /* 11000011 */ - 0xc3, /* 11000011 */ - 0xe7, /* 11100111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - - /* 9 0x09 '^I' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0x42, /* 01000010 */ - 0x42, /* 01000010 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 10 0x0a '^J' */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xc3, /* 11000011 */ - 0x99, /* 10011001 */ - 0xbd, /* 10111101 */ - 0xbd, /* 10111101 */ - 0x99, /* 10011001 */ - 0xc3, /* 11000011 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - - /* 11 0x0b '^K' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x1e, /* 00011110 */ - 0x0e, /* 00001110 */ - 0x1a, /* 00011010 */ - 0x32, /* 00110010 */ - 0x78, /* 01111000 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x78, /* 01111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 12 0x0c '^L' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 13 0x0d '^M' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3f, /* 00111111 */ - 0x33, /* 00110011 */ - 0x3f, /* 00111111 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x70, /* 01110000 */ - 0xf0, /* 11110000 */ - 0xe0, /* 11100000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 14 0x0e '^N' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7f, /* 01111111 */ - 0x63, /* 01100011 */ - 0x7f, /* 01111111 */ - 0x63, /* 01100011 */ - 0x63, /* 01100011 */ - 0x63, /* 01100011 */ - 0x63, /* 01100011 */ - 0x67, /* 01100111 */ - 0xe7, /* 11100111 */ - 0xe6, /* 11100110 */ - 0xc0, /* 11000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 15 0x0f '^O' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xdb, /* 11011011 */ - 0x3c, /* 00111100 */ - 0xe7, /* 11100111 */ - 0x3c, /* 00111100 */ - 0xdb, /* 11011011 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 16 0x10 '^P' */ - 0x00, /* 00000000 */ - 0x80, /* 10000000 */ - 0xc0, /* 11000000 */ - 0xe0, /* 11100000 */ - 0xf0, /* 11110000 */ - 0xf8, /* 11111000 */ - 0xfe, /* 11111110 */ - 0xf8, /* 11111000 */ - 0xf0, /* 11110000 */ - 0xe0, /* 11100000 */ - 0xc0, /* 11000000 */ - 0x80, /* 10000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 17 0x11 '^Q' */ - 0x00, /* 00000000 */ - 0x02, /* 00000010 */ - 0x06, /* 00000110 */ - 0x0e, /* 00001110 */ - 0x1e, /* 00011110 */ - 0x3e, /* 00111110 */ - 0xfe, /* 11111110 */ - 0x3e, /* 00111110 */ - 0x1e, /* 00011110 */ - 0x0e, /* 00001110 */ - 0x06, /* 00000110 */ - 0x02, /* 00000010 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 18 0x12 '^R' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 19 0x13 '^S' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x00, /* 00000000 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 20 0x14 '^T' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7f, /* 01111111 */ - 0xdb, /* 11011011 */ - 0xdb, /* 11011011 */ - 0xdb, /* 11011011 */ - 0x7b, /* 01111011 */ - 0x1b, /* 00011011 */ - 0x1b, /* 00011011 */ - 0x1b, /* 00011011 */ - 0x1b, /* 00011011 */ - 0x1b, /* 00011011 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 21 0x15 '^U' */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0x60, /* 01100000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x0c, /* 00001100 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 22 0x16 '^V' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0xfe, /* 11111110 */ - 0xfe, /* 11111110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 23 0x17 '^W' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 24 0x18 '^X' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 25 0x19 '^Y' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 26 0x1a '^Z' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0xfe, /* 11111110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 27 0x1b '^[' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0xfe, /* 11111110 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 28 0x1c '^\' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 29 0x1d '^]' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x28, /* 00101000 */ - 0x6c, /* 01101100 */ - 0xfe, /* 11111110 */ - 0x6c, /* 01101100 */ - 0x28, /* 00101000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 30 0x1e '^^' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x38, /* 00111000 */ - 0x7c, /* 01111100 */ - 0x7c, /* 01111100 */ - 0xfe, /* 11111110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 31 0x1f '^_' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0xfe, /* 11111110 */ - 0x7c, /* 01111100 */ - 0x7c, /* 01111100 */ - 0x38, /* 00111000 */ - 0x38, /* 00111000 */ - 0x10, /* 00010000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 32 0x20 ' ' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 33 0x21 '!' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x3c, /* 00111100 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 34 0x22 '"' */ - 0x00, /* 00000000 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x24, /* 00100100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 35 0x23 '#' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0xfe, /* 11111110 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0xfe, /* 11111110 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 36 0x24 '$' */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc2, /* 11000010 */ - 0xc0, /* 11000000 */ - 0x7c, /* 01111100 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x86, /* 10000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 37 0x25 '%' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc2, /* 11000010 */ - 0xc6, /* 11000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0xc6, /* 11000110 */ - 0x86, /* 10000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 38 0x26 '&' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x76, /* 01110110 */ - 0xdc, /* 11011100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 39 0x27 ''' */ - 0x00, /* 00000000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 40 0x28 '(' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 41 0x29 ')' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 42 0x2a '*' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0xff, /* 11111111 */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 43 0x2b '+' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 44 0x2c ',' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 45 0x2d '-' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 46 0x2e '.' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 47 0x2f '/' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x02, /* 00000010 */ - 0x06, /* 00000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0xc0, /* 11000000 */ - 0x80, /* 10000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 48 0x30 '0' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xd6, /* 11010110 */ - 0xd6, /* 11010110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 49 0x31 '1' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x38, /* 00111000 */ - 0x78, /* 01111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 50 0x32 '2' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0x06, /* 00000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0xc0, /* 11000000 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 51 0x33 '3' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x3c, /* 00111100 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 52 0x34 '4' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x0c, /* 00001100 */ - 0x1c, /* 00011100 */ - 0x3c, /* 00111100 */ - 0x6c, /* 01101100 */ - 0xcc, /* 11001100 */ - 0xfe, /* 11111110 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x1e, /* 00011110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 53 0x35 '5' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xfc, /* 11111100 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 54 0x36 '6' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x60, /* 01100000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xfc, /* 11111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 55 0x37 '7' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 56 0x38 '8' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 57 0x39 '9' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7e, /* 01111110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x0c, /* 00001100 */ - 0x78, /* 01111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 58 0x3a ':' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 59 0x3b ';' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 60 0x3c '<' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x06, /* 00000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x06, /* 00000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 61 0x3d '=' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 62 0x3e '>' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x06, /* 00000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 63 0x3f '?' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 64 0x40 '@' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xde, /* 11011110 */ - 0xde, /* 11011110 */ - 0xde, /* 11011110 */ - 0xdc, /* 11011100 */ - 0xc0, /* 11000000 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 65 0x41 'A' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 66 0x42 'B' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfc, /* 11111100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x7c, /* 01111100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0xfc, /* 11111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 67 0x43 'C' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0xc2, /* 11000010 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc2, /* 11000010 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 68 0x44 'D' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xf8, /* 11111000 */ - 0x6c, /* 01101100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x6c, /* 01101100 */ - 0xf8, /* 11111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 69 0x45 'E' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x66, /* 01100110 */ - 0x62, /* 01100010 */ - 0x68, /* 01101000 */ - 0x78, /* 01111000 */ - 0x68, /* 01101000 */ - 0x60, /* 01100000 */ - 0x62, /* 01100010 */ - 0x66, /* 01100110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 70 0x46 'F' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x66, /* 01100110 */ - 0x62, /* 01100010 */ - 0x68, /* 01101000 */ - 0x78, /* 01111000 */ - 0x68, /* 01101000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0xf0, /* 11110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 71 0x47 'G' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0xc2, /* 11000010 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xde, /* 11011110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x66, /* 01100110 */ - 0x3a, /* 00111010 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 72 0x48 'H' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 73 0x49 'I' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 74 0x4a 'J' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x1e, /* 00011110 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x78, /* 01111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 75 0x4b 'K' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xe6, /* 11100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x6c, /* 01101100 */ - 0x78, /* 01111000 */ - 0x78, /* 01111000 */ - 0x6c, /* 01101100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0xe6, /* 11100110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 76 0x4c 'L' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xf0, /* 11110000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x62, /* 01100010 */ - 0x66, /* 01100110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 77 0x4d 'M' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xee, /* 11101110 */ - 0xfe, /* 11111110 */ - 0xfe, /* 11111110 */ - 0xd6, /* 11010110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 78 0x4e 'N' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xe6, /* 11100110 */ - 0xf6, /* 11110110 */ - 0xfe, /* 11111110 */ - 0xde, /* 11011110 */ - 0xce, /* 11001110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 79 0x4f 'O' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 80 0x50 'P' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfc, /* 11111100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x7c, /* 01111100 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0xf0, /* 11110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 81 0x51 'Q' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xd6, /* 11010110 */ - 0xde, /* 11011110 */ - 0x7c, /* 01111100 */ - 0x0c, /* 00001100 */ - 0x0e, /* 00001110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 82 0x52 'R' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfc, /* 11111100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x7c, /* 01111100 */ - 0x6c, /* 01101100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0xe6, /* 11100110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 83 0x53 'S' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x60, /* 01100000 */ - 0x38, /* 00111000 */ - 0x0c, /* 00001100 */ - 0x06, /* 00000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 84 0x54 'T' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x7e, /* 01111110 */ - 0x5a, /* 01011010 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 85 0x55 'U' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 86 0x56 'V' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x10, /* 00010000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 87 0x57 'W' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xd6, /* 11010110 */ - 0xd6, /* 11010110 */ - 0xd6, /* 11010110 */ - 0xfe, /* 11111110 */ - 0xee, /* 11101110 */ - 0x6c, /* 01101100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 88 0x58 'X' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x7c, /* 01111100 */ - 0x38, /* 00111000 */ - 0x38, /* 00111000 */ - 0x7c, /* 01111100 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 89 0x59 'Y' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 90 0x5a 'Z' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0x86, /* 10000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0xc2, /* 11000010 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 91 0x5b '[' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00111100 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 92 0x5c '\' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x80, /* 10000000 */ - 0xc0, /* 11000000 */ - 0xe0, /* 11100000 */ - 0x70, /* 01110000 */ - 0x38, /* 00111000 */ - 0x1c, /* 00011100 */ - 0x0e, /* 00001110 */ - 0x06, /* 00000110 */ - 0x02, /* 00000010 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 93 0x5d ']' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00111100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 94 0x5e '^' */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 95 0x5f '_' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 96 0x60 '`' */ - 0x00, /* 00000000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 97 0x61 'a' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x78, /* 01111000 */ - 0x0c, /* 00001100 */ - 0x7c, /* 01111100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 98 0x62 'b' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xe0, /* 11100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x78, /* 01111000 */ - 0x6c, /* 01101100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 99 0x63 'c' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 100 0x64 'd' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x1c, /* 00011100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x3c, /* 00111100 */ - 0x6c, /* 01101100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 101 0x65 'e' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 102 0x66 'f' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x1c, /* 00011100 */ - 0x36, /* 00110110 */ - 0x32, /* 00110010 */ - 0x30, /* 00110000 */ - 0x78, /* 01111000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x78, /* 01111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 103 0x67 'g' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x76, /* 01110110 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x7c, /* 01111100 */ - 0x0c, /* 00001100 */ - 0xcc, /* 11001100 */ - 0x78, /* 01111000 */ - 0x00, /* 00000000 */ - - /* 104 0x68 'h' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xe0, /* 11100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x6c, /* 01101100 */ - 0x76, /* 01110110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0xe6, /* 11100110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 105 0x69 'i' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 106 0x6a 'j' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x00, /* 00000000 */ - 0x0e, /* 00001110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - - /* 107 0x6b 'k' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xe0, /* 11100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x66, /* 01100110 */ - 0x6c, /* 01101100 */ - 0x78, /* 01111000 */ - 0x78, /* 01111000 */ - 0x6c, /* 01101100 */ - 0x66, /* 01100110 */ - 0xe6, /* 11100110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 108 0x6c 'l' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 109 0x6d 'm' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xec, /* 11101100 */ - 0xfe, /* 11111110 */ - 0xd6, /* 11010110 */ - 0xd6, /* 11010110 */ - 0xd6, /* 11010110 */ - 0xd6, /* 11010110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 110 0x6e 'n' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xdc, /* 11011100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 111 0x6f 'o' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 112 0x70 'p' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xdc, /* 11011100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x7c, /* 01111100 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0xf0, /* 11110000 */ - 0x00, /* 00000000 */ - - /* 113 0x71 'q' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x76, /* 01110110 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x7c, /* 01111100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x1e, /* 00011110 */ - 0x00, /* 00000000 */ - - /* 114 0x72 'r' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xdc, /* 11011100 */ - 0x76, /* 01110110 */ - 0x66, /* 01100110 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0xf0, /* 11110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 115 0x73 's' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0x60, /* 01100000 */ - 0x38, /* 00111000 */ - 0x0c, /* 00001100 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 116 0x74 't' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x10, /* 00010000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0xfc, /* 11111100 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x36, /* 00110110 */ - 0x1c, /* 00011100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 117 0x75 'u' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 118 0x76 'v' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 119 0x77 'w' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xd6, /* 11010110 */ - 0xd6, /* 11010110 */ - 0xd6, /* 11010110 */ - 0xfe, /* 11111110 */ - 0x6c, /* 01101100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 120 0x78 'x' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x38, /* 00111000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 121 0x79 'y' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7e, /* 01111110 */ - 0x06, /* 00000110 */ - 0x0c, /* 00001100 */ - 0xf8, /* 11111000 */ - 0x00, /* 00000000 */ - - /* 122 0x7a 'z' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0xcc, /* 11001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 123 0x7b '{' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x0e, /* 00001110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x70, /* 01110000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x0e, /* 00001110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 124 0x7c '|' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 125 0x7d '}' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x70, /* 01110000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x0e, /* 00001110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x70, /* 01110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 126 0x7e '~' */ - 0x00, /* 00000000 */ - 0x76, /* 01110110 */ - 0xdc, /* 11011100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 127 0x7f '' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 128 0x80 '€' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0xc2, /* 11000010 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc2, /* 11000010 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x70, /* 01110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 129 0x81 '' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xcc, /* 11001100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 130 0x82 '‚' */ - 0x00, /* 00000000 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 131 0x83 'ƒ' */ - 0x00, /* 00000000 */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0x00, /* 00000000 */ - 0x78, /* 01111000 */ - 0x0c, /* 00001100 */ - 0x7c, /* 01111100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 132 0x84 '„' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xcc, /* 11001100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x78, /* 01111000 */ - 0x0c, /* 00001100 */ - 0x7c, /* 01111100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 133 0x85 '…' */ - 0x00, /* 00000000 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x78, /* 01111000 */ - 0x0c, /* 00001100 */ - 0x7c, /* 01111100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 134 0x86 '†' */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x00, /* 00000000 */ - 0x78, /* 01111000 */ - 0x0c, /* 00001100 */ - 0x7c, /* 01111100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 135 0x87 '‡' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x18, /* 00011000 */ - 0x70, /* 01110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 136 0x88 'ˆ' */ - 0x00, /* 00000000 */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 137 0x89 '‰' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 138 0x8a 'Š' */ - 0x00, /* 00000000 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 139 0x8b '‹' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x66, /* 01100110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 140 0x8c 'Œ' */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 141 0x8d '' */ - 0x00, /* 00000000 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 142 0x8e 'Ž' */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 143 0x8f '' */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 144 0x90 '' */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x66, /* 01100110 */ - 0x62, /* 01100010 */ - 0x68, /* 01101000 */ - 0x78, /* 01111000 */ - 0x68, /* 01101000 */ - 0x62, /* 01100010 */ - 0x66, /* 01100110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 145 0x91 '‘' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xec, /* 11101100 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x7e, /* 01111110 */ - 0xd8, /* 11011000 */ - 0xd8, /* 11011000 */ - 0x6e, /* 01101110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 146 0x92 '’' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3e, /* 00111110 */ - 0x6c, /* 01101100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xfe, /* 11111110 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xce, /* 11001110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 147 0x93 '“' */ - 0x00, /* 00000000 */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 148 0x94 '”' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 149 0x95 '•' */ - 0x00, /* 00000000 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 150 0x96 '–' */ - 0x00, /* 00000000 */ - 0x30, /* 00110000 */ - 0x78, /* 01111000 */ - 0xcc, /* 11001100 */ - 0x00, /* 00000000 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 151 0x97 '—' */ - 0x00, /* 00000000 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 152 0x98 '˜' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7e, /* 01111110 */ - 0x06, /* 00000110 */ - 0x0c, /* 00001100 */ - 0x78, /* 01111000 */ - 0x00, /* 00000000 */ - - /* 153 0x99 '™' */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 154 0x9a 'š' */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 155 0x9b '›' */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 156 0x9c 'œ' */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0x64, /* 01100100 */ - 0x60, /* 01100000 */ - 0xf0, /* 11110000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0xe6, /* 11100110 */ - 0xfc, /* 11111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 157 0x9d '' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 158 0x9e 'ž' */ - 0x00, /* 00000000 */ - 0xf8, /* 11111000 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xf8, /* 11111000 */ - 0xc4, /* 11000100 */ - 0xcc, /* 11001100 */ - 0xde, /* 11011110 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 159 0x9f 'Ÿ' */ - 0x00, /* 00000000 */ - 0x0e, /* 00001110 */ - 0x1b, /* 00011011 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xd8, /* 11011000 */ - 0x70, /* 01110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 160 0xa0 ' ' */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0x00, /* 00000000 */ - 0x78, /* 01111000 */ - 0x0c, /* 00001100 */ - 0x7c, /* 01111100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 161 0xa1 '¡' */ - 0x00, /* 00000000 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 162 0xa2 '¢' */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 163 0xa3 '£' */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0x00, /* 00000000 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 164 0xa4 '¤' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x76, /* 01110110 */ - 0xdc, /* 11011100 */ - 0x00, /* 00000000 */ - 0xdc, /* 11011100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 165 0xa5 '¥' */ - 0x76, /* 01110110 */ - 0xdc, /* 11011100 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xe6, /* 11100110 */ - 0xf6, /* 11110110 */ - 0xfe, /* 11111110 */ - 0xde, /* 11011110 */ - 0xce, /* 11001110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 166 0xa6 '¦' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00111100 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x3e, /* 00111110 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 167 0xa7 '§' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 168 0xa8 '¨' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x00, /* 00000000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0xc0, /* 11000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 169 0xa9 '©' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 170 0xaa 'ª' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 171 0xab '«' */ - 0x00, /* 00000000 */ - 0x60, /* 01100000 */ - 0xe0, /* 11100000 */ - 0x62, /* 01100010 */ - 0x66, /* 01100110 */ - 0x6c, /* 01101100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0xdc, /* 11011100 */ - 0x86, /* 10000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x3e, /* 00111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 172 0xac '¬' */ - 0x00, /* 00000000 */ - 0x60, /* 01100000 */ - 0xe0, /* 11100000 */ - 0x62, /* 01100010 */ - 0x66, /* 01100110 */ - 0x6c, /* 01101100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x66, /* 01100110 */ - 0xce, /* 11001110 */ - 0x9a, /* 10011010 */ - 0x3f, /* 00111111 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 173 0xad '­' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x3c, /* 00111100 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 174 0xae '®' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x36, /* 00110110 */ - 0x6c, /* 01101100 */ - 0xd8, /* 11011000 */ - 0x6c, /* 01101100 */ - 0x36, /* 00110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 175 0xaf '¯' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xd8, /* 11011000 */ - 0x6c, /* 01101100 */ - 0x36, /* 00110110 */ - 0x6c, /* 01101100 */ - 0xd8, /* 11011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 176 0xb0 '°' */ - 0x11, /* 00010001 */ - 0x44, /* 01000100 */ - 0x11, /* 00010001 */ - 0x44, /* 01000100 */ - 0x11, /* 00010001 */ - 0x44, /* 01000100 */ - 0x11, /* 00010001 */ - 0x44, /* 01000100 */ - 0x11, /* 00010001 */ - 0x44, /* 01000100 */ - 0x11, /* 00010001 */ - 0x44, /* 01000100 */ - 0x11, /* 00010001 */ - 0x44, /* 01000100 */ - 0x11, /* 00010001 */ - 0x44, /* 01000100 */ - - /* 177 0xb1 '±' */ - 0x55, /* 01010101 */ - 0xaa, /* 10101010 */ - 0x55, /* 01010101 */ - 0xaa, /* 10101010 */ - 0x55, /* 01010101 */ - 0xaa, /* 10101010 */ - 0x55, /* 01010101 */ - 0xaa, /* 10101010 */ - 0x55, /* 01010101 */ - 0xaa, /* 10101010 */ - 0x55, /* 01010101 */ - 0xaa, /* 10101010 */ - 0x55, /* 01010101 */ - 0xaa, /* 10101010 */ - 0x55, /* 01010101 */ - 0xaa, /* 10101010 */ - - /* 178 0xb2 '²' */ - 0xdd, /* 11011101 */ - 0x77, /* 01110111 */ - 0xdd, /* 11011101 */ - 0x77, /* 01110111 */ - 0xdd, /* 11011101 */ - 0x77, /* 01110111 */ - 0xdd, /* 11011101 */ - 0x77, /* 01110111 */ - 0xdd, /* 11011101 */ - 0x77, /* 01110111 */ - 0xdd, /* 11011101 */ - 0x77, /* 01110111 */ - 0xdd, /* 11011101 */ - 0x77, /* 01110111 */ - 0xdd, /* 11011101 */ - 0x77, /* 01110111 */ - - /* 179 0xb3 '³' */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* 180 0xb4 '´' */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xf8, /* 11111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* 181 0xb5 'µ' */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xf8, /* 11111000 */ - 0x18, /* 00011000 */ - 0xf8, /* 11111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* 182 0xb6 '¶' */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0xf6, /* 11110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* 183 0xb7 '·' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* 184 0xb8 '¸' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xf8, /* 11111000 */ - 0x18, /* 00011000 */ - 0xf8, /* 11111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* 185 0xb9 '¹' */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0xf6, /* 11110110 */ - 0x06, /* 00000110 */ - 0xf6, /* 11110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* 186 0xba 'º' */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* 187 0xbb '»' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x06, /* 00000110 */ - 0xf6, /* 11110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* 188 0xbc '¼' */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0xf6, /* 11110110 */ - 0x06, /* 00000110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 189 0xbd '½' */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 190 0xbe '¾' */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xf8, /* 11111000 */ - 0x18, /* 00011000 */ - 0xf8, /* 11111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 191 0xbf '¿' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xf8, /* 11111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* 192 0xc0 'À' */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x1f, /* 00011111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 193 0xc1 'Á' */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 194 0xc2 'Â' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* 195 0xc3 'Ã' */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x1f, /* 00011111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* 196 0xc4 'Ä' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 197 0xc5 'Å' */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xff, /* 11111111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* 198 0xc6 'Æ' */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x1f, /* 00011111 */ - 0x18, /* 00011000 */ - 0x1f, /* 00011111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* 199 0xc7 'Ç' */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x37, /* 00110111 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* 200 0xc8 'È' */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x37, /* 00110111 */ - 0x30, /* 00110000 */ - 0x3f, /* 00111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 201 0xc9 'É' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3f, /* 00111111 */ - 0x30, /* 00110000 */ - 0x37, /* 00110111 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* 202 0xca 'Ê' */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0xf7, /* 11110111 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 203 0xcb 'Ë' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0xf7, /* 11110111 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* 204 0xcc 'Ì' */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x37, /* 00110111 */ - 0x30, /* 00110000 */ - 0x37, /* 00110111 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* 205 0xcd 'Í' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 206 0xce 'Î' */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0xf7, /* 11110111 */ - 0x00, /* 00000000 */ - 0xf7, /* 11110111 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* 207 0xcf 'Ï' */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 208 0xd0 'Ð' */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 209 0xd1 'Ñ' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* 210 0xd2 'Ò' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* 211 0xd3 'Ó' */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x3f, /* 00111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 212 0xd4 'Ô' */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x1f, /* 00011111 */ - 0x18, /* 00011000 */ - 0x1f, /* 00011111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 213 0xd5 'Õ' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x1f, /* 00011111 */ - 0x18, /* 00011000 */ - 0x1f, /* 00011111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* 214 0xd6 'Ö' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3f, /* 00111111 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* 215 0xd7 '×' */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0xff, /* 11111111 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* 216 0xd8 'Ø' */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xff, /* 11111111 */ - 0x18, /* 00011000 */ - 0xff, /* 11111111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* 217 0xd9 'Ù' */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xf8, /* 11111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 218 0xda 'Ú' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x1f, /* 00011111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* 219 0xdb 'Û' */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - - /* 220 0xdc 'Ü' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - - /* 221 0xdd 'Ý' */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - - /* 222 0xde 'Þ' */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - - /* 223 0xdf 'ß' */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 224 0xe0 'à' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x76, /* 01110110 */ - 0xdc, /* 11011100 */ - 0xd8, /* 11011000 */ - 0xd8, /* 11011000 */ - 0xd8, /* 11011000 */ - 0xdc, /* 11011100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 225 0xe1 'á' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x78, /* 01111000 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xd8, /* 11011000 */ - 0xcc, /* 11001100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xcc, /* 11001100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 226 0xe2 'â' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 227 0xe3 'ã' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 228 0xe4 'ä' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 229 0xe5 'å' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0xd8, /* 11011000 */ - 0xd8, /* 11011000 */ - 0xd8, /* 11011000 */ - 0xd8, /* 11011000 */ - 0xd8, /* 11011000 */ - 0x70, /* 01110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 230 0xe6 'æ' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x7c, /* 01111100 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0xc0, /* 11000000 */ - 0x00, /* 00000000 */ - - /* 231 0xe7 'ç' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x76, /* 01110110 */ - 0xdc, /* 11011100 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 232 0xe8 'è' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 233 0xe9 'é' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 234 0xea 'ê' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0xee, /* 11101110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 235 0xeb 'ë' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x1e, /* 00011110 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x3e, /* 00111110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 236 0xec 'ì' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0xdb, /* 11011011 */ - 0xdb, /* 11011011 */ - 0xdb, /* 11011011 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 237 0xed 'í' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x03, /* 00000011 */ - 0x06, /* 00000110 */ - 0x7e, /* 01111110 */ - 0xdb, /* 11011011 */ - 0xdb, /* 11011011 */ - 0xf3, /* 11110011 */ - 0x7e, /* 01111110 */ - 0x60, /* 01100000 */ - 0xc0, /* 11000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 238 0xee 'î' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x1c, /* 00011100 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x7c, /* 01111100 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x1c, /* 00011100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 239 0xef 'ï' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 240 0xf0 'ð' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 241 0xf1 'ñ' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 242 0xf2 'ò' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x06, /* 00000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 243 0xf3 'ó' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 244 0xf4 'ô' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x0e, /* 00001110 */ - 0x1b, /* 00011011 */ - 0x1b, /* 00011011 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* 245 0xf5 'õ' */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xd8, /* 11011000 */ - 0xd8, /* 11011000 */ - 0xd8, /* 11011000 */ - 0x70, /* 01110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 246 0xf6 'ö' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 247 0xf7 '÷' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x76, /* 01110110 */ - 0xdc, /* 11011100 */ - 0x00, /* 00000000 */ - 0x76, /* 01110110 */ - 0xdc, /* 11011100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 248 0xf8 'ø' */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 249 0xf9 'ù' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 250 0xfa 'ú' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 251 0xfb 'û' */ - 0x00, /* 00000000 */ - 0x0f, /* 00001111 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0xec, /* 11101100 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x3c, /* 00111100 */ - 0x1c, /* 00011100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 252 0xfc 'ü' */ - 0x00, /* 00000000 */ - 0x6c, /* 01101100 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 253 0xfd 'ý' */ - 0x00, /* 00000000 */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x32, /* 00110010 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 254 0xfe 'þ' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x7e, /* 01111110 */ - 0x7e, /* 01111110 */ - 0x7e, /* 01111110 */ - 0x7e, /* 01111110 */ - 0x7e, /* 01111110 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 255 0xff 'ÿ' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ + /* 0 0x00 '^@' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 1 0x01 '^A' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x81, /* 10000001 */ + 0xa5, /* 10100101 */ + 0x81, /* 10000001 */ + 0x81, /* 10000001 */ + 0xbd, /* 10111101 */ + 0x99, /* 10011001 */ + 0x81, /* 10000001 */ + 0x81, /* 10000001 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 2 0x02 '^B' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xff, /* 11111111 */ + 0xdb, /* 11011011 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xc3, /* 11000011 */ + 0xe7, /* 11100111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 3 0x03 '^C' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0x10, /* 00010000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 4 0x04 '^D' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x7c, /* 01111100 */ + 0xfe, /* 11111110 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0x10, /* 00010000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 5 0x05 '^E' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0xe7, /* 11100111 */ + 0xe7, /* 11100111 */ + 0xe7, /* 11100111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 6 0x06 '^F' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 7 0x07 '^G' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 8 0x08 '^H' */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xe7, /* 11100111 */ + 0xc3, /* 11000011 */ + 0xc3, /* 11000011 */ + 0xe7, /* 11100111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + + /* 9 0x09 '^I' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x42, /* 01000010 */ + 0x42, /* 01000010 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 10 0x0a '^J' */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xc3, /* 11000011 */ + 0x99, /* 10011001 */ + 0xbd, /* 10111101 */ + 0xbd, /* 10111101 */ + 0x99, /* 10011001 */ + 0xc3, /* 11000011 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + + /* 11 0x0b '^K' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1e, /* 00011110 */ + 0x0e, /* 00001110 */ + 0x1a, /* 00011010 */ + 0x32, /* 00110010 */ + 0x78, /* 01111000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 12 0x0c '^L' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 13 0x0d '^M' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3f, /* 00111111 */ + 0x33, /* 00110011 */ + 0x3f, /* 00111111 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x70, /* 01110000 */ + 0xf0, /* 11110000 */ + 0xe0, /* 11100000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 14 0x0e '^N' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7f, /* 01111111 */ + 0x63, /* 01100011 */ + 0x7f, /* 01111111 */ + 0x63, /* 01100011 */ + 0x63, /* 01100011 */ + 0x63, /* 01100011 */ + 0x63, /* 01100011 */ + 0x67, /* 01100111 */ + 0xe7, /* 11100111 */ + 0xe6, /* 11100110 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 15 0x0f '^O' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xdb, /* 11011011 */ + 0x3c, /* 00111100 */ + 0xe7, /* 11100111 */ + 0x3c, /* 00111100 */ + 0xdb, /* 11011011 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 16 0x10 '^P' */ + 0x00, /* 00000000 */ + 0x80, /* 10000000 */ + 0xc0, /* 11000000 */ + 0xe0, /* 11100000 */ + 0xf0, /* 11110000 */ + 0xf8, /* 11111000 */ + 0xfe, /* 11111110 */ + 0xf8, /* 11111000 */ + 0xf0, /* 11110000 */ + 0xe0, /* 11100000 */ + 0xc0, /* 11000000 */ + 0x80, /* 10000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 17 0x11 '^Q' */ + 0x00, /* 00000000 */ + 0x02, /* 00000010 */ + 0x06, /* 00000110 */ + 0x0e, /* 00001110 */ + 0x1e, /* 00011110 */ + 0x3e, /* 00111110 */ + 0xfe, /* 11111110 */ + 0x3e, /* 00111110 */ + 0x1e, /* 00011110 */ + 0x0e, /* 00001110 */ + 0x06, /* 00000110 */ + 0x02, /* 00000010 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 18 0x12 '^R' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 19 0x13 '^S' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 20 0x14 '^T' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7f, /* 01111111 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0x7b, /* 01111011 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 21 0x15 '^U' */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x60, /* 01100000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x0c, /* 00001100 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 22 0x16 '^V' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 23 0x17 '^W' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 24 0x18 '^X' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 25 0x19 '^Y' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 26 0x1a '^Z' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0xfe, /* 11111110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 27 0x1b '^[' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xfe, /* 11111110 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 28 0x1c '^\' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 29 0x1d '^]' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x28, /* 00101000 */ + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x28, /* 00101000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 30 0x1e '^^' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x38, /* 00111000 */ + 0x7c, /* 01111100 */ + 0x7c, /* 01111100 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 31 0x1f '^_' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0x7c, /* 01111100 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0x38, /* 00111000 */ + 0x10, /* 00010000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 32 0x20 ' ' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 33 0x21 '!' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 34 0x22 '"' */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x24, /* 00100100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 35 0x23 '#' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 36 0x24 '$' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc2, /* 11000010 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x86, /* 10000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 37 0x25 '%' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc2, /* 11000010 */ + 0xc6, /* 11000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc6, /* 11000110 */ + 0x86, /* 10000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 38 0x26 '&' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 39 0x27 ''' */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 40 0x28 '(' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 41 0x29 ')' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 42 0x2a '*' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0xff, /* 11111111 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 43 0x2b '+' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 44 0x2c ',' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 45 0x2d '-' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 46 0x2e '.' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 47 0x2f '/' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x02, /* 00000010 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0x80, /* 10000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 48 0x30 '0' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 49 0x31 '1' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x38, /* 00111000 */ + 0x78, /* 01111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 50 0x32 '2' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 51 0x33 '3' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x3c, /* 00111100 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 52 0x34 '4' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x0c, /* 00001100 */ + 0x1c, /* 00011100 */ + 0x3c, /* 00111100 */ + 0x6c, /* 01101100 */ + 0xcc, /* 11001100 */ + 0xfe, /* 11111110 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x1e, /* 00011110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 53 0x35 '5' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xfc, /* 11111100 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 54 0x36 '6' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 55 0x37 '7' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 56 0x38 '8' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 57 0x39 '9' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 58 0x3a ':' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 59 0x3b ';' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 60 0x3c '<' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x06, /* 00000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 61 0x3d '=' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 62 0x3e '>' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 63 0x3f '?' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 64 0x40 '@' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xde, /* 11011110 */ + 0xde, /* 11011110 */ + 0xde, /* 11011110 */ + 0xdc, /* 11011100 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 65 0x41 'A' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 66 0x42 'B' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfc, /* 11111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0xfc, /* 11111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 67 0x43 'C' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0xc2, /* 11000010 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc2, /* 11000010 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 68 0x44 'D' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xf8, /* 11111000 */ + 0x6c, /* 01101100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x6c, /* 01101100 */ + 0xf8, /* 11111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 69 0x45 'E' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x66, /* 01100110 */ + 0x62, /* 01100010 */ + 0x68, /* 01101000 */ + 0x78, /* 01111000 */ + 0x68, /* 01101000 */ + 0x60, /* 01100000 */ + 0x62, /* 01100010 */ + 0x66, /* 01100110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 70 0x46 'F' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x66, /* 01100110 */ + 0x62, /* 01100010 */ + 0x68, /* 01101000 */ + 0x78, /* 01111000 */ + 0x68, /* 01101000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 71 0x47 'G' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0xc2, /* 11000010 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xde, /* 11011110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x66, /* 01100110 */ + 0x3a, /* 00111010 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 72 0x48 'H' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 73 0x49 'I' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 74 0x4a 'J' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1e, /* 00011110 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 75 0x4b 'K' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xe6, /* 11100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x6c, /* 01101100 */ + 0x78, /* 01111000 */ + 0x78, /* 01111000 */ + 0x6c, /* 01101100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0xe6, /* 11100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 76 0x4c 'L' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xf0, /* 11110000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x62, /* 01100010 */ + 0x66, /* 01100110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 77 0x4d 'M' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xee, /* 11101110 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xd6, /* 11010110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 78 0x4e 'N' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xe6, /* 11100110 */ + 0xf6, /* 11110110 */ + 0xfe, /* 11111110 */ + 0xde, /* 11011110 */ + 0xce, /* 11001110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 79 0x4f 'O' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 80 0x50 'P' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfc, /* 11111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 81 0x51 'Q' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xd6, /* 11010110 */ + 0xde, /* 11011110 */ + 0x7c, /* 01111100 */ + 0x0c, /* 00001100 */ + 0x0e, /* 00001110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 82 0x52 'R' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfc, /* 11111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x6c, /* 01101100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0xe6, /* 11100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 83 0x53 'S' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x60, /* 01100000 */ + 0x38, /* 00111000 */ + 0x0c, /* 00001100 */ + 0x06, /* 00000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 84 0x54 'T' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x5a, /* 01011010 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 85 0x55 'U' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 86 0x56 'V' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x10, /* 00010000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 87 0x57 'W' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xfe, /* 11111110 */ + 0xee, /* 11101110 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 88 0x58 'X' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0x38, /* 00111000 */ + 0x7c, /* 01111100 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 89 0x59 'Y' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 90 0x5a 'Z' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0x86, /* 10000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc2, /* 11000010 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 91 0x5b '[' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 92 0x5c '\' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x80, /* 10000000 */ + 0xc0, /* 11000000 */ + 0xe0, /* 11100000 */ + 0x70, /* 01110000 */ + 0x38, /* 00111000 */ + 0x1c, /* 00011100 */ + 0x0e, /* 00001110 */ + 0x06, /* 00000110 */ + 0x02, /* 00000010 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 93 0x5d ']' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 94 0x5e '^' */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 95 0x5f '_' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 96 0x60 '`' */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 97 0x61 'a' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 98 0x62 'b' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xe0, /* 11100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x78, /* 01111000 */ + 0x6c, /* 01101100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 99 0x63 'c' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 100 0x64 'd' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1c, /* 00011100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x3c, /* 00111100 */ + 0x6c, /* 01101100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 101 0x65 'e' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 102 0x66 'f' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1c, /* 00011100 */ + 0x36, /* 00110110 */ + 0x32, /* 00110010 */ + 0x30, /* 00110000 */ + 0x78, /* 01111000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 103 0x67 'g' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x7c, /* 01111100 */ + 0x0c, /* 00001100 */ + 0xcc, /* 11001100 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + + /* 104 0x68 'h' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xe0, /* 11100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x6c, /* 01101100 */ + 0x76, /* 01110110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0xe6, /* 11100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 105 0x69 'i' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 106 0x6a 'j' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x00, /* 00000000 */ + 0x0e, /* 00001110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 107 0x6b 'k' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xe0, /* 11100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x66, /* 01100110 */ + 0x6c, /* 01101100 */ + 0x78, /* 01111000 */ + 0x78, /* 01111000 */ + 0x6c, /* 01101100 */ + 0x66, /* 01100110 */ + 0xe6, /* 11100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 108 0x6c 'l' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 109 0x6d 'm' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xec, /* 11101100 */ + 0xfe, /* 11111110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 110 0x6e 'n' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 111 0x6f 'o' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 112 0x70 'p' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x00, /* 00000000 */ + + /* 113 0x71 'q' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x7c, /* 01111100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x1e, /* 00011110 */ + 0x00, /* 00000000 */ + + /* 114 0x72 'r' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x76, /* 01110110 */ + 0x66, /* 01100110 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 115 0x73 's' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x60, /* 01100000 */ + 0x38, /* 00111000 */ + 0x0c, /* 00001100 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 116 0x74 't' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0xfc, /* 11111100 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x36, /* 00110110 */ + 0x1c, /* 00011100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 117 0x75 'u' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 118 0x76 'v' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 119 0x77 'w' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 120 0x78 'x' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x38, /* 00111000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 121 0x79 'y' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0xf8, /* 11111000 */ + 0x00, /* 00000000 */ + + /* 122 0x7a 'z' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xcc, /* 11001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 123 0x7b '{' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x0e, /* 00001110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x70, /* 01110000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x0e, /* 00001110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 124 0x7c '|' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 125 0x7d '}' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x70, /* 01110000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x0e, /* 00001110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 126 0x7e '~' */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 127 0x7f '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 128 0x80 '€' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0xc2, /* 11000010 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc2, /* 11000010 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 129 0x81 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 130 0x82 '‚' */ + 0x00, /* 00000000 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 131 0x83 'ƒ' */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 132 0x84 '„' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 133 0x85 '…' */ + 0x00, /* 00000000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 134 0x86 '†' */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 135 0x87 '‡' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x18, /* 00011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 136 0x88 'ˆ' */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 137 0x89 '‰' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 138 0x8a 'Š' */ + 0x00, /* 00000000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 139 0x8b '‹' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 140 0x8c 'Œ' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 141 0x8d '' */ + 0x00, /* 00000000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 142 0x8e 'Ž' */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 143 0x8f '' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 144 0x90 '' */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x66, /* 01100110 */ + 0x62, /* 01100010 */ + 0x68, /* 01101000 */ + 0x78, /* 01111000 */ + 0x68, /* 01101000 */ + 0x62, /* 01100010 */ + 0x66, /* 01100110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 145 0x91 '‘' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xec, /* 11101100 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x7e, /* 01111110 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0x6e, /* 01101110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 146 0x92 '’' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3e, /* 00111110 */ + 0x6c, /* 01101100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xfe, /* 11111110 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xce, /* 11001110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 147 0x93 '“' */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 148 0x94 '”' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 149 0x95 '•' */ + 0x00, /* 00000000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 150 0x96 '–' */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x78, /* 01111000 */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 151 0x97 '—' */ + 0x00, /* 00000000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 152 0x98 '˜' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + + /* 153 0x99 '™' */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 154 0x9a 'š' */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 155 0x9b '›' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 156 0x9c 'œ' */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x64, /* 01100100 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xe6, /* 11100110 */ + 0xfc, /* 11111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 157 0x9d '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 158 0x9e 'ž' */ + 0x00, /* 00000000 */ + 0xf8, /* 11111000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xf8, /* 11111000 */ + 0xc4, /* 11000100 */ + 0xcc, /* 11001100 */ + 0xde, /* 11011110 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 159 0x9f 'Ÿ' */ + 0x00, /* 00000000 */ + 0x0e, /* 00001110 */ + 0x1b, /* 00011011 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xd8, /* 11011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 160 0xa0 ' ' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 161 0xa1 '¡' */ + 0x00, /* 00000000 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 162 0xa2 '¢' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 163 0xa3 '£' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 164 0xa4 '¤' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 165 0xa5 '¥' */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xe6, /* 11100110 */ + 0xf6, /* 11110110 */ + 0xfe, /* 11111110 */ + 0xde, /* 11011110 */ + 0xce, /* 11001110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 166 0xa6 '¦' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x3e, /* 00111110 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 167 0xa7 '§' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 168 0xa8 '¨' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 169 0xa9 '©' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 170 0xaa 'ª' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 171 0xab '«' */ + 0x00, /* 00000000 */ + 0x60, /* 01100000 */ + 0xe0, /* 11100000 */ + 0x62, /* 01100010 */ + 0x66, /* 01100110 */ + 0x6c, /* 01101100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xdc, /* 11011100 */ + 0x86, /* 10000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x3e, /* 00111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 172 0xac '¬' */ + 0x00, /* 00000000 */ + 0x60, /* 01100000 */ + 0xe0, /* 11100000 */ + 0x62, /* 01100010 */ + 0x66, /* 01100110 */ + 0x6c, /* 01101100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x66, /* 01100110 */ + 0xce, /* 11001110 */ + 0x9a, /* 10011010 */ + 0x3f, /* 00111111 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 173 0xad '­' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 174 0xae '®' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x36, /* 00110110 */ + 0x6c, /* 01101100 */ + 0xd8, /* 11011000 */ + 0x6c, /* 01101100 */ + 0x36, /* 00110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 175 0xaf '¯' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xd8, /* 11011000 */ + 0x6c, /* 01101100 */ + 0x36, /* 00110110 */ + 0x6c, /* 01101100 */ + 0xd8, /* 11011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 176 0xb0 '°' */ + 0x11, /* 00010001 */ + 0x44, /* 01000100 */ + 0x11, /* 00010001 */ + 0x44, /* 01000100 */ + 0x11, /* 00010001 */ + 0x44, /* 01000100 */ + 0x11, /* 00010001 */ + 0x44, /* 01000100 */ + 0x11, /* 00010001 */ + 0x44, /* 01000100 */ + 0x11, /* 00010001 */ + 0x44, /* 01000100 */ + 0x11, /* 00010001 */ + 0x44, /* 01000100 */ + 0x11, /* 00010001 */ + 0x44, /* 01000100 */ + + /* 177 0xb1 '±' */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + + /* 178 0xb2 '²' */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + + /* 179 0xb3 '³' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 180 0xb4 '´' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 181 0xb5 'µ' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 182 0xb6 '¶' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf6, /* 11110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 183 0xb7 '·' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 184 0xb8 '¸' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 185 0xb9 '¹' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf6, /* 11110110 */ + 0x06, /* 00000110 */ + 0xf6, /* 11110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 186 0xba 'º' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 187 0xbb '»' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x06, /* 00000110 */ + 0xf6, /* 11110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 188 0xbc '¼' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf6, /* 11110110 */ + 0x06, /* 00000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 189 0xbd '½' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 190 0xbe '¾' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 191 0xbf '¿' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 192 0xc0 'À' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 193 0xc1 'Á' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 194 0xc2 'Â' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 195 0xc3 'Ã' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 196 0xc4 'Ä' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 197 0xc5 'Å' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 198 0xc6 'Æ' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 199 0xc7 'Ç' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x37, /* 00110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 200 0xc8 'È' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x37, /* 00110111 */ + 0x30, /* 00110000 */ + 0x3f, /* 00111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 201 0xc9 'É' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3f, /* 00111111 */ + 0x30, /* 00110000 */ + 0x37, /* 00110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 202 0xca 'Ê' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf7, /* 11110111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 203 0xcb 'Ë' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xf7, /* 11110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 204 0xcc 'Ì' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x37, /* 00110111 */ + 0x30, /* 00110000 */ + 0x37, /* 00110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 205 0xcd 'Í' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 206 0xce 'Î' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf7, /* 11110111 */ + 0x00, /* 00000000 */ + 0xf7, /* 11110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 207 0xcf 'Ï' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 208 0xd0 'Ð' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 209 0xd1 'Ñ' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 210 0xd2 'Ò' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 211 0xd3 'Ó' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x3f, /* 00111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 212 0xd4 'Ô' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 213 0xd5 'Õ' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 214 0xd6 'Ö' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3f, /* 00111111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 215 0xd7 '×' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xff, /* 11111111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 216 0xd8 'Ø' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 217 0xd9 'Ù' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 218 0xda 'Ú' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 219 0xdb 'Û' */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + + /* 220 0xdc 'Ü' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + + /* 221 0xdd 'Ý' */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + + /* 222 0xde 'Þ' */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + + /* 223 0xdf 'ß' */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 224 0xe0 'à' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0xdc, /* 11011100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 225 0xe1 'á' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xd8, /* 11011000 */ + 0xcc, /* 11001100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 226 0xe2 'â' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 227 0xe3 'ã' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 228 0xe4 'ä' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 229 0xe5 'å' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 230 0xe6 'æ' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + + /* 231 0xe7 'ç' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 232 0xe8 'è' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 233 0xe9 'é' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 234 0xea 'ê' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0xee, /* 11101110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 235 0xeb 'ë' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1e, /* 00011110 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x3e, /* 00111110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 236 0xec 'ì' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 237 0xed 'í' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x03, /* 00000011 */ + 0x06, /* 00000110 */ + 0x7e, /* 01111110 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0xf3, /* 11110011 */ + 0x7e, /* 01111110 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 238 0xee 'î' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1c, /* 00011100 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x7c, /* 01111100 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x1c, /* 00011100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 239 0xef 'ï' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 240 0xf0 'ð' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 241 0xf1 'ñ' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 242 0xf2 'ò' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 243 0xf3 'ó' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 244 0xf4 'ô' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x0e, /* 00001110 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 245 0xf5 'õ' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 246 0xf6 'ö' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 247 0xf7 '÷' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 248 0xf8 'ø' */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 249 0xf9 'ù' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 250 0xfa 'ú' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 251 0xfb 'û' */ + 0x00, /* 00000000 */ + 0x0f, /* 00001111 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0xec, /* 11101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x3c, /* 00111100 */ + 0x1c, /* 00011100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 252 0xfc 'ü' */ + 0x00, /* 00000000 */ + 0x6c, /* 01101100 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 253 0xfd 'ý' */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x32, /* 00110010 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 254 0xfe 'þ' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 255 0xff 'ÿ' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ }; diff --git a/ui/vnc-enc-zywrle-template.c b/ui/vnc-enc-zywrle-template.c index e9be55966e..4afa583e76 100644 --- a/ui/vnc-enc-zywrle-template.c +++ b/ui/vnc-enc-zywrle-template.c @@ -86,17 +86,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #undef L_2 #if ZYWRLE_ENDIAN == ENDIAN_BIG -# define S_0 1 -# define S_1 0 -# define L_0 3 -# define L_1 2 -# define L_2 1 +# define S_0 1 +# define S_1 0 +# define L_0 3 +# define L_1 2 +# define L_2 1 #else -# define S_0 0 -# define S_1 1 -# define L_0 0 -# define L_1 1 -# define L_2 2 +# define S_0 0 +# define S_1 1 +# define L_0 0 +# define L_1 1 +# define L_2 2 #endif #define ZYWRLE_QUANTIZE diff --git a/ui/vnc-enc-zywrle.h b/ui/vnc-enc-zywrle.h index 9b7f698975..e661ec117d 100644 --- a/ui/vnc-enc-zywrle.h +++ b/ui/vnc-enc-zywrle.h @@ -51,14 +51,14 @@ static const unsigned int zywrle_param[3][3]={ {0x0000F000, 0x00000000, 0x00000000}, {0x0000C000, 0x00F0F0F0, 0x00000000}, {0x0000C000, 0x00C0C0C0, 0x00F0F0F0}, -/* {0x0000FF00, 0x00000000, 0x00000000}, +/* {0x0000FF00, 0x00000000, 0x00000000}, {0x0000FF00, 0x00FFFFFF, 0x00000000}, {0x0000FF00, 0x00FFFFFF, 0x00FFFFFF}, */ }; #else /* Type B:Non liner quantization filter. */ static const int8_t zywrle_conv[4][256]={ -{ /* bi=5, bo=5 r=0.0:PSNR=24.849 */ +{ /* bi=5, bo=5 r=0.0:PSNR=24.849 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -92,7 +92,7 @@ static const int8_t zywrle_conv[4][256]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, -{ /* bi=5, bo=5 r=2.0:PSNR=74.031 */ +{ /* bi=5, bo=5 r=2.0:PSNR=74.031 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, @@ -126,7 +126,7 @@ static const int8_t zywrle_conv[4][256]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, -{ /* bi=5, bo=4 r=2.0:PSNR=64.441 */ +{ /* bi=5, bo=4 r=2.0:PSNR=64.441 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -160,7 +160,7 @@ static const int8_t zywrle_conv[4][256]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, -{ /* bi=5, bo=2 r=2.0:PSNR=43.175 */ +{ /* bi=5, bo=2 r=2.0:PSNR=43.175 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -274,14 +274,14 @@ static inline void harr(int8_t *px0, int8_t *px1) x1 += x0; if (((x1 ^ orgx1) & 0x80) == 0) { /* |x1| > |x0| */ - x0 -= x1; /* H = -B */ + x0 -= x1; /* H = -B */ } } else { /* same sign */ x0 -= x1; if (((x0 ^ orgx0) & 0x80) == 0) { /* |x0| > |x1| */ - x1 += x0; /* L = A */ + x1 += x0; /* L = A */ } } *px0 = (int8_t)x1; @@ -585,7 +585,7 @@ static inline void wavelet(int *buf, int width, int height, int level) } \ } while (0) -#define ZYWRLE_PACK_COEFF(buf, data, t, width, height, scanline, level) \ +#define ZYWRLE_PACK_COEFF(buf, data, t, width, height, scanline, level) \ ZYWRLE_TRANSFER_COEFF(buf, data, t, width, height, scanline, level, \ ZYWRLE_LOAD_COEFF(ph, r, g, b); \ ZYWRLE_SAVE_PIXEL(data, r, g, b);) diff --git a/ui/vnc_keysym.h b/ui/vnc_keysym.h index e8a2ec73c5..016405e74b 100644 --- a/ui/vnc_keysym.h +++ b/ui/vnc_keysym.h @@ -102,7 +102,7 @@ static const name2keysym_t name2keysym[]={ /* latin 1 extensions */ { "nobreakspace", 0x0a0}, { "exclamdown", 0x0a1}, -{ "cent", 0x0a2}, +{ "cent", 0x0a2}, { "sterling", 0x0a3}, { "currency", 0x0a4}, { "yen", 0x0a5}, From a076a3dcbf6cd5b038ce5ac8f419bb8d65f6432a Mon Sep 17 00:00:00 2001 From: Amarjargal Gundjalam Date: Tue, 25 Oct 2022 22:28:10 +0800 Subject: [PATCH 684/705] hw/display: fix tab indentation The TABs should be replaced with spaces, to make sure that we have a consistent coding style with an indentation of 4 spaces everywhere. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/370 Signed-off-by: Amarjargal Gundjalam Message-Id: <5cefd05b4d3721d416e48e6df19df18cb6338933.1666707782.git.amarjargal16@gmail.com> Reviewed-by: Thomas Huth Signed-off-by: Thomas Huth --- hw/display/blizzard.c | 352 ++++----- hw/display/cirrus_vga.c | 1600 +++++++++++++++++++-------------------- hw/display/omap_dss.c | 598 +++++++-------- hw/display/pxa2xx_lcd.c | 184 ++--- hw/display/vga_regs.h | 6 +- hw/display/xenfb.c | 258 +++---- 6 files changed, 1499 insertions(+), 1499 deletions(-) diff --git a/hw/display/blizzard.c b/hw/display/blizzard.c index ebe230dd0a..030abbe7d4 100644 --- a/hw/display/blizzard.c +++ b/hw/display/blizzard.c @@ -123,14 +123,14 @@ typedef struct { /* Bytes(!) per pixel */ static const int blizzard_iformat_bpp[0x10] = { 0, - 2, /* RGB 5:6:5*/ - 3, /* RGB 6:6:6 mode 1 */ - 3, /* RGB 8:8:8 mode 1 */ + 2, /* RGB 5:6:5*/ + 3, /* RGB 6:6:6 mode 1 */ + 3, /* RGB 8:8:8 mode 1 */ 0, 0, - 4, /* RGB 6:6:6 mode 2 */ - 4, /* RGB 8:8:8 mode 2 */ - 0, /* YUV 4:2:2 */ - 0, /* YUV 4:2:0 */ + 4, /* RGB 6:6:6 mode 2 */ + 4, /* RGB 8:8:8 mode 2 */ + 0, /* YUV 4:2:2 */ + 0, /* YUV 4:2:0 */ 0, 0, 0, 0, 0, 0, }; @@ -281,196 +281,196 @@ static uint16_t blizzard_reg_read(void *opaque, uint8_t reg) BlizzardState *s = (BlizzardState *) opaque; switch (reg) { - case 0x00: /* Revision Code */ + case 0x00: /* Revision Code */ return 0xa5; - case 0x02: /* Configuration Readback */ - return 0x83; /* Macrovision OK, CNF[2:0] = 3 */ + case 0x02: /* Configuration Readback */ + return 0x83; /* Macrovision OK, CNF[2:0] = 3 */ - case 0x04: /* PLL M-Divider */ + case 0x04: /* PLL M-Divider */ return (s->pll - 1) | (1 << 7); - case 0x06: /* PLL Lock Range Control */ + case 0x06: /* PLL Lock Range Control */ return s->pll_range; - case 0x08: /* PLL Lock Synthesis Control 0 */ + case 0x08: /* PLL Lock Synthesis Control 0 */ return s->pll_ctrl & 0xff; - case 0x0a: /* PLL Lock Synthesis Control 1 */ + case 0x0a: /* PLL Lock Synthesis Control 1 */ return s->pll_ctrl >> 8; - case 0x0c: /* PLL Mode Control 0 */ + case 0x0c: /* PLL Mode Control 0 */ return s->pll_mode; - case 0x0e: /* Clock-Source Select */ + case 0x0e: /* Clock-Source Select */ return s->clksel; - case 0x10: /* Memory Controller Activate */ - case 0x14: /* Memory Controller Bank 0 Status Flag */ + case 0x10: /* Memory Controller Activate */ + case 0x14: /* Memory Controller Bank 0 Status Flag */ return s->memenable; - case 0x18: /* Auto-Refresh Interval Setting 0 */ + case 0x18: /* Auto-Refresh Interval Setting 0 */ return s->memrefresh & 0xff; - case 0x1a: /* Auto-Refresh Interval Setting 1 */ + case 0x1a: /* Auto-Refresh Interval Setting 1 */ return s->memrefresh >> 8; - case 0x1c: /* Power-On Sequence Timing Control */ + case 0x1c: /* Power-On Sequence Timing Control */ return s->timing[0]; - case 0x1e: /* Timing Control 0 */ + case 0x1e: /* Timing Control 0 */ return s->timing[1]; - case 0x20: /* Timing Control 1 */ + case 0x20: /* Timing Control 1 */ return s->timing[2]; - case 0x24: /* Arbitration Priority Control */ + case 0x24: /* Arbitration Priority Control */ return s->priority; - case 0x28: /* LCD Panel Configuration */ + case 0x28: /* LCD Panel Configuration */ return s->lcd_config; - case 0x2a: /* LCD Horizontal Display Width */ + case 0x2a: /* LCD Horizontal Display Width */ return s->x >> 3; - case 0x2c: /* LCD Horizontal Non-display Period */ + case 0x2c: /* LCD Horizontal Non-display Period */ return s->hndp; - case 0x2e: /* LCD Vertical Display Height 0 */ + case 0x2e: /* LCD Vertical Display Height 0 */ return s->y & 0xff; - case 0x30: /* LCD Vertical Display Height 1 */ + case 0x30: /* LCD Vertical Display Height 1 */ return s->y >> 8; - case 0x32: /* LCD Vertical Non-display Period */ + case 0x32: /* LCD Vertical Non-display Period */ return s->vndp; - case 0x34: /* LCD HS Pulse-width */ + case 0x34: /* LCD HS Pulse-width */ return s->hsync; - case 0x36: /* LCd HS Pulse Start Position */ + case 0x36: /* LCd HS Pulse Start Position */ return s->skipx >> 3; - case 0x38: /* LCD VS Pulse-width */ + case 0x38: /* LCD VS Pulse-width */ return s->vsync; - case 0x3a: /* LCD VS Pulse Start Position */ + case 0x3a: /* LCD VS Pulse Start Position */ return s->skipy; - case 0x3c: /* PCLK Polarity */ + case 0x3c: /* PCLK Polarity */ return s->pclk; - case 0x3e: /* High-speed Serial Interface Tx Configuration Port 0 */ + case 0x3e: /* High-speed Serial Interface Tx Configuration Port 0 */ return s->hssi_config[0]; - case 0x40: /* High-speed Serial Interface Tx Configuration Port 1 */ + case 0x40: /* High-speed Serial Interface Tx Configuration Port 1 */ return s->hssi_config[1]; - case 0x42: /* High-speed Serial Interface Tx Mode */ + case 0x42: /* High-speed Serial Interface Tx Mode */ return s->hssi_config[2]; - case 0x44: /* TV Display Configuration */ + case 0x44: /* TV Display Configuration */ return s->tv_config; - case 0x46 ... 0x4c: /* TV Vertical Blanking Interval Data bits */ + case 0x46 ... 0x4c: /* TV Vertical Blanking Interval Data bits */ return s->tv_timing[(reg - 0x46) >> 1]; - case 0x4e: /* VBI: Closed Caption / XDS Control / Status */ + case 0x4e: /* VBI: Closed Caption / XDS Control / Status */ return s->vbi; - case 0x50: /* TV Horizontal Start Position */ + case 0x50: /* TV Horizontal Start Position */ return s->tv_x; - case 0x52: /* TV Vertical Start Position */ + case 0x52: /* TV Vertical Start Position */ return s->tv_y; - case 0x54: /* TV Test Pattern Setting */ + case 0x54: /* TV Test Pattern Setting */ return s->tv_test; - case 0x56: /* TV Filter Setting */ + case 0x56: /* TV Filter Setting */ return s->tv_filter_config; - case 0x58: /* TV Filter Coefficient Index */ + case 0x58: /* TV Filter Coefficient Index */ return s->tv_filter_idx; - case 0x5a: /* TV Filter Coefficient Data */ + case 0x5a: /* TV Filter Coefficient Data */ if (s->tv_filter_idx < 0x20) return s->tv_filter_coeff[s->tv_filter_idx ++]; return 0; - case 0x60: /* Input YUV/RGB Translate Mode 0 */ + case 0x60: /* Input YUV/RGB Translate Mode 0 */ return s->yrc[0]; - case 0x62: /* Input YUV/RGB Translate Mode 1 */ + case 0x62: /* Input YUV/RGB Translate Mode 1 */ return s->yrc[1]; - case 0x64: /* U Data Fix */ + case 0x64: /* U Data Fix */ return s->u; - case 0x66: /* V Data Fix */ + case 0x66: /* V Data Fix */ return s->v; - case 0x68: /* Display Mode */ + case 0x68: /* Display Mode */ return s->mode; - case 0x6a: /* Special Effects */ + case 0x6a: /* Special Effects */ return s->effect; - case 0x6c: /* Input Window X Start Position 0 */ + case 0x6c: /* Input Window X Start Position 0 */ return s->ix[0] & 0xff; - case 0x6e: /* Input Window X Start Position 1 */ + case 0x6e: /* Input Window X Start Position 1 */ return s->ix[0] >> 3; - case 0x70: /* Input Window Y Start Position 0 */ + case 0x70: /* Input Window Y Start Position 0 */ return s->ix[0] & 0xff; - case 0x72: /* Input Window Y Start Position 1 */ + case 0x72: /* Input Window Y Start Position 1 */ return s->ix[0] >> 3; - case 0x74: /* Input Window X End Position 0 */ + case 0x74: /* Input Window X End Position 0 */ return s->ix[1] & 0xff; - case 0x76: /* Input Window X End Position 1 */ + case 0x76: /* Input Window X End Position 1 */ return s->ix[1] >> 3; - case 0x78: /* Input Window Y End Position 0 */ + case 0x78: /* Input Window Y End Position 0 */ return s->ix[1] & 0xff; - case 0x7a: /* Input Window Y End Position 1 */ + case 0x7a: /* Input Window Y End Position 1 */ return s->ix[1] >> 3; - case 0x7c: /* Output Window X Start Position 0 */ + case 0x7c: /* Output Window X Start Position 0 */ return s->ox[0] & 0xff; - case 0x7e: /* Output Window X Start Position 1 */ + case 0x7e: /* Output Window X Start Position 1 */ return s->ox[0] >> 3; - case 0x80: /* Output Window Y Start Position 0 */ + case 0x80: /* Output Window Y Start Position 0 */ return s->oy[0] & 0xff; - case 0x82: /* Output Window Y Start Position 1 */ + case 0x82: /* Output Window Y Start Position 1 */ return s->oy[0] >> 3; - case 0x84: /* Output Window X End Position 0 */ + case 0x84: /* Output Window X End Position 0 */ return s->ox[1] & 0xff; - case 0x86: /* Output Window X End Position 1 */ + case 0x86: /* Output Window X End Position 1 */ return s->ox[1] >> 3; - case 0x88: /* Output Window Y End Position 0 */ + case 0x88: /* Output Window Y End Position 0 */ return s->oy[1] & 0xff; - case 0x8a: /* Output Window Y End Position 1 */ + case 0x8a: /* Output Window Y End Position 1 */ return s->oy[1] >> 3; - case 0x8c: /* Input Data Format */ + case 0x8c: /* Input Data Format */ return s->iformat; - case 0x8e: /* Data Source Select */ + case 0x8e: /* Data Source Select */ return s->source; - case 0x90: /* Display Memory Data Port */ + case 0x90: /* Display Memory Data Port */ return 0; - case 0xa8: /* Border Color 0 */ + case 0xa8: /* Border Color 0 */ return s->border_r; - case 0xaa: /* Border Color 1 */ + case 0xaa: /* Border Color 1 */ return s->border_g; - case 0xac: /* Border Color 2 */ + case 0xac: /* Border Color 2 */ return s->border_b; - case 0xb4: /* Gamma Correction Enable */ + case 0xb4: /* Gamma Correction Enable */ return s->gamma_config; - case 0xb6: /* Gamma Correction Table Index */ + case 0xb6: /* Gamma Correction Table Index */ return s->gamma_idx; - case 0xb8: /* Gamma Correction Table Data */ + case 0xb8: /* Gamma Correction Table Data */ return s->gamma_lut[s->gamma_idx ++]; - case 0xba: /* 3x3 Matrix Enable */ + case 0xba: /* 3x3 Matrix Enable */ return s->matrix_ena; - case 0xbc ... 0xde: /* Coefficient Registers */ + case 0xbc ... 0xde: /* Coefficient Registers */ return s->matrix_coeff[(reg - 0xbc) >> 1]; - case 0xe0: /* 3x3 Matrix Red Offset */ + case 0xe0: /* 3x3 Matrix Red Offset */ return s->matrix_r; - case 0xe2: /* 3x3 Matrix Green Offset */ + case 0xe2: /* 3x3 Matrix Green Offset */ return s->matrix_g; - case 0xe4: /* 3x3 Matrix Blue Offset */ + case 0xe4: /* 3x3 Matrix Blue Offset */ return s->matrix_b; - case 0xe6: /* Power-save */ + case 0xe6: /* Power-save */ return s->pm; - case 0xe8: /* Non-display Period Control / Status */ + case 0xe8: /* Non-display Period Control / Status */ return s->status | (1 << 5); - case 0xea: /* RGB Interface Control */ + case 0xea: /* RGB Interface Control */ return s->rgbgpio_dir; - case 0xec: /* RGB Interface Status */ + case 0xec: /* RGB Interface Status */ return s->rgbgpio; - case 0xee: /* General-purpose IO Pins Configuration */ + case 0xee: /* General-purpose IO Pins Configuration */ return s->gpio_dir; - case 0xf0: /* General-purpose IO Pins Status / Control */ + case 0xf0: /* General-purpose IO Pins Status / Control */ return s->gpio; - case 0xf2: /* GPIO Positive Edge Interrupt Trigger */ + case 0xf2: /* GPIO Positive Edge Interrupt Trigger */ return s->gpio_edge[0]; - case 0xf4: /* GPIO Negative Edge Interrupt Trigger */ + case 0xf4: /* GPIO Negative Edge Interrupt Trigger */ return s->gpio_edge[1]; - case 0xf6: /* GPIO Interrupt Status */ + case 0xf6: /* GPIO Interrupt Status */ return s->gpio_irq; - case 0xf8: /* GPIO Pull-down Control */ + case 0xf8: /* GPIO Pull-down Control */ return s->gpio_pdown; default: @@ -484,157 +484,157 @@ static void blizzard_reg_write(void *opaque, uint8_t reg, uint16_t value) BlizzardState *s = (BlizzardState *) opaque; switch (reg) { - case 0x04: /* PLL M-Divider */ + case 0x04: /* PLL M-Divider */ s->pll = (value & 0x3f) + 1; break; - case 0x06: /* PLL Lock Range Control */ + case 0x06: /* PLL Lock Range Control */ s->pll_range = value & 3; break; - case 0x08: /* PLL Lock Synthesis Control 0 */ + case 0x08: /* PLL Lock Synthesis Control 0 */ s->pll_ctrl &= 0xf00; s->pll_ctrl |= (value << 0) & 0x0ff; break; - case 0x0a: /* PLL Lock Synthesis Control 1 */ + case 0x0a: /* PLL Lock Synthesis Control 1 */ s->pll_ctrl &= 0x0ff; s->pll_ctrl |= (value << 8) & 0xf00; break; - case 0x0c: /* PLL Mode Control 0 */ + case 0x0c: /* PLL Mode Control 0 */ s->pll_mode = value & 0x77; if ((value & 3) == 0 || (value & 3) == 3) fprintf(stderr, "%s: wrong PLL Control bits (%i)\n", __func__, value & 3); break; - case 0x0e: /* Clock-Source Select */ + case 0x0e: /* Clock-Source Select */ s->clksel = value & 0xff; break; - case 0x10: /* Memory Controller Activate */ + case 0x10: /* Memory Controller Activate */ s->memenable = value & 1; break; - case 0x14: /* Memory Controller Bank 0 Status Flag */ + case 0x14: /* Memory Controller Bank 0 Status Flag */ break; - case 0x18: /* Auto-Refresh Interval Setting 0 */ + case 0x18: /* Auto-Refresh Interval Setting 0 */ s->memrefresh &= 0xf00; s->memrefresh |= (value << 0) & 0x0ff; break; - case 0x1a: /* Auto-Refresh Interval Setting 1 */ + case 0x1a: /* Auto-Refresh Interval Setting 1 */ s->memrefresh &= 0x0ff; s->memrefresh |= (value << 8) & 0xf00; break; - case 0x1c: /* Power-On Sequence Timing Control */ + case 0x1c: /* Power-On Sequence Timing Control */ s->timing[0] = value & 0x7f; break; - case 0x1e: /* Timing Control 0 */ + case 0x1e: /* Timing Control 0 */ s->timing[1] = value & 0x17; break; - case 0x20: /* Timing Control 1 */ + case 0x20: /* Timing Control 1 */ s->timing[2] = value & 0x35; break; - case 0x24: /* Arbitration Priority Control */ + case 0x24: /* Arbitration Priority Control */ s->priority = value & 1; break; - case 0x28: /* LCD Panel Configuration */ + case 0x28: /* LCD Panel Configuration */ s->lcd_config = value & 0xff; if (value & (1 << 7)) fprintf(stderr, "%s: data swap not supported!\n", __func__); break; - case 0x2a: /* LCD Horizontal Display Width */ + case 0x2a: /* LCD Horizontal Display Width */ s->x = value << 3; break; - case 0x2c: /* LCD Horizontal Non-display Period */ + case 0x2c: /* LCD Horizontal Non-display Period */ s->hndp = value & 0xff; break; - case 0x2e: /* LCD Vertical Display Height 0 */ + case 0x2e: /* LCD Vertical Display Height 0 */ s->y &= 0x300; s->y |= (value << 0) & 0x0ff; break; - case 0x30: /* LCD Vertical Display Height 1 */ + case 0x30: /* LCD Vertical Display Height 1 */ s->y &= 0x0ff; s->y |= (value << 8) & 0x300; break; - case 0x32: /* LCD Vertical Non-display Period */ + case 0x32: /* LCD Vertical Non-display Period */ s->vndp = value & 0xff; break; - case 0x34: /* LCD HS Pulse-width */ + case 0x34: /* LCD HS Pulse-width */ s->hsync = value & 0xff; break; - case 0x36: /* LCD HS Pulse Start Position */ + case 0x36: /* LCD HS Pulse Start Position */ s->skipx = value & 0xff; break; - case 0x38: /* LCD VS Pulse-width */ + case 0x38: /* LCD VS Pulse-width */ s->vsync = value & 0xbf; break; - case 0x3a: /* LCD VS Pulse Start Position */ + case 0x3a: /* LCD VS Pulse Start Position */ s->skipy = value & 0xff; break; - case 0x3c: /* PCLK Polarity */ + case 0x3c: /* PCLK Polarity */ s->pclk = value & 0x82; /* Affects calculation of s->hndp, s->hsync and s->skipx. */ break; - case 0x3e: /* High-speed Serial Interface Tx Configuration Port 0 */ + case 0x3e: /* High-speed Serial Interface Tx Configuration Port 0 */ s->hssi_config[0] = value; break; - case 0x40: /* High-speed Serial Interface Tx Configuration Port 1 */ + case 0x40: /* High-speed Serial Interface Tx Configuration Port 1 */ s->hssi_config[1] = value; if (((value >> 4) & 3) == 3) fprintf(stderr, "%s: Illegal active-data-links value\n", __func__); break; - case 0x42: /* High-speed Serial Interface Tx Mode */ + case 0x42: /* High-speed Serial Interface Tx Mode */ s->hssi_config[2] = value & 0xbd; break; - case 0x44: /* TV Display Configuration */ + case 0x44: /* TV Display Configuration */ s->tv_config = value & 0xfe; break; - case 0x46 ... 0x4c: /* TV Vertical Blanking Interval Data bits 0 */ + case 0x46 ... 0x4c: /* TV Vertical Blanking Interval Data bits 0 */ s->tv_timing[(reg - 0x46) >> 1] = value; break; - case 0x4e: /* VBI: Closed Caption / XDS Control / Status */ + case 0x4e: /* VBI: Closed Caption / XDS Control / Status */ s->vbi = value; break; - case 0x50: /* TV Horizontal Start Position */ + case 0x50: /* TV Horizontal Start Position */ s->tv_x = value; break; - case 0x52: /* TV Vertical Start Position */ + case 0x52: /* TV Vertical Start Position */ s->tv_y = value & 0x7f; break; - case 0x54: /* TV Test Pattern Setting */ + case 0x54: /* TV Test Pattern Setting */ s->tv_test = value; break; - case 0x56: /* TV Filter Setting */ + case 0x56: /* TV Filter Setting */ s->tv_filter_config = value & 0xbf; break; - case 0x58: /* TV Filter Coefficient Index */ + case 0x58: /* TV Filter Coefficient Index */ s->tv_filter_idx = value & 0x1f; break; - case 0x5a: /* TV Filter Coefficient Data */ + case 0x5a: /* TV Filter Coefficient Data */ if (s->tv_filter_idx < 0x20) s->tv_filter_coeff[s->tv_filter_idx ++] = value; break; - case 0x60: /* Input YUV/RGB Translate Mode 0 */ + case 0x60: /* Input YUV/RGB Translate Mode 0 */ s->yrc[0] = value & 0xb0; break; - case 0x62: /* Input YUV/RGB Translate Mode 1 */ + case 0x62: /* Input YUV/RGB Translate Mode 1 */ s->yrc[1] = value & 0x30; break; - case 0x64: /* U Data Fix */ + case 0x64: /* U Data Fix */ s->u = value & 0xff; break; - case 0x66: /* V Data Fix */ + case 0x66: /* V Data Fix */ s->v = value & 0xff; break; - case 0x68: /* Display Mode */ + case 0x68: /* Display Mode */ if ((s->mode ^ value) & 3) s->invalidate = 1; s->mode = value & 0xb7; @@ -644,83 +644,83 @@ static void blizzard_reg_write(void *opaque, uint8_t reg, uint16_t value) fprintf(stderr, "%s: Macrovision enable attempt!\n", __func__); break; - case 0x6a: /* Special Effects */ + case 0x6a: /* Special Effects */ s->effect = value & 0xfb; break; - case 0x6c: /* Input Window X Start Position 0 */ + case 0x6c: /* Input Window X Start Position 0 */ s->ix[0] &= 0x300; s->ix[0] |= (value << 0) & 0x0ff; break; - case 0x6e: /* Input Window X Start Position 1 */ + case 0x6e: /* Input Window X Start Position 1 */ s->ix[0] &= 0x0ff; s->ix[0] |= (value << 8) & 0x300; break; - case 0x70: /* Input Window Y Start Position 0 */ + case 0x70: /* Input Window Y Start Position 0 */ s->iy[0] &= 0x300; s->iy[0] |= (value << 0) & 0x0ff; break; - case 0x72: /* Input Window Y Start Position 1 */ + case 0x72: /* Input Window Y Start Position 1 */ s->iy[0] &= 0x0ff; s->iy[0] |= (value << 8) & 0x300; break; - case 0x74: /* Input Window X End Position 0 */ + case 0x74: /* Input Window X End Position 0 */ s->ix[1] &= 0x300; s->ix[1] |= (value << 0) & 0x0ff; break; - case 0x76: /* Input Window X End Position 1 */ + case 0x76: /* Input Window X End Position 1 */ s->ix[1] &= 0x0ff; s->ix[1] |= (value << 8) & 0x300; break; - case 0x78: /* Input Window Y End Position 0 */ + case 0x78: /* Input Window Y End Position 0 */ s->iy[1] &= 0x300; s->iy[1] |= (value << 0) & 0x0ff; break; - case 0x7a: /* Input Window Y End Position 1 */ + case 0x7a: /* Input Window Y End Position 1 */ s->iy[1] &= 0x0ff; s->iy[1] |= (value << 8) & 0x300; break; - case 0x7c: /* Output Window X Start Position 0 */ + case 0x7c: /* Output Window X Start Position 0 */ s->ox[0] &= 0x300; s->ox[0] |= (value << 0) & 0x0ff; break; - case 0x7e: /* Output Window X Start Position 1 */ + case 0x7e: /* Output Window X Start Position 1 */ s->ox[0] &= 0x0ff; s->ox[0] |= (value << 8) & 0x300; break; - case 0x80: /* Output Window Y Start Position 0 */ + case 0x80: /* Output Window Y Start Position 0 */ s->oy[0] &= 0x300; s->oy[0] |= (value << 0) & 0x0ff; break; - case 0x82: /* Output Window Y Start Position 1 */ + case 0x82: /* Output Window Y Start Position 1 */ s->oy[0] &= 0x0ff; s->oy[0] |= (value << 8) & 0x300; break; - case 0x84: /* Output Window X End Position 0 */ + case 0x84: /* Output Window X End Position 0 */ s->ox[1] &= 0x300; s->ox[1] |= (value << 0) & 0x0ff; break; - case 0x86: /* Output Window X End Position 1 */ + case 0x86: /* Output Window X End Position 1 */ s->ox[1] &= 0x0ff; s->ox[1] |= (value << 8) & 0x300; break; - case 0x88: /* Output Window Y End Position 0 */ + case 0x88: /* Output Window Y End Position 0 */ s->oy[1] &= 0x300; s->oy[1] |= (value << 0) & 0x0ff; break; - case 0x8a: /* Output Window Y End Position 1 */ + case 0x8a: /* Output Window Y End Position 1 */ s->oy[1] &= 0x0ff; s->oy[1] |= (value << 8) & 0x300; break; - case 0x8c: /* Input Data Format */ + case 0x8c: /* Input Data Format */ s->iformat = value & 0xf; s->bpp = blizzard_iformat_bpp[s->iformat]; if (!s->bpp) fprintf(stderr, "%s: Illegal or unsupported input format %x\n", __func__, s->iformat); break; - case 0x8e: /* Data Source Select */ + case 0x8e: /* Data Source Select */ s->source = value & 7; /* Currently all windows will be "destructive overlays". */ if ((!(s->effect & (1 << 3)) && (s->ix[0] != s->ox[0] || @@ -735,7 +735,7 @@ static void blizzard_reg_write(void *opaque, uint8_t reg, uint16_t value) blizzard_transfer_setup(s); break; - case 0x90: /* Display Memory Data Port */ + case 0x90: /* Display Memory Data Port */ if (!s->data.len && !blizzard_transfer_setup(s)) break; @@ -744,73 +744,73 @@ static void blizzard_reg_write(void *opaque, uint8_t reg, uint16_t value) blizzard_window(s); break; - case 0xa8: /* Border Color 0 */ + case 0xa8: /* Border Color 0 */ s->border_r = value; break; - case 0xaa: /* Border Color 1 */ + case 0xaa: /* Border Color 1 */ s->border_g = value; break; - case 0xac: /* Border Color 2 */ + case 0xac: /* Border Color 2 */ s->border_b = value; break; - case 0xb4: /* Gamma Correction Enable */ + case 0xb4: /* Gamma Correction Enable */ s->gamma_config = value & 0x87; break; - case 0xb6: /* Gamma Correction Table Index */ + case 0xb6: /* Gamma Correction Table Index */ s->gamma_idx = value; break; - case 0xb8: /* Gamma Correction Table Data */ + case 0xb8: /* Gamma Correction Table Data */ s->gamma_lut[s->gamma_idx ++] = value; break; - case 0xba: /* 3x3 Matrix Enable */ + case 0xba: /* 3x3 Matrix Enable */ s->matrix_ena = value & 1; break; - case 0xbc ... 0xde: /* Coefficient Registers */ + case 0xbc ... 0xde: /* Coefficient Registers */ s->matrix_coeff[(reg - 0xbc) >> 1] = value & ((reg & 2) ? 0x80 : 0xff); break; - case 0xe0: /* 3x3 Matrix Red Offset */ + case 0xe0: /* 3x3 Matrix Red Offset */ s->matrix_r = value; break; - case 0xe2: /* 3x3 Matrix Green Offset */ + case 0xe2: /* 3x3 Matrix Green Offset */ s->matrix_g = value; break; - case 0xe4: /* 3x3 Matrix Blue Offset */ + case 0xe4: /* 3x3 Matrix Blue Offset */ s->matrix_b = value; break; - case 0xe6: /* Power-save */ + case 0xe6: /* Power-save */ s->pm = value & 0x83; if (value & s->mode & 1) fprintf(stderr, "%s: The display must be disabled before entering " "Standby Mode\n", __func__); break; - case 0xe8: /* Non-display Period Control / Status */ + case 0xe8: /* Non-display Period Control / Status */ s->status = value & 0x1b; break; - case 0xea: /* RGB Interface Control */ + case 0xea: /* RGB Interface Control */ s->rgbgpio_dir = value & 0x8f; break; - case 0xec: /* RGB Interface Status */ + case 0xec: /* RGB Interface Status */ s->rgbgpio = value & 0xcf; break; - case 0xee: /* General-purpose IO Pins Configuration */ + case 0xee: /* General-purpose IO Pins Configuration */ s->gpio_dir = value; break; - case 0xf0: /* General-purpose IO Pins Status / Control */ + case 0xf0: /* General-purpose IO Pins Status / Control */ s->gpio = value; break; - case 0xf2: /* GPIO Positive Edge Interrupt Trigger */ + case 0xf2: /* GPIO Positive Edge Interrupt Trigger */ s->gpio_edge[0] = value; break; - case 0xf4: /* GPIO Negative Edge Interrupt Trigger */ + case 0xf4: /* GPIO Negative Edge Interrupt Trigger */ s->gpio_edge[1] = value; break; - case 0xf6: /* GPIO Interrupt Status */ + case 0xf6: /* GPIO Interrupt Status */ s->gpio_irq &= value; break; - case 0xf8: /* GPIO Pull-down Control */ + case 0xf8: /* GPIO Pull-down Control */ s->gpio_pdown = value; break; diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c index 2577005d03..c1e719a405 100644 --- a/hw/display/cirrus_vga.c +++ b/hw/display/cirrus_vga.c @@ -76,12 +76,12 @@ #define CIRRUS_MEMSIZE_512k 0x08 #define CIRRUS_MEMSIZE_1M 0x10 #define CIRRUS_MEMSIZE_2M 0x18 -#define CIRRUS_MEMFLAGS_BANKSWITCH 0x80 // bank switching is enabled. +#define CIRRUS_MEMFLAGS_BANKSWITCH 0x80 // bank switching is enabled. // sequencer 0x12 #define CIRRUS_CURSOR_SHOW 0x01 #define CIRRUS_CURSOR_HIDDENPEL 0x02 -#define CIRRUS_CURSOR_LARGE 0x04 // 64x64 if set, 32x32 if clear +#define CIRRUS_CURSOR_LARGE 0x04 // 64x64 if set, 32x32 if clear // sequencer 0x17 #define CIRRUS_BUSTYPE_VLBFAST 0x10 @@ -89,12 +89,12 @@ #define CIRRUS_BUSTYPE_VLBSLOW 0x30 #define CIRRUS_BUSTYPE_ISA 0x38 #define CIRRUS_MMIO_ENABLE 0x04 -#define CIRRUS_MMIO_USE_PCIADDR 0x40 // 0xb8000 if cleared. +#define CIRRUS_MMIO_USE_PCIADDR 0x40 // 0xb8000 if cleared. #define CIRRUS_MEMSIZEEXT_DOUBLE 0x80 // control 0x0b #define CIRRUS_BANKING_DUAL 0x01 -#define CIRRUS_BANKING_GRANULARITY_16K 0x20 // set:16k, clear:4k +#define CIRRUS_BANKING_GRANULARITY_16K 0x20 // set:16k, clear:4k // control 0x30 #define CIRRUS_BLTMODE_BACKWARDS 0x01 @@ -143,35 +143,35 @@ #define CIRRUS_BLTMODEEXT_DWORDGRANULARITY 0x01 // memory-mapped IO -#define CIRRUS_MMIO_BLTBGCOLOR 0x00 // dword -#define CIRRUS_MMIO_BLTFGCOLOR 0x04 // dword -#define CIRRUS_MMIO_BLTWIDTH 0x08 // word -#define CIRRUS_MMIO_BLTHEIGHT 0x0a // word -#define CIRRUS_MMIO_BLTDESTPITCH 0x0c // word -#define CIRRUS_MMIO_BLTSRCPITCH 0x0e // word -#define CIRRUS_MMIO_BLTDESTADDR 0x10 // dword -#define CIRRUS_MMIO_BLTSRCADDR 0x14 // dword -#define CIRRUS_MMIO_BLTWRITEMASK 0x17 // byte -#define CIRRUS_MMIO_BLTMODE 0x18 // byte -#define CIRRUS_MMIO_BLTROP 0x1a // byte -#define CIRRUS_MMIO_BLTMODEEXT 0x1b // byte -#define CIRRUS_MMIO_BLTTRANSPARENTCOLOR 0x1c // word? -#define CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK 0x20 // word? -#define CIRRUS_MMIO_LINEARDRAW_START_X 0x24 // word -#define CIRRUS_MMIO_LINEARDRAW_START_Y 0x26 // word -#define CIRRUS_MMIO_LINEARDRAW_END_X 0x28 // word -#define CIRRUS_MMIO_LINEARDRAW_END_Y 0x2a // word -#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_INC 0x2c // byte -#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_ROLLOVER 0x2d // byte -#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_MASK 0x2e // byte -#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_ACCUM 0x2f // byte -#define CIRRUS_MMIO_BRESENHAM_K1 0x30 // word -#define CIRRUS_MMIO_BRESENHAM_K3 0x32 // word -#define CIRRUS_MMIO_BRESENHAM_ERROR 0x34 // word -#define CIRRUS_MMIO_BRESENHAM_DELTA_MAJOR 0x36 // word -#define CIRRUS_MMIO_BRESENHAM_DIRECTION 0x38 // byte -#define CIRRUS_MMIO_LINEDRAW_MODE 0x39 // byte -#define CIRRUS_MMIO_BLTSTATUS 0x40 // byte +#define CIRRUS_MMIO_BLTBGCOLOR 0x00 // dword +#define CIRRUS_MMIO_BLTFGCOLOR 0x04 // dword +#define CIRRUS_MMIO_BLTWIDTH 0x08 // word +#define CIRRUS_MMIO_BLTHEIGHT 0x0a // word +#define CIRRUS_MMIO_BLTDESTPITCH 0x0c // word +#define CIRRUS_MMIO_BLTSRCPITCH 0x0e // word +#define CIRRUS_MMIO_BLTDESTADDR 0x10 // dword +#define CIRRUS_MMIO_BLTSRCADDR 0x14 // dword +#define CIRRUS_MMIO_BLTWRITEMASK 0x17 // byte +#define CIRRUS_MMIO_BLTMODE 0x18 // byte +#define CIRRUS_MMIO_BLTROP 0x1a // byte +#define CIRRUS_MMIO_BLTMODEEXT 0x1b // byte +#define CIRRUS_MMIO_BLTTRANSPARENTCOLOR 0x1c // word? +#define CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK 0x20 // word? +#define CIRRUS_MMIO_LINEARDRAW_START_X 0x24 // word +#define CIRRUS_MMIO_LINEARDRAW_START_Y 0x26 // word +#define CIRRUS_MMIO_LINEARDRAW_END_X 0x28 // word +#define CIRRUS_MMIO_LINEARDRAW_END_Y 0x2a // word +#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_INC 0x2c // byte +#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_ROLLOVER 0x2d // byte +#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_MASK 0x2e // byte +#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_ACCUM 0x2f // byte +#define CIRRUS_MMIO_BRESENHAM_K1 0x30 // word +#define CIRRUS_MMIO_BRESENHAM_K3 0x32 // word +#define CIRRUS_MMIO_BRESENHAM_ERROR 0x34 // word +#define CIRRUS_MMIO_BRESENHAM_DELTA_MAJOR 0x36 // word +#define CIRRUS_MMIO_BRESENHAM_DIRECTION 0x38 // byte +#define CIRRUS_MMIO_LINEDRAW_MODE 0x39 // byte +#define CIRRUS_MMIO_BLTSTATUS 0x40 // byte #define CIRRUS_PNPMMIO_SIZE 0x1000 @@ -628,8 +628,8 @@ static inline void cirrus_bitblt_bgcol(CirrusVGAState *s) } static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin, - int off_pitch, int bytesperline, - int lines) + int off_pitch, int bytesperline, + int lines) { int y; int off_cur; @@ -708,8 +708,8 @@ static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop) s->cirrus_blt_dstpitch, s->cirrus_blt_width, s->cirrus_blt_height); cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, - s->cirrus_blt_dstpitch, s->cirrus_blt_width, - s->cirrus_blt_height); + s->cirrus_blt_dstpitch, s->cirrus_blt_width, + s->cirrus_blt_height); cirrus_bitblt_reset(s); return 1; } @@ -773,8 +773,8 @@ static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h) (*s->cirrus_rop) (s, s->cirrus_blt_dstaddr, s->cirrus_blt_srcaddr, - s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch, - s->cirrus_blt_width, s->cirrus_blt_height); + s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch, + s->cirrus_blt_width, s->cirrus_blt_height); if (notify) { dpy_gfx_update(s->vga.con, dx, dy, @@ -786,8 +786,8 @@ static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h) changed since qemu_console_copy implies this */ cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, - s->cirrus_blt_dstpitch, s->cirrus_blt_width, - s->cirrus_blt_height); + s->cirrus_blt_dstpitch, s->cirrus_blt_width, + s->cirrus_blt_height); return 1; } @@ -854,7 +854,7 @@ static void cirrus_bitblt_reset(CirrusVGAState * s) int need_update; s->vga.gr[0x31] &= - ~(CIRRUS_BLT_START | CIRRUS_BLT_BUSY | CIRRUS_BLT_FIFOUSED); + ~(CIRRUS_BLT_START | CIRRUS_BLT_BUSY | CIRRUS_BLT_FIFOUSED); need_update = s->cirrus_srcptr != &s->cirrus_bltbuf[0] || s->cirrus_srcptr_end != &s->cirrus_bltbuf[0]; s->cirrus_srcptr = &s->cirrus_bltbuf[0]; @@ -878,24 +878,24 @@ static int cirrus_bitblt_cputovideo(CirrusVGAState * s) s->cirrus_srcptr_end = &s->cirrus_bltbuf[0]; if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) { - if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) { - s->cirrus_blt_srcpitch = 8; - } else { + if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) { + s->cirrus_blt_srcpitch = 8; + } else { /* XXX: check for 24 bpp */ - s->cirrus_blt_srcpitch = 8 * 8 * s->cirrus_blt_pixelwidth; - } - s->cirrus_srccounter = s->cirrus_blt_srcpitch; + s->cirrus_blt_srcpitch = 8 * 8 * s->cirrus_blt_pixelwidth; + } + s->cirrus_srccounter = s->cirrus_blt_srcpitch; } else { - if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) { + if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) { w = s->cirrus_blt_width / s->cirrus_blt_pixelwidth; if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY) s->cirrus_blt_srcpitch = ((w + 31) >> 5); else s->cirrus_blt_srcpitch = ((w + 7) >> 3); - } else { + } else { /* always align input size to 32 bits */ - s->cirrus_blt_srcpitch = (s->cirrus_blt_width + 3) & ~3; - } + s->cirrus_blt_srcpitch = (s->cirrus_blt_width + 3) & ~3; + } s->cirrus_srccounter = s->cirrus_blt_srcpitch * s->cirrus_blt_height; } @@ -921,12 +921,12 @@ static int cirrus_bitblt_videotovideo(CirrusVGAState * s) int ret; if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) { - ret = cirrus_bitblt_videotovideo_patterncopy(s); + ret = cirrus_bitblt_videotovideo_patterncopy(s); } else { - ret = cirrus_bitblt_videotovideo_copy(s); + ret = cirrus_bitblt_videotovideo_copy(s); } if (ret) - cirrus_bitblt_reset(s); + cirrus_bitblt_reset(s); return ret; } @@ -945,9 +945,9 @@ static void cirrus_bitblt_start(CirrusVGAState * s) s->cirrus_blt_dstpitch = (s->vga.gr[0x24] | (s->vga.gr[0x25] << 8)); s->cirrus_blt_srcpitch = (s->vga.gr[0x26] | (s->vga.gr[0x27] << 8)); s->cirrus_blt_dstaddr = - (s->vga.gr[0x28] | (s->vga.gr[0x29] << 8) | (s->vga.gr[0x2a] << 16)); + (s->vga.gr[0x28] | (s->vga.gr[0x29] << 8) | (s->vga.gr[0x2a] << 16)); s->cirrus_blt_srcaddr = - (s->vga.gr[0x2c] | (s->vga.gr[0x2d] << 8) | (s->vga.gr[0x2e] << 16)); + (s->vga.gr[0x2c] | (s->vga.gr[0x2d] << 8) | (s->vga.gr[0x2e] << 16)); s->cirrus_blt_mode = s->vga.gr[0x30]; s->cirrus_blt_modeext = s->vga.gr[0x33]; blt_rop = s->vga.gr[0x32]; @@ -968,31 +968,31 @@ static void cirrus_bitblt_start(CirrusVGAState * s) switch (s->cirrus_blt_mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) { case CIRRUS_BLTMODE_PIXELWIDTH8: - s->cirrus_blt_pixelwidth = 1; - break; + s->cirrus_blt_pixelwidth = 1; + break; case CIRRUS_BLTMODE_PIXELWIDTH16: - s->cirrus_blt_pixelwidth = 2; - break; + s->cirrus_blt_pixelwidth = 2; + break; case CIRRUS_BLTMODE_PIXELWIDTH24: - s->cirrus_blt_pixelwidth = 3; - break; + s->cirrus_blt_pixelwidth = 3; + break; case CIRRUS_BLTMODE_PIXELWIDTH32: - s->cirrus_blt_pixelwidth = 4; - break; + s->cirrus_blt_pixelwidth = 4; + break; default: qemu_log_mask(LOG_GUEST_ERROR, "cirrus: bitblt - pixel width is unknown\n"); - goto bitblt_ignore; + goto bitblt_ignore; } s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_PIXELWIDTHMASK; if ((s-> - cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSSRC | - CIRRUS_BLTMODE_MEMSYSDEST)) - == (CIRRUS_BLTMODE_MEMSYSSRC | CIRRUS_BLTMODE_MEMSYSDEST)) { + cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSSRC | + CIRRUS_BLTMODE_MEMSYSDEST)) + == (CIRRUS_BLTMODE_MEMSYSSRC | CIRRUS_BLTMODE_MEMSYSDEST)) { qemu_log_mask(LOG_UNIMP, "cirrus: bitblt - memory-to-memory copy requested\n"); - goto bitblt_ignore; + goto bitblt_ignore; } if ((s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_SOLIDFILL) && @@ -1036,30 +1036,30 @@ static void cirrus_bitblt_start(CirrusVGAState * s) s->cirrus_rop = cirrus_patternfill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; } } else { - if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) { - if (s->cirrus_blt_pixelwidth > 2) { + if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) { + if (s->cirrus_blt_pixelwidth > 2) { qemu_log_mask(LOG_GUEST_ERROR, "cirrus: src transparent without colorexpand " "must be 8bpp or 16bpp\n"); - goto bitblt_ignore; - } - if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) { - s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch; - s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch; - s->cirrus_rop = cirrus_bkwd_transp_rop[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; - } else { - s->cirrus_rop = cirrus_fwd_transp_rop[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; - } - } else { - if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) { - s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch; - s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch; - s->cirrus_rop = cirrus_bkwd_rop[rop_to_index[blt_rop]]; - } else { - s->cirrus_rop = cirrus_fwd_rop[rop_to_index[blt_rop]]; - } - } - } + goto bitblt_ignore; + } + if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) { + s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch; + s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch; + s->cirrus_rop = cirrus_bkwd_transp_rop[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; + } else { + s->cirrus_rop = cirrus_fwd_transp_rop[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; + } + } else { + if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) { + s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch; + s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch; + s->cirrus_rop = cirrus_bkwd_rop[rop_to_index[blt_rop]]; + } else { + s->cirrus_rop = cirrus_fwd_rop[rop_to_index[blt_rop]]; + } + } + } // setup bitblt engine. if (s->cirrus_blt_mode & CIRRUS_BLTMODE_MEMSYSSRC) { if (!cirrus_bitblt_cputovideo(s)) @@ -1085,11 +1085,11 @@ static void cirrus_write_bitblt(CirrusVGAState * s, unsigned reg_value) s->vga.gr[0x31] = reg_value; if (((old_value & CIRRUS_BLT_RESET) != 0) && - ((reg_value & CIRRUS_BLT_RESET) == 0)) { - cirrus_bitblt_reset(s); + ((reg_value & CIRRUS_BLT_RESET) == 0)) { + cirrus_bitblt_reset(s); } else if (((old_value & CIRRUS_BLT_START) == 0) && - ((reg_value & CIRRUS_BLT_START) != 0)) { - cirrus_bitblt_start(s); + ((reg_value & CIRRUS_BLT_START) != 0)) { + cirrus_bitblt_start(s); } } @@ -1109,15 +1109,15 @@ static void cirrus_get_offsets(VGACommonState *s1, uint32_t start_addr, line_offset, line_compare; line_offset = s->vga.cr[0x13] - | ((s->vga.cr[0x1b] & 0x10) << 4); + | ((s->vga.cr[0x1b] & 0x10) << 4); line_offset <<= 3; *pline_offset = line_offset; start_addr = (s->vga.cr[0x0c] << 8) - | s->vga.cr[0x0d] - | ((s->vga.cr[0x1b] & 0x01) << 16) - | ((s->vga.cr[0x1b] & 0x0c) << 15) - | ((s->vga.cr[0x1d] & 0x80) << 12); + | s->vga.cr[0x0d] + | ((s->vga.cr[0x1b] & 0x01) << 16) + | ((s->vga.cr[0x1b] & 0x0c) << 15) + | ((s->vga.cr[0x1d] & 0x80) << 12); *pstart_addr = start_addr; line_compare = s->vga.cr[0x18] | @@ -1132,17 +1132,17 @@ static uint32_t cirrus_get_bpp16_depth(CirrusVGAState * s) switch (s->cirrus_hidden_dac_data & 0xf) { case 0: - ret = 15; - break; /* Sierra HiColor */ + ret = 15; + break; /* Sierra HiColor */ case 1: - ret = 16; - break; /* XGA HiColor */ + ret = 16; + break; /* XGA HiColor */ default: qemu_log_mask(LOG_GUEST_ERROR, "cirrus: invalid DAC value 0x%x in 16bpp\n", (s->cirrus_hidden_dac_data & 0xf)); - ret = 15; /* XXX */ - break; + ret = 15; /* XXX */ + break; } return ret; } @@ -1153,33 +1153,33 @@ static int cirrus_get_bpp(VGACommonState *s1) uint32_t ret = 8; if ((s->vga.sr[0x07] & 0x01) != 0) { - /* Cirrus SVGA */ - switch (s->vga.sr[0x07] & CIRRUS_SR7_BPP_MASK) { - case CIRRUS_SR7_BPP_8: - ret = 8; - break; - case CIRRUS_SR7_BPP_16_DOUBLEVCLK: - ret = cirrus_get_bpp16_depth(s); - break; - case CIRRUS_SR7_BPP_24: - ret = 24; - break; - case CIRRUS_SR7_BPP_16: - ret = cirrus_get_bpp16_depth(s); - break; - case CIRRUS_SR7_BPP_32: - ret = 32; - break; - default: + /* Cirrus SVGA */ + switch (s->vga.sr[0x07] & CIRRUS_SR7_BPP_MASK) { + case CIRRUS_SR7_BPP_8: + ret = 8; + break; + case CIRRUS_SR7_BPP_16_DOUBLEVCLK: + ret = cirrus_get_bpp16_depth(s); + break; + case CIRRUS_SR7_BPP_24: + ret = 24; + break; + case CIRRUS_SR7_BPP_16: + ret = cirrus_get_bpp16_depth(s); + break; + case CIRRUS_SR7_BPP_32: + ret = 32; + break; + default: #ifdef DEBUG_CIRRUS - printf("cirrus: unknown bpp - sr7=%x\n", s->vga.sr[0x7]); + printf("cirrus: unknown bpp - sr7=%x\n", s->vga.sr[0x7]); #endif - ret = 8; - break; - } + ret = 8; + break; + } } else { - /* VGA */ - ret = 0; + /* VGA */ + ret = 0; } return ret; @@ -1212,36 +1212,36 @@ static void cirrus_update_bank_ptr(CirrusVGAState * s, unsigned bank_index) unsigned offset; unsigned limit; - if ((s->vga.gr[0x0b] & 0x01) != 0) /* dual bank */ - offset = s->vga.gr[0x09 + bank_index]; - else /* single bank */ - offset = s->vga.gr[0x09]; + if ((s->vga.gr[0x0b] & 0x01) != 0) /* dual bank */ + offset = s->vga.gr[0x09 + bank_index]; + else /* single bank */ + offset = s->vga.gr[0x09]; if ((s->vga.gr[0x0b] & 0x20) != 0) - offset <<= 14; + offset <<= 14; else - offset <<= 12; + offset <<= 12; if (s->real_vram_size <= offset) - limit = 0; + limit = 0; else - limit = s->real_vram_size - offset; + limit = s->real_vram_size - offset; if (((s->vga.gr[0x0b] & 0x01) == 0) && (bank_index != 0)) { - if (limit > 0x8000) { - offset += 0x8000; - limit -= 0x8000; - } else { - limit = 0; - } + if (limit > 0x8000) { + offset += 0x8000; + limit -= 0x8000; + } else { + limit = 0; + } } if (limit > 0) { - s->cirrus_bank_base[bank_index] = offset; - s->cirrus_bank_limit[bank_index] = limit; + s->cirrus_bank_base[bank_index] = offset; + s->cirrus_bank_limit[bank_index] = limit; } else { - s->cirrus_bank_base[bank_index] = 0; - s->cirrus_bank_limit[bank_index] = 0; + s->cirrus_bank_base[bank_index] = 0; + s->cirrus_bank_limit[bank_index] = 0; } } @@ -1254,148 +1254,148 @@ static void cirrus_update_bank_ptr(CirrusVGAState * s, unsigned bank_index) static int cirrus_vga_read_sr(CirrusVGAState * s) { switch (s->vga.sr_index) { - case 0x00: // Standard VGA - case 0x01: // Standard VGA - case 0x02: // Standard VGA - case 0x03: // Standard VGA - case 0x04: // Standard VGA - return s->vga.sr[s->vga.sr_index]; - case 0x06: // Unlock Cirrus extensions - return s->vga.sr[s->vga.sr_index]; + case 0x00: // Standard VGA + case 0x01: // Standard VGA + case 0x02: // Standard VGA + case 0x03: // Standard VGA + case 0x04: // Standard VGA + return s->vga.sr[s->vga.sr_index]; + case 0x06: // Unlock Cirrus extensions + return s->vga.sr[s->vga.sr_index]; case 0x10: case 0x30: case 0x50: - case 0x70: // Graphics Cursor X + case 0x70: // Graphics Cursor X case 0x90: case 0xb0: case 0xd0: - case 0xf0: // Graphics Cursor X - return s->vga.sr[0x10]; + case 0xf0: // Graphics Cursor X + return s->vga.sr[0x10]; case 0x11: case 0x31: case 0x51: - case 0x71: // Graphics Cursor Y + case 0x71: // Graphics Cursor Y case 0x91: case 0xb1: case 0xd1: - case 0xf1: // Graphics Cursor Y - return s->vga.sr[0x11]; - case 0x05: // ??? - case 0x07: // Extended Sequencer Mode - case 0x08: // EEPROM Control - case 0x09: // Scratch Register 0 - case 0x0a: // Scratch Register 1 - case 0x0b: // VCLK 0 - case 0x0c: // VCLK 1 - case 0x0d: // VCLK 2 - case 0x0e: // VCLK 3 - case 0x0f: // DRAM Control - case 0x12: // Graphics Cursor Attribute - case 0x13: // Graphics Cursor Pattern Address - case 0x14: // Scratch Register 2 - case 0x15: // Scratch Register 3 - case 0x16: // Performance Tuning Register - case 0x17: // Configuration Readback and Extended Control - case 0x18: // Signature Generator Control - case 0x19: // Signal Generator Result - case 0x1a: // Signal Generator Result - case 0x1b: // VCLK 0 Denominator & Post - case 0x1c: // VCLK 1 Denominator & Post - case 0x1d: // VCLK 2 Denominator & Post - case 0x1e: // VCLK 3 Denominator & Post - case 0x1f: // BIOS Write Enable and MCLK select + case 0xf1: // Graphics Cursor Y + return s->vga.sr[0x11]; + case 0x05: // ??? + case 0x07: // Extended Sequencer Mode + case 0x08: // EEPROM Control + case 0x09: // Scratch Register 0 + case 0x0a: // Scratch Register 1 + case 0x0b: // VCLK 0 + case 0x0c: // VCLK 1 + case 0x0d: // VCLK 2 + case 0x0e: // VCLK 3 + case 0x0f: // DRAM Control + case 0x12: // Graphics Cursor Attribute + case 0x13: // Graphics Cursor Pattern Address + case 0x14: // Scratch Register 2 + case 0x15: // Scratch Register 3 + case 0x16: // Performance Tuning Register + case 0x17: // Configuration Readback and Extended Control + case 0x18: // Signature Generator Control + case 0x19: // Signal Generator Result + case 0x1a: // Signal Generator Result + case 0x1b: // VCLK 0 Denominator & Post + case 0x1c: // VCLK 1 Denominator & Post + case 0x1d: // VCLK 2 Denominator & Post + case 0x1e: // VCLK 3 Denominator & Post + case 0x1f: // BIOS Write Enable and MCLK select #ifdef DEBUG_CIRRUS - printf("cirrus: handled inport sr_index %02x\n", s->vga.sr_index); + printf("cirrus: handled inport sr_index %02x\n", s->vga.sr_index); #endif - return s->vga.sr[s->vga.sr_index]; + return s->vga.sr[s->vga.sr_index]; default: qemu_log_mask(LOG_GUEST_ERROR, "cirrus: inport sr_index 0x%02x\n", s->vga.sr_index); - return 0xff; + return 0xff; } } static void cirrus_vga_write_sr(CirrusVGAState * s, uint32_t val) { switch (s->vga.sr_index) { - case 0x00: // Standard VGA - case 0x01: // Standard VGA - case 0x02: // Standard VGA - case 0x03: // Standard VGA - case 0x04: // Standard VGA - s->vga.sr[s->vga.sr_index] = val & sr_mask[s->vga.sr_index]; - if (s->vga.sr_index == 1) + case 0x00: // Standard VGA + case 0x01: // Standard VGA + case 0x02: // Standard VGA + case 0x03: // Standard VGA + case 0x04: // Standard VGA + s->vga.sr[s->vga.sr_index] = val & sr_mask[s->vga.sr_index]; + if (s->vga.sr_index == 1) s->vga.update_retrace_info(&s->vga); break; - case 0x06: // Unlock Cirrus extensions - val &= 0x17; - if (val == 0x12) { - s->vga.sr[s->vga.sr_index] = 0x12; - } else { - s->vga.sr[s->vga.sr_index] = 0x0f; - } - break; + case 0x06: // Unlock Cirrus extensions + val &= 0x17; + if (val == 0x12) { + s->vga.sr[s->vga.sr_index] = 0x12; + } else { + s->vga.sr[s->vga.sr_index] = 0x0f; + } + break; case 0x10: case 0x30: case 0x50: - case 0x70: // Graphics Cursor X + case 0x70: // Graphics Cursor X case 0x90: case 0xb0: case 0xd0: - case 0xf0: // Graphics Cursor X - s->vga.sr[0x10] = val; + case 0xf0: // Graphics Cursor X + s->vga.sr[0x10] = val; s->vga.hw_cursor_x = (val << 3) | (s->vga.sr_index >> 5); - break; + break; case 0x11: case 0x31: case 0x51: - case 0x71: // Graphics Cursor Y + case 0x71: // Graphics Cursor Y case 0x91: case 0xb1: case 0xd1: - case 0xf1: // Graphics Cursor Y - s->vga.sr[0x11] = val; + case 0xf1: // Graphics Cursor Y + s->vga.sr[0x11] = val; s->vga.hw_cursor_y = (val << 3) | (s->vga.sr_index >> 5); - break; - case 0x07: // Extended Sequencer Mode + break; + case 0x07: // Extended Sequencer Mode cirrus_update_memory_access(s); /* fall through */ - case 0x08: // EEPROM Control - case 0x09: // Scratch Register 0 - case 0x0a: // Scratch Register 1 - case 0x0b: // VCLK 0 - case 0x0c: // VCLK 1 - case 0x0d: // VCLK 2 - case 0x0e: // VCLK 3 - case 0x0f: // DRAM Control - case 0x13: // Graphics Cursor Pattern Address - case 0x14: // Scratch Register 2 - case 0x15: // Scratch Register 3 - case 0x16: // Performance Tuning Register - case 0x18: // Signature Generator Control - case 0x19: // Signature Generator Result - case 0x1a: // Signature Generator Result - case 0x1b: // VCLK 0 Denominator & Post - case 0x1c: // VCLK 1 Denominator & Post - case 0x1d: // VCLK 2 Denominator & Post - case 0x1e: // VCLK 3 Denominator & Post - case 0x1f: // BIOS Write Enable and MCLK select - s->vga.sr[s->vga.sr_index] = val; + case 0x08: // EEPROM Control + case 0x09: // Scratch Register 0 + case 0x0a: // Scratch Register 1 + case 0x0b: // VCLK 0 + case 0x0c: // VCLK 1 + case 0x0d: // VCLK 2 + case 0x0e: // VCLK 3 + case 0x0f: // DRAM Control + case 0x13: // Graphics Cursor Pattern Address + case 0x14: // Scratch Register 2 + case 0x15: // Scratch Register 3 + case 0x16: // Performance Tuning Register + case 0x18: // Signature Generator Control + case 0x19: // Signature Generator Result + case 0x1a: // Signature Generator Result + case 0x1b: // VCLK 0 Denominator & Post + case 0x1c: // VCLK 1 Denominator & Post + case 0x1d: // VCLK 2 Denominator & Post + case 0x1e: // VCLK 3 Denominator & Post + case 0x1f: // BIOS Write Enable and MCLK select + s->vga.sr[s->vga.sr_index] = val; #ifdef DEBUG_CIRRUS - printf("cirrus: handled outport sr_index %02x, sr_value %02x\n", - s->vga.sr_index, val); + printf("cirrus: handled outport sr_index %02x, sr_value %02x\n", + s->vga.sr_index, val); #endif - break; - case 0x12: // Graphics Cursor Attribute - s->vga.sr[0x12] = val; + break; + case 0x12: // Graphics Cursor Attribute + s->vga.sr[0x12] = val; s->vga.force_shadow = !!(val & CIRRUS_CURSOR_SHOW); #ifdef DEBUG_CIRRUS printf("cirrus: cursor ctl SR12=%02x (force shadow: %d)\n", val, s->vga.force_shadow); #endif break; - case 0x17: // Configuration Readback and Extended Control - s->vga.sr[s->vga.sr_index] = (s->vga.sr[s->vga.sr_index] & 0x38) + case 0x17: // Configuration Readback and Extended Control + s->vga.sr[s->vga.sr_index] = (s->vga.sr[s->vga.sr_index] & 0x38) | (val & 0xc7); cirrus_update_memory_access(s); break; @@ -1403,7 +1403,7 @@ static void cirrus_vga_write_sr(CirrusVGAState * s, uint32_t val) qemu_log_mask(LOG_GUEST_ERROR, "cirrus: outport sr_index 0x%02x, sr_value 0x%02x\n", s->vga.sr_index, val); - break; + break; } } @@ -1425,9 +1425,9 @@ static int cirrus_read_hidden_dac(CirrusVGAState * s) static void cirrus_write_hidden_dac(CirrusVGAState * s, int reg_value) { if (s->cirrus_hidden_dac_lockindex == 4) { - s->cirrus_hidden_dac_data = reg_value; + s->cirrus_hidden_dac_data = reg_value; #if defined(DEBUG_CIRRUS) - printf("cirrus: outport hidden DAC, value %02x\n", reg_value); + printf("cirrus: outport hidden DAC, value %02x\n", reg_value); #endif } s->cirrus_hidden_dac_lockindex = 0; @@ -1450,8 +1450,8 @@ static int cirrus_vga_read_palette(CirrusVGAState * s) val = s->vga.palette[s->vga.dac_read_index * 3 + s->vga.dac_sub_index]; } if (++s->vga.dac_sub_index == 3) { - s->vga.dac_sub_index = 0; - s->vga.dac_read_index++; + s->vga.dac_sub_index = 0; + s->vga.dac_read_index++; } return val; } @@ -1467,8 +1467,8 @@ static void cirrus_vga_write_palette(CirrusVGAState * s, int reg_value) memcpy(&s->vga.palette[s->vga.dac_write_index * 3], s->vga.dac_cache, 3); } /* XXX update cursor */ - s->vga.dac_sub_index = 0; - s->vga.dac_write_index++; + s->vga.dac_sub_index = 0; + s->vga.dac_write_index++; } } @@ -1485,24 +1485,24 @@ static int cirrus_vga_read_gr(CirrusVGAState * s, unsigned reg_index) return s->cirrus_shadow_gr0; case 0x01: // Standard VGA, FGCOLOR 0x000000ff return s->cirrus_shadow_gr1; - case 0x02: // Standard VGA - case 0x03: // Standard VGA - case 0x04: // Standard VGA - case 0x06: // Standard VGA - case 0x07: // Standard VGA - case 0x08: // Standard VGA + case 0x02: // Standard VGA + case 0x03: // Standard VGA + case 0x04: // Standard VGA + case 0x06: // Standard VGA + case 0x07: // Standard VGA + case 0x08: // Standard VGA return s->vga.gr[s->vga.gr_index]; - case 0x05: // Standard VGA, Cirrus extended mode + case 0x05: // Standard VGA, Cirrus extended mode default: - break; + break; } if (reg_index < 0x3a) { - return s->vga.gr[reg_index]; + return s->vga.gr[reg_index]; } else { qemu_log_mask(LOG_GUEST_ERROR, "cirrus: inport gr_index 0x%02x\n", reg_index); - return 0xff; + return 0xff; } } @@ -1511,87 +1511,87 @@ cirrus_vga_write_gr(CirrusVGAState * s, unsigned reg_index, int reg_value) { trace_vga_cirrus_write_gr(reg_index, reg_value); switch (reg_index) { - case 0x00: // Standard VGA, BGCOLOR 0x000000ff - s->vga.gr[reg_index] = reg_value & gr_mask[reg_index]; - s->cirrus_shadow_gr0 = reg_value; - break; - case 0x01: // Standard VGA, FGCOLOR 0x000000ff - s->vga.gr[reg_index] = reg_value & gr_mask[reg_index]; - s->cirrus_shadow_gr1 = reg_value; - break; - case 0x02: // Standard VGA - case 0x03: // Standard VGA - case 0x04: // Standard VGA - case 0x06: // Standard VGA - case 0x07: // Standard VGA - case 0x08: // Standard VGA - s->vga.gr[reg_index] = reg_value & gr_mask[reg_index]; + case 0x00: // Standard VGA, BGCOLOR 0x000000ff + s->vga.gr[reg_index] = reg_value & gr_mask[reg_index]; + s->cirrus_shadow_gr0 = reg_value; break; - case 0x05: // Standard VGA, Cirrus extended mode - s->vga.gr[reg_index] = reg_value & 0x7f; + case 0x01: // Standard VGA, FGCOLOR 0x000000ff + s->vga.gr[reg_index] = reg_value & gr_mask[reg_index]; + s->cirrus_shadow_gr1 = reg_value; + break; + case 0x02: // Standard VGA + case 0x03: // Standard VGA + case 0x04: // Standard VGA + case 0x06: // Standard VGA + case 0x07: // Standard VGA + case 0x08: // Standard VGA + s->vga.gr[reg_index] = reg_value & gr_mask[reg_index]; + break; + case 0x05: // Standard VGA, Cirrus extended mode + s->vga.gr[reg_index] = reg_value & 0x7f; cirrus_update_memory_access(s); - break; - case 0x09: // bank offset #0 - case 0x0A: // bank offset #1 - s->vga.gr[reg_index] = reg_value; - cirrus_update_bank_ptr(s, 0); - cirrus_update_bank_ptr(s, 1); + break; + case 0x09: // bank offset #0 + case 0x0A: // bank offset #1 + s->vga.gr[reg_index] = reg_value; + cirrus_update_bank_ptr(s, 0); + cirrus_update_bank_ptr(s, 1); cirrus_update_memory_access(s); break; case 0x0B: - s->vga.gr[reg_index] = reg_value; - cirrus_update_bank_ptr(s, 0); - cirrus_update_bank_ptr(s, 1); + s->vga.gr[reg_index] = reg_value; + cirrus_update_bank_ptr(s, 0); + cirrus_update_bank_ptr(s, 1); cirrus_update_memory_access(s); - break; - case 0x10: // BGCOLOR 0x0000ff00 - case 0x11: // FGCOLOR 0x0000ff00 - case 0x12: // BGCOLOR 0x00ff0000 - case 0x13: // FGCOLOR 0x00ff0000 - case 0x14: // BGCOLOR 0xff000000 - case 0x15: // FGCOLOR 0xff000000 - case 0x20: // BLT WIDTH 0x0000ff - case 0x22: // BLT HEIGHT 0x0000ff - case 0x24: // BLT DEST PITCH 0x0000ff - case 0x26: // BLT SRC PITCH 0x0000ff - case 0x28: // BLT DEST ADDR 0x0000ff - case 0x29: // BLT DEST ADDR 0x00ff00 - case 0x2c: // BLT SRC ADDR 0x0000ff - case 0x2d: // BLT SRC ADDR 0x00ff00 + break; + case 0x10: // BGCOLOR 0x0000ff00 + case 0x11: // FGCOLOR 0x0000ff00 + case 0x12: // BGCOLOR 0x00ff0000 + case 0x13: // FGCOLOR 0x00ff0000 + case 0x14: // BGCOLOR 0xff000000 + case 0x15: // FGCOLOR 0xff000000 + case 0x20: // BLT WIDTH 0x0000ff + case 0x22: // BLT HEIGHT 0x0000ff + case 0x24: // BLT DEST PITCH 0x0000ff + case 0x26: // BLT SRC PITCH 0x0000ff + case 0x28: // BLT DEST ADDR 0x0000ff + case 0x29: // BLT DEST ADDR 0x00ff00 + case 0x2c: // BLT SRC ADDR 0x0000ff + case 0x2d: // BLT SRC ADDR 0x00ff00 case 0x2f: // BLT WRITEMASK - case 0x30: // BLT MODE - case 0x32: // RASTER OP - case 0x33: // BLT MODEEXT - case 0x34: // BLT TRANSPARENT COLOR 0x00ff - case 0x35: // BLT TRANSPARENT COLOR 0xff00 - case 0x38: // BLT TRANSPARENT COLOR MASK 0x00ff - case 0x39: // BLT TRANSPARENT COLOR MASK 0xff00 - s->vga.gr[reg_index] = reg_value; - break; - case 0x21: // BLT WIDTH 0x001f00 - case 0x23: // BLT HEIGHT 0x001f00 - case 0x25: // BLT DEST PITCH 0x001f00 - case 0x27: // BLT SRC PITCH 0x001f00 - s->vga.gr[reg_index] = reg_value & 0x1f; - break; - case 0x2a: // BLT DEST ADDR 0x3f0000 - s->vga.gr[reg_index] = reg_value & 0x3f; + case 0x30: // BLT MODE + case 0x32: // RASTER OP + case 0x33: // BLT MODEEXT + case 0x34: // BLT TRANSPARENT COLOR 0x00ff + case 0x35: // BLT TRANSPARENT COLOR 0xff00 + case 0x38: // BLT TRANSPARENT COLOR MASK 0x00ff + case 0x39: // BLT TRANSPARENT COLOR MASK 0xff00 + s->vga.gr[reg_index] = reg_value; + break; + case 0x21: // BLT WIDTH 0x001f00 + case 0x23: // BLT HEIGHT 0x001f00 + case 0x25: // BLT DEST PITCH 0x001f00 + case 0x27: // BLT SRC PITCH 0x001f00 + s->vga.gr[reg_index] = reg_value & 0x1f; + break; + case 0x2a: // BLT DEST ADDR 0x3f0000 + s->vga.gr[reg_index] = reg_value & 0x3f; /* if auto start mode, starts bit blt now */ if (s->vga.gr[0x31] & CIRRUS_BLT_AUTOSTART) { cirrus_bitblt_start(s); } - break; - case 0x2e: // BLT SRC ADDR 0x3f0000 - s->vga.gr[reg_index] = reg_value & 0x3f; - break; - case 0x31: // BLT STATUS/START - cirrus_write_bitblt(s, reg_value); - break; + break; + case 0x2e: // BLT SRC ADDR 0x3f0000 + s->vga.gr[reg_index] = reg_value & 0x3f; + break; + case 0x31: // BLT STATUS/START + cirrus_write_bitblt(s, reg_value); + break; default: qemu_log_mask(LOG_GUEST_ERROR, "cirrus: outport gr_index 0x%02x, gr_value 0x%02x\n", reg_index, reg_value); - break; + break; } } @@ -1604,122 +1604,122 @@ cirrus_vga_write_gr(CirrusVGAState * s, unsigned reg_index, int reg_value) static int cirrus_vga_read_cr(CirrusVGAState * s, unsigned reg_index) { switch (reg_index) { - case 0x00: // Standard VGA - case 0x01: // Standard VGA - case 0x02: // Standard VGA - case 0x03: // Standard VGA - case 0x04: // Standard VGA - case 0x05: // Standard VGA - case 0x06: // Standard VGA - case 0x07: // Standard VGA - case 0x08: // Standard VGA - case 0x09: // Standard VGA - case 0x0a: // Standard VGA - case 0x0b: // Standard VGA - case 0x0c: // Standard VGA - case 0x0d: // Standard VGA - case 0x0e: // Standard VGA - case 0x0f: // Standard VGA - case 0x10: // Standard VGA - case 0x11: // Standard VGA - case 0x12: // Standard VGA - case 0x13: // Standard VGA - case 0x14: // Standard VGA - case 0x15: // Standard VGA - case 0x16: // Standard VGA - case 0x17: // Standard VGA - case 0x18: // Standard VGA - return s->vga.cr[s->vga.cr_index]; - case 0x24: // Attribute Controller Toggle Readback (R) + case 0x00: // Standard VGA + case 0x01: // Standard VGA + case 0x02: // Standard VGA + case 0x03: // Standard VGA + case 0x04: // Standard VGA + case 0x05: // Standard VGA + case 0x06: // Standard VGA + case 0x07: // Standard VGA + case 0x08: // Standard VGA + case 0x09: // Standard VGA + case 0x0a: // Standard VGA + case 0x0b: // Standard VGA + case 0x0c: // Standard VGA + case 0x0d: // Standard VGA + case 0x0e: // Standard VGA + case 0x0f: // Standard VGA + case 0x10: // Standard VGA + case 0x11: // Standard VGA + case 0x12: // Standard VGA + case 0x13: // Standard VGA + case 0x14: // Standard VGA + case 0x15: // Standard VGA + case 0x16: // Standard VGA + case 0x17: // Standard VGA + case 0x18: // Standard VGA + return s->vga.cr[s->vga.cr_index]; + case 0x24: // Attribute Controller Toggle Readback (R) return (s->vga.ar_flip_flop << 7); - case 0x19: // Interlace End - case 0x1a: // Miscellaneous Control - case 0x1b: // Extended Display Control - case 0x1c: // Sync Adjust and Genlock - case 0x1d: // Overlay Extended Control - case 0x22: // Graphics Data Latches Readback (R) - case 0x25: // Part Status - case 0x27: // Part ID (R) - return s->vga.cr[s->vga.cr_index]; - case 0x26: // Attribute Controller Index Readback (R) - return s->vga.ar_index & 0x3f; + case 0x19: // Interlace End + case 0x1a: // Miscellaneous Control + case 0x1b: // Extended Display Control + case 0x1c: // Sync Adjust and Genlock + case 0x1d: // Overlay Extended Control + case 0x22: // Graphics Data Latches Readback (R) + case 0x25: // Part Status + case 0x27: // Part ID (R) + return s->vga.cr[s->vga.cr_index]; + case 0x26: // Attribute Controller Index Readback (R) + return s->vga.ar_index & 0x3f; default: qemu_log_mask(LOG_GUEST_ERROR, "cirrus: inport cr_index 0x%02x\n", reg_index); - return 0xff; + return 0xff; } } static void cirrus_vga_write_cr(CirrusVGAState * s, int reg_value) { switch (s->vga.cr_index) { - case 0x00: // Standard VGA - case 0x01: // Standard VGA - case 0x02: // Standard VGA - case 0x03: // Standard VGA - case 0x04: // Standard VGA - case 0x05: // Standard VGA - case 0x06: // Standard VGA - case 0x07: // Standard VGA - case 0x08: // Standard VGA - case 0x09: // Standard VGA - case 0x0a: // Standard VGA - case 0x0b: // Standard VGA - case 0x0c: // Standard VGA - case 0x0d: // Standard VGA - case 0x0e: // Standard VGA - case 0x0f: // Standard VGA - case 0x10: // Standard VGA - case 0x11: // Standard VGA - case 0x12: // Standard VGA - case 0x13: // Standard VGA - case 0x14: // Standard VGA - case 0x15: // Standard VGA - case 0x16: // Standard VGA - case 0x17: // Standard VGA - case 0x18: // Standard VGA - /* handle CR0-7 protection */ - if ((s->vga.cr[0x11] & 0x80) && s->vga.cr_index <= 7) { - /* can always write bit 4 of CR7 */ - if (s->vga.cr_index == 7) - s->vga.cr[7] = (s->vga.cr[7] & ~0x10) | (reg_value & 0x10); - return; - } - s->vga.cr[s->vga.cr_index] = reg_value; - switch(s->vga.cr_index) { - case 0x00: - case 0x04: - case 0x05: - case 0x06: - case 0x07: - case 0x11: - case 0x17: - s->vga.update_retrace_info(&s->vga); - break; - } + case 0x00: // Standard VGA + case 0x01: // Standard VGA + case 0x02: // Standard VGA + case 0x03: // Standard VGA + case 0x04: // Standard VGA + case 0x05: // Standard VGA + case 0x06: // Standard VGA + case 0x07: // Standard VGA + case 0x08: // Standard VGA + case 0x09: // Standard VGA + case 0x0a: // Standard VGA + case 0x0b: // Standard VGA + case 0x0c: // Standard VGA + case 0x0d: // Standard VGA + case 0x0e: // Standard VGA + case 0x0f: // Standard VGA + case 0x10: // Standard VGA + case 0x11: // Standard VGA + case 0x12: // Standard VGA + case 0x13: // Standard VGA + case 0x14: // Standard VGA + case 0x15: // Standard VGA + case 0x16: // Standard VGA + case 0x17: // Standard VGA + case 0x18: // Standard VGA + /* handle CR0-7 protection */ + if ((s->vga.cr[0x11] & 0x80) && s->vga.cr_index <= 7) { + /* can always write bit 4 of CR7 */ + if (s->vga.cr_index == 7) + s->vga.cr[7] = (s->vga.cr[7] & ~0x10) | (reg_value & 0x10); + return; + } + s->vga.cr[s->vga.cr_index] = reg_value; + switch(s->vga.cr_index) { + case 0x00: + case 0x04: + case 0x05: + case 0x06: + case 0x07: + case 0x11: + case 0x17: + s->vga.update_retrace_info(&s->vga); + break; + } break; - case 0x19: // Interlace End - case 0x1a: // Miscellaneous Control - case 0x1b: // Extended Display Control - case 0x1c: // Sync Adjust and Genlock - case 0x1d: // Overlay Extended Control - s->vga.cr[s->vga.cr_index] = reg_value; + case 0x19: // Interlace End + case 0x1a: // Miscellaneous Control + case 0x1b: // Extended Display Control + case 0x1c: // Sync Adjust and Genlock + case 0x1d: // Overlay Extended Control + s->vga.cr[s->vga.cr_index] = reg_value; #ifdef DEBUG_CIRRUS - printf("cirrus: handled outport cr_index %02x, cr_value %02x\n", - s->vga.cr_index, reg_value); + printf("cirrus: handled outport cr_index %02x, cr_value %02x\n", + s->vga.cr_index, reg_value); #endif - break; - case 0x22: // Graphics Data Latches Readback (R) - case 0x24: // Attribute Controller Toggle Readback (R) - case 0x26: // Attribute Controller Index Readback (R) - case 0x27: // Part ID (R) - break; - case 0x25: // Part Status + break; + case 0x22: // Graphics Data Latches Readback (R) + case 0x24: // Attribute Controller Toggle Readback (R) + case 0x26: // Attribute Controller Index Readback (R) + case 0x27: // Part ID (R) + break; + case 0x25: // Part Status default: qemu_log_mask(LOG_GUEST_ERROR, "cirrus: outport cr_index 0x%02x, cr_value 0x%02x\n", s->vga.cr_index, reg_value); - break; + break; } } @@ -1735,102 +1735,102 @@ static uint8_t cirrus_mmio_blt_read(CirrusVGAState * s, unsigned address) switch (address) { case (CIRRUS_MMIO_BLTBGCOLOR + 0): - value = cirrus_vga_read_gr(s, 0x00); - break; + value = cirrus_vga_read_gr(s, 0x00); + break; case (CIRRUS_MMIO_BLTBGCOLOR + 1): - value = cirrus_vga_read_gr(s, 0x10); - break; + value = cirrus_vga_read_gr(s, 0x10); + break; case (CIRRUS_MMIO_BLTBGCOLOR + 2): - value = cirrus_vga_read_gr(s, 0x12); - break; + value = cirrus_vga_read_gr(s, 0x12); + break; case (CIRRUS_MMIO_BLTBGCOLOR + 3): - value = cirrus_vga_read_gr(s, 0x14); - break; + value = cirrus_vga_read_gr(s, 0x14); + break; case (CIRRUS_MMIO_BLTFGCOLOR + 0): - value = cirrus_vga_read_gr(s, 0x01); - break; + value = cirrus_vga_read_gr(s, 0x01); + break; case (CIRRUS_MMIO_BLTFGCOLOR + 1): - value = cirrus_vga_read_gr(s, 0x11); - break; + value = cirrus_vga_read_gr(s, 0x11); + break; case (CIRRUS_MMIO_BLTFGCOLOR + 2): - value = cirrus_vga_read_gr(s, 0x13); - break; + value = cirrus_vga_read_gr(s, 0x13); + break; case (CIRRUS_MMIO_BLTFGCOLOR + 3): - value = cirrus_vga_read_gr(s, 0x15); - break; + value = cirrus_vga_read_gr(s, 0x15); + break; case (CIRRUS_MMIO_BLTWIDTH + 0): - value = cirrus_vga_read_gr(s, 0x20); - break; + value = cirrus_vga_read_gr(s, 0x20); + break; case (CIRRUS_MMIO_BLTWIDTH + 1): - value = cirrus_vga_read_gr(s, 0x21); - break; + value = cirrus_vga_read_gr(s, 0x21); + break; case (CIRRUS_MMIO_BLTHEIGHT + 0): - value = cirrus_vga_read_gr(s, 0x22); - break; + value = cirrus_vga_read_gr(s, 0x22); + break; case (CIRRUS_MMIO_BLTHEIGHT + 1): - value = cirrus_vga_read_gr(s, 0x23); - break; + value = cirrus_vga_read_gr(s, 0x23); + break; case (CIRRUS_MMIO_BLTDESTPITCH + 0): - value = cirrus_vga_read_gr(s, 0x24); - break; + value = cirrus_vga_read_gr(s, 0x24); + break; case (CIRRUS_MMIO_BLTDESTPITCH + 1): - value = cirrus_vga_read_gr(s, 0x25); - break; + value = cirrus_vga_read_gr(s, 0x25); + break; case (CIRRUS_MMIO_BLTSRCPITCH + 0): - value = cirrus_vga_read_gr(s, 0x26); - break; + value = cirrus_vga_read_gr(s, 0x26); + break; case (CIRRUS_MMIO_BLTSRCPITCH + 1): - value = cirrus_vga_read_gr(s, 0x27); - break; + value = cirrus_vga_read_gr(s, 0x27); + break; case (CIRRUS_MMIO_BLTDESTADDR + 0): - value = cirrus_vga_read_gr(s, 0x28); - break; + value = cirrus_vga_read_gr(s, 0x28); + break; case (CIRRUS_MMIO_BLTDESTADDR + 1): - value = cirrus_vga_read_gr(s, 0x29); - break; + value = cirrus_vga_read_gr(s, 0x29); + break; case (CIRRUS_MMIO_BLTDESTADDR + 2): - value = cirrus_vga_read_gr(s, 0x2a); - break; + value = cirrus_vga_read_gr(s, 0x2a); + break; case (CIRRUS_MMIO_BLTSRCADDR + 0): - value = cirrus_vga_read_gr(s, 0x2c); - break; + value = cirrus_vga_read_gr(s, 0x2c); + break; case (CIRRUS_MMIO_BLTSRCADDR + 1): - value = cirrus_vga_read_gr(s, 0x2d); - break; + value = cirrus_vga_read_gr(s, 0x2d); + break; case (CIRRUS_MMIO_BLTSRCADDR + 2): - value = cirrus_vga_read_gr(s, 0x2e); - break; + value = cirrus_vga_read_gr(s, 0x2e); + break; case CIRRUS_MMIO_BLTWRITEMASK: - value = cirrus_vga_read_gr(s, 0x2f); - break; + value = cirrus_vga_read_gr(s, 0x2f); + break; case CIRRUS_MMIO_BLTMODE: - value = cirrus_vga_read_gr(s, 0x30); - break; + value = cirrus_vga_read_gr(s, 0x30); + break; case CIRRUS_MMIO_BLTROP: - value = cirrus_vga_read_gr(s, 0x32); - break; + value = cirrus_vga_read_gr(s, 0x32); + break; case CIRRUS_MMIO_BLTMODEEXT: - value = cirrus_vga_read_gr(s, 0x33); - break; + value = cirrus_vga_read_gr(s, 0x33); + break; case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 0): - value = cirrus_vga_read_gr(s, 0x34); - break; + value = cirrus_vga_read_gr(s, 0x34); + break; case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 1): - value = cirrus_vga_read_gr(s, 0x35); - break; + value = cirrus_vga_read_gr(s, 0x35); + break; case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 0): - value = cirrus_vga_read_gr(s, 0x38); - break; + value = cirrus_vga_read_gr(s, 0x38); + break; case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 1): - value = cirrus_vga_read_gr(s, 0x39); - break; + value = cirrus_vga_read_gr(s, 0x39); + break; case CIRRUS_MMIO_BLTSTATUS: - value = cirrus_vga_read_gr(s, 0x31); - break; + value = cirrus_vga_read_gr(s, 0x31); + break; default: qemu_log_mask(LOG_GUEST_ERROR, "cirrus: mmio read - address 0x%04x\n", address); - break; + break; } trace_vga_cirrus_write_blt(address, value); @@ -1838,111 +1838,111 @@ static uint8_t cirrus_mmio_blt_read(CirrusVGAState * s, unsigned address) } static void cirrus_mmio_blt_write(CirrusVGAState * s, unsigned address, - uint8_t value) + uint8_t value) { trace_vga_cirrus_write_blt(address, value); switch (address) { case (CIRRUS_MMIO_BLTBGCOLOR + 0): - cirrus_vga_write_gr(s, 0x00, value); - break; + cirrus_vga_write_gr(s, 0x00, value); + break; case (CIRRUS_MMIO_BLTBGCOLOR + 1): - cirrus_vga_write_gr(s, 0x10, value); - break; + cirrus_vga_write_gr(s, 0x10, value); + break; case (CIRRUS_MMIO_BLTBGCOLOR + 2): - cirrus_vga_write_gr(s, 0x12, value); - break; + cirrus_vga_write_gr(s, 0x12, value); + break; case (CIRRUS_MMIO_BLTBGCOLOR + 3): - cirrus_vga_write_gr(s, 0x14, value); - break; + cirrus_vga_write_gr(s, 0x14, value); + break; case (CIRRUS_MMIO_BLTFGCOLOR + 0): - cirrus_vga_write_gr(s, 0x01, value); - break; + cirrus_vga_write_gr(s, 0x01, value); + break; case (CIRRUS_MMIO_BLTFGCOLOR + 1): - cirrus_vga_write_gr(s, 0x11, value); - break; + cirrus_vga_write_gr(s, 0x11, value); + break; case (CIRRUS_MMIO_BLTFGCOLOR + 2): - cirrus_vga_write_gr(s, 0x13, value); - break; + cirrus_vga_write_gr(s, 0x13, value); + break; case (CIRRUS_MMIO_BLTFGCOLOR + 3): - cirrus_vga_write_gr(s, 0x15, value); - break; + cirrus_vga_write_gr(s, 0x15, value); + break; case (CIRRUS_MMIO_BLTWIDTH + 0): - cirrus_vga_write_gr(s, 0x20, value); - break; + cirrus_vga_write_gr(s, 0x20, value); + break; case (CIRRUS_MMIO_BLTWIDTH + 1): - cirrus_vga_write_gr(s, 0x21, value); - break; + cirrus_vga_write_gr(s, 0x21, value); + break; case (CIRRUS_MMIO_BLTHEIGHT + 0): - cirrus_vga_write_gr(s, 0x22, value); - break; + cirrus_vga_write_gr(s, 0x22, value); + break; case (CIRRUS_MMIO_BLTHEIGHT + 1): - cirrus_vga_write_gr(s, 0x23, value); - break; + cirrus_vga_write_gr(s, 0x23, value); + break; case (CIRRUS_MMIO_BLTDESTPITCH + 0): - cirrus_vga_write_gr(s, 0x24, value); - break; + cirrus_vga_write_gr(s, 0x24, value); + break; case (CIRRUS_MMIO_BLTDESTPITCH + 1): - cirrus_vga_write_gr(s, 0x25, value); - break; + cirrus_vga_write_gr(s, 0x25, value); + break; case (CIRRUS_MMIO_BLTSRCPITCH + 0): - cirrus_vga_write_gr(s, 0x26, value); - break; + cirrus_vga_write_gr(s, 0x26, value); + break; case (CIRRUS_MMIO_BLTSRCPITCH + 1): - cirrus_vga_write_gr(s, 0x27, value); - break; + cirrus_vga_write_gr(s, 0x27, value); + break; case (CIRRUS_MMIO_BLTDESTADDR + 0): - cirrus_vga_write_gr(s, 0x28, value); - break; + cirrus_vga_write_gr(s, 0x28, value); + break; case (CIRRUS_MMIO_BLTDESTADDR + 1): - cirrus_vga_write_gr(s, 0x29, value); - break; + cirrus_vga_write_gr(s, 0x29, value); + break; case (CIRRUS_MMIO_BLTDESTADDR + 2): - cirrus_vga_write_gr(s, 0x2a, value); - break; + cirrus_vga_write_gr(s, 0x2a, value); + break; case (CIRRUS_MMIO_BLTDESTADDR + 3): - /* ignored */ - break; + /* ignored */ + break; case (CIRRUS_MMIO_BLTSRCADDR + 0): - cirrus_vga_write_gr(s, 0x2c, value); - break; + cirrus_vga_write_gr(s, 0x2c, value); + break; case (CIRRUS_MMIO_BLTSRCADDR + 1): - cirrus_vga_write_gr(s, 0x2d, value); - break; + cirrus_vga_write_gr(s, 0x2d, value); + break; case (CIRRUS_MMIO_BLTSRCADDR + 2): - cirrus_vga_write_gr(s, 0x2e, value); - break; + cirrus_vga_write_gr(s, 0x2e, value); + break; case CIRRUS_MMIO_BLTWRITEMASK: - cirrus_vga_write_gr(s, 0x2f, value); - break; + cirrus_vga_write_gr(s, 0x2f, value); + break; case CIRRUS_MMIO_BLTMODE: - cirrus_vga_write_gr(s, 0x30, value); - break; + cirrus_vga_write_gr(s, 0x30, value); + break; case CIRRUS_MMIO_BLTROP: - cirrus_vga_write_gr(s, 0x32, value); - break; + cirrus_vga_write_gr(s, 0x32, value); + break; case CIRRUS_MMIO_BLTMODEEXT: - cirrus_vga_write_gr(s, 0x33, value); - break; + cirrus_vga_write_gr(s, 0x33, value); + break; case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 0): - cirrus_vga_write_gr(s, 0x34, value); - break; + cirrus_vga_write_gr(s, 0x34, value); + break; case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 1): - cirrus_vga_write_gr(s, 0x35, value); - break; + cirrus_vga_write_gr(s, 0x35, value); + break; case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 0): - cirrus_vga_write_gr(s, 0x38, value); - break; + cirrus_vga_write_gr(s, 0x38, value); + break; case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 1): - cirrus_vga_write_gr(s, 0x39, value); - break; + cirrus_vga_write_gr(s, 0x39, value); + break; case CIRRUS_MMIO_BLTSTATUS: - cirrus_vga_write_gr(s, 0x31, value); - break; + cirrus_vga_write_gr(s, 0x31, value); + break; default: qemu_log_mask(LOG_GUEST_ERROR, "cirrus: mmio write - addr 0x%04x val 0x%02x (ignored)\n", address, value); - break; + break; } } @@ -1953,9 +1953,9 @@ static void cirrus_mmio_blt_write(CirrusVGAState * s, unsigned address, ***************************************/ static void cirrus_mem_writeb_mode4and5_8bpp(CirrusVGAState * s, - unsigned mode, - unsigned offset, - uint32_t mem_value) + unsigned mode, + unsigned offset, + uint32_t mem_value) { int x; unsigned val = mem_value; @@ -1963,20 +1963,20 @@ static void cirrus_mem_writeb_mode4and5_8bpp(CirrusVGAState * s, for (x = 0; x < 8; x++) { dst = s->vga.vram_ptr + ((offset + x) & s->cirrus_addr_mask); - if (val & 0x80) { - *dst = s->cirrus_shadow_gr1; - } else if (mode == 5) { - *dst = s->cirrus_shadow_gr0; - } - val <<= 1; + if (val & 0x80) { + *dst = s->cirrus_shadow_gr1; + } else if (mode == 5) { + *dst = s->cirrus_shadow_gr0; + } + val <<= 1; } memory_region_set_dirty(&s->vga.vram, offset, 8); } static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s, - unsigned mode, - unsigned offset, - uint32_t mem_value) + unsigned mode, + unsigned offset, + uint32_t mem_value) { int x; unsigned val = mem_value; @@ -1984,14 +1984,14 @@ static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s, for (x = 0; x < 8; x++) { dst = s->vga.vram_ptr + ((offset + 2 * x) & s->cirrus_addr_mask & ~1); - if (val & 0x80) { - *dst = s->cirrus_shadow_gr1; - *(dst + 1) = s->vga.gr[0x11]; - } else if (mode == 5) { - *dst = s->cirrus_shadow_gr0; - *(dst + 1) = s->vga.gr[0x10]; - } - val <<= 1; + if (val & 0x80) { + *dst = s->cirrus_shadow_gr1; + *(dst + 1) = s->vga.gr[0x11]; + } else if (mode == 5) { + *dst = s->cirrus_shadow_gr0; + *(dst + 1) = s->vga.gr[0x10]; + } + val <<= 1; } memory_region_set_dirty(&s->vga.vram, offset, 16); } @@ -2016,29 +2016,29 @@ static uint64_t cirrus_vga_mem_read(void *opaque, } if (addr < 0x10000) { - /* XXX handle bitblt */ - /* video memory */ - bank_index = addr >> 15; - bank_offset = addr & 0x7fff; - if (bank_offset < s->cirrus_bank_limit[bank_index]) { - bank_offset += s->cirrus_bank_base[bank_index]; - if ((s->vga.gr[0x0B] & 0x14) == 0x14) { - bank_offset <<= 4; - } else if (s->vga.gr[0x0B] & 0x02) { - bank_offset <<= 3; - } - bank_offset &= s->cirrus_addr_mask; - val = *(s->vga.vram_ptr + bank_offset); - } else - val = 0xff; + /* XXX handle bitblt */ + /* video memory */ + bank_index = addr >> 15; + bank_offset = addr & 0x7fff; + if (bank_offset < s->cirrus_bank_limit[bank_index]) { + bank_offset += s->cirrus_bank_base[bank_index]; + if ((s->vga.gr[0x0B] & 0x14) == 0x14) { + bank_offset <<= 4; + } else if (s->vga.gr[0x0B] & 0x02) { + bank_offset <<= 3; + } + bank_offset &= s->cirrus_addr_mask; + val = *(s->vga.vram_ptr + bank_offset); + } else + val = 0xff; } else if (addr >= 0x18000 && addr < 0x18100) { - /* memory-mapped I/O */ - val = 0xff; - if ((s->vga.sr[0x17] & 0x44) == 0x04) { - val = cirrus_mmio_blt_read(s, addr & 0xff); - } + /* memory-mapped I/O */ + val = 0xff; + if ((s->vga.sr[0x17] & 0x44) == 0x04) { + val = cirrus_mmio_blt_read(s, addr & 0xff); + } } else { - val = 0xff; + val = 0xff; qemu_log_mask(LOG_GUEST_ERROR, "cirrus: mem_readb 0x" TARGET_FMT_plx "\n", addr); } @@ -2061,47 +2061,47 @@ static void cirrus_vga_mem_write(void *opaque, } if (addr < 0x10000) { - if (s->cirrus_srcptr != s->cirrus_srcptr_end) { - /* bitblt */ - *s->cirrus_srcptr++ = (uint8_t) mem_value; - if (s->cirrus_srcptr >= s->cirrus_srcptr_end) { - cirrus_bitblt_cputovideo_next(s); - } - } else { - /* video memory */ - bank_index = addr >> 15; - bank_offset = addr & 0x7fff; - if (bank_offset < s->cirrus_bank_limit[bank_index]) { - bank_offset += s->cirrus_bank_base[bank_index]; - if ((s->vga.gr[0x0B] & 0x14) == 0x14) { - bank_offset <<= 4; - } else if (s->vga.gr[0x0B] & 0x02) { - bank_offset <<= 3; - } - bank_offset &= s->cirrus_addr_mask; - mode = s->vga.gr[0x05] & 0x7; - if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) { - *(s->vga.vram_ptr + bank_offset) = mem_value; + if (s->cirrus_srcptr != s->cirrus_srcptr_end) { + /* bitblt */ + *s->cirrus_srcptr++ = (uint8_t) mem_value; + if (s->cirrus_srcptr >= s->cirrus_srcptr_end) { + cirrus_bitblt_cputovideo_next(s); + } + } else { + /* video memory */ + bank_index = addr >> 15; + bank_offset = addr & 0x7fff; + if (bank_offset < s->cirrus_bank_limit[bank_index]) { + bank_offset += s->cirrus_bank_base[bank_index]; + if ((s->vga.gr[0x0B] & 0x14) == 0x14) { + bank_offset <<= 4; + } else if (s->vga.gr[0x0B] & 0x02) { + bank_offset <<= 3; + } + bank_offset &= s->cirrus_addr_mask; + mode = s->vga.gr[0x05] & 0x7; + if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) { + *(s->vga.vram_ptr + bank_offset) = mem_value; memory_region_set_dirty(&s->vga.vram, bank_offset, sizeof(mem_value)); - } else { - if ((s->vga.gr[0x0B] & 0x14) != 0x14) { - cirrus_mem_writeb_mode4and5_8bpp(s, mode, - bank_offset, - mem_value); - } else { - cirrus_mem_writeb_mode4and5_16bpp(s, mode, - bank_offset, - mem_value); - } - } - } - } + } else { + if ((s->vga.gr[0x0B] & 0x14) != 0x14) { + cirrus_mem_writeb_mode4and5_8bpp(s, mode, + bank_offset, + mem_value); + } else { + cirrus_mem_writeb_mode4and5_16bpp(s, mode, + bank_offset, + mem_value); + } + } + } + } } else if (addr >= 0x18000 && addr < 0x18100) { - /* memory-mapped I/O */ - if ((s->vga.sr[0x17] & 0x44) == 0x04) { - cirrus_mmio_blt_write(s, addr & 0xff, mem_value); - } + /* memory-mapped I/O */ + if ((s->vga.sr[0x17] & 0x44) == 0x04) { + cirrus_mmio_blt_write(s, addr & 0xff, mem_value); + } } else { qemu_log_mask(LOG_GUEST_ERROR, "cirrus: mem_writeb 0x" TARGET_FMT_plx " " @@ -2326,20 +2326,20 @@ static uint64_t cirrus_linear_read(void *opaque, hwaddr addr, if (((s->vga.sr[0x17] & 0x44) == 0x44) && ((addr & s->linear_mmio_mask) == s->linear_mmio_mask)) { - /* memory-mapped I/O */ - ret = cirrus_mmio_blt_read(s, addr & 0xff); + /* memory-mapped I/O */ + ret = cirrus_mmio_blt_read(s, addr & 0xff); } else if (0) { - /* XXX handle bitblt */ - ret = 0xff; + /* XXX handle bitblt */ + ret = 0xff; } else { - /* video memory */ - if ((s->vga.gr[0x0B] & 0x14) == 0x14) { - addr <<= 4; - } else if (s->vga.gr[0x0B] & 0x02) { - addr <<= 3; - } - addr &= s->cirrus_addr_mask; - ret = *(s->vga.vram_ptr + addr); + /* video memory */ + if ((s->vga.gr[0x0B] & 0x14) == 0x14) { + addr <<= 4; + } else if (s->vga.gr[0x0B] & 0x02) { + addr <<= 3; + } + addr &= s->cirrus_addr_mask; + ret = *(s->vga.vram_ptr + addr); } return ret; @@ -2355,34 +2355,34 @@ static void cirrus_linear_write(void *opaque, hwaddr addr, if (((s->vga.sr[0x17] & 0x44) == 0x44) && ((addr & s->linear_mmio_mask) == s->linear_mmio_mask)) { - /* memory-mapped I/O */ - cirrus_mmio_blt_write(s, addr & 0xff, val); + /* memory-mapped I/O */ + cirrus_mmio_blt_write(s, addr & 0xff, val); } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) { - /* bitblt */ - *s->cirrus_srcptr++ = (uint8_t) val; - if (s->cirrus_srcptr >= s->cirrus_srcptr_end) { - cirrus_bitblt_cputovideo_next(s); - } + /* bitblt */ + *s->cirrus_srcptr++ = (uint8_t) val; + if (s->cirrus_srcptr >= s->cirrus_srcptr_end) { + cirrus_bitblt_cputovideo_next(s); + } } else { - /* video memory */ - if ((s->vga.gr[0x0B] & 0x14) == 0x14) { - addr <<= 4; - } else if (s->vga.gr[0x0B] & 0x02) { - addr <<= 3; - } - addr &= s->cirrus_addr_mask; + /* video memory */ + if ((s->vga.gr[0x0B] & 0x14) == 0x14) { + addr <<= 4; + } else if (s->vga.gr[0x0B] & 0x02) { + addr <<= 3; + } + addr &= s->cirrus_addr_mask; - mode = s->vga.gr[0x05] & 0x7; - if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) { - *(s->vga.vram_ptr + addr) = (uint8_t) val; + mode = s->vga.gr[0x05] & 0x7; + if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) { + *(s->vga.vram_ptr + addr) = (uint8_t) val; memory_region_set_dirty(&s->vga.vram, addr, 1); - } else { - if ((s->vga.gr[0x0B] & 0x14) != 0x14) { - cirrus_mem_writeb_mode4and5_8bpp(s, mode, addr, val); - } else { - cirrus_mem_writeb_mode4and5_16bpp(s, mode, addr, val); - } - } + } else { + if ((s->vga.gr[0x0B] & 0x14) != 0x14) { + cirrus_mem_writeb_mode4and5_8bpp(s, mode, addr, val); + } else { + cirrus_mem_writeb_mode4and5_16bpp(s, mode, addr, val); + } + } } } @@ -2415,11 +2415,11 @@ static void cirrus_linear_bitblt_write(void *opaque, CirrusVGAState *s = opaque; if (s->cirrus_srcptr != s->cirrus_srcptr_end) { - /* bitblt */ - *s->cirrus_srcptr++ = (uint8_t) val; - if (s->cirrus_srcptr >= s->cirrus_srcptr_end) { - cirrus_bitblt_cputovideo_next(s); - } + /* bitblt */ + *s->cirrus_srcptr++ = (uint8_t) val; + if (s->cirrus_srcptr >= s->cirrus_srcptr_end) { + cirrus_bitblt_cputovideo_next(s); + } } } @@ -2476,14 +2476,14 @@ static void cirrus_update_memory_access(CirrusVGAState *s) } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) { goto generic_io; } else { - if ((s->vga.gr[0x0B] & 0x14) == 0x14) { + if ((s->vga.gr[0x0B] & 0x14) == 0x14) { goto generic_io; - } else if (s->vga.gr[0x0B] & 0x02) { + } else if (s->vga.gr[0x0B] & 0x02) { goto generic_io; } - mode = s->vga.gr[0x05] & 0x7; - if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) { + mode = s->vga.gr[0x05] & 0x7; + if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) { map_linear_vram(s); } else { generic_io: @@ -2506,76 +2506,76 @@ static uint64_t cirrus_vga_ioport_read(void *opaque, hwaddr addr, addr += 0x3b0; if (vga_ioport_invalid(s, addr)) { - val = 0xff; + val = 0xff; } else { - switch (addr) { - case 0x3c0: - if (s->ar_flip_flop == 0) { - val = s->ar_index; - } else { - val = 0; - } - break; - case 0x3c1: - index = s->ar_index & 0x1f; - if (index < 21) - val = s->ar[index]; - else - val = 0; - break; - case 0x3c2: - val = s->st00; - break; - case 0x3c4: - val = s->sr_index; - break; - case 0x3c5: - val = cirrus_vga_read_sr(c); + switch (addr) { + case 0x3c0: + if (s->ar_flip_flop == 0) { + val = s->ar_index; + } else { + val = 0; + } + break; + case 0x3c1: + index = s->ar_index & 0x1f; + if (index < 21) + val = s->ar[index]; + else + val = 0; + break; + case 0x3c2: + val = s->st00; + break; + case 0x3c4: + val = s->sr_index; + break; + case 0x3c5: + val = cirrus_vga_read_sr(c); + break; + break; + case 0x3c6: + val = cirrus_read_hidden_dac(c); + break; + case 0x3c7: + val = s->dac_state; + break; + case 0x3c8: + val = s->dac_write_index; + c->cirrus_hidden_dac_lockindex = 0; break; - break; - case 0x3c6: - val = cirrus_read_hidden_dac(c); - break; - case 0x3c7: - val = s->dac_state; - break; - case 0x3c8: - val = s->dac_write_index; - c->cirrus_hidden_dac_lockindex = 0; - break; case 0x3c9: val = cirrus_vga_read_palette(c); break; - case 0x3ca: - val = s->fcr; - break; - case 0x3cc: - val = s->msr; - break; - case 0x3ce: - val = s->gr_index; - break; - case 0x3cf: - val = cirrus_vga_read_gr(c, s->gr_index); - break; - case 0x3b4: - case 0x3d4: - val = s->cr_index; - break; - case 0x3b5: - case 0x3d5: + case 0x3ca: + val = s->fcr; + break; + case 0x3cc: + val = s->msr; + break; + case 0x3ce: + val = s->gr_index; + break; + case 0x3cf: + val = cirrus_vga_read_gr(c, s->gr_index); + break; + case 0x3b4: + case 0x3d4: + val = s->cr_index; + break; + case 0x3b5: + case 0x3d5: val = cirrus_vga_read_cr(c, s->cr_index); - break; - case 0x3ba: - case 0x3da: - /* just toggle to fool polling */ - val = s->st01 = s->retrace(s); - s->ar_flip_flop = 0; - break; - default: - val = 0x00; - break; - } + break; + case 0x3ba: + case 0x3da: + /* just toggle to fool polling */ + val = s->st01 = s->retrace(s); + s->ar_flip_flop = 0; + break; + default: + val = 0x00; + break; + } } trace_vga_cirrus_read_io(addr, val); return val; @@ -2592,86 +2592,86 @@ static void cirrus_vga_ioport_write(void *opaque, hwaddr addr, uint64_t val, /* check port range access depending on color/monochrome mode */ if (vga_ioport_invalid(s, addr)) { - return; + return; } trace_vga_cirrus_write_io(addr, val); switch (addr) { case 0x3c0: - if (s->ar_flip_flop == 0) { - val &= 0x3f; - s->ar_index = val; - } else { - index = s->ar_index & 0x1f; - switch (index) { - case 0x00 ... 0x0f: - s->ar[index] = val & 0x3f; - break; - case 0x10: - s->ar[index] = val & ~0x10; - break; - case 0x11: - s->ar[index] = val; - break; - case 0x12: - s->ar[index] = val & ~0xc0; - break; - case 0x13: - s->ar[index] = val & ~0xf0; - break; - case 0x14: - s->ar[index] = val & ~0xf0; - break; - default: - break; - } - } - s->ar_flip_flop ^= 1; - break; + if (s->ar_flip_flop == 0) { + val &= 0x3f; + s->ar_index = val; + } else { + index = s->ar_index & 0x1f; + switch (index) { + case 0x00 ... 0x0f: + s->ar[index] = val & 0x3f; + break; + case 0x10: + s->ar[index] = val & ~0x10; + break; + case 0x11: + s->ar[index] = val; + break; + case 0x12: + s->ar[index] = val & ~0xc0; + break; + case 0x13: + s->ar[index] = val & ~0xf0; + break; + case 0x14: + s->ar[index] = val & ~0xf0; + break; + default: + break; + } + } + s->ar_flip_flop ^= 1; + break; case 0x3c2: - s->msr = val & ~0x10; - s->update_retrace_info(s); - break; + s->msr = val & ~0x10; + s->update_retrace_info(s); + break; case 0x3c4: - s->sr_index = val; - break; + s->sr_index = val; + break; case 0x3c5: - cirrus_vga_write_sr(c, val); + cirrus_vga_write_sr(c, val); break; case 0x3c6: - cirrus_write_hidden_dac(c, val); - break; + cirrus_write_hidden_dac(c, val); + break; case 0x3c7: - s->dac_read_index = val; - s->dac_sub_index = 0; - s->dac_state = 3; - break; + s->dac_read_index = val; + s->dac_sub_index = 0; + s->dac_state = 3; + break; case 0x3c8: - s->dac_write_index = val; - s->dac_sub_index = 0; - s->dac_state = 0; - break; + s->dac_write_index = val; + s->dac_sub_index = 0; + s->dac_state = 0; + break; case 0x3c9: cirrus_vga_write_palette(c, val); break; case 0x3ce: - s->gr_index = val; - break; + s->gr_index = val; + break; case 0x3cf: - cirrus_vga_write_gr(c, s->gr_index, val); - break; + cirrus_vga_write_gr(c, s->gr_index, val); + break; case 0x3b4: case 0x3d4: - s->cr_index = val; - break; + s->cr_index = val; + break; case 0x3b5: case 0x3d5: - cirrus_vga_write_cr(c, val); - break; + cirrus_vga_write_cr(c, val); + break; case 0x3ba: case 0x3da: - s->fcr = val & 0x10; - break; + s->fcr = val & 0x10; + break; } } @@ -2699,7 +2699,7 @@ static void cirrus_mmio_write(void *opaque, hwaddr addr, CirrusVGAState *s = opaque; if (addr >= 0x100) { - cirrus_mmio_blt_write(s, addr - 0x100, val); + cirrus_mmio_blt_write(s, addr - 0x100, val); } else { cirrus_vga_ioport_write(s, addr + 0x10, val, size); } @@ -2799,13 +2799,13 @@ static void cirrus_reset(void *opaque) s->vga.sr[0x06] = 0x0f; if (s->device_id == CIRRUS_ID_CLGD5446) { /* 4MB 64 bit memory config, always PCI */ - s->vga.sr[0x1F] = 0x2d; // MemClock + s->vga.sr[0x1F] = 0x2d; // MemClock s->vga.gr[0x18] = 0x0f; // fastest memory configuration s->vga.sr[0x0f] = 0x98; s->vga.sr[0x17] = 0x20; s->vga.sr[0x15] = 0x04; /* memory size, 3=2MB, 4=4MB */ } else { - s->vga.sr[0x1F] = 0x22; // MemClock + s->vga.sr[0x1F] = 0x22; // MemClock s->vga.sr[0x0F] = CIRRUS_MEMSIZE_2M; s->vga.sr[0x17] = s->bustype; s->vga.sr[0x15] = 0x03; /* memory size, 3=2MB, 4=4MB */ diff --git a/hw/display/omap_dss.c b/hw/display/omap_dss.c index 8c0e9ee700..09e18407b4 100644 --- a/hw/display/omap_dss.c +++ b/hw/display/omap_dss.c @@ -182,25 +182,25 @@ static uint64_t omap_diss_read(void *opaque, hwaddr addr, } switch (addr) { - case 0x00: /* DSS_REVISIONNUMBER */ + case 0x00: /* DSS_REVISIONNUMBER */ return 0x20; - case 0x10: /* DSS_SYSCONFIG */ + case 0x10: /* DSS_SYSCONFIG */ return s->autoidle; - case 0x14: /* DSS_SYSSTATUS */ - return 1; /* RESETDONE */ + case 0x14: /* DSS_SYSSTATUS */ + return 1; /* RESETDONE */ - case 0x40: /* DSS_CONTROL */ + case 0x40: /* DSS_CONTROL */ return s->control; - case 0x50: /* DSS_PSA_LCD_REG_1 */ - case 0x54: /* DSS_PSA_LCD_REG_2 */ - case 0x58: /* DSS_PSA_VIDEO_REG */ + case 0x50: /* DSS_PSA_LCD_REG_1 */ + case 0x54: /* DSS_PSA_LCD_REG_2 */ + case 0x58: /* DSS_PSA_VIDEO_REG */ /* TODO: fake some values when appropriate s->control bits are set */ return 0; - case 0x5c: /* DSS_STATUS */ + case 0x5c: /* DSS_STATUS */ return 1 + (s->control & 1); default: @@ -221,22 +221,22 @@ static void omap_diss_write(void *opaque, hwaddr addr, } switch (addr) { - case 0x00: /* DSS_REVISIONNUMBER */ - case 0x14: /* DSS_SYSSTATUS */ - case 0x50: /* DSS_PSA_LCD_REG_1 */ - case 0x54: /* DSS_PSA_LCD_REG_2 */ - case 0x58: /* DSS_PSA_VIDEO_REG */ - case 0x5c: /* DSS_STATUS */ + case 0x00: /* DSS_REVISIONNUMBER */ + case 0x14: /* DSS_SYSSTATUS */ + case 0x50: /* DSS_PSA_LCD_REG_1 */ + case 0x54: /* DSS_PSA_LCD_REG_2 */ + case 0x58: /* DSS_PSA_VIDEO_REG */ + case 0x5c: /* DSS_STATUS */ OMAP_RO_REG(addr); break; - case 0x10: /* DSS_SYSCONFIG */ - if (value & 2) /* SOFTRESET */ + case 0x10: /* DSS_SYSCONFIG */ + if (value & 2) /* SOFTRESET */ omap_dss_reset(s); s->autoidle = value & 1; break; - case 0x40: /* DSS_CONTROL */ + case 0x40: /* DSS_CONTROL */ s->control = value & 0x3dd; break; @@ -261,112 +261,112 @@ static uint64_t omap_disc_read(void *opaque, hwaddr addr, } switch (addr) { - case 0x000: /* DISPC_REVISION */ + case 0x000: /* DISPC_REVISION */ return 0x20; - case 0x010: /* DISPC_SYSCONFIG */ + case 0x010: /* DISPC_SYSCONFIG */ return s->dispc.idlemode; - case 0x014: /* DISPC_SYSSTATUS */ - return 1; /* RESETDONE */ + case 0x014: /* DISPC_SYSSTATUS */ + return 1; /* RESETDONE */ - case 0x018: /* DISPC_IRQSTATUS */ + case 0x018: /* DISPC_IRQSTATUS */ return s->dispc.irqst; - case 0x01c: /* DISPC_IRQENABLE */ + case 0x01c: /* DISPC_IRQENABLE */ return s->dispc.irqen; - case 0x040: /* DISPC_CONTROL */ + case 0x040: /* DISPC_CONTROL */ return s->dispc.control; - case 0x044: /* DISPC_CONFIG */ + case 0x044: /* DISPC_CONFIG */ return s->dispc.config; - case 0x048: /* DISPC_CAPABLE */ + case 0x048: /* DISPC_CAPABLE */ return s->dispc.capable; - case 0x04c: /* DISPC_DEFAULT_COLOR0 */ + case 0x04c: /* DISPC_DEFAULT_COLOR0 */ return s->dispc.bg[0]; - case 0x050: /* DISPC_DEFAULT_COLOR1 */ + case 0x050: /* DISPC_DEFAULT_COLOR1 */ return s->dispc.bg[1]; - case 0x054: /* DISPC_TRANS_COLOR0 */ + case 0x054: /* DISPC_TRANS_COLOR0 */ return s->dispc.trans[0]; - case 0x058: /* DISPC_TRANS_COLOR1 */ + case 0x058: /* DISPC_TRANS_COLOR1 */ return s->dispc.trans[1]; - case 0x05c: /* DISPC_LINE_STATUS */ + case 0x05c: /* DISPC_LINE_STATUS */ return 0x7ff; - case 0x060: /* DISPC_LINE_NUMBER */ + case 0x060: /* DISPC_LINE_NUMBER */ return s->dispc.line; - case 0x064: /* DISPC_TIMING_H */ + case 0x064: /* DISPC_TIMING_H */ return s->dispc.timing[0]; - case 0x068: /* DISPC_TIMING_V */ + case 0x068: /* DISPC_TIMING_V */ return s->dispc.timing[1]; - case 0x06c: /* DISPC_POL_FREQ */ + case 0x06c: /* DISPC_POL_FREQ */ return s->dispc.timing[2]; - case 0x070: /* DISPC_DIVISOR */ + case 0x070: /* DISPC_DIVISOR */ return s->dispc.timing[3]; - case 0x078: /* DISPC_SIZE_DIG */ + case 0x078: /* DISPC_SIZE_DIG */ return ((s->dig.ny - 1) << 16) | (s->dig.nx - 1); - case 0x07c: /* DISPC_SIZE_LCD */ + case 0x07c: /* DISPC_SIZE_LCD */ return ((s->lcd.ny - 1) << 16) | (s->lcd.nx - 1); - case 0x080: /* DISPC_GFX_BA0 */ + case 0x080: /* DISPC_GFX_BA0 */ return s->dispc.l[0].addr[0]; - case 0x084: /* DISPC_GFX_BA1 */ + case 0x084: /* DISPC_GFX_BA1 */ return s->dispc.l[0].addr[1]; - case 0x088: /* DISPC_GFX_POSITION */ + case 0x088: /* DISPC_GFX_POSITION */ return (s->dispc.l[0].posy << 16) | s->dispc.l[0].posx; - case 0x08c: /* DISPC_GFX_SIZE */ + case 0x08c: /* DISPC_GFX_SIZE */ return ((s->dispc.l[0].ny - 1) << 16) | (s->dispc.l[0].nx - 1); - case 0x0a0: /* DISPC_GFX_ATTRIBUTES */ + case 0x0a0: /* DISPC_GFX_ATTRIBUTES */ return s->dispc.l[0].attr; - case 0x0a4: /* DISPC_GFX_FIFO_TRESHOLD */ + case 0x0a4: /* DISPC_GFX_FIFO_TRESHOLD */ return s->dispc.l[0].tresh; - case 0x0a8: /* DISPC_GFX_FIFO_SIZE_STATUS */ + case 0x0a8: /* DISPC_GFX_FIFO_SIZE_STATUS */ return 256; - case 0x0ac: /* DISPC_GFX_ROW_INC */ + case 0x0ac: /* DISPC_GFX_ROW_INC */ return s->dispc.l[0].rowinc; - case 0x0b0: /* DISPC_GFX_PIXEL_INC */ + case 0x0b0: /* DISPC_GFX_PIXEL_INC */ return s->dispc.l[0].colinc; - case 0x0b4: /* DISPC_GFX_WINDOW_SKIP */ + case 0x0b4: /* DISPC_GFX_WINDOW_SKIP */ return s->dispc.l[0].wininc; - case 0x0b8: /* DISPC_GFX_TABLE_BA */ + case 0x0b8: /* DISPC_GFX_TABLE_BA */ return s->dispc.l[0].addr[2]; - case 0x0bc: /* DISPC_VID1_BA0 */ - case 0x0c0: /* DISPC_VID1_BA1 */ - case 0x0c4: /* DISPC_VID1_POSITION */ - case 0x0c8: /* DISPC_VID1_SIZE */ - case 0x0cc: /* DISPC_VID1_ATTRIBUTES */ - case 0x0d0: /* DISPC_VID1_FIFO_TRESHOLD */ - case 0x0d4: /* DISPC_VID1_FIFO_SIZE_STATUS */ - case 0x0d8: /* DISPC_VID1_ROW_INC */ - case 0x0dc: /* DISPC_VID1_PIXEL_INC */ - case 0x0e0: /* DISPC_VID1_FIR */ - case 0x0e4: /* DISPC_VID1_PICTURE_SIZE */ - case 0x0e8: /* DISPC_VID1_ACCU0 */ - case 0x0ec: /* DISPC_VID1_ACCU1 */ - case 0x0f0 ... 0x140: /* DISPC_VID1_FIR_COEF, DISPC_VID1_CONV_COEF */ - case 0x14c: /* DISPC_VID2_BA0 */ - case 0x150: /* DISPC_VID2_BA1 */ - case 0x154: /* DISPC_VID2_POSITION */ - case 0x158: /* DISPC_VID2_SIZE */ - case 0x15c: /* DISPC_VID2_ATTRIBUTES */ - case 0x160: /* DISPC_VID2_FIFO_TRESHOLD */ - case 0x164: /* DISPC_VID2_FIFO_SIZE_STATUS */ - case 0x168: /* DISPC_VID2_ROW_INC */ - case 0x16c: /* DISPC_VID2_PIXEL_INC */ - case 0x170: /* DISPC_VID2_FIR */ - case 0x174: /* DISPC_VID2_PICTURE_SIZE */ - case 0x178: /* DISPC_VID2_ACCU0 */ - case 0x17c: /* DISPC_VID2_ACCU1 */ - case 0x180 ... 0x1d0: /* DISPC_VID2_FIR_COEF, DISPC_VID2_CONV_COEF */ - case 0x1d4: /* DISPC_DATA_CYCLE1 */ - case 0x1d8: /* DISPC_DATA_CYCLE2 */ - case 0x1dc: /* DISPC_DATA_CYCLE3 */ + case 0x0bc: /* DISPC_VID1_BA0 */ + case 0x0c0: /* DISPC_VID1_BA1 */ + case 0x0c4: /* DISPC_VID1_POSITION */ + case 0x0c8: /* DISPC_VID1_SIZE */ + case 0x0cc: /* DISPC_VID1_ATTRIBUTES */ + case 0x0d0: /* DISPC_VID1_FIFO_TRESHOLD */ + case 0x0d4: /* DISPC_VID1_FIFO_SIZE_STATUS */ + case 0x0d8: /* DISPC_VID1_ROW_INC */ + case 0x0dc: /* DISPC_VID1_PIXEL_INC */ + case 0x0e0: /* DISPC_VID1_FIR */ + case 0x0e4: /* DISPC_VID1_PICTURE_SIZE */ + case 0x0e8: /* DISPC_VID1_ACCU0 */ + case 0x0ec: /* DISPC_VID1_ACCU1 */ + case 0x0f0 ... 0x140: /* DISPC_VID1_FIR_COEF, DISPC_VID1_CONV_COEF */ + case 0x14c: /* DISPC_VID2_BA0 */ + case 0x150: /* DISPC_VID2_BA1 */ + case 0x154: /* DISPC_VID2_POSITION */ + case 0x158: /* DISPC_VID2_SIZE */ + case 0x15c: /* DISPC_VID2_ATTRIBUTES */ + case 0x160: /* DISPC_VID2_FIFO_TRESHOLD */ + case 0x164: /* DISPC_VID2_FIFO_SIZE_STATUS */ + case 0x168: /* DISPC_VID2_ROW_INC */ + case 0x16c: /* DISPC_VID2_PIXEL_INC */ + case 0x170: /* DISPC_VID2_FIR */ + case 0x174: /* DISPC_VID2_PICTURE_SIZE */ + case 0x178: /* DISPC_VID2_ACCU0 */ + case 0x17c: /* DISPC_VID2_ACCU1 */ + case 0x180 ... 0x1d0: /* DISPC_VID2_FIR_COEF, DISPC_VID2_CONV_COEF */ + case 0x1d4: /* DISPC_DATA_CYCLE1 */ + case 0x1d8: /* DISPC_DATA_CYCLE2 */ + case 0x1dc: /* DISPC_DATA_CYCLE3 */ return 0; default: @@ -387,33 +387,33 @@ static void omap_disc_write(void *opaque, hwaddr addr, } switch (addr) { - case 0x010: /* DISPC_SYSCONFIG */ - if (value & 2) /* SOFTRESET */ + case 0x010: /* DISPC_SYSCONFIG */ + if (value & 2) /* SOFTRESET */ omap_dss_reset(s); s->dispc.idlemode = value & 0x301b; break; - case 0x018: /* DISPC_IRQSTATUS */ + case 0x018: /* DISPC_IRQSTATUS */ s->dispc.irqst &= ~value; omap_dispc_interrupt_update(s); break; - case 0x01c: /* DISPC_IRQENABLE */ + case 0x01c: /* DISPC_IRQENABLE */ s->dispc.irqen = value & 0xffff; omap_dispc_interrupt_update(s); break; - case 0x040: /* DISPC_CONTROL */ + case 0x040: /* DISPC_CONTROL */ s->dispc.control = value & 0x07ff9fff; s->dig.enable = (value >> 1) & 1; s->lcd.enable = (value >> 0) & 1; - if (value & (1 << 12)) /* OVERLAY_OPTIMIZATION */ + if (value & (1 << 12)) /* OVERLAY_OPTIMIZATION */ if (!((s->dispc.l[1].attr | s->dispc.l[2].attr) & 1)) { fprintf(stderr, "%s: Overlay Optimization when no overlay " "region effectively exists leads to " "unpredictable behaviour!\n", __func__); } - if (value & (1 << 6)) { /* GODIGITAL */ + if (value & (1 << 6)) { /* GODIGITAL */ /* XXX: Shadowed fields are: * s->dispc.config * s->dispc.capable @@ -444,13 +444,13 @@ static void omap_disc_write(void *opaque, hwaddr addr, * All they need to be loaded here from their shadow registers. */ } - if (value & (1 << 5)) { /* GOLCD */ + if (value & (1 << 5)) { /* GOLCD */ /* XXX: Likewise for LCD here. */ } s->dispc.invalidate = 1; break; - case 0x044: /* DISPC_CONFIG */ + case 0x044: /* DISPC_CONFIG */ s->dispc.config = value & 0x3fff; /* XXX: * bits 2:1 (LOADMODE) reset to 0 after set to 1 and palette loaded @@ -459,73 +459,73 @@ static void omap_disc_write(void *opaque, hwaddr addr, s->dispc.invalidate = 1; break; - case 0x048: /* DISPC_CAPABLE */ + case 0x048: /* DISPC_CAPABLE */ s->dispc.capable = value & 0x3ff; break; - case 0x04c: /* DISPC_DEFAULT_COLOR0 */ + case 0x04c: /* DISPC_DEFAULT_COLOR0 */ s->dispc.bg[0] = value & 0xffffff; s->dispc.invalidate = 1; break; - case 0x050: /* DISPC_DEFAULT_COLOR1 */ + case 0x050: /* DISPC_DEFAULT_COLOR1 */ s->dispc.bg[1] = value & 0xffffff; s->dispc.invalidate = 1; break; - case 0x054: /* DISPC_TRANS_COLOR0 */ + case 0x054: /* DISPC_TRANS_COLOR0 */ s->dispc.trans[0] = value & 0xffffff; s->dispc.invalidate = 1; break; - case 0x058: /* DISPC_TRANS_COLOR1 */ + case 0x058: /* DISPC_TRANS_COLOR1 */ s->dispc.trans[1] = value & 0xffffff; s->dispc.invalidate = 1; break; - case 0x060: /* DISPC_LINE_NUMBER */ + case 0x060: /* DISPC_LINE_NUMBER */ s->dispc.line = value & 0x7ff; break; - case 0x064: /* DISPC_TIMING_H */ + case 0x064: /* DISPC_TIMING_H */ s->dispc.timing[0] = value & 0x0ff0ff3f; break; - case 0x068: /* DISPC_TIMING_V */ + case 0x068: /* DISPC_TIMING_V */ s->dispc.timing[1] = value & 0x0ff0ff3f; break; - case 0x06c: /* DISPC_POL_FREQ */ + case 0x06c: /* DISPC_POL_FREQ */ s->dispc.timing[2] = value & 0x0003ffff; break; - case 0x070: /* DISPC_DIVISOR */ + case 0x070: /* DISPC_DIVISOR */ s->dispc.timing[3] = value & 0x00ff00ff; break; - case 0x078: /* DISPC_SIZE_DIG */ - s->dig.nx = ((value >> 0) & 0x7ff) + 1; /* PPL */ - s->dig.ny = ((value >> 16) & 0x7ff) + 1; /* LPP */ + case 0x078: /* DISPC_SIZE_DIG */ + s->dig.nx = ((value >> 0) & 0x7ff) + 1; /* PPL */ + s->dig.ny = ((value >> 16) & 0x7ff) + 1; /* LPP */ s->dispc.invalidate = 1; break; - case 0x07c: /* DISPC_SIZE_LCD */ - s->lcd.nx = ((value >> 0) & 0x7ff) + 1; /* PPL */ - s->lcd.ny = ((value >> 16) & 0x7ff) + 1; /* LPP */ + case 0x07c: /* DISPC_SIZE_LCD */ + s->lcd.nx = ((value >> 0) & 0x7ff) + 1; /* PPL */ + s->lcd.ny = ((value >> 16) & 0x7ff) + 1; /* LPP */ s->dispc.invalidate = 1; break; - case 0x080: /* DISPC_GFX_BA0 */ + case 0x080: /* DISPC_GFX_BA0 */ s->dispc.l[0].addr[0] = (hwaddr) value; s->dispc.invalidate = 1; break; - case 0x084: /* DISPC_GFX_BA1 */ + case 0x084: /* DISPC_GFX_BA1 */ s->dispc.l[0].addr[1] = (hwaddr) value; s->dispc.invalidate = 1; break; - case 0x088: /* DISPC_GFX_POSITION */ - s->dispc.l[0].posx = ((value >> 0) & 0x7ff); /* GFXPOSX */ - s->dispc.l[0].posy = ((value >> 16) & 0x7ff); /* GFXPOSY */ + case 0x088: /* DISPC_GFX_POSITION */ + s->dispc.l[0].posx = ((value >> 0) & 0x7ff); /* GFXPOSX */ + s->dispc.l[0].posy = ((value >> 16) & 0x7ff); /* GFXPOSY */ s->dispc.invalidate = 1; break; - case 0x08c: /* DISPC_GFX_SIZE */ - s->dispc.l[0].nx = ((value >> 0) & 0x7ff) + 1; /* GFXSIZEX */ - s->dispc.l[0].ny = ((value >> 16) & 0x7ff) + 1; /* GFXSIZEY */ + case 0x08c: /* DISPC_GFX_SIZE */ + s->dispc.l[0].nx = ((value >> 0) & 0x7ff) + 1; /* GFXSIZEX */ + s->dispc.l[0].ny = ((value >> 16) & 0x7ff) + 1; /* GFXSIZEY */ s->dispc.invalidate = 1; break; - case 0x0a0: /* DISPC_GFX_ATTRIBUTES */ + case 0x0a0: /* DISPC_GFX_ATTRIBUTES */ s->dispc.l[0].attr = value & 0x7ff; if (value & (3 << 9)) fprintf(stderr, "%s: Big-endian pixel format not supported\n", @@ -534,54 +534,54 @@ static void omap_disc_write(void *opaque, hwaddr addr, s->dispc.l[0].bpp = (value >> 1) & 0xf; s->dispc.invalidate = 1; break; - case 0x0a4: /* DISPC_GFX_FIFO_TRESHOLD */ + case 0x0a4: /* DISPC_GFX_FIFO_TRESHOLD */ s->dispc.l[0].tresh = value & 0x01ff01ff; break; - case 0x0ac: /* DISPC_GFX_ROW_INC */ + case 0x0ac: /* DISPC_GFX_ROW_INC */ s->dispc.l[0].rowinc = value; s->dispc.invalidate = 1; break; - case 0x0b0: /* DISPC_GFX_PIXEL_INC */ + case 0x0b0: /* DISPC_GFX_PIXEL_INC */ s->dispc.l[0].colinc = value; s->dispc.invalidate = 1; break; - case 0x0b4: /* DISPC_GFX_WINDOW_SKIP */ + case 0x0b4: /* DISPC_GFX_WINDOW_SKIP */ s->dispc.l[0].wininc = value; break; - case 0x0b8: /* DISPC_GFX_TABLE_BA */ + case 0x0b8: /* DISPC_GFX_TABLE_BA */ s->dispc.l[0].addr[2] = (hwaddr) value; s->dispc.invalidate = 1; break; - case 0x0bc: /* DISPC_VID1_BA0 */ - case 0x0c0: /* DISPC_VID1_BA1 */ - case 0x0c4: /* DISPC_VID1_POSITION */ - case 0x0c8: /* DISPC_VID1_SIZE */ - case 0x0cc: /* DISPC_VID1_ATTRIBUTES */ - case 0x0d0: /* DISPC_VID1_FIFO_TRESHOLD */ - case 0x0d8: /* DISPC_VID1_ROW_INC */ - case 0x0dc: /* DISPC_VID1_PIXEL_INC */ - case 0x0e0: /* DISPC_VID1_FIR */ - case 0x0e4: /* DISPC_VID1_PICTURE_SIZE */ - case 0x0e8: /* DISPC_VID1_ACCU0 */ - case 0x0ec: /* DISPC_VID1_ACCU1 */ - case 0x0f0 ... 0x140: /* DISPC_VID1_FIR_COEF, DISPC_VID1_CONV_COEF */ - case 0x14c: /* DISPC_VID2_BA0 */ - case 0x150: /* DISPC_VID2_BA1 */ - case 0x154: /* DISPC_VID2_POSITION */ - case 0x158: /* DISPC_VID2_SIZE */ - case 0x15c: /* DISPC_VID2_ATTRIBUTES */ - case 0x160: /* DISPC_VID2_FIFO_TRESHOLD */ - case 0x168: /* DISPC_VID2_ROW_INC */ - case 0x16c: /* DISPC_VID2_PIXEL_INC */ - case 0x170: /* DISPC_VID2_FIR */ - case 0x174: /* DISPC_VID2_PICTURE_SIZE */ - case 0x178: /* DISPC_VID2_ACCU0 */ - case 0x17c: /* DISPC_VID2_ACCU1 */ - case 0x180 ... 0x1d0: /* DISPC_VID2_FIR_COEF, DISPC_VID2_CONV_COEF */ - case 0x1d4: /* DISPC_DATA_CYCLE1 */ - case 0x1d8: /* DISPC_DATA_CYCLE2 */ - case 0x1dc: /* DISPC_DATA_CYCLE3 */ + case 0x0bc: /* DISPC_VID1_BA0 */ + case 0x0c0: /* DISPC_VID1_BA1 */ + case 0x0c4: /* DISPC_VID1_POSITION */ + case 0x0c8: /* DISPC_VID1_SIZE */ + case 0x0cc: /* DISPC_VID1_ATTRIBUTES */ + case 0x0d0: /* DISPC_VID1_FIFO_TRESHOLD */ + case 0x0d8: /* DISPC_VID1_ROW_INC */ + case 0x0dc: /* DISPC_VID1_PIXEL_INC */ + case 0x0e0: /* DISPC_VID1_FIR */ + case 0x0e4: /* DISPC_VID1_PICTURE_SIZE */ + case 0x0e8: /* DISPC_VID1_ACCU0 */ + case 0x0ec: /* DISPC_VID1_ACCU1 */ + case 0x0f0 ... 0x140: /* DISPC_VID1_FIR_COEF, DISPC_VID1_CONV_COEF */ + case 0x14c: /* DISPC_VID2_BA0 */ + case 0x150: /* DISPC_VID2_BA1 */ + case 0x154: /* DISPC_VID2_POSITION */ + case 0x158: /* DISPC_VID2_SIZE */ + case 0x15c: /* DISPC_VID2_ATTRIBUTES */ + case 0x160: /* DISPC_VID2_FIFO_TRESHOLD */ + case 0x168: /* DISPC_VID2_ROW_INC */ + case 0x16c: /* DISPC_VID2_PIXEL_INC */ + case 0x170: /* DISPC_VID2_FIR */ + case 0x174: /* DISPC_VID2_PICTURE_SIZE */ + case 0x178: /* DISPC_VID2_ACCU0 */ + case 0x17c: /* DISPC_VID2_ACCU1 */ + case 0x180 ... 0x1d0: /* DISPC_VID2_FIR_COEF, DISPC_VID2_CONV_COEF */ + case 0x1d4: /* DISPC_DATA_CYCLE1 */ + case 0x1d8: /* DISPC_DATA_CYCLE2 */ + case 0x1dc: /* DISPC_DATA_CYCLE3 */ break; default: @@ -617,14 +617,14 @@ static void omap_rfbi_transfer_start(struct omap_dss_s *s) if (!s->rfbi.enable || s->rfbi.busy) return; - if (s->rfbi.control & (1 << 1)) { /* BYPASS */ + if (s->rfbi.control & (1 << 1)) { /* BYPASS */ /* TODO: in non-Bypass mode we probably need to just assert the * DRQ and wait for DMA to write the pixels. */ qemu_log_mask(LOG_UNIMP, "%s: Bypass mode unimplemented\n", __func__); return; } - if (!(s->dispc.control & (1 << 11))) /* RFBIMODE */ + if (!(s->dispc.control & (1 << 11))) /* RFBIMODE */ return; /* TODO: check that LCD output is enabled in DISPC. */ @@ -665,7 +665,7 @@ static void omap_rfbi_transfer_start(struct omap_dss_s *s) omap_rfbi_transfer_stop(s); /* TODO */ - s->dispc.irqst |= 1; /* FRAMEDONE */ + s->dispc.irqst |= 1; /* FRAMEDONE */ omap_dispc_interrupt_update(s); } @@ -679,57 +679,57 @@ static uint64_t omap_rfbi_read(void *opaque, hwaddr addr, } switch (addr) { - case 0x00: /* RFBI_REVISION */ + case 0x00: /* RFBI_REVISION */ return 0x10; - case 0x10: /* RFBI_SYSCONFIG */ + case 0x10: /* RFBI_SYSCONFIG */ return s->rfbi.idlemode; - case 0x14: /* RFBI_SYSSTATUS */ - return 1 | (s->rfbi.busy << 8); /* RESETDONE */ + case 0x14: /* RFBI_SYSSTATUS */ + return 1 | (s->rfbi.busy << 8); /* RESETDONE */ - case 0x40: /* RFBI_CONTROL */ + case 0x40: /* RFBI_CONTROL */ return s->rfbi.control; - case 0x44: /* RFBI_PIXELCNT */ + case 0x44: /* RFBI_PIXELCNT */ return s->rfbi.pixels; - case 0x48: /* RFBI_LINE_NUMBER */ + case 0x48: /* RFBI_LINE_NUMBER */ return s->rfbi.skiplines; - case 0x58: /* RFBI_READ */ - case 0x5c: /* RFBI_STATUS */ + case 0x58: /* RFBI_READ */ + case 0x5c: /* RFBI_STATUS */ return s->rfbi.rxbuf; - case 0x60: /* RFBI_CONFIG0 */ + case 0x60: /* RFBI_CONFIG0 */ return s->rfbi.config[0]; - case 0x64: /* RFBI_ONOFF_TIME0 */ + case 0x64: /* RFBI_ONOFF_TIME0 */ return s->rfbi.time[0]; - case 0x68: /* RFBI_CYCLE_TIME0 */ + case 0x68: /* RFBI_CYCLE_TIME0 */ return s->rfbi.time[1]; - case 0x6c: /* RFBI_DATA_CYCLE1_0 */ + case 0x6c: /* RFBI_DATA_CYCLE1_0 */ return s->rfbi.data[0]; - case 0x70: /* RFBI_DATA_CYCLE2_0 */ + case 0x70: /* RFBI_DATA_CYCLE2_0 */ return s->rfbi.data[1]; - case 0x74: /* RFBI_DATA_CYCLE3_0 */ + case 0x74: /* RFBI_DATA_CYCLE3_0 */ return s->rfbi.data[2]; - case 0x78: /* RFBI_CONFIG1 */ + case 0x78: /* RFBI_CONFIG1 */ return s->rfbi.config[1]; - case 0x7c: /* RFBI_ONOFF_TIME1 */ + case 0x7c: /* RFBI_ONOFF_TIME1 */ return s->rfbi.time[2]; - case 0x80: /* RFBI_CYCLE_TIME1 */ + case 0x80: /* RFBI_CYCLE_TIME1 */ return s->rfbi.time[3]; - case 0x84: /* RFBI_DATA_CYCLE1_1 */ + case 0x84: /* RFBI_DATA_CYCLE1_1 */ return s->rfbi.data[3]; - case 0x88: /* RFBI_DATA_CYCLE2_1 */ + case 0x88: /* RFBI_DATA_CYCLE2_1 */ return s->rfbi.data[4]; - case 0x8c: /* RFBI_DATA_CYCLE3_1 */ + case 0x8c: /* RFBI_DATA_CYCLE3_1 */ return s->rfbi.data[5]; - case 0x90: /* RFBI_VSYNC_WIDTH */ + case 0x90: /* RFBI_VSYNC_WIDTH */ return s->rfbi.vsync; - case 0x94: /* RFBI_HSYNC_WIDTH */ + case 0x94: /* RFBI_HSYNC_WIDTH */ return s->rfbi.hsync; } OMAP_BAD_REG(addr); @@ -747,41 +747,41 @@ static void omap_rfbi_write(void *opaque, hwaddr addr, } switch (addr) { - case 0x10: /* RFBI_SYSCONFIG */ - if (value & 2) /* SOFTRESET */ + case 0x10: /* RFBI_SYSCONFIG */ + if (value & 2) /* SOFTRESET */ omap_rfbi_reset(s); s->rfbi.idlemode = value & 0x19; break; - case 0x40: /* RFBI_CONTROL */ + case 0x40: /* RFBI_CONTROL */ s->rfbi.control = value & 0xf; s->rfbi.enable = value & 1; - if (value & (1 << 4) && /* ITE */ + if (value & (1 << 4) && /* ITE */ !(s->rfbi.config[0] & s->rfbi.config[1] & 0xc)) omap_rfbi_transfer_start(s); break; - case 0x44: /* RFBI_PIXELCNT */ + case 0x44: /* RFBI_PIXELCNT */ s->rfbi.pixels = value; break; - case 0x48: /* RFBI_LINE_NUMBER */ + case 0x48: /* RFBI_LINE_NUMBER */ s->rfbi.skiplines = value & 0x7ff; break; - case 0x4c: /* RFBI_CMD */ + case 0x4c: /* RFBI_CMD */ if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0]) s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 0, value & 0xffff); if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1]) s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 0, value & 0xffff); break; - case 0x50: /* RFBI_PARAM */ + case 0x50: /* RFBI_PARAM */ if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0]) s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 1, value & 0xffff); if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1]) s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 1, value & 0xffff); break; - case 0x54: /* RFBI_DATA */ + case 0x54: /* RFBI_DATA */ /* TODO: take into account the format set up in s->rfbi.config[?] and * s->rfbi.data[?], but special-case the most usual scenario so that * speed doesn't suffer. */ @@ -796,7 +796,7 @@ static void omap_rfbi_write(void *opaque, hwaddr addr, if (!-- s->rfbi.pixels) omap_rfbi_transfer_stop(s); break; - case 0x58: /* RFBI_READ */ + case 0x58: /* RFBI_READ */ if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0]) s->rfbi.rxbuf = s->rfbi.chip[0]->read(s->rfbi.chip[0]->opaque, 1); else if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1]) @@ -805,7 +805,7 @@ static void omap_rfbi_write(void *opaque, hwaddr addr, omap_rfbi_transfer_stop(s); break; - case 0x5c: /* RFBI_STATUS */ + case 0x5c: /* RFBI_STATUS */ if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0]) s->rfbi.rxbuf = s->rfbi.chip[0]->read(s->rfbi.chip[0]->opaque, 0); else if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1]) @@ -814,49 +814,49 @@ static void omap_rfbi_write(void *opaque, hwaddr addr, omap_rfbi_transfer_stop(s); break; - case 0x60: /* RFBI_CONFIG0 */ + case 0x60: /* RFBI_CONFIG0 */ s->rfbi.config[0] = value & 0x003f1fff; break; - case 0x64: /* RFBI_ONOFF_TIME0 */ + case 0x64: /* RFBI_ONOFF_TIME0 */ s->rfbi.time[0] = value & 0x3fffffff; break; - case 0x68: /* RFBI_CYCLE_TIME0 */ + case 0x68: /* RFBI_CYCLE_TIME0 */ s->rfbi.time[1] = value & 0x0fffffff; break; - case 0x6c: /* RFBI_DATA_CYCLE1_0 */ + case 0x6c: /* RFBI_DATA_CYCLE1_0 */ s->rfbi.data[0] = value & 0x0f1f0f1f; break; - case 0x70: /* RFBI_DATA_CYCLE2_0 */ + case 0x70: /* RFBI_DATA_CYCLE2_0 */ s->rfbi.data[1] = value & 0x0f1f0f1f; break; - case 0x74: /* RFBI_DATA_CYCLE3_0 */ + case 0x74: /* RFBI_DATA_CYCLE3_0 */ s->rfbi.data[2] = value & 0x0f1f0f1f; break; - case 0x78: /* RFBI_CONFIG1 */ + case 0x78: /* RFBI_CONFIG1 */ s->rfbi.config[1] = value & 0x003f1fff; break; - case 0x7c: /* RFBI_ONOFF_TIME1 */ + case 0x7c: /* RFBI_ONOFF_TIME1 */ s->rfbi.time[2] = value & 0x3fffffff; break; - case 0x80: /* RFBI_CYCLE_TIME1 */ + case 0x80: /* RFBI_CYCLE_TIME1 */ s->rfbi.time[3] = value & 0x0fffffff; break; - case 0x84: /* RFBI_DATA_CYCLE1_1 */ + case 0x84: /* RFBI_DATA_CYCLE1_1 */ s->rfbi.data[3] = value & 0x0f1f0f1f; break; - case 0x88: /* RFBI_DATA_CYCLE2_1 */ + case 0x88: /* RFBI_DATA_CYCLE2_1 */ s->rfbi.data[4] = value & 0x0f1f0f1f; break; - case 0x8c: /* RFBI_DATA_CYCLE3_1 */ + case 0x8c: /* RFBI_DATA_CYCLE3_1 */ s->rfbi.data[5] = value & 0x0f1f0f1f; break; - case 0x90: /* RFBI_VSYNC_WIDTH */ + case 0x90: /* RFBI_VSYNC_WIDTH */ s->rfbi.vsync = value & 0xffff; break; - case 0x94: /* RFBI_HSYNC_WIDTH */ + case 0x94: /* RFBI_HSYNC_WIDTH */ s->rfbi.hsync = value & 0xffff; break; @@ -879,49 +879,49 @@ static uint64_t omap_venc_read(void *opaque, hwaddr addr, } switch (addr) { - case 0x00: /* REV_ID */ - case 0x04: /* STATUS */ - case 0x08: /* F_CONTROL */ - case 0x10: /* VIDOUT_CTRL */ - case 0x14: /* SYNC_CTRL */ - case 0x1c: /* LLEN */ - case 0x20: /* FLENS */ - case 0x24: /* HFLTR_CTRL */ - case 0x28: /* CC_CARR_WSS_CARR */ - case 0x2c: /* C_PHASE */ - case 0x30: /* GAIN_U */ - case 0x34: /* GAIN_V */ - case 0x38: /* GAIN_Y */ - case 0x3c: /* BLACK_LEVEL */ - case 0x40: /* BLANK_LEVEL */ - case 0x44: /* X_COLOR */ - case 0x48: /* M_CONTROL */ - case 0x4c: /* BSTAMP_WSS_DATA */ - case 0x50: /* S_CARR */ - case 0x54: /* LINE21 */ - case 0x58: /* LN_SEL */ - case 0x5c: /* L21__WC_CTL */ - case 0x60: /* HTRIGGER_VTRIGGER */ - case 0x64: /* SAVID__EAVID */ - case 0x68: /* FLEN__FAL */ - case 0x6c: /* LAL__PHASE_RESET */ - case 0x70: /* HS_INT_START_STOP_X */ - case 0x74: /* HS_EXT_START_STOP_X */ - case 0x78: /* VS_INT_START_X */ - case 0x7c: /* VS_INT_STOP_X__VS_INT_START_Y */ - case 0x80: /* VS_INT_STOP_Y__VS_INT_START_X */ - case 0x84: /* VS_EXT_STOP_X__VS_EXT_START_Y */ - case 0x88: /* VS_EXT_STOP_Y */ - case 0x90: /* AVID_START_STOP_X */ - case 0x94: /* AVID_START_STOP_Y */ - case 0xa0: /* FID_INT_START_X__FID_INT_START_Y */ - case 0xa4: /* FID_INT_OFFSET_Y__FID_EXT_START_X */ - case 0xa8: /* FID_EXT_START_Y__FID_EXT_OFFSET_Y */ - case 0xb0: /* TVDETGP_INT_START_STOP_X */ - case 0xb4: /* TVDETGP_INT_START_STOP_Y */ - case 0xb8: /* GEN_CTRL */ - case 0xc4: /* DAC_TST__DAC_A */ - case 0xc8: /* DAC_B__DAC_C */ + case 0x00: /* REV_ID */ + case 0x04: /* STATUS */ + case 0x08: /* F_CONTROL */ + case 0x10: /* VIDOUT_CTRL */ + case 0x14: /* SYNC_CTRL */ + case 0x1c: /* LLEN */ + case 0x20: /* FLENS */ + case 0x24: /* HFLTR_CTRL */ + case 0x28: /* CC_CARR_WSS_CARR */ + case 0x2c: /* C_PHASE */ + case 0x30: /* GAIN_U */ + case 0x34: /* GAIN_V */ + case 0x38: /* GAIN_Y */ + case 0x3c: /* BLACK_LEVEL */ + case 0x40: /* BLANK_LEVEL */ + case 0x44: /* X_COLOR */ + case 0x48: /* M_CONTROL */ + case 0x4c: /* BSTAMP_WSS_DATA */ + case 0x50: /* S_CARR */ + case 0x54: /* LINE21 */ + case 0x58: /* LN_SEL */ + case 0x5c: /* L21__WC_CTL */ + case 0x60: /* HTRIGGER_VTRIGGER */ + case 0x64: /* SAVID__EAVID */ + case 0x68: /* FLEN__FAL */ + case 0x6c: /* LAL__PHASE_RESET */ + case 0x70: /* HS_INT_START_STOP_X */ + case 0x74: /* HS_EXT_START_STOP_X */ + case 0x78: /* VS_INT_START_X */ + case 0x7c: /* VS_INT_STOP_X__VS_INT_START_Y */ + case 0x80: /* VS_INT_STOP_Y__VS_INT_START_X */ + case 0x84: /* VS_EXT_STOP_X__VS_EXT_START_Y */ + case 0x88: /* VS_EXT_STOP_Y */ + case 0x90: /* AVID_START_STOP_X */ + case 0x94: /* AVID_START_STOP_Y */ + case 0xa0: /* FID_INT_START_X__FID_INT_START_Y */ + case 0xa4: /* FID_INT_OFFSET_Y__FID_EXT_START_X */ + case 0xa8: /* FID_EXT_START_Y__FID_EXT_OFFSET_Y */ + case 0xb0: /* TVDETGP_INT_START_STOP_X */ + case 0xb4: /* TVDETGP_INT_START_STOP_Y */ + case 0xb8: /* GEN_CTRL */ + case 0xc4: /* DAC_TST__DAC_A */ + case 0xc8: /* DAC_B__DAC_C */ return 0; default: @@ -940,47 +940,47 @@ static void omap_venc_write(void *opaque, hwaddr addr, } switch (addr) { - case 0x08: /* F_CONTROL */ - case 0x10: /* VIDOUT_CTRL */ - case 0x14: /* SYNC_CTRL */ - case 0x1c: /* LLEN */ - case 0x20: /* FLENS */ - case 0x24: /* HFLTR_CTRL */ - case 0x28: /* CC_CARR_WSS_CARR */ - case 0x2c: /* C_PHASE */ - case 0x30: /* GAIN_U */ - case 0x34: /* GAIN_V */ - case 0x38: /* GAIN_Y */ - case 0x3c: /* BLACK_LEVEL */ - case 0x40: /* BLANK_LEVEL */ - case 0x44: /* X_COLOR */ - case 0x48: /* M_CONTROL */ - case 0x4c: /* BSTAMP_WSS_DATA */ - case 0x50: /* S_CARR */ - case 0x54: /* LINE21 */ - case 0x58: /* LN_SEL */ - case 0x5c: /* L21__WC_CTL */ - case 0x60: /* HTRIGGER_VTRIGGER */ - case 0x64: /* SAVID__EAVID */ - case 0x68: /* FLEN__FAL */ - case 0x6c: /* LAL__PHASE_RESET */ - case 0x70: /* HS_INT_START_STOP_X */ - case 0x74: /* HS_EXT_START_STOP_X */ - case 0x78: /* VS_INT_START_X */ - case 0x7c: /* VS_INT_STOP_X__VS_INT_START_Y */ - case 0x80: /* VS_INT_STOP_Y__VS_INT_START_X */ - case 0x84: /* VS_EXT_STOP_X__VS_EXT_START_Y */ - case 0x88: /* VS_EXT_STOP_Y */ - case 0x90: /* AVID_START_STOP_X */ - case 0x94: /* AVID_START_STOP_Y */ - case 0xa0: /* FID_INT_START_X__FID_INT_START_Y */ - case 0xa4: /* FID_INT_OFFSET_Y__FID_EXT_START_X */ - case 0xa8: /* FID_EXT_START_Y__FID_EXT_OFFSET_Y */ - case 0xb0: /* TVDETGP_INT_START_STOP_X */ - case 0xb4: /* TVDETGP_INT_START_STOP_Y */ - case 0xb8: /* GEN_CTRL */ - case 0xc4: /* DAC_TST__DAC_A */ - case 0xc8: /* DAC_B__DAC_C */ + case 0x08: /* F_CONTROL */ + case 0x10: /* VIDOUT_CTRL */ + case 0x14: /* SYNC_CTRL */ + case 0x1c: /* LLEN */ + case 0x20: /* FLENS */ + case 0x24: /* HFLTR_CTRL */ + case 0x28: /* CC_CARR_WSS_CARR */ + case 0x2c: /* C_PHASE */ + case 0x30: /* GAIN_U */ + case 0x34: /* GAIN_V */ + case 0x38: /* GAIN_Y */ + case 0x3c: /* BLACK_LEVEL */ + case 0x40: /* BLANK_LEVEL */ + case 0x44: /* X_COLOR */ + case 0x48: /* M_CONTROL */ + case 0x4c: /* BSTAMP_WSS_DATA */ + case 0x50: /* S_CARR */ + case 0x54: /* LINE21 */ + case 0x58: /* LN_SEL */ + case 0x5c: /* L21__WC_CTL */ + case 0x60: /* HTRIGGER_VTRIGGER */ + case 0x64: /* SAVID__EAVID */ + case 0x68: /* FLEN__FAL */ + case 0x6c: /* LAL__PHASE_RESET */ + case 0x70: /* HS_INT_START_STOP_X */ + case 0x74: /* HS_EXT_START_STOP_X */ + case 0x78: /* VS_INT_START_X */ + case 0x7c: /* VS_INT_STOP_X__VS_INT_START_Y */ + case 0x80: /* VS_INT_STOP_Y__VS_INT_START_X */ + case 0x84: /* VS_EXT_STOP_X__VS_EXT_START_Y */ + case 0x88: /* VS_EXT_STOP_Y */ + case 0x90: /* AVID_START_STOP_X */ + case 0x94: /* AVID_START_STOP_Y */ + case 0xa0: /* FID_INT_START_X__FID_INT_START_Y */ + case 0xa4: /* FID_INT_OFFSET_Y__FID_EXT_START_X */ + case 0xa8: /* FID_EXT_START_Y__FID_EXT_OFFSET_Y */ + case 0xb0: /* TVDETGP_INT_START_STOP_X */ + case 0xb4: /* TVDETGP_INT_START_STOP_Y */ + case 0xb8: /* GEN_CTRL */ + case 0xc4: /* DAC_TST__DAC_A */ + case 0xc8: /* DAC_B__DAC_C */ break; default: @@ -1002,15 +1002,15 @@ static uint64_t omap_im3_read(void *opaque, hwaddr addr, } switch (addr) { - case 0x0a8: /* SBIMERRLOGA */ - case 0x0b0: /* SBIMERRLOG */ - case 0x190: /* SBIMSTATE */ - case 0x198: /* SBTMSTATE_L */ - case 0x19c: /* SBTMSTATE_H */ - case 0x1a8: /* SBIMCONFIG_L */ - case 0x1ac: /* SBIMCONFIG_H */ - case 0x1f8: /* SBID_L */ - case 0x1fc: /* SBID_H */ + case 0x0a8: /* SBIMERRLOGA */ + case 0x0b0: /* SBIMERRLOG */ + case 0x190: /* SBIMSTATE */ + case 0x198: /* SBTMSTATE_L */ + case 0x19c: /* SBTMSTATE_H */ + case 0x1a8: /* SBIMCONFIG_L */ + case 0x1ac: /* SBIMCONFIG_H */ + case 0x1f8: /* SBID_L */ + case 0x1fc: /* SBID_H */ return 0; default: @@ -1029,12 +1029,12 @@ static void omap_im3_write(void *opaque, hwaddr addr, } switch (addr) { - case 0x0b0: /* SBIMERRLOG */ - case 0x190: /* SBIMSTATE */ - case 0x198: /* SBTMSTATE_L */ - case 0x19c: /* SBTMSTATE_H */ - case 0x1a8: /* SBIMCONFIG_L */ - case 0x1ac: /* SBIMCONFIG_H */ + case 0x0b0: /* SBIMERRLOG */ + case 0x190: /* SBIMSTATE */ + case 0x198: /* SBTMSTATE_L */ + case 0x19c: /* SBTMSTATE_H */ + case 0x1a8: /* SBIMCONFIG_L */ + case 0x1ac: /* SBIMCONFIG_H */ break; default: diff --git a/hw/display/pxa2xx_lcd.c b/hw/display/pxa2xx_lcd.c index 7859c5d1cd..eb83d88222 100644 --- a/hw/display/pxa2xx_lcd.c +++ b/hw/display/pxa2xx_lcd.c @@ -86,106 +86,106 @@ typedef struct QEMU_PACKED { uint32_t ldcmd; } PXAFrameDescriptor; -#define LCCR0 0x000 /* LCD Controller Control register 0 */ -#define LCCR1 0x004 /* LCD Controller Control register 1 */ -#define LCCR2 0x008 /* LCD Controller Control register 2 */ -#define LCCR3 0x00c /* LCD Controller Control register 3 */ -#define LCCR4 0x010 /* LCD Controller Control register 4 */ -#define LCCR5 0x014 /* LCD Controller Control register 5 */ +#define LCCR0 0x000 /* LCD Controller Control register 0 */ +#define LCCR1 0x004 /* LCD Controller Control register 1 */ +#define LCCR2 0x008 /* LCD Controller Control register 2 */ +#define LCCR3 0x00c /* LCD Controller Control register 3 */ +#define LCCR4 0x010 /* LCD Controller Control register 4 */ +#define LCCR5 0x014 /* LCD Controller Control register 5 */ -#define FBR0 0x020 /* DMA Channel 0 Frame Branch register */ -#define FBR1 0x024 /* DMA Channel 1 Frame Branch register */ -#define FBR2 0x028 /* DMA Channel 2 Frame Branch register */ -#define FBR3 0x02c /* DMA Channel 3 Frame Branch register */ -#define FBR4 0x030 /* DMA Channel 4 Frame Branch register */ -#define FBR5 0x110 /* DMA Channel 5 Frame Branch register */ -#define FBR6 0x114 /* DMA Channel 6 Frame Branch register */ +#define FBR0 0x020 /* DMA Channel 0 Frame Branch register */ +#define FBR1 0x024 /* DMA Channel 1 Frame Branch register */ +#define FBR2 0x028 /* DMA Channel 2 Frame Branch register */ +#define FBR3 0x02c /* DMA Channel 3 Frame Branch register */ +#define FBR4 0x030 /* DMA Channel 4 Frame Branch register */ +#define FBR5 0x110 /* DMA Channel 5 Frame Branch register */ +#define FBR6 0x114 /* DMA Channel 6 Frame Branch register */ -#define LCSR1 0x034 /* LCD Controller Status register 1 */ -#define LCSR0 0x038 /* LCD Controller Status register 0 */ -#define LIIDR 0x03c /* LCD Controller Interrupt ID register */ +#define LCSR1 0x034 /* LCD Controller Status register 1 */ +#define LCSR0 0x038 /* LCD Controller Status register 0 */ +#define LIIDR 0x03c /* LCD Controller Interrupt ID register */ -#define TRGBR 0x040 /* TMED RGB Seed register */ -#define TCR 0x044 /* TMED Control register */ +#define TRGBR 0x040 /* TMED RGB Seed register */ +#define TCR 0x044 /* TMED Control register */ -#define OVL1C1 0x050 /* Overlay 1 Control register 1 */ -#define OVL1C2 0x060 /* Overlay 1 Control register 2 */ -#define OVL2C1 0x070 /* Overlay 2 Control register 1 */ -#define OVL2C2 0x080 /* Overlay 2 Control register 2 */ -#define CCR 0x090 /* Cursor Control register */ +#define OVL1C1 0x050 /* Overlay 1 Control register 1 */ +#define OVL1C2 0x060 /* Overlay 1 Control register 2 */ +#define OVL2C1 0x070 /* Overlay 2 Control register 1 */ +#define OVL2C2 0x080 /* Overlay 2 Control register 2 */ +#define CCR 0x090 /* Cursor Control register */ -#define CMDCR 0x100 /* Command Control register */ -#define PRSR 0x104 /* Panel Read Status register */ +#define CMDCR 0x100 /* Command Control register */ +#define PRSR 0x104 /* Panel Read Status register */ -#define PXA_LCDDMA_CHANS 7 -#define DMA_FDADR 0x00 /* Frame Descriptor Address register */ -#define DMA_FSADR 0x04 /* Frame Source Address register */ -#define DMA_FIDR 0x08 /* Frame ID register */ -#define DMA_LDCMD 0x0c /* Command register */ +#define PXA_LCDDMA_CHANS 7 +#define DMA_FDADR 0x00 /* Frame Descriptor Address register */ +#define DMA_FSADR 0x04 /* Frame Source Address register */ +#define DMA_FIDR 0x08 /* Frame ID register */ +#define DMA_LDCMD 0x0c /* Command register */ /* LCD Buffer Strength Control register */ -#define BSCNTR 0x04000054 +#define BSCNTR 0x04000054 /* Bitfield masks */ -#define LCCR0_ENB (1 << 0) -#define LCCR0_CMS (1 << 1) -#define LCCR0_SDS (1 << 2) -#define LCCR0_LDM (1 << 3) -#define LCCR0_SOFM0 (1 << 4) -#define LCCR0_IUM (1 << 5) -#define LCCR0_EOFM0 (1 << 6) -#define LCCR0_PAS (1 << 7) -#define LCCR0_DPD (1 << 9) -#define LCCR0_DIS (1 << 10) -#define LCCR0_QDM (1 << 11) -#define LCCR0_PDD (0xff << 12) -#define LCCR0_BSM0 (1 << 20) -#define LCCR0_OUM (1 << 21) -#define LCCR0_LCDT (1 << 22) -#define LCCR0_RDSTM (1 << 23) -#define LCCR0_CMDIM (1 << 24) -#define LCCR0_OUC (1 << 25) -#define LCCR0_LDDALT (1 << 26) -#define LCCR1_PPL(x) ((x) & 0x3ff) -#define LCCR2_LPP(x) ((x) & 0x3ff) -#define LCCR3_API (15 << 16) -#define LCCR3_BPP(x) ((((x) >> 24) & 7) | (((x) >> 26) & 8)) -#define LCCR3_PDFOR(x) (((x) >> 30) & 3) -#define LCCR4_K1(x) (((x) >> 0) & 7) -#define LCCR4_K2(x) (((x) >> 3) & 7) -#define LCCR4_K3(x) (((x) >> 6) & 7) -#define LCCR4_PALFOR(x) (((x) >> 15) & 3) -#define LCCR5_SOFM(ch) (1 << (ch - 1)) -#define LCCR5_EOFM(ch) (1 << (ch + 7)) -#define LCCR5_BSM(ch) (1 << (ch + 15)) -#define LCCR5_IUM(ch) (1 << (ch + 23)) -#define OVLC1_EN (1 << 31) -#define CCR_CEN (1 << 31) -#define FBR_BRA (1 << 0) -#define FBR_BINT (1 << 1) -#define FBR_SRCADDR (0xfffffff << 4) -#define LCSR0_LDD (1 << 0) -#define LCSR0_SOF0 (1 << 1) -#define LCSR0_BER (1 << 2) -#define LCSR0_ABC (1 << 3) -#define LCSR0_IU0 (1 << 4) -#define LCSR0_IU1 (1 << 5) -#define LCSR0_OU (1 << 6) -#define LCSR0_QD (1 << 7) -#define LCSR0_EOF0 (1 << 8) -#define LCSR0_BS0 (1 << 9) -#define LCSR0_SINT (1 << 10) -#define LCSR0_RDST (1 << 11) -#define LCSR0_CMDINT (1 << 12) -#define LCSR0_BERCH(x) (((x) & 7) << 28) -#define LCSR1_SOF(ch) (1 << (ch - 1)) -#define LCSR1_EOF(ch) (1 << (ch + 7)) -#define LCSR1_BS(ch) (1 << (ch + 15)) -#define LCSR1_IU(ch) (1 << (ch + 23)) -#define LDCMD_LENGTH(x) ((x) & 0x001ffffc) -#define LDCMD_EOFINT (1 << 21) -#define LDCMD_SOFINT (1 << 22) -#define LDCMD_PAL (1 << 26) +#define LCCR0_ENB (1 << 0) +#define LCCR0_CMS (1 << 1) +#define LCCR0_SDS (1 << 2) +#define LCCR0_LDM (1 << 3) +#define LCCR0_SOFM0 (1 << 4) +#define LCCR0_IUM (1 << 5) +#define LCCR0_EOFM0 (1 << 6) +#define LCCR0_PAS (1 << 7) +#define LCCR0_DPD (1 << 9) +#define LCCR0_DIS (1 << 10) +#define LCCR0_QDM (1 << 11) +#define LCCR0_PDD (0xff << 12) +#define LCCR0_BSM0 (1 << 20) +#define LCCR0_OUM (1 << 21) +#define LCCR0_LCDT (1 << 22) +#define LCCR0_RDSTM (1 << 23) +#define LCCR0_CMDIM (1 << 24) +#define LCCR0_OUC (1 << 25) +#define LCCR0_LDDALT (1 << 26) +#define LCCR1_PPL(x) ((x) & 0x3ff) +#define LCCR2_LPP(x) ((x) & 0x3ff) +#define LCCR3_API (15 << 16) +#define LCCR3_BPP(x) ((((x) >> 24) & 7) | (((x) >> 26) & 8)) +#define LCCR3_PDFOR(x) (((x) >> 30) & 3) +#define LCCR4_K1(x) (((x) >> 0) & 7) +#define LCCR4_K2(x) (((x) >> 3) & 7) +#define LCCR4_K3(x) (((x) >> 6) & 7) +#define LCCR4_PALFOR(x) (((x) >> 15) & 3) +#define LCCR5_SOFM(ch) (1 << (ch - 1)) +#define LCCR5_EOFM(ch) (1 << (ch + 7)) +#define LCCR5_BSM(ch) (1 << (ch + 15)) +#define LCCR5_IUM(ch) (1 << (ch + 23)) +#define OVLC1_EN (1 << 31) +#define CCR_CEN (1 << 31) +#define FBR_BRA (1 << 0) +#define FBR_BINT (1 << 1) +#define FBR_SRCADDR (0xfffffff << 4) +#define LCSR0_LDD (1 << 0) +#define LCSR0_SOF0 (1 << 1) +#define LCSR0_BER (1 << 2) +#define LCSR0_ABC (1 << 3) +#define LCSR0_IU0 (1 << 4) +#define LCSR0_IU1 (1 << 5) +#define LCSR0_OU (1 << 6) +#define LCSR0_QD (1 << 7) +#define LCSR0_EOF0 (1 << 8) +#define LCSR0_BS0 (1 << 9) +#define LCSR0_SINT (1 << 10) +#define LCSR0_RDST (1 << 11) +#define LCSR0_CMDINT (1 << 12) +#define LCSR0_BERCH(x) (((x) & 7) << 28) +#define LCSR1_SOF(ch) (1 << (ch - 1)) +#define LCSR1_EOF(ch) (1 << (ch + 7)) +#define LCSR1_BS(ch) (1 << (ch + 15)) +#define LCSR1_IU(ch) (1 << (ch + 23)) +#define LDCMD_LENGTH(x) ((x) & 0x001ffffc) +#define LDCMD_EOFINT (1 << 21) +#define LDCMD_SOFINT (1 << 22) +#define LDCMD_PAL (1 << 26) /* Size of a pixel in the QEMU UI output surface, in bytes */ #define DEST_PIXEL_WIDTH 4 @@ -788,7 +788,7 @@ static uint64_t pxa2xx_lcdc_read(void *opaque, hwaddr offset, case TCR: return s->tcr; - case 0x200 ... 0x1000: /* DMA per-channel registers */ + case 0x200 ... 0x1000: /* DMA per-channel registers */ ch = (offset - 0x200) >> 4; if (!(ch >= 0 && ch < PXA_LCDDMA_CHANS)) goto fail; @@ -938,7 +938,7 @@ static void pxa2xx_lcdc_write(void *opaque, hwaddr offset, s->tcr = value & 0x7fff; break; - case 0x200 ... 0x1000: /* DMA per-channel registers */ + case 0x200 ... 0x1000: /* DMA per-channel registers */ ch = (offset - 0x200) >> 4; if (!(ch >= 0 && ch < PXA_LCDDMA_CHANS)) goto fail; diff --git a/hw/display/vga_regs.h b/hw/display/vga_regs.h index 30a98b8736..7fdba34b9b 100644 --- a/hw/display/vga_regs.h +++ b/hw/display/vga_regs.h @@ -4,9 +4,9 @@ * Copyright 1999 Jeff Garzik * * Copyright history from vga16fb.c: - * Copyright 1999 Ben Pfaff and Petr Vandrovec - * Based on VGA info at http://www.osdever.net/FreeVGA/home.htm - * Based on VESA framebuffer (c) 1998 Gerd Knorr + * Copyright 1999 Ben Pfaff and Petr Vandrovec + * Based on VGA info at http://www.osdever.net/FreeVGA/home.htm + * Based on VESA framebuffer (c) 1998 Gerd Knorr * * This file is subject to the terms and conditions of the GNU General * Public License. See the file COPYING in the main directory of this diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c index 50857cd97a..260eb38a76 100644 --- a/hw/display/xenfb.c +++ b/hw/display/xenfb.c @@ -76,7 +76,7 @@ struct XenFB { int do_resize; struct { - int x,y,w,h; + int x,y,w,h; } up_rects[UP_QUEUE]; int up_count; int up_fullscreen; @@ -116,32 +116,32 @@ static void common_unbind(struct common *c) xen_pv_unbind_evtchn(&c->xendev); if (c->page) { xenforeignmemory_unmap(xen_fmem, c->page, 1); - c->page = NULL; + c->page = NULL; } } /* -------------------------------------------------------------------- */ /* Send an event to the keyboard frontend driver */ static int xenfb_kbd_event(struct XenInput *xenfb, - union xenkbd_in_event *event) + union xenkbd_in_event *event) { struct xenkbd_page *page = xenfb->c.page; uint32_t prod; if (xenfb->c.xendev.be_state != XenbusStateConnected) - return 0; + return 0; if (!page) return 0; prod = page->in_prod; if (prod - page->in_cons == XENKBD_IN_RING_LEN) { - errno = EAGAIN; - return -1; + errno = EAGAIN; + return -1; } - xen_mb(); /* ensure ring space available */ + xen_mb(); /* ensure ring space available */ XENKBD_IN_RING_REF(page, prod) = *event; - xen_wmb(); /* ensure ring contents visible */ + xen_wmb(); /* ensure ring contents visible */ page->in_prod = prod + 1; return xen_pv_send_notify(&xenfb->c.xendev); } @@ -161,7 +161,7 @@ static int xenfb_send_key(struct XenInput *xenfb, bool down, int keycode) /* Send a relative mouse movement event */ static int xenfb_send_motion(struct XenInput *xenfb, - int rel_x, int rel_y, int rel_z) + int rel_x, int rel_y, int rel_z) { union xenkbd_in_event event; @@ -176,7 +176,7 @@ static int xenfb_send_motion(struct XenInput *xenfb, /* Send an absolute mouse movement event */ static int xenfb_send_position(struct XenInput *xenfb, - int abs_x, int abs_y, int z) + int abs_x, int abs_y, int z) { union xenkbd_in_event event; @@ -354,7 +354,7 @@ static int input_initialise(struct XenLegacyDevice *xendev) rc = common_bind(&in->c); if (rc != 0) - return rc; + return rc; return 0; } @@ -415,7 +415,7 @@ static void input_event(struct XenLegacyDevice *xendev) /* We don't understand any keyboard events, so just ignore them. */ if (page->out_prod == page->out_cons) - return; + return; page->out_cons = page->out_prod; xen_pv_send_notify(&xenfb->c.xendev); } @@ -429,7 +429,7 @@ static void xenfb_copy_mfns(int mode, int count, xen_pfn_t *dst, void *src) int i; for (i = 0; i < count; i++) - dst[i] = (mode == 32) ? src32[i] : src64[i]; + dst[i] = (mode == 32) ? src32[i] : src64[i]; } static int xenfb_map_fb(struct XenFB *xenfb) @@ -447,43 +447,43 @@ static int xenfb_map_fb(struct XenFB *xenfb) mode = sizeof(unsigned long) * 8; if (!protocol) { - /* - * Undefined protocol, some guesswork needed. - * - * Old frontends which don't set the protocol use - * one page directory only, thus pd[1] must be zero. - * pd[1] of the 32bit struct layout and the lower - * 32 bits of pd[0] of the 64bit struct layout have - * the same location, so we can check that ... - */ - uint32_t *ptr32 = NULL; - uint32_t *ptr64 = NULL; + /* + * Undefined protocol, some guesswork needed. + * + * Old frontends which don't set the protocol use + * one page directory only, thus pd[1] must be zero. + * pd[1] of the 32bit struct layout and the lower + * 32 bits of pd[0] of the 64bit struct layout have + * the same location, so we can check that ... + */ + uint32_t *ptr32 = NULL; + uint32_t *ptr64 = NULL; #if defined(__i386__) - ptr32 = (void*)page->pd; - ptr64 = ((void*)page->pd) + 4; + ptr32 = (void*)page->pd; + ptr64 = ((void*)page->pd) + 4; #elif defined(__x86_64__) - ptr32 = ((void*)page->pd) - 4; - ptr64 = (void*)page->pd; + ptr32 = ((void*)page->pd) - 4; + ptr64 = (void*)page->pd; #endif - if (ptr32) { - if (ptr32[1] == 0) { - mode = 32; - pd = ptr32; - } else { - mode = 64; - pd = ptr64; - } - } + if (ptr32) { + if (ptr32[1] == 0) { + mode = 32; + pd = ptr32; + } else { + mode = 64; + pd = ptr64; + } + } #if defined(__x86_64__) } else if (strcmp(protocol, XEN_IO_PROTO_ABI_X86_32) == 0) { - /* 64bit dom0, 32bit domU */ - mode = 32; - pd = ((void*)page->pd) - 4; + /* 64bit dom0, 32bit domU */ + mode = 32; + pd = ((void*)page->pd) - 4; #elif defined(__i386__) } else if (strcmp(protocol, XEN_IO_PROTO_ABI_X86_64) == 0) { - /* 32bit dom0, 64bit domU */ - mode = 64; - pd = ((void*)page->pd) + 4; + /* 32bit dom0, 64bit domU */ + mode = 64; + pd = ((void*)page->pd) + 4; #endif } @@ -503,14 +503,14 @@ static int xenfb_map_fb(struct XenFB *xenfb) map = xenforeignmemory_map(xen_fmem, xenfb->c.xendev.dom, PROT_READ, n_fbdirs, pgmfns, NULL); if (map == NULL) - goto out; + goto out; xenfb_copy_mfns(mode, xenfb->fbpages, fbmfns, map); xenforeignmemory_unmap(xen_fmem, map, n_fbdirs); xenfb->pixels = xenforeignmemory_map(xen_fmem, xenfb->c.xendev.dom, PROT_READ, xenfb->fbpages, fbmfns, NULL); if (xenfb->pixels == NULL) - goto out; + goto out; ret = 0; /* all is fine */ @@ -589,35 +589,35 @@ static int xenfb_configure_fb(struct XenFB *xenfb, size_t fb_len_lim, /* A convenient function for munging pixels between different depths */ #define BLT(SRC_T,DST_T,RSB,GSB,BSB,RDB,GDB,BDB) \ - for (line = y ; line < (y+h) ; line++) { \ - SRC_T *src = (SRC_T *)(xenfb->pixels \ - + xenfb->offset \ - + (line * xenfb->row_stride) \ - + (x * xenfb->depth / 8)); \ - DST_T *dst = (DST_T *)(data \ - + (line * linesize) \ - + (x * bpp / 8)); \ - int col; \ - const int RSS = 32 - (RSB + GSB + BSB); \ - const int GSS = 32 - (GSB + BSB); \ - const int BSS = 32 - (BSB); \ - const uint32_t RSM = (~0U) << (32 - RSB); \ - const uint32_t GSM = (~0U) << (32 - GSB); \ - const uint32_t BSM = (~0U) << (32 - BSB); \ - const int RDS = 32 - (RDB + GDB + BDB); \ - const int GDS = 32 - (GDB + BDB); \ - const int BDS = 32 - (BDB); \ - const uint32_t RDM = (~0U) << (32 - RDB); \ - const uint32_t GDM = (~0U) << (32 - GDB); \ - const uint32_t BDM = (~0U) << (32 - BDB); \ - for (col = x ; col < (x+w) ; col++) { \ - uint32_t spix = *src; \ - *dst = (((spix << RSS) & RSM & RDM) >> RDS) | \ - (((spix << GSS) & GSM & GDM) >> GDS) | \ - (((spix << BSS) & BSM & BDM) >> BDS); \ - src = (SRC_T *) ((unsigned long) src + xenfb->depth / 8); \ - dst = (DST_T *) ((unsigned long) dst + bpp / 8); \ - } \ + for (line = y ; line < (y+h) ; line++) { \ + SRC_T *src = (SRC_T *)(xenfb->pixels \ + + xenfb->offset \ + + (line * xenfb->row_stride) \ + + (x * xenfb->depth / 8)); \ + DST_T *dst = (DST_T *)(data \ + + (line * linesize) \ + + (x * bpp / 8)); \ + int col; \ + const int RSS = 32 - (RSB + GSB + BSB); \ + const int GSS = 32 - (GSB + BSB); \ + const int BSS = 32 - (BSB); \ + const uint32_t RSM = (~0U) << (32 - RSB); \ + const uint32_t GSM = (~0U) << (32 - GSB); \ + const uint32_t BSM = (~0U) << (32 - BSB); \ + const int RDS = 32 - (RDB + GDB + BDB); \ + const int GDS = 32 - (GDB + BDB); \ + const int BDS = 32 - (BDB); \ + const uint32_t RDM = (~0U) << (32 - RDB); \ + const uint32_t GDM = (~0U) << (32 - GDB); \ + const uint32_t BDM = (~0U) << (32 - BDB); \ + for (col = x ; col < (x+w) ; col++) { \ + uint32_t spix = *src; \ + *dst = (((spix << RSS) & RSM & RDM) >> RDS) | \ + (((spix << GSS) & GSM & GDM) >> GDS) | \ + (((spix << BSS) & BSM & BDM) >> BDS); \ + src = (SRC_T *) ((unsigned long) src + xenfb->depth / 8); \ + dst = (DST_T *) ((unsigned long) dst + bpp / 8); \ + } \ } @@ -657,7 +657,7 @@ static void xenfb_guest_copy(struct XenFB *xenfb, int x, int y, int w, int h) break; default: oops = 1; - } + } } if (oops) /* should not happen */ xen_pv_printf(&xenfb->c.xendev, 0, "%s: oops: convert %d -> %d bpp?\n", @@ -816,60 +816,60 @@ static void xenfb_handle_events(struct XenFB *xenfb) if (prod - out_cons > XENFB_OUT_RING_LEN) { return; } - xen_rmb(); /* ensure we see ring contents up to prod */ + xen_rmb(); /* ensure we see ring contents up to prod */ for (cons = out_cons; cons != prod; cons++) { - union xenfb_out_event *event = &XENFB_OUT_RING_REF(page, cons); + union xenfb_out_event *event = &XENFB_OUT_RING_REF(page, cons); uint8_t type = event->type; - int x, y, w, h; + int x, y, w, h; - switch (type) { - case XENFB_TYPE_UPDATE: - if (xenfb->up_count == UP_QUEUE) - xenfb->up_fullscreen = 1; - if (xenfb->up_fullscreen) - break; - x = MAX(event->update.x, 0); - y = MAX(event->update.y, 0); - w = MIN(event->update.width, xenfb->width - x); - h = MIN(event->update.height, xenfb->height - y); - if (w < 0 || h < 0) { + switch (type) { + case XENFB_TYPE_UPDATE: + if (xenfb->up_count == UP_QUEUE) + xenfb->up_fullscreen = 1; + if (xenfb->up_fullscreen) + break; + x = MAX(event->update.x, 0); + y = MAX(event->update.y, 0); + w = MIN(event->update.width, xenfb->width - x); + h = MIN(event->update.height, xenfb->height - y); + if (w < 0 || h < 0) { xen_pv_printf(&xenfb->c.xendev, 1, "bogus update ignored\n"); - break; - } - if (x != event->update.x || + break; + } + if (x != event->update.x || y != event->update.y || - w != event->update.width || - h != event->update.height) { + w != event->update.width || + h != event->update.height) { xen_pv_printf(&xenfb->c.xendev, 1, "bogus update clipped\n"); - } - if (w == xenfb->width && h > xenfb->height / 2) { - /* scroll detector: updated more than 50% of the lines, - * don't bother keeping track of the rectangles then */ - xenfb->up_fullscreen = 1; - } else { - xenfb->up_rects[xenfb->up_count].x = x; - xenfb->up_rects[xenfb->up_count].y = y; - xenfb->up_rects[xenfb->up_count].w = w; - xenfb->up_rects[xenfb->up_count].h = h; - xenfb->up_count++; - } - break; + } + if (w == xenfb->width && h > xenfb->height / 2) { + /* scroll detector: updated more than 50% of the lines, + * don't bother keeping track of the rectangles then */ + xenfb->up_fullscreen = 1; + } else { + xenfb->up_rects[xenfb->up_count].x = x; + xenfb->up_rects[xenfb->up_count].y = y; + xenfb->up_rects[xenfb->up_count].w = w; + xenfb->up_rects[xenfb->up_count].h = h; + xenfb->up_count++; + } + break; #ifdef XENFB_TYPE_RESIZE - case XENFB_TYPE_RESIZE: - if (xenfb_configure_fb(xenfb, xenfb->fb_len, - event->resize.width, - event->resize.height, - event->resize.depth, - xenfb->fb_len, - event->resize.offset, - event->resize.stride) < 0) - break; - xenfb_invalidate(xenfb); - break; + case XENFB_TYPE_RESIZE: + if (xenfb_configure_fb(xenfb, xenfb->fb_len, + event->resize.width, + event->resize.height, + event->resize.depth, + xenfb->fb_len, + event->resize.offset, + event->resize.stride) < 0) + break; + xenfb_invalidate(xenfb); + break; #endif - } + } } - xen_mb(); /* ensure we're done with ring contents */ + xen_mb(); /* ensure we're done with ring contents */ page->out_cons = cons; } @@ -889,32 +889,32 @@ static int fb_initialise(struct XenLegacyDevice *xendev) int rc; if (xenstore_read_fe_int(xendev, "videoram", &videoram) == -1) - videoram = 0; + videoram = 0; rc = common_bind(&fb->c); if (rc != 0) - return rc; + return rc; fb_page = fb->c.page; rc = xenfb_configure_fb(fb, videoram * MiB, - fb_page->width, fb_page->height, fb_page->depth, - fb_page->mem_length, 0, fb_page->line_length); + fb_page->width, fb_page->height, fb_page->depth, + fb_page->mem_length, 0, fb_page->line_length); if (rc != 0) - return rc; + return rc; rc = xenfb_map_fb(fb); if (rc != 0) - return rc; + return rc; fb->con = graphic_console_init(NULL, 0, &xenfb_ops, fb); if (xenstore_read_fe_int(xendev, "feature-update", &fb->feature_update) == -1) - fb->feature_update = 0; + fb->feature_update = 0; if (fb->feature_update) - xenstore_write_be_int(xendev, "request-update", 1); + xenstore_write_be_int(xendev, "request-update", 1); xen_pv_printf(xendev, 1, "feature-update=%d, videoram=%d\n", - fb->feature_update, videoram); + fb->feature_update, videoram); return 0; } From 6c10e08a4f131431dbb50a11912cb2a726879df3 Mon Sep 17 00:00:00 2001 From: Amarjargal Gundjalam Date: Tue, 25 Oct 2022 22:28:11 +0800 Subject: [PATCH 685/705] hw/usb: fix tab indentation The TABs should be replaced with spaces, to make sure that we have a consistent coding style with an indentation of 4 spaces everywhere. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/370 Signed-off-by: Amarjargal Gundjalam Message-Id: <6c993f57800f8fef7a910074620f6e80e077a3d1.1666707782.git.amarjargal16@gmail.com> Signed-off-by: Thomas Huth --- hw/usb/dev-hub.c | 78 +- hw/usb/dev-network.c | 286 +++---- hw/usb/dev-wacom.c | 4 +- hw/usb/hcd-musb.c | 326 ++++---- hw/usb/quirks-pl2303-ids.h | 180 ++--- include/hw/usb.h | 100 +-- include/hw/usb/dwc2-regs.h | 1506 ++++++++++++++++++------------------ 7 files changed, 1240 insertions(+), 1240 deletions(-) diff --git a/hw/usb/dev-hub.c b/hw/usb/dev-hub.c index e35813d772..a6b50dbc8d 100644 --- a/hw/usb/dev-hub.c +++ b/hw/usb/dev-hub.c @@ -54,44 +54,44 @@ struct USBHubState { #define TYPE_USB_HUB "usb-hub" OBJECT_DECLARE_SIMPLE_TYPE(USBHubState, USB_HUB) -#define ClearHubFeature (0x2000 | USB_REQ_CLEAR_FEATURE) -#define ClearPortFeature (0x2300 | USB_REQ_CLEAR_FEATURE) -#define GetHubDescriptor (0xa000 | USB_REQ_GET_DESCRIPTOR) -#define GetHubStatus (0xa000 | USB_REQ_GET_STATUS) -#define GetPortStatus (0xa300 | USB_REQ_GET_STATUS) -#define SetHubFeature (0x2000 | USB_REQ_SET_FEATURE) -#define SetPortFeature (0x2300 | USB_REQ_SET_FEATURE) +#define ClearHubFeature (0x2000 | USB_REQ_CLEAR_FEATURE) +#define ClearPortFeature (0x2300 | USB_REQ_CLEAR_FEATURE) +#define GetHubDescriptor (0xa000 | USB_REQ_GET_DESCRIPTOR) +#define GetHubStatus (0xa000 | USB_REQ_GET_STATUS) +#define GetPortStatus (0xa300 | USB_REQ_GET_STATUS) +#define SetHubFeature (0x2000 | USB_REQ_SET_FEATURE) +#define SetPortFeature (0x2300 | USB_REQ_SET_FEATURE) -#define PORT_STAT_CONNECTION 0x0001 -#define PORT_STAT_ENABLE 0x0002 -#define PORT_STAT_SUSPEND 0x0004 -#define PORT_STAT_OVERCURRENT 0x0008 -#define PORT_STAT_RESET 0x0010 -#define PORT_STAT_POWER 0x0100 -#define PORT_STAT_LOW_SPEED 0x0200 +#define PORT_STAT_CONNECTION 0x0001 +#define PORT_STAT_ENABLE 0x0002 +#define PORT_STAT_SUSPEND 0x0004 +#define PORT_STAT_OVERCURRENT 0x0008 +#define PORT_STAT_RESET 0x0010 +#define PORT_STAT_POWER 0x0100 +#define PORT_STAT_LOW_SPEED 0x0200 #define PORT_STAT_HIGH_SPEED 0x0400 #define PORT_STAT_TEST 0x0800 #define PORT_STAT_INDICATOR 0x1000 -#define PORT_STAT_C_CONNECTION 0x0001 -#define PORT_STAT_C_ENABLE 0x0002 -#define PORT_STAT_C_SUSPEND 0x0004 -#define PORT_STAT_C_OVERCURRENT 0x0008 -#define PORT_STAT_C_RESET 0x0010 +#define PORT_STAT_C_CONNECTION 0x0001 +#define PORT_STAT_C_ENABLE 0x0002 +#define PORT_STAT_C_SUSPEND 0x0004 +#define PORT_STAT_C_OVERCURRENT 0x0008 +#define PORT_STAT_C_RESET 0x0010 -#define PORT_CONNECTION 0 -#define PORT_ENABLE 1 -#define PORT_SUSPEND 2 -#define PORT_OVERCURRENT 3 -#define PORT_RESET 4 -#define PORT_POWER 8 -#define PORT_LOWSPEED 9 -#define PORT_HIGHSPEED 10 -#define PORT_C_CONNECTION 16 -#define PORT_C_ENABLE 17 -#define PORT_C_SUSPEND 18 -#define PORT_C_OVERCURRENT 19 -#define PORT_C_RESET 20 +#define PORT_CONNECTION 0 +#define PORT_ENABLE 1 +#define PORT_SUSPEND 2 +#define PORT_OVERCURRENT 3 +#define PORT_RESET 4 +#define PORT_POWER 8 +#define PORT_LOWSPEED 9 +#define PORT_HIGHSPEED 10 +#define PORT_C_CONNECTION 16 +#define PORT_C_ENABLE 17 +#define PORT_C_SUSPEND 18 +#define PORT_C_OVERCURRENT 19 +#define PORT_C_RESET 20 #define PORT_TEST 21 #define PORT_INDICATOR 22 @@ -155,13 +155,13 @@ static const USBDesc desc_hub = { static const uint8_t qemu_hub_hub_descriptor[] = { - 0x00, /* u8 bLength; patched in later */ - 0x29, /* u8 bDescriptorType; Hub-descriptor */ - 0x00, /* u8 bNbrPorts; (patched later) */ - 0x0a, /* u16 wHubCharacteristics; */ - 0x00, /* (per-port OC, no power switching) */ - 0x01, /* u8 bPwrOn2pwrGood; 2ms */ - 0x00 /* u8 bHubContrCurrent; 0 mA */ + 0x00, /* u8 bLength; patched in later */ + 0x29, /* u8 bDescriptorType; Hub-descriptor */ + 0x00, /* u8 bNbrPorts; (patched later) */ + 0x0a, /* u16 wHubCharacteristics; */ + 0x00, /* (per-port OC, no power switching) */ + 0x01, /* u8 bPwrOn2pwrGood; 2ms */ + 0x00 /* u8 bHubContrCurrent; 0 mA */ /* DeviceRemovable and PortPwrCtrlMask patched in later */ }; diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c index ac1adca543..5fff487ee5 100644 --- a/hw/usb/dev-network.c +++ b/hw/usb/dev-network.c @@ -52,7 +52,7 @@ #define RNDIS_PRODUCT_NUM 0xa4a2 /* Ethernet/RNDIS Gadget */ enum usbstring_idx { - STRING_MANUFACTURER = 1, + STRING_MANUFACTURER = 1, STRING_PRODUCT, STRING_ETHADDR, STRING_DATA, @@ -64,39 +64,39 @@ enum usbstring_idx { STRING_SERIALNUMBER, }; -#define DEV_CONFIG_VALUE 1 /* CDC or a subset */ -#define DEV_RNDIS_CONFIG_VALUE 2 /* RNDIS; optional */ +#define DEV_CONFIG_VALUE 1 /* CDC or a subset */ +#define DEV_RNDIS_CONFIG_VALUE 2 /* RNDIS; optional */ -#define USB_CDC_SUBCLASS_ACM 0x02 -#define USB_CDC_SUBCLASS_ETHERNET 0x06 +#define USB_CDC_SUBCLASS_ACM 0x02 +#define USB_CDC_SUBCLASS_ETHERNET 0x06 -#define USB_CDC_PROTO_NONE 0 -#define USB_CDC_ACM_PROTO_VENDOR 0xff +#define USB_CDC_PROTO_NONE 0 +#define USB_CDC_ACM_PROTO_VENDOR 0xff -#define USB_CDC_HEADER_TYPE 0x00 /* header_desc */ -#define USB_CDC_CALL_MANAGEMENT_TYPE 0x01 /* call_mgmt_descriptor */ -#define USB_CDC_ACM_TYPE 0x02 /* acm_descriptor */ -#define USB_CDC_UNION_TYPE 0x06 /* union_desc */ -#define USB_CDC_ETHERNET_TYPE 0x0f /* ether_desc */ +#define USB_CDC_HEADER_TYPE 0x00 /* header_desc */ +#define USB_CDC_CALL_MANAGEMENT_TYPE 0x01 /* call_mgmt_descriptor */ +#define USB_CDC_ACM_TYPE 0x02 /* acm_descriptor */ +#define USB_CDC_UNION_TYPE 0x06 /* union_desc */ +#define USB_CDC_ETHERNET_TYPE 0x0f /* ether_desc */ -#define USB_CDC_SEND_ENCAPSULATED_COMMAND 0x00 -#define USB_CDC_GET_ENCAPSULATED_RESPONSE 0x01 -#define USB_CDC_REQ_SET_LINE_CODING 0x20 -#define USB_CDC_REQ_GET_LINE_CODING 0x21 -#define USB_CDC_REQ_SET_CONTROL_LINE_STATE 0x22 -#define USB_CDC_REQ_SEND_BREAK 0x23 -#define USB_CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40 -#define USB_CDC_SET_ETHERNET_PM_PATTERN_FILTER 0x41 -#define USB_CDC_GET_ETHERNET_PM_PATTERN_FILTER 0x42 -#define USB_CDC_SET_ETHERNET_PACKET_FILTER 0x43 -#define USB_CDC_GET_ETHERNET_STATISTIC 0x44 +#define USB_CDC_SEND_ENCAPSULATED_COMMAND 0x00 +#define USB_CDC_GET_ENCAPSULATED_RESPONSE 0x01 +#define USB_CDC_REQ_SET_LINE_CODING 0x20 +#define USB_CDC_REQ_GET_LINE_CODING 0x21 +#define USB_CDC_REQ_SET_CONTROL_LINE_STATE 0x22 +#define USB_CDC_REQ_SEND_BREAK 0x23 +#define USB_CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40 +#define USB_CDC_SET_ETHERNET_PM_PATTERN_FILTER 0x41 +#define USB_CDC_GET_ETHERNET_PM_PATTERN_FILTER 0x42 +#define USB_CDC_SET_ETHERNET_PACKET_FILTER 0x43 +#define USB_CDC_GET_ETHERNET_STATISTIC 0x44 -#define USB_CDC_NETWORK_CONNECTION 0x00 +#define USB_CDC_NETWORK_CONNECTION 0x00 -#define LOG2_STATUS_INTERVAL_MSEC 5 /* 1 << 5 == 32 msec */ -#define STATUS_BYTECOUNT 16 /* 8 byte header + data */ +#define LOG2_STATUS_INTERVAL_MSEC 5 /* 1 << 5 == 32 msec */ +#define STATUS_BYTECOUNT 16 /* 8 byte header + data */ -#define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */ +#define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */ static const USBDescStrings usb_net_stringtable = { [STRING_MANUFACTURER] = "QEMU", @@ -306,57 +306,57 @@ static const USBDesc desc_net = { /* * RNDIS Definitions - in theory not specific to USB. */ -#define RNDIS_MAXIMUM_FRAME_SIZE 1518 -#define RNDIS_MAX_TOTAL_SIZE 1558 +#define RNDIS_MAXIMUM_FRAME_SIZE 1518 +#define RNDIS_MAX_TOTAL_SIZE 1558 /* Remote NDIS Versions */ -#define RNDIS_MAJOR_VERSION 1 -#define RNDIS_MINOR_VERSION 0 +#define RNDIS_MAJOR_VERSION 1 +#define RNDIS_MINOR_VERSION 0 /* Status Values */ -#define RNDIS_STATUS_SUCCESS 0x00000000U /* Success */ -#define RNDIS_STATUS_FAILURE 0xc0000001U /* Unspecified error */ -#define RNDIS_STATUS_INVALID_DATA 0xc0010015U /* Invalid data */ -#define RNDIS_STATUS_NOT_SUPPORTED 0xc00000bbU /* Unsupported request */ -#define RNDIS_STATUS_MEDIA_CONNECT 0x4001000bU /* Device connected */ -#define RNDIS_STATUS_MEDIA_DISCONNECT 0x4001000cU /* Device disconnected */ +#define RNDIS_STATUS_SUCCESS 0x00000000U /* Success */ +#define RNDIS_STATUS_FAILURE 0xc0000001U /* Unspecified error */ +#define RNDIS_STATUS_INVALID_DATA 0xc0010015U /* Invalid data */ +#define RNDIS_STATUS_NOT_SUPPORTED 0xc00000bbU /* Unsupported request */ +#define RNDIS_STATUS_MEDIA_CONNECT 0x4001000bU /* Device connected */ +#define RNDIS_STATUS_MEDIA_DISCONNECT 0x4001000cU /* Device disconnected */ /* Message Set for Connectionless (802.3) Devices */ enum { - RNDIS_PACKET_MSG = 1, - RNDIS_INITIALIZE_MSG = 2, /* Initialize device */ - RNDIS_HALT_MSG = 3, - RNDIS_QUERY_MSG = 4, - RNDIS_SET_MSG = 5, - RNDIS_RESET_MSG = 6, - RNDIS_INDICATE_STATUS_MSG = 7, - RNDIS_KEEPALIVE_MSG = 8, + RNDIS_PACKET_MSG = 1, + RNDIS_INITIALIZE_MSG = 2, /* Initialize device */ + RNDIS_HALT_MSG = 3, + RNDIS_QUERY_MSG = 4, + RNDIS_SET_MSG = 5, + RNDIS_RESET_MSG = 6, + RNDIS_INDICATE_STATUS_MSG = 7, + RNDIS_KEEPALIVE_MSG = 8, }; /* Message completion */ enum { - RNDIS_INITIALIZE_CMPLT = 0x80000002U, - RNDIS_QUERY_CMPLT = 0x80000004U, - RNDIS_SET_CMPLT = 0x80000005U, - RNDIS_RESET_CMPLT = 0x80000006U, - RNDIS_KEEPALIVE_CMPLT = 0x80000008U, + RNDIS_INITIALIZE_CMPLT = 0x80000002U, + RNDIS_QUERY_CMPLT = 0x80000004U, + RNDIS_SET_CMPLT = 0x80000005U, + RNDIS_RESET_CMPLT = 0x80000006U, + RNDIS_KEEPALIVE_CMPLT = 0x80000008U, }; /* Device Flags */ enum { - RNDIS_DF_CONNECTIONLESS = 1, - RNDIS_DF_CONNECTIONORIENTED = 2, + RNDIS_DF_CONNECTIONLESS = 1, + RNDIS_DF_CONNECTIONORIENTED = 2, }; -#define RNDIS_MEDIUM_802_3 0x00000000U +#define RNDIS_MEDIUM_802_3 0x00000000U /* from drivers/net/sk98lin/h/skgepnmi.h */ -#define OID_PNP_CAPABILITIES 0xfd010100 -#define OID_PNP_SET_POWER 0xfd010101 -#define OID_PNP_QUERY_POWER 0xfd010102 -#define OID_PNP_ADD_WAKE_UP_PATTERN 0xfd010103 -#define OID_PNP_REMOVE_WAKE_UP_PATTERN 0xfd010104 -#define OID_PNP_ENABLE_WAKE_UP 0xfd010106 +#define OID_PNP_CAPABILITIES 0xfd010100 +#define OID_PNP_SET_POWER 0xfd010101 +#define OID_PNP_QUERY_POWER 0xfd010102 +#define OID_PNP_ADD_WAKE_UP_PATTERN 0xfd010103 +#define OID_PNP_REMOVE_WAKE_UP_PATTERN 0xfd010104 +#define OID_PNP_ENABLE_WAKE_UP 0xfd010106 typedef uint32_t le32; @@ -494,88 +494,88 @@ enum rndis_state /* from ndis.h */ enum ndis_oid { /* Required Object IDs (OIDs) */ - OID_GEN_SUPPORTED_LIST = 0x00010101, - OID_GEN_HARDWARE_STATUS = 0x00010102, - OID_GEN_MEDIA_SUPPORTED = 0x00010103, - OID_GEN_MEDIA_IN_USE = 0x00010104, - OID_GEN_MAXIMUM_LOOKAHEAD = 0x00010105, - OID_GEN_MAXIMUM_FRAME_SIZE = 0x00010106, - OID_GEN_LINK_SPEED = 0x00010107, - OID_GEN_TRANSMIT_BUFFER_SPACE = 0x00010108, - OID_GEN_RECEIVE_BUFFER_SPACE = 0x00010109, - OID_GEN_TRANSMIT_BLOCK_SIZE = 0x0001010a, - OID_GEN_RECEIVE_BLOCK_SIZE = 0x0001010b, - OID_GEN_VENDOR_ID = 0x0001010c, - OID_GEN_VENDOR_DESCRIPTION = 0x0001010d, - OID_GEN_CURRENT_PACKET_FILTER = 0x0001010e, - OID_GEN_CURRENT_LOOKAHEAD = 0x0001010f, - OID_GEN_DRIVER_VERSION = 0x00010110, - OID_GEN_MAXIMUM_TOTAL_SIZE = 0x00010111, - OID_GEN_PROTOCOL_OPTIONS = 0x00010112, - OID_GEN_MAC_OPTIONS = 0x00010113, - OID_GEN_MEDIA_CONNECT_STATUS = 0x00010114, - OID_GEN_MAXIMUM_SEND_PACKETS = 0x00010115, - OID_GEN_VENDOR_DRIVER_VERSION = 0x00010116, - OID_GEN_SUPPORTED_GUIDS = 0x00010117, - OID_GEN_NETWORK_LAYER_ADDRESSES = 0x00010118, - OID_GEN_TRANSPORT_HEADER_OFFSET = 0x00010119, - OID_GEN_MACHINE_NAME = 0x0001021a, - OID_GEN_RNDIS_CONFIG_PARAMETER = 0x0001021b, - OID_GEN_VLAN_ID = 0x0001021c, + OID_GEN_SUPPORTED_LIST = 0x00010101, + OID_GEN_HARDWARE_STATUS = 0x00010102, + OID_GEN_MEDIA_SUPPORTED = 0x00010103, + OID_GEN_MEDIA_IN_USE = 0x00010104, + OID_GEN_MAXIMUM_LOOKAHEAD = 0x00010105, + OID_GEN_MAXIMUM_FRAME_SIZE = 0x00010106, + OID_GEN_LINK_SPEED = 0x00010107, + OID_GEN_TRANSMIT_BUFFER_SPACE = 0x00010108, + OID_GEN_RECEIVE_BUFFER_SPACE = 0x00010109, + OID_GEN_TRANSMIT_BLOCK_SIZE = 0x0001010a, + OID_GEN_RECEIVE_BLOCK_SIZE = 0x0001010b, + OID_GEN_VENDOR_ID = 0x0001010c, + OID_GEN_VENDOR_DESCRIPTION = 0x0001010d, + OID_GEN_CURRENT_PACKET_FILTER = 0x0001010e, + OID_GEN_CURRENT_LOOKAHEAD = 0x0001010f, + OID_GEN_DRIVER_VERSION = 0x00010110, + OID_GEN_MAXIMUM_TOTAL_SIZE = 0x00010111, + OID_GEN_PROTOCOL_OPTIONS = 0x00010112, + OID_GEN_MAC_OPTIONS = 0x00010113, + OID_GEN_MEDIA_CONNECT_STATUS = 0x00010114, + OID_GEN_MAXIMUM_SEND_PACKETS = 0x00010115, + OID_GEN_VENDOR_DRIVER_VERSION = 0x00010116, + OID_GEN_SUPPORTED_GUIDS = 0x00010117, + OID_GEN_NETWORK_LAYER_ADDRESSES = 0x00010118, + OID_GEN_TRANSPORT_HEADER_OFFSET = 0x00010119, + OID_GEN_MACHINE_NAME = 0x0001021a, + OID_GEN_RNDIS_CONFIG_PARAMETER = 0x0001021b, + OID_GEN_VLAN_ID = 0x0001021c, /* Optional OIDs */ - OID_GEN_MEDIA_CAPABILITIES = 0x00010201, - OID_GEN_PHYSICAL_MEDIUM = 0x00010202, + OID_GEN_MEDIA_CAPABILITIES = 0x00010201, + OID_GEN_PHYSICAL_MEDIUM = 0x00010202, /* Required statistics OIDs */ - OID_GEN_XMIT_OK = 0x00020101, - OID_GEN_RCV_OK = 0x00020102, - OID_GEN_XMIT_ERROR = 0x00020103, - OID_GEN_RCV_ERROR = 0x00020104, - OID_GEN_RCV_NO_BUFFER = 0x00020105, + OID_GEN_XMIT_OK = 0x00020101, + OID_GEN_RCV_OK = 0x00020102, + OID_GEN_XMIT_ERROR = 0x00020103, + OID_GEN_RCV_ERROR = 0x00020104, + OID_GEN_RCV_NO_BUFFER = 0x00020105, /* Optional statistics OIDs */ - OID_GEN_DIRECTED_BYTES_XMIT = 0x00020201, - OID_GEN_DIRECTED_FRAMES_XMIT = 0x00020202, - OID_GEN_MULTICAST_BYTES_XMIT = 0x00020203, - OID_GEN_MULTICAST_FRAMES_XMIT = 0x00020204, - OID_GEN_BROADCAST_BYTES_XMIT = 0x00020205, - OID_GEN_BROADCAST_FRAMES_XMIT = 0x00020206, - OID_GEN_DIRECTED_BYTES_RCV = 0x00020207, - OID_GEN_DIRECTED_FRAMES_RCV = 0x00020208, - OID_GEN_MULTICAST_BYTES_RCV = 0x00020209, - OID_GEN_MULTICAST_FRAMES_RCV = 0x0002020a, - OID_GEN_BROADCAST_BYTES_RCV = 0x0002020b, - OID_GEN_BROADCAST_FRAMES_RCV = 0x0002020c, - OID_GEN_RCV_CRC_ERROR = 0x0002020d, - OID_GEN_TRANSMIT_QUEUE_LENGTH = 0x0002020e, - OID_GEN_GET_TIME_CAPS = 0x0002020f, - OID_GEN_GET_NETCARD_TIME = 0x00020210, - OID_GEN_NETCARD_LOAD = 0x00020211, - OID_GEN_DEVICE_PROFILE = 0x00020212, - OID_GEN_INIT_TIME_MS = 0x00020213, - OID_GEN_RESET_COUNTS = 0x00020214, - OID_GEN_MEDIA_SENSE_COUNTS = 0x00020215, - OID_GEN_FRIENDLY_NAME = 0x00020216, - OID_GEN_MINIPORT_INFO = 0x00020217, - OID_GEN_RESET_VERIFY_PARAMETERS = 0x00020218, + OID_GEN_DIRECTED_BYTES_XMIT = 0x00020201, + OID_GEN_DIRECTED_FRAMES_XMIT = 0x00020202, + OID_GEN_MULTICAST_BYTES_XMIT = 0x00020203, + OID_GEN_MULTICAST_FRAMES_XMIT = 0x00020204, + OID_GEN_BROADCAST_BYTES_XMIT = 0x00020205, + OID_GEN_BROADCAST_FRAMES_XMIT = 0x00020206, + OID_GEN_DIRECTED_BYTES_RCV = 0x00020207, + OID_GEN_DIRECTED_FRAMES_RCV = 0x00020208, + OID_GEN_MULTICAST_BYTES_RCV = 0x00020209, + OID_GEN_MULTICAST_FRAMES_RCV = 0x0002020a, + OID_GEN_BROADCAST_BYTES_RCV = 0x0002020b, + OID_GEN_BROADCAST_FRAMES_RCV = 0x0002020c, + OID_GEN_RCV_CRC_ERROR = 0x0002020d, + OID_GEN_TRANSMIT_QUEUE_LENGTH = 0x0002020e, + OID_GEN_GET_TIME_CAPS = 0x0002020f, + OID_GEN_GET_NETCARD_TIME = 0x00020210, + OID_GEN_NETCARD_LOAD = 0x00020211, + OID_GEN_DEVICE_PROFILE = 0x00020212, + OID_GEN_INIT_TIME_MS = 0x00020213, + OID_GEN_RESET_COUNTS = 0x00020214, + OID_GEN_MEDIA_SENSE_COUNTS = 0x00020215, + OID_GEN_FRIENDLY_NAME = 0x00020216, + OID_GEN_MINIPORT_INFO = 0x00020217, + OID_GEN_RESET_VERIFY_PARAMETERS = 0x00020218, /* IEEE 802.3 (Ethernet) OIDs */ - OID_802_3_PERMANENT_ADDRESS = 0x01010101, - OID_802_3_CURRENT_ADDRESS = 0x01010102, - OID_802_3_MULTICAST_LIST = 0x01010103, - OID_802_3_MAXIMUM_LIST_SIZE = 0x01010104, - OID_802_3_MAC_OPTIONS = 0x01010105, - OID_802_3_RCV_ERROR_ALIGNMENT = 0x01020101, - OID_802_3_XMIT_ONE_COLLISION = 0x01020102, - OID_802_3_XMIT_MORE_COLLISIONS = 0x01020103, - OID_802_3_XMIT_DEFERRED = 0x01020201, - OID_802_3_XMIT_MAX_COLLISIONS = 0x01020202, - OID_802_3_RCV_OVERRUN = 0x01020203, - OID_802_3_XMIT_UNDERRUN = 0x01020204, - OID_802_3_XMIT_HEARTBEAT_FAILURE = 0x01020205, - OID_802_3_XMIT_TIMES_CRS_LOST = 0x01020206, - OID_802_3_XMIT_LATE_COLLISIONS = 0x01020207, + OID_802_3_PERMANENT_ADDRESS = 0x01010101, + OID_802_3_CURRENT_ADDRESS = 0x01010102, + OID_802_3_MULTICAST_LIST = 0x01010103, + OID_802_3_MAXIMUM_LIST_SIZE = 0x01010104, + OID_802_3_MAC_OPTIONS = 0x01010105, + OID_802_3_RCV_ERROR_ALIGNMENT = 0x01020101, + OID_802_3_XMIT_ONE_COLLISION = 0x01020102, + OID_802_3_XMIT_MORE_COLLISIONS = 0x01020103, + OID_802_3_XMIT_DEFERRED = 0x01020201, + OID_802_3_XMIT_MAX_COLLISIONS = 0x01020202, + OID_802_3_RCV_OVERRUN = 0x01020203, + OID_802_3_XMIT_UNDERRUN = 0x01020204, + OID_802_3_XMIT_HEARTBEAT_FAILURE = 0x01020205, + OID_802_3_XMIT_TIMES_CRS_LOST = 0x01020206, + OID_802_3_XMIT_LATE_COLLISIONS = 0x01020207, }; static const uint32_t oid_supported_list[] = @@ -618,13 +618,13 @@ static const uint32_t oid_supported_list[] = OID_802_3_XMIT_MORE_COLLISIONS, }; -#define NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA (1 << 0) -#define NDIS_MAC_OPTION_RECEIVE_SERIALIZED (1 << 1) -#define NDIS_MAC_OPTION_TRANSFERS_NOT_PEND (1 << 2) -#define NDIS_MAC_OPTION_NO_LOOPBACK (1 << 3) -#define NDIS_MAC_OPTION_FULL_DUPLEX (1 << 4) -#define NDIS_MAC_OPTION_EOTX_INDICATION (1 << 5) -#define NDIS_MAC_OPTION_8021P_PRIORITY (1 << 6) +#define NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA (1 << 0) +#define NDIS_MAC_OPTION_RECEIVE_SERIALIZED (1 << 1) +#define NDIS_MAC_OPTION_TRANSFERS_NOT_PEND (1 << 2) +#define NDIS_MAC_OPTION_NO_LOOPBACK (1 << 3) +#define NDIS_MAC_OPTION_FULL_DUPLEX (1 << 4) +#define NDIS_MAC_OPTION_EOTX_INDICATION (1 << 5) +#define NDIS_MAC_OPTION_8021P_PRIORITY (1 << 6) struct rndis_response { QTAILQ_ENTRY(rndis_response) entries; @@ -1375,12 +1375,12 @@ static void usb_net_realize(USBDevice *dev, Error **errp) s->rndis_state = RNDIS_UNINITIALIZED; QTAILQ_INIT(&s->rndis_resp); - s->medium = 0; /* NDIS_MEDIUM_802_3 */ + s->medium = 0; /* NDIS_MEDIUM_802_3 */ s->speed = 1000000; /* 100MBps, in 100Bps units */ - s->media_state = 0; /* NDIS_MEDIA_STATE_CONNECTED */; + s->media_state = 0; /* NDIS_MEDIA_STATE_CONNECTED */; s->filter = 0; s->vendorid = 0x1234; - s->connection = 1; /* Connected */ + s->connection = 1; /* Connected */ s->intr = usb_ep_get(dev, USB_TOKEN_IN, 1); s->bulk_in = usb_ep_get(dev, USB_TOKEN_IN, 2); diff --git a/hw/usb/dev-wacom.c b/hw/usb/dev-wacom.c index 8323650c6a..7177c17f03 100644 --- a/hw/usb/dev-wacom.c +++ b/hw/usb/dev-wacom.c @@ -36,8 +36,8 @@ #include "qom/object.h" /* Interface requests */ -#define WACOM_GET_REPORT 0x2101 -#define WACOM_SET_REPORT 0x2109 +#define WACOM_GET_REPORT 0x2101 +#define WACOM_SET_REPORT 0x2109 struct USBWacomState { USBDevice dev; diff --git a/hw/usb/hcd-musb.c b/hw/usb/hcd-musb.c index 85f5ff5bd4..6dca373cb1 100644 --- a/hw/usb/hcd-musb.c +++ b/hw/usb/hcd-musb.c @@ -28,227 +28,227 @@ #include "hw/hw.h" /* Common USB registers */ -#define MUSB_HDRC_FADDR 0x00 /* 8-bit */ -#define MUSB_HDRC_POWER 0x01 /* 8-bit */ +#define MUSB_HDRC_FADDR 0x00 /* 8-bit */ +#define MUSB_HDRC_POWER 0x01 /* 8-bit */ -#define MUSB_HDRC_INTRTX 0x02 /* 16-bit */ -#define MUSB_HDRC_INTRRX 0x04 -#define MUSB_HDRC_INTRTXE 0x06 -#define MUSB_HDRC_INTRRXE 0x08 -#define MUSB_HDRC_INTRUSB 0x0a /* 8 bit */ -#define MUSB_HDRC_INTRUSBE 0x0b /* 8 bit */ -#define MUSB_HDRC_FRAME 0x0c /* 16-bit */ -#define MUSB_HDRC_INDEX 0x0e /* 8 bit */ -#define MUSB_HDRC_TESTMODE 0x0f /* 8 bit */ +#define MUSB_HDRC_INTRTX 0x02 /* 16-bit */ +#define MUSB_HDRC_INTRRX 0x04 +#define MUSB_HDRC_INTRTXE 0x06 +#define MUSB_HDRC_INTRRXE 0x08 +#define MUSB_HDRC_INTRUSB 0x0a /* 8 bit */ +#define MUSB_HDRC_INTRUSBE 0x0b /* 8 bit */ +#define MUSB_HDRC_FRAME 0x0c /* 16-bit */ +#define MUSB_HDRC_INDEX 0x0e /* 8 bit */ +#define MUSB_HDRC_TESTMODE 0x0f /* 8 bit */ /* Per-EP registers in indexed mode */ -#define MUSB_HDRC_EP_IDX 0x10 /* 8-bit */ +#define MUSB_HDRC_EP_IDX 0x10 /* 8-bit */ /* EP FIFOs */ -#define MUSB_HDRC_FIFO 0x20 +#define MUSB_HDRC_FIFO 0x20 /* Additional Control Registers */ -#define MUSB_HDRC_DEVCTL 0x60 /* 8 bit */ +#define MUSB_HDRC_DEVCTL 0x60 /* 8 bit */ /* These are indexed */ -#define MUSB_HDRC_TXFIFOSZ 0x62 /* 8 bit (see masks) */ -#define MUSB_HDRC_RXFIFOSZ 0x63 /* 8 bit (see masks) */ -#define MUSB_HDRC_TXFIFOADDR 0x64 /* 16 bit offset shifted right 3 */ -#define MUSB_HDRC_RXFIFOADDR 0x66 /* 16 bit offset shifted right 3 */ +#define MUSB_HDRC_TXFIFOSZ 0x62 /* 8 bit (see masks) */ +#define MUSB_HDRC_RXFIFOSZ 0x63 /* 8 bit (see masks) */ +#define MUSB_HDRC_TXFIFOADDR 0x64 /* 16 bit offset shifted right 3 */ +#define MUSB_HDRC_RXFIFOADDR 0x66 /* 16 bit offset shifted right 3 */ /* Some more registers */ -#define MUSB_HDRC_VCTRL 0x68 /* 8 bit */ -#define MUSB_HDRC_HWVERS 0x6c /* 8 bit */ +#define MUSB_HDRC_VCTRL 0x68 /* 8 bit */ +#define MUSB_HDRC_HWVERS 0x6c /* 8 bit */ /* Added in HDRC 1.9(?) & MHDRC 1.4 */ /* ULPI pass-through */ -#define MUSB_HDRC_ULPI_VBUSCTL 0x70 -#define MUSB_HDRC_ULPI_REGDATA 0x74 -#define MUSB_HDRC_ULPI_REGADDR 0x75 -#define MUSB_HDRC_ULPI_REGCTL 0x76 +#define MUSB_HDRC_ULPI_VBUSCTL 0x70 +#define MUSB_HDRC_ULPI_REGDATA 0x74 +#define MUSB_HDRC_ULPI_REGADDR 0x75 +#define MUSB_HDRC_ULPI_REGCTL 0x76 /* Extended config & PHY control */ -#define MUSB_HDRC_ENDCOUNT 0x78 /* 8 bit */ -#define MUSB_HDRC_DMARAMCFG 0x79 /* 8 bit */ -#define MUSB_HDRC_PHYWAIT 0x7a /* 8 bit */ -#define MUSB_HDRC_PHYVPLEN 0x7b /* 8 bit */ -#define MUSB_HDRC_HS_EOF1 0x7c /* 8 bit, units of 546.1 us */ -#define MUSB_HDRC_FS_EOF1 0x7d /* 8 bit, units of 533.3 ns */ -#define MUSB_HDRC_LS_EOF1 0x7e /* 8 bit, units of 1.067 us */ +#define MUSB_HDRC_ENDCOUNT 0x78 /* 8 bit */ +#define MUSB_HDRC_DMARAMCFG 0x79 /* 8 bit */ +#define MUSB_HDRC_PHYWAIT 0x7a /* 8 bit */ +#define MUSB_HDRC_PHYVPLEN 0x7b /* 8 bit */ +#define MUSB_HDRC_HS_EOF1 0x7c /* 8 bit, units of 546.1 us */ +#define MUSB_HDRC_FS_EOF1 0x7d /* 8 bit, units of 533.3 ns */ +#define MUSB_HDRC_LS_EOF1 0x7e /* 8 bit, units of 1.067 us */ /* Per-EP BUSCTL registers */ -#define MUSB_HDRC_BUSCTL 0x80 +#define MUSB_HDRC_BUSCTL 0x80 /* Per-EP registers in flat mode */ -#define MUSB_HDRC_EP 0x100 +#define MUSB_HDRC_EP 0x100 /* offsets to registers in flat model */ -#define MUSB_HDRC_TXMAXP 0x00 /* 16 bit apparently */ -#define MUSB_HDRC_TXCSR 0x02 /* 16 bit apparently */ -#define MUSB_HDRC_CSR0 MUSB_HDRC_TXCSR /* re-used for EP0 */ -#define MUSB_HDRC_RXMAXP 0x04 /* 16 bit apparently */ -#define MUSB_HDRC_RXCSR 0x06 /* 16 bit apparently */ -#define MUSB_HDRC_RXCOUNT 0x08 /* 16 bit apparently */ -#define MUSB_HDRC_COUNT0 MUSB_HDRC_RXCOUNT /* re-used for EP0 */ -#define MUSB_HDRC_TXTYPE 0x0a /* 8 bit apparently */ -#define MUSB_HDRC_TYPE0 MUSB_HDRC_TXTYPE /* re-used for EP0 */ -#define MUSB_HDRC_TXINTERVAL 0x0b /* 8 bit apparently */ -#define MUSB_HDRC_NAKLIMIT0 MUSB_HDRC_TXINTERVAL /* re-used for EP0 */ -#define MUSB_HDRC_RXTYPE 0x0c /* 8 bit apparently */ -#define MUSB_HDRC_RXINTERVAL 0x0d /* 8 bit apparently */ -#define MUSB_HDRC_FIFOSIZE 0x0f /* 8 bit apparently */ -#define MUSB_HDRC_CONFIGDATA MGC_O_HDRC_FIFOSIZE /* re-used for EP0 */ +#define MUSB_HDRC_TXMAXP 0x00 /* 16 bit apparently */ +#define MUSB_HDRC_TXCSR 0x02 /* 16 bit apparently */ +#define MUSB_HDRC_CSR0 MUSB_HDRC_TXCSR /* re-used for EP0 */ +#define MUSB_HDRC_RXMAXP 0x04 /* 16 bit apparently */ +#define MUSB_HDRC_RXCSR 0x06 /* 16 bit apparently */ +#define MUSB_HDRC_RXCOUNT 0x08 /* 16 bit apparently */ +#define MUSB_HDRC_COUNT0 MUSB_HDRC_RXCOUNT /* re-used for EP0 */ +#define MUSB_HDRC_TXTYPE 0x0a /* 8 bit apparently */ +#define MUSB_HDRC_TYPE0 MUSB_HDRC_TXTYPE /* re-used for EP0 */ +#define MUSB_HDRC_TXINTERVAL 0x0b /* 8 bit apparently */ +#define MUSB_HDRC_NAKLIMIT0 MUSB_HDRC_TXINTERVAL /* re-used for EP0 */ +#define MUSB_HDRC_RXTYPE 0x0c /* 8 bit apparently */ +#define MUSB_HDRC_RXINTERVAL 0x0d /* 8 bit apparently */ +#define MUSB_HDRC_FIFOSIZE 0x0f /* 8 bit apparently */ +#define MUSB_HDRC_CONFIGDATA MGC_O_HDRC_FIFOSIZE /* re-used for EP0 */ /* "Bus control" registers */ -#define MUSB_HDRC_TXFUNCADDR 0x00 -#define MUSB_HDRC_TXHUBADDR 0x02 -#define MUSB_HDRC_TXHUBPORT 0x03 +#define MUSB_HDRC_TXFUNCADDR 0x00 +#define MUSB_HDRC_TXHUBADDR 0x02 +#define MUSB_HDRC_TXHUBPORT 0x03 -#define MUSB_HDRC_RXFUNCADDR 0x04 -#define MUSB_HDRC_RXHUBADDR 0x06 -#define MUSB_HDRC_RXHUBPORT 0x07 +#define MUSB_HDRC_RXFUNCADDR 0x04 +#define MUSB_HDRC_RXHUBADDR 0x06 +#define MUSB_HDRC_RXHUBPORT 0x07 /* * MUSBHDRC Register bit masks */ /* POWER */ -#define MGC_M_POWER_ISOUPDATE 0x80 -#define MGC_M_POWER_SOFTCONN 0x40 -#define MGC_M_POWER_HSENAB 0x20 -#define MGC_M_POWER_HSMODE 0x10 -#define MGC_M_POWER_RESET 0x08 -#define MGC_M_POWER_RESUME 0x04 -#define MGC_M_POWER_SUSPENDM 0x02 -#define MGC_M_POWER_ENSUSPEND 0x01 +#define MGC_M_POWER_ISOUPDATE 0x80 +#define MGC_M_POWER_SOFTCONN 0x40 +#define MGC_M_POWER_HSENAB 0x20 +#define MGC_M_POWER_HSMODE 0x10 +#define MGC_M_POWER_RESET 0x08 +#define MGC_M_POWER_RESUME 0x04 +#define MGC_M_POWER_SUSPENDM 0x02 +#define MGC_M_POWER_ENSUSPEND 0x01 /* INTRUSB */ -#define MGC_M_INTR_SUSPEND 0x01 -#define MGC_M_INTR_RESUME 0x02 -#define MGC_M_INTR_RESET 0x04 -#define MGC_M_INTR_BABBLE 0x04 -#define MGC_M_INTR_SOF 0x08 -#define MGC_M_INTR_CONNECT 0x10 -#define MGC_M_INTR_DISCONNECT 0x20 -#define MGC_M_INTR_SESSREQ 0x40 -#define MGC_M_INTR_VBUSERROR 0x80 /* FOR SESSION END */ -#define MGC_M_INTR_EP0 0x01 /* FOR EP0 INTERRUPT */ +#define MGC_M_INTR_SUSPEND 0x01 +#define MGC_M_INTR_RESUME 0x02 +#define MGC_M_INTR_RESET 0x04 +#define MGC_M_INTR_BABBLE 0x04 +#define MGC_M_INTR_SOF 0x08 +#define MGC_M_INTR_CONNECT 0x10 +#define MGC_M_INTR_DISCONNECT 0x20 +#define MGC_M_INTR_SESSREQ 0x40 +#define MGC_M_INTR_VBUSERROR 0x80 /* FOR SESSION END */ +#define MGC_M_INTR_EP0 0x01 /* FOR EP0 INTERRUPT */ /* DEVCTL */ -#define MGC_M_DEVCTL_BDEVICE 0x80 -#define MGC_M_DEVCTL_FSDEV 0x40 -#define MGC_M_DEVCTL_LSDEV 0x20 -#define MGC_M_DEVCTL_VBUS 0x18 -#define MGC_S_DEVCTL_VBUS 3 -#define MGC_M_DEVCTL_HM 0x04 -#define MGC_M_DEVCTL_HR 0x02 -#define MGC_M_DEVCTL_SESSION 0x01 +#define MGC_M_DEVCTL_BDEVICE 0x80 +#define MGC_M_DEVCTL_FSDEV 0x40 +#define MGC_M_DEVCTL_LSDEV 0x20 +#define MGC_M_DEVCTL_VBUS 0x18 +#define MGC_S_DEVCTL_VBUS 3 +#define MGC_M_DEVCTL_HM 0x04 +#define MGC_M_DEVCTL_HR 0x02 +#define MGC_M_DEVCTL_SESSION 0x01 /* TESTMODE */ -#define MGC_M_TEST_FORCE_HOST 0x80 -#define MGC_M_TEST_FIFO_ACCESS 0x40 -#define MGC_M_TEST_FORCE_FS 0x20 -#define MGC_M_TEST_FORCE_HS 0x10 -#define MGC_M_TEST_PACKET 0x08 -#define MGC_M_TEST_K 0x04 -#define MGC_M_TEST_J 0x02 -#define MGC_M_TEST_SE0_NAK 0x01 +#define MGC_M_TEST_FORCE_HOST 0x80 +#define MGC_M_TEST_FIFO_ACCESS 0x40 +#define MGC_M_TEST_FORCE_FS 0x20 +#define MGC_M_TEST_FORCE_HS 0x10 +#define MGC_M_TEST_PACKET 0x08 +#define MGC_M_TEST_K 0x04 +#define MGC_M_TEST_J 0x02 +#define MGC_M_TEST_SE0_NAK 0x01 /* CSR0 */ -#define MGC_M_CSR0_FLUSHFIFO 0x0100 -#define MGC_M_CSR0_TXPKTRDY 0x0002 -#define MGC_M_CSR0_RXPKTRDY 0x0001 +#define MGC_M_CSR0_FLUSHFIFO 0x0100 +#define MGC_M_CSR0_TXPKTRDY 0x0002 +#define MGC_M_CSR0_RXPKTRDY 0x0001 /* CSR0 in Peripheral mode */ -#define MGC_M_CSR0_P_SVDSETUPEND 0x0080 -#define MGC_M_CSR0_P_SVDRXPKTRDY 0x0040 -#define MGC_M_CSR0_P_SENDSTALL 0x0020 -#define MGC_M_CSR0_P_SETUPEND 0x0010 -#define MGC_M_CSR0_P_DATAEND 0x0008 -#define MGC_M_CSR0_P_SENTSTALL 0x0004 +#define MGC_M_CSR0_P_SVDSETUPEND 0x0080 +#define MGC_M_CSR0_P_SVDRXPKTRDY 0x0040 +#define MGC_M_CSR0_P_SENDSTALL 0x0020 +#define MGC_M_CSR0_P_SETUPEND 0x0010 +#define MGC_M_CSR0_P_DATAEND 0x0008 +#define MGC_M_CSR0_P_SENTSTALL 0x0004 /* CSR0 in Host mode */ -#define MGC_M_CSR0_H_NO_PING 0x0800 -#define MGC_M_CSR0_H_WR_DATATOGGLE 0x0400 /* set to allow setting: */ -#define MGC_M_CSR0_H_DATATOGGLE 0x0200 /* data toggle control */ -#define MGC_M_CSR0_H_NAKTIMEOUT 0x0080 -#define MGC_M_CSR0_H_STATUSPKT 0x0040 -#define MGC_M_CSR0_H_REQPKT 0x0020 -#define MGC_M_CSR0_H_ERROR 0x0010 -#define MGC_M_CSR0_H_SETUPPKT 0x0008 -#define MGC_M_CSR0_H_RXSTALL 0x0004 +#define MGC_M_CSR0_H_NO_PING 0x0800 +#define MGC_M_CSR0_H_WR_DATATOGGLE 0x0400 /* set to allow setting: */ +#define MGC_M_CSR0_H_DATATOGGLE 0x0200 /* data toggle control */ +#define MGC_M_CSR0_H_NAKTIMEOUT 0x0080 +#define MGC_M_CSR0_H_STATUSPKT 0x0040 +#define MGC_M_CSR0_H_REQPKT 0x0020 +#define MGC_M_CSR0_H_ERROR 0x0010 +#define MGC_M_CSR0_H_SETUPPKT 0x0008 +#define MGC_M_CSR0_H_RXSTALL 0x0004 /* CONFIGDATA */ -#define MGC_M_CONFIGDATA_MPRXE 0x80 /* auto bulk pkt combining */ -#define MGC_M_CONFIGDATA_MPTXE 0x40 /* auto bulk pkt splitting */ -#define MGC_M_CONFIGDATA_BIGENDIAN 0x20 -#define MGC_M_CONFIGDATA_HBRXE 0x10 /* HB-ISO for RX */ -#define MGC_M_CONFIGDATA_HBTXE 0x08 /* HB-ISO for TX */ -#define MGC_M_CONFIGDATA_DYNFIFO 0x04 /* dynamic FIFO sizing */ -#define MGC_M_CONFIGDATA_SOFTCONE 0x02 /* SoftConnect */ -#define MGC_M_CONFIGDATA_UTMIDW 0x01 /* Width, 0 => 8b, 1 => 16b */ +#define MGC_M_CONFIGDATA_MPRXE 0x80 /* auto bulk pkt combining */ +#define MGC_M_CONFIGDATA_MPTXE 0x40 /* auto bulk pkt splitting */ +#define MGC_M_CONFIGDATA_BIGENDIAN 0x20 +#define MGC_M_CONFIGDATA_HBRXE 0x10 /* HB-ISO for RX */ +#define MGC_M_CONFIGDATA_HBTXE 0x08 /* HB-ISO for TX */ +#define MGC_M_CONFIGDATA_DYNFIFO 0x04 /* dynamic FIFO sizing */ +#define MGC_M_CONFIGDATA_SOFTCONE 0x02 /* SoftConnect */ +#define MGC_M_CONFIGDATA_UTMIDW 0x01 /* Width, 0 => 8b, 1 => 16b */ /* TXCSR in Peripheral and Host mode */ -#define MGC_M_TXCSR_AUTOSET 0x8000 -#define MGC_M_TXCSR_ISO 0x4000 -#define MGC_M_TXCSR_MODE 0x2000 -#define MGC_M_TXCSR_DMAENAB 0x1000 -#define MGC_M_TXCSR_FRCDATATOG 0x0800 -#define MGC_M_TXCSR_DMAMODE 0x0400 -#define MGC_M_TXCSR_CLRDATATOG 0x0040 -#define MGC_M_TXCSR_FLUSHFIFO 0x0008 -#define MGC_M_TXCSR_FIFONOTEMPTY 0x0002 -#define MGC_M_TXCSR_TXPKTRDY 0x0001 +#define MGC_M_TXCSR_AUTOSET 0x8000 +#define MGC_M_TXCSR_ISO 0x4000 +#define MGC_M_TXCSR_MODE 0x2000 +#define MGC_M_TXCSR_DMAENAB 0x1000 +#define MGC_M_TXCSR_FRCDATATOG 0x0800 +#define MGC_M_TXCSR_DMAMODE 0x0400 +#define MGC_M_TXCSR_CLRDATATOG 0x0040 +#define MGC_M_TXCSR_FLUSHFIFO 0x0008 +#define MGC_M_TXCSR_FIFONOTEMPTY 0x0002 +#define MGC_M_TXCSR_TXPKTRDY 0x0001 /* TXCSR in Peripheral mode */ -#define MGC_M_TXCSR_P_INCOMPTX 0x0080 -#define MGC_M_TXCSR_P_SENTSTALL 0x0020 -#define MGC_M_TXCSR_P_SENDSTALL 0x0010 -#define MGC_M_TXCSR_P_UNDERRUN 0x0004 +#define MGC_M_TXCSR_P_INCOMPTX 0x0080 +#define MGC_M_TXCSR_P_SENTSTALL 0x0020 +#define MGC_M_TXCSR_P_SENDSTALL 0x0010 +#define MGC_M_TXCSR_P_UNDERRUN 0x0004 /* TXCSR in Host mode */ -#define MGC_M_TXCSR_H_WR_DATATOGGLE 0x0200 -#define MGC_M_TXCSR_H_DATATOGGLE 0x0100 -#define MGC_M_TXCSR_H_NAKTIMEOUT 0x0080 -#define MGC_M_TXCSR_H_RXSTALL 0x0020 -#define MGC_M_TXCSR_H_ERROR 0x0004 +#define MGC_M_TXCSR_H_WR_DATATOGGLE 0x0200 +#define MGC_M_TXCSR_H_DATATOGGLE 0x0100 +#define MGC_M_TXCSR_H_NAKTIMEOUT 0x0080 +#define MGC_M_TXCSR_H_RXSTALL 0x0020 +#define MGC_M_TXCSR_H_ERROR 0x0004 /* RXCSR in Peripheral and Host mode */ -#define MGC_M_RXCSR_AUTOCLEAR 0x8000 -#define MGC_M_RXCSR_DMAENAB 0x2000 -#define MGC_M_RXCSR_DISNYET 0x1000 -#define MGC_M_RXCSR_DMAMODE 0x0800 -#define MGC_M_RXCSR_INCOMPRX 0x0100 -#define MGC_M_RXCSR_CLRDATATOG 0x0080 -#define MGC_M_RXCSR_FLUSHFIFO 0x0010 -#define MGC_M_RXCSR_DATAERROR 0x0008 -#define MGC_M_RXCSR_FIFOFULL 0x0002 -#define MGC_M_RXCSR_RXPKTRDY 0x0001 +#define MGC_M_RXCSR_AUTOCLEAR 0x8000 +#define MGC_M_RXCSR_DMAENAB 0x2000 +#define MGC_M_RXCSR_DISNYET 0x1000 +#define MGC_M_RXCSR_DMAMODE 0x0800 +#define MGC_M_RXCSR_INCOMPRX 0x0100 +#define MGC_M_RXCSR_CLRDATATOG 0x0080 +#define MGC_M_RXCSR_FLUSHFIFO 0x0010 +#define MGC_M_RXCSR_DATAERROR 0x0008 +#define MGC_M_RXCSR_FIFOFULL 0x0002 +#define MGC_M_RXCSR_RXPKTRDY 0x0001 /* RXCSR in Peripheral mode */ -#define MGC_M_RXCSR_P_ISO 0x4000 -#define MGC_M_RXCSR_P_SENTSTALL 0x0040 -#define MGC_M_RXCSR_P_SENDSTALL 0x0020 -#define MGC_M_RXCSR_P_OVERRUN 0x0004 +#define MGC_M_RXCSR_P_ISO 0x4000 +#define MGC_M_RXCSR_P_SENTSTALL 0x0040 +#define MGC_M_RXCSR_P_SENDSTALL 0x0020 +#define MGC_M_RXCSR_P_OVERRUN 0x0004 /* RXCSR in Host mode */ -#define MGC_M_RXCSR_H_AUTOREQ 0x4000 -#define MGC_M_RXCSR_H_WR_DATATOGGLE 0x0400 -#define MGC_M_RXCSR_H_DATATOGGLE 0x0200 -#define MGC_M_RXCSR_H_RXSTALL 0x0040 -#define MGC_M_RXCSR_H_REQPKT 0x0020 -#define MGC_M_RXCSR_H_ERROR 0x0004 +#define MGC_M_RXCSR_H_AUTOREQ 0x4000 +#define MGC_M_RXCSR_H_WR_DATATOGGLE 0x0400 +#define MGC_M_RXCSR_H_DATATOGGLE 0x0200 +#define MGC_M_RXCSR_H_RXSTALL 0x0040 +#define MGC_M_RXCSR_H_REQPKT 0x0020 +#define MGC_M_RXCSR_H_ERROR 0x0004 /* HUBADDR */ -#define MGC_M_HUBADDR_MULTI_TT 0x80 +#define MGC_M_HUBADDR_MULTI_TT 0x80 /* ULPI: Added in HDRC 1.9(?) & MHDRC 1.4 */ -#define MGC_M_ULPI_VBCTL_USEEXTVBUSIND 0x02 -#define MGC_M_ULPI_VBCTL_USEEXTVBUS 0x01 -#define MGC_M_ULPI_REGCTL_INT_ENABLE 0x08 -#define MGC_M_ULPI_REGCTL_READNOTWRITE 0x04 -#define MGC_M_ULPI_REGCTL_COMPLETE 0x02 -#define MGC_M_ULPI_REGCTL_REG 0x01 +#define MGC_M_ULPI_VBCTL_USEEXTVBUSIND 0x02 +#define MGC_M_ULPI_VBCTL_USEEXTVBUS 0x01 +#define MGC_M_ULPI_REGCTL_INT_ENABLE 0x08 +#define MGC_M_ULPI_REGCTL_READNOTWRITE 0x04 +#define MGC_M_ULPI_REGCTL_COMPLETE 0x02 +#define MGC_M_ULPI_REGCTL_REG 0x01 /* #define MUSB_DEBUG */ @@ -296,7 +296,7 @@ struct MUSBEndPoint { uint8_t interval[2]; uint8_t config; uint8_t fifosize; - int timeout[2]; /* Always in microframes */ + int timeout[2]; /* Always in microframes */ uint8_t *buf[2]; int fifolen[2]; @@ -542,7 +542,7 @@ static void musb_cb_tick1(void *opaque) ep->delayed_cb[1](&ep->packey[1].p, opaque); } -#define musb_cb_tick (dir ? musb_cb_tick1 : musb_cb_tick0) +#define musb_cb_tick (dir ? musb_cb_tick1 : musb_cb_tick0) static void musb_schedule_cb(USBPort *port, USBPacket *packey) { @@ -1323,7 +1323,7 @@ static void musb_writeb(void *opaque, hwaddr addr, uint32_t value) /* Negotiate high-speed operation if MGC_M_POWER_HSENAB is set. */ if ((value & MGC_M_POWER_HSENAB) && s->port.dev->speed == USB_SPEED_HIGH) - s->power |= MGC_M_POWER_HSMODE; /* Success */ + s->power |= MGC_M_POWER_HSMODE; /* Success */ /* Restart frame counting. */ } if (value & MGC_M_POWER_SUSPENDM) { diff --git a/hw/usb/quirks-pl2303-ids.h b/hw/usb/quirks-pl2303-ids.h index 8dbdb46ffe..28dd8da61c 100644 --- a/hw/usb/quirks-pl2303-ids.h +++ b/hw/usb/quirks-pl2303-ids.h @@ -1,150 +1,150 @@ /* * Prolific PL2303 USB to serial adaptor driver header file * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * */ -#define BENQ_VENDOR_ID 0x04a5 -#define BENQ_PRODUCT_ID_S81 0x4027 +#define BENQ_VENDOR_ID 0x04a5 +#define BENQ_PRODUCT_ID_S81 0x4027 -#define PL2303_VENDOR_ID 0x067b -#define PL2303_PRODUCT_ID 0x2303 -#define PL2303_PRODUCT_ID_RSAQ2 0x04bb -#define PL2303_PRODUCT_ID_DCU11 0x1234 -#define PL2303_PRODUCT_ID_PHAROS 0xaaa0 -#define PL2303_PRODUCT_ID_RSAQ3 0xaaa2 -#define PL2303_PRODUCT_ID_ALDIGA 0x0611 -#define PL2303_PRODUCT_ID_MMX 0x0612 -#define PL2303_PRODUCT_ID_GPRS 0x0609 -#define PL2303_PRODUCT_ID_HCR331 0x331a -#define PL2303_PRODUCT_ID_MOTOROLA 0x0307 +#define PL2303_VENDOR_ID 0x067b +#define PL2303_PRODUCT_ID 0x2303 +#define PL2303_PRODUCT_ID_RSAQ2 0x04bb +#define PL2303_PRODUCT_ID_DCU11 0x1234 +#define PL2303_PRODUCT_ID_PHAROS 0xaaa0 +#define PL2303_PRODUCT_ID_RSAQ3 0xaaa2 +#define PL2303_PRODUCT_ID_ALDIGA 0x0611 +#define PL2303_PRODUCT_ID_MMX 0x0612 +#define PL2303_PRODUCT_ID_GPRS 0x0609 +#define PL2303_PRODUCT_ID_HCR331 0x331a +#define PL2303_PRODUCT_ID_MOTOROLA 0x0307 -#define ATEN_VENDOR_ID 0x0557 -#define ATEN_VENDOR_ID2 0x0547 -#define ATEN_PRODUCT_ID 0x2008 +#define ATEN_VENDOR_ID 0x0557 +#define ATEN_VENDOR_ID2 0x0547 +#define ATEN_PRODUCT_ID 0x2008 -#define IODATA_VENDOR_ID 0x04bb -#define IODATA_PRODUCT_ID 0x0a03 -#define IODATA_PRODUCT_ID_RSAQ5 0x0a0e +#define IODATA_VENDOR_ID 0x04bb +#define IODATA_PRODUCT_ID 0x0a03 +#define IODATA_PRODUCT_ID_RSAQ5 0x0a0e -#define ELCOM_VENDOR_ID 0x056e -#define ELCOM_PRODUCT_ID 0x5003 -#define ELCOM_PRODUCT_ID_UCSGT 0x5004 +#define ELCOM_VENDOR_ID 0x056e +#define ELCOM_PRODUCT_ID 0x5003 +#define ELCOM_PRODUCT_ID_UCSGT 0x5004 -#define ITEGNO_VENDOR_ID 0x0eba -#define ITEGNO_PRODUCT_ID 0x1080 -#define ITEGNO_PRODUCT_ID_2080 0x2080 +#define ITEGNO_VENDOR_ID 0x0eba +#define ITEGNO_PRODUCT_ID 0x1080 +#define ITEGNO_PRODUCT_ID_2080 0x2080 -#define MA620_VENDOR_ID 0x0df7 -#define MA620_PRODUCT_ID 0x0620 +#define MA620_VENDOR_ID 0x0df7 +#define MA620_PRODUCT_ID 0x0620 -#define RATOC_VENDOR_ID 0x0584 -#define RATOC_PRODUCT_ID 0xb000 +#define RATOC_VENDOR_ID 0x0584 +#define RATOC_PRODUCT_ID 0xb000 -#define TRIPP_VENDOR_ID 0x2478 -#define TRIPP_PRODUCT_ID 0x2008 +#define TRIPP_VENDOR_ID 0x2478 +#define TRIPP_PRODUCT_ID 0x2008 -#define RADIOSHACK_VENDOR_ID 0x1453 -#define RADIOSHACK_PRODUCT_ID 0x4026 +#define RADIOSHACK_VENDOR_ID 0x1453 +#define RADIOSHACK_PRODUCT_ID 0x4026 -#define DCU10_VENDOR_ID 0x0731 -#define DCU10_PRODUCT_ID 0x0528 +#define DCU10_VENDOR_ID 0x0731 +#define DCU10_PRODUCT_ID 0x0528 -#define SITECOM_VENDOR_ID 0x6189 -#define SITECOM_PRODUCT_ID 0x2068 +#define SITECOM_VENDOR_ID 0x6189 +#define SITECOM_PRODUCT_ID 0x2068 /* Alcatel OT535/735 USB cable */ -#define ALCATEL_VENDOR_ID 0x11f7 -#define ALCATEL_PRODUCT_ID 0x02df +#define ALCATEL_VENDOR_ID 0x11f7 +#define ALCATEL_PRODUCT_ID 0x02df /* Samsung I330 phone cradle */ -#define SAMSUNG_VENDOR_ID 0x04e8 -#define SAMSUNG_PRODUCT_ID 0x8001 +#define SAMSUNG_VENDOR_ID 0x04e8 +#define SAMSUNG_PRODUCT_ID 0x8001 -#define SIEMENS_VENDOR_ID 0x11f5 -#define SIEMENS_PRODUCT_ID_SX1 0x0001 -#define SIEMENS_PRODUCT_ID_X65 0x0003 -#define SIEMENS_PRODUCT_ID_X75 0x0004 -#define SIEMENS_PRODUCT_ID_EF81 0x0005 +#define SIEMENS_VENDOR_ID 0x11f5 +#define SIEMENS_PRODUCT_ID_SX1 0x0001 +#define SIEMENS_PRODUCT_ID_X65 0x0003 +#define SIEMENS_PRODUCT_ID_X75 0x0004 +#define SIEMENS_PRODUCT_ID_EF81 0x0005 -#define SYNTECH_VENDOR_ID 0x0745 -#define SYNTECH_PRODUCT_ID 0x0001 +#define SYNTECH_VENDOR_ID 0x0745 +#define SYNTECH_PRODUCT_ID 0x0001 /* Nokia CA-42 Cable */ -#define NOKIA_CA42_VENDOR_ID 0x078b -#define NOKIA_CA42_PRODUCT_ID 0x1234 +#define NOKIA_CA42_VENDOR_ID 0x078b +#define NOKIA_CA42_PRODUCT_ID 0x1234 /* CA-42 CLONE Cable www.ca-42.com chipset: Prolific Technology Inc */ -#define CA_42_CA42_VENDOR_ID 0x10b5 -#define CA_42_CA42_PRODUCT_ID 0xac70 +#define CA_42_CA42_VENDOR_ID 0x10b5 +#define CA_42_CA42_PRODUCT_ID 0xac70 -#define SAGEM_VENDOR_ID 0x079b -#define SAGEM_PRODUCT_ID 0x0027 +#define SAGEM_VENDOR_ID 0x079b +#define SAGEM_PRODUCT_ID 0x0027 /* Leadtek GPS 9531 (ID 0413:2101) */ -#define LEADTEK_VENDOR_ID 0x0413 -#define LEADTEK_9531_PRODUCT_ID 0x2101 +#define LEADTEK_VENDOR_ID 0x0413 +#define LEADTEK_9531_PRODUCT_ID 0x2101 /* USB GSM cable from Speed Dragon Multimedia, Ltd */ -#define SPEEDDRAGON_VENDOR_ID 0x0e55 -#define SPEEDDRAGON_PRODUCT_ID 0x110b +#define SPEEDDRAGON_VENDOR_ID 0x0e55 +#define SPEEDDRAGON_PRODUCT_ID 0x110b /* DATAPILOT Universal-2 Phone Cable */ -#define DATAPILOT_U2_VENDOR_ID 0x0731 -#define DATAPILOT_U2_PRODUCT_ID 0x2003 +#define DATAPILOT_U2_VENDOR_ID 0x0731 +#define DATAPILOT_U2_PRODUCT_ID 0x2003 /* Belkin "F5U257" Serial Adapter */ -#define BELKIN_VENDOR_ID 0x050d -#define BELKIN_PRODUCT_ID 0x0257 +#define BELKIN_VENDOR_ID 0x050d +#define BELKIN_PRODUCT_ID 0x0257 /* Alcor Micro Corp. USB 2.0 TO RS-232 */ -#define ALCOR_VENDOR_ID 0x058F -#define ALCOR_PRODUCT_ID 0x9720 +#define ALCOR_VENDOR_ID 0x058F +#define ALCOR_PRODUCT_ID 0x9720 /* Willcom WS002IN Data Driver (by NetIndex Inc.) */ -#define WS002IN_VENDOR_ID 0x11f6 -#define WS002IN_PRODUCT_ID 0x2001 +#define WS002IN_VENDOR_ID 0x11f6 +#define WS002IN_PRODUCT_ID 0x2001 /* Corega CG-USBRS232R Serial Adapter */ -#define COREGA_VENDOR_ID 0x07aa -#define COREGA_PRODUCT_ID 0x002a +#define COREGA_VENDOR_ID 0x07aa +#define COREGA_PRODUCT_ID 0x002a /* Y.C. Cable U.S.A., Inc - USB to RS-232 */ -#define YCCABLE_VENDOR_ID 0x05ad -#define YCCABLE_PRODUCT_ID 0x0fba +#define YCCABLE_VENDOR_ID 0x05ad +#define YCCABLE_PRODUCT_ID 0x0fba /* "Superial" USB - Serial */ -#define SUPERIAL_VENDOR_ID 0x5372 -#define SUPERIAL_PRODUCT_ID 0x2303 +#define SUPERIAL_VENDOR_ID 0x5372 +#define SUPERIAL_PRODUCT_ID 0x2303 /* Hewlett-Packard LD220-HP POS Pole Display */ -#define HP_VENDOR_ID 0x03f0 -#define HP_LD220_PRODUCT_ID 0x3524 +#define HP_VENDOR_ID 0x03f0 +#define HP_LD220_PRODUCT_ID 0x3524 /* Cressi Edy (diving computer) PC interface */ -#define CRESSI_VENDOR_ID 0x04b8 -#define CRESSI_EDY_PRODUCT_ID 0x0521 +#define CRESSI_VENDOR_ID 0x04b8 +#define CRESSI_EDY_PRODUCT_ID 0x0521 /* Zeagle dive computer interface */ -#define ZEAGLE_VENDOR_ID 0x04b8 -#define ZEAGLE_N2ITION3_PRODUCT_ID 0x0522 +#define ZEAGLE_VENDOR_ID 0x04b8 +#define ZEAGLE_N2ITION3_PRODUCT_ID 0x0522 /* Sony, USB data cable for CMD-Jxx mobile phones */ -#define SONY_VENDOR_ID 0x054c -#define SONY_QN3USB_PRODUCT_ID 0x0437 +#define SONY_VENDOR_ID 0x054c +#define SONY_QN3USB_PRODUCT_ID 0x0437 /* Sanwa KB-USB2 multimeter cable (ID: 11ad:0001) */ -#define SANWA_VENDOR_ID 0x11ad -#define SANWA_PRODUCT_ID 0x0001 +#define SANWA_VENDOR_ID 0x11ad +#define SANWA_PRODUCT_ID 0x0001 /* ADLINK ND-6530 RS232,RS485 and RS422 adapter */ -#define ADLINK_VENDOR_ID 0x0b63 -#define ADLINK_ND6530_PRODUCT_ID 0x6530 +#define ADLINK_VENDOR_ID 0x0b63 +#define ADLINK_ND6530_PRODUCT_ID 0x6530 /* SMART USB Serial Adapter */ -#define SMART_VENDOR_ID 0x0b8c -#define SMART_PRODUCT_ID 0x2303 +#define SMART_VENDOR_ID 0x0b8c +#define SMART_PRODUCT_ID 0x2303 diff --git a/include/hw/usb.h b/include/hw/usb.h index 33668dd0a9..32c23a5ca2 100644 --- a/include/hw/usb.h +++ b/include/hw/usb.h @@ -66,42 +66,42 @@ //#define USB_STATE_POWERED 2 #define USB_STATE_DEFAULT 3 //#define USB_STATE_ADDRESS 4 -//#define USB_STATE_CONFIGURED 5 +//#define USB_STATE_CONFIGURED 5 #define USB_STATE_SUSPENDED 6 -#define USB_CLASS_AUDIO 1 -#define USB_CLASS_COMM 2 -#define USB_CLASS_HID 3 -#define USB_CLASS_PHYSICAL 5 -#define USB_CLASS_STILL_IMAGE 6 -#define USB_CLASS_PRINTER 7 -#define USB_CLASS_MASS_STORAGE 8 -#define USB_CLASS_HUB 9 -#define USB_CLASS_CDC_DATA 0x0a -#define USB_CLASS_CSCID 0x0b -#define USB_CLASS_CONTENT_SEC 0x0d -#define USB_CLASS_APP_SPEC 0xfe -#define USB_CLASS_VENDOR_SPEC 0xff +#define USB_CLASS_AUDIO 1 +#define USB_CLASS_COMM 2 +#define USB_CLASS_HID 3 +#define USB_CLASS_PHYSICAL 5 +#define USB_CLASS_STILL_IMAGE 6 +#define USB_CLASS_PRINTER 7 +#define USB_CLASS_MASS_STORAGE 8 +#define USB_CLASS_HUB 9 +#define USB_CLASS_CDC_DATA 0x0a +#define USB_CLASS_CSCID 0x0b +#define USB_CLASS_CONTENT_SEC 0x0d +#define USB_CLASS_APP_SPEC 0xfe +#define USB_CLASS_VENDOR_SPEC 0xff #define USB_SUBCLASS_UNDEFINED 0 #define USB_SUBCLASS_AUDIO_CONTROL 1 #define USB_SUBCLASS_AUDIO_STREAMING 2 #define USB_SUBCLASS_AUDIO_MIDISTREAMING 3 -#define USB_DIR_OUT 0 -#define USB_DIR_IN 0x80 +#define USB_DIR_OUT 0 +#define USB_DIR_IN 0x80 -#define USB_TYPE_MASK (0x03 << 5) -#define USB_TYPE_STANDARD (0x00 << 5) -#define USB_TYPE_CLASS (0x01 << 5) -#define USB_TYPE_VENDOR (0x02 << 5) -#define USB_TYPE_RESERVED (0x03 << 5) +#define USB_TYPE_MASK (0x03 << 5) +#define USB_TYPE_STANDARD (0x00 << 5) +#define USB_TYPE_CLASS (0x01 << 5) +#define USB_TYPE_VENDOR (0x02 << 5) +#define USB_TYPE_RESERVED (0x03 << 5) -#define USB_RECIP_MASK 0x1f -#define USB_RECIP_DEVICE 0x00 -#define USB_RECIP_INTERFACE 0x01 -#define USB_RECIP_ENDPOINT 0x02 -#define USB_RECIP_OTHER 0x03 +#define USB_RECIP_MASK 0x1f +#define USB_RECIP_DEVICE 0x00 +#define USB_RECIP_INTERFACE 0x01 +#define USB_RECIP_ENDPOINT 0x02 +#define USB_RECIP_OTHER 0x03 #define DeviceRequest ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8) #define DeviceOutRequest ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8) @@ -126,28 +126,28 @@ #define EndpointOutRequest \ ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8) -#define USB_REQ_GET_STATUS 0x00 -#define USB_REQ_CLEAR_FEATURE 0x01 -#define USB_REQ_SET_FEATURE 0x03 -#define USB_REQ_SET_ADDRESS 0x05 -#define USB_REQ_GET_DESCRIPTOR 0x06 -#define USB_REQ_SET_DESCRIPTOR 0x07 -#define USB_REQ_GET_CONFIGURATION 0x08 -#define USB_REQ_SET_CONFIGURATION 0x09 -#define USB_REQ_GET_INTERFACE 0x0A -#define USB_REQ_SET_INTERFACE 0x0B -#define USB_REQ_SYNCH_FRAME 0x0C +#define USB_REQ_GET_STATUS 0x00 +#define USB_REQ_CLEAR_FEATURE 0x01 +#define USB_REQ_SET_FEATURE 0x03 +#define USB_REQ_SET_ADDRESS 0x05 +#define USB_REQ_GET_DESCRIPTOR 0x06 +#define USB_REQ_SET_DESCRIPTOR 0x07 +#define USB_REQ_GET_CONFIGURATION 0x08 +#define USB_REQ_SET_CONFIGURATION 0x09 +#define USB_REQ_GET_INTERFACE 0x0A +#define USB_REQ_SET_INTERFACE 0x0B +#define USB_REQ_SYNCH_FRAME 0x0C #define USB_REQ_SET_SEL 0x30 #define USB_REQ_SET_ISOCH_DELAY 0x31 -#define USB_DEVICE_SELF_POWERED 0 -#define USB_DEVICE_REMOTE_WAKEUP 1 +#define USB_DEVICE_SELF_POWERED 0 +#define USB_DEVICE_REMOTE_WAKEUP 1 -#define USB_DT_DEVICE 0x01 -#define USB_DT_CONFIG 0x02 -#define USB_DT_STRING 0x03 -#define USB_DT_INTERFACE 0x04 -#define USB_DT_ENDPOINT 0x05 +#define USB_DT_DEVICE 0x01 +#define USB_DT_CONFIG 0x02 +#define USB_DT_STRING 0x03 +#define USB_DT_INTERFACE 0x04 +#define USB_DT_ENDPOINT 0x05 #define USB_DT_DEVICE_QUALIFIER 0x06 #define USB_DT_OTHER_SPEED_CONFIG 0x07 #define USB_DT_DEBUG 0x0A @@ -167,10 +167,10 @@ #define USB_CFG_ATT_WAKEUP (1 << 5) #define USB_CFG_ATT_BATTERY (1 << 4) -#define USB_ENDPOINT_XFER_CONTROL 0 -#define USB_ENDPOINT_XFER_ISOC 1 -#define USB_ENDPOINT_XFER_BULK 2 -#define USB_ENDPOINT_XFER_INT 3 +#define USB_ENDPOINT_XFER_CONTROL 0 +#define USB_ENDPOINT_XFER_ISOC 1 +#define USB_ENDPOINT_XFER_BULK 2 +#define USB_ENDPOINT_XFER_INT 3 #define USB_ENDPOINT_XFER_INVALID 255 #define USB_INTERFACE_INVALID 255 @@ -569,9 +569,9 @@ static inline bool usb_device_is_scsi_storage(USBDevice *dev) /* quirks.c */ /* In bulk endpoints are streaming data sources (iow behave like isoc eps) */ -#define USB_QUIRK_BUFFER_BULK_IN 0x01 +#define USB_QUIRK_BUFFER_BULK_IN 0x01 /* Bulk pkts in FTDI format, need special handling when combining packets */ -#define USB_QUIRK_IS_FTDI 0x02 +#define USB_QUIRK_IS_FTDI 0x02 int usb_get_quirks(uint16_t vendor_id, uint16_t product_id, uint8_t interface_class, uint8_t interface_subclass, diff --git a/include/hw/usb/dwc2-regs.h b/include/hw/usb/dwc2-regs.h index 4015c1d691..0bf3f2aa17 100644 --- a/include/hw/usb/dwc2-regs.h +++ b/include/hw/usb/dwc2-regs.h @@ -42,788 +42,788 @@ #ifndef DWC2_REGS_H #define DWC2_REGS_H -#define HSOTG_REG(x) (x) +#define HSOTG_REG(x) (x) -#define GOTGCTL HSOTG_REG(0x000) -#define GOTGCTL_CHIRPEN BIT(27) -#define GOTGCTL_MULT_VALID_BC_MASK (0x1f << 22) -#define GOTGCTL_MULT_VALID_BC_SHIFT 22 -#define GOTGCTL_OTGVER BIT(20) -#define GOTGCTL_BSESVLD BIT(19) -#define GOTGCTL_ASESVLD BIT(18) -#define GOTGCTL_DBNC_SHORT BIT(17) -#define GOTGCTL_CONID_B BIT(16) -#define GOTGCTL_DBNCE_FLTR_BYPASS BIT(15) -#define GOTGCTL_DEVHNPEN BIT(11) -#define GOTGCTL_HSTSETHNPEN BIT(10) -#define GOTGCTL_HNPREQ BIT(9) -#define GOTGCTL_HSTNEGSCS BIT(8) -#define GOTGCTL_SESREQ BIT(1) -#define GOTGCTL_SESREQSCS BIT(0) +#define GOTGCTL HSOTG_REG(0x000) +#define GOTGCTL_CHIRPEN BIT(27) +#define GOTGCTL_MULT_VALID_BC_MASK (0x1f << 22) +#define GOTGCTL_MULT_VALID_BC_SHIFT 22 +#define GOTGCTL_OTGVER BIT(20) +#define GOTGCTL_BSESVLD BIT(19) +#define GOTGCTL_ASESVLD BIT(18) +#define GOTGCTL_DBNC_SHORT BIT(17) +#define GOTGCTL_CONID_B BIT(16) +#define GOTGCTL_DBNCE_FLTR_BYPASS BIT(15) +#define GOTGCTL_DEVHNPEN BIT(11) +#define GOTGCTL_HSTSETHNPEN BIT(10) +#define GOTGCTL_HNPREQ BIT(9) +#define GOTGCTL_HSTNEGSCS BIT(8) +#define GOTGCTL_SESREQ BIT(1) +#define GOTGCTL_SESREQSCS BIT(0) -#define GOTGINT HSOTG_REG(0x004) -#define GOTGINT_DBNCE_DONE BIT(19) -#define GOTGINT_A_DEV_TOUT_CHG BIT(18) -#define GOTGINT_HST_NEG_DET BIT(17) -#define GOTGINT_HST_NEG_SUC_STS_CHNG BIT(9) -#define GOTGINT_SES_REQ_SUC_STS_CHNG BIT(8) -#define GOTGINT_SES_END_DET BIT(2) +#define GOTGINT HSOTG_REG(0x004) +#define GOTGINT_DBNCE_DONE BIT(19) +#define GOTGINT_A_DEV_TOUT_CHG BIT(18) +#define GOTGINT_HST_NEG_DET BIT(17) +#define GOTGINT_HST_NEG_SUC_STS_CHNG BIT(9) +#define GOTGINT_SES_REQ_SUC_STS_CHNG BIT(8) +#define GOTGINT_SES_END_DET BIT(2) -#define GAHBCFG HSOTG_REG(0x008) -#define GAHBCFG_AHB_SINGLE BIT(23) -#define GAHBCFG_NOTI_ALL_DMA_WRIT BIT(22) -#define GAHBCFG_REM_MEM_SUPP BIT(21) -#define GAHBCFG_P_TXF_EMP_LVL BIT(8) -#define GAHBCFG_NP_TXF_EMP_LVL BIT(7) -#define GAHBCFG_DMA_EN BIT(5) -#define GAHBCFG_HBSTLEN_MASK (0xf << 1) -#define GAHBCFG_HBSTLEN_SHIFT 1 -#define GAHBCFG_HBSTLEN_SINGLE 0 -#define GAHBCFG_HBSTLEN_INCR 1 -#define GAHBCFG_HBSTLEN_INCR4 3 -#define GAHBCFG_HBSTLEN_INCR8 5 -#define GAHBCFG_HBSTLEN_INCR16 7 -#define GAHBCFG_GLBL_INTR_EN BIT(0) -#define GAHBCFG_CTRL_MASK (GAHBCFG_P_TXF_EMP_LVL | \ - GAHBCFG_NP_TXF_EMP_LVL | \ - GAHBCFG_DMA_EN | \ - GAHBCFG_GLBL_INTR_EN) +#define GAHBCFG HSOTG_REG(0x008) +#define GAHBCFG_AHB_SINGLE BIT(23) +#define GAHBCFG_NOTI_ALL_DMA_WRIT BIT(22) +#define GAHBCFG_REM_MEM_SUPP BIT(21) +#define GAHBCFG_P_TXF_EMP_LVL BIT(8) +#define GAHBCFG_NP_TXF_EMP_LVL BIT(7) +#define GAHBCFG_DMA_EN BIT(5) +#define GAHBCFG_HBSTLEN_MASK (0xf << 1) +#define GAHBCFG_HBSTLEN_SHIFT 1 +#define GAHBCFG_HBSTLEN_SINGLE 0 +#define GAHBCFG_HBSTLEN_INCR 1 +#define GAHBCFG_HBSTLEN_INCR4 3 +#define GAHBCFG_HBSTLEN_INCR8 5 +#define GAHBCFG_HBSTLEN_INCR16 7 +#define GAHBCFG_GLBL_INTR_EN BIT(0) +#define GAHBCFG_CTRL_MASK (GAHBCFG_P_TXF_EMP_LVL | \ + GAHBCFG_NP_TXF_EMP_LVL | \ + GAHBCFG_DMA_EN | \ + GAHBCFG_GLBL_INTR_EN) -#define GUSBCFG HSOTG_REG(0x00C) -#define GUSBCFG_FORCEDEVMODE BIT(30) -#define GUSBCFG_FORCEHOSTMODE BIT(29) -#define GUSBCFG_TXENDDELAY BIT(28) -#define GUSBCFG_ICTRAFFICPULLREMOVE BIT(27) -#define GUSBCFG_ICUSBCAP BIT(26) -#define GUSBCFG_ULPI_INT_PROT_DIS BIT(25) -#define GUSBCFG_INDICATORPASSTHROUGH BIT(24) -#define GUSBCFG_INDICATORCOMPLEMENT BIT(23) -#define GUSBCFG_TERMSELDLPULSE BIT(22) -#define GUSBCFG_ULPI_INT_VBUS_IND BIT(21) -#define GUSBCFG_ULPI_EXT_VBUS_DRV BIT(20) -#define GUSBCFG_ULPI_CLK_SUSP_M BIT(19) -#define GUSBCFG_ULPI_AUTO_RES BIT(18) -#define GUSBCFG_ULPI_FS_LS BIT(17) -#define GUSBCFG_OTG_UTMI_FS_SEL BIT(16) -#define GUSBCFG_PHY_LP_CLK_SEL BIT(15) -#define GUSBCFG_USBTRDTIM_MASK (0xf << 10) -#define GUSBCFG_USBTRDTIM_SHIFT 10 -#define GUSBCFG_HNPCAP BIT(9) -#define GUSBCFG_SRPCAP BIT(8) -#define GUSBCFG_DDRSEL BIT(7) -#define GUSBCFG_PHYSEL BIT(6) -#define GUSBCFG_FSINTF BIT(5) -#define GUSBCFG_ULPI_UTMI_SEL BIT(4) -#define GUSBCFG_PHYIF16 BIT(3) -#define GUSBCFG_PHYIF8 (0 << 3) -#define GUSBCFG_TOUTCAL_MASK (0x7 << 0) -#define GUSBCFG_TOUTCAL_SHIFT 0 -#define GUSBCFG_TOUTCAL_LIMIT 0x7 -#define GUSBCFG_TOUTCAL(_x) ((_x) << 0) +#define GUSBCFG HSOTG_REG(0x00C) +#define GUSBCFG_FORCEDEVMODE BIT(30) +#define GUSBCFG_FORCEHOSTMODE BIT(29) +#define GUSBCFG_TXENDDELAY BIT(28) +#define GUSBCFG_ICTRAFFICPULLREMOVE BIT(27) +#define GUSBCFG_ICUSBCAP BIT(26) +#define GUSBCFG_ULPI_INT_PROT_DIS BIT(25) +#define GUSBCFG_INDICATORPASSTHROUGH BIT(24) +#define GUSBCFG_INDICATORCOMPLEMENT BIT(23) +#define GUSBCFG_TERMSELDLPULSE BIT(22) +#define GUSBCFG_ULPI_INT_VBUS_IND BIT(21) +#define GUSBCFG_ULPI_EXT_VBUS_DRV BIT(20) +#define GUSBCFG_ULPI_CLK_SUSP_M BIT(19) +#define GUSBCFG_ULPI_AUTO_RES BIT(18) +#define GUSBCFG_ULPI_FS_LS BIT(17) +#define GUSBCFG_OTG_UTMI_FS_SEL BIT(16) +#define GUSBCFG_PHY_LP_CLK_SEL BIT(15) +#define GUSBCFG_USBTRDTIM_MASK (0xf << 10) +#define GUSBCFG_USBTRDTIM_SHIFT 10 +#define GUSBCFG_HNPCAP BIT(9) +#define GUSBCFG_SRPCAP BIT(8) +#define GUSBCFG_DDRSEL BIT(7) +#define GUSBCFG_PHYSEL BIT(6) +#define GUSBCFG_FSINTF BIT(5) +#define GUSBCFG_ULPI_UTMI_SEL BIT(4) +#define GUSBCFG_PHYIF16 BIT(3) +#define GUSBCFG_PHYIF8 (0 << 3) +#define GUSBCFG_TOUTCAL_MASK (0x7 << 0) +#define GUSBCFG_TOUTCAL_SHIFT 0 +#define GUSBCFG_TOUTCAL_LIMIT 0x7 +#define GUSBCFG_TOUTCAL(_x) ((_x) << 0) -#define GRSTCTL HSOTG_REG(0x010) -#define GRSTCTL_AHBIDLE BIT(31) -#define GRSTCTL_DMAREQ BIT(30) -#define GRSTCTL_TXFNUM_MASK (0x1f << 6) -#define GRSTCTL_TXFNUM_SHIFT 6 -#define GRSTCTL_TXFNUM_LIMIT 0x1f -#define GRSTCTL_TXFNUM(_x) ((_x) << 6) -#define GRSTCTL_TXFFLSH BIT(5) -#define GRSTCTL_RXFFLSH BIT(4) -#define GRSTCTL_IN_TKNQ_FLSH BIT(3) -#define GRSTCTL_FRMCNTRRST BIT(2) -#define GRSTCTL_HSFTRST BIT(1) -#define GRSTCTL_CSFTRST BIT(0) +#define GRSTCTL HSOTG_REG(0x010) +#define GRSTCTL_AHBIDLE BIT(31) +#define GRSTCTL_DMAREQ BIT(30) +#define GRSTCTL_TXFNUM_MASK (0x1f << 6) +#define GRSTCTL_TXFNUM_SHIFT 6 +#define GRSTCTL_TXFNUM_LIMIT 0x1f +#define GRSTCTL_TXFNUM(_x) ((_x) << 6) +#define GRSTCTL_TXFFLSH BIT(5) +#define GRSTCTL_RXFFLSH BIT(4) +#define GRSTCTL_IN_TKNQ_FLSH BIT(3) +#define GRSTCTL_FRMCNTRRST BIT(2) +#define GRSTCTL_HSFTRST BIT(1) +#define GRSTCTL_CSFTRST BIT(0) -#define GINTSTS HSOTG_REG(0x014) -#define GINTMSK HSOTG_REG(0x018) -#define GINTSTS_WKUPINT BIT(31) -#define GINTSTS_SESSREQINT BIT(30) -#define GINTSTS_DISCONNINT BIT(29) -#define GINTSTS_CONIDSTSCHNG BIT(28) -#define GINTSTS_LPMTRANRCVD BIT(27) -#define GINTSTS_PTXFEMP BIT(26) -#define GINTSTS_HCHINT BIT(25) -#define GINTSTS_PRTINT BIT(24) -#define GINTSTS_RESETDET BIT(23) -#define GINTSTS_FET_SUSP BIT(22) -#define GINTSTS_INCOMPL_IP BIT(21) -#define GINTSTS_INCOMPL_SOOUT BIT(21) -#define GINTSTS_INCOMPL_SOIN BIT(20) -#define GINTSTS_OEPINT BIT(19) -#define GINTSTS_IEPINT BIT(18) -#define GINTSTS_EPMIS BIT(17) -#define GINTSTS_RESTOREDONE BIT(16) -#define GINTSTS_EOPF BIT(15) -#define GINTSTS_ISOUTDROP BIT(14) -#define GINTSTS_ENUMDONE BIT(13) -#define GINTSTS_USBRST BIT(12) -#define GINTSTS_USBSUSP BIT(11) -#define GINTSTS_ERLYSUSP BIT(10) -#define GINTSTS_I2CINT BIT(9) -#define GINTSTS_ULPI_CK_INT BIT(8) -#define GINTSTS_GOUTNAKEFF BIT(7) -#define GINTSTS_GINNAKEFF BIT(6) -#define GINTSTS_NPTXFEMP BIT(5) -#define GINTSTS_RXFLVL BIT(4) -#define GINTSTS_SOF BIT(3) -#define GINTSTS_OTGINT BIT(2) -#define GINTSTS_MODEMIS BIT(1) -#define GINTSTS_CURMODE_HOST BIT(0) +#define GINTSTS HSOTG_REG(0x014) +#define GINTMSK HSOTG_REG(0x018) +#define GINTSTS_WKUPINT BIT(31) +#define GINTSTS_SESSREQINT BIT(30) +#define GINTSTS_DISCONNINT BIT(29) +#define GINTSTS_CONIDSTSCHNG BIT(28) +#define GINTSTS_LPMTRANRCVD BIT(27) +#define GINTSTS_PTXFEMP BIT(26) +#define GINTSTS_HCHINT BIT(25) +#define GINTSTS_PRTINT BIT(24) +#define GINTSTS_RESETDET BIT(23) +#define GINTSTS_FET_SUSP BIT(22) +#define GINTSTS_INCOMPL_IP BIT(21) +#define GINTSTS_INCOMPL_SOOUT BIT(21) +#define GINTSTS_INCOMPL_SOIN BIT(20) +#define GINTSTS_OEPINT BIT(19) +#define GINTSTS_IEPINT BIT(18) +#define GINTSTS_EPMIS BIT(17) +#define GINTSTS_RESTOREDONE BIT(16) +#define GINTSTS_EOPF BIT(15) +#define GINTSTS_ISOUTDROP BIT(14) +#define GINTSTS_ENUMDONE BIT(13) +#define GINTSTS_USBRST BIT(12) +#define GINTSTS_USBSUSP BIT(11) +#define GINTSTS_ERLYSUSP BIT(10) +#define GINTSTS_I2CINT BIT(9) +#define GINTSTS_ULPI_CK_INT BIT(8) +#define GINTSTS_GOUTNAKEFF BIT(7) +#define GINTSTS_GINNAKEFF BIT(6) +#define GINTSTS_NPTXFEMP BIT(5) +#define GINTSTS_RXFLVL BIT(4) +#define GINTSTS_SOF BIT(3) +#define GINTSTS_OTGINT BIT(2) +#define GINTSTS_MODEMIS BIT(1) +#define GINTSTS_CURMODE_HOST BIT(0) -#define GRXSTSR HSOTG_REG(0x01C) -#define GRXSTSP HSOTG_REG(0x020) -#define GRXSTS_FN_MASK (0x7f << 25) -#define GRXSTS_FN_SHIFT 25 -#define GRXSTS_PKTSTS_MASK (0xf << 17) -#define GRXSTS_PKTSTS_SHIFT 17 -#define GRXSTS_PKTSTS_GLOBALOUTNAK 1 -#define GRXSTS_PKTSTS_OUTRX 2 -#define GRXSTS_PKTSTS_HCHIN 2 -#define GRXSTS_PKTSTS_OUTDONE 3 -#define GRXSTS_PKTSTS_HCHIN_XFER_COMP 3 -#define GRXSTS_PKTSTS_SETUPDONE 4 -#define GRXSTS_PKTSTS_DATATOGGLEERR 5 -#define GRXSTS_PKTSTS_SETUPRX 6 -#define GRXSTS_PKTSTS_HCHHALTED 7 -#define GRXSTS_HCHNUM_MASK (0xf << 0) -#define GRXSTS_HCHNUM_SHIFT 0 -#define GRXSTS_DPID_MASK (0x3 << 15) -#define GRXSTS_DPID_SHIFT 15 -#define GRXSTS_BYTECNT_MASK (0x7ff << 4) -#define GRXSTS_BYTECNT_SHIFT 4 -#define GRXSTS_EPNUM_MASK (0xf << 0) -#define GRXSTS_EPNUM_SHIFT 0 +#define GRXSTSR HSOTG_REG(0x01C) +#define GRXSTSP HSOTG_REG(0x020) +#define GRXSTS_FN_MASK (0x7f << 25) +#define GRXSTS_FN_SHIFT 25 +#define GRXSTS_PKTSTS_MASK (0xf << 17) +#define GRXSTS_PKTSTS_SHIFT 17 +#define GRXSTS_PKTSTS_GLOBALOUTNAK 1 +#define GRXSTS_PKTSTS_OUTRX 2 +#define GRXSTS_PKTSTS_HCHIN 2 +#define GRXSTS_PKTSTS_OUTDONE 3 +#define GRXSTS_PKTSTS_HCHIN_XFER_COMP 3 +#define GRXSTS_PKTSTS_SETUPDONE 4 +#define GRXSTS_PKTSTS_DATATOGGLEERR 5 +#define GRXSTS_PKTSTS_SETUPRX 6 +#define GRXSTS_PKTSTS_HCHHALTED 7 +#define GRXSTS_HCHNUM_MASK (0xf << 0) +#define GRXSTS_HCHNUM_SHIFT 0 +#define GRXSTS_DPID_MASK (0x3 << 15) +#define GRXSTS_DPID_SHIFT 15 +#define GRXSTS_BYTECNT_MASK (0x7ff << 4) +#define GRXSTS_BYTECNT_SHIFT 4 +#define GRXSTS_EPNUM_MASK (0xf << 0) +#define GRXSTS_EPNUM_SHIFT 0 -#define GRXFSIZ HSOTG_REG(0x024) -#define GRXFSIZ_DEPTH_MASK (0xffff << 0) -#define GRXFSIZ_DEPTH_SHIFT 0 +#define GRXFSIZ HSOTG_REG(0x024) +#define GRXFSIZ_DEPTH_MASK (0xffff << 0) +#define GRXFSIZ_DEPTH_SHIFT 0 -#define GNPTXFSIZ HSOTG_REG(0x028) +#define GNPTXFSIZ HSOTG_REG(0x028) /* Use FIFOSIZE_* constants to access this register */ -#define GNPTXSTS HSOTG_REG(0x02C) -#define GNPTXSTS_NP_TXQ_TOP_MASK (0x7f << 24) -#define GNPTXSTS_NP_TXQ_TOP_SHIFT 24 -#define GNPTXSTS_NP_TXQ_SPC_AVAIL_MASK (0xff << 16) -#define GNPTXSTS_NP_TXQ_SPC_AVAIL_SHIFT 16 -#define GNPTXSTS_NP_TXQ_SPC_AVAIL_GET(_v) (((_v) >> 16) & 0xff) -#define GNPTXSTS_NP_TXF_SPC_AVAIL_MASK (0xffff << 0) -#define GNPTXSTS_NP_TXF_SPC_AVAIL_SHIFT 0 -#define GNPTXSTS_NP_TXF_SPC_AVAIL_GET(_v) (((_v) >> 0) & 0xffff) +#define GNPTXSTS HSOTG_REG(0x02C) +#define GNPTXSTS_NP_TXQ_TOP_MASK (0x7f << 24) +#define GNPTXSTS_NP_TXQ_TOP_SHIFT 24 +#define GNPTXSTS_NP_TXQ_SPC_AVAIL_MASK (0xff << 16) +#define GNPTXSTS_NP_TXQ_SPC_AVAIL_SHIFT 16 +#define GNPTXSTS_NP_TXQ_SPC_AVAIL_GET(_v) (((_v) >> 16) & 0xff) +#define GNPTXSTS_NP_TXF_SPC_AVAIL_MASK (0xffff << 0) +#define GNPTXSTS_NP_TXF_SPC_AVAIL_SHIFT 0 +#define GNPTXSTS_NP_TXF_SPC_AVAIL_GET(_v) (((_v) >> 0) & 0xffff) -#define GI2CCTL HSOTG_REG(0x0030) -#define GI2CCTL_BSYDNE BIT(31) -#define GI2CCTL_RW BIT(30) -#define GI2CCTL_I2CDATSE0 BIT(28) -#define GI2CCTL_I2CDEVADDR_MASK (0x3 << 26) -#define GI2CCTL_I2CDEVADDR_SHIFT 26 -#define GI2CCTL_I2CSUSPCTL BIT(25) -#define GI2CCTL_ACK BIT(24) -#define GI2CCTL_I2CEN BIT(23) -#define GI2CCTL_ADDR_MASK (0x7f << 16) -#define GI2CCTL_ADDR_SHIFT 16 -#define GI2CCTL_REGADDR_MASK (0xff << 8) -#define GI2CCTL_REGADDR_SHIFT 8 -#define GI2CCTL_RWDATA_MASK (0xff << 0) -#define GI2CCTL_RWDATA_SHIFT 0 +#define GI2CCTL HSOTG_REG(0x0030) +#define GI2CCTL_BSYDNE BIT(31) +#define GI2CCTL_RW BIT(30) +#define GI2CCTL_I2CDATSE0 BIT(28) +#define GI2CCTL_I2CDEVADDR_MASK (0x3 << 26) +#define GI2CCTL_I2CDEVADDR_SHIFT 26 +#define GI2CCTL_I2CSUSPCTL BIT(25) +#define GI2CCTL_ACK BIT(24) +#define GI2CCTL_I2CEN BIT(23) +#define GI2CCTL_ADDR_MASK (0x7f << 16) +#define GI2CCTL_ADDR_SHIFT 16 +#define GI2CCTL_REGADDR_MASK (0xff << 8) +#define GI2CCTL_REGADDR_SHIFT 8 +#define GI2CCTL_RWDATA_MASK (0xff << 0) +#define GI2CCTL_RWDATA_SHIFT 0 -#define GPVNDCTL HSOTG_REG(0x0034) -#define GGPIO HSOTG_REG(0x0038) -#define GGPIO_STM32_OTG_GCCFG_PWRDWN BIT(16) +#define GPVNDCTL HSOTG_REG(0x0034) +#define GGPIO HSOTG_REG(0x0038) +#define GGPIO_STM32_OTG_GCCFG_PWRDWN BIT(16) -#define GUID HSOTG_REG(0x003c) -#define GSNPSID HSOTG_REG(0x0040) -#define GHWCFG1 HSOTG_REG(0x0044) -#define GSNPSID_ID_MASK GENMASK(31, 16) +#define GUID HSOTG_REG(0x003c) +#define GSNPSID HSOTG_REG(0x0040) +#define GHWCFG1 HSOTG_REG(0x0044) +#define GSNPSID_ID_MASK GENMASK(31, 16) -#define GHWCFG2 HSOTG_REG(0x0048) -#define GHWCFG2_OTG_ENABLE_IC_USB BIT(31) -#define GHWCFG2_DEV_TOKEN_Q_DEPTH_MASK (0x1f << 26) -#define GHWCFG2_DEV_TOKEN_Q_DEPTH_SHIFT 26 -#define GHWCFG2_HOST_PERIO_TX_Q_DEPTH_MASK (0x3 << 24) -#define GHWCFG2_HOST_PERIO_TX_Q_DEPTH_SHIFT 24 -#define GHWCFG2_NONPERIO_TX_Q_DEPTH_MASK (0x3 << 22) -#define GHWCFG2_NONPERIO_TX_Q_DEPTH_SHIFT 22 -#define GHWCFG2_MULTI_PROC_INT BIT(20) -#define GHWCFG2_DYNAMIC_FIFO BIT(19) -#define GHWCFG2_PERIO_EP_SUPPORTED BIT(18) -#define GHWCFG2_NUM_HOST_CHAN_MASK (0xf << 14) -#define GHWCFG2_NUM_HOST_CHAN_SHIFT 14 -#define GHWCFG2_NUM_DEV_EP_MASK (0xf << 10) -#define GHWCFG2_NUM_DEV_EP_SHIFT 10 -#define GHWCFG2_FS_PHY_TYPE_MASK (0x3 << 8) -#define GHWCFG2_FS_PHY_TYPE_SHIFT 8 -#define GHWCFG2_FS_PHY_TYPE_NOT_SUPPORTED 0 -#define GHWCFG2_FS_PHY_TYPE_DEDICATED 1 -#define GHWCFG2_FS_PHY_TYPE_SHARED_UTMI 2 -#define GHWCFG2_FS_PHY_TYPE_SHARED_ULPI 3 -#define GHWCFG2_HS_PHY_TYPE_MASK (0x3 << 6) -#define GHWCFG2_HS_PHY_TYPE_SHIFT 6 -#define GHWCFG2_HS_PHY_TYPE_NOT_SUPPORTED 0 -#define GHWCFG2_HS_PHY_TYPE_UTMI 1 -#define GHWCFG2_HS_PHY_TYPE_ULPI 2 -#define GHWCFG2_HS_PHY_TYPE_UTMI_ULPI 3 -#define GHWCFG2_POINT2POINT BIT(5) -#define GHWCFG2_ARCHITECTURE_MASK (0x3 << 3) -#define GHWCFG2_ARCHITECTURE_SHIFT 3 -#define GHWCFG2_SLAVE_ONLY_ARCH 0 -#define GHWCFG2_EXT_DMA_ARCH 1 -#define GHWCFG2_INT_DMA_ARCH 2 -#define GHWCFG2_OP_MODE_MASK (0x7 << 0) -#define GHWCFG2_OP_MODE_SHIFT 0 -#define GHWCFG2_OP_MODE_HNP_SRP_CAPABLE 0 -#define GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE 1 -#define GHWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE 2 -#define GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE 3 -#define GHWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE 4 -#define GHWCFG2_OP_MODE_SRP_CAPABLE_HOST 5 -#define GHWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST 6 -#define GHWCFG2_OP_MODE_UNDEFINED 7 +#define GHWCFG2 HSOTG_REG(0x0048) +#define GHWCFG2_OTG_ENABLE_IC_USB BIT(31) +#define GHWCFG2_DEV_TOKEN_Q_DEPTH_MASK (0x1f << 26) +#define GHWCFG2_DEV_TOKEN_Q_DEPTH_SHIFT 26 +#define GHWCFG2_HOST_PERIO_TX_Q_DEPTH_MASK (0x3 << 24) +#define GHWCFG2_HOST_PERIO_TX_Q_DEPTH_SHIFT 24 +#define GHWCFG2_NONPERIO_TX_Q_DEPTH_MASK (0x3 << 22) +#define GHWCFG2_NONPERIO_TX_Q_DEPTH_SHIFT 22 +#define GHWCFG2_MULTI_PROC_INT BIT(20) +#define GHWCFG2_DYNAMIC_FIFO BIT(19) +#define GHWCFG2_PERIO_EP_SUPPORTED BIT(18) +#define GHWCFG2_NUM_HOST_CHAN_MASK (0xf << 14) +#define GHWCFG2_NUM_HOST_CHAN_SHIFT 14 +#define GHWCFG2_NUM_DEV_EP_MASK (0xf << 10) +#define GHWCFG2_NUM_DEV_EP_SHIFT 10 +#define GHWCFG2_FS_PHY_TYPE_MASK (0x3 << 8) +#define GHWCFG2_FS_PHY_TYPE_SHIFT 8 +#define GHWCFG2_FS_PHY_TYPE_NOT_SUPPORTED 0 +#define GHWCFG2_FS_PHY_TYPE_DEDICATED 1 +#define GHWCFG2_FS_PHY_TYPE_SHARED_UTMI 2 +#define GHWCFG2_FS_PHY_TYPE_SHARED_ULPI 3 +#define GHWCFG2_HS_PHY_TYPE_MASK (0x3 << 6) +#define GHWCFG2_HS_PHY_TYPE_SHIFT 6 +#define GHWCFG2_HS_PHY_TYPE_NOT_SUPPORTED 0 +#define GHWCFG2_HS_PHY_TYPE_UTMI 1 +#define GHWCFG2_HS_PHY_TYPE_ULPI 2 +#define GHWCFG2_HS_PHY_TYPE_UTMI_ULPI 3 +#define GHWCFG2_POINT2POINT BIT(5) +#define GHWCFG2_ARCHITECTURE_MASK (0x3 << 3) +#define GHWCFG2_ARCHITECTURE_SHIFT 3 +#define GHWCFG2_SLAVE_ONLY_ARCH 0 +#define GHWCFG2_EXT_DMA_ARCH 1 +#define GHWCFG2_INT_DMA_ARCH 2 +#define GHWCFG2_OP_MODE_MASK (0x7 << 0) +#define GHWCFG2_OP_MODE_SHIFT 0 +#define GHWCFG2_OP_MODE_HNP_SRP_CAPABLE 0 +#define GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE 1 +#define GHWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE 2 +#define GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE 3 +#define GHWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE 4 +#define GHWCFG2_OP_MODE_SRP_CAPABLE_HOST 5 +#define GHWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST 6 +#define GHWCFG2_OP_MODE_UNDEFINED 7 -#define GHWCFG3 HSOTG_REG(0x004c) -#define GHWCFG3_DFIFO_DEPTH_MASK (0xffff << 16) -#define GHWCFG3_DFIFO_DEPTH_SHIFT 16 -#define GHWCFG3_OTG_LPM_EN BIT(15) -#define GHWCFG3_BC_SUPPORT BIT(14) -#define GHWCFG3_OTG_ENABLE_HSIC BIT(13) -#define GHWCFG3_ADP_SUPP BIT(12) -#define GHWCFG3_SYNCH_RESET_TYPE BIT(11) -#define GHWCFG3_OPTIONAL_FEATURES BIT(10) -#define GHWCFG3_VENDOR_CTRL_IF BIT(9) -#define GHWCFG3_I2C BIT(8) -#define GHWCFG3_OTG_FUNC BIT(7) -#define GHWCFG3_PACKET_SIZE_CNTR_WIDTH_MASK (0x7 << 4) -#define GHWCFG3_PACKET_SIZE_CNTR_WIDTH_SHIFT 4 -#define GHWCFG3_XFER_SIZE_CNTR_WIDTH_MASK (0xf << 0) -#define GHWCFG3_XFER_SIZE_CNTR_WIDTH_SHIFT 0 +#define GHWCFG3 HSOTG_REG(0x004c) +#define GHWCFG3_DFIFO_DEPTH_MASK (0xffff << 16) +#define GHWCFG3_DFIFO_DEPTH_SHIFT 16 +#define GHWCFG3_OTG_LPM_EN BIT(15) +#define GHWCFG3_BC_SUPPORT BIT(14) +#define GHWCFG3_OTG_ENABLE_HSIC BIT(13) +#define GHWCFG3_ADP_SUPP BIT(12) +#define GHWCFG3_SYNCH_RESET_TYPE BIT(11) +#define GHWCFG3_OPTIONAL_FEATURES BIT(10) +#define GHWCFG3_VENDOR_CTRL_IF BIT(9) +#define GHWCFG3_I2C BIT(8) +#define GHWCFG3_OTG_FUNC BIT(7) +#define GHWCFG3_PACKET_SIZE_CNTR_WIDTH_MASK (0x7 << 4) +#define GHWCFG3_PACKET_SIZE_CNTR_WIDTH_SHIFT 4 +#define GHWCFG3_XFER_SIZE_CNTR_WIDTH_MASK (0xf << 0) +#define GHWCFG3_XFER_SIZE_CNTR_WIDTH_SHIFT 0 -#define GHWCFG4 HSOTG_REG(0x0050) -#define GHWCFG4_DESC_DMA_DYN BIT(31) -#define GHWCFG4_DESC_DMA BIT(30) -#define GHWCFG4_NUM_IN_EPS_MASK (0xf << 26) -#define GHWCFG4_NUM_IN_EPS_SHIFT 26 -#define GHWCFG4_DED_FIFO_EN BIT(25) -#define GHWCFG4_DED_FIFO_SHIFT 25 -#define GHWCFG4_SESSION_END_FILT_EN BIT(24) -#define GHWCFG4_B_VALID_FILT_EN BIT(23) -#define GHWCFG4_A_VALID_FILT_EN BIT(22) -#define GHWCFG4_VBUS_VALID_FILT_EN BIT(21) -#define GHWCFG4_IDDIG_FILT_EN BIT(20) -#define GHWCFG4_NUM_DEV_MODE_CTRL_EP_MASK (0xf << 16) -#define GHWCFG4_NUM_DEV_MODE_CTRL_EP_SHIFT 16 -#define GHWCFG4_UTMI_PHY_DATA_WIDTH_MASK (0x3 << 14) -#define GHWCFG4_UTMI_PHY_DATA_WIDTH_SHIFT 14 -#define GHWCFG4_UTMI_PHY_DATA_WIDTH_8 0 -#define GHWCFG4_UTMI_PHY_DATA_WIDTH_16 1 -#define GHWCFG4_UTMI_PHY_DATA_WIDTH_8_OR_16 2 -#define GHWCFG4_ACG_SUPPORTED BIT(12) -#define GHWCFG4_IPG_ISOC_SUPPORTED BIT(11) +#define GHWCFG4 HSOTG_REG(0x0050) +#define GHWCFG4_DESC_DMA_DYN BIT(31) +#define GHWCFG4_DESC_DMA BIT(30) +#define GHWCFG4_NUM_IN_EPS_MASK (0xf << 26) +#define GHWCFG4_NUM_IN_EPS_SHIFT 26 +#define GHWCFG4_DED_FIFO_EN BIT(25) +#define GHWCFG4_DED_FIFO_SHIFT 25 +#define GHWCFG4_SESSION_END_FILT_EN BIT(24) +#define GHWCFG4_B_VALID_FILT_EN BIT(23) +#define GHWCFG4_A_VALID_FILT_EN BIT(22) +#define GHWCFG4_VBUS_VALID_FILT_EN BIT(21) +#define GHWCFG4_IDDIG_FILT_EN BIT(20) +#define GHWCFG4_NUM_DEV_MODE_CTRL_EP_MASK (0xf << 16) +#define GHWCFG4_NUM_DEV_MODE_CTRL_EP_SHIFT 16 +#define GHWCFG4_UTMI_PHY_DATA_WIDTH_MASK (0x3 << 14) +#define GHWCFG4_UTMI_PHY_DATA_WIDTH_SHIFT 14 +#define GHWCFG4_UTMI_PHY_DATA_WIDTH_8 0 +#define GHWCFG4_UTMI_PHY_DATA_WIDTH_16 1 +#define GHWCFG4_UTMI_PHY_DATA_WIDTH_8_OR_16 2 +#define GHWCFG4_ACG_SUPPORTED BIT(12) +#define GHWCFG4_IPG_ISOC_SUPPORTED BIT(11) #define GHWCFG4_SERVICE_INTERVAL_SUPPORTED BIT(10) -#define GHWCFG4_XHIBER BIT(7) -#define GHWCFG4_HIBER BIT(6) -#define GHWCFG4_MIN_AHB_FREQ BIT(5) -#define GHWCFG4_POWER_OPTIMIZ BIT(4) -#define GHWCFG4_NUM_DEV_PERIO_IN_EP_MASK (0xf << 0) -#define GHWCFG4_NUM_DEV_PERIO_IN_EP_SHIFT 0 +#define GHWCFG4_XHIBER BIT(7) +#define GHWCFG4_HIBER BIT(6) +#define GHWCFG4_MIN_AHB_FREQ BIT(5) +#define GHWCFG4_POWER_OPTIMIZ BIT(4) +#define GHWCFG4_NUM_DEV_PERIO_IN_EP_MASK (0xf << 0) +#define GHWCFG4_NUM_DEV_PERIO_IN_EP_SHIFT 0 -#define GLPMCFG HSOTG_REG(0x0054) -#define GLPMCFG_INVSELHSIC BIT(31) -#define GLPMCFG_HSICCON BIT(30) -#define GLPMCFG_RSTRSLPSTS BIT(29) -#define GLPMCFG_ENBESL BIT(28) -#define GLPMCFG_LPM_RETRYCNT_STS_MASK (0x7 << 25) -#define GLPMCFG_LPM_RETRYCNT_STS_SHIFT 25 -#define GLPMCFG_SNDLPM BIT(24) -#define GLPMCFG_RETRY_CNT_MASK (0x7 << 21) -#define GLPMCFG_RETRY_CNT_SHIFT 21 -#define GLPMCFG_LPM_REJECT_CTRL_CONTROL BIT(21) -#define GLPMCFG_LPM_ACCEPT_CTRL_ISOC BIT(22) -#define GLPMCFG_LPM_CHNL_INDX_MASK (0xf << 17) -#define GLPMCFG_LPM_CHNL_INDX_SHIFT 17 -#define GLPMCFG_L1RESUMEOK BIT(16) -#define GLPMCFG_SLPSTS BIT(15) -#define GLPMCFG_COREL1RES_MASK (0x3 << 13) -#define GLPMCFG_COREL1RES_SHIFT 13 -#define GLPMCFG_HIRD_THRES_MASK (0x1f << 8) -#define GLPMCFG_HIRD_THRES_SHIFT 8 -#define GLPMCFG_HIRD_THRES_EN (0x10 << 8) -#define GLPMCFG_ENBLSLPM BIT(7) -#define GLPMCFG_BREMOTEWAKE BIT(6) -#define GLPMCFG_HIRD_MASK (0xf << 2) -#define GLPMCFG_HIRD_SHIFT 2 -#define GLPMCFG_APPL1RES BIT(1) -#define GLPMCFG_LPMCAP BIT(0) +#define GLPMCFG HSOTG_REG(0x0054) +#define GLPMCFG_INVSELHSIC BIT(31) +#define GLPMCFG_HSICCON BIT(30) +#define GLPMCFG_RSTRSLPSTS BIT(29) +#define GLPMCFG_ENBESL BIT(28) +#define GLPMCFG_LPM_RETRYCNT_STS_MASK (0x7 << 25) +#define GLPMCFG_LPM_RETRYCNT_STS_SHIFT 25 +#define GLPMCFG_SNDLPM BIT(24) +#define GLPMCFG_RETRY_CNT_MASK (0x7 << 21) +#define GLPMCFG_RETRY_CNT_SHIFT 21 +#define GLPMCFG_LPM_REJECT_CTRL_CONTROL BIT(21) +#define GLPMCFG_LPM_ACCEPT_CTRL_ISOC BIT(22) +#define GLPMCFG_LPM_CHNL_INDX_MASK (0xf << 17) +#define GLPMCFG_LPM_CHNL_INDX_SHIFT 17 +#define GLPMCFG_L1RESUMEOK BIT(16) +#define GLPMCFG_SLPSTS BIT(15) +#define GLPMCFG_COREL1RES_MASK (0x3 << 13) +#define GLPMCFG_COREL1RES_SHIFT 13 +#define GLPMCFG_HIRD_THRES_MASK (0x1f << 8) +#define GLPMCFG_HIRD_THRES_SHIFT 8 +#define GLPMCFG_HIRD_THRES_EN (0x10 << 8) +#define GLPMCFG_ENBLSLPM BIT(7) +#define GLPMCFG_BREMOTEWAKE BIT(6) +#define GLPMCFG_HIRD_MASK (0xf << 2) +#define GLPMCFG_HIRD_SHIFT 2 +#define GLPMCFG_APPL1RES BIT(1) +#define GLPMCFG_LPMCAP BIT(0) -#define GPWRDN HSOTG_REG(0x0058) -#define GPWRDN_MULT_VAL_ID_BC_MASK (0x1f << 24) -#define GPWRDN_MULT_VAL_ID_BC_SHIFT 24 -#define GPWRDN_ADP_INT BIT(23) -#define GPWRDN_BSESSVLD BIT(22) -#define GPWRDN_IDSTS BIT(21) -#define GPWRDN_LINESTATE_MASK (0x3 << 19) -#define GPWRDN_LINESTATE_SHIFT 19 -#define GPWRDN_STS_CHGINT_MSK BIT(18) -#define GPWRDN_STS_CHGINT BIT(17) -#define GPWRDN_SRP_DET_MSK BIT(16) -#define GPWRDN_SRP_DET BIT(15) -#define GPWRDN_CONNECT_DET_MSK BIT(14) -#define GPWRDN_CONNECT_DET BIT(13) -#define GPWRDN_DISCONN_DET_MSK BIT(12) -#define GPWRDN_DISCONN_DET BIT(11) -#define GPWRDN_RST_DET_MSK BIT(10) -#define GPWRDN_RST_DET BIT(9) -#define GPWRDN_LNSTSCHG_MSK BIT(8) -#define GPWRDN_LNSTSCHG BIT(7) -#define GPWRDN_DIS_VBUS BIT(6) -#define GPWRDN_PWRDNSWTCH BIT(5) -#define GPWRDN_PWRDNRSTN BIT(4) -#define GPWRDN_PWRDNCLMP BIT(3) -#define GPWRDN_RESTORE BIT(2) -#define GPWRDN_PMUACTV BIT(1) -#define GPWRDN_PMUINTSEL BIT(0) +#define GPWRDN HSOTG_REG(0x0058) +#define GPWRDN_MULT_VAL_ID_BC_MASK (0x1f << 24) +#define GPWRDN_MULT_VAL_ID_BC_SHIFT 24 +#define GPWRDN_ADP_INT BIT(23) +#define GPWRDN_BSESSVLD BIT(22) +#define GPWRDN_IDSTS BIT(21) +#define GPWRDN_LINESTATE_MASK (0x3 << 19) +#define GPWRDN_LINESTATE_SHIFT 19 +#define GPWRDN_STS_CHGINT_MSK BIT(18) +#define GPWRDN_STS_CHGINT BIT(17) +#define GPWRDN_SRP_DET_MSK BIT(16) +#define GPWRDN_SRP_DET BIT(15) +#define GPWRDN_CONNECT_DET_MSK BIT(14) +#define GPWRDN_CONNECT_DET BIT(13) +#define GPWRDN_DISCONN_DET_MSK BIT(12) +#define GPWRDN_DISCONN_DET BIT(11) +#define GPWRDN_RST_DET_MSK BIT(10) +#define GPWRDN_RST_DET BIT(9) +#define GPWRDN_LNSTSCHG_MSK BIT(8) +#define GPWRDN_LNSTSCHG BIT(7) +#define GPWRDN_DIS_VBUS BIT(6) +#define GPWRDN_PWRDNSWTCH BIT(5) +#define GPWRDN_PWRDNRSTN BIT(4) +#define GPWRDN_PWRDNCLMP BIT(3) +#define GPWRDN_RESTORE BIT(2) +#define GPWRDN_PMUACTV BIT(1) +#define GPWRDN_PMUINTSEL BIT(0) -#define GDFIFOCFG HSOTG_REG(0x005c) -#define GDFIFOCFG_EPINFOBASE_MASK (0xffff << 16) -#define GDFIFOCFG_EPINFOBASE_SHIFT 16 -#define GDFIFOCFG_GDFIFOCFG_MASK (0xffff << 0) -#define GDFIFOCFG_GDFIFOCFG_SHIFT 0 +#define GDFIFOCFG HSOTG_REG(0x005c) +#define GDFIFOCFG_EPINFOBASE_MASK (0xffff << 16) +#define GDFIFOCFG_EPINFOBASE_SHIFT 16 +#define GDFIFOCFG_GDFIFOCFG_MASK (0xffff << 0) +#define GDFIFOCFG_GDFIFOCFG_SHIFT 0 -#define ADPCTL HSOTG_REG(0x0060) -#define ADPCTL_AR_MASK (0x3 << 27) -#define ADPCTL_AR_SHIFT 27 -#define ADPCTL_ADP_TMOUT_INT_MSK BIT(26) -#define ADPCTL_ADP_SNS_INT_MSK BIT(25) -#define ADPCTL_ADP_PRB_INT_MSK BIT(24) -#define ADPCTL_ADP_TMOUT_INT BIT(23) -#define ADPCTL_ADP_SNS_INT BIT(22) -#define ADPCTL_ADP_PRB_INT BIT(21) -#define ADPCTL_ADPENA BIT(20) -#define ADPCTL_ADPRES BIT(19) -#define ADPCTL_ENASNS BIT(18) -#define ADPCTL_ENAPRB BIT(17) -#define ADPCTL_RTIM_MASK (0x7ff << 6) -#define ADPCTL_RTIM_SHIFT 6 -#define ADPCTL_PRB_PER_MASK (0x3 << 4) -#define ADPCTL_PRB_PER_SHIFT 4 -#define ADPCTL_PRB_DELTA_MASK (0x3 << 2) -#define ADPCTL_PRB_DELTA_SHIFT 2 -#define ADPCTL_PRB_DSCHRG_MASK (0x3 << 0) -#define ADPCTL_PRB_DSCHRG_SHIFT 0 +#define ADPCTL HSOTG_REG(0x0060) +#define ADPCTL_AR_MASK (0x3 << 27) +#define ADPCTL_AR_SHIFT 27 +#define ADPCTL_ADP_TMOUT_INT_MSK BIT(26) +#define ADPCTL_ADP_SNS_INT_MSK BIT(25) +#define ADPCTL_ADP_PRB_INT_MSK BIT(24) +#define ADPCTL_ADP_TMOUT_INT BIT(23) +#define ADPCTL_ADP_SNS_INT BIT(22) +#define ADPCTL_ADP_PRB_INT BIT(21) +#define ADPCTL_ADPENA BIT(20) +#define ADPCTL_ADPRES BIT(19) +#define ADPCTL_ENASNS BIT(18) +#define ADPCTL_ENAPRB BIT(17) +#define ADPCTL_RTIM_MASK (0x7ff << 6) +#define ADPCTL_RTIM_SHIFT 6 +#define ADPCTL_PRB_PER_MASK (0x3 << 4) +#define ADPCTL_PRB_PER_SHIFT 4 +#define ADPCTL_PRB_DELTA_MASK (0x3 << 2) +#define ADPCTL_PRB_DELTA_SHIFT 2 +#define ADPCTL_PRB_DSCHRG_MASK (0x3 << 0) +#define ADPCTL_PRB_DSCHRG_SHIFT 0 -#define GREFCLK HSOTG_REG(0x0064) -#define GREFCLK_REFCLKPER_MASK (0x1ffff << 15) -#define GREFCLK_REFCLKPER_SHIFT 15 -#define GREFCLK_REF_CLK_MODE BIT(14) -#define GREFCLK_SOF_CNT_WKUP_ALERT_MASK (0x3ff) +#define GREFCLK HSOTG_REG(0x0064) +#define GREFCLK_REFCLKPER_MASK (0x1ffff << 15) +#define GREFCLK_REFCLKPER_SHIFT 15 +#define GREFCLK_REF_CLK_MODE BIT(14) +#define GREFCLK_SOF_CNT_WKUP_ALERT_MASK (0x3ff) #define GREFCLK_SOF_CNT_WKUP_ALERT_SHIFT 0 -#define GINTMSK2 HSOTG_REG(0x0068) -#define GINTMSK2_WKUP_ALERT_INT_MSK BIT(0) +#define GINTMSK2 HSOTG_REG(0x0068) +#define GINTMSK2_WKUP_ALERT_INT_MSK BIT(0) -#define GINTSTS2 HSOTG_REG(0x006c) -#define GINTSTS2_WKUP_ALERT_INT BIT(0) +#define GINTSTS2 HSOTG_REG(0x006c) +#define GINTSTS2_WKUP_ALERT_INT BIT(0) -#define HPTXFSIZ HSOTG_REG(0x100) +#define HPTXFSIZ HSOTG_REG(0x100) /* Use FIFOSIZE_* constants to access this register */ -#define DPTXFSIZN(_a) HSOTG_REG(0x104 + (((_a) - 1) * 4)) +#define DPTXFSIZN(_a) HSOTG_REG(0x104 + (((_a) - 1) * 4)) /* Use FIFOSIZE_* constants to access this register */ /* These apply to the GNPTXFSIZ, HPTXFSIZ and DPTXFSIZN registers */ -#define FIFOSIZE_DEPTH_MASK (0xffff << 16) -#define FIFOSIZE_DEPTH_SHIFT 16 -#define FIFOSIZE_STARTADDR_MASK (0xffff << 0) -#define FIFOSIZE_STARTADDR_SHIFT 0 -#define FIFOSIZE_DEPTH_GET(_x) (((_x) >> 16) & 0xffff) +#define FIFOSIZE_DEPTH_MASK (0xffff << 16) +#define FIFOSIZE_DEPTH_SHIFT 16 +#define FIFOSIZE_STARTADDR_MASK (0xffff << 0) +#define FIFOSIZE_STARTADDR_SHIFT 0 +#define FIFOSIZE_DEPTH_GET(_x) (((_x) >> 16) & 0xffff) /* Device mode registers */ -#define DCFG HSOTG_REG(0x800) -#define DCFG_DESCDMA_EN BIT(23) -#define DCFG_EPMISCNT_MASK (0x1f << 18) -#define DCFG_EPMISCNT_SHIFT 18 -#define DCFG_EPMISCNT_LIMIT 0x1f -#define DCFG_EPMISCNT(_x) ((_x) << 18) -#define DCFG_IPG_ISOC_SUPPORDED BIT(17) -#define DCFG_PERFRINT_MASK (0x3 << 11) -#define DCFG_PERFRINT_SHIFT 11 -#define DCFG_PERFRINT_LIMIT 0x3 -#define DCFG_PERFRINT(_x) ((_x) << 11) -#define DCFG_DEVADDR_MASK (0x7f << 4) -#define DCFG_DEVADDR_SHIFT 4 -#define DCFG_DEVADDR_LIMIT 0x7f -#define DCFG_DEVADDR(_x) ((_x) << 4) -#define DCFG_NZ_STS_OUT_HSHK BIT(2) -#define DCFG_DEVSPD_MASK (0x3 << 0) -#define DCFG_DEVSPD_SHIFT 0 -#define DCFG_DEVSPD_HS 0 -#define DCFG_DEVSPD_FS 1 -#define DCFG_DEVSPD_LS 2 -#define DCFG_DEVSPD_FS48 3 +#define DCFG HSOTG_REG(0x800) +#define DCFG_DESCDMA_EN BIT(23) +#define DCFG_EPMISCNT_MASK (0x1f << 18) +#define DCFG_EPMISCNT_SHIFT 18 +#define DCFG_EPMISCNT_LIMIT 0x1f +#define DCFG_EPMISCNT(_x) ((_x) << 18) +#define DCFG_IPG_ISOC_SUPPORDED BIT(17) +#define DCFG_PERFRINT_MASK (0x3 << 11) +#define DCFG_PERFRINT_SHIFT 11 +#define DCFG_PERFRINT_LIMIT 0x3 +#define DCFG_PERFRINT(_x) ((_x) << 11) +#define DCFG_DEVADDR_MASK (0x7f << 4) +#define DCFG_DEVADDR_SHIFT 4 +#define DCFG_DEVADDR_LIMIT 0x7f +#define DCFG_DEVADDR(_x) ((_x) << 4) +#define DCFG_NZ_STS_OUT_HSHK BIT(2) +#define DCFG_DEVSPD_MASK (0x3 << 0) +#define DCFG_DEVSPD_SHIFT 0 +#define DCFG_DEVSPD_HS 0 +#define DCFG_DEVSPD_FS 1 +#define DCFG_DEVSPD_LS 2 +#define DCFG_DEVSPD_FS48 3 -#define DCTL HSOTG_REG(0x804) +#define DCTL HSOTG_REG(0x804) #define DCTL_SERVICE_INTERVAL_SUPPORTED BIT(19) -#define DCTL_PWRONPRGDONE BIT(11) -#define DCTL_CGOUTNAK BIT(10) -#define DCTL_SGOUTNAK BIT(9) -#define DCTL_CGNPINNAK BIT(8) -#define DCTL_SGNPINNAK BIT(7) -#define DCTL_TSTCTL_MASK (0x7 << 4) -#define DCTL_TSTCTL_SHIFT 4 -#define DCTL_GOUTNAKSTS BIT(3) -#define DCTL_GNPINNAKSTS BIT(2) -#define DCTL_SFTDISCON BIT(1) -#define DCTL_RMTWKUPSIG BIT(0) +#define DCTL_PWRONPRGDONE BIT(11) +#define DCTL_CGOUTNAK BIT(10) +#define DCTL_SGOUTNAK BIT(9) +#define DCTL_CGNPINNAK BIT(8) +#define DCTL_SGNPINNAK BIT(7) +#define DCTL_TSTCTL_MASK (0x7 << 4) +#define DCTL_TSTCTL_SHIFT 4 +#define DCTL_GOUTNAKSTS BIT(3) +#define DCTL_GNPINNAKSTS BIT(2) +#define DCTL_SFTDISCON BIT(1) +#define DCTL_RMTWKUPSIG BIT(0) -#define DSTS HSOTG_REG(0x808) -#define DSTS_SOFFN_MASK (0x3fff << 8) -#define DSTS_SOFFN_SHIFT 8 -#define DSTS_SOFFN_LIMIT 0x3fff -#define DSTS_SOFFN(_x) ((_x) << 8) -#define DSTS_ERRATICERR BIT(3) -#define DSTS_ENUMSPD_MASK (0x3 << 1) -#define DSTS_ENUMSPD_SHIFT 1 -#define DSTS_ENUMSPD_HS 0 -#define DSTS_ENUMSPD_FS 1 -#define DSTS_ENUMSPD_LS 2 -#define DSTS_ENUMSPD_FS48 3 -#define DSTS_SUSPSTS BIT(0) +#define DSTS HSOTG_REG(0x808) +#define DSTS_SOFFN_MASK (0x3fff << 8) +#define DSTS_SOFFN_SHIFT 8 +#define DSTS_SOFFN_LIMIT 0x3fff +#define DSTS_SOFFN(_x) ((_x) << 8) +#define DSTS_ERRATICERR BIT(3) +#define DSTS_ENUMSPD_MASK (0x3 << 1) +#define DSTS_ENUMSPD_SHIFT 1 +#define DSTS_ENUMSPD_HS 0 +#define DSTS_ENUMSPD_FS 1 +#define DSTS_ENUMSPD_LS 2 +#define DSTS_ENUMSPD_FS48 3 +#define DSTS_SUSPSTS BIT(0) -#define DIEPMSK HSOTG_REG(0x810) -#define DIEPMSK_NAKMSK BIT(13) -#define DIEPMSK_BNAININTRMSK BIT(9) -#define DIEPMSK_TXFIFOUNDRNMSK BIT(8) -#define DIEPMSK_TXFIFOEMPTY BIT(7) -#define DIEPMSK_INEPNAKEFFMSK BIT(6) -#define DIEPMSK_INTKNEPMISMSK BIT(5) -#define DIEPMSK_INTKNTXFEMPMSK BIT(4) -#define DIEPMSK_TIMEOUTMSK BIT(3) -#define DIEPMSK_AHBERRMSK BIT(2) -#define DIEPMSK_EPDISBLDMSK BIT(1) -#define DIEPMSK_XFERCOMPLMSK BIT(0) +#define DIEPMSK HSOTG_REG(0x810) +#define DIEPMSK_NAKMSK BIT(13) +#define DIEPMSK_BNAININTRMSK BIT(9) +#define DIEPMSK_TXFIFOUNDRNMSK BIT(8) +#define DIEPMSK_TXFIFOEMPTY BIT(7) +#define DIEPMSK_INEPNAKEFFMSK BIT(6) +#define DIEPMSK_INTKNEPMISMSK BIT(5) +#define DIEPMSK_INTKNTXFEMPMSK BIT(4) +#define DIEPMSK_TIMEOUTMSK BIT(3) +#define DIEPMSK_AHBERRMSK BIT(2) +#define DIEPMSK_EPDISBLDMSK BIT(1) +#define DIEPMSK_XFERCOMPLMSK BIT(0) -#define DOEPMSK HSOTG_REG(0x814) -#define DOEPMSK_BNAMSK BIT(9) -#define DOEPMSK_BACK2BACKSETUP BIT(6) -#define DOEPMSK_STSPHSERCVDMSK BIT(5) -#define DOEPMSK_OUTTKNEPDISMSK BIT(4) -#define DOEPMSK_SETUPMSK BIT(3) -#define DOEPMSK_AHBERRMSK BIT(2) -#define DOEPMSK_EPDISBLDMSK BIT(1) -#define DOEPMSK_XFERCOMPLMSK BIT(0) +#define DOEPMSK HSOTG_REG(0x814) +#define DOEPMSK_BNAMSK BIT(9) +#define DOEPMSK_BACK2BACKSETUP BIT(6) +#define DOEPMSK_STSPHSERCVDMSK BIT(5) +#define DOEPMSK_OUTTKNEPDISMSK BIT(4) +#define DOEPMSK_SETUPMSK BIT(3) +#define DOEPMSK_AHBERRMSK BIT(2) +#define DOEPMSK_EPDISBLDMSK BIT(1) +#define DOEPMSK_XFERCOMPLMSK BIT(0) -#define DAINT HSOTG_REG(0x818) -#define DAINTMSK HSOTG_REG(0x81C) -#define DAINT_OUTEP_SHIFT 16 -#define DAINT_OUTEP(_x) (1 << ((_x) + 16)) -#define DAINT_INEP(_x) (1 << (_x)) +#define DAINT HSOTG_REG(0x818) +#define DAINTMSK HSOTG_REG(0x81C) +#define DAINT_OUTEP_SHIFT 16 +#define DAINT_OUTEP(_x) (1 << ((_x) + 16)) +#define DAINT_INEP(_x) (1 << (_x)) -#define DTKNQR1 HSOTG_REG(0x820) -#define DTKNQR2 HSOTG_REG(0x824) -#define DTKNQR3 HSOTG_REG(0x830) -#define DTKNQR4 HSOTG_REG(0x834) -#define DIEPEMPMSK HSOTG_REG(0x834) +#define DTKNQR1 HSOTG_REG(0x820) +#define DTKNQR2 HSOTG_REG(0x824) +#define DTKNQR3 HSOTG_REG(0x830) +#define DTKNQR4 HSOTG_REG(0x834) +#define DIEPEMPMSK HSOTG_REG(0x834) -#define DVBUSDIS HSOTG_REG(0x828) -#define DVBUSPULSE HSOTG_REG(0x82C) +#define DVBUSDIS HSOTG_REG(0x828) +#define DVBUSPULSE HSOTG_REG(0x82C) -#define DIEPCTL0 HSOTG_REG(0x900) -#define DIEPCTL(_a) HSOTG_REG(0x900 + ((_a) * 0x20)) +#define DIEPCTL0 HSOTG_REG(0x900) +#define DIEPCTL(_a) HSOTG_REG(0x900 + ((_a) * 0x20)) -#define DOEPCTL0 HSOTG_REG(0xB00) -#define DOEPCTL(_a) HSOTG_REG(0xB00 + ((_a) * 0x20)) +#define DOEPCTL0 HSOTG_REG(0xB00) +#define DOEPCTL(_a) HSOTG_REG(0xB00 + ((_a) * 0x20)) /* EP0 specialness: * bits[29..28] - reserved (no SetD0PID, SetD1PID) * bits[25..22] - should always be zero, this isn't a periodic endpoint * bits[10..0] - MPS setting different for EP0 */ -#define D0EPCTL_MPS_MASK (0x3 << 0) -#define D0EPCTL_MPS_SHIFT 0 -#define D0EPCTL_MPS_64 0 -#define D0EPCTL_MPS_32 1 -#define D0EPCTL_MPS_16 2 -#define D0EPCTL_MPS_8 3 +#define D0EPCTL_MPS_MASK (0x3 << 0) +#define D0EPCTL_MPS_SHIFT 0 +#define D0EPCTL_MPS_64 0 +#define D0EPCTL_MPS_32 1 +#define D0EPCTL_MPS_16 2 +#define D0EPCTL_MPS_8 3 -#define DXEPCTL_EPENA BIT(31) -#define DXEPCTL_EPDIS BIT(30) -#define DXEPCTL_SETD1PID BIT(29) -#define DXEPCTL_SETODDFR BIT(29) -#define DXEPCTL_SETD0PID BIT(28) -#define DXEPCTL_SETEVENFR BIT(28) -#define DXEPCTL_SNAK BIT(27) -#define DXEPCTL_CNAK BIT(26) -#define DXEPCTL_TXFNUM_MASK (0xf << 22) -#define DXEPCTL_TXFNUM_SHIFT 22 -#define DXEPCTL_TXFNUM_LIMIT 0xf -#define DXEPCTL_TXFNUM(_x) ((_x) << 22) -#define DXEPCTL_STALL BIT(21) -#define DXEPCTL_SNP BIT(20) -#define DXEPCTL_EPTYPE_MASK (0x3 << 18) -#define DXEPCTL_EPTYPE_CONTROL (0x0 << 18) -#define DXEPCTL_EPTYPE_ISO (0x1 << 18) -#define DXEPCTL_EPTYPE_BULK (0x2 << 18) -#define DXEPCTL_EPTYPE_INTERRUPT (0x3 << 18) +#define DXEPCTL_EPENA BIT(31) +#define DXEPCTL_EPDIS BIT(30) +#define DXEPCTL_SETD1PID BIT(29) +#define DXEPCTL_SETODDFR BIT(29) +#define DXEPCTL_SETD0PID BIT(28) +#define DXEPCTL_SETEVENFR BIT(28) +#define DXEPCTL_SNAK BIT(27) +#define DXEPCTL_CNAK BIT(26) +#define DXEPCTL_TXFNUM_MASK (0xf << 22) +#define DXEPCTL_TXFNUM_SHIFT 22 +#define DXEPCTL_TXFNUM_LIMIT 0xf +#define DXEPCTL_TXFNUM(_x) ((_x) << 22) +#define DXEPCTL_STALL BIT(21) +#define DXEPCTL_SNP BIT(20) +#define DXEPCTL_EPTYPE_MASK (0x3 << 18) +#define DXEPCTL_EPTYPE_CONTROL (0x0 << 18) +#define DXEPCTL_EPTYPE_ISO (0x1 << 18) +#define DXEPCTL_EPTYPE_BULK (0x2 << 18) +#define DXEPCTL_EPTYPE_INTERRUPT (0x3 << 18) -#define DXEPCTL_NAKSTS BIT(17) -#define DXEPCTL_DPID BIT(16) -#define DXEPCTL_EOFRNUM BIT(16) -#define DXEPCTL_USBACTEP BIT(15) -#define DXEPCTL_NEXTEP_MASK (0xf << 11) -#define DXEPCTL_NEXTEP_SHIFT 11 -#define DXEPCTL_NEXTEP_LIMIT 0xf -#define DXEPCTL_NEXTEP(_x) ((_x) << 11) -#define DXEPCTL_MPS_MASK (0x7ff << 0) -#define DXEPCTL_MPS_SHIFT 0 -#define DXEPCTL_MPS_LIMIT 0x7ff -#define DXEPCTL_MPS(_x) ((_x) << 0) +#define DXEPCTL_NAKSTS BIT(17) +#define DXEPCTL_DPID BIT(16) +#define DXEPCTL_EOFRNUM BIT(16) +#define DXEPCTL_USBACTEP BIT(15) +#define DXEPCTL_NEXTEP_MASK (0xf << 11) +#define DXEPCTL_NEXTEP_SHIFT 11 +#define DXEPCTL_NEXTEP_LIMIT 0xf +#define DXEPCTL_NEXTEP(_x) ((_x) << 11) +#define DXEPCTL_MPS_MASK (0x7ff << 0) +#define DXEPCTL_MPS_SHIFT 0 +#define DXEPCTL_MPS_LIMIT 0x7ff +#define DXEPCTL_MPS(_x) ((_x) << 0) -#define DIEPINT(_a) HSOTG_REG(0x908 + ((_a) * 0x20)) -#define DOEPINT(_a) HSOTG_REG(0xB08 + ((_a) * 0x20)) -#define DXEPINT_SETUP_RCVD BIT(15) -#define DXEPINT_NYETINTRPT BIT(14) -#define DXEPINT_NAKINTRPT BIT(13) -#define DXEPINT_BBLEERRINTRPT BIT(12) -#define DXEPINT_PKTDRPSTS BIT(11) -#define DXEPINT_BNAINTR BIT(9) -#define DXEPINT_TXFIFOUNDRN BIT(8) -#define DXEPINT_OUTPKTERR BIT(8) -#define DXEPINT_TXFEMP BIT(7) -#define DXEPINT_INEPNAKEFF BIT(6) -#define DXEPINT_BACK2BACKSETUP BIT(6) -#define DXEPINT_INTKNEPMIS BIT(5) -#define DXEPINT_STSPHSERCVD BIT(5) -#define DXEPINT_INTKNTXFEMP BIT(4) -#define DXEPINT_OUTTKNEPDIS BIT(4) -#define DXEPINT_TIMEOUT BIT(3) -#define DXEPINT_SETUP BIT(3) -#define DXEPINT_AHBERR BIT(2) -#define DXEPINT_EPDISBLD BIT(1) -#define DXEPINT_XFERCOMPL BIT(0) +#define DIEPINT(_a) HSOTG_REG(0x908 + ((_a) * 0x20)) +#define DOEPINT(_a) HSOTG_REG(0xB08 + ((_a) * 0x20)) +#define DXEPINT_SETUP_RCVD BIT(15) +#define DXEPINT_NYETINTRPT BIT(14) +#define DXEPINT_NAKINTRPT BIT(13) +#define DXEPINT_BBLEERRINTRPT BIT(12) +#define DXEPINT_PKTDRPSTS BIT(11) +#define DXEPINT_BNAINTR BIT(9) +#define DXEPINT_TXFIFOUNDRN BIT(8) +#define DXEPINT_OUTPKTERR BIT(8) +#define DXEPINT_TXFEMP BIT(7) +#define DXEPINT_INEPNAKEFF BIT(6) +#define DXEPINT_BACK2BACKSETUP BIT(6) +#define DXEPINT_INTKNEPMIS BIT(5) +#define DXEPINT_STSPHSERCVD BIT(5) +#define DXEPINT_INTKNTXFEMP BIT(4) +#define DXEPINT_OUTTKNEPDIS BIT(4) +#define DXEPINT_TIMEOUT BIT(3) +#define DXEPINT_SETUP BIT(3) +#define DXEPINT_AHBERR BIT(2) +#define DXEPINT_EPDISBLD BIT(1) +#define DXEPINT_XFERCOMPL BIT(0) -#define DIEPTSIZ0 HSOTG_REG(0x910) -#define DIEPTSIZ0_PKTCNT_MASK (0x3 << 19) -#define DIEPTSIZ0_PKTCNT_SHIFT 19 -#define DIEPTSIZ0_PKTCNT_LIMIT 0x3 -#define DIEPTSIZ0_PKTCNT(_x) ((_x) << 19) -#define DIEPTSIZ0_XFERSIZE_MASK (0x7f << 0) -#define DIEPTSIZ0_XFERSIZE_SHIFT 0 -#define DIEPTSIZ0_XFERSIZE_LIMIT 0x7f -#define DIEPTSIZ0_XFERSIZE(_x) ((_x) << 0) +#define DIEPTSIZ0 HSOTG_REG(0x910) +#define DIEPTSIZ0_PKTCNT_MASK (0x3 << 19) +#define DIEPTSIZ0_PKTCNT_SHIFT 19 +#define DIEPTSIZ0_PKTCNT_LIMIT 0x3 +#define DIEPTSIZ0_PKTCNT(_x) ((_x) << 19) +#define DIEPTSIZ0_XFERSIZE_MASK (0x7f << 0) +#define DIEPTSIZ0_XFERSIZE_SHIFT 0 +#define DIEPTSIZ0_XFERSIZE_LIMIT 0x7f +#define DIEPTSIZ0_XFERSIZE(_x) ((_x) << 0) -#define DOEPTSIZ0 HSOTG_REG(0xB10) -#define DOEPTSIZ0_SUPCNT_MASK (0x3 << 29) -#define DOEPTSIZ0_SUPCNT_SHIFT 29 -#define DOEPTSIZ0_SUPCNT_LIMIT 0x3 -#define DOEPTSIZ0_SUPCNT(_x) ((_x) << 29) -#define DOEPTSIZ0_PKTCNT BIT(19) -#define DOEPTSIZ0_XFERSIZE_MASK (0x7f << 0) -#define DOEPTSIZ0_XFERSIZE_SHIFT 0 +#define DOEPTSIZ0 HSOTG_REG(0xB10) +#define DOEPTSIZ0_SUPCNT_MASK (0x3 << 29) +#define DOEPTSIZ0_SUPCNT_SHIFT 29 +#define DOEPTSIZ0_SUPCNT_LIMIT 0x3 +#define DOEPTSIZ0_SUPCNT(_x) ((_x) << 29) +#define DOEPTSIZ0_PKTCNT BIT(19) +#define DOEPTSIZ0_XFERSIZE_MASK (0x7f << 0) +#define DOEPTSIZ0_XFERSIZE_SHIFT 0 -#define DIEPTSIZ(_a) HSOTG_REG(0x910 + ((_a) * 0x20)) -#define DOEPTSIZ(_a) HSOTG_REG(0xB10 + ((_a) * 0x20)) -#define DXEPTSIZ_MC_MASK (0x3 << 29) -#define DXEPTSIZ_MC_SHIFT 29 -#define DXEPTSIZ_MC_LIMIT 0x3 -#define DXEPTSIZ_MC(_x) ((_x) << 29) -#define DXEPTSIZ_PKTCNT_MASK (0x3ff << 19) -#define DXEPTSIZ_PKTCNT_SHIFT 19 -#define DXEPTSIZ_PKTCNT_LIMIT 0x3ff -#define DXEPTSIZ_PKTCNT_GET(_v) (((_v) >> 19) & 0x3ff) -#define DXEPTSIZ_PKTCNT(_x) ((_x) << 19) -#define DXEPTSIZ_XFERSIZE_MASK (0x7ffff << 0) -#define DXEPTSIZ_XFERSIZE_SHIFT 0 -#define DXEPTSIZ_XFERSIZE_LIMIT 0x7ffff -#define DXEPTSIZ_XFERSIZE_GET(_v) (((_v) >> 0) & 0x7ffff) -#define DXEPTSIZ_XFERSIZE(_x) ((_x) << 0) +#define DIEPTSIZ(_a) HSOTG_REG(0x910 + ((_a) * 0x20)) +#define DOEPTSIZ(_a) HSOTG_REG(0xB10 + ((_a) * 0x20)) +#define DXEPTSIZ_MC_MASK (0x3 << 29) +#define DXEPTSIZ_MC_SHIFT 29 +#define DXEPTSIZ_MC_LIMIT 0x3 +#define DXEPTSIZ_MC(_x) ((_x) << 29) +#define DXEPTSIZ_PKTCNT_MASK (0x3ff << 19) +#define DXEPTSIZ_PKTCNT_SHIFT 19 +#define DXEPTSIZ_PKTCNT_LIMIT 0x3ff +#define DXEPTSIZ_PKTCNT_GET(_v) (((_v) >> 19) & 0x3ff) +#define DXEPTSIZ_PKTCNT(_x) ((_x) << 19) +#define DXEPTSIZ_XFERSIZE_MASK (0x7ffff << 0) +#define DXEPTSIZ_XFERSIZE_SHIFT 0 +#define DXEPTSIZ_XFERSIZE_LIMIT 0x7ffff +#define DXEPTSIZ_XFERSIZE_GET(_v) (((_v) >> 0) & 0x7ffff) +#define DXEPTSIZ_XFERSIZE(_x) ((_x) << 0) -#define DIEPDMA(_a) HSOTG_REG(0x914 + ((_a) * 0x20)) -#define DOEPDMA(_a) HSOTG_REG(0xB14 + ((_a) * 0x20)) +#define DIEPDMA(_a) HSOTG_REG(0x914 + ((_a) * 0x20)) +#define DOEPDMA(_a) HSOTG_REG(0xB14 + ((_a) * 0x20)) -#define DTXFSTS(_a) HSOTG_REG(0x918 + ((_a) * 0x20)) +#define DTXFSTS(_a) HSOTG_REG(0x918 + ((_a) * 0x20)) -#define PCGCTL HSOTG_REG(0x0e00) -#define PCGCTL_IF_DEV_MODE BIT(31) -#define PCGCTL_P2HD_PRT_SPD_MASK (0x3 << 29) -#define PCGCTL_P2HD_PRT_SPD_SHIFT 29 -#define PCGCTL_P2HD_DEV_ENUM_SPD_MASK (0x3 << 27) -#define PCGCTL_P2HD_DEV_ENUM_SPD_SHIFT 27 -#define PCGCTL_MAC_DEV_ADDR_MASK (0x7f << 20) -#define PCGCTL_MAC_DEV_ADDR_SHIFT 20 -#define PCGCTL_MAX_TERMSEL BIT(19) -#define PCGCTL_MAX_XCVRSELECT_MASK (0x3 << 17) -#define PCGCTL_MAX_XCVRSELECT_SHIFT 17 -#define PCGCTL_PORT_POWER BIT(16) -#define PCGCTL_PRT_CLK_SEL_MASK (0x3 << 14) -#define PCGCTL_PRT_CLK_SEL_SHIFT 14 -#define PCGCTL_ESS_REG_RESTORED BIT(13) -#define PCGCTL_EXTND_HIBER_SWITCH BIT(12) -#define PCGCTL_EXTND_HIBER_PWRCLMP BIT(11) -#define PCGCTL_ENBL_EXTND_HIBER BIT(10) -#define PCGCTL_RESTOREMODE BIT(9) -#define PCGCTL_RESETAFTSUSP BIT(8) -#define PCGCTL_DEEP_SLEEP BIT(7) -#define PCGCTL_PHY_IN_SLEEP BIT(6) -#define PCGCTL_ENBL_SLEEP_GATING BIT(5) -#define PCGCTL_RSTPDWNMODULE BIT(3) -#define PCGCTL_PWRCLMP BIT(2) -#define PCGCTL_GATEHCLK BIT(1) -#define PCGCTL_STOPPCLK BIT(0) +#define PCGCTL HSOTG_REG(0x0e00) +#define PCGCTL_IF_DEV_MODE BIT(31) +#define PCGCTL_P2HD_PRT_SPD_MASK (0x3 << 29) +#define PCGCTL_P2HD_PRT_SPD_SHIFT 29 +#define PCGCTL_P2HD_DEV_ENUM_SPD_MASK (0x3 << 27) +#define PCGCTL_P2HD_DEV_ENUM_SPD_SHIFT 27 +#define PCGCTL_MAC_DEV_ADDR_MASK (0x7f << 20) +#define PCGCTL_MAC_DEV_ADDR_SHIFT 20 +#define PCGCTL_MAX_TERMSEL BIT(19) +#define PCGCTL_MAX_XCVRSELECT_MASK (0x3 << 17) +#define PCGCTL_MAX_XCVRSELECT_SHIFT 17 +#define PCGCTL_PORT_POWER BIT(16) +#define PCGCTL_PRT_CLK_SEL_MASK (0x3 << 14) +#define PCGCTL_PRT_CLK_SEL_SHIFT 14 +#define PCGCTL_ESS_REG_RESTORED BIT(13) +#define PCGCTL_EXTND_HIBER_SWITCH BIT(12) +#define PCGCTL_EXTND_HIBER_PWRCLMP BIT(11) +#define PCGCTL_ENBL_EXTND_HIBER BIT(10) +#define PCGCTL_RESTOREMODE BIT(9) +#define PCGCTL_RESETAFTSUSP BIT(8) +#define PCGCTL_DEEP_SLEEP BIT(7) +#define PCGCTL_PHY_IN_SLEEP BIT(6) +#define PCGCTL_ENBL_SLEEP_GATING BIT(5) +#define PCGCTL_RSTPDWNMODULE BIT(3) +#define PCGCTL_PWRCLMP BIT(2) +#define PCGCTL_GATEHCLK BIT(1) +#define PCGCTL_STOPPCLK BIT(0) #define PCGCCTL1 HSOTG_REG(0xe04) #define PCGCCTL1_TIMER (0x3 << 1) #define PCGCCTL1_GATEEN BIT(0) -#define EPFIFO(_a) HSOTG_REG(0x1000 + ((_a) * 0x1000)) +#define EPFIFO(_a) HSOTG_REG(0x1000 + ((_a) * 0x1000)) /* Host Mode Registers */ -#define HCFG HSOTG_REG(0x0400) -#define HCFG_MODECHTIMEN BIT(31) -#define HCFG_PERSCHEDENA BIT(26) -#define HCFG_FRLISTEN_MASK (0x3 << 24) -#define HCFG_FRLISTEN_SHIFT 24 -#define HCFG_FRLISTEN_8 (0 << 24) -#define FRLISTEN_8_SIZE 8 -#define HCFG_FRLISTEN_16 BIT(24) -#define FRLISTEN_16_SIZE 16 -#define HCFG_FRLISTEN_32 (2 << 24) -#define FRLISTEN_32_SIZE 32 -#define HCFG_FRLISTEN_64 (3 << 24) -#define FRLISTEN_64_SIZE 64 -#define HCFG_DESCDMA BIT(23) -#define HCFG_RESVALID_MASK (0xff << 8) -#define HCFG_RESVALID_SHIFT 8 -#define HCFG_ENA32KHZ BIT(7) -#define HCFG_FSLSSUPP BIT(2) -#define HCFG_FSLSPCLKSEL_MASK (0x3 << 0) -#define HCFG_FSLSPCLKSEL_SHIFT 0 -#define HCFG_FSLSPCLKSEL_30_60_MHZ 0 -#define HCFG_FSLSPCLKSEL_48_MHZ 1 -#define HCFG_FSLSPCLKSEL_6_MHZ 2 +#define HCFG HSOTG_REG(0x0400) +#define HCFG_MODECHTIMEN BIT(31) +#define HCFG_PERSCHEDENA BIT(26) +#define HCFG_FRLISTEN_MASK (0x3 << 24) +#define HCFG_FRLISTEN_SHIFT 24 +#define HCFG_FRLISTEN_8 (0 << 24) +#define FRLISTEN_8_SIZE 8 +#define HCFG_FRLISTEN_16 BIT(24) +#define FRLISTEN_16_SIZE 16 +#define HCFG_FRLISTEN_32 (2 << 24) +#define FRLISTEN_32_SIZE 32 +#define HCFG_FRLISTEN_64 (3 << 24) +#define FRLISTEN_64_SIZE 64 +#define HCFG_DESCDMA BIT(23) +#define HCFG_RESVALID_MASK (0xff << 8) +#define HCFG_RESVALID_SHIFT 8 +#define HCFG_ENA32KHZ BIT(7) +#define HCFG_FSLSSUPP BIT(2) +#define HCFG_FSLSPCLKSEL_MASK (0x3 << 0) +#define HCFG_FSLSPCLKSEL_SHIFT 0 +#define HCFG_FSLSPCLKSEL_30_60_MHZ 0 +#define HCFG_FSLSPCLKSEL_48_MHZ 1 +#define HCFG_FSLSPCLKSEL_6_MHZ 2 -#define HFIR HSOTG_REG(0x0404) -#define HFIR_FRINT_MASK (0xffff << 0) -#define HFIR_FRINT_SHIFT 0 -#define HFIR_RLDCTRL BIT(16) +#define HFIR HSOTG_REG(0x0404) +#define HFIR_FRINT_MASK (0xffff << 0) +#define HFIR_FRINT_SHIFT 0 +#define HFIR_RLDCTRL BIT(16) -#define HFNUM HSOTG_REG(0x0408) -#define HFNUM_FRREM_MASK (0xffff << 16) -#define HFNUM_FRREM_SHIFT 16 -#define HFNUM_FRNUM_MASK (0xffff << 0) -#define HFNUM_FRNUM_SHIFT 0 -#define HFNUM_MAX_FRNUM 0x3fff +#define HFNUM HSOTG_REG(0x0408) +#define HFNUM_FRREM_MASK (0xffff << 16) +#define HFNUM_FRREM_SHIFT 16 +#define HFNUM_FRNUM_MASK (0xffff << 0) +#define HFNUM_FRNUM_SHIFT 0 +#define HFNUM_MAX_FRNUM 0x3fff -#define HPTXSTS HSOTG_REG(0x0410) -#define TXSTS_QTOP_ODD BIT(31) -#define TXSTS_QTOP_CHNEP_MASK (0xf << 27) -#define TXSTS_QTOP_CHNEP_SHIFT 27 -#define TXSTS_QTOP_TOKEN_MASK (0x3 << 25) -#define TXSTS_QTOP_TOKEN_SHIFT 25 -#define TXSTS_QTOP_TERMINATE BIT(24) -#define TXSTS_QSPCAVAIL_MASK (0xff << 16) -#define TXSTS_QSPCAVAIL_SHIFT 16 -#define TXSTS_FSPCAVAIL_MASK (0xffff << 0) -#define TXSTS_FSPCAVAIL_SHIFT 0 +#define HPTXSTS HSOTG_REG(0x0410) +#define TXSTS_QTOP_ODD BIT(31) +#define TXSTS_QTOP_CHNEP_MASK (0xf << 27) +#define TXSTS_QTOP_CHNEP_SHIFT 27 +#define TXSTS_QTOP_TOKEN_MASK (0x3 << 25) +#define TXSTS_QTOP_TOKEN_SHIFT 25 +#define TXSTS_QTOP_TERMINATE BIT(24) +#define TXSTS_QSPCAVAIL_MASK (0xff << 16) +#define TXSTS_QSPCAVAIL_SHIFT 16 +#define TXSTS_FSPCAVAIL_MASK (0xffff << 0) +#define TXSTS_FSPCAVAIL_SHIFT 0 -#define HAINT HSOTG_REG(0x0414) -#define HAINTMSK HSOTG_REG(0x0418) -#define HFLBADDR HSOTG_REG(0x041c) +#define HAINT HSOTG_REG(0x0414) +#define HAINTMSK HSOTG_REG(0x0418) +#define HFLBADDR HSOTG_REG(0x041c) -#define HPRT0 HSOTG_REG(0x0440) -#define HPRT0_SPD_MASK (0x3 << 17) -#define HPRT0_SPD_SHIFT 17 -#define HPRT0_SPD_HIGH_SPEED 0 -#define HPRT0_SPD_FULL_SPEED 1 -#define HPRT0_SPD_LOW_SPEED 2 -#define HPRT0_TSTCTL_MASK (0xf << 13) -#define HPRT0_TSTCTL_SHIFT 13 -#define HPRT0_PWR BIT(12) -#define HPRT0_LNSTS_MASK (0x3 << 10) -#define HPRT0_LNSTS_SHIFT 10 -#define HPRT0_RST BIT(8) -#define HPRT0_SUSP BIT(7) -#define HPRT0_RES BIT(6) -#define HPRT0_OVRCURRCHG BIT(5) -#define HPRT0_OVRCURRACT BIT(4) -#define HPRT0_ENACHG BIT(3) -#define HPRT0_ENA BIT(2) -#define HPRT0_CONNDET BIT(1) -#define HPRT0_CONNSTS BIT(0) +#define HPRT0 HSOTG_REG(0x0440) +#define HPRT0_SPD_MASK (0x3 << 17) +#define HPRT0_SPD_SHIFT 17 +#define HPRT0_SPD_HIGH_SPEED 0 +#define HPRT0_SPD_FULL_SPEED 1 +#define HPRT0_SPD_LOW_SPEED 2 +#define HPRT0_TSTCTL_MASK (0xf << 13) +#define HPRT0_TSTCTL_SHIFT 13 +#define HPRT0_PWR BIT(12) +#define HPRT0_LNSTS_MASK (0x3 << 10) +#define HPRT0_LNSTS_SHIFT 10 +#define HPRT0_RST BIT(8) +#define HPRT0_SUSP BIT(7) +#define HPRT0_RES BIT(6) +#define HPRT0_OVRCURRCHG BIT(5) +#define HPRT0_OVRCURRACT BIT(4) +#define HPRT0_ENACHG BIT(3) +#define HPRT0_ENA BIT(2) +#define HPRT0_CONNDET BIT(1) +#define HPRT0_CONNSTS BIT(0) -#define HCCHAR(_ch) HSOTG_REG(0x0500 + 0x20 * (_ch)) -#define HCCHAR_CHENA BIT(31) -#define HCCHAR_CHDIS BIT(30) -#define HCCHAR_ODDFRM BIT(29) -#define HCCHAR_DEVADDR_MASK (0x7f << 22) -#define HCCHAR_DEVADDR_SHIFT 22 -#define HCCHAR_MULTICNT_MASK (0x3 << 20) -#define HCCHAR_MULTICNT_SHIFT 20 -#define HCCHAR_EPTYPE_MASK (0x3 << 18) -#define HCCHAR_EPTYPE_SHIFT 18 -#define HCCHAR_LSPDDEV BIT(17) -#define HCCHAR_EPDIR BIT(15) -#define HCCHAR_EPNUM_MASK (0xf << 11) -#define HCCHAR_EPNUM_SHIFT 11 -#define HCCHAR_MPS_MASK (0x7ff << 0) -#define HCCHAR_MPS_SHIFT 0 +#define HCCHAR(_ch) HSOTG_REG(0x0500 + 0x20 * (_ch)) +#define HCCHAR_CHENA BIT(31) +#define HCCHAR_CHDIS BIT(30) +#define HCCHAR_ODDFRM BIT(29) +#define HCCHAR_DEVADDR_MASK (0x7f << 22) +#define HCCHAR_DEVADDR_SHIFT 22 +#define HCCHAR_MULTICNT_MASK (0x3 << 20) +#define HCCHAR_MULTICNT_SHIFT 20 +#define HCCHAR_EPTYPE_MASK (0x3 << 18) +#define HCCHAR_EPTYPE_SHIFT 18 +#define HCCHAR_LSPDDEV BIT(17) +#define HCCHAR_EPDIR BIT(15) +#define HCCHAR_EPNUM_MASK (0xf << 11) +#define HCCHAR_EPNUM_SHIFT 11 +#define HCCHAR_MPS_MASK (0x7ff << 0) +#define HCCHAR_MPS_SHIFT 0 -#define HCSPLT(_ch) HSOTG_REG(0x0504 + 0x20 * (_ch)) -#define HCSPLT_SPLTENA BIT(31) -#define HCSPLT_COMPSPLT BIT(16) -#define HCSPLT_XACTPOS_MASK (0x3 << 14) -#define HCSPLT_XACTPOS_SHIFT 14 -#define HCSPLT_XACTPOS_MID 0 -#define HCSPLT_XACTPOS_END 1 -#define HCSPLT_XACTPOS_BEGIN 2 -#define HCSPLT_XACTPOS_ALL 3 -#define HCSPLT_HUBADDR_MASK (0x7f << 7) -#define HCSPLT_HUBADDR_SHIFT 7 -#define HCSPLT_PRTADDR_MASK (0x7f << 0) -#define HCSPLT_PRTADDR_SHIFT 0 +#define HCSPLT(_ch) HSOTG_REG(0x0504 + 0x20 * (_ch)) +#define HCSPLT_SPLTENA BIT(31) +#define HCSPLT_COMPSPLT BIT(16) +#define HCSPLT_XACTPOS_MASK (0x3 << 14) +#define HCSPLT_XACTPOS_SHIFT 14 +#define HCSPLT_XACTPOS_MID 0 +#define HCSPLT_XACTPOS_END 1 +#define HCSPLT_XACTPOS_BEGIN 2 +#define HCSPLT_XACTPOS_ALL 3 +#define HCSPLT_HUBADDR_MASK (0x7f << 7) +#define HCSPLT_HUBADDR_SHIFT 7 +#define HCSPLT_PRTADDR_MASK (0x7f << 0) +#define HCSPLT_PRTADDR_SHIFT 0 -#define HCINT(_ch) HSOTG_REG(0x0508 + 0x20 * (_ch)) -#define HCINTMSK(_ch) HSOTG_REG(0x050c + 0x20 * (_ch)) -#define HCINTMSK_RESERVED14_31 (0x3ffff << 14) -#define HCINTMSK_FRM_LIST_ROLL BIT(13) -#define HCINTMSK_XCS_XACT BIT(12) -#define HCINTMSK_BNA BIT(11) -#define HCINTMSK_DATATGLERR BIT(10) -#define HCINTMSK_FRMOVRUN BIT(9) -#define HCINTMSK_BBLERR BIT(8) -#define HCINTMSK_XACTERR BIT(7) -#define HCINTMSK_NYET BIT(6) -#define HCINTMSK_ACK BIT(5) -#define HCINTMSK_NAK BIT(4) -#define HCINTMSK_STALL BIT(3) -#define HCINTMSK_AHBERR BIT(2) -#define HCINTMSK_CHHLTD BIT(1) -#define HCINTMSK_XFERCOMPL BIT(0) +#define HCINT(_ch) HSOTG_REG(0x0508 + 0x20 * (_ch)) +#define HCINTMSK(_ch) HSOTG_REG(0x050c + 0x20 * (_ch)) +#define HCINTMSK_RESERVED14_31 (0x3ffff << 14) +#define HCINTMSK_FRM_LIST_ROLL BIT(13) +#define HCINTMSK_XCS_XACT BIT(12) +#define HCINTMSK_BNA BIT(11) +#define HCINTMSK_DATATGLERR BIT(10) +#define HCINTMSK_FRMOVRUN BIT(9) +#define HCINTMSK_BBLERR BIT(8) +#define HCINTMSK_XACTERR BIT(7) +#define HCINTMSK_NYET BIT(6) +#define HCINTMSK_ACK BIT(5) +#define HCINTMSK_NAK BIT(4) +#define HCINTMSK_STALL BIT(3) +#define HCINTMSK_AHBERR BIT(2) +#define HCINTMSK_CHHLTD BIT(1) +#define HCINTMSK_XFERCOMPL BIT(0) -#define HCTSIZ(_ch) HSOTG_REG(0x0510 + 0x20 * (_ch)) -#define TSIZ_DOPNG BIT(31) -#define TSIZ_SC_MC_PID_MASK (0x3 << 29) -#define TSIZ_SC_MC_PID_SHIFT 29 -#define TSIZ_SC_MC_PID_DATA0 0 -#define TSIZ_SC_MC_PID_DATA2 1 -#define TSIZ_SC_MC_PID_DATA1 2 -#define TSIZ_SC_MC_PID_MDATA 3 -#define TSIZ_SC_MC_PID_SETUP 3 -#define TSIZ_PKTCNT_MASK (0x3ff << 19) -#define TSIZ_PKTCNT_SHIFT 19 -#define TSIZ_NTD_MASK (0xff << 8) -#define TSIZ_NTD_SHIFT 8 -#define TSIZ_SCHINFO_MASK (0xff << 0) -#define TSIZ_SCHINFO_SHIFT 0 -#define TSIZ_XFERSIZE_MASK (0x7ffff << 0) -#define TSIZ_XFERSIZE_SHIFT 0 +#define HCTSIZ(_ch) HSOTG_REG(0x0510 + 0x20 * (_ch)) +#define TSIZ_DOPNG BIT(31) +#define TSIZ_SC_MC_PID_MASK (0x3 << 29) +#define TSIZ_SC_MC_PID_SHIFT 29 +#define TSIZ_SC_MC_PID_DATA0 0 +#define TSIZ_SC_MC_PID_DATA2 1 +#define TSIZ_SC_MC_PID_DATA1 2 +#define TSIZ_SC_MC_PID_MDATA 3 +#define TSIZ_SC_MC_PID_SETUP 3 +#define TSIZ_PKTCNT_MASK (0x3ff << 19) +#define TSIZ_PKTCNT_SHIFT 19 +#define TSIZ_NTD_MASK (0xff << 8) +#define TSIZ_NTD_SHIFT 8 +#define TSIZ_SCHINFO_MASK (0xff << 0) +#define TSIZ_SCHINFO_SHIFT 0 +#define TSIZ_XFERSIZE_MASK (0x7ffff << 0) +#define TSIZ_XFERSIZE_SHIFT 0 -#define HCDMA(_ch) HSOTG_REG(0x0514 + 0x20 * (_ch)) +#define HCDMA(_ch) HSOTG_REG(0x0514 + 0x20 * (_ch)) -#define HCDMAB(_ch) HSOTG_REG(0x051c + 0x20 * (_ch)) +#define HCDMAB(_ch) HSOTG_REG(0x051c + 0x20 * (_ch)) -#define HCFIFO(_ch) HSOTG_REG(0x1000 + 0x1000 * (_ch)) +#define HCFIFO(_ch) HSOTG_REG(0x1000 + 0x1000 * (_ch)) /** * struct dwc2_dma_desc - DMA descriptor structure, @@ -836,64 +836,64 @@ * Status quadlet and Data buffer pointer. */ struct dwc2_dma_desc { - uint32_t status; - uint32_t buf; + uint32_t status; + uint32_t buf; } __packed; /* Host Mode DMA descriptor status quadlet */ -#define HOST_DMA_A BIT(31) -#define HOST_DMA_STS_MASK (0x3 << 28) -#define HOST_DMA_STS_SHIFT 28 -#define HOST_DMA_STS_PKTERR BIT(28) -#define HOST_DMA_EOL BIT(26) -#define HOST_DMA_IOC BIT(25) -#define HOST_DMA_SUP BIT(24) -#define HOST_DMA_ALT_QTD BIT(23) -#define HOST_DMA_QTD_OFFSET_MASK (0x3f << 17) -#define HOST_DMA_QTD_OFFSET_SHIFT 17 -#define HOST_DMA_ISOC_NBYTES_MASK (0xfff << 0) -#define HOST_DMA_ISOC_NBYTES_SHIFT 0 -#define HOST_DMA_NBYTES_MASK (0x1ffff << 0) -#define HOST_DMA_NBYTES_SHIFT 0 -#define HOST_DMA_NBYTES_LIMIT 131071 +#define HOST_DMA_A BIT(31) +#define HOST_DMA_STS_MASK (0x3 << 28) +#define HOST_DMA_STS_SHIFT 28 +#define HOST_DMA_STS_PKTERR BIT(28) +#define HOST_DMA_EOL BIT(26) +#define HOST_DMA_IOC BIT(25) +#define HOST_DMA_SUP BIT(24) +#define HOST_DMA_ALT_QTD BIT(23) +#define HOST_DMA_QTD_OFFSET_MASK (0x3f << 17) +#define HOST_DMA_QTD_OFFSET_SHIFT 17 +#define HOST_DMA_ISOC_NBYTES_MASK (0xfff << 0) +#define HOST_DMA_ISOC_NBYTES_SHIFT 0 +#define HOST_DMA_NBYTES_MASK (0x1ffff << 0) +#define HOST_DMA_NBYTES_SHIFT 0 +#define HOST_DMA_NBYTES_LIMIT 131071 /* Device Mode DMA descriptor status quadlet */ -#define DEV_DMA_BUFF_STS_MASK (0x3 << 30) -#define DEV_DMA_BUFF_STS_SHIFT 30 -#define DEV_DMA_BUFF_STS_HREADY 0 -#define DEV_DMA_BUFF_STS_DMABUSY 1 -#define DEV_DMA_BUFF_STS_DMADONE 2 -#define DEV_DMA_BUFF_STS_HBUSY 3 -#define DEV_DMA_STS_MASK (0x3 << 28) -#define DEV_DMA_STS_SHIFT 28 -#define DEV_DMA_STS_SUCC 0 -#define DEV_DMA_STS_BUFF_FLUSH 1 -#define DEV_DMA_STS_BUFF_ERR 3 -#define DEV_DMA_L BIT(27) -#define DEV_DMA_SHORT BIT(26) -#define DEV_DMA_IOC BIT(25) -#define DEV_DMA_SR BIT(24) -#define DEV_DMA_MTRF BIT(23) -#define DEV_DMA_ISOC_PID_MASK (0x3 << 23) -#define DEV_DMA_ISOC_PID_SHIFT 23 -#define DEV_DMA_ISOC_PID_DATA0 0 -#define DEV_DMA_ISOC_PID_DATA2 1 -#define DEV_DMA_ISOC_PID_DATA1 2 -#define DEV_DMA_ISOC_PID_MDATA 3 -#define DEV_DMA_ISOC_FRNUM_MASK (0x7ff << 12) -#define DEV_DMA_ISOC_FRNUM_SHIFT 12 -#define DEV_DMA_ISOC_TX_NBYTES_MASK (0xfff << 0) -#define DEV_DMA_ISOC_TX_NBYTES_LIMIT 0xfff -#define DEV_DMA_ISOC_RX_NBYTES_MASK (0x7ff << 0) -#define DEV_DMA_ISOC_RX_NBYTES_LIMIT 0x7ff -#define DEV_DMA_ISOC_NBYTES_SHIFT 0 -#define DEV_DMA_NBYTES_MASK (0xffff << 0) -#define DEV_DMA_NBYTES_SHIFT 0 -#define DEV_DMA_NBYTES_LIMIT 0xffff +#define DEV_DMA_BUFF_STS_MASK (0x3 << 30) +#define DEV_DMA_BUFF_STS_SHIFT 30 +#define DEV_DMA_BUFF_STS_HREADY 0 +#define DEV_DMA_BUFF_STS_DMABUSY 1 +#define DEV_DMA_BUFF_STS_DMADONE 2 +#define DEV_DMA_BUFF_STS_HBUSY 3 +#define DEV_DMA_STS_MASK (0x3 << 28) +#define DEV_DMA_STS_SHIFT 28 +#define DEV_DMA_STS_SUCC 0 +#define DEV_DMA_STS_BUFF_FLUSH 1 +#define DEV_DMA_STS_BUFF_ERR 3 +#define DEV_DMA_L BIT(27) +#define DEV_DMA_SHORT BIT(26) +#define DEV_DMA_IOC BIT(25) +#define DEV_DMA_SR BIT(24) +#define DEV_DMA_MTRF BIT(23) +#define DEV_DMA_ISOC_PID_MASK (0x3 << 23) +#define DEV_DMA_ISOC_PID_SHIFT 23 +#define DEV_DMA_ISOC_PID_DATA0 0 +#define DEV_DMA_ISOC_PID_DATA2 1 +#define DEV_DMA_ISOC_PID_DATA1 2 +#define DEV_DMA_ISOC_PID_MDATA 3 +#define DEV_DMA_ISOC_FRNUM_MASK (0x7ff << 12) +#define DEV_DMA_ISOC_FRNUM_SHIFT 12 +#define DEV_DMA_ISOC_TX_NBYTES_MASK (0xfff << 0) +#define DEV_DMA_ISOC_TX_NBYTES_LIMIT 0xfff +#define DEV_DMA_ISOC_RX_NBYTES_MASK (0x7ff << 0) +#define DEV_DMA_ISOC_RX_NBYTES_LIMIT 0x7ff +#define DEV_DMA_ISOC_NBYTES_SHIFT 0 +#define DEV_DMA_NBYTES_MASK (0xffff << 0) +#define DEV_DMA_NBYTES_SHIFT 0 +#define DEV_DMA_NBYTES_LIMIT 0xffff -#define MAX_DMA_DESC_NUM_GENERIC 64 -#define MAX_DMA_DESC_NUM_HS_ISOC 256 +#define MAX_DMA_DESC_NUM_GENERIC 64 +#define MAX_DMA_DESC_NUM_HS_ISOC 256 #endif /* DWC2_REGS_H */ From bc5add1dadcc140fef9af4fe215167e796cd1a58 Mon Sep 17 00:00:00 2001 From: Si-Wei Liu Date: Tue, 8 Nov 2022 12:19:28 +0800 Subject: [PATCH 686/705] vhost-vdpa: fix assert !virtio_net_get_subqueue(nc)->async_tx.elem in virtio_net_reset The citing commit has incorrect code in vhost_vdpa_receive() that returns zero instead of full packet size to the caller. This renders pending packets unable to be freed so then get clogged in the tx queue forever. When device is being reset later on, below assertion failure ensues: 0 0x00007f86d53bb387 in raise () from /lib64/libc.so.6 1 0x00007f86d53bca78 in abort () from /lib64/libc.so.6 2 0x00007f86d53b41a6 in __assert_fail_base () from /lib64/libc.so.6 3 0x00007f86d53b4252 in __assert_fail () from /lib64/libc.so.6 4 0x000055b8f6ff6fcc in virtio_net_reset (vdev=) at /usr/src/debug/qemu/hw/net/virtio-net.c:563 5 0x000055b8f7012fcf in virtio_reset (opaque=0x55b8faf881f0) at /usr/src/debug/qemu/hw/virtio/virtio.c:1993 6 0x000055b8f71f0086 in virtio_bus_reset (bus=bus@entry=0x55b8faf88178) at /usr/src/debug/qemu/hw/virtio/virtio-bus.c:102 7 0x000055b8f71f1620 in virtio_pci_reset (qdev=) at /usr/src/debug/qemu/hw/virtio/virtio-pci.c:1845 8 0x000055b8f6fafc6c in memory_region_write_accessor (mr=, addr=, value=, size=, shift=, mask=, attrs=...) at /usr/src/debug/qemu/memory.c:483 9 0x000055b8f6fadce9 in access_with_adjusted_size (addr=addr@entry=20, value=value@entry=0x7f867e7fb7e8, size=size@entry=1, access_size_min=, access_size_max=, access_fn=0x55b8f6fafc20 , mr=0x55b8faf80a50, attrs=...) at /usr/src/debug/qemu/memory.c:544 10 0x000055b8f6fb1d0b in memory_region_dispatch_write (mr=mr@entry=0x55b8faf80a50, addr=addr@entry=20, data=0, op=, attrs=attrs@entry=...) at /usr/src/debug/qemu/memory.c:1470 11 0x000055b8f6f62ada in flatview_write_continue (fv=fv@entry=0x7f86ac04cd20, addr=addr@entry=549755813908, attrs=..., attrs@entry=..., buf=buf@entry=0x7f86d0223028

, len=len@entry=1, addr1=20, l=1, mr=0x55b8faf80a50) at /usr/src/debug/qemu/exec.c:3266 12 0x000055b8f6f62c8f in flatview_write (fv=0x7f86ac04cd20, addr=549755813908, attrs=..., buf=0x7f86d0223028
, len=1) at /usr/src/debug/qemu/exec.c:3306 13 0x000055b8f6f674cb in address_space_write (as=, addr=, attrs=..., buf=, len=) at /usr/src/debug/qemu/exec.c:3396 14 0x000055b8f6f67575 in address_space_rw (as=, addr=, attrs=..., attrs@entry=..., buf=buf@entry=0x7f86d0223028
, len=, is_write=) at /usr/src/debug/qemu/exec.c:3406 15 0x000055b8f6fc1cc8 in kvm_cpu_exec (cpu=cpu@entry=0x55b8f9aa0e10) at /usr/src/debug/qemu/accel/kvm/kvm-all.c:2410 16 0x000055b8f6fa5f5e in qemu_kvm_cpu_thread_fn (arg=0x55b8f9aa0e10) at /usr/src/debug/qemu/cpus.c:1318 17 0x000055b8f7336e16 in qemu_thread_start (args=0x55b8f9ac8480) at /usr/src/debug/qemu/util/qemu-thread-posix.c:519 18 0x00007f86d575aea5 in start_thread () from /lib64/libpthread.so.0 19 0x00007f86d5483b2d in clone () from /lib64/libc.so.6 Make vhost_vdpa_receive() return the size passed in as is, so that the caller qemu_deliver_packet_iov() would eventually propagate it back to virtio_net_flush_tx() to release pending packets from the async_tx queue. Which corresponds to the drop path where qemu_sendv_packet_async() returns non-zero in virtio_net_flush_tx(). Fixes: 846a1e85da64 ("vdpa: Add dummy receive callback") Cc: Eugenio Perez Martin Signed-off-by: Si-Wei Liu Signed-off-by: Jason Wang Signed-off-by: Stefan Hajnoczi Message-Id: <20221108041929.18417-2-jasowang@redhat.com> --- net/vhost-vdpa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c index e370ecb8eb..6811089231 100644 --- a/net/vhost-vdpa.c +++ b/net/vhost-vdpa.c @@ -210,7 +210,7 @@ static bool vhost_vdpa_check_peer_type(NetClientState *nc, ObjectClass *oc, static ssize_t vhost_vdpa_receive(NetClientState *nc, const uint8_t *buf, size_t size) { - return 0; + return size; } static NetClientInfo net_vhost_vdpa_info = { From f9c307c3f9dfda64355fd2c6d73b002913d6752c Mon Sep 17 00:00:00 2001 From: Zhenzhong Duan Date: Wed, 22 Jun 2022 17:59:12 +0800 Subject: [PATCH 687/705] memory: Fix wrong end address dump MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The end address of memory region section isn't correctly calculated which leads to overflowed mtree dump: Dispatch Physical sections ...... #70 @0000000000002000..0000000000011fff io [ROOT] #71 @0000000000005000..0000000000005fff (noname) #72 @0000000000005000..0000000000014fff io [ROOT] #73 @0000000000005658..0000000000005658 vmport #74 @0000000000005659..0000000000015658 io [ROOT] #75 @0000000000006000..0000000000015fff io [ROOT] After fix: #70 @0000000000002000..0000000000004fff io [ROOT] #71 @0000000000005000..0000000000005fff (noname) #72 @0000000000005000..0000000000005657 io [ROOT] #73 @0000000000005658..0000000000005658 vmport #74 @0000000000005659..0000000000005fff io [ROOT] #75 @0000000000006000..000000000000ffff io [ROOT] Fixes: 5e8fd947e2670 ("memory: Rework "info mtree" to print flat views and dispatch trees") Signed-off-by: Zhenzhong Duan Reviewed-by: David Hildenbrand Reviewed-by: Peter Xu Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20220622095912.3430583-1-zhenzhong.duan@intel.com> Signed-off-by: Philippe Mathieu-Daudé --- softmmu/physmem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/softmmu/physmem.c b/softmmu/physmem.c index d9578ccfd4..1b606a3002 100644 --- a/softmmu/physmem.c +++ b/softmmu/physmem.c @@ -3712,7 +3712,7 @@ void mtree_print_dispatch(AddressSpaceDispatch *d, MemoryRegion *root) " %s%s%s%s%s", i, s->offset_within_address_space, - s->offset_within_address_space + MR_SIZE(s->mr->size), + s->offset_within_address_space + MR_SIZE(s->size), s->mr->name ? s->mr->name : "(noname)", i < ARRAY_SIZE(names) ? names[i] : "", s->mr == root ? " [ROOT]" : "", From ef7716cacc1d727747a6b230dde9f42fb46e939c Mon Sep 17 00:00:00 2001 From: Daniel Henrique Barboza Date: Tue, 8 Nov 2022 15:00:32 +0100 Subject: [PATCH 688/705] Revert "hw/block/pflash_cfi: Error out if dev length isn't power of 2" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 334c388f25 ("pflash_cfi: Error out if device length isn't a power of two") aimed to finish the effort started by commit 06f1521795 ("pflash: Require backend size to match device, improve errors"), but unfortunately we are not quite there since various machines are still ready to accept incomplete / oversized pflash backend images, and now fail, i.e. on Debian bullseye: $ qemu-system-x86_64 \ -drive \ if=pflash,format=raw,unit=0,readonly=on,file=/usr/share/OVMF/OVMF_CODE.fd qemu-system-x86_64: Device size must be a power of two. where OVMF_CODE.fd comes from the ovmf package, which doesn't pad the firmware images to the flash size: $ ls -lh /usr/share/OVMF/ -rw-r--r-- 1 root root 3.5M Aug 19 2021 OVMF_CODE_4M.fd -rw-r--r-- 1 root root 1.9M Aug 19 2021 OVMF_CODE.fd -rw-r--r-- 1 root root 128K Aug 19 2021 OVMF_VARS.fd Since we entered the freeze period to prepare the v7.2.0 release, the safest is to revert commit 334c388f25707a234c4a0dea05b9df08d. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1294 Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20221108175755.95141-1-philmd@linaro.org> Signed-off-by: Daniel Henrique Barboza Message-Id: <20221108172633.860700-1-danielhb413@gmail.com> --- hw/block/pflash_cfi01.c | 8 ++------ hw/block/pflash_cfi02.c | 5 ----- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c index 9c235bf66e..0cbc2fb4cb 100644 --- a/hw/block/pflash_cfi01.c +++ b/hw/block/pflash_cfi01.c @@ -690,7 +690,7 @@ static const MemoryRegionOps pflash_cfi01_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -static void pflash_cfi01_fill_cfi_table(PFlashCFI01 *pfl, Error **errp) +static void pflash_cfi01_fill_cfi_table(PFlashCFI01 *pfl) { uint64_t blocks_per_device, sector_len_per_device, device_len; int num_devices; @@ -708,10 +708,6 @@ static void pflash_cfi01_fill_cfi_table(PFlashCFI01 *pfl, Error **errp) sector_len_per_device = pfl->sector_len / num_devices; } device_len = sector_len_per_device * blocks_per_device; - if (!is_power_of_2(device_len)) { - error_setg(errp, "Device size must be a power of two."); - return; - } /* Hardcoded CFI table */ /* Standard "QRY" string */ @@ -869,7 +865,7 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp) */ pfl->cmd = 0x00; pfl->status = 0x80; /* WSM ready */ - pflash_cfi01_fill_cfi_table(pfl, errp); + pflash_cfi01_fill_cfi_table(pfl); } static void pflash_cfi01_system_reset(DeviceState *dev) diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c index ff2fe154c1..2a99b286b0 100644 --- a/hw/block/pflash_cfi02.c +++ b/hw/block/pflash_cfi02.c @@ -880,11 +880,6 @@ static void pflash_cfi02_realize(DeviceState *dev, Error **errp) return; } - if (!is_power_of_2(pfl->chip_len)) { - error_setg(errp, "Device size must be a power of two."); - return; - } - memory_region_init_rom_device(&pfl->orig_mem, OBJECT(pfl), &pflash_cfi02_ops, pfl, pfl->name, pfl->chip_len, errp); From 60ab36907ded2918d33683f2b66f603b7400d8f3 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Tue, 8 Nov 2022 13:41:40 -0500 Subject: [PATCH 689/705] Update VERSION for v7.2.0-rc0 Signed-off-by: Stefan Hajnoczi --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 72cf60d0ec..628ab8965f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.1.50 +7.1.90 From 35abb009b22e93e89cc627de74fa90339b680882 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sun, 6 Nov 2022 10:55:37 +1100 Subject: [PATCH 690/705] tcg: Move TCG_TARGET_HAS_direct_jump init to tb_gen_code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- accel/tcg/translate-all.c | 10 ---------- tcg/tcg.c | 12 ++++++++++++ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 921944a5ab..9ee21f7f52 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -821,16 +821,6 @@ TranslationBlock *tb_gen_code(CPUState *cpu, trace_translate_block(tb, pc, tb->tc.ptr); /* generate machine code */ - tb->jmp_reset_offset[0] = TB_JMP_RESET_OFFSET_INVALID; - tb->jmp_reset_offset[1] = TB_JMP_RESET_OFFSET_INVALID; - tcg_ctx->tb_jmp_reset_offset = tb->jmp_reset_offset; - if (TCG_TARGET_HAS_direct_jump) { - tcg_ctx->tb_jmp_insn_offset = tb->jmp_target_arg; - tcg_ctx->tb_jmp_target_addr = NULL; - } else { - tcg_ctx->tb_jmp_insn_offset = NULL; - tcg_ctx->tb_jmp_target_addr = tb->jmp_target_arg; - } #ifdef CONFIG_PROFILER qatomic_set(&prof->tb_count, prof->tb_count + 1); diff --git a/tcg/tcg.c b/tcg/tcg.c index b43b6a7981..436fcf6ebd 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -4228,6 +4228,18 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, target_ulong pc_start) } #endif + /* Initialize goto_tb jump offsets. */ + tb->jmp_reset_offset[0] = TB_JMP_RESET_OFFSET_INVALID; + tb->jmp_reset_offset[1] = TB_JMP_RESET_OFFSET_INVALID; + tcg_ctx->tb_jmp_reset_offset = tb->jmp_reset_offset; + if (TCG_TARGET_HAS_direct_jump) { + tcg_ctx->tb_jmp_insn_offset = tb->jmp_target_arg; + tcg_ctx->tb_jmp_target_addr = NULL; + } else { + tcg_ctx->tb_jmp_insn_offset = NULL; + tcg_ctx->tb_jmp_target_addr = tb->jmp_target_arg; + } + tcg_reg_alloc_start(s); /* From 344b63b380541a63c02ef7a8a6ae66cb0b6f0273 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sun, 6 Nov 2022 11:12:33 +1100 Subject: [PATCH 691/705] accel/tcg: Split out setjmp_gen_code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Isolate the code protected by setjmp. Fixes: translate-all.c: In function ‘tb_gen_code’: translate-all.c:748:51: error: argument ‘cflags’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Werror=clobbered] Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- accel/tcg/translate-all.c | 58 ++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 9ee21f7f52..ac3ee3740c 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -742,6 +742,37 @@ void page_collection_unlock(struct page_collection *set) #endif /* !CONFIG_USER_ONLY */ +/* + * Isolate the portion of code gen which can setjmp/longjmp. + * Return the size of the generated code, or negative on error. + */ +static int setjmp_gen_code(CPUArchState *env, TranslationBlock *tb, + target_ulong pc, void *host_pc, + int *max_insns, int64_t *ti) +{ + int ret = sigsetjmp(tcg_ctx->jmp_trans, 0); + if (unlikely(ret != 0)) { + return ret; + } + + tcg_func_start(tcg_ctx); + + tcg_ctx->cpu = env_cpu(env); + gen_intermediate_code(env_cpu(env), tb, *max_insns, pc, host_pc); + assert(tb->size != 0); + tcg_ctx->cpu = NULL; + *max_insns = tb->icount; + +#ifdef CONFIG_PROFILER + qatomic_set(&tcg_ctx->prof.tb_count, tcg_ctx->prof.tb_count + 1); + qatomic_set(&tcg_ctx->prof.interm_time, + tcg_ctx->prof.interm_time + profile_getclock() - *ti); + *ti = profile_getclock(); +#endif + + return tcg_gen_code(tcg_ctx, tb, pc); +} + /* Called with mmap_lock held for user mode emulation. */ TranslationBlock *tb_gen_code(CPUState *cpu, target_ulong pc, target_ulong cs_base, @@ -754,8 +785,8 @@ TranslationBlock *tb_gen_code(CPUState *cpu, int gen_code_size, search_size, max_insns; #ifdef CONFIG_PROFILER TCGProfile *prof = &tcg_ctx->prof; - int64_t ti; #endif + int64_t ti; void *host_pc; assert_memory_lock(); @@ -805,33 +836,10 @@ TranslationBlock *tb_gen_code(CPUState *cpu, ti = profile_getclock(); #endif - gen_code_size = sigsetjmp(tcg_ctx->jmp_trans, 0); - if (unlikely(gen_code_size != 0)) { - goto error_return; - } - - tcg_func_start(tcg_ctx); - - tcg_ctx->cpu = env_cpu(env); - gen_intermediate_code(cpu, tb, max_insns, pc, host_pc); - assert(tb->size != 0); - tcg_ctx->cpu = NULL; - max_insns = tb->icount; - trace_translate_block(tb, pc, tb->tc.ptr); - /* generate machine code */ - -#ifdef CONFIG_PROFILER - qatomic_set(&prof->tb_count, prof->tb_count + 1); - qatomic_set(&prof->interm_time, - prof->interm_time + profile_getclock() - ti); - ti = profile_getclock(); -#endif - - gen_code_size = tcg_gen_code(tcg_ctx, tb, pc); + gen_code_size = setjmp_gen_code(env, tb, pc, host_pc, &max_insns, &ti); if (unlikely(gen_code_size < 0)) { - error_return: switch (gen_code_size) { case -1: /* From 53a3b83259a7880982b3eddda31520ff0d8c9268 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 8 Nov 2022 08:52:06 -0500 Subject: [PATCH 692/705] checkpatch: typo fix remove inline #inline - it's an obvious typo. Should just be remove inline. Fixes: 1ef47f40dc ("checkpatch: better pattern for inline comments") Signed-off-by: Michael S. Tsirkin Message-Id: <20221108135155.1121566-1-mst@redhat.com> --- scripts/checkpatch.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index bc7d4780ec..6ecabfb2b5 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1682,7 +1682,7 @@ sub process { # Block comments use /* on a line of its own my $commentline = $rawline; - while ($commentline =~ s@^(\+.*)/\*.*\*/@$1@o) { # remove inline #inline /*...*/ + while ($commentline =~ s@^(\+.*)/\*.*\*/@$1@o) { # remove inline /*...*/ } if ($commentline =~ m@^\+.*/\*\*?+[ \t]*[^ \t]@) { # /* or /** non-blank WARN("Block comments use a leading /* on a separate line\n" . $herecurr); From 28cf39609603e4b5b2de8b74d4caa4d840425eff Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 9 Nov 2022 17:21:23 -0500 Subject: [PATCH 693/705] display: include dependencies explicitly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit acpi-vga-stub.c pulls in vga_int.h However that currently pulls in ui/console.h which breaks e.g. on systems without pixman. It's better to remove ui/console.h from vga_int.h and directly include it where it's used. Signed-off-by: Michael S. Tsirkin Message-Id: <20221109222112.74519-1-mst@redhat.com> Tested-by: Laurent Vivier Reported-by: Miroslav Rezanina Reported-by: Frederic Bezies Reported-by: Laurent Vivier Fixes: cfead31326 ("AcpiDevAmlIf interface to build VGA device descs") Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé --- hw/display/ati_2d.c | 1 + hw/display/cirrus_vga.c | 1 + hw/display/cirrus_vga_isa.c | 1 + hw/display/vga-isa.c | 1 + hw/display/vga-mmio.c | 1 + hw/display/vga-pci.c | 1 + hw/display/vga.c | 1 + hw/display/vga_int.h | 1 - hw/display/vmware_vga.c | 1 + include/qemu/typedefs.h | 2 ++ 10 files changed, 10 insertions(+), 1 deletion(-) diff --git a/hw/display/ati_2d.c b/hw/display/ati_2d.c index 692bec91de..7d786653e8 100644 --- a/hw/display/ati_2d.c +++ b/hw/display/ati_2d.c @@ -12,6 +12,7 @@ #include "ati_regs.h" #include "qemu/log.h" #include "ui/pixel_ops.h" +#include "ui/console.h" /* * NOTE: diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c index c1e719a405..6e8c747c46 100644 --- a/hw/display/cirrus_vga.c +++ b/hw/display/cirrus_vga.c @@ -45,6 +45,7 @@ #include "ui/pixel_ops.h" #include "cirrus_vga_internal.h" #include "qom/object.h" +#include "ui/console.h" /* * TODO: diff --git a/hw/display/cirrus_vga_isa.c b/hw/display/cirrus_vga_isa.c index 96144bd690..84be51670e 100644 --- a/hw/display/cirrus_vga_isa.c +++ b/hw/display/cirrus_vga_isa.c @@ -31,6 +31,7 @@ #include "hw/isa/isa.h" #include "cirrus_vga_internal.h" #include "qom/object.h" +#include "ui/console.h" #define TYPE_ISA_CIRRUS_VGA "isa-cirrus-vga" OBJECT_DECLARE_SIMPLE_TYPE(ISACirrusVGAState, ISA_CIRRUS_VGA) diff --git a/hw/display/vga-isa.c b/hw/display/vga-isa.c index 46abbc5653..2a5437d803 100644 --- a/hw/display/vga-isa.c +++ b/hw/display/vga-isa.c @@ -32,6 +32,7 @@ #include "qemu/timer.h" #include "hw/loader.h" #include "hw/qdev-properties.h" +#include "ui/console.h" #include "qom/object.h" #define TYPE_ISA_VGA "isa-vga" diff --git a/hw/display/vga-mmio.c b/hw/display/vga-mmio.c index 75dfcedea5..cd2c46776d 100644 --- a/hw/display/vga-mmio.c +++ b/hw/display/vga-mmio.c @@ -27,6 +27,7 @@ #include "hw/sysbus.h" #include "hw/display/vga.h" #include "hw/qdev-properties.h" +#include "ui/console.h" #include "vga_int.h" /* diff --git a/hw/display/vga-pci.c b/hw/display/vga-pci.c index 9a91de7ed1..df23dbf3a0 100644 --- a/hw/display/vga-pci.c +++ b/hw/display/vga-pci.c @@ -30,6 +30,7 @@ #include "migration/vmstate.h" #include "vga_int.h" #include "ui/pixel_ops.h" +#include "ui/console.h" #include "qemu/module.h" #include "qemu/timer.h" #include "hw/loader.h" diff --git a/hw/display/vga.c b/hw/display/vga.c index 50ecb1ad02..0cb26a791b 100644 --- a/hw/display/vga.c +++ b/hw/display/vga.c @@ -31,6 +31,7 @@ #include "vga_int.h" #include "vga_regs.h" #include "ui/pixel_ops.h" +#include "ui/console.h" #include "qemu/timer.h" #include "hw/xen/xen.h" #include "migration/vmstate.h" diff --git a/hw/display/vga_int.h b/hw/display/vga_int.h index 330406ad9c..7cf0d11201 100644 --- a/hw/display/vga_int.h +++ b/hw/display/vga_int.h @@ -27,7 +27,6 @@ #include "exec/ioport.h" #include "exec/memory.h" -#include "ui/console.h" #include "hw/display/bochs-vbe.h" #include "hw/acpi/acpi_aml_interface.h" diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c index cedbbde522..53949d2539 100644 --- a/hw/display/vmware_vga.c +++ b/hw/display/vmware_vga.c @@ -33,6 +33,7 @@ #include "hw/qdev-properties.h" #include "migration/vmstate.h" #include "qom/object.h" +#include "ui/console.h" #undef VERBOSE #define HW_RECT_ACCEL diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h index 6d4e6d9708..688408e048 100644 --- a/include/qemu/typedefs.h +++ b/include/qemu/typedefs.h @@ -132,6 +132,8 @@ typedef struct Visitor Visitor; typedef struct VMChangeStateEntry VMChangeStateEntry; typedef struct VMStateDescription VMStateDescription; typedef struct DumpState DumpState; +typedef struct GraphicHwOps GraphicHwOps; +typedef struct QEMUCursor QEMUCursor; /* * Pointer types From f47af0af0db5933664c621b8af8067ebbcbe66cd Mon Sep 17 00:00:00 2001 From: Xuan Zhuo Date: Thu, 10 Nov 2022 17:57:39 +0800 Subject: [PATCH 694/705] virtio-net: fix for heap-buffer-overflow Run shell script: cat << EOF | valgrind qemu-system-i386 -display none -machine accel=qtest, -m \ 512M -M q35 -nodefaults -device virtio-net,netdev=net0 -netdev \ user,id=net0 -qtest stdio outl 0xcf8 0x80000810 outl 0xcfc 0xc000 outl 0xcf8 0x80000804 outl 0xcfc 0x01 outl 0xc00d 0x0200 outl 0xcf8 0x80000890 outb 0xcfc 0x4 outl 0xcf8 0x80000889 outl 0xcfc 0x1c000000 outl 0xcf8 0x80000893 outw 0xcfc 0x100 EOF Got: ==68666== Invalid read of size 8 ==68666== at 0x688536: virtio_net_queue_enable (virtio-net.c:575) ==68666== by 0x6E31AE: memory_region_write_accessor (memory.c:492) ==68666== by 0x6E098D: access_with_adjusted_size (memory.c:554) ==68666== by 0x6E4DB3: memory_region_dispatch_write (memory.c:1521) ==68666== by 0x6E31AE: memory_region_write_accessor (memory.c:492) ==68666== by 0x6E098D: access_with_adjusted_size (memory.c:554) ==68666== by 0x6E4DB3: memory_region_dispatch_write (memory.c:1521) ==68666== by 0x6EBCD3: flatview_write_continue (physmem.c:2820) ==68666== by 0x6EBFBF: flatview_write (physmem.c:2862) ==68666== by 0x6EF5E7: address_space_write (physmem.c:2958) ==68666== by 0x6DFDEC: cpu_outw (ioport.c:70) ==68666== by 0x6F6DF0: qtest_process_command (qtest.c:480) ==68666== Address 0x29087fe8 is 24 bytes after a block of size 416 in arena "client" That is reported by Alexander Bulekov. https://gitlab.com/qemu-project/qemu/-/issues/1309 Here, the queue_index is the index of the cvq, but in some cases cvq does not have the corresponding NetClientState, so overflow appears. I add a check here, ignore illegal queue_index and cvq queue_index. Note the queue_index is below the VIRTIO_QUEUE_MAX but greater or equal than cvq index could hit this. Other devices are similar. Fixes: 7f863302 ("virtio-net: support queue_enable") Fixes: https://gitlab.com/qemu-project/qemu/-/issues/1309 Reported-by: Alexander Bulekov Signed-off-by: Xuan Zhuo Message-Id: <20221110095739.130393-1-xuanzhuo@linux.alibaba.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/net/virtio-net.c | 18 ++++++++++++++++-- include/hw/virtio/virtio.h | 2 ++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 8b32339b76..aba12759d5 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -549,7 +549,14 @@ static RxFilterInfo *virtio_net_query_rxfilter(NetClientState *nc) static void virtio_net_queue_reset(VirtIODevice *vdev, uint32_t queue_index) { VirtIONet *n = VIRTIO_NET(vdev); - NetClientState *nc = qemu_get_subqueue(n->nic, vq2q(queue_index)); + NetClientState *nc; + + /* validate queue_index and skip for cvq */ + if (queue_index >= n->max_queue_pairs * 2) { + return; + } + + nc = qemu_get_subqueue(n->nic, vq2q(queue_index)); if (!nc->peer) { return; @@ -566,9 +573,16 @@ static void virtio_net_queue_reset(VirtIODevice *vdev, uint32_t queue_index) static void virtio_net_queue_enable(VirtIODevice *vdev, uint32_t queue_index) { VirtIONet *n = VIRTIO_NET(vdev); - NetClientState *nc = qemu_get_subqueue(n->nic, vq2q(queue_index)); + NetClientState *nc; int r; + /* validate queue_index and skip for cvq */ + if (queue_index >= n->max_queue_pairs * 2) { + return; + } + + nc = qemu_get_subqueue(n->nic, vq2q(queue_index)); + if (!nc->peer || !vdev->vhost_started) { return; } diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 141a253a2c..a973811cbf 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -148,7 +148,9 @@ struct VirtioDeviceClass { void (*set_config)(VirtIODevice *vdev, const uint8_t *config); void (*reset)(VirtIODevice *vdev); void (*set_status)(VirtIODevice *vdev, uint8_t val); + /* Device must validate queue_index. */ void (*queue_reset)(VirtIODevice *vdev, uint32_t queue_index); + /* Device must validate queue_index. */ void (*queue_enable)(VirtIODevice *vdev, uint32_t queue_index); /* For transitional devices, this is a bitmap of features * that are only exposed on the legacy interface but not From ec5651340d445f009db1c2dc507da8cb4df85ad0 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Wed, 9 Nov 2022 13:22:10 +0100 Subject: [PATCH 695/705] hw/pci-host/pnv_phb: Avoid quitting QEMU if hotplug of pnv-phb-root-port fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently QEMU terminates if you try to hotplug pnv-phb-root-port in an environment where it is not supported, e.g. if doing this: echo "device_add pnv-phb-root-port" | \ ./qemu-system-ppc64 -monitor stdio -M powernv9 To avoid this problem, the pnv_phb_root_port_realize() function should not use error_fatal when trying to set the properties which might not be available. Fixes: c2f3f78af5 ("ppc/pnv: set root port chassis and slot using Bus properties") Signed-off-by: Thomas Huth Reviewed-by: Cédric Le Goater Reviewed-by: Daniel Henrique Barboza Message-Id: <20221109122210.115667-1-thuth@redhat.com> Signed-off-by: Daniel Henrique Barboza --- hw/pci-host/pnv_phb.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/hw/pci-host/pnv_phb.c b/hw/pci-host/pnv_phb.c index 7b11f1e8dd..0b26b43736 100644 --- a/hw/pci-host/pnv_phb.c +++ b/hw/pci-host/pnv_phb.c @@ -241,8 +241,16 @@ static void pnv_phb_root_port_realize(DeviceState *dev, Error **errp) * QOM id. 'chip_id' is going to be used as PCIE chassis for the * root port. */ - chip_id = object_property_get_int(OBJECT(bus), "chip-id", &error_fatal); - index = object_property_get_int(OBJECT(bus), "phb-id", &error_fatal); + chip_id = object_property_get_int(OBJECT(bus), "chip-id", &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + index = object_property_get_int(OBJECT(bus), "phb-id", &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } /* Set unique chassis/slot values for the root port */ qdev_prop_set_uint8(dev, "chassis", chip_id); From 7d7238c72b983cff5064734349d2d45be9c6282c Mon Sep 17 00:00:00 2001 From: Miroslav Rezanina Date: Wed, 9 Nov 2022 10:57:11 -0500 Subject: [PATCH 696/705] rtl8139: Remove unused variable Variable send_count used in rtl8139_cplus_transmit_one function is only incremented but never read. This causes 'Unused but set variable' warning on Clang 15.0.1 compiler. Removing the variable to prevent the warning. Signed-off-by: Miroslav Rezanina Reviewed-by: Thomas Huth Message-Id: <15a32dd06c492216cbf27cd3ddcbe1e9afb8d8f5.1668009030.git.mrezanin@redhat.com> Signed-off-by: Thomas Huth --- hw/net/rtl8139.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c index 6b65823b4b..e6643e3c9d 100644 --- a/hw/net/rtl8139.c +++ b/hw/net/rtl8139.c @@ -2156,7 +2156,6 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) ip_data_len, saved_size - ETH_HLEN, large_send_mss); int tcp_send_offset = 0; - int send_count = 0; /* maximum IP header length is 60 bytes */ uint8_t saved_ip_header[60]; @@ -2261,7 +2260,6 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) /* add transferred count to TCP sequence number */ stl_be_p(&p_tcp_hdr->th_seq, chunk_size + ldl_be_p(&p_tcp_hdr->th_seq)); - ++send_count; } /* Stop sending this frame */ From 6083dcad80743718620a3f8a72fb76ea8b7c28ca Mon Sep 17 00:00:00 2001 From: Miroslav Rezanina Date: Wed, 9 Nov 2022 10:57:12 -0500 Subject: [PATCH 697/705] tulip: Remove unused variable Variable n used in tulip_idblock_crc function is only incremented but never read. This causes 'Unused but set variable' warning on Clang 15.0.1 compiler. Removing the variable to prevent the warning. Signed-off-by: Miroslav Rezanina Reviewed-by: Thomas Huth Message-Id: <02e1560d115c208df32236df8916fed98429fda1.1668009030.git.mrezanin@redhat.com> Signed-off-by: Thomas Huth --- hw/net/tulip.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/hw/net/tulip.c b/hw/net/tulip.c index b9e42c322a..c2b3b1bdfa 100644 --- a/hw/net/tulip.c +++ b/hw/net/tulip.c @@ -870,11 +870,10 @@ static const MemoryRegionOps tulip_ops = { static void tulip_idblock_crc(TULIPState *s, uint16_t *srom) { - int word, n; + int word; int bit; unsigned char bitval, crc; const int len = 9; - n = 0; crc = -1; for (word = 0; word < len; word++) { @@ -887,7 +886,6 @@ static void tulip_idblock_crc(TULIPState *s, uint16_t *srom) srom[len - 1] = (srom[len - 1] & 0xff00) | (unsigned short)crc; break; } - n++; bitval = ((srom[word] >> bit) & 1) ^ ((crc >> 7) & 1); crc = crc << 1; if (bitval == 1) { From 0f48c47c679bc29fceb3a67283ee3b78175524bf Mon Sep 17 00:00:00 2001 From: Miroslav Rezanina Date: Wed, 9 Nov 2022 10:57:13 -0500 Subject: [PATCH 698/705] qemu-img: remove unused variable Variable block_count used in img_dd function is only incremented but never read. This causes 'Unused but set variable' warning on Clang 15.0.1 compiler. Removing the variable to prevent the warning. Signed-off-by: Miroslav Rezanina Reviewed-by: Thomas Huth Message-Id: Signed-off-by: Thomas Huth --- qemu-img.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qemu-img.c b/qemu-img.c index a3b64c88af..a9b3a8103c 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -4922,7 +4922,7 @@ static int img_dd(int argc, char **argv) const char *out_fmt = "raw"; const char *fmt = NULL; int64_t size = 0; - int64_t block_count = 0, out_pos, in_pos; + int64_t out_pos, in_pos; bool force_share = false; struct DdInfo dd = { .flags = 0, @@ -5122,7 +5122,7 @@ static int img_dd(int argc, char **argv) in.buf = g_new(uint8_t, in.bsz); - for (out_pos = 0; in_pos < size; block_count++) { + for (out_pos = 0; in_pos < size; ) { int bytes = (in_pos + in.bsz > size) ? size - in_pos : in.bsz; ret = blk_pread(blk1, in_pos, bytes, in.buf, 0); From 5ab8ba977d361ecb23cd42c1e5ecf2883e84de32 Mon Sep 17 00:00:00 2001 From: Miroslav Rezanina Date: Wed, 9 Nov 2022 10:57:14 -0500 Subject: [PATCH 699/705] host-libusb: Remove unused variable Variable unconnected used in usb_host_auto_check function is only incremented but never read as line where it is read was disabled since introducing the code. This causes 'Unused but set variable' warning on Clang 15.0.1 compiler. Removing the variable and disabled code to prevent the warning. Signed-off-by: Miroslav Rezanina Reviewed-by: Thomas Huth Message-Id: <00df0db69ff9167d38bac81f6d03281955bd861a.1668009030.git.mrezanin@redhat.com> Signed-off-by: Thomas Huth --- hw/usb/host-libusb.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c index 28f8af8941..176868d345 100644 --- a/hw/usb/host-libusb.c +++ b/hw/usb/host-libusb.c @@ -1837,7 +1837,6 @@ static void usb_host_auto_check(void *unused) struct USBAutoFilter *f; libusb_device **devs = NULL; struct libusb_device_descriptor ddesc; - int unconnected = 0; int i, n; if (usb_host_init() != 0) { @@ -1897,9 +1896,6 @@ static void usb_host_auto_check(void *unused) libusb_free_device_list(devs, 1); QTAILQ_FOREACH(s, &hostdevs, next) { - if (s->dh == NULL) { - unconnected++; - } if (s->seen == 0) { if (s->dh) { usb_host_close(s); @@ -1908,17 +1904,6 @@ static void usb_host_auto_check(void *unused) } s->seen = 0; } - -#if 0 - if (unconnected == 0) { - /* nothing to watch */ - if (usb_auto_timer) { - timer_del(usb_auto_timer); - trace_usb_host_auto_scan_disabled(); - } - return; - } -#endif } if (!usb_vmstate) { From b2a3cbb80c21f38f0cc626ddd642240d7194c8df Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Thu, 10 Nov 2022 14:11:12 +0100 Subject: [PATCH 700/705] libdecnumber/dpd/decimal64: Fix compiler warning from Clang 15 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clang 15 from Fedora 37 complains: ../libdecnumber/dpd/decimal64.c:620:8: error: variable 'n' set but not used [-Werror,-Wunused-but-set-variable] Int n; /* output bunch counter */ ^ 1 error generated. Remove the unused variable to silence the compiler warning. Message-Id: <20221110131112.104283-1-thuth@redhat.com> Reviewed-by: Cédric Le Goater Signed-off-by: Thomas Huth --- libdecnumber/dpd/decimal64.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libdecnumber/dpd/decimal64.c b/libdecnumber/dpd/decimal64.c index 4816176410..290dbe8177 100644 --- a/libdecnumber/dpd/decimal64.c +++ b/libdecnumber/dpd/decimal64.c @@ -617,7 +617,6 @@ static const uInt multies[]={131073, 26215, 5243, 1049, 210}; #endif void decDigitsToDPD(const decNumber *dn, uInt *targ, Int shift) { Int cut; /* work */ - Int n; /* output bunch counter */ Int digits=dn->digits; /* digit countdown */ uInt dpd; /* densely packed decimal value */ uInt bin; /* binary value 0-999 */ @@ -676,7 +675,7 @@ void decDigitsToDPD(const decNumber *dn, uInt *targ, Int shift) { bin=0; /* [keep compiler quiet] */ #endif - for(n=0; digits>0; n++) { /* each output bunch */ + while (digits > 0) { /* each output bunch */ #if DECDPUN==3 /* fast path, 3-at-a-time */ bin=*inu; /* 3 digits ready for convert */ digits-=3; /* [may go negative] */ From e0091133e3367265c08345afe2950c0c22e93d12 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Thu, 10 Nov 2022 09:36:26 +0100 Subject: [PATCH 701/705] qga: Allow building of the guest agent without system emulators or tools MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If configuring with "--disable-system --disable-user --enable-guest-agent" the linking currently fails with: qga/qemu-ga.p/commands.c.o: In function `qmp_command_info': build/../../home/thuth/devel/qemu/qga/commands.c:70: undefined reference to `qmp_command_name' build/../../home/thuth/devel/qemu/qga/commands.c:71: undefined reference to `qmp_command_is_enabled' build/../../home/thuth/devel/qemu/qga/commands.c:72: undefined reference to `qmp_has_success_response' qga/qemu-ga.p/commands.c.o: In function `qmp_guest_info': build/../../home/thuth/devel/qemu/qga/commands.c:82: undefined reference to `qmp_for_each_command' qga/qemu-ga.p/commands.c.o: In function `qmp_guest_exec': build/../../home/thuth/devel/qemu/qga/commands.c:410: undefined reference to `qbase64_decode' qga/qemu-ga.p/channel-posix.c.o: In function `ga_channel_open': build/../../home/thuth/devel/qemu/qga/channel-posix.c:214: undefined reference to `unix_listen' build/../../home/thuth/devel/qemu/qga/channel-posix.c:228: undefined reference to `socket_parse' build/../../home/thuth/devel/qemu/qga/channel-posix.c:234: undefined reference to `socket_listen' qga/qemu-ga.p/commands-posix.c.o: In function `qmp_guest_file_write': build/../../home/thuth/devel/qemu/qga/commands-posix.c:527: undefined reference to `qbase64_decode' Let's make sure that we also compile and link the required files if the system emulators have not been enabled. Message-Id: <20221110083626.31899-1-thuth@redhat.com> Tested-by: Philippe Mathieu-Daudé Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Thomas Huth --- qapi/meson.build | 2 +- stubs/meson.build | 2 +- util/meson.build | 20 ++++++++++++-------- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/qapi/meson.build b/qapi/meson.build index 9a36c15c04..fbdb442fdf 100644 --- a/qapi/meson.build +++ b/qapi/meson.build @@ -13,7 +13,7 @@ util_ss.add(files( if have_system util_ss.add(files('qapi-type-helpers.c')) endif -if have_system or have_tools +if have_system or have_tools or have_ga util_ss.add(files( 'qmp-dispatch.c', 'qmp-event.c', diff --git a/stubs/meson.build b/stubs/meson.build index 4314161f5f..c96a74f095 100644 --- a/stubs/meson.build +++ b/stubs/meson.build @@ -49,7 +49,7 @@ stub_ss.add(files('vmstate.c')) stub_ss.add(files('vm-stop.c')) stub_ss.add(files('win32-kbd-hook.c')) stub_ss.add(files('cpu-synchronize-state.c')) -if have_block +if have_block or have_ga stub_ss.add(files('replay-tools.c')) endif if have_system diff --git a/util/meson.build b/util/meson.build index 59c1f467bb..25b9b61f98 100644 --- a/util/meson.build +++ b/util/meson.build @@ -68,20 +68,25 @@ if have_system util_ss.add(when: 'CONFIG_LINUX', if_true: files('userfaultfd.c')) endif -if have_block - util_ss.add(files('aiocb.c', 'async.c', 'aio-wait.c')) +if have_block or have_ga + util_ss.add(files('aiocb.c', 'async.c')) util_ss.add(files('base64.c')) + util_ss.add(files('lockcnt.c')) + util_ss.add(files('main-loop.c')) + util_ss.add(files('qemu-coroutine.c', 'qemu-coroutine-lock.c', 'qemu-coroutine-io.c')) + util_ss.add(files('coroutine-@0@.c'.format(config_host['CONFIG_COROUTINE_BACKEND']))) + util_ss.add(files('thread-pool.c', 'qemu-timer.c')) + util_ss.add(files('qemu-sockets.c')) +endif +if have_block + util_ss.add(files('aio-wait.c')) util_ss.add(files('buffer.c')) util_ss.add(files('bufferiszero.c')) - util_ss.add(files('coroutine-@0@.c'.format(config_host['CONFIG_COROUTINE_BACKEND']))) util_ss.add(files('hbitmap.c')) util_ss.add(files('hexdump.c')) util_ss.add(files('iova-tree.c')) - util_ss.add(files('iov.c', 'qemu-sockets.c', 'uri.c')) - util_ss.add(files('lockcnt.c')) - util_ss.add(files('main-loop.c')) + util_ss.add(files('iov.c', 'uri.c')) util_ss.add(files('nvdimm-utils.c')) - util_ss.add(files('qemu-coroutine.c', 'qemu-coroutine-lock.c', 'qemu-coroutine-io.c')) util_ss.add(when: 'CONFIG_LINUX', if_true: [ files('vhost-user-server.c'), vhost_user ]) @@ -89,7 +94,6 @@ if have_block util_ss.add(files('qemu-coroutine-sleep.c')) util_ss.add(files('qemu-co-shared-resource.c')) util_ss.add(files('qemu-co-timeout.c')) - util_ss.add(files('thread-pool.c', 'qemu-timer.c')) util_ss.add(files('readline.c')) util_ss.add(files('throttle.c')) util_ss.add(files('timed-average.c')) From f469150be8d49649fa624b04c04795303aa635b1 Mon Sep 17 00:00:00 2001 From: Ahmed Abouzied Date: Mon, 14 Jun 2021 20:38:49 +0200 Subject: [PATCH 702/705] net: Replace TAB indentations with spaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces TABs with spaces, making sure to have a consistent coding style of 4 space indentations in the net subsystem. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/377 Signed-off-by: Ahmed Abouzied Message-Id: <20210614183849.20622-1-email@aabouzied.com> Reviewed-by: Philippe Mathieu-Daudé [thuth: Fixed mis-aligned indentation in some of the files] Signed-off-by: Thomas Huth --- hw/net/can/ctu_can_fd_frame.h | 180 ++--- hw/net/can/ctu_can_fd_regs.h | 1228 ++++++++++++++++----------------- hw/net/e1000_regs.h | 30 +- hw/net/mcf_fec.c | 8 +- hw/net/ne2000.c | 138 ++-- hw/net/pcnet.c | 136 ++-- hw/net/pcnet.h | 4 +- net/tap-linux.h | 10 +- 8 files changed, 867 insertions(+), 867 deletions(-) diff --git a/hw/net/can/ctu_can_fd_frame.h b/hw/net/can/ctu_can_fd_frame.h index 459c4a0ada..8c43fd99dd 100644 --- a/hw/net/can/ctu_can_fd_frame.h +++ b/hw/net/can/ctu_can_fd_frame.h @@ -34,156 +34,156 @@ /* CAN_Frame_format memory map */ enum ctu_can_fd_can_frame_format { - CTU_CAN_FD_FRAME_FORM_W = 0x0, - CTU_CAN_FD_IDENTIFIER_W = 0x4, - CTU_CAN_FD_TIMESTAMP_L_W = 0x8, - CTU_CAN_FD_TIMESTAMP_U_W = 0xc, - CTU_CAN_FD_DATA_1_4_W = 0x10, - CTU_CAN_FD_DATA_5_8_W = 0x14, - CTU_CAN_FD_DATA_61_64_W = 0x4c, + CTU_CAN_FD_FRAME_FORM_W = 0x0, + CTU_CAN_FD_IDENTIFIER_W = 0x4, + CTU_CAN_FD_TIMESTAMP_L_W = 0x8, + CTU_CAN_FD_TIMESTAMP_U_W = 0xc, + CTU_CAN_FD_DATA_1_4_W = 0x10, + CTU_CAN_FD_DATA_5_8_W = 0x14, + CTU_CAN_FD_DATA_61_64_W = 0x4c, }; /* Register descriptions: */ union ctu_can_fd_frame_form_w { - uint32_t u32; - struct ctu_can_fd_frame_form_w_s { + uint32_t u32; + struct ctu_can_fd_frame_form_w_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* FRAME_FORM_W */ - uint32_t dlc : 4; - uint32_t reserved_4 : 1; - uint32_t rtr : 1; - uint32_t ide : 1; - uint32_t fdf : 1; - uint32_t reserved_8 : 1; - uint32_t brs : 1; - uint32_t esi_rsv : 1; - uint32_t rwcnt : 5; - uint32_t reserved_31_16 : 16; + uint32_t dlc : 4; + uint32_t reserved_4 : 1; + uint32_t rtr : 1; + uint32_t ide : 1; + uint32_t fdf : 1; + uint32_t reserved_8 : 1; + uint32_t brs : 1; + uint32_t esi_rsv : 1; + uint32_t rwcnt : 5; + uint32_t reserved_31_16 : 16; #else - uint32_t reserved_31_16 : 16; - uint32_t rwcnt : 5; - uint32_t esi_rsv : 1; - uint32_t brs : 1; - uint32_t reserved_8 : 1; - uint32_t fdf : 1; - uint32_t ide : 1; - uint32_t rtr : 1; - uint32_t reserved_4 : 1; - uint32_t dlc : 4; + uint32_t reserved_31_16 : 16; + uint32_t rwcnt : 5; + uint32_t esi_rsv : 1; + uint32_t brs : 1; + uint32_t reserved_8 : 1; + uint32_t fdf : 1; + uint32_t ide : 1; + uint32_t rtr : 1; + uint32_t reserved_4 : 1; + uint32_t dlc : 4; #endif - } s; + } s; }; enum ctu_can_fd_frame_form_w_rtr { - NO_RTR_FRAME = 0x0, - RTR_FRAME = 0x1, + NO_RTR_FRAME = 0x0, + RTR_FRAME = 0x1, }; enum ctu_can_fd_frame_form_w_ide { - BASE = 0x0, - EXTENDED = 0x1, + BASE = 0x0, + EXTENDED = 0x1, }; enum ctu_can_fd_frame_form_w_fdf { - NORMAL_CAN = 0x0, - FD_CAN = 0x1, + NORMAL_CAN = 0x0, + FD_CAN = 0x1, }; enum ctu_can_fd_frame_form_w_brs { - BR_NO_SHIFT = 0x0, - BR_SHIFT = 0x1, + BR_NO_SHIFT = 0x0, + BR_SHIFT = 0x1, }; enum ctu_can_fd_frame_form_w_esi_rsv { - ESI_ERR_ACTIVE = 0x0, - ESI_ERR_PASIVE = 0x1, + ESI_ERR_ACTIVE = 0x0, + ESI_ERR_PASIVE = 0x1, }; union ctu_can_fd_identifier_w { - uint32_t u32; - struct ctu_can_fd_identifier_w_s { + uint32_t u32; + struct ctu_can_fd_identifier_w_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* IDENTIFIER_W */ - uint32_t identifier_ext : 18; - uint32_t identifier_base : 11; - uint32_t reserved_31_29 : 3; + uint32_t identifier_ext : 18; + uint32_t identifier_base : 11; + uint32_t reserved_31_29 : 3; #else - uint32_t reserved_31_29 : 3; - uint32_t identifier_base : 11; - uint32_t identifier_ext : 18; + uint32_t reserved_31_29 : 3; + uint32_t identifier_base : 11; + uint32_t identifier_ext : 18; #endif - } s; + } s; }; union ctu_can_fd_timestamp_l_w { - uint32_t u32; - struct ctu_can_fd_timestamp_l_w_s { + uint32_t u32; + struct ctu_can_fd_timestamp_l_w_s { /* TIMESTAMP_L_W */ - uint32_t time_stamp_31_0 : 32; - } s; + uint32_t time_stamp_31_0 : 32; + } s; }; union ctu_can_fd_timestamp_u_w { - uint32_t u32; - struct ctu_can_fd_timestamp_u_w_s { + uint32_t u32; + struct ctu_can_fd_timestamp_u_w_s { /* TIMESTAMP_U_W */ - uint32_t timestamp_l_w : 32; - } s; + uint32_t timestamp_l_w : 32; + } s; }; union ctu_can_fd_data_1_4_w { - uint32_t u32; - struct ctu_can_fd_data_1_4_w_s { + uint32_t u32; + struct ctu_can_fd_data_1_4_w_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* DATA_1_4_W */ - uint32_t data_1 : 8; - uint32_t data_2 : 8; - uint32_t data_3 : 8; - uint32_t data_4 : 8; + uint32_t data_1 : 8; + uint32_t data_2 : 8; + uint32_t data_3 : 8; + uint32_t data_4 : 8; #else - uint32_t data_4 : 8; - uint32_t data_3 : 8; - uint32_t data_2 : 8; - uint32_t data_1 : 8; + uint32_t data_4 : 8; + uint32_t data_3 : 8; + uint32_t data_2 : 8; + uint32_t data_1 : 8; #endif - } s; + } s; }; union ctu_can_fd_data_5_8_w { - uint32_t u32; - struct ctu_can_fd_data_5_8_w_s { + uint32_t u32; + struct ctu_can_fd_data_5_8_w_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* DATA_5_8_W */ - uint32_t data_5 : 8; - uint32_t data_6 : 8; - uint32_t data_7 : 8; - uint32_t data_8 : 8; + uint32_t data_5 : 8; + uint32_t data_6 : 8; + uint32_t data_7 : 8; + uint32_t data_8 : 8; #else - uint32_t data_8 : 8; - uint32_t data_7 : 8; - uint32_t data_6 : 8; - uint32_t data_5 : 8; + uint32_t data_8 : 8; + uint32_t data_7 : 8; + uint32_t data_6 : 8; + uint32_t data_5 : 8; #endif - } s; + } s; }; union ctu_can_fd_data_61_64_w { - uint32_t u32; - struct ctu_can_fd_data_61_64_w_s { + uint32_t u32; + struct ctu_can_fd_data_61_64_w_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* DATA_61_64_W */ - uint32_t data_61 : 8; - uint32_t data_62 : 8; - uint32_t data_63 : 8; - uint32_t data_64 : 8; + uint32_t data_61 : 8; + uint32_t data_62 : 8; + uint32_t data_63 : 8; + uint32_t data_64 : 8; #else - uint32_t data_64 : 8; - uint32_t data_63 : 8; - uint32_t data_62 : 8; - uint32_t data_61 : 8; + uint32_t data_64 : 8; + uint32_t data_63 : 8; + uint32_t data_62 : 8; + uint32_t data_61 : 8; #endif - } s; + } s; }; #endif diff --git a/hw/net/can/ctu_can_fd_regs.h b/hw/net/can/ctu_can_fd_regs.h index 57859b87bc..d2d88cdd1a 100644 --- a/hw/net/can/ctu_can_fd_regs.h +++ b/hw/net/can/ctu_can_fd_regs.h @@ -34,938 +34,938 @@ /* CAN_Registers memory map */ enum ctu_can_fd_can_registers { - CTU_CAN_FD_DEVICE_ID = 0x0, - CTU_CAN_FD_VERSION = 0x2, - CTU_CAN_FD_MODE = 0x4, - CTU_CAN_FD_SETTINGS = 0x6, - CTU_CAN_FD_STATUS = 0x8, - CTU_CAN_FD_COMMAND = 0xc, - CTU_CAN_FD_INT_STAT = 0x10, - CTU_CAN_FD_INT_ENA_SET = 0x14, - CTU_CAN_FD_INT_ENA_CLR = 0x18, - CTU_CAN_FD_INT_MASK_SET = 0x1c, - CTU_CAN_FD_INT_MASK_CLR = 0x20, - CTU_CAN_FD_BTR = 0x24, - CTU_CAN_FD_BTR_FD = 0x28, - CTU_CAN_FD_EWL = 0x2c, - CTU_CAN_FD_ERP = 0x2d, - CTU_CAN_FD_FAULT_STATE = 0x2e, - CTU_CAN_FD_REC = 0x30, - CTU_CAN_FD_TEC = 0x32, - CTU_CAN_FD_ERR_NORM = 0x34, - CTU_CAN_FD_ERR_FD = 0x36, - CTU_CAN_FD_CTR_PRES = 0x38, - CTU_CAN_FD_FILTER_A_MASK = 0x3c, - CTU_CAN_FD_FILTER_A_VAL = 0x40, - CTU_CAN_FD_FILTER_B_MASK = 0x44, - CTU_CAN_FD_FILTER_B_VAL = 0x48, - CTU_CAN_FD_FILTER_C_MASK = 0x4c, - CTU_CAN_FD_FILTER_C_VAL = 0x50, - CTU_CAN_FD_FILTER_RAN_LOW = 0x54, - CTU_CAN_FD_FILTER_RAN_HIGH = 0x58, - CTU_CAN_FD_FILTER_CONTROL = 0x5c, - CTU_CAN_FD_FILTER_STATUS = 0x5e, - CTU_CAN_FD_RX_MEM_INFO = 0x60, - CTU_CAN_FD_RX_POINTERS = 0x64, - CTU_CAN_FD_RX_STATUS = 0x68, - CTU_CAN_FD_RX_SETTINGS = 0x6a, - CTU_CAN_FD_RX_DATA = 0x6c, - CTU_CAN_FD_TX_STATUS = 0x70, - CTU_CAN_FD_TX_COMMAND = 0x74, - CTU_CAN_FD_TX_PRIORITY = 0x78, - CTU_CAN_FD_ERR_CAPT = 0x7c, - CTU_CAN_FD_ALC = 0x7e, - CTU_CAN_FD_TRV_DELAY = 0x80, - CTU_CAN_FD_SSP_CFG = 0x82, - CTU_CAN_FD_RX_FR_CTR = 0x84, - CTU_CAN_FD_TX_FR_CTR = 0x88, - CTU_CAN_FD_DEBUG_REGISTER = 0x8c, - CTU_CAN_FD_YOLO_REG = 0x90, - CTU_CAN_FD_TIMESTAMP_LOW = 0x94, - CTU_CAN_FD_TIMESTAMP_HIGH = 0x98, - CTU_CAN_FD_TXTB1_DATA_1 = 0x100, - CTU_CAN_FD_TXTB1_DATA_2 = 0x104, - CTU_CAN_FD_TXTB1_DATA_20 = 0x14c, - CTU_CAN_FD_TXTB2_DATA_1 = 0x200, - CTU_CAN_FD_TXTB2_DATA_2 = 0x204, - CTU_CAN_FD_TXTB2_DATA_20 = 0x24c, - CTU_CAN_FD_TXTB3_DATA_1 = 0x300, - CTU_CAN_FD_TXTB3_DATA_2 = 0x304, - CTU_CAN_FD_TXTB3_DATA_20 = 0x34c, - CTU_CAN_FD_TXTB4_DATA_1 = 0x400, - CTU_CAN_FD_TXTB4_DATA_2 = 0x404, - CTU_CAN_FD_TXTB4_DATA_20 = 0x44c, + CTU_CAN_FD_DEVICE_ID = 0x0, + CTU_CAN_FD_VERSION = 0x2, + CTU_CAN_FD_MODE = 0x4, + CTU_CAN_FD_SETTINGS = 0x6, + CTU_CAN_FD_STATUS = 0x8, + CTU_CAN_FD_COMMAND = 0xc, + CTU_CAN_FD_INT_STAT = 0x10, + CTU_CAN_FD_INT_ENA_SET = 0x14, + CTU_CAN_FD_INT_ENA_CLR = 0x18, + CTU_CAN_FD_INT_MASK_SET = 0x1c, + CTU_CAN_FD_INT_MASK_CLR = 0x20, + CTU_CAN_FD_BTR = 0x24, + CTU_CAN_FD_BTR_FD = 0x28, + CTU_CAN_FD_EWL = 0x2c, + CTU_CAN_FD_ERP = 0x2d, + CTU_CAN_FD_FAULT_STATE = 0x2e, + CTU_CAN_FD_REC = 0x30, + CTU_CAN_FD_TEC = 0x32, + CTU_CAN_FD_ERR_NORM = 0x34, + CTU_CAN_FD_ERR_FD = 0x36, + CTU_CAN_FD_CTR_PRES = 0x38, + CTU_CAN_FD_FILTER_A_MASK = 0x3c, + CTU_CAN_FD_FILTER_A_VAL = 0x40, + CTU_CAN_FD_FILTER_B_MASK = 0x44, + CTU_CAN_FD_FILTER_B_VAL = 0x48, + CTU_CAN_FD_FILTER_C_MASK = 0x4c, + CTU_CAN_FD_FILTER_C_VAL = 0x50, + CTU_CAN_FD_FILTER_RAN_LOW = 0x54, + CTU_CAN_FD_FILTER_RAN_HIGH = 0x58, + CTU_CAN_FD_FILTER_CONTROL = 0x5c, + CTU_CAN_FD_FILTER_STATUS = 0x5e, + CTU_CAN_FD_RX_MEM_INFO = 0x60, + CTU_CAN_FD_RX_POINTERS = 0x64, + CTU_CAN_FD_RX_STATUS = 0x68, + CTU_CAN_FD_RX_SETTINGS = 0x6a, + CTU_CAN_FD_RX_DATA = 0x6c, + CTU_CAN_FD_TX_STATUS = 0x70, + CTU_CAN_FD_TX_COMMAND = 0x74, + CTU_CAN_FD_TX_PRIORITY = 0x78, + CTU_CAN_FD_ERR_CAPT = 0x7c, + CTU_CAN_FD_ALC = 0x7e, + CTU_CAN_FD_TRV_DELAY = 0x80, + CTU_CAN_FD_SSP_CFG = 0x82, + CTU_CAN_FD_RX_FR_CTR = 0x84, + CTU_CAN_FD_TX_FR_CTR = 0x88, + CTU_CAN_FD_DEBUG_REGISTER = 0x8c, + CTU_CAN_FD_YOLO_REG = 0x90, + CTU_CAN_FD_TIMESTAMP_LOW = 0x94, + CTU_CAN_FD_TIMESTAMP_HIGH = 0x98, + CTU_CAN_FD_TXTB1_DATA_1 = 0x100, + CTU_CAN_FD_TXTB1_DATA_2 = 0x104, + CTU_CAN_FD_TXTB1_DATA_20 = 0x14c, + CTU_CAN_FD_TXTB2_DATA_1 = 0x200, + CTU_CAN_FD_TXTB2_DATA_2 = 0x204, + CTU_CAN_FD_TXTB2_DATA_20 = 0x24c, + CTU_CAN_FD_TXTB3_DATA_1 = 0x300, + CTU_CAN_FD_TXTB3_DATA_2 = 0x304, + CTU_CAN_FD_TXTB3_DATA_20 = 0x34c, + CTU_CAN_FD_TXTB4_DATA_1 = 0x400, + CTU_CAN_FD_TXTB4_DATA_2 = 0x404, + CTU_CAN_FD_TXTB4_DATA_20 = 0x44c, }; /* Register descriptions: */ union ctu_can_fd_device_id_version { - uint32_t u32; - struct ctu_can_fd_device_id_version_s { + uint32_t u32; + struct ctu_can_fd_device_id_version_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* DEVICE_ID */ - uint32_t device_id : 16; + uint32_t device_id : 16; /* VERSION */ - uint32_t ver_minor : 8; - uint32_t ver_major : 8; + uint32_t ver_minor : 8; + uint32_t ver_major : 8; #else - uint32_t ver_major : 8; - uint32_t ver_minor : 8; - uint32_t device_id : 16; + uint32_t ver_major : 8; + uint32_t ver_minor : 8; + uint32_t device_id : 16; #endif - } s; + } s; }; enum ctu_can_fd_device_id_device_id { - CTU_CAN_FD_ID = 0xcafd, + CTU_CAN_FD_ID = 0xcafd, }; union ctu_can_fd_mode_settings { - uint32_t u32; - struct ctu_can_fd_mode_settings_s { + uint32_t u32; + struct ctu_can_fd_mode_settings_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* MODE */ - uint32_t rst : 1; - uint32_t lom : 1; - uint32_t stm : 1; - uint32_t afm : 1; - uint32_t fde : 1; - uint32_t reserved_6_5 : 2; - uint32_t acf : 1; - uint32_t tstm : 1; - uint32_t reserved_15_9 : 7; + uint32_t rst : 1; + uint32_t lom : 1; + uint32_t stm : 1; + uint32_t afm : 1; + uint32_t fde : 1; + uint32_t reserved_6_5 : 2; + uint32_t acf : 1; + uint32_t tstm : 1; + uint32_t reserved_15_9 : 7; /* SETTINGS */ - uint32_t rtrle : 1; - uint32_t rtrth : 4; - uint32_t ilbp : 1; - uint32_t ena : 1; - uint32_t nisofd : 1; - uint32_t pex : 1; - uint32_t reserved_31_25 : 7; + uint32_t rtrle : 1; + uint32_t rtrth : 4; + uint32_t ilbp : 1; + uint32_t ena : 1; + uint32_t nisofd : 1; + uint32_t pex : 1; + uint32_t reserved_31_25 : 7; #else - uint32_t reserved_31_25 : 7; - uint32_t pex : 1; - uint32_t nisofd : 1; - uint32_t ena : 1; - uint32_t ilbp : 1; - uint32_t rtrth : 4; - uint32_t rtrle : 1; - uint32_t reserved_15_9 : 7; - uint32_t tstm : 1; - uint32_t acf : 1; - uint32_t reserved_6_5 : 2; - uint32_t fde : 1; - uint32_t afm : 1; - uint32_t stm : 1; - uint32_t lom : 1; - uint32_t rst : 1; + uint32_t reserved_31_25 : 7; + uint32_t pex : 1; + uint32_t nisofd : 1; + uint32_t ena : 1; + uint32_t ilbp : 1; + uint32_t rtrth : 4; + uint32_t rtrle : 1; + uint32_t reserved_15_9 : 7; + uint32_t tstm : 1; + uint32_t acf : 1; + uint32_t reserved_6_5 : 2; + uint32_t fde : 1; + uint32_t afm : 1; + uint32_t stm : 1; + uint32_t lom : 1; + uint32_t rst : 1; #endif - } s; + } s; }; enum ctu_can_fd_mode_lom { - LOM_DISABLED = 0x0, - LOM_ENABLED = 0x1, + LOM_DISABLED = 0x0, + LOM_ENABLED = 0x1, }; enum ctu_can_fd_mode_stm { - STM_DISABLED = 0x0, - STM_ENABLED = 0x1, + STM_DISABLED = 0x0, + STM_ENABLED = 0x1, }; enum ctu_can_fd_mode_afm { - AFM_DISABLED = 0x0, - AFM_ENABLED = 0x1, + AFM_DISABLED = 0x0, + AFM_ENABLED = 0x1, }; enum ctu_can_fd_mode_fde { - FDE_DISABLE = 0x0, - FDE_ENABLE = 0x1, + FDE_DISABLE = 0x0, + FDE_ENABLE = 0x1, }; enum ctu_can_fd_mode_acf { - ACF_DISABLED = 0x0, - ACF_ENABLED = 0x1, + ACF_DISABLED = 0x0, + ACF_ENABLED = 0x1, }; enum ctu_can_fd_settings_rtrle { - RTRLE_DISABLED = 0x0, - RTRLE_ENABLED = 0x1, + RTRLE_DISABLED = 0x0, + RTRLE_ENABLED = 0x1, }; enum ctu_can_fd_settings_ilbp { - INT_LOOP_DISABLED = 0x0, - INT_LOOP_ENABLED = 0x1, + INT_LOOP_DISABLED = 0x0, + INT_LOOP_ENABLED = 0x1, }; enum ctu_can_fd_settings_ena { - CTU_CAN_DISABLED = 0x0, - CTU_CAN_ENABLED = 0x1, + CTU_CAN_DISABLED = 0x0, + CTU_CAN_ENABLED = 0x1, }; enum ctu_can_fd_settings_nisofd { - ISO_FD = 0x0, - NON_ISO_FD = 0x1, + ISO_FD = 0x0, + NON_ISO_FD = 0x1, }; enum ctu_can_fd_settings_pex { - PROTOCOL_EXCEPTION_DISABLED = 0x0, - PROTOCOL_EXCEPTION_ENABLED = 0x1, + PROTOCOL_EXCEPTION_DISABLED = 0x0, + PROTOCOL_EXCEPTION_ENABLED = 0x1, }; union ctu_can_fd_status { - uint32_t u32; - struct ctu_can_fd_status_s { + uint32_t u32; + struct ctu_can_fd_status_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* STATUS */ - uint32_t rxne : 1; - uint32_t dor : 1; - uint32_t txnf : 1; - uint32_t eft : 1; - uint32_t rxs : 1; - uint32_t txs : 1; - uint32_t ewl : 1; - uint32_t idle : 1; - uint32_t reserved_31_8 : 24; + uint32_t rxne : 1; + uint32_t dor : 1; + uint32_t txnf : 1; + uint32_t eft : 1; + uint32_t rxs : 1; + uint32_t txs : 1; + uint32_t ewl : 1; + uint32_t idle : 1; + uint32_t reserved_31_8 : 24; #else - uint32_t reserved_31_8 : 24; - uint32_t idle : 1; - uint32_t ewl : 1; - uint32_t txs : 1; - uint32_t rxs : 1; - uint32_t eft : 1; - uint32_t txnf : 1; - uint32_t dor : 1; - uint32_t rxne : 1; + uint32_t reserved_31_8 : 24; + uint32_t idle : 1; + uint32_t ewl : 1; + uint32_t txs : 1; + uint32_t rxs : 1; + uint32_t eft : 1; + uint32_t txnf : 1; + uint32_t dor : 1; + uint32_t rxne : 1; #endif - } s; + } s; }; union ctu_can_fd_command { - uint32_t u32; - struct ctu_can_fd_command_s { + uint32_t u32; + struct ctu_can_fd_command_s { #ifdef __LITTLE_ENDIAN_BITFIELD - uint32_t reserved_1_0 : 2; + uint32_t reserved_1_0 : 2; /* COMMAND */ - uint32_t rrb : 1; - uint32_t cdo : 1; - uint32_t ercrst : 1; - uint32_t rxfcrst : 1; - uint32_t txfcrst : 1; - uint32_t reserved_31_7 : 25; + uint32_t rrb : 1; + uint32_t cdo : 1; + uint32_t ercrst : 1; + uint32_t rxfcrst : 1; + uint32_t txfcrst : 1; + uint32_t reserved_31_7 : 25; #else - uint32_t reserved_31_7 : 25; - uint32_t txfcrst : 1; - uint32_t rxfcrst : 1; - uint32_t ercrst : 1; - uint32_t cdo : 1; - uint32_t rrb : 1; - uint32_t reserved_1_0 : 2; + uint32_t reserved_31_7 : 25; + uint32_t txfcrst : 1; + uint32_t rxfcrst : 1; + uint32_t ercrst : 1; + uint32_t cdo : 1; + uint32_t rrb : 1; + uint32_t reserved_1_0 : 2; #endif - } s; + } s; }; union ctu_can_fd_int_stat { - uint32_t u32; - struct ctu_can_fd_int_stat_s { + uint32_t u32; + struct ctu_can_fd_int_stat_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* INT_STAT */ - uint32_t rxi : 1; - uint32_t txi : 1; - uint32_t ewli : 1; - uint32_t doi : 1; - uint32_t fcsi : 1; - uint32_t ali : 1; - uint32_t bei : 1; - uint32_t ofi : 1; - uint32_t rxfi : 1; - uint32_t bsi : 1; - uint32_t rbnei : 1; - uint32_t txbhci : 1; - uint32_t reserved_31_12 : 20; + uint32_t rxi : 1; + uint32_t txi : 1; + uint32_t ewli : 1; + uint32_t doi : 1; + uint32_t fcsi : 1; + uint32_t ali : 1; + uint32_t bei : 1; + uint32_t ofi : 1; + uint32_t rxfi : 1; + uint32_t bsi : 1; + uint32_t rbnei : 1; + uint32_t txbhci : 1; + uint32_t reserved_31_12 : 20; #else - uint32_t reserved_31_12 : 20; - uint32_t txbhci : 1; - uint32_t rbnei : 1; - uint32_t bsi : 1; - uint32_t rxfi : 1; - uint32_t ofi : 1; - uint32_t bei : 1; - uint32_t ali : 1; - uint32_t fcsi : 1; - uint32_t doi : 1; - uint32_t ewli : 1; - uint32_t txi : 1; - uint32_t rxi : 1; + uint32_t reserved_31_12 : 20; + uint32_t txbhci : 1; + uint32_t rbnei : 1; + uint32_t bsi : 1; + uint32_t rxfi : 1; + uint32_t ofi : 1; + uint32_t bei : 1; + uint32_t ali : 1; + uint32_t fcsi : 1; + uint32_t doi : 1; + uint32_t ewli : 1; + uint32_t txi : 1; + uint32_t rxi : 1; #endif - } s; + } s; }; union ctu_can_fd_int_ena_set { - uint32_t u32; - struct ctu_can_fd_int_ena_set_s { + uint32_t u32; + struct ctu_can_fd_int_ena_set_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* INT_ENA_SET */ - uint32_t int_ena_set : 12; - uint32_t reserved_31_12 : 20; + uint32_t int_ena_set : 12; + uint32_t reserved_31_12 : 20; #else - uint32_t reserved_31_12 : 20; - uint32_t int_ena_set : 12; + uint32_t reserved_31_12 : 20; + uint32_t int_ena_set : 12; #endif - } s; + } s; }; union ctu_can_fd_int_ena_clr { - uint32_t u32; - struct ctu_can_fd_int_ena_clr_s { + uint32_t u32; + struct ctu_can_fd_int_ena_clr_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* INT_ENA_CLR */ - uint32_t int_ena_clr : 12; - uint32_t reserved_31_12 : 20; + uint32_t int_ena_clr : 12; + uint32_t reserved_31_12 : 20; #else - uint32_t reserved_31_12 : 20; - uint32_t int_ena_clr : 12; + uint32_t reserved_31_12 : 20; + uint32_t int_ena_clr : 12; #endif - } s; + } s; }; union ctu_can_fd_int_mask_set { - uint32_t u32; - struct ctu_can_fd_int_mask_set_s { + uint32_t u32; + struct ctu_can_fd_int_mask_set_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* INT_MASK_SET */ - uint32_t int_mask_set : 12; - uint32_t reserved_31_12 : 20; + uint32_t int_mask_set : 12; + uint32_t reserved_31_12 : 20; #else - uint32_t reserved_31_12 : 20; - uint32_t int_mask_set : 12; + uint32_t reserved_31_12 : 20; + uint32_t int_mask_set : 12; #endif - } s; + } s; }; union ctu_can_fd_int_mask_clr { - uint32_t u32; - struct ctu_can_fd_int_mask_clr_s { + uint32_t u32; + struct ctu_can_fd_int_mask_clr_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* INT_MASK_CLR */ - uint32_t int_mask_clr : 12; - uint32_t reserved_31_12 : 20; + uint32_t int_mask_clr : 12; + uint32_t reserved_31_12 : 20; #else - uint32_t reserved_31_12 : 20; - uint32_t int_mask_clr : 12; + uint32_t reserved_31_12 : 20; + uint32_t int_mask_clr : 12; #endif - } s; + } s; }; union ctu_can_fd_btr { - uint32_t u32; - struct ctu_can_fd_btr_s { + uint32_t u32; + struct ctu_can_fd_btr_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* BTR */ - uint32_t prop : 7; - uint32_t ph1 : 6; - uint32_t ph2 : 6; - uint32_t brp : 8; - uint32_t sjw : 5; + uint32_t prop : 7; + uint32_t ph1 : 6; + uint32_t ph2 : 6; + uint32_t brp : 8; + uint32_t sjw : 5; #else - uint32_t sjw : 5; - uint32_t brp : 8; - uint32_t ph2 : 6; - uint32_t ph1 : 6; - uint32_t prop : 7; + uint32_t sjw : 5; + uint32_t brp : 8; + uint32_t ph2 : 6; + uint32_t ph1 : 6; + uint32_t prop : 7; #endif - } s; + } s; }; union ctu_can_fd_btr_fd { - uint32_t u32; - struct ctu_can_fd_btr_fd_s { + uint32_t u32; + struct ctu_can_fd_btr_fd_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* BTR_FD */ - uint32_t prop_fd : 6; - uint32_t reserved_6 : 1; - uint32_t ph1_fd : 5; - uint32_t reserved_12 : 1; - uint32_t ph2_fd : 5; - uint32_t reserved_18 : 1; - uint32_t brp_fd : 8; - uint32_t sjw_fd : 5; + uint32_t prop_fd : 6; + uint32_t reserved_6 : 1; + uint32_t ph1_fd : 5; + uint32_t reserved_12 : 1; + uint32_t ph2_fd : 5; + uint32_t reserved_18 : 1; + uint32_t brp_fd : 8; + uint32_t sjw_fd : 5; #else - uint32_t sjw_fd : 5; - uint32_t brp_fd : 8; - uint32_t reserved_18 : 1; - uint32_t ph2_fd : 5; - uint32_t reserved_12 : 1; - uint32_t ph1_fd : 5; - uint32_t reserved_6 : 1; - uint32_t prop_fd : 6; + uint32_t sjw_fd : 5; + uint32_t brp_fd : 8; + uint32_t reserved_18 : 1; + uint32_t ph2_fd : 5; + uint32_t reserved_12 : 1; + uint32_t ph1_fd : 5; + uint32_t reserved_6 : 1; + uint32_t prop_fd : 6; #endif - } s; + } s; }; union ctu_can_fd_ewl_erp_fault_state { - uint32_t u32; - struct ctu_can_fd_ewl_erp_fault_state_s { + uint32_t u32; + struct ctu_can_fd_ewl_erp_fault_state_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* EWL */ - uint32_t ew_limit : 8; + uint32_t ew_limit : 8; /* ERP */ - uint32_t erp_limit : 8; + uint32_t erp_limit : 8; /* FAULT_STATE */ - uint32_t era : 1; - uint32_t erp : 1; - uint32_t bof : 1; - uint32_t reserved_31_19 : 13; + uint32_t era : 1; + uint32_t erp : 1; + uint32_t bof : 1; + uint32_t reserved_31_19 : 13; #else - uint32_t reserved_31_19 : 13; - uint32_t bof : 1; - uint32_t erp : 1; - uint32_t era : 1; - uint32_t erp_limit : 8; - uint32_t ew_limit : 8; + uint32_t reserved_31_19 : 13; + uint32_t bof : 1; + uint32_t erp : 1; + uint32_t era : 1; + uint32_t erp_limit : 8; + uint32_t ew_limit : 8; #endif - } s; + } s; }; union ctu_can_fd_rec_tec { - uint32_t u32; - struct ctu_can_fd_rec_tec_s { + uint32_t u32; + struct ctu_can_fd_rec_tec_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* REC */ - uint32_t rec_val : 9; - uint32_t reserved_15_9 : 7; + uint32_t rec_val : 9; + uint32_t reserved_15_9 : 7; /* TEC */ - uint32_t tec_val : 9; - uint32_t reserved_31_25 : 7; + uint32_t tec_val : 9; + uint32_t reserved_31_25 : 7; #else - uint32_t reserved_31_25 : 7; - uint32_t tec_val : 9; - uint32_t reserved_15_9 : 7; - uint32_t rec_val : 9; + uint32_t reserved_31_25 : 7; + uint32_t tec_val : 9; + uint32_t reserved_15_9 : 7; + uint32_t rec_val : 9; #endif - } s; + } s; }; union ctu_can_fd_err_norm_err_fd { - uint32_t u32; - struct ctu_can_fd_err_norm_err_fd_s { + uint32_t u32; + struct ctu_can_fd_err_norm_err_fd_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* ERR_NORM */ - uint32_t err_norm_val : 16; + uint32_t err_norm_val : 16; /* ERR_FD */ - uint32_t err_fd_val : 16; + uint32_t err_fd_val : 16; #else - uint32_t err_fd_val : 16; - uint32_t err_norm_val : 16; + uint32_t err_fd_val : 16; + uint32_t err_norm_val : 16; #endif - } s; + } s; }; union ctu_can_fd_ctr_pres { - uint32_t u32; - struct ctu_can_fd_ctr_pres_s { + uint32_t u32; + struct ctu_can_fd_ctr_pres_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* CTR_PRES */ - uint32_t ctpv : 9; - uint32_t ptx : 1; - uint32_t prx : 1; - uint32_t enorm : 1; - uint32_t efd : 1; - uint32_t reserved_31_13 : 19; + uint32_t ctpv : 9; + uint32_t ptx : 1; + uint32_t prx : 1; + uint32_t enorm : 1; + uint32_t efd : 1; + uint32_t reserved_31_13 : 19; #else - uint32_t reserved_31_13 : 19; - uint32_t efd : 1; - uint32_t enorm : 1; - uint32_t prx : 1; - uint32_t ptx : 1; - uint32_t ctpv : 9; + uint32_t reserved_31_13 : 19; + uint32_t efd : 1; + uint32_t enorm : 1; + uint32_t prx : 1; + uint32_t ptx : 1; + uint32_t ctpv : 9; #endif - } s; + } s; }; union ctu_can_fd_filter_a_mask { - uint32_t u32; - struct ctu_can_fd_filter_a_mask_s { + uint32_t u32; + struct ctu_can_fd_filter_a_mask_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* FILTER_A_MASK */ - uint32_t bit_mask_a_val : 29; - uint32_t reserved_31_29 : 3; + uint32_t bit_mask_a_val : 29; + uint32_t reserved_31_29 : 3; #else - uint32_t reserved_31_29 : 3; - uint32_t bit_mask_a_val : 29; + uint32_t reserved_31_29 : 3; + uint32_t bit_mask_a_val : 29; #endif - } s; + } s; }; union ctu_can_fd_filter_a_val { - uint32_t u32; - struct ctu_can_fd_filter_a_val_s { + uint32_t u32; + struct ctu_can_fd_filter_a_val_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* FILTER_A_VAL */ - uint32_t bit_val_a_val : 29; - uint32_t reserved_31_29 : 3; + uint32_t bit_val_a_val : 29; + uint32_t reserved_31_29 : 3; #else - uint32_t reserved_31_29 : 3; - uint32_t bit_val_a_val : 29; + uint32_t reserved_31_29 : 3; + uint32_t bit_val_a_val : 29; #endif - } s; + } s; }; union ctu_can_fd_filter_b_mask { - uint32_t u32; - struct ctu_can_fd_filter_b_mask_s { + uint32_t u32; + struct ctu_can_fd_filter_b_mask_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* FILTER_B_MASK */ - uint32_t bit_mask_b_val : 29; - uint32_t reserved_31_29 : 3; + uint32_t bit_mask_b_val : 29; + uint32_t reserved_31_29 : 3; #else - uint32_t reserved_31_29 : 3; - uint32_t bit_mask_b_val : 29; + uint32_t reserved_31_29 : 3; + uint32_t bit_mask_b_val : 29; #endif - } s; + } s; }; union ctu_can_fd_filter_b_val { - uint32_t u32; - struct ctu_can_fd_filter_b_val_s { + uint32_t u32; + struct ctu_can_fd_filter_b_val_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* FILTER_B_VAL */ - uint32_t bit_val_b_val : 29; - uint32_t reserved_31_29 : 3; + uint32_t bit_val_b_val : 29; + uint32_t reserved_31_29 : 3; #else - uint32_t reserved_31_29 : 3; - uint32_t bit_val_b_val : 29; + uint32_t reserved_31_29 : 3; + uint32_t bit_val_b_val : 29; #endif - } s; + } s; }; union ctu_can_fd_filter_c_mask { - uint32_t u32; - struct ctu_can_fd_filter_c_mask_s { + uint32_t u32; + struct ctu_can_fd_filter_c_mask_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* FILTER_C_MASK */ - uint32_t bit_mask_c_val : 29; - uint32_t reserved_31_29 : 3; + uint32_t bit_mask_c_val : 29; + uint32_t reserved_31_29 : 3; #else - uint32_t reserved_31_29 : 3; - uint32_t bit_mask_c_val : 29; + uint32_t reserved_31_29 : 3; + uint32_t bit_mask_c_val : 29; #endif - } s; + } s; }; union ctu_can_fd_filter_c_val { - uint32_t u32; - struct ctu_can_fd_filter_c_val_s { + uint32_t u32; + struct ctu_can_fd_filter_c_val_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* FILTER_C_VAL */ - uint32_t bit_val_c_val : 29; - uint32_t reserved_31_29 : 3; + uint32_t bit_val_c_val : 29; + uint32_t reserved_31_29 : 3; #else - uint32_t reserved_31_29 : 3; - uint32_t bit_val_c_val : 29; + uint32_t reserved_31_29 : 3; + uint32_t bit_val_c_val : 29; #endif - } s; + } s; }; union ctu_can_fd_filter_ran_low { - uint32_t u32; - struct ctu_can_fd_filter_ran_low_s { + uint32_t u32; + struct ctu_can_fd_filter_ran_low_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* FILTER_RAN_LOW */ - uint32_t bit_ran_low_val : 29; - uint32_t reserved_31_29 : 3; + uint32_t bit_ran_low_val : 29; + uint32_t reserved_31_29 : 3; #else - uint32_t reserved_31_29 : 3; - uint32_t bit_ran_low_val : 29; + uint32_t reserved_31_29 : 3; + uint32_t bit_ran_low_val : 29; #endif - } s; + } s; }; union ctu_can_fd_filter_ran_high { - uint32_t u32; - struct ctu_can_fd_filter_ran_high_s { + uint32_t u32; + struct ctu_can_fd_filter_ran_high_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* FILTER_RAN_HIGH */ - uint32_t bit_ran_high_val : 29; - uint32_t reserved_31_29 : 3; + uint32_t bit_ran_high_val : 29; + uint32_t reserved_31_29 : 3; #else - uint32_t reserved_31_29 : 3; - uint32_t bit_ran_high_val : 29; + uint32_t reserved_31_29 : 3; + uint32_t bit_ran_high_val : 29; #endif - } s; + } s; }; union ctu_can_fd_filter_control_filter_status { - uint32_t u32; - struct ctu_can_fd_filter_control_filter_status_s { + uint32_t u32; + struct ctu_can_fd_filter_control_filter_status_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* FILTER_CONTROL */ - uint32_t fanb : 1; - uint32_t fane : 1; - uint32_t fafb : 1; - uint32_t fafe : 1; - uint32_t fbnb : 1; - uint32_t fbne : 1; - uint32_t fbfb : 1; - uint32_t fbfe : 1; - uint32_t fcnb : 1; - uint32_t fcne : 1; - uint32_t fcfb : 1; - uint32_t fcfe : 1; - uint32_t frnb : 1; - uint32_t frne : 1; - uint32_t frfb : 1; - uint32_t frfe : 1; + uint32_t fanb : 1; + uint32_t fane : 1; + uint32_t fafb : 1; + uint32_t fafe : 1; + uint32_t fbnb : 1; + uint32_t fbne : 1; + uint32_t fbfb : 1; + uint32_t fbfe : 1; + uint32_t fcnb : 1; + uint32_t fcne : 1; + uint32_t fcfb : 1; + uint32_t fcfe : 1; + uint32_t frnb : 1; + uint32_t frne : 1; + uint32_t frfb : 1; + uint32_t frfe : 1; /* FILTER_STATUS */ - uint32_t sfa : 1; - uint32_t sfb : 1; - uint32_t sfc : 1; - uint32_t sfr : 1; - uint32_t reserved_31_20 : 12; + uint32_t sfa : 1; + uint32_t sfb : 1; + uint32_t sfc : 1; + uint32_t sfr : 1; + uint32_t reserved_31_20 : 12; #else - uint32_t reserved_31_20 : 12; - uint32_t sfr : 1; - uint32_t sfc : 1; - uint32_t sfb : 1; - uint32_t sfa : 1; - uint32_t frfe : 1; - uint32_t frfb : 1; - uint32_t frne : 1; - uint32_t frnb : 1; - uint32_t fcfe : 1; - uint32_t fcfb : 1; - uint32_t fcne : 1; - uint32_t fcnb : 1; - uint32_t fbfe : 1; - uint32_t fbfb : 1; - uint32_t fbne : 1; - uint32_t fbnb : 1; - uint32_t fafe : 1; - uint32_t fafb : 1; - uint32_t fane : 1; - uint32_t fanb : 1; + uint32_t reserved_31_20 : 12; + uint32_t sfr : 1; + uint32_t sfc : 1; + uint32_t sfb : 1; + uint32_t sfa : 1; + uint32_t frfe : 1; + uint32_t frfb : 1; + uint32_t frne : 1; + uint32_t frnb : 1; + uint32_t fcfe : 1; + uint32_t fcfb : 1; + uint32_t fcne : 1; + uint32_t fcnb : 1; + uint32_t fbfe : 1; + uint32_t fbfb : 1; + uint32_t fbne : 1; + uint32_t fbnb : 1; + uint32_t fafe : 1; + uint32_t fafb : 1; + uint32_t fane : 1; + uint32_t fanb : 1; #endif - } s; + } s; }; union ctu_can_fd_rx_mem_info { - uint32_t u32; - struct ctu_can_fd_rx_mem_info_s { + uint32_t u32; + struct ctu_can_fd_rx_mem_info_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* RX_MEM_INFO */ - uint32_t rx_buff_size : 13; - uint32_t reserved_15_13 : 3; - uint32_t rx_mem_free : 13; - uint32_t reserved_31_29 : 3; + uint32_t rx_buff_size : 13; + uint32_t reserved_15_13 : 3; + uint32_t rx_mem_free : 13; + uint32_t reserved_31_29 : 3; #else - uint32_t reserved_31_29 : 3; - uint32_t rx_mem_free : 13; - uint32_t reserved_15_13 : 3; - uint32_t rx_buff_size : 13; + uint32_t reserved_31_29 : 3; + uint32_t rx_mem_free : 13; + uint32_t reserved_15_13 : 3; + uint32_t rx_buff_size : 13; #endif - } s; + } s; }; union ctu_can_fd_rx_pointers { - uint32_t u32; - struct ctu_can_fd_rx_pointers_s { + uint32_t u32; + struct ctu_can_fd_rx_pointers_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* RX_POINTERS */ - uint32_t rx_wpp : 12; - uint32_t reserved_15_12 : 4; - uint32_t rx_rpp : 12; - uint32_t reserved_31_28 : 4; + uint32_t rx_wpp : 12; + uint32_t reserved_15_12 : 4; + uint32_t rx_rpp : 12; + uint32_t reserved_31_28 : 4; #else - uint32_t reserved_31_28 : 4; - uint32_t rx_rpp : 12; - uint32_t reserved_15_12 : 4; - uint32_t rx_wpp : 12; + uint32_t reserved_31_28 : 4; + uint32_t rx_rpp : 12; + uint32_t reserved_15_12 : 4; + uint32_t rx_wpp : 12; #endif - } s; + } s; }; union ctu_can_fd_rx_status_rx_settings { - uint32_t u32; - struct ctu_can_fd_rx_status_rx_settings_s { + uint32_t u32; + struct ctu_can_fd_rx_status_rx_settings_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* RX_STATUS */ - uint32_t rxe : 1; - uint32_t rxf : 1; - uint32_t reserved_3_2 : 2; - uint32_t rxfrc : 11; - uint32_t reserved_15 : 1; + uint32_t rxe : 1; + uint32_t rxf : 1; + uint32_t reserved_3_2 : 2; + uint32_t rxfrc : 11; + uint32_t reserved_15 : 1; /* RX_SETTINGS */ - uint32_t rtsop : 1; - uint32_t reserved_31_17 : 15; + uint32_t rtsop : 1; + uint32_t reserved_31_17 : 15; #else - uint32_t reserved_31_17 : 15; - uint32_t rtsop : 1; - uint32_t reserved_15 : 1; - uint32_t rxfrc : 11; - uint32_t reserved_3_2 : 2; - uint32_t rxf : 1; - uint32_t rxe : 1; + uint32_t reserved_31_17 : 15; + uint32_t rtsop : 1; + uint32_t reserved_15 : 1; + uint32_t rxfrc : 11; + uint32_t reserved_3_2 : 2; + uint32_t rxf : 1; + uint32_t rxe : 1; #endif - } s; + } s; }; enum ctu_can_fd_rx_settings_rtsop { - RTS_END = 0x0, - RTS_BEG = 0x1, + RTS_END = 0x0, + RTS_BEG = 0x1, }; union ctu_can_fd_rx_data { - uint32_t u32; - struct ctu_can_fd_rx_data_s { + uint32_t u32; + struct ctu_can_fd_rx_data_s { /* RX_DATA */ - uint32_t rx_data : 32; - } s; + uint32_t rx_data : 32; + } s; }; union ctu_can_fd_tx_status { - uint32_t u32; - struct ctu_can_fd_tx_status_s { + uint32_t u32; + struct ctu_can_fd_tx_status_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* TX_STATUS */ - uint32_t tx1s : 4; - uint32_t tx2s : 4; - uint32_t tx3s : 4; - uint32_t tx4s : 4; - uint32_t reserved_31_16 : 16; + uint32_t tx1s : 4; + uint32_t tx2s : 4; + uint32_t tx3s : 4; + uint32_t tx4s : 4; + uint32_t reserved_31_16 : 16; #else - uint32_t reserved_31_16 : 16; - uint32_t tx4s : 4; - uint32_t tx3s : 4; - uint32_t tx2s : 4; - uint32_t tx1s : 4; + uint32_t reserved_31_16 : 16; + uint32_t tx4s : 4; + uint32_t tx3s : 4; + uint32_t tx2s : 4; + uint32_t tx1s : 4; #endif - } s; + } s; }; enum ctu_can_fd_tx_status_tx1s { - TXT_RDY = 0x1, - TXT_TRAN = 0x2, - TXT_ABTP = 0x3, - TXT_TOK = 0x4, - TXT_ERR = 0x6, - TXT_ABT = 0x7, - TXT_ETY = 0x8, + TXT_RDY = 0x1, + TXT_TRAN = 0x2, + TXT_ABTP = 0x3, + TXT_TOK = 0x4, + TXT_ERR = 0x6, + TXT_ABT = 0x7, + TXT_ETY = 0x8, }; union ctu_can_fd_tx_command { - uint32_t u32; - struct ctu_can_fd_tx_command_s { + uint32_t u32; + struct ctu_can_fd_tx_command_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* TX_COMMAND */ - uint32_t txce : 1; - uint32_t txcr : 1; - uint32_t txca : 1; - uint32_t reserved_7_3 : 5; - uint32_t txb1 : 1; - uint32_t txb2 : 1; - uint32_t txb3 : 1; - uint32_t txb4 : 1; - uint32_t reserved_31_12 : 20; + uint32_t txce : 1; + uint32_t txcr : 1; + uint32_t txca : 1; + uint32_t reserved_7_3 : 5; + uint32_t txb1 : 1; + uint32_t txb2 : 1; + uint32_t txb3 : 1; + uint32_t txb4 : 1; + uint32_t reserved_31_12 : 20; #else - uint32_t reserved_31_12 : 20; - uint32_t txb4 : 1; - uint32_t txb3 : 1; - uint32_t txb2 : 1; - uint32_t txb1 : 1; - uint32_t reserved_7_3 : 5; - uint32_t txca : 1; - uint32_t txcr : 1; - uint32_t txce : 1; + uint32_t reserved_31_12 : 20; + uint32_t txb4 : 1; + uint32_t txb3 : 1; + uint32_t txb2 : 1; + uint32_t txb1 : 1; + uint32_t reserved_7_3 : 5; + uint32_t txca : 1; + uint32_t txcr : 1; + uint32_t txce : 1; #endif - } s; + } s; }; union ctu_can_fd_tx_priority { - uint32_t u32; - struct ctu_can_fd_tx_priority_s { + uint32_t u32; + struct ctu_can_fd_tx_priority_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* TX_PRIORITY */ - uint32_t txt1p : 3; - uint32_t reserved_3 : 1; - uint32_t txt2p : 3; - uint32_t reserved_7 : 1; - uint32_t txt3p : 3; - uint32_t reserved_11 : 1; - uint32_t txt4p : 3; - uint32_t reserved_31_15 : 17; + uint32_t txt1p : 3; + uint32_t reserved_3 : 1; + uint32_t txt2p : 3; + uint32_t reserved_7 : 1; + uint32_t txt3p : 3; + uint32_t reserved_11 : 1; + uint32_t txt4p : 3; + uint32_t reserved_31_15 : 17; #else - uint32_t reserved_31_15 : 17; - uint32_t txt4p : 3; - uint32_t reserved_11 : 1; - uint32_t txt3p : 3; - uint32_t reserved_7 : 1; - uint32_t txt2p : 3; - uint32_t reserved_3 : 1; - uint32_t txt1p : 3; + uint32_t reserved_31_15 : 17; + uint32_t txt4p : 3; + uint32_t reserved_11 : 1; + uint32_t txt3p : 3; + uint32_t reserved_7 : 1; + uint32_t txt2p : 3; + uint32_t reserved_3 : 1; + uint32_t txt1p : 3; #endif - } s; + } s; }; union ctu_can_fd_err_capt_alc { - uint32_t u32; - struct ctu_can_fd_err_capt_alc_s { + uint32_t u32; + struct ctu_can_fd_err_capt_alc_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* ERR_CAPT */ - uint32_t err_pos : 5; - uint32_t err_type : 3; - uint32_t reserved_15_8 : 8; + uint32_t err_pos : 5; + uint32_t err_type : 3; + uint32_t reserved_15_8 : 8; /* ALC */ - uint32_t alc_bit : 5; - uint32_t alc_id_field : 3; - uint32_t reserved_31_24 : 8; + uint32_t alc_bit : 5; + uint32_t alc_id_field : 3; + uint32_t reserved_31_24 : 8; #else - uint32_t reserved_31_24 : 8; - uint32_t alc_id_field : 3; - uint32_t alc_bit : 5; - uint32_t reserved_15_8 : 8; - uint32_t err_type : 3; - uint32_t err_pos : 5; + uint32_t reserved_31_24 : 8; + uint32_t alc_id_field : 3; + uint32_t alc_bit : 5; + uint32_t reserved_15_8 : 8; + uint32_t err_type : 3; + uint32_t err_pos : 5; #endif - } s; + } s; }; enum ctu_can_fd_err_capt_err_pos { - ERC_POS_SOF = 0x0, - ERC_POS_ARB = 0x1, - ERC_POS_CTRL = 0x2, - ERC_POS_DATA = 0x3, - ERC_POS_CRC = 0x4, - ERC_POS_ACK = 0x5, - ERC_POS_EOF = 0x6, - ERC_POS_ERR = 0x7, - ERC_POS_OVRL = 0x8, - ERC_POS_OTHER = 0x1f, + ERC_POS_SOF = 0x0, + ERC_POS_ARB = 0x1, + ERC_POS_CTRL = 0x2, + ERC_POS_DATA = 0x3, + ERC_POS_CRC = 0x4, + ERC_POS_ACK = 0x5, + ERC_POS_EOF = 0x6, + ERC_POS_ERR = 0x7, + ERC_POS_OVRL = 0x8, + ERC_POS_OTHER = 0x1f, }; enum ctu_can_fd_err_capt_err_type { - ERC_BIT_ERR = 0x0, - ERC_CRC_ERR = 0x1, - ERC_FRM_ERR = 0x2, - ERC_ACK_ERR = 0x3, - ERC_STUF_ERR = 0x4, + ERC_BIT_ERR = 0x0, + ERC_CRC_ERR = 0x1, + ERC_FRM_ERR = 0x2, + ERC_ACK_ERR = 0x3, + ERC_STUF_ERR = 0x4, }; enum ctu_can_fd_alc_alc_id_field { - ALC_RSVD = 0x0, - ALC_BASE_ID = 0x1, - ALC_SRR_RTR = 0x2, - ALC_IDE = 0x3, - ALC_EXTENSION = 0x4, - ALC_RTR = 0x5, + ALC_RSVD = 0x0, + ALC_BASE_ID = 0x1, + ALC_SRR_RTR = 0x2, + ALC_IDE = 0x3, + ALC_EXTENSION = 0x4, + ALC_RTR = 0x5, }; union ctu_can_fd_trv_delay_ssp_cfg { - uint32_t u32; - struct ctu_can_fd_trv_delay_ssp_cfg_s { + uint32_t u32; + struct ctu_can_fd_trv_delay_ssp_cfg_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* TRV_DELAY */ - uint32_t trv_delay_value : 7; - uint32_t reserved_15_7 : 9; + uint32_t trv_delay_value : 7; + uint32_t reserved_15_7 : 9; /* SSP_CFG */ - uint32_t ssp_offset : 8; - uint32_t ssp_src : 2; - uint32_t reserved_31_26 : 6; + uint32_t ssp_offset : 8; + uint32_t ssp_src : 2; + uint32_t reserved_31_26 : 6; #else - uint32_t reserved_31_26 : 6; - uint32_t ssp_src : 2; - uint32_t ssp_offset : 8; - uint32_t reserved_15_7 : 9; - uint32_t trv_delay_value : 7; + uint32_t reserved_31_26 : 6; + uint32_t ssp_src : 2; + uint32_t ssp_offset : 8; + uint32_t reserved_15_7 : 9; + uint32_t trv_delay_value : 7; #endif - } s; + } s; }; enum ctu_can_fd_ssp_cfg_ssp_src { - SSP_SRC_MEAS_N_OFFSET = 0x0, - SSP_SRC_NO_SSP = 0x1, - SSP_SRC_OFFSET = 0x2, + SSP_SRC_MEAS_N_OFFSET = 0x0, + SSP_SRC_NO_SSP = 0x1, + SSP_SRC_OFFSET = 0x2, }; union ctu_can_fd_rx_fr_ctr { - uint32_t u32; - struct ctu_can_fd_rx_fr_ctr_s { + uint32_t u32; + struct ctu_can_fd_rx_fr_ctr_s { /* RX_FR_CTR */ - uint32_t rx_fr_ctr_val : 32; - } s; + uint32_t rx_fr_ctr_val : 32; + } s; }; union ctu_can_fd_tx_fr_ctr { - uint32_t u32; - struct ctu_can_fd_tx_fr_ctr_s { + uint32_t u32; + struct ctu_can_fd_tx_fr_ctr_s { /* TX_FR_CTR */ - uint32_t tx_fr_ctr_val : 32; - } s; + uint32_t tx_fr_ctr_val : 32; + } s; }; union ctu_can_fd_debug_register { - uint32_t u32; - struct ctu_can_fd_debug_register_s { + uint32_t u32; + struct ctu_can_fd_debug_register_s { #ifdef __LITTLE_ENDIAN_BITFIELD /* DEBUG_REGISTER */ - uint32_t stuff_count : 3; - uint32_t destuff_count : 3; - uint32_t pc_arb : 1; - uint32_t pc_con : 1; - uint32_t pc_dat : 1; - uint32_t pc_stc : 1; - uint32_t pc_crc : 1; - uint32_t pc_crcd : 1; - uint32_t pc_ack : 1; - uint32_t pc_ackd : 1; - uint32_t pc_eof : 1; - uint32_t pc_int : 1; - uint32_t pc_susp : 1; - uint32_t pc_ovr : 1; - uint32_t pc_sof : 1; - uint32_t reserved_31_19 : 13; + uint32_t stuff_count : 3; + uint32_t destuff_count : 3; + uint32_t pc_arb : 1; + uint32_t pc_con : 1; + uint32_t pc_dat : 1; + uint32_t pc_stc : 1; + uint32_t pc_crc : 1; + uint32_t pc_crcd : 1; + uint32_t pc_ack : 1; + uint32_t pc_ackd : 1; + uint32_t pc_eof : 1; + uint32_t pc_int : 1; + uint32_t pc_susp : 1; + uint32_t pc_ovr : 1; + uint32_t pc_sof : 1; + uint32_t reserved_31_19 : 13; #else - uint32_t reserved_31_19 : 13; - uint32_t pc_sof : 1; - uint32_t pc_ovr : 1; - uint32_t pc_susp : 1; - uint32_t pc_int : 1; - uint32_t pc_eof : 1; - uint32_t pc_ackd : 1; - uint32_t pc_ack : 1; - uint32_t pc_crcd : 1; - uint32_t pc_crc : 1; - uint32_t pc_stc : 1; - uint32_t pc_dat : 1; - uint32_t pc_con : 1; - uint32_t pc_arb : 1; - uint32_t destuff_count : 3; - uint32_t stuff_count : 3; + uint32_t reserved_31_19 : 13; + uint32_t pc_sof : 1; + uint32_t pc_ovr : 1; + uint32_t pc_susp : 1; + uint32_t pc_int : 1; + uint32_t pc_eof : 1; + uint32_t pc_ackd : 1; + uint32_t pc_ack : 1; + uint32_t pc_crcd : 1; + uint32_t pc_crc : 1; + uint32_t pc_stc : 1; + uint32_t pc_dat : 1; + uint32_t pc_con : 1; + uint32_t pc_arb : 1; + uint32_t destuff_count : 3; + uint32_t stuff_count : 3; #endif - } s; + } s; }; union ctu_can_fd_yolo_reg { - uint32_t u32; - struct ctu_can_fd_yolo_reg_s { + uint32_t u32; + struct ctu_can_fd_yolo_reg_s { /* YOLO_REG */ - uint32_t yolo_val : 32; - } s; + uint32_t yolo_val : 32; + } s; }; union ctu_can_fd_timestamp_low { - uint32_t u32; - struct ctu_can_fd_timestamp_low_s { + uint32_t u32; + struct ctu_can_fd_timestamp_low_s { /* TIMESTAMP_LOW */ - uint32_t timestamp_low : 32; - } s; + uint32_t timestamp_low : 32; + } s; }; union ctu_can_fd_timestamp_high { - uint32_t u32; - struct ctu_can_fd_timestamp_high_s { + uint32_t u32; + struct ctu_can_fd_timestamp_high_s { /* TIMESTAMP_HIGH */ - uint32_t timestamp_high : 32; - } s; + uint32_t timestamp_high : 32; + } s; }; #endif diff --git a/hw/net/e1000_regs.h b/hw/net/e1000_regs.h index 9d423f6c09..59e050742b 100644 --- a/hw/net/e1000_regs.h +++ b/hw/net/e1000_regs.h @@ -552,21 +552,21 @@ #define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */ /* PHY Status Register */ -#define MII_SR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */ -#define MII_SR_JABBER_DETECT 0x0002 /* Jabber Detected */ -#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */ -#define MII_SR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */ -#define MII_SR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */ -#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */ -#define MII_SR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */ -#define MII_SR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */ -#define MII_SR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */ -#define MII_SR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */ -#define MII_SR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */ -#define MII_SR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */ -#define MII_SR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */ -#define MII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */ -#define MII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */ +#define MII_SR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */ +#define MII_SR_JABBER_DETECT 0x0002 /* Jabber Detected */ +#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */ +#define MII_SR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */ +#define MII_SR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */ +#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */ +#define MII_SR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */ +#define MII_SR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */ +#define MII_SR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */ +#define MII_SR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */ +#define MII_SR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */ +#define MII_SR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */ +#define MII_SR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */ +#define MII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */ +#define MII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */ /* PHY Link Partner Ability Register */ #define MII_LPAR_LPACK 0x4000 /* Acked by link partner */ diff --git a/hw/net/mcf_fec.c b/hw/net/mcf_fec.c index 25e3e453ab..8aa27bd322 100644 --- a/hw/net/mcf_fec.c +++ b/hw/net/mcf_fec.c @@ -313,10 +313,10 @@ static void mcf_fec_reset(DeviceState *dev) s->rfsr = 0x500; } -#define MMFR_WRITE_OP (1 << 28) -#define MMFR_READ_OP (2 << 28) -#define MMFR_PHYADDR(v) (((v) >> 23) & 0x1f) -#define MMFR_REGNUM(v) (((v) >> 18) & 0x1f) +#define MMFR_WRITE_OP (1 << 28) +#define MMFR_READ_OP (2 << 28) +#define MMFR_PHYADDR(v) (((v) >> 23) & 0x1f) +#define MMFR_REGNUM(v) (((v) >> 18) & 0x1f) static uint64_t mcf_fec_read_mdio(mcf_fec_state *s) { diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c index 6c17ee1ae2..3f31d04efb 100644 --- a/hw/net/ne2000.c +++ b/hw/net/ne2000.c @@ -36,89 +36,89 @@ #define MAX_ETH_FRAME_SIZE 1514 -#define E8390_CMD 0x00 /* The command register (for all pages) */ +#define E8390_CMD 0x00 /* The command register (for all pages) */ /* Page 0 register offsets. */ -#define EN0_CLDALO 0x01 /* Low byte of current local dma addr RD */ -#define EN0_STARTPG 0x01 /* Starting page of ring bfr WR */ -#define EN0_CLDAHI 0x02 /* High byte of current local dma addr RD */ -#define EN0_STOPPG 0x02 /* Ending page +1 of ring bfr WR */ -#define EN0_BOUNDARY 0x03 /* Boundary page of ring bfr RD WR */ -#define EN0_TSR 0x04 /* Transmit status reg RD */ -#define EN0_TPSR 0x04 /* Transmit starting page WR */ -#define EN0_NCR 0x05 /* Number of collision reg RD */ -#define EN0_TCNTLO 0x05 /* Low byte of tx byte count WR */ -#define EN0_FIFO 0x06 /* FIFO RD */ -#define EN0_TCNTHI 0x06 /* High byte of tx byte count WR */ -#define EN0_ISR 0x07 /* Interrupt status reg RD WR */ -#define EN0_CRDALO 0x08 /* low byte of current remote dma address RD */ -#define EN0_RSARLO 0x08 /* Remote start address reg 0 */ -#define EN0_CRDAHI 0x09 /* high byte, current remote dma address RD */ -#define EN0_RSARHI 0x09 /* Remote start address reg 1 */ -#define EN0_RCNTLO 0x0a /* Remote byte count reg WR */ -#define EN0_RTL8029ID0 0x0a /* Realtek ID byte #1 RD */ -#define EN0_RCNTHI 0x0b /* Remote byte count reg WR */ -#define EN0_RTL8029ID1 0x0b /* Realtek ID byte #2 RD */ -#define EN0_RSR 0x0c /* rx status reg RD */ -#define EN0_RXCR 0x0c /* RX configuration reg WR */ -#define EN0_TXCR 0x0d /* TX configuration reg WR */ -#define EN0_COUNTER0 0x0d /* Rcv alignment error counter RD */ -#define EN0_DCFG 0x0e /* Data configuration reg WR */ -#define EN0_COUNTER1 0x0e /* Rcv CRC error counter RD */ -#define EN0_IMR 0x0f /* Interrupt mask reg WR */ -#define EN0_COUNTER2 0x0f /* Rcv missed frame error counter RD */ +#define EN0_CLDALO 0x01 /* Low byte of current local dma addr RD */ +#define EN0_STARTPG 0x01 /* Starting page of ring bfr WR */ +#define EN0_CLDAHI 0x02 /* High byte of current local dma addr RD */ +#define EN0_STOPPG 0x02 /* Ending page +1 of ring bfr WR */ +#define EN0_BOUNDARY 0x03 /* Boundary page of ring bfr RD WR */ +#define EN0_TSR 0x04 /* Transmit status reg RD */ +#define EN0_TPSR 0x04 /* Transmit starting page WR */ +#define EN0_NCR 0x05 /* Number of collision reg RD */ +#define EN0_TCNTLO 0x05 /* Low byte of tx byte count WR */ +#define EN0_FIFO 0x06 /* FIFO RD */ +#define EN0_TCNTHI 0x06 /* High byte of tx byte count WR */ +#define EN0_ISR 0x07 /* Interrupt status reg RD WR */ +#define EN0_CRDALO 0x08 /* low byte of current remote dma address RD */ +#define EN0_RSARLO 0x08 /* Remote start address reg 0 */ +#define EN0_CRDAHI 0x09 /* high byte, current remote dma address RD */ +#define EN0_RSARHI 0x09 /* Remote start address reg 1 */ +#define EN0_RCNTLO 0x0a /* Remote byte count reg WR */ +#define EN0_RTL8029ID0 0x0a /* Realtek ID byte #1 RD */ +#define EN0_RCNTHI 0x0b /* Remote byte count reg WR */ +#define EN0_RTL8029ID1 0x0b /* Realtek ID byte #2 RD */ +#define EN0_RSR 0x0c /* rx status reg RD */ +#define EN0_RXCR 0x0c /* RX configuration reg WR */ +#define EN0_TXCR 0x0d /* TX configuration reg WR */ +#define EN0_COUNTER0 0x0d /* Rcv alignment error counter RD */ +#define EN0_DCFG 0x0e /* Data configuration reg WR */ +#define EN0_COUNTER1 0x0e /* Rcv CRC error counter RD */ +#define EN0_IMR 0x0f /* Interrupt mask reg WR */ +#define EN0_COUNTER2 0x0f /* Rcv missed frame error counter RD */ #define EN1_PHYS 0x11 #define EN1_CURPAG 0x17 #define EN1_MULT 0x18 -#define EN2_STARTPG 0x21 /* Starting page of ring bfr RD */ -#define EN2_STOPPG 0x22 /* Ending page +1 of ring bfr RD */ +#define EN2_STARTPG 0x21 /* Starting page of ring bfr RD */ +#define EN2_STOPPG 0x22 /* Ending page +1 of ring bfr RD */ -#define EN3_CONFIG0 0x33 -#define EN3_CONFIG1 0x34 -#define EN3_CONFIG2 0x35 -#define EN3_CONFIG3 0x36 +#define EN3_CONFIG0 0x33 +#define EN3_CONFIG1 0x34 +#define EN3_CONFIG2 0x35 +#define EN3_CONFIG3 0x36 /* Register accessed at EN_CMD, the 8390 base addr. */ -#define E8390_STOP 0x01 /* Stop and reset the chip */ -#define E8390_START 0x02 /* Start the chip, clear reset */ -#define E8390_TRANS 0x04 /* Transmit a frame */ -#define E8390_RREAD 0x08 /* Remote read */ -#define E8390_RWRITE 0x10 /* Remote write */ -#define E8390_NODMA 0x20 /* Remote DMA */ -#define E8390_PAGE0 0x00 /* Select page chip registers */ -#define E8390_PAGE1 0x40 /* using the two high-order bits */ -#define E8390_PAGE2 0x80 /* Page 3 is invalid. */ +#define E8390_STOP 0x01 /* Stop and reset the chip */ +#define E8390_START 0x02 /* Start the chip, clear reset */ +#define E8390_TRANS 0x04 /* Transmit a frame */ +#define E8390_RREAD 0x08 /* Remote read */ +#define E8390_RWRITE 0x10 /* Remote write */ +#define E8390_NODMA 0x20 /* Remote DMA */ +#define E8390_PAGE0 0x00 /* Select page chip registers */ +#define E8390_PAGE1 0x40 /* using the two high-order bits */ +#define E8390_PAGE2 0x80 /* Page 3 is invalid. */ /* Bits in EN0_ISR - Interrupt status register */ -#define ENISR_RX 0x01 /* Receiver, no error */ -#define ENISR_TX 0x02 /* Transmitter, no error */ -#define ENISR_RX_ERR 0x04 /* Receiver, with error */ -#define ENISR_TX_ERR 0x08 /* Transmitter, with error */ -#define ENISR_OVER 0x10 /* Receiver overwrote the ring */ -#define ENISR_COUNTERS 0x20 /* Counters need emptying */ -#define ENISR_RDC 0x40 /* remote dma complete */ -#define ENISR_RESET 0x80 /* Reset completed */ -#define ENISR_ALL 0x3f /* Interrupts we will enable */ +#define ENISR_RX 0x01 /* Receiver, no error */ +#define ENISR_TX 0x02 /* Transmitter, no error */ +#define ENISR_RX_ERR 0x04 /* Receiver, with error */ +#define ENISR_TX_ERR 0x08 /* Transmitter, with error */ +#define ENISR_OVER 0x10 /* Receiver overwrote the ring */ +#define ENISR_COUNTERS 0x20 /* Counters need emptying */ +#define ENISR_RDC 0x40 /* remote dma complete */ +#define ENISR_RESET 0x80 /* Reset completed */ +#define ENISR_ALL 0x3f /* Interrupts we will enable */ /* Bits in received packet status byte and EN0_RSR*/ -#define ENRSR_RXOK 0x01 /* Received a good packet */ -#define ENRSR_CRC 0x02 /* CRC error */ -#define ENRSR_FAE 0x04 /* frame alignment error */ -#define ENRSR_FO 0x08 /* FIFO overrun */ -#define ENRSR_MPA 0x10 /* missed pkt */ -#define ENRSR_PHY 0x20 /* physical/multicast address */ -#define ENRSR_DIS 0x40 /* receiver disable. set in monitor mode */ -#define ENRSR_DEF 0x80 /* deferring */ +#define ENRSR_RXOK 0x01 /* Received a good packet */ +#define ENRSR_CRC 0x02 /* CRC error */ +#define ENRSR_FAE 0x04 /* frame alignment error */ +#define ENRSR_FO 0x08 /* FIFO overrun */ +#define ENRSR_MPA 0x10 /* missed pkt */ +#define ENRSR_PHY 0x20 /* physical/multicast address */ +#define ENRSR_DIS 0x40 /* receiver disable. set in monitor mode */ +#define ENRSR_DEF 0x80 /* deferring */ /* Transmitted packet status, EN0_TSR. */ -#define ENTSR_PTX 0x01 /* Packet transmitted without error */ -#define ENTSR_ND 0x02 /* The transmit wasn't deferred. */ -#define ENTSR_COL 0x04 /* The transmit collided at least once. */ +#define ENTSR_PTX 0x01 /* Packet transmitted without error */ +#define ENTSR_ND 0x02 /* The transmit wasn't deferred. */ +#define ENTSR_COL 0x04 /* The transmit collided at least once. */ #define ENTSR_ABT 0x08 /* The transmit collided 16 times, and was deferred. */ -#define ENTSR_CRS 0x10 /* The carrier sense was lost. */ +#define ENTSR_CRS 0x10 /* The carrier sense was lost. */ #define ENTSR_FU 0x20 /* A "FIFO underrun" occurred during transmit. */ -#define ENTSR_CDH 0x40 /* The collision detect "heartbeat" signal was lost. */ +#define ENTSR_CDH 0x40 /* The collision detect "heartbeat" signal was lost. */ #define ENTSR_OWC 0x80 /* There was an out-of-window collision. */ void ne2000_reset(NE2000State *s) @@ -425,13 +425,13 @@ static uint32_t ne2000_ioport_read(void *opaque, uint32_t addr) ret = 0x43; break; case EN3_CONFIG0: - ret = 0; /* 10baseT media */ + ret = 0; /* 10baseT media */ break; case EN3_CONFIG2: - ret = 0x40; /* 10baseT active */ + ret = 0x40; /* 10baseT active */ break; case EN3_CONFIG3: - ret = 0x40; /* Full duplex */ + ret = 0x40; /* Full duplex */ break; default: ret = 0x00; diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c index dcd3fc4948..e63e524913 100644 --- a/hw/net/pcnet.c +++ b/hw/net/pcnet.c @@ -370,7 +370,7 @@ static inline void pcnet_rmd_load(PCNetState *s, struct pcnet_RMD *rmd, uint32_t rbadr; int16_t buf_length; int16_t msg_length; - } rda; + } rda; s->phys_mem_read(s->dma_opaque, addr, (void *)&rda, sizeof(rda), 0); rmd->rbadr = le32_to_cpu(rda.rbadr) & 0xffffff; rmd->buf_length = le16_to_cpu(rda.buf_length); @@ -524,77 +524,77 @@ static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd, be16_to_cpu(hdr->ether_type)); \ } while (0) -#define CRC(crc, ch) (crc = (crc >> 8) ^ crctab[(crc ^ (ch)) & 0xff]) +#define CRC(crc, ch) (crc = (crc >> 8) ^ crctab[(crc ^ (ch)) & 0xff]) /* generated using the AUTODIN II polynomial - * x^32 + x^26 + x^23 + x^22 + x^16 + - * x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1 + * x^32 + x^26 + x^23 + x^22 + x^16 + + * x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1 */ static const uint32_t crctab[256] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, - 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, - 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, - 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, - 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, - 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, - 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, - 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, - 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, - 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, - 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, - 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, - 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, - 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, - 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, - 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, - 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, - 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, - 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, - 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, - 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, - 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, - 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, - 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, - 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, - 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, - 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, - 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, - 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, - 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, - 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, - 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, - 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, - 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, - 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, - 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, - 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, - 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, - 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, - 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, - 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, - 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, - 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, - 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, + 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, + 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, + 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, + 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, + 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, + 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, + 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, + 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, + 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, + 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, + 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, + 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, + 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, + 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, + 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, + 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, + 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, }; static inline int padr_match(PCNetState *s, const uint8_t *buf, int size) diff --git a/hw/net/pcnet.h b/hw/net/pcnet.h index f49b213c57..eb7f46aab3 100644 --- a/hw/net/pcnet.h +++ b/hw/net/pcnet.h @@ -4,8 +4,8 @@ #define PCNET_IOPORT_SIZE 0x20 #define PCNET_PNPMMIO_SIZE 0x20 -#define PCNET_LOOPTEST_CRC 1 -#define PCNET_LOOPTEST_NOCRC 2 +#define PCNET_LOOPTEST_CRC 1 +#define PCNET_LOOPTEST_NOCRC 2 #include "exec/memory.h" #include "hw/irq.h" diff --git a/net/tap-linux.h b/net/tap-linux.h index 1d06fe0de6..bbbb62c2a7 100644 --- a/net/tap-linux.h +++ b/net/tap-linux.h @@ -45,10 +45,10 @@ #define IFF_DETACH_QUEUE 0x0400 /* Features for GSO (TUNSETOFFLOAD). */ -#define TUN_F_CSUM 0x01 /* You can hand me unchecksummed packets. */ -#define TUN_F_TSO4 0x02 /* I can handle TSO for IPv4 packets */ -#define TUN_F_TSO6 0x04 /* I can handle TSO for IPv6 packets */ -#define TUN_F_TSO_ECN 0x08 /* I can handle TSO with ECN bits. */ -#define TUN_F_UFO 0x10 /* I can handle UFO packets */ +#define TUN_F_CSUM 0x01 /* You can hand me unchecksummed packets. */ +#define TUN_F_TSO4 0x02 /* I can handle TSO for IPv4 packets */ +#define TUN_F_TSO6 0x04 /* I can handle TSO for IPv6 packets */ +#define TUN_F_TSO_ECN 0x08 /* I can handle TSO with ECN bits. */ +#define TUN_F_UFO 0x10 /* I can handle UFO packets */ #endif /* QEMU_TAP_LINUX_H */ From 2cb40d446fac6a2aeccba7687448a9f48ec6b6c6 Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Thu, 10 Nov 2022 20:08:25 +0100 Subject: [PATCH 703/705] Fix several typos in documentation (found by codespell) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Those typos are in files which are used to generate the QEMU manual. Signed-off-by: Stefan Weil Message-Id: <20221110190825.879620-1-sw@weilnetz.de> Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Ani Sinha Reviewed-by: Peter Maydell Acked-by: Michael S. Tsirkin [thuth: update sentence in can.rst as suggested by Peter] Signed-off-by: Thomas Huth --- docs/devel/acpi-bits.rst | 2 +- docs/system/devices/can.rst | 5 +++-- hw/scsi/esp.c | 6 +++--- include/exec/memory.h | 6 +++--- qapi/virtio.json | 4 ++-- qemu-options.hx | 6 +++--- tests/qtest/libqos/qgraph.h | 2 +- tests/qtest/libqos/virtio-9p.c | 2 +- 8 files changed, 17 insertions(+), 16 deletions(-) diff --git a/docs/devel/acpi-bits.rst b/docs/devel/acpi-bits.rst index c9564d871a..5e22be8ef6 100644 --- a/docs/devel/acpi-bits.rst +++ b/docs/devel/acpi-bits.rst @@ -132,7 +132,7 @@ Under ``tests/avocado/`` as the root we have: (a) They are python2.7 based scripts and not python 3 scripts. (b) They are run from within the bios bits VM and is not subjected to QEMU - build/test python script maintainance and dependency resolutions. + build/test python script maintenance and dependency resolutions. (c) They need not be loaded by avocado framework when running tests. diff --git a/docs/system/devices/can.rst b/docs/system/devices/can.rst index fe37af8223..0af3d9912a 100644 --- a/docs/system/devices/can.rst +++ b/docs/system/devices/can.rst @@ -169,8 +169,9 @@ and with bitrate switch:: cangen can0 -b -The test can be run viceversa, generate messages in the guest system and capture them -in the host one and much more combinations. +The test can also be run the other way around, generating messages in the +guest system and capturing them in the host system. Other combinations are +also possible. Links to other resources ------------------------ diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c index e5b281e836..e52188d022 100644 --- a/hw/scsi/esp.c +++ b/hw/scsi/esp.c @@ -515,7 +515,7 @@ static void do_dma_pdma_cb(ESPState *s) } else { /* * Extra message out bytes received: update cmdfifo_cdb_offset - * and then switch to commmand phase + * and then switch to command phase */ s->cmdfifo_cdb_offset = fifo8_num_used(&s->cmdfifo); s->rregs[ESP_RSTAT] = STAT_TC | STAT_CD; @@ -627,7 +627,7 @@ static void esp_do_dma(ESPState *s) } else { /* * Extra message out bytes received: update cmdfifo_cdb_offset - * and then switch to commmand phase + * and then switch to command phase */ s->cmdfifo_cdb_offset = fifo8_num_used(&s->cmdfifo); s->rregs[ESP_RSTAT] = STAT_TC | STAT_CD; @@ -738,7 +738,7 @@ static void esp_do_nodma(ESPState *s) } else { /* * Extra message out bytes received: update cmdfifo_cdb_offset - * and then switch to commmand phase + * and then switch to command phase */ s->cmdfifo_cdb_offset = fifo8_num_used(&s->cmdfifo); s->rregs[ESP_RSTAT] = STAT_TC | STAT_CD; diff --git a/include/exec/memory.h b/include/exec/memory.h index 80fa75baa1..91f8a2395a 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -561,7 +561,7 @@ typedef void (*ReplayRamDiscard)(MemoryRegionSection *section, void *opaque); * A #RamDiscardManager coordinates which parts of specific RAM #MemoryRegion * regions are currently populated to be used/accessed by the VM, notifying * after parts were discarded (freeing up memory) and before parts will be - * populated (consuming memory), to be used/acessed by the VM. + * populated (consuming memory), to be used/accessed by the VM. * * A #RamDiscardManager can only be set for a RAM #MemoryRegion while the * #MemoryRegion isn't mapped yet; it cannot change while the #MemoryRegion is @@ -585,7 +585,7 @@ typedef void (*ReplayRamDiscard)(MemoryRegionSection *section, void *opaque); * Listeners are called in multiples of the minimum granularity (unless it * would exceed the registered range) and changes are aligned to the minimum * granularity within the #MemoryRegion. Listeners have to prepare for memory - * becomming discarded in a different granularity than it was populated and the + * becoming discarded in a different granularity than it was populated and the * other way around. */ struct RamDiscardManagerClass { @@ -1247,7 +1247,7 @@ void memory_region_init_ram_flags_nomigrate(MemoryRegion *mr, Error **errp); /** - * memory_region_init_resizeable_ram: Initialize memory region with resizeable + * memory_region_init_resizeable_ram: Initialize memory region with resizable * RAM. Accesses into the region will * modify memory directly. Only an initial * portion of this RAM is actually used. diff --git a/qapi/virtio.json b/qapi/virtio.json index 872c7e3623..019d2d1987 100644 --- a/qapi/virtio.json +++ b/qapi/virtio.json @@ -321,7 +321,7 @@ # }, # "backend-features": { # "dev-features": [ -# "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features negotation supported", +# "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features negotiation supported", # "VIRTIO_NET_F_GSO: Handling GSO-type packets supported", # "VIRTIO_NET_F_CTRL_MAC_ADDR: MAC address set through control channel", # "VIRTIO_NET_F_GUEST_ANNOUNCE: Driver sending gratuitous packets supported", @@ -394,7 +394,7 @@ # }, # "host-features": { # "dev-features": [ -# "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features negotation supported", +# "VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features negotiation supported", # "VIRTIO_NET_F_GSO: Handling GSO-type packets supported", # "VIRTIO_NET_F_CTRL_MAC_ADDR: MAC address set through control channel", # "VIRTIO_NET_F_GUEST_ANNOUNCE: Driver sending gratuitous packets supported", diff --git a/qemu-options.hx b/qemu-options.hx index 8b8a4a5d01..7f99d15b23 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -139,7 +139,7 @@ SRST interleave requirements before enabling the memory devices. ``targets.X=target`` provides the mapping to CXL host bridges - which may be identified by the id provied in the -device entry. + which may be identified by the id provided in the -device entry. Multiple entries are needed to specify all the targets when the fixed memory window represents interleaved memory. X is the target index from 0. @@ -362,7 +362,7 @@ SRST \ ``-numa cpu,node-id=node[,socket-id=x][,core-id=y][,thread-id=z]`` \ -``-numa hmat-lb,initiator=node,target=node,hierarchy=hierarchy,data-type=tpye[,latency=lat][,bandwidth=bw]`` +``-numa hmat-lb,initiator=node,target=node,hierarchy=hierarchy,data-type=type[,latency=lat][,bandwidth=bw]`` \ ``-numa hmat-cache,node-id=node,size=size,level=level[,associativity=str][,policy=str][,line=size]`` Define a NUMA node and assign RAM and VCPUs to it. Set the NUMA @@ -1785,7 +1785,7 @@ SRST directory on host is made directly accessible by guest as a pass-through file system by using the 9P network protocol for communication between host and guests, if desired even accessible, shared by several guests - simultaniously. + simultaneously. Note that ``-virtfs`` is actually just a convenience shortcut for its generalized form ``-fsdev -device virtio-9p-pci``. diff --git a/tests/qtest/libqos/qgraph.h b/tests/qtest/libqos/qgraph.h index 5c0046e989..287022a67c 100644 --- a/tests/qtest/libqos/qgraph.h +++ b/tests/qtest/libqos/qgraph.h @@ -381,7 +381,7 @@ QOSGraphObject *qos_driver_new(QOSGraphNode *node, QOSGraphObject *parent, * mind: only tests with a path down from the actual test case node (leaf) up * to the graph's root node are actually executed by the qtest framework. And * the qtest framework uses QMP to automatically check which QEMU drivers are - * actually currently available, and accordingly qos marks certain pathes as + * actually currently available, and accordingly qos marks certain paths as * 'unavailable' in such cases (e.g. when QEMU was compiled without support for * a certain feature). */ diff --git a/tests/qtest/libqos/virtio-9p.c b/tests/qtest/libqos/virtio-9p.c index ae9b0a20e2..7f21028256 100644 --- a/tests/qtest/libqos/virtio-9p.c +++ b/tests/qtest/libqos/virtio-9p.c @@ -31,7 +31,7 @@ static QGuestAllocator *alloc; static char *local_test_path; -/* Concatenates the passed 2 pathes. Returned result must be freed. */ +/* Concatenates the passed 2 paths. Returned result must be freed. */ static char *concat_path(const char* a, const char* b) { return g_build_filename(a, b, NULL); From 46b21de238c643ea098f2dcffe493abd135f7d89 Mon Sep 17 00:00:00 2001 From: Song Gao Date: Wed, 9 Nov 2022 10:04:49 +0800 Subject: [PATCH 704/705] hw/loongarch: Fix loongarch fdt addr confict Fix LoongArch check-tcg error: TEST hello on loongarch64 qemu-system-loongarch64: Some ROM regions are overlapping These ROM regions might have been loaded by direct user request or by default. They could be BIOS/firmware images, a guest kernel, initrd or some other file loaded into guest memory. Check whether you intended to load all this guest code, and whether it has been built to load to the correct addresses. The following two regions overlap (in the memory address space): hello ELF program header segment 0 (addresses 0x0000000000200000 - 0x0000000000242000) fdt (addresses 0x0000000000200000 - 0x0000000000300000) make[1]: *** [Makefile:177: run-hello] Error 1 Fixes: 021836936ef ("hw/loongarch: Load FDT table into dram memory space") Reported-by: Richard Henderson Signed-off-by: Song Gao Reviewed-by: Richard Henderson Message-Id: <20221109020449.978064-1-gaosong@loongson.cn> Signed-off-by: Richard Henderson --- hw/loongarch/virt.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index 5e4c2790bf..5136940b0b 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -793,13 +793,13 @@ static void loongarch_init(MachineState *machine) qemu_add_machine_init_done_notifier(&lams->machine_done); fdt_add_pcie_node(lams); /* - * Since lowmem region starts from 0, FDT base address is located - * at 2 MiB to avoid NULL pointer access. - * + * Since lowmem region starts from 0 and Linux kernel legacy start address + * at 2 MiB, FDT base address is located at 1 MiB to avoid NULL pointer + * access. FDT size limit with 1 MiB. * Put the FDT into the memory map as a ROM image: this will ensure * the FDT is copied again upon reset, even if addr points into RAM. */ - fdt_base = 2 * MiB; + fdt_base = 1 * MiB; qemu_fdt_dumpdtb(machine->fdt, lams->fdt_size); rom_add_blob_fixed("fdt", machine->fdt, lams->fdt_size, fdt_base); } From 57bc6e40e82c0446a358ab01f9bbf0db0d9465e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 11 Nov 2022 13:45:50 +0100 Subject: [PATCH 705/705] libvduse: Avoid warning about dangerous use of strncpy() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GCC 8 added a -Wstringop-truncation warning: The -Wstringop-truncation warning added in GCC 8.0 via r254630 for bug 81117 is specifically intended to highlight likely unintended uses of the strncpy function that truncate the terminating NUL character from the source string. Here the next line indeed unconditionally zeroes the last byte, but 1/ the buffer has been calloc'd, so we don't need to add an extra byte, and 2/ we called vduse_name_is_invalid() which checked the string length, so we can simply call strcpy(). This fixes when using gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0: [42/666] Compiling C object subprojects/libvduse/libvduse.a.p/libvduse.c.o FAILED: subprojects/libvduse/libvduse.a.p/libvduse.c.o cc -m64 -mcx16 -Isubprojects/libvduse/libvduse.a.p -Isubprojects/libvduse -I../../subprojects/libvduse [...] -o subprojects/libvduse/libvduse.a.p/libvduse.c.o -c ../../subprojects/libvduse/libvduse.c In file included from /usr/include/string.h:495, from ../../subprojects/libvduse/libvduse.c:24: In function ‘strncpy’, inlined from ‘vduse_dev_create’ at ../../subprojects/libvduse/libvduse.c:1312:5: /usr/include/x86_64-linux-gnu/bits/string_fortified.h:106:10: error: ‘__builtin_strncpy’ specified bound 256 equals destination size [-Werror=stringop-truncation] 106 | return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cc1: all warnings being treated as errors ninja: build stopped: cannot make progress due to previous errors. Fixes: d9cf16c0be ("libvduse: Replace strcpy() with strncpy()") Suggested-by: Markus Armbruster Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Xie Yongji Reviewed-by: Stefan Hajnoczi Tested-by: Bin Meng Signed-off-by: Stefan Hajnoczi Message-Id: <20221111124550.35753-1-philmd@linaro.org> --- subprojects/libvduse/libvduse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subprojects/libvduse/libvduse.c b/subprojects/libvduse/libvduse.c index 1a5981445c..e089d4d546 100644 --- a/subprojects/libvduse/libvduse.c +++ b/subprojects/libvduse/libvduse.c @@ -1309,8 +1309,8 @@ VduseDev *vduse_dev_create(const char *name, uint32_t device_id, goto err_dev; } - strncpy(dev_config->name, name, VDUSE_NAME_MAX); - dev_config->name[VDUSE_NAME_MAX - 1] = '\0'; + assert(!vduse_name_is_invalid(name)); + strcpy(dev_config->name, name); dev_config->device_id = device_id; dev_config->vendor_id = vendor_id; dev_config->features = features;