Commit de2f658b authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20200511' into staging



target-arm queue:
 aspeed: Add boot stub for smp booting
 target/arm: Drop access_el3_aa32ns_aa64any()
 aspeed: Support AST2600A1 silicon revision
 aspeed: sdmc: Implement AST2600 locking behaviour
 nrf51: Tracing cleanups
 target/arm: Improve handling of SVE loads and stores
 target/arm: Don't show TCG-only CPUs in KVM-only QEMU builds
 hw/arm/musicpal: Map the UART devices unconditionally
 target/arm: Fix tcg_gen_gvec_dup_imm vs DUP (indexed)
 target/arm: Use tcg_gen_gvec_5_ptr for sve FMLA/FCMLA

# gpg: Signature made Mon 11 May 2020 14:33:14 BST
# gpg:                using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE
# gpg:                issuer "peter.maydell@linaro.org"
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate]
# gpg:                 aka "Peter Maydell <pmaydell@gmail.com>" [ultimate]
# gpg:                 aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate]
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83  15CF 3C25 25ED 1436 0CDE

* remotes/pmaydell/tags/pull-target-arm-20200511: (34 commits)
  target/arm: Fix tcg_gen_gvec_dup_imm vs DUP (indexed)
  target/arm: Use tcg_gen_gvec_5_ptr for sve FMLA/FCMLA
  hw/arm/musicpal: Map the UART devices unconditionally
  target/arm: Restrict TCG cpus to TCG accel
  target/arm/cpu: Restrict v8M IDAU interface to Aarch32 CPUs
  target/arm/cpu: Use ARRAY_SIZE() to iterate over ARMCPUInfo[]
  target/arm: Make set_feature() available for other files
  target/arm/kvm: Inline set_feature() calls
  target/arm: Remove sve_memopidx
  target/arm: Reuse sve_probe_page for gather loads
  target/arm: Reuse sve_probe_page for scatter stores
  target/arm: Reuse sve_probe_page for gather first-fault loads
  target/arm: Use SVEContLdSt for contiguous stores
  target/arm: Update contiguous first-fault and no-fault loads
  target/arm: Use SVEContLdSt for multi-register contiguous loads
  target/arm: Handle watchpoints in sve_ld1_r
  target/arm: Use SVEContLdSt in sve_ld1_r
  target/arm: Adjust interface of sve_ld1_host_fn
  target/arm: Add sve infrastructure for page lookup
  target/arm: Drop manual handling of set/clear_helper_retaddr
  ...

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents c88f1ffc 7e17d50e
Loading
Loading
Loading
Loading
+255 −138
Original line number Diff line number Diff line
@@ -1231,130 +1231,133 @@ static void notdirty_write(CPUState *cpu, vaddr mem_vaddr, unsigned size,
    }
}

/*
 * Probe for whether the specified guest access is permitted. If it is not
 * permitted then an exception will be taken in the same way as if this
 * were a real access (and we will not return).
 * If the size is 0 or the page requires I/O access, returns NULL; otherwise,
 * returns the address of the host page similar to tlb_vaddr_to_host().
 */
void *probe_access(CPUArchState *env, target_ulong addr, int size,
                   MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
static int probe_access_internal(CPUArchState *env, target_ulong addr,
                                 int fault_size, MMUAccessType access_type,
                                 int mmu_idx, bool nonfault,
                                 void **phost, uintptr_t retaddr)
{
    uintptr_t index = tlb_index(env, mmu_idx, addr);
    CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
    target_ulong tlb_addr;
    target_ulong tlb_addr, page_addr;
    size_t elt_ofs;
    int wp_access;

    g_assert(-(addr | TARGET_PAGE_MASK) >= size);
    int flags;

    switch (access_type) {
    case MMU_DATA_LOAD:
        elt_ofs = offsetof(CPUTLBEntry, addr_read);
        wp_access = BP_MEM_READ;
        break;
    case MMU_DATA_STORE:
        elt_ofs = offsetof(CPUTLBEntry, addr_write);
        wp_access = BP_MEM_WRITE;
        break;
    case MMU_INST_FETCH:
        elt_ofs = offsetof(CPUTLBEntry, addr_code);
        wp_access = BP_MEM_READ;
        break;
    default:
        g_assert_not_reached();
    }
    tlb_addr = tlb_read_ofs(entry, elt_ofs);

    if (unlikely(!tlb_hit(tlb_addr, addr))) {
        if (!victim_tlb_hit(env, mmu_idx, index, elt_ofs,
                            addr & TARGET_PAGE_MASK)) {
            tlb_fill(env_cpu(env), addr, size, access_type, mmu_idx, retaddr);
    page_addr = addr & TARGET_PAGE_MASK;
    if (!tlb_hit_page(tlb_addr, page_addr)) {
        if (!victim_tlb_hit(env, mmu_idx, index, elt_ofs, page_addr)) {
            CPUState *cs = env_cpu(env);
            CPUClass *cc = CPU_GET_CLASS(cs);

            if (!cc->tlb_fill(cs, addr, fault_size, access_type,
                              mmu_idx, nonfault, retaddr)) {
                /* Non-faulting page table read failed.  */
                *phost = NULL;
                return TLB_INVALID_MASK;
            }

            /* TLB resize via tlb_fill may have moved the entry.  */
            index = tlb_index(env, mmu_idx, addr);
            entry = tlb_entry(env, mmu_idx, addr);
        }
        tlb_addr = tlb_read_ofs(entry, elt_ofs);
    }
    flags = tlb_addr & TLB_FLAGS_MASK;

    if (!size) {
        return NULL;
    /* Fold all "mmio-like" bits into TLB_MMIO.  This is not RAM.  */
    if (unlikely(flags & ~(TLB_WATCHPOINT | TLB_NOTDIRTY))) {
        *phost = NULL;
        return TLB_MMIO;
    }

    if (unlikely(tlb_addr & TLB_FLAGS_MASK)) {
        CPUIOTLBEntry *iotlbentry = &env_tlb(env)->d[mmu_idx].iotlb[index];

        /* Reject I/O access, or other required slow-path.  */
        if (tlb_addr & (TLB_MMIO | TLB_BSWAP | TLB_DISCARD_WRITE)) {
            return NULL;
    /* Everything else is RAM. */
    *phost = (void *)((uintptr_t)addr + entry->addend);
    return flags;
}

        /* Handle watchpoints.  */
        if (tlb_addr & TLB_WATCHPOINT) {
            cpu_check_watchpoint(env_cpu(env), addr, size,
                                 iotlbentry->attrs, wp_access, retaddr);
        }
int probe_access_flags(CPUArchState *env, target_ulong addr,
                       MMUAccessType access_type, int mmu_idx,
                       bool nonfault, void **phost, uintptr_t retaddr)
{
    int flags;

    flags = probe_access_internal(env, addr, 0, access_type, mmu_idx,
                                  nonfault, phost, retaddr);

    /* Handle clean RAM pages.  */
        if (tlb_addr & TLB_NOTDIRTY) {
            notdirty_write(env_cpu(env), addr, size, iotlbentry, retaddr);
        }
    if (unlikely(flags & TLB_NOTDIRTY)) {
        uintptr_t index = tlb_index(env, mmu_idx, addr);
        CPUIOTLBEntry *iotlbentry = &env_tlb(env)->d[mmu_idx].iotlb[index];

        notdirty_write(env_cpu(env), addr, 1, iotlbentry, retaddr);
        flags &= ~TLB_NOTDIRTY;
    }

    return (void *)((uintptr_t)addr + entry->addend);
    return flags;
}

void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
                        MMUAccessType access_type, int mmu_idx)
void *probe_access(CPUArchState *env, target_ulong addr, int size,
                   MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
{
    CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
    target_ulong tlb_addr, page;
    size_t elt_ofs;
    void *host;
    int flags;

    switch (access_type) {
    case MMU_DATA_LOAD:
        elt_ofs = offsetof(CPUTLBEntry, addr_read);
        break;
    case MMU_DATA_STORE:
        elt_ofs = offsetof(CPUTLBEntry, addr_write);
        break;
    case MMU_INST_FETCH:
        elt_ofs = offsetof(CPUTLBEntry, addr_code);
        break;
    default:
        g_assert_not_reached();
    }
    g_assert(-(addr | TARGET_PAGE_MASK) >= size);

    page = addr & TARGET_PAGE_MASK;
    tlb_addr = tlb_read_ofs(entry, elt_ofs);
    flags = probe_access_internal(env, addr, size, access_type, mmu_idx,
                                  false, &host, retaddr);

    if (!tlb_hit_page(tlb_addr, page)) {
        uintptr_t index = tlb_index(env, mmu_idx, addr);
    /* Per the interface, size == 0 merely faults the access. */
    if (size == 0) {
        return NULL;
    }

        if (!victim_tlb_hit(env, mmu_idx, index, elt_ofs, page)) {
            CPUState *cs = env_cpu(env);
            CPUClass *cc = CPU_GET_CLASS(cs);
    if (unlikely(flags & (TLB_NOTDIRTY | TLB_WATCHPOINT))) {
        uintptr_t index = tlb_index(env, mmu_idx, addr);
        CPUIOTLBEntry *iotlbentry = &env_tlb(env)->d[mmu_idx].iotlb[index];

            if (!cc->tlb_fill(cs, addr, 0, access_type, mmu_idx, true, 0)) {
                /* Non-faulting page table read failed.  */
                return NULL;
        /* Handle watchpoints.  */
        if (flags & TLB_WATCHPOINT) {
            int wp_access = (access_type == MMU_DATA_STORE
                             ? BP_MEM_WRITE : BP_MEM_READ);
            cpu_check_watchpoint(env_cpu(env), addr, size,
                                 iotlbentry->attrs, wp_access, retaddr);
        }

            /* TLB resize via tlb_fill may have moved the entry.  */
            entry = tlb_entry(env, mmu_idx, addr);
        /* Handle clean RAM pages.  */
        if (flags & TLB_NOTDIRTY) {
            notdirty_write(env_cpu(env), addr, 1, iotlbentry, retaddr);
        }
        tlb_addr = tlb_read_ofs(entry, elt_ofs);
    }

    if (tlb_addr & ~TARGET_PAGE_MASK) {
        /* IO access */
        return NULL;
    return host;
}

    return (void *)((uintptr_t)addr + entry->addend);
}
void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
                        MMUAccessType access_type, int mmu_idx)
{
    void *host;
    int flags;

    flags = probe_access_internal(env, addr, 0, access_type,
                                  mmu_idx, true, &host, 0);

    /* No combination of flags are expected by the caller. */
    return flags ? NULL : host;
}

#ifdef CONFIG_PLUGIN
/*
@@ -1769,36 +1772,54 @@ int cpu_ldsb_mmuidx_ra(CPUArchState *env, abi_ptr addr,
                                   full_ldub_mmu);
}

uint32_t cpu_lduw_mmuidx_ra(CPUArchState *env, abi_ptr addr,
uint32_t cpu_lduw_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
                               int mmu_idx, uintptr_t ra)
{
    return cpu_load_helper(env, addr, mmu_idx, ra, MO_BEUW, full_be_lduw_mmu);
}

int cpu_ldsw_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
                          int mmu_idx, uintptr_t ra)
{
    return (int16_t)cpu_load_helper(env, addr, mmu_idx, ra, MO_BESW,
                                    full_be_lduw_mmu);
}

uint32_t cpu_ldl_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
                              int mmu_idx, uintptr_t ra)
{
    return cpu_load_helper(env, addr, mmu_idx, ra, MO_BEUL, full_be_ldul_mmu);
}

uint64_t cpu_ldq_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
                              int mmu_idx, uintptr_t ra)
{
    return cpu_load_helper(env, addr, mmu_idx, ra, MO_TEUW,
                           MO_TE == MO_LE
                           ? full_le_lduw_mmu : full_be_lduw_mmu);
    return cpu_load_helper(env, addr, mmu_idx, ra, MO_BEQ, helper_be_ldq_mmu);
}

int cpu_ldsw_mmuidx_ra(CPUArchState *env, abi_ptr addr,
uint32_t cpu_lduw_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
                               int mmu_idx, uintptr_t ra)
{
    return (int16_t)cpu_load_helper(env, addr, mmu_idx, ra, MO_TESW,
                                    MO_TE == MO_LE
                                    ? full_le_lduw_mmu : full_be_lduw_mmu);
    return cpu_load_helper(env, addr, mmu_idx, ra, MO_LEUW, full_le_lduw_mmu);
}

uint32_t cpu_ldl_mmuidx_ra(CPUArchState *env, abi_ptr addr,
int cpu_ldsw_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
                          int mmu_idx, uintptr_t ra)
{
    return cpu_load_helper(env, addr, mmu_idx, ra, MO_TEUL,
                           MO_TE == MO_LE
                           ? full_le_ldul_mmu : full_be_ldul_mmu);
    return (int16_t)cpu_load_helper(env, addr, mmu_idx, ra, MO_LESW,
                                    full_le_lduw_mmu);
}

uint32_t cpu_ldl_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
                              int mmu_idx, uintptr_t ra)
{
    return cpu_load_helper(env, addr, mmu_idx, ra, MO_LEUL, full_le_ldul_mmu);
}

uint64_t cpu_ldq_mmuidx_ra(CPUArchState *env, abi_ptr addr,
uint64_t cpu_ldq_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
                              int mmu_idx, uintptr_t ra)
{
    return cpu_load_helper(env, addr, mmu_idx, ra, MO_TEQ,
                           MO_TE == MO_LE
                           ? helper_le_ldq_mmu : helper_be_ldq_mmu);
    return cpu_load_helper(env, addr, mmu_idx, ra, MO_LEQ, helper_le_ldq_mmu);
}

uint32_t cpu_ldub_data_ra(CPUArchState *env, target_ulong ptr,
@@ -1812,25 +1833,50 @@ int cpu_ldsb_data_ra(CPUArchState *env, target_ulong ptr, uintptr_t retaddr)
    return cpu_ldsb_mmuidx_ra(env, ptr, cpu_mmu_index(env, false), retaddr);
}

uint32_t cpu_lduw_data_ra(CPUArchState *env, target_ulong ptr,
uint32_t cpu_lduw_be_data_ra(CPUArchState *env, target_ulong ptr,
                             uintptr_t retaddr)
{
    return cpu_lduw_mmuidx_ra(env, ptr, cpu_mmu_index(env, false), retaddr);
    return cpu_lduw_be_mmuidx_ra(env, ptr, cpu_mmu_index(env, false), retaddr);
}

int cpu_ldsw_data_ra(CPUArchState *env, target_ulong ptr, uintptr_t retaddr)
int cpu_ldsw_be_data_ra(CPUArchState *env, target_ulong ptr, uintptr_t retaddr)
{
    return cpu_ldsw_mmuidx_ra(env, ptr, cpu_mmu_index(env, false), retaddr);
    return cpu_ldsw_be_mmuidx_ra(env, ptr, cpu_mmu_index(env, false), retaddr);
}

uint32_t cpu_ldl_data_ra(CPUArchState *env, target_ulong ptr, uintptr_t retaddr)
uint32_t cpu_ldl_be_data_ra(CPUArchState *env, target_ulong ptr,
                            uintptr_t retaddr)
{
    return cpu_ldl_mmuidx_ra(env, ptr, cpu_mmu_index(env, false), retaddr);
    return cpu_ldl_be_mmuidx_ra(env, ptr, cpu_mmu_index(env, false), retaddr);
}

uint64_t cpu_ldq_data_ra(CPUArchState *env, target_ulong ptr, uintptr_t retaddr)
uint64_t cpu_ldq_be_data_ra(CPUArchState *env, target_ulong ptr,
                            uintptr_t retaddr)
{
    return cpu_ldq_mmuidx_ra(env, ptr, cpu_mmu_index(env, false), retaddr);
    return cpu_ldq_be_mmuidx_ra(env, ptr, cpu_mmu_index(env, false), retaddr);
}

uint32_t cpu_lduw_le_data_ra(CPUArchState *env, target_ulong ptr,
                             uintptr_t retaddr)
{
    return cpu_lduw_le_mmuidx_ra(env, ptr, cpu_mmu_index(env, false), retaddr);
}

int cpu_ldsw_le_data_ra(CPUArchState *env, target_ulong ptr, uintptr_t retaddr)
{
    return cpu_ldsw_le_mmuidx_ra(env, ptr, cpu_mmu_index(env, false), retaddr);
}

uint32_t cpu_ldl_le_data_ra(CPUArchState *env, target_ulong ptr,
                            uintptr_t retaddr)
{
    return cpu_ldl_le_mmuidx_ra(env, ptr, cpu_mmu_index(env, false), retaddr);
}

uint64_t cpu_ldq_le_data_ra(CPUArchState *env, target_ulong ptr,
                            uintptr_t retaddr)
{
    return cpu_ldq_le_mmuidx_ra(env, ptr, cpu_mmu_index(env, false), retaddr);
}

uint32_t cpu_ldub_data(CPUArchState *env, target_ulong ptr)
@@ -1843,24 +1889,44 @@ int cpu_ldsb_data(CPUArchState *env, target_ulong ptr)
    return cpu_ldsb_data_ra(env, ptr, 0);
}

uint32_t cpu_lduw_data(CPUArchState *env, target_ulong ptr)
uint32_t cpu_lduw_be_data(CPUArchState *env, target_ulong ptr)
{
    return cpu_lduw_be_data_ra(env, ptr, 0);
}

int cpu_ldsw_be_data(CPUArchState *env, target_ulong ptr)
{
    return cpu_lduw_data_ra(env, ptr, 0);
    return cpu_ldsw_be_data_ra(env, ptr, 0);
}

int cpu_ldsw_data(CPUArchState *env, target_ulong ptr)
uint32_t cpu_ldl_be_data(CPUArchState *env, target_ulong ptr)
{
    return cpu_ldsw_data_ra(env, ptr, 0);
    return cpu_ldl_be_data_ra(env, ptr, 0);
}

uint32_t cpu_ldl_data(CPUArchState *env, target_ulong ptr)
uint64_t cpu_ldq_be_data(CPUArchState *env, target_ulong ptr)
{
    return cpu_ldl_data_ra(env, ptr, 0);
    return cpu_ldq_be_data_ra(env, ptr, 0);
}

uint64_t cpu_ldq_data(CPUArchState *env, target_ulong ptr)
uint32_t cpu_lduw_le_data(CPUArchState *env, target_ulong ptr)
{
    return cpu_ldq_data_ra(env, ptr, 0);
    return cpu_lduw_le_data_ra(env, ptr, 0);
}

int cpu_ldsw_le_data(CPUArchState *env, target_ulong ptr)
{
    return cpu_ldsw_le_data_ra(env, ptr, 0);
}

uint32_t cpu_ldl_le_data(CPUArchState *env, target_ulong ptr)
{
    return cpu_ldl_le_data_ra(env, ptr, 0);
}

uint64_t cpu_ldq_le_data(CPUArchState *env, target_ulong ptr)
{
    return cpu_ldq_le_data_ra(env, ptr, 0);
}

/*
@@ -2118,22 +2184,40 @@ void cpu_stb_mmuidx_ra(CPUArchState *env, target_ulong addr, uint32_t val,
    cpu_store_helper(env, addr, val, mmu_idx, retaddr, MO_UB);
}

void cpu_stw_mmuidx_ra(CPUArchState *env, target_ulong addr, uint32_t val,
void cpu_stw_be_mmuidx_ra(CPUArchState *env, target_ulong addr, uint32_t val,
                          int mmu_idx, uintptr_t retaddr)
{
    cpu_store_helper(env, addr, val, mmu_idx, retaddr, MO_TEUW);
    cpu_store_helper(env, addr, val, mmu_idx, retaddr, MO_BEUW);
}

void cpu_stl_mmuidx_ra(CPUArchState *env, target_ulong addr, uint32_t val,
void cpu_stl_be_mmuidx_ra(CPUArchState *env, target_ulong addr, uint32_t val,
                          int mmu_idx, uintptr_t retaddr)
{
    cpu_store_helper(env, addr, val, mmu_idx, retaddr, MO_TEUL);
    cpu_store_helper(env, addr, val, mmu_idx, retaddr, MO_BEUL);
}

void cpu_stq_mmuidx_ra(CPUArchState *env, target_ulong addr, uint64_t val,
void cpu_stq_be_mmuidx_ra(CPUArchState *env, target_ulong addr, uint64_t val,
                          int mmu_idx, uintptr_t retaddr)
{
    cpu_store_helper(env, addr, val, mmu_idx, retaddr, MO_TEQ);
    cpu_store_helper(env, addr, val, mmu_idx, retaddr, MO_BEQ);
}

void cpu_stw_le_mmuidx_ra(CPUArchState *env, target_ulong addr, uint32_t val,
                          int mmu_idx, uintptr_t retaddr)
{
    cpu_store_helper(env, addr, val, mmu_idx, retaddr, MO_LEUW);
}

void cpu_stl_le_mmuidx_ra(CPUArchState *env, target_ulong addr, uint32_t val,
                          int mmu_idx, uintptr_t retaddr)
{
    cpu_store_helper(env, addr, val, mmu_idx, retaddr, MO_LEUL);
}

void cpu_stq_le_mmuidx_ra(CPUArchState *env, target_ulong addr, uint64_t val,
                          int mmu_idx, uintptr_t retaddr)
{
    cpu_store_helper(env, addr, val, mmu_idx, retaddr, MO_LEQ);
}

void cpu_stb_data_ra(CPUArchState *env, target_ulong ptr,
@@ -2142,22 +2226,40 @@ void cpu_stb_data_ra(CPUArchState *env, target_ulong ptr,
    cpu_stb_mmuidx_ra(env, ptr, val, cpu_mmu_index(env, false), retaddr);
}

void cpu_stw_data_ra(CPUArchState *env, target_ulong ptr,
void cpu_stw_be_data_ra(CPUArchState *env, target_ulong ptr,
                        uint32_t val, uintptr_t retaddr)
{
    cpu_stw_be_mmuidx_ra(env, ptr, val, cpu_mmu_index(env, false), retaddr);
}

void cpu_stl_be_data_ra(CPUArchState *env, target_ulong ptr,
                        uint32_t val, uintptr_t retaddr)
{
    cpu_stl_be_mmuidx_ra(env, ptr, val, cpu_mmu_index(env, false), retaddr);
}

void cpu_stq_be_data_ra(CPUArchState *env, target_ulong ptr,
                        uint64_t val, uintptr_t retaddr)
{
    cpu_stq_be_mmuidx_ra(env, ptr, val, cpu_mmu_index(env, false), retaddr);
}

void cpu_stw_le_data_ra(CPUArchState *env, target_ulong ptr,
                        uint32_t val, uintptr_t retaddr)
{
    cpu_stw_mmuidx_ra(env, ptr, val, cpu_mmu_index(env, false), retaddr);
    cpu_stw_le_mmuidx_ra(env, ptr, val, cpu_mmu_index(env, false), retaddr);
}

void cpu_stl_data_ra(CPUArchState *env, target_ulong ptr,
void cpu_stl_le_data_ra(CPUArchState *env, target_ulong ptr,
                        uint32_t val, uintptr_t retaddr)
{
    cpu_stl_mmuidx_ra(env, ptr, val, cpu_mmu_index(env, false), retaddr);
    cpu_stl_le_mmuidx_ra(env, ptr, val, cpu_mmu_index(env, false), retaddr);
}

void cpu_stq_data_ra(CPUArchState *env, target_ulong ptr,
void cpu_stq_le_data_ra(CPUArchState *env, target_ulong ptr,
                        uint64_t val, uintptr_t retaddr)
{
    cpu_stq_mmuidx_ra(env, ptr, val, cpu_mmu_index(env, false), retaddr);
    cpu_stq_le_mmuidx_ra(env, ptr, val, cpu_mmu_index(env, false), retaddr);
}

void cpu_stb_data(CPUArchState *env, target_ulong ptr, uint32_t val)
@@ -2165,19 +2267,34 @@ void cpu_stb_data(CPUArchState *env, target_ulong ptr, uint32_t val)
    cpu_stb_data_ra(env, ptr, val, 0);
}

void cpu_stw_data(CPUArchState *env, target_ulong ptr, uint32_t val)
void cpu_stw_be_data(CPUArchState *env, target_ulong ptr, uint32_t val)
{
    cpu_stw_be_data_ra(env, ptr, val, 0);
}

void cpu_stl_be_data(CPUArchState *env, target_ulong ptr, uint32_t val)
{
    cpu_stl_be_data_ra(env, ptr, val, 0);
}

void cpu_stq_be_data(CPUArchState *env, target_ulong ptr, uint64_t val)
{
    cpu_stq_be_data_ra(env, ptr, val, 0);
}

void cpu_stw_le_data(CPUArchState *env, target_ulong ptr, uint32_t val)
{
    cpu_stw_data_ra(env, ptr, val, 0);
    cpu_stw_le_data_ra(env, ptr, val, 0);
}

void cpu_stl_data(CPUArchState *env, target_ulong ptr, uint32_t val)
void cpu_stl_le_data(CPUArchState *env, target_ulong ptr, uint32_t val)
{
    cpu_stl_data_ra(env, ptr, val, 0);
    cpu_stl_le_data_ra(env, ptr, val, 0);
}

void cpu_stq_data(CPUArchState *env, target_ulong ptr, uint64_t val)
void cpu_stq_le_data(CPUArchState *env, target_ulong ptr, uint64_t val)
{
    cpu_stq_data_ra(env, ptr, val, 0);
    cpu_stq_le_data_ra(env, ptr, val, 0);
}

/* First set of helpers allows passing in of OI and RETADDR.  This makes
+208 −48

File changed.

Preview size limit exceeded, changes collapsed.

+27 −12
Original line number Diff line number Diff line
@@ -97,9 +97,9 @@ function, which is a return address into the generated code.

Function names follow the pattern:

load: ``cpu_ld{sign}{size}_mmuidx_ra(env, ptr, mmuidx, retaddr)``
load: ``cpu_ld{sign}{size}{end}_mmuidx_ra(env, ptr, mmuidx, retaddr)``

store: ``cpu_st{size}_mmuidx_ra(env, ptr, val, mmuidx, retaddr)``
store: ``cpu_st{size}{end}_mmuidx_ra(env, ptr, val, mmuidx, retaddr)``

``sign``
 - (empty) : for 32 or 64 bit sizes
@@ -112,9 +112,14 @@ store: ``cpu_st{size}_mmuidx_ra(env, ptr, val, mmuidx, retaddr)``
 - ``l`` : 32 bits
 - ``q`` : 64 bits

``end``
 - (empty) : for target endian, or 8 bit sizes
 - ``_be`` : big endian
 - ``_le`` : little endian

Regexes for git grep:
 - ``\<cpu_ld[us]\?[bwlq]_mmuidx_ra\>``
 - ``\<cpu_st[bwlq]_mmuidx_ra\>``
 - ``\<cpu_ld[us]\?[bwlq](_[bl]e)\?_mmuidx_ra\>``
 - ``\<cpu_st[bwlq](_[bl]e)\?_mmuidx_ra\>``

``cpu_{ld,st}*_data_ra``
~~~~~~~~~~~~~~~~~~~~~~~~
@@ -129,9 +134,9 @@ be performed with a context other than the default.

Function names follow the pattern:

load: ``cpu_ld{sign}{size}_data_ra(env, ptr, ra)``
load: ``cpu_ld{sign}{size}{end}_data_ra(env, ptr, ra)``

store: ``cpu_st{size}_data_ra(env, ptr, val, ra)``
store: ``cpu_st{size}{end}_data_ra(env, ptr, val, ra)``

``sign``
 - (empty) : for 32 or 64 bit sizes
@@ -144,9 +149,14 @@ store: ``cpu_st{size}_data_ra(env, ptr, val, ra)``
 - ``l`` : 32 bits
 - ``q`` : 64 bits

``end``
 - (empty) : for target endian, or 8 bit sizes
 - ``_be`` : big endian
 - ``_le`` : little endian

Regexes for git grep:
 - ``\<cpu_ld[us]\?[bwlq]_data_ra\>``
 - ``\<cpu_st[bwlq]_data_ra\>``
 - ``\<cpu_ld[us]\?[bwlq](_[bl]e)\?_data_ra\>``
 - ``\<cpu_st[bwlq](_[bl]e)\?_data_ra\>``

``cpu_{ld,st}*_data``
~~~~~~~~~~~~~~~~~~~~~
@@ -163,9 +173,9 @@ the CPU state anyway.

Function names follow the pattern:

load: ``cpu_ld{sign}{size}_data(env, ptr)``
load: ``cpu_ld{sign}{size}{end}_data(env, ptr)``

store: ``cpu_st{size}_data(env, ptr, val)``
store: ``cpu_st{size}{end}_data(env, ptr, val)``

``sign``
 - (empty) : for 32 or 64 bit sizes
@@ -178,9 +188,14 @@ store: ``cpu_st{size}_data(env, ptr, val)``
 - ``l`` : 32 bits
 - ``q`` : 64 bits

``end``
 - (empty) : for target endian, or 8 bit sizes
 - ``_be`` : big endian
 - ``_le`` : little endian

Regexes for git grep
 - ``\<cpu_ld[us]\?[bwlq]_data\>``
 - ``\<cpu_st[bwlq]_data\+\>``
 - ``\<cpu_ld[us]\?[bwlq](_[bl]e)\?_data\>``
 - ``\<cpu_st[bwlq](_[bl]e)\?_data\+\>``

``cpu_ld*_code``
~~~~~~~~~~~~~~~~
+1 −1
Original line number Diff line number Diff line
@@ -1127,7 +1127,7 @@ int cpu_watchpoint_address_matches(CPUState *cpu, vaddr addr, vaddr len)
    int ret = 0;

    QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
        if (watchpoint_address_matches(wp, addr, TARGET_PAGE_SIZE)) {
        if (watchpoint_address_matches(wp, addr, len)) {
            ret |= wp->flags;
        }
    }
+69 −4
Original line number Diff line number Diff line
@@ -93,7 +93,7 @@ struct AspeedBoardState {

/* Tacoma hardware value */
#define TACOMA_BMC_HW_STRAP1  0x00000000
#define TACOMA_BMC_HW_STRAP2  0x00000000
#define TACOMA_BMC_HW_STRAP2  0x00000040

/*
 * The max ram region is for firmwares that scan the address space
@@ -116,6 +116,58 @@ static const MemoryRegionOps max_ram_ops = {
    .endianness = DEVICE_NATIVE_ENDIAN,
};

#define AST_SMP_MAILBOX_BASE            0x1e6e2180
#define AST_SMP_MBOX_FIELD_ENTRY        (AST_SMP_MAILBOX_BASE + 0x0)
#define AST_SMP_MBOX_FIELD_GOSIGN       (AST_SMP_MAILBOX_BASE + 0x4)
#define AST_SMP_MBOX_FIELD_READY        (AST_SMP_MAILBOX_BASE + 0x8)
#define AST_SMP_MBOX_FIELD_POLLINSN     (AST_SMP_MAILBOX_BASE + 0xc)
#define AST_SMP_MBOX_CODE               (AST_SMP_MAILBOX_BASE + 0x10)
#define AST_SMP_MBOX_GOSIGN             0xabbaab00

static void aspeed_write_smpboot(ARMCPU *cpu,
                                 const struct arm_boot_info *info)
{
    static const uint32_t poll_mailbox_ready[] = {
        /*
         * r2 = per-cpu go sign value
         * r1 = AST_SMP_MBOX_FIELD_ENTRY
         * r0 = AST_SMP_MBOX_FIELD_GOSIGN
         */
        0xee100fb0,  /* mrc     p15, 0, r0, c0, c0, 5 */
        0xe21000ff,  /* ands    r0, r0, #255          */
        0xe59f201c,  /* ldr     r2, [pc, #28]         */
        0xe1822000,  /* orr     r2, r2, r0            */

        0xe59f1018,  /* ldr     r1, [pc, #24]         */
        0xe59f0018,  /* ldr     r0, [pc, #24]         */

        0xe320f002,  /* wfe                           */
        0xe5904000,  /* ldr     r4, [r0]              */
        0xe1520004,  /* cmp     r2, r4                */
        0x1afffffb,  /* bne     <wfe>                 */
        0xe591f000,  /* ldr     pc, [r1]              */
        AST_SMP_MBOX_GOSIGN,
        AST_SMP_MBOX_FIELD_ENTRY,
        AST_SMP_MBOX_FIELD_GOSIGN,
    };

    rom_add_blob_fixed("aspeed.smpboot", poll_mailbox_ready,
                       sizeof(poll_mailbox_ready),
                       info->smp_loader_start);
}

static void aspeed_reset_secondary(ARMCPU *cpu,
                                   const struct arm_boot_info *info)
{
    AddressSpace *as = arm_boot_address_space(cpu, info);
    CPUState *cs = CPU(cpu);

    /* info->smp_bootreg_addr */
    address_space_stl_notdirty(as, AST_SMP_MBOX_FIELD_GOSIGN, 0,
                               MEMTXATTRS_UNSPECIFIED, NULL);
    cpu_set_pc(cs, info->smp_loader_start);
}

#define FIRMWARE_ADDR 0x0

static void write_boot_rom(DriveInfo *dinfo, hwaddr addr, size_t rom_size,
@@ -270,6 +322,19 @@ static void aspeed_machine_init(MachineState *machine)
        }
    }

    if (machine->kernel_filename && bmc->soc.num_cpus > 1) {
        /* With no u-boot we must set up a boot stub for the secondary CPU */
        MemoryRegion *smpboot = g_new(MemoryRegion, 1);
        memory_region_init_ram(smpboot, OBJECT(bmc), "aspeed.smpboot",
                               0x80, &error_abort);
        memory_region_add_subregion(get_system_memory(),
                                    AST_SMP_MAILBOX_BASE, smpboot);

        aspeed_board_binfo.write_secondary_boot = aspeed_write_smpboot;
        aspeed_board_binfo.secondary_cpu_reset_hook = aspeed_reset_secondary;
        aspeed_board_binfo.smp_loader_start = AST_SMP_MBOX_CODE;
    }

    aspeed_board_binfo.ram_size = ram_size;
    aspeed_board_binfo.loader_start = sc->memmap[ASPEED_SDRAM];
    aspeed_board_binfo.nb_cpus = bmc->soc.num_cpus;
@@ -520,7 +585,7 @@ static void aspeed_machine_ast2600_evb_class_init(ObjectClass *oc, void *data)
    AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);

    mc->desc       = "Aspeed AST2600 EVB (Cortex A7)";
    amc->soc_name  = "ast2600-a0";
    amc->soc_name  = "ast2600-a1";
    amc->hw_strap1 = AST2600_EVB_HW_STRAP1;
    amc->hw_strap2 = AST2600_EVB_HW_STRAP2;
    amc->fmc_model = "w25q512jv";
@@ -535,8 +600,8 @@ static void aspeed_machine_tacoma_class_init(ObjectClass *oc, void *data)
    MachineClass *mc = MACHINE_CLASS(oc);
    AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);

    mc->desc       = "Aspeed AST2600 EVB (Cortex A7)";
    amc->soc_name  = "ast2600-a0";
    mc->desc       = "OpenPOWER Tacoma BMC (Cortex A7)";
    amc->soc_name  = "ast2600-a1";
    amc->hw_strap1 = TACOMA_BMC_HW_STRAP1;
    amc->hw_strap2 = TACOMA_BMC_HW_STRAP2;
    amc->fmc_model = "mx66l1g45g";
Loading