Commit 138985c1 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/amarkovic/tags/mips-queue-sep-12-2019' into staging



MIPS queue for September 12th, 2019

# gpg: Signature made Thu 12 Sep 2019 17:26:10 BST
# gpg:                using RSA key D4972A8967F75A65
# gpg: Good signature from "Aleksandar Markovic <amarkovic@wavecomp.com>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 8526 FBF1 5DA3 811F 4A01  DD75 D497 2A89 67F7 5A65

* remotes/amarkovic/tags/mips-queue-sep-12-2019:
  target/mips: gdbstub: Revert commit 8e0b373f
  hw/mips/mips_jazz: Remove no-longer-necessary override of do_unassigned_access
  target/mips: Switch to do_transaction_failed() hook
  hw/mips/mips_jazz: Override do_transaction_failed hook

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 85182c96 d1cc1533
Loading
Loading
Loading
Loading
+33 −14
Original line number Diff line number Diff line
@@ -111,16 +111,26 @@ static const MemoryRegionOps dma_dummy_ops = {
#define MAGNUM_BIOS_SIZE_MAX 0x7e000
#define MAGNUM_BIOS_SIZE (BIOS_SIZE < MAGNUM_BIOS_SIZE_MAX ? BIOS_SIZE : MAGNUM_BIOS_SIZE_MAX)

static CPUUnassignedAccess real_do_unassigned_access;
static void mips_jazz_do_unassigned_access(CPUState *cpu, hwaddr addr,
                                           bool is_write, bool is_exec,
                                           int opaque, unsigned size)
static void (*real_do_transaction_failed)(CPUState *cpu, hwaddr physaddr,
                                          vaddr addr, unsigned size,
                                          MMUAccessType access_type,
                                          int mmu_idx, MemTxAttrs attrs,
                                          MemTxResult response,
                                          uintptr_t retaddr);

static void mips_jazz_do_transaction_failed(CPUState *cs, hwaddr physaddr,
                                            vaddr addr, unsigned size,
                                            MMUAccessType access_type,
                                            int mmu_idx, MemTxAttrs attrs,
                                            MemTxResult response,
                                            uintptr_t retaddr)
{
    if (!is_exec) {
    if (access_type != MMU_INST_FETCH) {
        /* ignore invalid access (ie do not raise exception) */
        return;
    }
    (*real_do_unassigned_access)(cpu, addr, is_write, is_exec, opaque, size);
    (*real_do_transaction_failed)(cs, physaddr, addr, size, access_type,
                                  mmu_idx, attrs, response, retaddr);
}

static void mips_jazz_init(MachineState *machine,
@@ -157,16 +167,25 @@ static void mips_jazz_init(MachineState *machine,
    env = &cpu->env;
    qemu_register_reset(main_cpu_reset, cpu);

    /* Chipset returns 0 in invalid reads and do not raise data exceptions.
    /*
     * Chipset returns 0 in invalid reads and do not raise data exceptions.
     * However, we can't simply add a global memory region to catch
     * everything, as memory core directly call unassigned_mem_read/write
     * on some invalid accesses, which call do_unassigned_access on the
     * CPU, which raise an exception.
     * Handle that case by hijacking the do_unassigned_access method on
     * the CPU, and do not raise exceptions for data access. */
     * everything, as this would make all accesses including instruction
     * accesses be ignored and not raise exceptions.
     * So instead we hijack the do_transaction_failed method on the CPU, and
     * do not raise exceptions for data access.
     *
     * NOTE: this behaviour of raising exceptions for bad instruction
     * fetches but not bad data accesses was added in commit 54e755588cf1e9
     * to restore behaviour broken by c658b94f6e8c206, but it is not clear
     * whether the real hardware behaves this way. It is possible that
     * real hardware ignores bad instruction fetches as well -- if so then
     * we could replace this hijacking of CPU methods with a simple global
     * memory region that catches all memory accesses, as we do on Malta.
     */
    cc = CPU_GET_CLASS(cpu);
    real_do_unassigned_access = cc->do_unassigned_access;
    cc->do_unassigned_access = mips_jazz_do_unassigned_access;
    real_do_transaction_failed = cc->do_transaction_failed;
    cc->do_transaction_failed = mips_jazz_do_transaction_failed;

    /* allocate RAM */
    memory_region_allocate_system_memory(ram, NULL, "mips_jazz.ram",
+1 −1
Original line number Diff line number Diff line
@@ -202,7 +202,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
    cc->gdb_read_register = mips_cpu_gdb_read_register;
    cc->gdb_write_register = mips_cpu_gdb_write_register;
#ifndef CONFIG_USER_ONLY
    cc->do_unassigned_access = mips_cpu_unassigned_access;
    cc->do_transaction_failed = mips_cpu_do_transaction_failed;
    cc->do_unaligned_access = mips_cpu_do_unaligned_access;
    cc->get_phys_page_debug = mips_cpu_get_phys_page_debug;
    cc->vmsd = &vmstate_mips_cpu;
+1 −2
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ int mips_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
            return gdb_get_regl(mem_buf, (int32_t)env->active_fpu.fcr0);
        default:
            if (env->CP0_Status & (1 << CP0St_FR)) {
                return gdb_get_reg64(mem_buf,
                return gdb_get_regl(mem_buf,
                    env->active_fpu.fpr[n - 38].d);
            } else {
                return gdb_get_regl(mem_buf,
@@ -99,7 +99,6 @@ int mips_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
            break;
        default:
            if (env->CP0_Status & (1 << CP0St_FR)) {
                uint64_t tmp = ldq_p(mem_buf);
                env->active_fpu.fpr[n - 38].d = tmp;
            } else {
                env->active_fpu.fpr[n - 38].w[FP_ENDIAN_IDX] = tmp;
+5 −3
Original line number Diff line number Diff line
@@ -139,9 +139,11 @@ void r4k_helper_tlbinv(CPUMIPSState *env);
void r4k_helper_tlbinvf(CPUMIPSState *env);
void r4k_invalidate_tlb(CPUMIPSState *env, int idx, int use_extra);

void mips_cpu_unassigned_access(CPUState *cpu, hwaddr addr,
                                bool is_write, bool is_exec, int unused,
                                unsigned size);
void mips_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
                                    vaddr addr, unsigned size,
                                    MMUAccessType access_type,
                                    int mmu_idx, MemTxAttrs attrs,
                                    MemTxResult response, uintptr_t retaddr);
hwaddr cpu_mips_translate_address(CPUMIPSState *env, target_ulong address,
                                  int rw);
#endif
+8 −16
Original line number Diff line number Diff line
@@ -2668,27 +2668,19 @@ void mips_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
    do_raise_exception_err(env, excp, error_code, retaddr);
}

void mips_cpu_unassigned_access(CPUState *cs, hwaddr addr,
                                bool is_write, bool is_exec, int unused,
                                unsigned size)
void mips_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
                                    vaddr addr, unsigned size,
                                    MMUAccessType access_type,
                                    int mmu_idx, MemTxAttrs attrs,
                                    MemTxResult response, uintptr_t retaddr)
{
    MIPSCPU *cpu = MIPS_CPU(cs);
    CPUMIPSState *env = &cpu->env;

    /*
     * Raising an exception with KVM enabled will crash because it won't be from
     * the main execution loop so the longjmp won't have a matching setjmp.
     * Until we can trigger a bus error exception through KVM lets just ignore
     * the access.
     */
    if (kvm_enabled()) {
        return;
    }

    if (is_exec) {
        raise_exception(env, EXCP_IBE);
    if (access_type == MMU_INST_FETCH) {
        do_raise_exception(env, EXCP_IBE, retaddr);
    } else {
        raise_exception(env, EXCP_DBE);
        do_raise_exception(env, EXCP_DBE, retaddr);
    }
}
#endif /* !CONFIG_USER_ONLY */