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
 -----BEGIN PGP SIGNATURE-----
 
 iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAl65VBoZHHBldGVyLm1h
 eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3siMEACqZygfkro+GDLDecmIxcHi
 YfRkC8gZ9G+s0xMjcY2rLncYY5eb626R8vROppdJxMWEnRs7aZKTXZEbzFeGXgVc
 uDGf1EyZ8+JNL/GE/D1m2e4WT3qg6TFQM/+FXwnYeQYgSgso/YGQeNMQI1/kiNTq
 HoJJLxESy2z3Nyyc9iudP3z79cRcusoZFFZCWGCoiwde6o2GWM2NjSgEdra5to3H
 31pkI+xEc3PoV2VyXX6K9S7Nvq3zVnaJECSouTbhUzHmkG+/NLCYh4MAYqvvjkPW
 0CNszYJ2nJzyZuIoINdaK4KwQBoywfsjIZgVdUTRg04x7FsE2wq/tJlrvVEVnGAJ
 ARWyoeXPDuy2/Ip+7yrMHZz5jh+aWhQ+5v8Dkvis+payEE6v4004VvEkSWtjppiS
 6GHclpNnYQVXN/1It6Wx/wzaBzIvce/MyrIEgvdYjbYMFky7w5goT/UQS3jTv9gL
 IjuDfF1Nwx4al2l0mPM9Dfpk1OK/W7iFrjdnar02rfKQB2gt7/Ha978jLbB8Qaar
 uvRacc6doyKCliPqA8qUmI52YAm6WHfU3lHwr7825RyjdHRS5YZ4Jfvf03wt6iG5
 ojTEP3z0Waf8S2YDM0PStbG0aQChMaAuVLjZTQmG9JyXgNGhYO+ItXWL0ry1L6+W
 dIFZFdJYqRaWew+wijI/8w==
 =EEFX
 -----END PGP SIGNATURE-----

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: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2020-05-11 14:34:27 +01:00
commit de2f658b6b
33 changed files with 2975 additions and 2248 deletions

View File

@ -1231,86 +1231,16 @@ 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;
size_t elt_ofs;
int wp_access;
g_assert(-(addr | TARGET_PAGE_MASK) >= size);
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);
/* 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);
}
if (!size) {
return NULL;
}
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;
}
/* Handle watchpoints. */
if (tlb_addr & TLB_WATCHPOINT) {
cpu_check_watchpoint(env_cpu(env), addr, size,
iotlbentry->attrs, wp_access, retaddr);
}
/* Handle clean RAM pages. */
if (tlb_addr & TLB_NOTDIRTY) {
notdirty_write(env_cpu(env), addr, size, iotlbentry, retaddr);
}
}
return (void *)((uintptr_t)addr + entry->addend);
}
void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
MMUAccessType access_type, int mmu_idx)
{
CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
target_ulong tlb_addr, page;
target_ulong tlb_addr, page_addr;
size_t elt_ofs;
int flags;
switch (access_type) {
case MMU_DATA_LOAD:
@ -1325,20 +1255,19 @@ void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
default:
g_assert_not_reached();
}
page = addr & TARGET_PAGE_MASK;
tlb_addr = tlb_read_ofs(entry, elt_ofs);
if (!tlb_hit_page(tlb_addr, page)) {
uintptr_t index = tlb_index(env, mmu_idx, addr);
if (!victim_tlb_hit(env, mmu_idx, index, elt_ofs, page)) {
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, 0, access_type, mmu_idx, true, 0)) {
if (!cc->tlb_fill(cs, addr, fault_size, access_type,
mmu_idx, nonfault, retaddr)) {
/* Non-faulting page table read failed. */
return NULL;
*phost = NULL;
return TLB_INVALID_MASK;
}
/* TLB resize via tlb_fill may have moved the entry. */
@ -1346,15 +1275,89 @@ void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
}
tlb_addr = tlb_read_ofs(entry, elt_ofs);
}
flags = tlb_addr & TLB_FLAGS_MASK;
if (tlb_addr & ~TARGET_PAGE_MASK) {
/* IO access */
/* Fold all "mmio-like" bits into TLB_MMIO. This is not RAM. */
if (unlikely(flags & ~(TLB_WATCHPOINT | TLB_NOTDIRTY))) {
*phost = NULL;
return TLB_MMIO;
}
/* Everything else is RAM. */
*phost = (void *)((uintptr_t)addr + entry->addend);
return flags;
}
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 (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 flags;
}
void *probe_access(CPUArchState *env, target_ulong addr, int size,
MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
{
void *host;
int flags;
g_assert(-(addr | TARGET_PAGE_MASK) >= size);
flags = probe_access_internal(env, addr, size, access_type, mmu_idx,
false, &host, retaddr);
/* Per the interface, size == 0 merely faults the access. */
if (size == 0) {
return NULL;
}
return (void *)((uintptr_t)addr + entry->addend);
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];
/* 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);
}
/* Handle clean RAM pages. */
if (flags & TLB_NOTDIRTY) {
notdirty_write(env_cpu(env), addr, 1, iotlbentry, retaddr);
}
}
return host;
}
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,
int mmu_idx, uintptr_t ra)
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_TEUW,
MO_TE == MO_LE
? full_le_lduw_mmu : full_be_lduw_mmu);
return cpu_load_helper(env, addr, mmu_idx, ra, MO_BEUW, full_be_lduw_mmu);
}
int cpu_ldsw_mmuidx_ra(CPUArchState *env, abi_ptr addr,
int mmu_idx, uintptr_t ra)
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_TESW,
MO_TE == MO_LE
? full_le_lduw_mmu : full_be_lduw_mmu);
return (int16_t)cpu_load_helper(env, addr, mmu_idx, ra, MO_BESW,
full_be_lduw_mmu);
}
uint32_t cpu_ldl_mmuidx_ra(CPUArchState *env, abi_ptr addr,
int mmu_idx, uintptr_t ra)
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_TEUL,
MO_TE == MO_LE
? full_le_ldul_mmu : full_be_ldul_mmu);
return cpu_load_helper(env, addr, mmu_idx, ra, MO_BEUL, full_be_ldul_mmu);
}
uint64_t cpu_ldq_mmuidx_ra(CPUArchState *env, abi_ptr addr,
int mmu_idx, uintptr_t ra)
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_TEQ,
MO_TE == MO_LE
? helper_le_ldq_mmu : helper_be_ldq_mmu);
return cpu_load_helper(env, addr, mmu_idx, ra, MO_BEQ, helper_be_ldq_mmu);
}
uint32_t cpu_lduw_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
int mmu_idx, uintptr_t ra)
{
return cpu_load_helper(env, addr, mmu_idx, ra, MO_LEUW, full_le_lduw_mmu);
}
int cpu_ldsw_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_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_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
int mmu_idx, uintptr_t ra)
{
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,
uintptr_t retaddr)
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_data_ra(env, ptr, 0);
return cpu_lduw_be_data_ra(env, ptr, 0);
}
int cpu_ldsw_data(CPUArchState *env, target_ulong ptr)
int cpu_ldsw_be_data(CPUArchState *env, target_ulong ptr)
{
return cpu_ldsw_data_ra(env, ptr, 0);
return cpu_ldsw_be_data_ra(env, ptr, 0);
}
uint32_t cpu_ldl_data(CPUArchState *env, target_ulong ptr)
uint32_t cpu_ldl_be_data(CPUArchState *env, target_ulong ptr)
{
return cpu_ldl_data_ra(env, ptr, 0);
return cpu_ldl_be_data_ra(env, ptr, 0);
}
uint64_t cpu_ldq_data(CPUArchState *env, target_ulong ptr)
uint64_t cpu_ldq_be_data(CPUArchState *env, target_ulong ptr)
{
return cpu_ldq_data_ra(env, ptr, 0);
return cpu_ldq_be_data_ra(env, ptr, 0);
}
uint32_t cpu_lduw_le_data(CPUArchState *env, target_ulong ptr)
{
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,
int mmu_idx, uintptr_t retaddr)
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,
int mmu_idx, uintptr_t retaddr)
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,
int mmu_idx, uintptr_t retaddr)
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,
uint32_t val, uintptr_t retaddr)
void cpu_stw_be_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_be_mmuidx_ra(env, ptr, val, cpu_mmu_index(env, false), retaddr);
}
void cpu_stl_data_ra(CPUArchState *env, target_ulong ptr,
uint32_t val, uintptr_t retaddr)
void cpu_stl_be_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_be_mmuidx_ra(env, ptr, val, cpu_mmu_index(env, false), retaddr);
}
void cpu_stq_data_ra(CPUArchState *env, target_ulong ptr,
uint64_t val, uintptr_t retaddr)
void cpu_stq_be_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_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_le_mmuidx_ra(env, ptr, val, cpu_mmu_index(env, false), retaddr);
}
void cpu_stl_le_data_ra(CPUArchState *env, target_ulong ptr,
uint32_t val, uintptr_t retaddr)
{
cpu_stl_le_mmuidx_ra(env, ptr, val, cpu_mmu_index(env, false), retaddr);
}
void cpu_stq_le_data_ra(CPUArchState *env, target_ulong ptr,
uint64_t val, uintptr_t 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_data_ra(env, ptr, val, 0);
cpu_stw_be_data_ra(env, ptr, val, 0);
}
void cpu_stl_data(CPUArchState *env, target_ulong ptr, uint32_t val)
void cpu_stl_be_data(CPUArchState *env, target_ulong ptr, uint32_t val)
{
cpu_stl_data_ra(env, ptr, val, 0);
cpu_stl_be_data_ra(env, ptr, val, 0);
}
void cpu_stq_data(CPUArchState *env, target_ulong ptr, uint64_t val)
void cpu_stq_be_data(CPUArchState *env, target_ulong ptr, uint64_t val)
{
cpu_stq_data_ra(env, ptr, val, 0);
cpu_stq_be_data_ra(env, ptr, val, 0);
}
void cpu_stw_le_data(CPUArchState *env, target_ulong ptr, uint32_t val)
{
cpu_stw_le_data_ra(env, ptr, val, 0);
}
void cpu_stl_le_data(CPUArchState *env, target_ulong ptr, uint32_t val)
{
cpu_stl_le_data_ra(env, ptr, val, 0);
}
void cpu_stq_le_data(CPUArchState *env, target_ulong ptr, uint64_t val)
{
cpu_stq_le_data_ra(env, ptr, val, 0);
}
/* First set of helpers allows passing in of OI and RETADDR. This makes

View File

@ -190,13 +190,12 @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo_t *info,
g_assert_not_reached();
}
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,
bool nonfault, uintptr_t ra)
{
int flags;
g_assert(-(addr | TARGET_PAGE_MASK) >= size);
switch (access_type) {
case MMU_DATA_STORE:
flags = PAGE_WRITE;
@ -211,13 +210,39 @@ void *probe_access(CPUArchState *env, target_ulong addr, int size,
g_assert_not_reached();
}
if (!guest_addr_valid(addr) || page_check_range(addr, size, flags) < 0) {
CPUState *cpu = env_cpu(env);
CPUClass *cc = CPU_GET_CLASS(cpu);
cc->tlb_fill(cpu, addr, size, access_type, MMU_USER_IDX, false,
retaddr);
g_assert_not_reached();
if (!guest_addr_valid(addr) || page_check_range(addr, 1, flags) < 0) {
if (nonfault) {
return TLB_INVALID_MASK;
} else {
CPUState *cpu = env_cpu(env);
CPUClass *cc = CPU_GET_CLASS(cpu);
cc->tlb_fill(cpu, addr, fault_size, access_type,
MMU_USER_IDX, false, ra);
g_assert_not_reached();
}
}
return 0;
}
int probe_access_flags(CPUArchState *env, target_ulong addr,
MMUAccessType access_type, int mmu_idx,
bool nonfault, void **phost, uintptr_t ra)
{
int flags;
flags = probe_access_internal(env, addr, 0, access_type, nonfault, ra);
*phost = flags ? NULL : g2h(addr);
return flags;
}
void *probe_access(CPUArchState *env, target_ulong addr, int size,
MMUAccessType access_type, int mmu_idx, uintptr_t ra)
{
int flags;
g_assert(-(addr | TARGET_PAGE_MASK) >= size);
flags = probe_access_internal(env, addr, size, access_type, false, ra);
g_assert(flags == 0);
return size ? g2h(addr) : NULL;
}
@ -758,46 +783,90 @@ int cpu_ldsb_data(CPUArchState *env, abi_ptr ptr)
return ret;
}
uint32_t cpu_lduw_data(CPUArchState *env, abi_ptr ptr)
uint32_t cpu_lduw_be_data(CPUArchState *env, abi_ptr ptr)
{
uint32_t ret;
uint16_t meminfo = trace_mem_get_info(MO_TEUW, MMU_USER_IDX, false);
uint16_t meminfo = trace_mem_get_info(MO_BEUW, MMU_USER_IDX, false);
trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
ret = lduw_p(g2h(ptr));
ret = lduw_be_p(g2h(ptr));
qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
return ret;
}
int cpu_ldsw_data(CPUArchState *env, abi_ptr ptr)
int cpu_ldsw_be_data(CPUArchState *env, abi_ptr ptr)
{
int ret;
uint16_t meminfo = trace_mem_get_info(MO_TESW, MMU_USER_IDX, false);
uint16_t meminfo = trace_mem_get_info(MO_BESW, MMU_USER_IDX, false);
trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
ret = ldsw_p(g2h(ptr));
ret = ldsw_be_p(g2h(ptr));
qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
return ret;
}
uint32_t cpu_ldl_data(CPUArchState *env, abi_ptr ptr)
uint32_t cpu_ldl_be_data(CPUArchState *env, abi_ptr ptr)
{
uint32_t ret;
uint16_t meminfo = trace_mem_get_info(MO_TEUL, MMU_USER_IDX, false);
uint16_t meminfo = trace_mem_get_info(MO_BEUL, MMU_USER_IDX, false);
trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
ret = ldl_p(g2h(ptr));
ret = ldl_be_p(g2h(ptr));
qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
return ret;
}
uint64_t cpu_ldq_data(CPUArchState *env, abi_ptr ptr)
uint64_t cpu_ldq_be_data(CPUArchState *env, abi_ptr ptr)
{
uint64_t ret;
uint16_t meminfo = trace_mem_get_info(MO_TEQ, MMU_USER_IDX, false);
uint16_t meminfo = trace_mem_get_info(MO_BEQ, MMU_USER_IDX, false);
trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
ret = ldq_p(g2h(ptr));
ret = ldq_be_p(g2h(ptr));
qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
return ret;
}
uint32_t cpu_lduw_le_data(CPUArchState *env, abi_ptr ptr)
{
uint32_t ret;
uint16_t meminfo = trace_mem_get_info(MO_LEUW, MMU_USER_IDX, false);
trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
ret = lduw_le_p(g2h(ptr));
qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
return ret;
}
int cpu_ldsw_le_data(CPUArchState *env, abi_ptr ptr)
{
int ret;
uint16_t meminfo = trace_mem_get_info(MO_LESW, MMU_USER_IDX, false);
trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
ret = ldsw_le_p(g2h(ptr));
qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
return ret;
}
uint32_t cpu_ldl_le_data(CPUArchState *env, abi_ptr ptr)
{
uint32_t ret;
uint16_t meminfo = trace_mem_get_info(MO_LEUL, MMU_USER_IDX, false);
trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
ret = ldl_le_p(g2h(ptr));
qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
return ret;
}
uint64_t cpu_ldq_le_data(CPUArchState *env, abi_ptr ptr)
{
uint64_t ret;
uint16_t meminfo = trace_mem_get_info(MO_LEQ, MMU_USER_IDX, false);
trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
ret = ldq_le_p(g2h(ptr));
qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
return ret;
}
@ -822,42 +891,82 @@ int cpu_ldsb_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t retaddr)
return ret;
}
uint32_t cpu_lduw_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t retaddr)
uint32_t cpu_lduw_be_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t retaddr)
{
uint32_t ret;
set_helper_retaddr(retaddr);
ret = cpu_lduw_data(env, ptr);
ret = cpu_lduw_be_data(env, ptr);
clear_helper_retaddr();
return ret;
}
int cpu_ldsw_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t retaddr)
int cpu_ldsw_be_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t retaddr)
{
int ret;
set_helper_retaddr(retaddr);
ret = cpu_ldsw_data(env, ptr);
ret = cpu_ldsw_be_data(env, ptr);
clear_helper_retaddr();
return ret;
}
uint32_t cpu_ldl_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t retaddr)
uint32_t cpu_ldl_be_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t retaddr)
{
uint32_t ret;
set_helper_retaddr(retaddr);
ret = cpu_ldl_data(env, ptr);
ret = cpu_ldl_be_data(env, ptr);
clear_helper_retaddr();
return ret;
}
uint64_t cpu_ldq_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t retaddr)
uint64_t cpu_ldq_be_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t retaddr)
{
uint64_t ret;
set_helper_retaddr(retaddr);
ret = cpu_ldq_data(env, ptr);
ret = cpu_ldq_be_data(env, ptr);
clear_helper_retaddr();
return ret;
}
uint32_t cpu_lduw_le_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t retaddr)
{
uint32_t ret;
set_helper_retaddr(retaddr);
ret = cpu_lduw_le_data(env, ptr);
clear_helper_retaddr();
return ret;
}
int cpu_ldsw_le_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t retaddr)
{
int ret;
set_helper_retaddr(retaddr);
ret = cpu_ldsw_le_data(env, ptr);
clear_helper_retaddr();
return ret;
}
uint32_t cpu_ldl_le_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t retaddr)
{
uint32_t ret;
set_helper_retaddr(retaddr);
ret = cpu_ldl_le_data(env, ptr);
clear_helper_retaddr();
return ret;
}
uint64_t cpu_ldq_le_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t retaddr)
{
uint64_t ret;
set_helper_retaddr(retaddr);
ret = cpu_ldq_le_data(env, ptr);
clear_helper_retaddr();
return ret;
}
@ -871,30 +980,57 @@ void cpu_stb_data(CPUArchState *env, abi_ptr ptr, uint32_t val)
qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
}
void cpu_stw_data(CPUArchState *env, abi_ptr ptr, uint32_t val)
void cpu_stw_be_data(CPUArchState *env, abi_ptr ptr, uint32_t val)
{
uint16_t meminfo = trace_mem_get_info(MO_TEUW, MMU_USER_IDX, true);
uint16_t meminfo = trace_mem_get_info(MO_BEUW, MMU_USER_IDX, true);
trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
stw_p(g2h(ptr), val);
stw_be_p(g2h(ptr), val);
qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
}
void cpu_stl_data(CPUArchState *env, abi_ptr ptr, uint32_t val)
void cpu_stl_be_data(CPUArchState *env, abi_ptr ptr, uint32_t val)
{
uint16_t meminfo = trace_mem_get_info(MO_TEUL, MMU_USER_IDX, true);
uint16_t meminfo = trace_mem_get_info(MO_BEUL, MMU_USER_IDX, true);
trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
stl_p(g2h(ptr), val);
stl_be_p(g2h(ptr), val);
qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
}
void cpu_stq_data(CPUArchState *env, abi_ptr ptr, uint64_t val)
void cpu_stq_be_data(CPUArchState *env, abi_ptr ptr, uint64_t val)
{
uint16_t meminfo = trace_mem_get_info(MO_TEQ, MMU_USER_IDX, true);
uint16_t meminfo = trace_mem_get_info(MO_BEQ, MMU_USER_IDX, true);
trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
stq_p(g2h(ptr), val);
stq_be_p(g2h(ptr), val);
qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
}
void cpu_stw_le_data(CPUArchState *env, abi_ptr ptr, uint32_t val)
{
uint16_t meminfo = trace_mem_get_info(MO_LEUW, MMU_USER_IDX, true);
trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
stw_le_p(g2h(ptr), val);
qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
}
void cpu_stl_le_data(CPUArchState *env, abi_ptr ptr, uint32_t val)
{
uint16_t meminfo = trace_mem_get_info(MO_LEUL, MMU_USER_IDX, true);
trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
stl_le_p(g2h(ptr), val);
qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
}
void cpu_stq_le_data(CPUArchState *env, abi_ptr ptr, uint64_t val)
{
uint16_t meminfo = trace_mem_get_info(MO_LEQ, MMU_USER_IDX, true);
trace_guest_mem_before_exec(env_cpu(env), ptr, meminfo);
stq_le_p(g2h(ptr), val);
qemu_plugin_vcpu_mem_cb(env_cpu(env), ptr, meminfo);
}
@ -906,27 +1042,51 @@ void cpu_stb_data_ra(CPUArchState *env, abi_ptr ptr,
clear_helper_retaddr();
}
void cpu_stw_data_ra(CPUArchState *env, abi_ptr ptr,
uint32_t val, uintptr_t retaddr)
void cpu_stw_be_data_ra(CPUArchState *env, abi_ptr ptr,
uint32_t val, uintptr_t retaddr)
{
set_helper_retaddr(retaddr);
cpu_stw_data(env, ptr, val);
cpu_stw_be_data(env, ptr, val);
clear_helper_retaddr();
}
void cpu_stl_data_ra(CPUArchState *env, abi_ptr ptr,
uint32_t val, uintptr_t retaddr)
void cpu_stl_be_data_ra(CPUArchState *env, abi_ptr ptr,
uint32_t val, uintptr_t retaddr)
{
set_helper_retaddr(retaddr);
cpu_stl_data(env, ptr, val);
cpu_stl_be_data(env, ptr, val);
clear_helper_retaddr();
}
void cpu_stq_data_ra(CPUArchState *env, abi_ptr ptr,
uint64_t val, uintptr_t retaddr)
void cpu_stq_be_data_ra(CPUArchState *env, abi_ptr ptr,
uint64_t val, uintptr_t retaddr)
{
set_helper_retaddr(retaddr);
cpu_stq_data(env, ptr, val);
cpu_stq_be_data(env, ptr, val);
clear_helper_retaddr();
}
void cpu_stw_le_data_ra(CPUArchState *env, abi_ptr ptr,
uint32_t val, uintptr_t retaddr)
{
set_helper_retaddr(retaddr);
cpu_stw_le_data(env, ptr, val);
clear_helper_retaddr();
}
void cpu_stl_le_data_ra(CPUArchState *env, abi_ptr ptr,
uint32_t val, uintptr_t retaddr)
{
set_helper_retaddr(retaddr);
cpu_stl_le_data(env, ptr, val);
clear_helper_retaddr();
}
void cpu_stq_le_data_ra(CPUArchState *env, abi_ptr ptr,
uint64_t val, uintptr_t retaddr)
{
set_helper_retaddr(retaddr);
cpu_stq_le_data(env, ptr, val);
clear_helper_retaddr();
}

View File

@ -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``
~~~~~~~~~~~~~~~~

2
exec.c
View File

@ -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;
}
}

View File

@ -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";

View File

@ -557,9 +557,9 @@ static void aspeed_soc_ast2600_class_init(ObjectClass *oc, void *data)
dc->realize = aspeed_soc_ast2600_realize;
sc->name = "ast2600-a0";
sc->name = "ast2600-a1";
sc->cpu_type = ARM_CPU_TYPE_NAME("cortex-a7");
sc->silicon_rev = AST2600_A0_SILICON_REV;
sc->silicon_rev = AST2600_A1_SILICON_REV;
sc->sram_size = 0x10000;
sc->spis_num = 2;
sc->ehcis_num = 2;
@ -571,7 +571,7 @@ static void aspeed_soc_ast2600_class_init(ObjectClass *oc, void *data)
}
static const TypeInfo aspeed_soc_ast2600_type_info = {
.name = "ast2600-a0",
.name = "ast2600-a1",
.parent = TYPE_ASPEED_SOC,
.instance_size = sizeof(AspeedSoCState),
.instance_init = aspeed_soc_ast2600_init,

View File

@ -1619,14 +1619,10 @@ static void musicpal_init(MachineState *machine)
pic[MP_TIMER2_IRQ], pic[MP_TIMER3_IRQ],
pic[MP_TIMER4_IRQ], NULL);
if (serial_hd(0)) {
serial_mm_init(address_space_mem, MP_UART1_BASE, 2, pic[MP_UART1_IRQ],
1825000, serial_hd(0), DEVICE_NATIVE_ENDIAN);
}
if (serial_hd(1)) {
serial_mm_init(address_space_mem, MP_UART2_BASE, 2, pic[MP_UART2_IRQ],
1825000, serial_hd(1), DEVICE_NATIVE_ENDIAN);
}
serial_mm_init(address_space_mem, MP_UART1_BASE, 2, pic[MP_UART1_IRQ],
1825000, serial_hd(0), DEVICE_NATIVE_ENDIAN);
serial_mm_init(address_space_mem, MP_UART2_BASE, 2, pic[MP_UART2_IRQ],
1825000, serial_hd(1), DEVICE_NATIVE_ENDIAN);
/* Register flash */
dinfo = drive_get(IF_PFLASH, 0, 0);

View File

@ -150,13 +150,18 @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
/* TIMER */
for (i = 0; i < NRF51_NUM_TIMERS; i++) {
object_property_set_uint(OBJECT(&s->timer[i]), i, "id", &err);
if (err) {
error_propagate(errp, err);
return;
}
object_property_set_bool(OBJECT(&s->timer[i]), true, "realized", &err);
if (err) {
error_propagate(errp, err);
return;
}
base_addr = NRF51_TIMER_BASE + i * NRF51_TIMER_SIZE;
base_addr = NRF51_TIMER_BASE + i * NRF51_PERIPHERAL_SIZE;
sysbus_mmio_map(SYS_BUS_DEVICE(&s->timer[i]), 0, base_addr);
sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer[i]), 0,
@ -166,7 +171,7 @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
/* STUB Peripherals */
memory_region_init_io(&s->clock, OBJECT(dev_soc), &clock_ops, NULL,
"nrf51_soc.clock", 0x1000);
"nrf51_soc.clock", NRF51_PERIPHERAL_SIZE);
memory_region_add_subregion_overlap(&s->container,
NRF51_IOMEM_BASE, &s->clock, -1);

View File

@ -100,7 +100,7 @@ static void microbit_i2c_realize(DeviceState *dev, Error **errp)
MicrobitI2CState *s = MICROBIT_I2C(dev);
memory_region_init_io(&s->iomem, OBJECT(s), &microbit_i2c_ops, s,
"microbit.twi", NRF51_TWI_SIZE);
"microbit.twi", NRF51_PERIPHERAL_SIZE);
sysbus_init_mmio(sbd, &s->iomem);
}

View File

@ -431,6 +431,7 @@ static uint32_t aspeed_silicon_revs[] = {
AST2500_A0_SILICON_REV,
AST2500_A1_SILICON_REV,
AST2600_A0_SILICON_REV,
AST2600_A1_SILICON_REV,
};
bool is_supported_silicon_rev(uint32_t silicon_rev)
@ -649,12 +650,10 @@ static const MemoryRegionOps aspeed_ast2600_scu_ops = {
.valid.unaligned = false,
};
static const uint32_t ast2600_a0_resets[ASPEED_AST2600_SCU_NR_REGS] = {
[AST2600_SILICON_REV] = AST2600_SILICON_REV,
[AST2600_SILICON_REV2] = AST2600_SILICON_REV,
[AST2600_SYS_RST_CTRL] = 0xF7CFFEDC | 0x100,
static const uint32_t ast2600_a1_resets[ASPEED_AST2600_SCU_NR_REGS] = {
[AST2600_SYS_RST_CTRL] = 0xF7C3FED8,
[AST2600_SYS_RST_CTRL2] = 0xFFFFFFFC,
[AST2600_CLK_STOP_CTRL] = 0xEFF43E8B,
[AST2600_CLK_STOP_CTRL] = 0xFFFF7F8A,
[AST2600_CLK_STOP_CTRL2] = 0xFFF0FFF0,
[AST2600_SDRAM_HANDSHAKE] = 0x00000040, /* SoC completed DRAM init */
[AST2600_HPLL_PARAM] = 0x1000405F,
@ -684,7 +683,7 @@ static void aspeed_2600_scu_class_init(ObjectClass *klass, void *data)
dc->desc = "ASPEED 2600 System Control Unit";
dc->reset = aspeed_ast2600_scu_reset;
asc->resets = ast2600_a0_resets;
asc->resets = ast2600_a1_resets;
asc->calc_hpll = aspeed_2500_scu_calc_hpll; /* No change since AST2500 */
asc->apb_divider = 4;
asc->nr_regs = ASPEED_AST2600_SCU_NR_REGS;

View File

@ -23,7 +23,12 @@
/* Protection Key Register */
#define R_PROT (0x00 / 4)
#define PROT_UNLOCKED 0x01
#define PROT_HARDLOCKED 0x10 /* AST2600 */
#define PROT_SOFTLOCKED 0x00
#define PROT_KEY_UNLOCK 0xFC600309
#define PROT_KEY_HARDLOCK 0xDEADDEAD /* AST2600 */
/* Configuration Register */
#define R_CONF (0x04 / 4)
@ -130,16 +135,6 @@ static void aspeed_sdmc_write(void *opaque, hwaddr addr, uint64_t data,
return;
}
if (addr == R_PROT) {
s->regs[addr] = (data == PROT_KEY_UNLOCK) ? 1 : 0;
return;
}
if (!s->regs[R_PROT]) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: SDMC is locked!\n", __func__);
return;
}
asc->write(s, addr, data);
}
@ -320,6 +315,16 @@ static uint32_t aspeed_2400_sdmc_compute_conf(AspeedSDMCState *s, uint32_t data)
static void aspeed_2400_sdmc_write(AspeedSDMCState *s, uint32_t reg,
uint32_t data)
{
if (reg == R_PROT) {
s->regs[reg] = (data == PROT_KEY_UNLOCK) ? PROT_UNLOCKED : PROT_SOFTLOCKED;
return;
}
if (!s->regs[R_PROT]) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: SDMC is locked!\n", __func__);
return;
}
switch (reg) {
case R_CONF:
data = aspeed_2400_sdmc_compute_conf(s, data);
@ -368,6 +373,16 @@ static uint32_t aspeed_2500_sdmc_compute_conf(AspeedSDMCState *s, uint32_t data)
static void aspeed_2500_sdmc_write(AspeedSDMCState *s, uint32_t reg,
uint32_t data)
{
if (reg == R_PROT) {
s->regs[reg] = (data == PROT_KEY_UNLOCK) ? PROT_UNLOCKED : PROT_SOFTLOCKED;
return;
}
if (!s->regs[R_PROT]) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: SDMC is locked!\n", __func__);
return;
}
switch (reg) {
case R_CONF:
data = aspeed_2500_sdmc_compute_conf(s, data);
@ -424,7 +439,27 @@ static uint32_t aspeed_2600_sdmc_compute_conf(AspeedSDMCState *s, uint32_t data)
static void aspeed_2600_sdmc_write(AspeedSDMCState *s, uint32_t reg,
uint32_t data)
{
if (s->regs[R_PROT] == PROT_HARDLOCKED) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: SDMC is locked until system reset!\n",
__func__);
return;
}
if (reg != R_PROT && s->regs[R_PROT] == PROT_SOFTLOCKED) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: SDMC is locked!\n", __func__);
return;
}
switch (reg) {
case R_PROT:
if (data == PROT_KEY_UNLOCK) {
data = PROT_UNLOCKED;
} else if (data == PROT_KEY_HARDLOCK) {
data = PROT_HARDLOCKED;
} else {
data = PROT_SOFTLOCKED;
}
break;
case R_CONF:
data = aspeed_2600_sdmc_compute_conf(s, data);
break;

View File

@ -17,6 +17,7 @@
#include "hw/arm/nrf51.h"
#include "hw/irq.h"
#include "hw/timer/nrf51_timer.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
#include "trace.h"
@ -185,7 +186,7 @@ static uint64_t nrf51_timer_read(void *opaque, hwaddr offset, unsigned int size)
__func__, offset);
}
trace_nrf51_timer_read(offset, r, size);
trace_nrf51_timer_read(s->id, offset, r, size);
return r;
}
@ -197,7 +198,7 @@ static void nrf51_timer_write(void *opaque, hwaddr offset,
uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
size_t idx;
trace_nrf51_timer_write(offset, value, size);
trace_nrf51_timer_write(s->id, offset, value, size);
switch (offset) {
case NRF51_TIMER_TASK_START:
@ -239,6 +240,7 @@ static void nrf51_timer_write(void *opaque, hwaddr offset,
idx = (offset - NRF51_TIMER_TASK_CAPTURE_0) / 4;
s->cc[idx] = s->counter;
trace_nrf51_timer_set_count(s->id, idx, s->counter);
}
break;
case NRF51_TIMER_EVENT_COMPARE_0 ... NRF51_TIMER_EVENT_COMPARE_3:
@ -313,7 +315,7 @@ static void nrf51_timer_init(Object *obj)
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
memory_region_init_io(&s->iomem, obj, &rng_ops, s,
TYPE_NRF51_TIMER, NRF51_TIMER_SIZE);
TYPE_NRF51_TIMER, NRF51_PERIPHERAL_SIZE);
sysbus_init_mmio(sbd, &s->iomem);
sysbus_init_irq(sbd, &s->irq);
@ -372,12 +374,18 @@ static const VMStateDescription vmstate_nrf51_timer = {
}
};
static Property nrf51_timer_properties[] = {
DEFINE_PROP_UINT8("id", NRF51TimerState, id, 0),
DEFINE_PROP_END_OF_LIST(),
};
static void nrf51_timer_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->reset = nrf51_timer_reset;
dc->vmsd = &vmstate_nrf51_timer;
device_class_set_props(dc, nrf51_timer_properties);
}
static const TypeInfo nrf51_timer_info = {

View File

@ -67,8 +67,9 @@ cmsdk_apb_dualtimer_write(uint64_t offset, uint64_t data, unsigned size) "CMSDK
cmsdk_apb_dualtimer_reset(void) "CMSDK APB dualtimer: reset"
# nrf51_timer.c
nrf51_timer_read(uint64_t addr, uint32_t value, unsigned size) "read addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
nrf51_timer_write(uint64_t addr, uint32_t value, unsigned size) "write addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
nrf51_timer_read(uint8_t timer_id, uint64_t addr, uint32_t value, unsigned size) "timer %u read addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
nrf51_timer_write(uint8_t timer_id, uint64_t addr, uint32_t value, unsigned size) "timer %u write addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
nrf51_timer_set_count(uint8_t timer_id, uint8_t counter_id, uint32_t value) "timer %u counter %u count 0x%" PRIx32
# bcm2835_systmr.c
bcm2835_systmr_irq(bool enable) "timer irq state %u"

View File

@ -328,7 +328,18 @@ CPUArchState *cpu_copy(CPUArchState *env);
| CPU_INTERRUPT_TGT_EXT_3 \
| CPU_INTERRUPT_TGT_EXT_4)
#if !defined(CONFIG_USER_ONLY)
#ifdef CONFIG_USER_ONLY
/*
* Allow some level of source compatibility with softmmu. We do not
* support any of the more exotic features, so only invalid pages may
* be signaled by probe_access_flags().
*/
#define TLB_INVALID_MASK (1 << (TARGET_PAGE_BITS_MIN - 1))
#define TLB_MMIO 0
#define TLB_WATCHPOINT 0
#else
/*
* Flags stored in the low bits of the TLB virtual address.

View File

@ -25,13 +25,13 @@
*
* The syntax for the accessors is:
*
* load: cpu_ld{sign}{size}_{mmusuffix}(env, ptr)
* cpu_ld{sign}{size}_{mmusuffix}_ra(env, ptr, retaddr)
* cpu_ld{sign}{size}_mmuidx_ra(env, ptr, mmu_idx, retaddr)
* load: cpu_ld{sign}{size}{end}_{mmusuffix}(env, ptr)
* cpu_ld{sign}{size}{end}_{mmusuffix}_ra(env, ptr, retaddr)
* cpu_ld{sign}{size}{end}_mmuidx_ra(env, ptr, mmu_idx, retaddr)
*
* store: cpu_st{size}_{mmusuffix}(env, ptr, val)
* cpu_st{size}_{mmusuffix}_ra(env, ptr, val, retaddr)
* cpu_st{size}_mmuidx_ra(env, ptr, val, mmu_idx, retaddr)
* store: cpu_st{size}{end}_{mmusuffix}(env, ptr, val)
* cpu_st{size}{end}_{mmusuffix}_ra(env, ptr, val, retaddr)
* cpu_st{size}{end}_mmuidx_ra(env, ptr, val, mmu_idx, retaddr)
*
* sign is:
* (empty): for 32 and 64 bit sizes
@ -44,6 +44,11 @@
* l: 32 bits
* q: 64 bits
*
* end is:
* (empty): for target native endian, or for 8 bit access
* _be: for forced big endian
* _le: for forced little endian
*
* mmusuffix is one of the generic suffixes "data" or "code", or "mmuidx".
* The "mmuidx" suffix carries an extra mmu_idx argument that specifies
* the index to use; the "data" and "code" suffixes take the index from
@ -95,32 +100,57 @@ typedef target_ulong abi_ptr;
#endif
uint32_t cpu_ldub_data(CPUArchState *env, abi_ptr ptr);
uint32_t cpu_lduw_data(CPUArchState *env, abi_ptr ptr);
uint32_t cpu_ldl_data(CPUArchState *env, abi_ptr ptr);
uint64_t cpu_ldq_data(CPUArchState *env, abi_ptr ptr);
int cpu_ldsb_data(CPUArchState *env, abi_ptr ptr);
int cpu_ldsw_data(CPUArchState *env, abi_ptr ptr);
uint32_t cpu_ldub_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t retaddr);
uint32_t cpu_lduw_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t retaddr);
uint32_t cpu_ldl_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t retaddr);
uint64_t cpu_ldq_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t retaddr);
int cpu_ldsb_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t retaddr);
int cpu_ldsw_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t retaddr);
uint32_t cpu_lduw_be_data(CPUArchState *env, abi_ptr ptr);
int cpu_ldsw_be_data(CPUArchState *env, abi_ptr ptr);
uint32_t cpu_ldl_be_data(CPUArchState *env, abi_ptr ptr);
uint64_t cpu_ldq_be_data(CPUArchState *env, abi_ptr ptr);
uint32_t cpu_lduw_le_data(CPUArchState *env, abi_ptr ptr);
int cpu_ldsw_le_data(CPUArchState *env, abi_ptr ptr);
uint32_t cpu_ldl_le_data(CPUArchState *env, abi_ptr ptr);
uint64_t cpu_ldq_le_data(CPUArchState *env, abi_ptr ptr);
uint32_t cpu_ldub_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t ra);
int cpu_ldsb_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t ra);
uint32_t cpu_lduw_be_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t ra);
int cpu_ldsw_be_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t ra);
uint32_t cpu_ldl_be_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t ra);
uint64_t cpu_ldq_be_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t ra);
uint32_t cpu_lduw_le_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t ra);
int cpu_ldsw_le_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t ra);
uint32_t cpu_ldl_le_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t ra);
uint64_t cpu_ldq_le_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t ra);
void cpu_stb_data(CPUArchState *env, abi_ptr ptr, uint32_t val);
void cpu_stw_data(CPUArchState *env, abi_ptr ptr, uint32_t val);
void cpu_stl_data(CPUArchState *env, abi_ptr ptr, uint32_t val);
void cpu_stq_data(CPUArchState *env, abi_ptr ptr, uint64_t val);
void cpu_stw_be_data(CPUArchState *env, abi_ptr ptr, uint32_t val);
void cpu_stl_be_data(CPUArchState *env, abi_ptr ptr, uint32_t val);
void cpu_stq_be_data(CPUArchState *env, abi_ptr ptr, uint64_t val);
void cpu_stw_le_data(CPUArchState *env, abi_ptr ptr, uint32_t val);
void cpu_stl_le_data(CPUArchState *env, abi_ptr ptr, uint32_t val);
void cpu_stq_le_data(CPUArchState *env, abi_ptr ptr, uint64_t val);
void cpu_stb_data_ra(CPUArchState *env, abi_ptr ptr,
uint32_t val, uintptr_t retaddr);
void cpu_stw_data_ra(CPUArchState *env, abi_ptr ptr,
uint32_t val, uintptr_t retaddr);
void cpu_stl_data_ra(CPUArchState *env, abi_ptr ptr,
uint32_t val, uintptr_t retaddr);
void cpu_stq_data_ra(CPUArchState *env, abi_ptr ptr,
uint64_t val, uintptr_t retaddr);
uint32_t val, uintptr_t ra);
void cpu_stw_be_data_ra(CPUArchState *env, abi_ptr ptr,
uint32_t val, uintptr_t ra);
void cpu_stl_be_data_ra(CPUArchState *env, abi_ptr ptr,
uint32_t val, uintptr_t ra);
void cpu_stq_be_data_ra(CPUArchState *env, abi_ptr ptr,
uint64_t val, uintptr_t ra);
void cpu_stw_le_data_ra(CPUArchState *env, abi_ptr ptr,
uint32_t val, uintptr_t ra);
void cpu_stl_le_data_ra(CPUArchState *env, abi_ptr ptr,
uint32_t val, uintptr_t ra);
void cpu_stq_le_data_ra(CPUArchState *env, abi_ptr ptr,
uint64_t val, uintptr_t ra);
#if defined(CONFIG_USER_ONLY)
@ -157,34 +187,58 @@ static inline uint32_t cpu_ldub_mmuidx_ra(CPUArchState *env, abi_ptr addr,
return cpu_ldub_data_ra(env, addr, ra);
}
static inline uint32_t cpu_lduw_mmuidx_ra(CPUArchState *env, abi_ptr addr,
int mmu_idx, uintptr_t ra)
{
return cpu_lduw_data_ra(env, addr, ra);
}
static inline uint32_t cpu_ldl_mmuidx_ra(CPUArchState *env, abi_ptr addr,
int mmu_idx, uintptr_t ra)
{
return cpu_ldl_data_ra(env, addr, ra);
}
static inline uint64_t cpu_ldq_mmuidx_ra(CPUArchState *env, abi_ptr addr,
int mmu_idx, uintptr_t ra)
{
return cpu_ldq_data_ra(env, addr, ra);
}
static inline int cpu_ldsb_mmuidx_ra(CPUArchState *env, abi_ptr addr,
int mmu_idx, uintptr_t ra)
{
return cpu_ldsb_data_ra(env, addr, ra);
}
static inline int cpu_ldsw_mmuidx_ra(CPUArchState *env, abi_ptr addr,
int mmu_idx, uintptr_t ra)
static inline uint32_t cpu_lduw_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
int mmu_idx, uintptr_t ra)
{
return cpu_ldsw_data_ra(env, addr, ra);
return cpu_lduw_be_data_ra(env, addr, ra);
}
static inline int cpu_ldsw_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
int mmu_idx, uintptr_t ra)
{
return cpu_ldsw_be_data_ra(env, addr, ra);
}
static inline uint32_t cpu_ldl_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
int mmu_idx, uintptr_t ra)
{
return cpu_ldl_be_data_ra(env, addr, ra);
}
static inline uint64_t cpu_ldq_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
int mmu_idx, uintptr_t ra)
{
return cpu_ldq_be_data_ra(env, addr, ra);
}
static inline uint32_t cpu_lduw_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
int mmu_idx, uintptr_t ra)
{
return cpu_lduw_le_data_ra(env, addr, ra);
}
static inline int cpu_ldsw_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
int mmu_idx, uintptr_t ra)
{
return cpu_ldsw_le_data_ra(env, addr, ra);
}
static inline uint32_t cpu_ldl_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
int mmu_idx, uintptr_t ra)
{
return cpu_ldl_le_data_ra(env, addr, ra);
}
static inline uint64_t cpu_ldq_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
int mmu_idx, uintptr_t ra)
{
return cpu_ldq_le_data_ra(env, addr, ra);
}
static inline void cpu_stb_mmuidx_ra(CPUArchState *env, abi_ptr addr,
@ -193,22 +247,46 @@ static inline void cpu_stb_mmuidx_ra(CPUArchState *env, abi_ptr addr,
cpu_stb_data_ra(env, addr, val, ra);
}
static inline void cpu_stw_mmuidx_ra(CPUArchState *env, abi_ptr addr,
uint32_t val, int mmu_idx, uintptr_t ra)
static inline void cpu_stw_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
uint32_t val, int mmu_idx,
uintptr_t ra)
{
cpu_stw_data_ra(env, addr, val, ra);
cpu_stw_be_data_ra(env, addr, val, ra);
}
static inline void cpu_stl_mmuidx_ra(CPUArchState *env, abi_ptr addr,
uint32_t val, int mmu_idx, uintptr_t ra)
static inline void cpu_stl_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
uint32_t val, int mmu_idx,
uintptr_t ra)
{
cpu_stl_data_ra(env, addr, val, ra);
cpu_stl_be_data_ra(env, addr, val, ra);
}
static inline void cpu_stq_mmuidx_ra(CPUArchState *env, abi_ptr addr,
uint64_t val, int mmu_idx, uintptr_t ra)
static inline void cpu_stq_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
uint64_t val, int mmu_idx,
uintptr_t ra)
{
cpu_stq_data_ra(env, addr, val, ra);
cpu_stq_be_data_ra(env, addr, val, ra);
}
static inline void cpu_stw_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
uint32_t val, int mmu_idx,
uintptr_t ra)
{
cpu_stw_le_data_ra(env, addr, val, ra);
}
static inline void cpu_stl_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
uint32_t val, int mmu_idx,
uintptr_t ra)
{
cpu_stl_le_data_ra(env, addr, val, ra);
}
static inline void cpu_stq_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
uint64_t val, int mmu_idx,
uintptr_t ra)
{
cpu_stq_le_data_ra(env, addr, val, ra);
}
#else
@ -243,29 +321,92 @@ static inline CPUTLBEntry *tlb_entry(CPUArchState *env, uintptr_t mmu_idx,
uint32_t cpu_ldub_mmuidx_ra(CPUArchState *env, abi_ptr addr,
int mmu_idx, uintptr_t ra);
uint32_t cpu_lduw_mmuidx_ra(CPUArchState *env, abi_ptr addr,
int mmu_idx, uintptr_t ra);
uint32_t cpu_ldl_mmuidx_ra(CPUArchState *env, abi_ptr addr,
int mmu_idx, uintptr_t ra);
uint64_t cpu_ldq_mmuidx_ra(CPUArchState *env, abi_ptr addr,
int mmu_idx, uintptr_t ra);
int cpu_ldsb_mmuidx_ra(CPUArchState *env, abi_ptr addr,
int mmu_idx, uintptr_t ra);
int cpu_ldsw_mmuidx_ra(CPUArchState *env, abi_ptr addr,
int mmu_idx, uintptr_t ra);
uint32_t cpu_lduw_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
int mmu_idx, uintptr_t ra);
int cpu_ldsw_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
int mmu_idx, uintptr_t ra);
uint32_t cpu_ldl_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
int mmu_idx, uintptr_t ra);
uint64_t cpu_ldq_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
int mmu_idx, uintptr_t ra);
uint32_t cpu_lduw_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
int mmu_idx, uintptr_t ra);
int cpu_ldsw_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
int mmu_idx, uintptr_t ra);
uint32_t cpu_ldl_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
int mmu_idx, uintptr_t ra);
uint64_t cpu_ldq_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
int mmu_idx, uintptr_t ra);
void cpu_stb_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
int mmu_idx, uintptr_t retaddr);
void cpu_stw_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
int mmu_idx, uintptr_t retaddr);
void cpu_stl_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
int mmu_idx, uintptr_t retaddr);
void cpu_stq_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint64_t val,
int mmu_idx, uintptr_t retaddr);
void cpu_stw_be_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
int mmu_idx, uintptr_t retaddr);
void cpu_stl_be_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
int mmu_idx, uintptr_t retaddr);
void cpu_stq_be_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint64_t val,
int mmu_idx, uintptr_t retaddr);
void cpu_stw_le_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
int mmu_idx, uintptr_t retaddr);
void cpu_stl_le_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
int mmu_idx, uintptr_t retaddr);
void cpu_stq_le_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint64_t val,
int mmu_idx, uintptr_t retaddr);
#endif /* defined(CONFIG_USER_ONLY) */
#ifdef TARGET_WORDS_BIGENDIAN
# define cpu_lduw_data cpu_lduw_be_data
# define cpu_ldsw_data cpu_ldsw_be_data
# define cpu_ldl_data cpu_ldl_be_data
# define cpu_ldq_data cpu_ldq_be_data
# define cpu_lduw_data_ra cpu_lduw_be_data_ra
# define cpu_ldsw_data_ra cpu_ldsw_be_data_ra
# define cpu_ldl_data_ra cpu_ldl_be_data_ra
# define cpu_ldq_data_ra cpu_ldq_be_data_ra
# define cpu_lduw_mmuidx_ra cpu_lduw_be_mmuidx_ra
# define cpu_ldsw_mmuidx_ra cpu_ldsw_be_mmuidx_ra
# define cpu_ldl_mmuidx_ra cpu_ldl_be_mmuidx_ra
# define cpu_ldq_mmuidx_ra cpu_ldq_be_mmuidx_ra
# define cpu_stw_data cpu_stw_be_data
# define cpu_stl_data cpu_stl_be_data
# define cpu_stq_data cpu_stq_be_data
# define cpu_stw_data_ra cpu_stw_be_data_ra
# define cpu_stl_data_ra cpu_stl_be_data_ra
# define cpu_stq_data_ra cpu_stq_be_data_ra
# define cpu_stw_mmuidx_ra cpu_stw_be_mmuidx_ra
# define cpu_stl_mmuidx_ra cpu_stl_be_mmuidx_ra
# define cpu_stq_mmuidx_ra cpu_stq_be_mmuidx_ra
#else
# define cpu_lduw_data cpu_lduw_le_data
# define cpu_ldsw_data cpu_ldsw_le_data
# define cpu_ldl_data cpu_ldl_le_data
# define cpu_ldq_data cpu_ldq_le_data
# define cpu_lduw_data_ra cpu_lduw_le_data_ra
# define cpu_ldsw_data_ra cpu_ldsw_le_data_ra
# define cpu_ldl_data_ra cpu_ldl_le_data_ra
# define cpu_ldq_data_ra cpu_ldq_le_data_ra
# define cpu_lduw_mmuidx_ra cpu_lduw_le_mmuidx_ra
# define cpu_ldsw_mmuidx_ra cpu_ldsw_le_mmuidx_ra
# define cpu_ldl_mmuidx_ra cpu_ldl_le_mmuidx_ra
# define cpu_ldq_mmuidx_ra cpu_ldq_le_mmuidx_ra
# define cpu_stw_data cpu_stw_le_data
# define cpu_stl_data cpu_stl_le_data
# define cpu_stq_data cpu_stq_le_data
# define cpu_stw_data_ra cpu_stw_le_data_ra
# define cpu_stl_data_ra cpu_stl_le_data_ra
# define cpu_stq_data_ra cpu_stq_le_data_ra
# define cpu_stw_mmuidx_ra cpu_stw_le_mmuidx_ra
# define cpu_stl_mmuidx_ra cpu_stl_le_mmuidx_ra
# define cpu_stq_mmuidx_ra cpu_stq_le_mmuidx_ra
#endif
uint32_t cpu_ldub_code(CPUArchState *env, abi_ptr addr);
uint32_t cpu_lduw_code(CPUArchState *env, abi_ptr addr);
uint32_t cpu_ldl_code(CPUArchState *env, abi_ptr addr);

View File

@ -330,6 +330,23 @@ static inline void tlb_flush_by_mmuidx_all_cpus_synced(CPUState *cpu,
{
}
#endif
/**
* probe_access:
* @env: CPUArchState
* @addr: guest virtual address to look up
* @size: size of the access
* @access_type: read, write or execute permission
* @mmu_idx: MMU index to use for lookup
* @retaddr: return address for unwinding
*
* Look up the guest virtual address @addr. Raise an exception if the
* page does not satisfy @access_type. Raise an exception if the
* access (@addr, @size) hits a watchpoint. For writes, mark a clean
* page as dirty.
*
* Finally, return the host address for a page that is backed by RAM,
* or NULL if the page requires I/O.
*/
void *probe_access(CPUArchState *env, target_ulong addr, int size,
MMUAccessType access_type, int mmu_idx, uintptr_t retaddr);
@ -345,6 +362,28 @@ static inline void *probe_read(CPUArchState *env, target_ulong addr, int size,
return probe_access(env, addr, size, MMU_DATA_LOAD, mmu_idx, retaddr);
}
/**
* probe_access_flags:
* @env: CPUArchState
* @addr: guest virtual address to look up
* @access_type: read, write or execute permission
* @mmu_idx: MMU index to use for lookup
* @nonfault: suppress the fault
* @phost: return value for host address
* @retaddr: return address for unwinding
*
* Similar to probe_access, loosely returning the TLB_FLAGS_MASK for
* the page, and storing the host address for RAM in @phost.
*
* If @nonfault is set, do not raise an exception but return TLB_INVALID_MASK.
* Do not handle watchpoints, but include TLB_WATCHPOINT in the returned flags.
* Do handle clean pages, so exclude TLB_NOTDIRY from the returned flags.
* For simplicity, all "mmio-like" flags are folded to TLB_MMIO.
*/
int probe_access_flags(CPUArchState *env, target_ulong addr,
MMUAccessType access_type, int mmu_idx,
bool nonfault, void **phost, uintptr_t retaddr);
#define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */
/* Estimated block size for TB allocation. */

View File

@ -24,11 +24,10 @@
#define NRF51_IOMEM_BASE 0x40000000
#define NRF51_IOMEM_SIZE 0x20000000
#define NRF51_PERIPHERAL_SIZE 0x00001000
#define NRF51_UART_BASE 0x40002000
#define NRF51_TWI_BASE 0x40003000
#define NRF51_TWI_SIZE 0x00001000
#define NRF51_TIMER_BASE 0x40008000
#define NRF51_TIMER_SIZE 0x00001000
#define NRF51_RNG_BASE 0x4000D000
#define NRF51_NVMC_BASE 0x4001E000
#define NRF51_GPIO_BASE 0x50000000

View File

@ -1100,8 +1100,31 @@ int cpu_watchpoint_remove(CPUState *cpu, vaddr addr,
vaddr len, int flags);
void cpu_watchpoint_remove_by_ref(CPUState *cpu, CPUWatchpoint *watchpoint);
void cpu_watchpoint_remove_all(CPUState *cpu, int mask);
/**
* cpu_check_watchpoint:
* @cpu: cpu context
* @addr: guest virtual address
* @len: access length
* @attrs: memory access attributes
* @flags: watchpoint access type
* @ra: unwind return address
*
* Check for a watchpoint hit in [addr, addr+len) of the type
* specified by @flags. Exit via exception with a hit.
*/
void cpu_check_watchpoint(CPUState *cpu, vaddr addr, vaddr len,
MemTxAttrs attrs, int flags, uintptr_t ra);
/**
* cpu_watchpoint_address_matches:
* @cpu: cpu context
* @addr: guest virtual address
* @len: access length
*
* Return the watchpoint flags that apply to [addr, addr+len).
* If no watchpoint is registered for the range, the result is 0.
*/
int cpu_watchpoint_address_matches(CPUState *cpu, vaddr addr, vaddr len);
#endif

View File

@ -29,7 +29,7 @@
#define MICROBIT_I2C(obj) \
OBJECT_CHECK(MicrobitI2CState, (obj), TYPE_MICROBIT_I2C)
#define MICROBIT_I2C_NREGS (NRF51_TWI_SIZE / sizeof(uint32_t))
#define MICROBIT_I2C_NREGS (NRF51_PERIPHERAL_SIZE / sizeof(uint32_t))
typedef struct {
SysBusDevice parent_obj;

View File

@ -41,6 +41,7 @@ typedef struct AspeedSCUState {
#define AST2500_A0_SILICON_REV 0x04000303U
#define AST2500_A1_SILICON_REV 0x04010303U
#define AST2600_A0_SILICON_REV 0x05000303U
#define AST2600_A1_SILICON_REV 0x05010303U
#define ASPEED_IS_AST2500(si_rev) ((((si_rev) >> 24) & 0xff) == 0x04)

View File

@ -59,6 +59,7 @@ typedef struct NRF51TimerState {
MemoryRegion iomem;
qemu_irq irq;
uint8_t id;
QEMUTimer timer;
int64_t timer_start_ns;
int64_t update_counter_ns;

View File

@ -79,6 +79,7 @@ obj-y += translate.o op_helper.o
obj-y += crypto_helper.o
obj-y += iwmmxt_helper.o vec_helper.o neon_helper.o
obj-y += m_helper.o
obj-y += cpu_tcg.o
obj-$(CONFIG_SOFTMMU) += psci.o

View File

@ -574,32 +574,6 @@ bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
return true;
}
#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{
CPUClass *cc = CPU_GET_CLASS(cs);
ARMCPU *cpu = ARM_CPU(cs);
CPUARMState *env = &cpu->env;
bool ret = false;
/*
* ARMv7-M interrupt masking works differently than -A or -R.
* There is no FIQ/IRQ distinction. Instead of I and F bits
* masking FIQ and IRQ interrupts, an exception is taken only
* if it is higher priority than the current execution priority
* (which depends on state like BASEPRI, FAULTMASK and the
* currently active exception).
*/
if (interrupt_request & CPU_INTERRUPT_HARD
&& (armv7m_nvic_can_take_pending_exception(env->nvic))) {
cs->exception_index = EXCP_IRQ;
cc->do_interrupt(cs);
ret = true;
}
return ret;
}
#endif
void arm_cpu_update_virq(ARMCPU *cpu)
{
/*
@ -725,16 +699,6 @@ static bool arm_cpu_virtio_is_big_endian(CPUState *cs)
#endif
static inline void set_feature(CPUARMState *env, int feature)
{
env->features |= 1ULL << feature;
}
static inline void unset_feature(CPUARMState *env, int feature)
{
env->features &= ~(1ULL << feature);
}
static int
print_insn_thumb1(bfd_vma pc, disassemble_info *info)
{
@ -1830,406 +1794,6 @@ static ObjectClass *arm_cpu_class_by_name(const char *cpu_model)
/* CPU models. These are not needed for the AArch64 linux-user build. */
#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
static void arm926_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "arm,arm926";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
cpu->midr = 0x41069265;
cpu->reset_fpsid = 0x41011090;
cpu->ctr = 0x1dd20d2;
cpu->reset_sctlr = 0x00090078;
/*
* ARMv5 does not have the ID_ISAR registers, but we can still
* set the field to indicate Jazelle support within QEMU.
*/
cpu->isar.id_isar1 = FIELD_DP32(cpu->isar.id_isar1, ID_ISAR1, JAZELLE, 1);
/*
* Similarly, we need to set MVFR0 fields to enable vfp and short vector
* support even though ARMv5 doesn't have this register.
*/
cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1);
cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSP, 1);
cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPDP, 1);
}
static void arm946_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "arm,arm946";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_PMSA);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
cpu->midr = 0x41059461;
cpu->ctr = 0x0f004006;
cpu->reset_sctlr = 0x00000078;
}
static void arm1026_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "arm,arm1026";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_AUXCR);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
cpu->midr = 0x4106a262;
cpu->reset_fpsid = 0x410110a0;
cpu->ctr = 0x1dd20d2;
cpu->reset_sctlr = 0x00090078;
cpu->reset_auxcr = 1;
/*
* ARMv5 does not have the ID_ISAR registers, but we can still
* set the field to indicate Jazelle support within QEMU.
*/
cpu->isar.id_isar1 = FIELD_DP32(cpu->isar.id_isar1, ID_ISAR1, JAZELLE, 1);
/*
* Similarly, we need to set MVFR0 fields to enable vfp and short vector
* support even though ARMv5 doesn't have this register.
*/
cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1);
cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSP, 1);
cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPDP, 1);
{
/* The 1026 had an IFAR at c6,c0,0,1 rather than the ARMv6 c6,c0,0,2 */
ARMCPRegInfo ifar = {
.name = "IFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 1,
.access = PL1_RW,
.fieldoffset = offsetof(CPUARMState, cp15.ifar_ns),
.resetvalue = 0
};
define_one_arm_cp_reg(cpu, &ifar);
}
}
static void arm1136_r2_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
/*
* What qemu calls "arm1136_r2" is actually the 1136 r0p2, ie an
* older core than plain "arm1136". In particular this does not
* have the v6K features.
* These ID register values are correct for 1136 but may be wrong
* for 1136_r2 (in particular r0p2 does not actually implement most
* of the ID registers).
*/
cpu->dtb_compatible = "arm,arm1136";
set_feature(&cpu->env, ARM_FEATURE_V6);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG);
set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS);
cpu->midr = 0x4107b362;
cpu->reset_fpsid = 0x410120b4;
cpu->isar.mvfr0 = 0x11111111;
cpu->isar.mvfr1 = 0x00000000;
cpu->ctr = 0x1dd20d2;
cpu->reset_sctlr = 0x00050078;
cpu->id_pfr0 = 0x111;
cpu->id_pfr1 = 0x1;
cpu->isar.id_dfr0 = 0x2;
cpu->id_afr0 = 0x3;
cpu->isar.id_mmfr0 = 0x01130003;
cpu->isar.id_mmfr1 = 0x10030302;
cpu->isar.id_mmfr2 = 0x01222110;
cpu->isar.id_isar0 = 0x00140011;
cpu->isar.id_isar1 = 0x12002111;
cpu->isar.id_isar2 = 0x11231111;
cpu->isar.id_isar3 = 0x01102131;
cpu->isar.id_isar4 = 0x141;
cpu->reset_auxcr = 7;
}
static void arm1136_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "arm,arm1136";
set_feature(&cpu->env, ARM_FEATURE_V6K);
set_feature(&cpu->env, ARM_FEATURE_V6);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG);
set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS);
cpu->midr = 0x4117b363;
cpu->reset_fpsid = 0x410120b4;
cpu->isar.mvfr0 = 0x11111111;
cpu->isar.mvfr1 = 0x00000000;
cpu->ctr = 0x1dd20d2;
cpu->reset_sctlr = 0x00050078;
cpu->id_pfr0 = 0x111;
cpu->id_pfr1 = 0x1;
cpu->isar.id_dfr0 = 0x2;
cpu->id_afr0 = 0x3;
cpu->isar.id_mmfr0 = 0x01130003;
cpu->isar.id_mmfr1 = 0x10030302;
cpu->isar.id_mmfr2 = 0x01222110;
cpu->isar.id_isar0 = 0x00140011;
cpu->isar.id_isar1 = 0x12002111;
cpu->isar.id_isar2 = 0x11231111;
cpu->isar.id_isar3 = 0x01102131;
cpu->isar.id_isar4 = 0x141;
cpu->reset_auxcr = 7;
}
static void arm1176_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "arm,arm1176";
set_feature(&cpu->env, ARM_FEATURE_V6K);
set_feature(&cpu->env, ARM_FEATURE_VAPA);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG);
set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS);
set_feature(&cpu->env, ARM_FEATURE_EL3);
cpu->midr = 0x410fb767;
cpu->reset_fpsid = 0x410120b5;
cpu->isar.mvfr0 = 0x11111111;
cpu->isar.mvfr1 = 0x00000000;
cpu->ctr = 0x1dd20d2;
cpu->reset_sctlr = 0x00050078;
cpu->id_pfr0 = 0x111;
cpu->id_pfr1 = 0x11;
cpu->isar.id_dfr0 = 0x33;
cpu->id_afr0 = 0;
cpu->isar.id_mmfr0 = 0x01130003;
cpu->isar.id_mmfr1 = 0x10030302;
cpu->isar.id_mmfr2 = 0x01222100;
cpu->isar.id_isar0 = 0x0140011;
cpu->isar.id_isar1 = 0x12002111;
cpu->isar.id_isar2 = 0x11231121;
cpu->isar.id_isar3 = 0x01102131;
cpu->isar.id_isar4 = 0x01141;
cpu->reset_auxcr = 7;
}
static void arm11mpcore_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "arm,arm11mpcore";
set_feature(&cpu->env, ARM_FEATURE_V6K);
set_feature(&cpu->env, ARM_FEATURE_VAPA);
set_feature(&cpu->env, ARM_FEATURE_MPIDR);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
cpu->midr = 0x410fb022;
cpu->reset_fpsid = 0x410120b4;
cpu->isar.mvfr0 = 0x11111111;
cpu->isar.mvfr1 = 0x00000000;
cpu->ctr = 0x1d192992; /* 32K icache 32K dcache */
cpu->id_pfr0 = 0x111;
cpu->id_pfr1 = 0x1;
cpu->isar.id_dfr0 = 0;
cpu->id_afr0 = 0x2;
cpu->isar.id_mmfr0 = 0x01100103;
cpu->isar.id_mmfr1 = 0x10020302;
cpu->isar.id_mmfr2 = 0x01222000;
cpu->isar.id_isar0 = 0x00100011;
cpu->isar.id_isar1 = 0x12002111;
cpu->isar.id_isar2 = 0x11221011;
cpu->isar.id_isar3 = 0x01102131;
cpu->isar.id_isar4 = 0x141;
cpu->reset_auxcr = 1;
}
static void cortex_m0_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
set_feature(&cpu->env, ARM_FEATURE_V6);
set_feature(&cpu->env, ARM_FEATURE_M);
cpu->midr = 0x410cc200;
}
static void cortex_m3_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
set_feature(&cpu->env, ARM_FEATURE_V7);
set_feature(&cpu->env, ARM_FEATURE_M);
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
cpu->midr = 0x410fc231;
cpu->pmsav7_dregion = 8;
cpu->id_pfr0 = 0x00000030;
cpu->id_pfr1 = 0x00000200;
cpu->isar.id_dfr0 = 0x00100000;
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x00000030;
cpu->isar.id_mmfr1 = 0x00000000;
cpu->isar.id_mmfr2 = 0x00000000;
cpu->isar.id_mmfr3 = 0x00000000;
cpu->isar.id_isar0 = 0x01141110;
cpu->isar.id_isar1 = 0x02111000;
cpu->isar.id_isar2 = 0x21112231;
cpu->isar.id_isar3 = 0x01111110;
cpu->isar.id_isar4 = 0x01310102;
cpu->isar.id_isar5 = 0x00000000;
cpu->isar.id_isar6 = 0x00000000;
}
static void cortex_m4_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
set_feature(&cpu->env, ARM_FEATURE_V7);
set_feature(&cpu->env, ARM_FEATURE_M);
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
cpu->midr = 0x410fc240; /* r0p0 */
cpu->pmsav7_dregion = 8;
cpu->isar.mvfr0 = 0x10110021;
cpu->isar.mvfr1 = 0x11000011;
cpu->isar.mvfr2 = 0x00000000;
cpu->id_pfr0 = 0x00000030;
cpu->id_pfr1 = 0x00000200;
cpu->isar.id_dfr0 = 0x00100000;
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x00000030;
cpu->isar.id_mmfr1 = 0x00000000;
cpu->isar.id_mmfr2 = 0x00000000;
cpu->isar.id_mmfr3 = 0x00000000;
cpu->isar.id_isar0 = 0x01141110;
cpu->isar.id_isar1 = 0x02111000;
cpu->isar.id_isar2 = 0x21112231;
cpu->isar.id_isar3 = 0x01111110;
cpu->isar.id_isar4 = 0x01310102;
cpu->isar.id_isar5 = 0x00000000;
cpu->isar.id_isar6 = 0x00000000;
}
static void cortex_m7_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
set_feature(&cpu->env, ARM_FEATURE_V7);
set_feature(&cpu->env, ARM_FEATURE_M);
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
cpu->midr = 0x411fc272; /* r1p2 */
cpu->pmsav7_dregion = 8;
cpu->isar.mvfr0 = 0x10110221;
cpu->isar.mvfr1 = 0x12000011;
cpu->isar.mvfr2 = 0x00000040;
cpu->id_pfr0 = 0x00000030;
cpu->id_pfr1 = 0x00000200;
cpu->isar.id_dfr0 = 0x00100000;
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x00100030;
cpu->isar.id_mmfr1 = 0x00000000;
cpu->isar.id_mmfr2 = 0x01000000;
cpu->isar.id_mmfr3 = 0x00000000;
cpu->isar.id_isar0 = 0x01101110;
cpu->isar.id_isar1 = 0x02112000;
cpu->isar.id_isar2 = 0x20232231;
cpu->isar.id_isar3 = 0x01111131;
cpu->isar.id_isar4 = 0x01310132;
cpu->isar.id_isar5 = 0x00000000;
cpu->isar.id_isar6 = 0x00000000;
}
static void cortex_m33_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
set_feature(&cpu->env, ARM_FEATURE_V8);
set_feature(&cpu->env, ARM_FEATURE_M);
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
cpu->midr = 0x410fd213; /* r0p3 */
cpu->pmsav7_dregion = 16;
cpu->sau_sregion = 8;
cpu->isar.mvfr0 = 0x10110021;
cpu->isar.mvfr1 = 0x11000011;
cpu->isar.mvfr2 = 0x00000040;
cpu->id_pfr0 = 0x00000030;
cpu->id_pfr1 = 0x00000210;
cpu->isar.id_dfr0 = 0x00200000;
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x00101F40;
cpu->isar.id_mmfr1 = 0x00000000;
cpu->isar.id_mmfr2 = 0x01000000;
cpu->isar.id_mmfr3 = 0x00000000;
cpu->isar.id_isar0 = 0x01101110;
cpu->isar.id_isar1 = 0x02212000;
cpu->isar.id_isar2 = 0x20232232;
cpu->isar.id_isar3 = 0x01111131;
cpu->isar.id_isar4 = 0x01310132;
cpu->isar.id_isar5 = 0x00000000;
cpu->isar.id_isar6 = 0x00000000;
cpu->clidr = 0x00000000;
cpu->ctr = 0x8000c000;
}
static void arm_v7m_class_init(ObjectClass *oc, void *data)
{
ARMCPUClass *acc = ARM_CPU_CLASS(oc);
CPUClass *cc = CPU_CLASS(oc);
acc->info = data;
#ifndef CONFIG_USER_ONLY
cc->do_interrupt = arm_v7m_cpu_do_interrupt;
#endif
cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt;
}
static const ARMCPRegInfo cortexr5_cp_reginfo[] = {
/* Dummy the TCM region regs for the moment */
{ .name = "ATCM", .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0,
.access = PL1_RW, .type = ARM_CP_CONST },
{ .name = "BTCM", .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 1,
.access = PL1_RW, .type = ARM_CP_CONST },
{ .name = "DCACHE_INVAL", .cp = 15, .opc1 = 0, .crn = 15, .crm = 5,
.opc2 = 0, .access = PL1_W, .type = ARM_CP_NOP },
REGINFO_SENTINEL
};
static void cortex_r5_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
set_feature(&cpu->env, ARM_FEATURE_V7);
set_feature(&cpu->env, ARM_FEATURE_V7MP);
set_feature(&cpu->env, ARM_FEATURE_PMSA);
set_feature(&cpu->env, ARM_FEATURE_PMU);
cpu->midr = 0x411fc153; /* r1p3 */
cpu->id_pfr0 = 0x0131;
cpu->id_pfr1 = 0x001;
cpu->isar.id_dfr0 = 0x010400;
cpu->id_afr0 = 0x0;
cpu->isar.id_mmfr0 = 0x0210030;
cpu->isar.id_mmfr1 = 0x00000000;
cpu->isar.id_mmfr2 = 0x01200000;
cpu->isar.id_mmfr3 = 0x0211;
cpu->isar.id_isar0 = 0x02101111;
cpu->isar.id_isar1 = 0x13112111;
cpu->isar.id_isar2 = 0x21232141;
cpu->isar.id_isar3 = 0x01112131;
cpu->isar.id_isar4 = 0x0010142;
cpu->isar.id_isar5 = 0x0;
cpu->isar.id_isar6 = 0x0;
cpu->mp_is_up = true;
cpu->pmsav7_dregion = 16;
define_arm_cp_regs(cpu, cortexr5_cp_reginfo);
}
static void cortex_r5f_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cortex_r5_initfn(obj);
cpu->isar.mvfr0 = 0x10110221;
cpu->isar.mvfr1 = 0x00000011;
}
static const ARMCPRegInfo cortexa8_cp_reginfo[] = {
{ .name = "L2LOCKDOWN", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 0,
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
@ -2456,174 +2020,6 @@ static void cortex_a15_initfn(Object *obj)
define_arm_cp_regs(cpu, cortexa15_cp_reginfo);
}
static void ti925t_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
set_feature(&cpu->env, ARM_FEATURE_V4T);
set_feature(&cpu->env, ARM_FEATURE_OMAPCP);
cpu->midr = ARM_CPUID_TI925T;
cpu->ctr = 0x5109149;
cpu->reset_sctlr = 0x00000070;
}
static void sa1100_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "intel,sa1100";
set_feature(&cpu->env, ARM_FEATURE_STRONGARM);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
cpu->midr = 0x4401A11B;
cpu->reset_sctlr = 0x00000070;
}
static void sa1110_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
set_feature(&cpu->env, ARM_FEATURE_STRONGARM);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
cpu->midr = 0x6901B119;
cpu->reset_sctlr = 0x00000070;
}
static void pxa250_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "marvell,xscale";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_XSCALE);
cpu->midr = 0x69052100;
cpu->ctr = 0xd172172;
cpu->reset_sctlr = 0x00000078;
}
static void pxa255_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "marvell,xscale";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_XSCALE);
cpu->midr = 0x69052d00;
cpu->ctr = 0xd172172;
cpu->reset_sctlr = 0x00000078;
}
static void pxa260_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "marvell,xscale";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_XSCALE);
cpu->midr = 0x69052903;
cpu->ctr = 0xd172172;
cpu->reset_sctlr = 0x00000078;
}
static void pxa261_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "marvell,xscale";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_XSCALE);
cpu->midr = 0x69052d05;
cpu->ctr = 0xd172172;
cpu->reset_sctlr = 0x00000078;
}
static void pxa262_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "marvell,xscale";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_XSCALE);
cpu->midr = 0x69052d06;
cpu->ctr = 0xd172172;
cpu->reset_sctlr = 0x00000078;
}
static void pxa270a0_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "marvell,xscale";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_XSCALE);
set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
cpu->midr = 0x69054110;
cpu->ctr = 0xd172172;
cpu->reset_sctlr = 0x00000078;
}
static void pxa270a1_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "marvell,xscale";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_XSCALE);
set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
cpu->midr = 0x69054111;
cpu->ctr = 0xd172172;
cpu->reset_sctlr = 0x00000078;
}
static void pxa270b0_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "marvell,xscale";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_XSCALE);
set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
cpu->midr = 0x69054112;
cpu->ctr = 0xd172172;
cpu->reset_sctlr = 0x00000078;
}
static void pxa270b1_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "marvell,xscale";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_XSCALE);
set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
cpu->midr = 0x69054113;
cpu->ctr = 0xd172172;
cpu->reset_sctlr = 0x00000078;
}
static void pxa270c0_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "marvell,xscale";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_XSCALE);
set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
cpu->midr = 0x69054114;
cpu->ctr = 0xd172172;
cpu->reset_sctlr = 0x00000078;
}
static void pxa270c5_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "marvell,xscale";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_XSCALE);
set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
cpu->midr = 0x69054117;
cpu->ctr = 0xd172172;
cpu->reset_sctlr = 0x00000078;
}
#ifndef TARGET_AARCH64
/* -cpu max: if KVM is enabled, like -cpu host (best possible with this host);
* otherwise, a CPU with as many features enabled as our emulation supports.
@ -2698,50 +2094,10 @@ static void arm_max_initfn(Object *obj)
static const ARMCPUInfo arm_cpus[] = {
#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
{ .name = "arm926", .initfn = arm926_initfn },
{ .name = "arm946", .initfn = arm946_initfn },
{ .name = "arm1026", .initfn = arm1026_initfn },
/*
* What QEMU calls "arm1136-r2" is actually the 1136 r0p2, i.e. an
* older core than plain "arm1136". In particular this does not
* have the v6K features.
*/
{ .name = "arm1136-r2", .initfn = arm1136_r2_initfn },
{ .name = "arm1136", .initfn = arm1136_initfn },
{ .name = "arm1176", .initfn = arm1176_initfn },
{ .name = "arm11mpcore", .initfn = arm11mpcore_initfn },
{ .name = "cortex-m0", .initfn = cortex_m0_initfn,
.class_init = arm_v7m_class_init },
{ .name = "cortex-m3", .initfn = cortex_m3_initfn,
.class_init = arm_v7m_class_init },
{ .name = "cortex-m4", .initfn = cortex_m4_initfn,
.class_init = arm_v7m_class_init },
{ .name = "cortex-m7", .initfn = cortex_m7_initfn,
.class_init = arm_v7m_class_init },
{ .name = "cortex-m33", .initfn = cortex_m33_initfn,
.class_init = arm_v7m_class_init },
{ .name = "cortex-r5", .initfn = cortex_r5_initfn },
{ .name = "cortex-r5f", .initfn = cortex_r5f_initfn },
{ .name = "cortex-a7", .initfn = cortex_a7_initfn },
{ .name = "cortex-a8", .initfn = cortex_a8_initfn },
{ .name = "cortex-a9", .initfn = cortex_a9_initfn },
{ .name = "cortex-a15", .initfn = cortex_a15_initfn },
{ .name = "ti925t", .initfn = ti925t_initfn },
{ .name = "sa1100", .initfn = sa1100_initfn },
{ .name = "sa1110", .initfn = sa1110_initfn },
{ .name = "pxa250", .initfn = pxa250_initfn },
{ .name = "pxa255", .initfn = pxa255_initfn },
{ .name = "pxa260", .initfn = pxa260_initfn },
{ .name = "pxa261", .initfn = pxa261_initfn },
{ .name = "pxa262", .initfn = pxa262_initfn },
/* "pxa270" is an alias for "pxa270-a0" */
{ .name = "pxa270", .initfn = pxa270a0_initfn },
{ .name = "pxa270-a0", .initfn = pxa270a0_initfn },
{ .name = "pxa270-a1", .initfn = pxa270a1_initfn },
{ .name = "pxa270-b0", .initfn = pxa270b0_initfn },
{ .name = "pxa270-b1", .initfn = pxa270b1_initfn },
{ .name = "pxa270-c0", .initfn = pxa270c0_initfn },
{ .name = "pxa270-c5", .initfn = pxa270c5_initfn },
#ifndef TARGET_AARCH64
{ .name = "max", .initfn = arm_max_initfn },
#endif
@ -2749,7 +2105,6 @@ static const ARMCPUInfo arm_cpus[] = {
{ .name = "any", .initfn = arm_max_initfn },
#endif
#endif
{ .name = NULL }
};
static Property arm_cpu_properties[] = {
@ -2897,19 +2252,22 @@ static const TypeInfo idau_interface_type_info = {
static void arm_cpu_register_types(void)
{
const ARMCPUInfo *info = arm_cpus;
const size_t cpu_count = ARRAY_SIZE(arm_cpus);
type_register_static(&arm_cpu_type_info);
type_register_static(&idau_interface_type_info);
while (info->name) {
arm_cpu_register(info);
info++;
}
#ifdef CONFIG_KVM
type_register_static(&host_arm_cpu_type_info);
#endif
if (cpu_count) {
size_t i;
type_register_static(&idau_interface_type_info);
for (i = 0; i < cpu_count; ++i) {
arm_cpu_register(&arm_cpus[i]);
}
}
}
type_init(arm_cpu_register_types)

View File

@ -696,6 +696,16 @@ typedef struct CPUARMState {
void *gicv3state;
} CPUARMState;
static inline void set_feature(CPUARMState *env, int feature)
{
env->features |= 1ULL << feature;
}
static inline void unset_feature(CPUARMState *env, int feature)
{
env->features &= ~(1ULL << feature);
}
/**
* ARMELChangeHookFn:
* type of a function which can be registered via arm_register_el_change_hook()

View File

@ -29,16 +29,6 @@
#include "kvm_arm.h"
#include "qapi/visitor.h"
static inline void set_feature(CPUARMState *env, int feature)
{
env->features |= 1ULL << feature;
}
static inline void unset_feature(CPUARMState *env, int feature)
{
env->features &= ~(1ULL << feature);
}
#ifndef CONFIG_USER_ONLY
static uint64_t a57_a53_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
@ -744,7 +734,6 @@ static const ARMCPUInfo aarch64_cpus[] = {
{ .name = "cortex-a53", .initfn = aarch64_a53_initfn },
{ .name = "cortex-a72", .initfn = aarch64_a72_initfn },
{ .name = "max", .initfn = aarch64_max_initfn },
{ .name = NULL }
};
static bool aarch64_cpu_get_aarch64(Object *obj, Error **errp)
@ -850,13 +839,12 @@ static const TypeInfo aarch64_cpu_type_info = {
static void aarch64_cpu_register_types(void)
{
const ARMCPUInfo *info = aarch64_cpus;
size_t i;
type_register_static(&aarch64_cpu_type_info);
while (info->name) {
aarch64_cpu_register(info);
info++;
for (i = 0; i < ARRAY_SIZE(aarch64_cpus); ++i) {
aarch64_cpu_register(&aarch64_cpus[i]);
}
}

664
target/arm/cpu_tcg.c Normal file
View File

@ -0,0 +1,664 @@
/*
* QEMU ARM TCG CPUs.
*
* Copyright (c) 2012 SUSE LINUX Products GmbH
*
* This code is licensed under the GNU GPL v2 or later.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "qemu/osdep.h"
#include "cpu.h"
#include "internals.h"
/* CPU models. These are not needed for the AArch64 linux-user build. */
#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{
CPUClass *cc = CPU_GET_CLASS(cs);
ARMCPU *cpu = ARM_CPU(cs);
CPUARMState *env = &cpu->env;
bool ret = false;
/*
* ARMv7-M interrupt masking works differently than -A or -R.
* There is no FIQ/IRQ distinction. Instead of I and F bits
* masking FIQ and IRQ interrupts, an exception is taken only
* if it is higher priority than the current execution priority
* (which depends on state like BASEPRI, FAULTMASK and the
* currently active exception).
*/
if (interrupt_request & CPU_INTERRUPT_HARD
&& (armv7m_nvic_can_take_pending_exception(env->nvic))) {
cs->exception_index = EXCP_IRQ;
cc->do_interrupt(cs);
ret = true;
}
return ret;
}
static void arm926_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "arm,arm926";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
cpu->midr = 0x41069265;
cpu->reset_fpsid = 0x41011090;
cpu->ctr = 0x1dd20d2;
cpu->reset_sctlr = 0x00090078;
/*
* ARMv5 does not have the ID_ISAR registers, but we can still
* set the field to indicate Jazelle support within QEMU.
*/
cpu->isar.id_isar1 = FIELD_DP32(cpu->isar.id_isar1, ID_ISAR1, JAZELLE, 1);
/*
* Similarly, we need to set MVFR0 fields to enable vfp and short vector
* support even though ARMv5 doesn't have this register.
*/
cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1);
cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSP, 1);
cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPDP, 1);
}
static void arm946_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "arm,arm946";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_PMSA);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
cpu->midr = 0x41059461;
cpu->ctr = 0x0f004006;
cpu->reset_sctlr = 0x00000078;
}
static void arm1026_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "arm,arm1026";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_AUXCR);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
cpu->midr = 0x4106a262;
cpu->reset_fpsid = 0x410110a0;
cpu->ctr = 0x1dd20d2;
cpu->reset_sctlr = 0x00090078;
cpu->reset_auxcr = 1;
/*
* ARMv5 does not have the ID_ISAR registers, but we can still
* set the field to indicate Jazelle support within QEMU.
*/
cpu->isar.id_isar1 = FIELD_DP32(cpu->isar.id_isar1, ID_ISAR1, JAZELLE, 1);
/*
* Similarly, we need to set MVFR0 fields to enable vfp and short vector
* support even though ARMv5 doesn't have this register.
*/
cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1);
cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSP, 1);
cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPDP, 1);
{
/* The 1026 had an IFAR at c6,c0,0,1 rather than the ARMv6 c6,c0,0,2 */
ARMCPRegInfo ifar = {
.name = "IFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 1,
.access = PL1_RW,
.fieldoffset = offsetof(CPUARMState, cp15.ifar_ns),
.resetvalue = 0
};
define_one_arm_cp_reg(cpu, &ifar);
}
}
static void arm1136_r2_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
/*
* What qemu calls "arm1136_r2" is actually the 1136 r0p2, ie an
* older core than plain "arm1136". In particular this does not
* have the v6K features.
* These ID register values are correct for 1136 but may be wrong
* for 1136_r2 (in particular r0p2 does not actually implement most
* of the ID registers).
*/
cpu->dtb_compatible = "arm,arm1136";
set_feature(&cpu->env, ARM_FEATURE_V6);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG);
set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS);
cpu->midr = 0x4107b362;
cpu->reset_fpsid = 0x410120b4;
cpu->isar.mvfr0 = 0x11111111;
cpu->isar.mvfr1 = 0x00000000;
cpu->ctr = 0x1dd20d2;
cpu->reset_sctlr = 0x00050078;
cpu->id_pfr0 = 0x111;
cpu->id_pfr1 = 0x1;
cpu->isar.id_dfr0 = 0x2;
cpu->id_afr0 = 0x3;
cpu->isar.id_mmfr0 = 0x01130003;
cpu->isar.id_mmfr1 = 0x10030302;
cpu->isar.id_mmfr2 = 0x01222110;
cpu->isar.id_isar0 = 0x00140011;
cpu->isar.id_isar1 = 0x12002111;
cpu->isar.id_isar2 = 0x11231111;
cpu->isar.id_isar3 = 0x01102131;
cpu->isar.id_isar4 = 0x141;
cpu->reset_auxcr = 7;
}
static void arm1136_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "arm,arm1136";
set_feature(&cpu->env, ARM_FEATURE_V6K);
set_feature(&cpu->env, ARM_FEATURE_V6);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG);
set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS);
cpu->midr = 0x4117b363;
cpu->reset_fpsid = 0x410120b4;
cpu->isar.mvfr0 = 0x11111111;
cpu->isar.mvfr1 = 0x00000000;
cpu->ctr = 0x1dd20d2;
cpu->reset_sctlr = 0x00050078;
cpu->id_pfr0 = 0x111;
cpu->id_pfr1 = 0x1;
cpu->isar.id_dfr0 = 0x2;
cpu->id_afr0 = 0x3;
cpu->isar.id_mmfr0 = 0x01130003;
cpu->isar.id_mmfr1 = 0x10030302;
cpu->isar.id_mmfr2 = 0x01222110;
cpu->isar.id_isar0 = 0x00140011;
cpu->isar.id_isar1 = 0x12002111;
cpu->isar.id_isar2 = 0x11231111;
cpu->isar.id_isar3 = 0x01102131;
cpu->isar.id_isar4 = 0x141;
cpu->reset_auxcr = 7;
}
static void arm1176_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "arm,arm1176";
set_feature(&cpu->env, ARM_FEATURE_V6K);
set_feature(&cpu->env, ARM_FEATURE_VAPA);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG);
set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS);
set_feature(&cpu->env, ARM_FEATURE_EL3);
cpu->midr = 0x410fb767;
cpu->reset_fpsid = 0x410120b5;
cpu->isar.mvfr0 = 0x11111111;
cpu->isar.mvfr1 = 0x00000000;
cpu->ctr = 0x1dd20d2;
cpu->reset_sctlr = 0x00050078;
cpu->id_pfr0 = 0x111;
cpu->id_pfr1 = 0x11;
cpu->isar.id_dfr0 = 0x33;
cpu->id_afr0 = 0;
cpu->isar.id_mmfr0 = 0x01130003;
cpu->isar.id_mmfr1 = 0x10030302;
cpu->isar.id_mmfr2 = 0x01222100;
cpu->isar.id_isar0 = 0x0140011;
cpu->isar.id_isar1 = 0x12002111;
cpu->isar.id_isar2 = 0x11231121;
cpu->isar.id_isar3 = 0x01102131;
cpu->isar.id_isar4 = 0x01141;
cpu->reset_auxcr = 7;
}
static void arm11mpcore_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "arm,arm11mpcore";
set_feature(&cpu->env, ARM_FEATURE_V6K);
set_feature(&cpu->env, ARM_FEATURE_VAPA);
set_feature(&cpu->env, ARM_FEATURE_MPIDR);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
cpu->midr = 0x410fb022;
cpu->reset_fpsid = 0x410120b4;
cpu->isar.mvfr0 = 0x11111111;
cpu->isar.mvfr1 = 0x00000000;
cpu->ctr = 0x1d192992; /* 32K icache 32K dcache */
cpu->id_pfr0 = 0x111;
cpu->id_pfr1 = 0x1;
cpu->isar.id_dfr0 = 0;
cpu->id_afr0 = 0x2;
cpu->isar.id_mmfr0 = 0x01100103;
cpu->isar.id_mmfr1 = 0x10020302;
cpu->isar.id_mmfr2 = 0x01222000;
cpu->isar.id_isar0 = 0x00100011;
cpu->isar.id_isar1 = 0x12002111;
cpu->isar.id_isar2 = 0x11221011;
cpu->isar.id_isar3 = 0x01102131;
cpu->isar.id_isar4 = 0x141;
cpu->reset_auxcr = 1;
}
static void cortex_m0_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
set_feature(&cpu->env, ARM_FEATURE_V6);
set_feature(&cpu->env, ARM_FEATURE_M);
cpu->midr = 0x410cc200;
}
static void cortex_m3_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
set_feature(&cpu->env, ARM_FEATURE_V7);
set_feature(&cpu->env, ARM_FEATURE_M);
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
cpu->midr = 0x410fc231;
cpu->pmsav7_dregion = 8;
cpu->id_pfr0 = 0x00000030;
cpu->id_pfr1 = 0x00000200;
cpu->isar.id_dfr0 = 0x00100000;
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x00000030;
cpu->isar.id_mmfr1 = 0x00000000;
cpu->isar.id_mmfr2 = 0x00000000;
cpu->isar.id_mmfr3 = 0x00000000;
cpu->isar.id_isar0 = 0x01141110;
cpu->isar.id_isar1 = 0x02111000;
cpu->isar.id_isar2 = 0x21112231;
cpu->isar.id_isar3 = 0x01111110;
cpu->isar.id_isar4 = 0x01310102;
cpu->isar.id_isar5 = 0x00000000;
cpu->isar.id_isar6 = 0x00000000;
}
static void cortex_m4_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
set_feature(&cpu->env, ARM_FEATURE_V7);
set_feature(&cpu->env, ARM_FEATURE_M);
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
cpu->midr = 0x410fc240; /* r0p0 */
cpu->pmsav7_dregion = 8;
cpu->isar.mvfr0 = 0x10110021;
cpu->isar.mvfr1 = 0x11000011;
cpu->isar.mvfr2 = 0x00000000;
cpu->id_pfr0 = 0x00000030;
cpu->id_pfr1 = 0x00000200;
cpu->isar.id_dfr0 = 0x00100000;
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x00000030;
cpu->isar.id_mmfr1 = 0x00000000;
cpu->isar.id_mmfr2 = 0x00000000;
cpu->isar.id_mmfr3 = 0x00000000;
cpu->isar.id_isar0 = 0x01141110;
cpu->isar.id_isar1 = 0x02111000;
cpu->isar.id_isar2 = 0x21112231;
cpu->isar.id_isar3 = 0x01111110;
cpu->isar.id_isar4 = 0x01310102;
cpu->isar.id_isar5 = 0x00000000;
cpu->isar.id_isar6 = 0x00000000;
}
static void cortex_m7_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
set_feature(&cpu->env, ARM_FEATURE_V7);
set_feature(&cpu->env, ARM_FEATURE_M);
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
cpu->midr = 0x411fc272; /* r1p2 */
cpu->pmsav7_dregion = 8;
cpu->isar.mvfr0 = 0x10110221;
cpu->isar.mvfr1 = 0x12000011;
cpu->isar.mvfr2 = 0x00000040;
cpu->id_pfr0 = 0x00000030;
cpu->id_pfr1 = 0x00000200;
cpu->isar.id_dfr0 = 0x00100000;
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x00100030;
cpu->isar.id_mmfr1 = 0x00000000;
cpu->isar.id_mmfr2 = 0x01000000;
cpu->isar.id_mmfr3 = 0x00000000;
cpu->isar.id_isar0 = 0x01101110;
cpu->isar.id_isar1 = 0x02112000;
cpu->isar.id_isar2 = 0x20232231;
cpu->isar.id_isar3 = 0x01111131;
cpu->isar.id_isar4 = 0x01310132;
cpu->isar.id_isar5 = 0x00000000;
cpu->isar.id_isar6 = 0x00000000;
}
static void cortex_m33_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
set_feature(&cpu->env, ARM_FEATURE_V8);
set_feature(&cpu->env, ARM_FEATURE_M);
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
cpu->midr = 0x410fd213; /* r0p3 */
cpu->pmsav7_dregion = 16;
cpu->sau_sregion = 8;
cpu->isar.mvfr0 = 0x10110021;
cpu->isar.mvfr1 = 0x11000011;
cpu->isar.mvfr2 = 0x00000040;
cpu->id_pfr0 = 0x00000030;
cpu->id_pfr1 = 0x00000210;
cpu->isar.id_dfr0 = 0x00200000;
cpu->id_afr0 = 0x00000000;
cpu->isar.id_mmfr0 = 0x00101F40;
cpu->isar.id_mmfr1 = 0x00000000;
cpu->isar.id_mmfr2 = 0x01000000;
cpu->isar.id_mmfr3 = 0x00000000;
cpu->isar.id_isar0 = 0x01101110;
cpu->isar.id_isar1 = 0x02212000;
cpu->isar.id_isar2 = 0x20232232;
cpu->isar.id_isar3 = 0x01111131;
cpu->isar.id_isar4 = 0x01310132;
cpu->isar.id_isar5 = 0x00000000;
cpu->isar.id_isar6 = 0x00000000;
cpu->clidr = 0x00000000;
cpu->ctr = 0x8000c000;
}
static const ARMCPRegInfo cortexr5_cp_reginfo[] = {
/* Dummy the TCM region regs for the moment */
{ .name = "ATCM", .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0,
.access = PL1_RW, .type = ARM_CP_CONST },
{ .name = "BTCM", .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 1,
.access = PL1_RW, .type = ARM_CP_CONST },
{ .name = "DCACHE_INVAL", .cp = 15, .opc1 = 0, .crn = 15, .crm = 5,
.opc2 = 0, .access = PL1_W, .type = ARM_CP_NOP },
REGINFO_SENTINEL
};
static void cortex_r5_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
set_feature(&cpu->env, ARM_FEATURE_V7);
set_feature(&cpu->env, ARM_FEATURE_V7MP);
set_feature(&cpu->env, ARM_FEATURE_PMSA);
set_feature(&cpu->env, ARM_FEATURE_PMU);
cpu->midr = 0x411fc153; /* r1p3 */
cpu->id_pfr0 = 0x0131;
cpu->id_pfr1 = 0x001;
cpu->isar.id_dfr0 = 0x010400;
cpu->id_afr0 = 0x0;
cpu->isar.id_mmfr0 = 0x0210030;
cpu->isar.id_mmfr1 = 0x00000000;
cpu->isar.id_mmfr2 = 0x01200000;
cpu->isar.id_mmfr3 = 0x0211;
cpu->isar.id_isar0 = 0x02101111;
cpu->isar.id_isar1 = 0x13112111;
cpu->isar.id_isar2 = 0x21232141;
cpu->isar.id_isar3 = 0x01112131;
cpu->isar.id_isar4 = 0x0010142;
cpu->isar.id_isar5 = 0x0;
cpu->isar.id_isar6 = 0x0;
cpu->mp_is_up = true;
cpu->pmsav7_dregion = 16;
define_arm_cp_regs(cpu, cortexr5_cp_reginfo);
}
static void cortex_r5f_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cortex_r5_initfn(obj);
cpu->isar.mvfr0 = 0x10110221;
cpu->isar.mvfr1 = 0x00000011;
}
static void ti925t_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
set_feature(&cpu->env, ARM_FEATURE_V4T);
set_feature(&cpu->env, ARM_FEATURE_OMAPCP);
cpu->midr = ARM_CPUID_TI925T;
cpu->ctr = 0x5109149;
cpu->reset_sctlr = 0x00000070;
}
static void sa1100_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "intel,sa1100";
set_feature(&cpu->env, ARM_FEATURE_STRONGARM);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
cpu->midr = 0x4401A11B;
cpu->reset_sctlr = 0x00000070;
}
static void sa1110_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
set_feature(&cpu->env, ARM_FEATURE_STRONGARM);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
cpu->midr = 0x6901B119;
cpu->reset_sctlr = 0x00000070;
}
static void pxa250_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "marvell,xscale";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_XSCALE);
cpu->midr = 0x69052100;
cpu->ctr = 0xd172172;
cpu->reset_sctlr = 0x00000078;
}
static void pxa255_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "marvell,xscale";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_XSCALE);
cpu->midr = 0x69052d00;
cpu->ctr = 0xd172172;
cpu->reset_sctlr = 0x00000078;
}
static void pxa260_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "marvell,xscale";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_XSCALE);
cpu->midr = 0x69052903;
cpu->ctr = 0xd172172;
cpu->reset_sctlr = 0x00000078;
}
static void pxa261_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "marvell,xscale";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_XSCALE);
cpu->midr = 0x69052d05;
cpu->ctr = 0xd172172;
cpu->reset_sctlr = 0x00000078;
}
static void pxa262_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "marvell,xscale";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_XSCALE);
cpu->midr = 0x69052d06;
cpu->ctr = 0xd172172;
cpu->reset_sctlr = 0x00000078;
}
static void pxa270a0_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "marvell,xscale";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_XSCALE);
set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
cpu->midr = 0x69054110;
cpu->ctr = 0xd172172;
cpu->reset_sctlr = 0x00000078;
}
static void pxa270a1_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "marvell,xscale";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_XSCALE);
set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
cpu->midr = 0x69054111;
cpu->ctr = 0xd172172;
cpu->reset_sctlr = 0x00000078;
}
static void pxa270b0_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "marvell,xscale";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_XSCALE);
set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
cpu->midr = 0x69054112;
cpu->ctr = 0xd172172;
cpu->reset_sctlr = 0x00000078;
}
static void pxa270b1_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "marvell,xscale";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_XSCALE);
set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
cpu->midr = 0x69054113;
cpu->ctr = 0xd172172;
cpu->reset_sctlr = 0x00000078;
}
static void pxa270c0_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "marvell,xscale";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_XSCALE);
set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
cpu->midr = 0x69054114;
cpu->ctr = 0xd172172;
cpu->reset_sctlr = 0x00000078;
}
static void pxa270c5_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
cpu->dtb_compatible = "marvell,xscale";
set_feature(&cpu->env, ARM_FEATURE_V5);
set_feature(&cpu->env, ARM_FEATURE_XSCALE);
set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
cpu->midr = 0x69054117;
cpu->ctr = 0xd172172;
cpu->reset_sctlr = 0x00000078;
}
static void arm_v7m_class_init(ObjectClass *oc, void *data)
{
ARMCPUClass *acc = ARM_CPU_CLASS(oc);
CPUClass *cc = CPU_CLASS(oc);
acc->info = data;
#ifndef CONFIG_USER_ONLY
cc->do_interrupt = arm_v7m_cpu_do_interrupt;
#endif
cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt;
}
static const ARMCPUInfo arm_tcg_cpus[] = {
{ .name = "arm926", .initfn = arm926_initfn },
{ .name = "arm946", .initfn = arm946_initfn },
{ .name = "arm1026", .initfn = arm1026_initfn },
/*
* What QEMU calls "arm1136-r2" is actually the 1136 r0p2, i.e. an
* older core than plain "arm1136". In particular this does not
* have the v6K features.
*/
{ .name = "arm1136-r2", .initfn = arm1136_r2_initfn },
{ .name = "arm1136", .initfn = arm1136_initfn },
{ .name = "arm1176", .initfn = arm1176_initfn },
{ .name = "arm11mpcore", .initfn = arm11mpcore_initfn },
{ .name = "cortex-m0", .initfn = cortex_m0_initfn,
.class_init = arm_v7m_class_init },
{ .name = "cortex-m3", .initfn = cortex_m3_initfn,
.class_init = arm_v7m_class_init },
{ .name = "cortex-m4", .initfn = cortex_m4_initfn,
.class_init = arm_v7m_class_init },
{ .name = "cortex-m7", .initfn = cortex_m7_initfn,
.class_init = arm_v7m_class_init },
{ .name = "cortex-m33", .initfn = cortex_m33_initfn,
.class_init = arm_v7m_class_init },
{ .name = "cortex-r5", .initfn = cortex_r5_initfn },
{ .name = "cortex-r5f", .initfn = cortex_r5f_initfn },
{ .name = "ti925t", .initfn = ti925t_initfn },
{ .name = "sa1100", .initfn = sa1100_initfn },
{ .name = "sa1110", .initfn = sa1110_initfn },
{ .name = "pxa250", .initfn = pxa250_initfn },
{ .name = "pxa255", .initfn = pxa255_initfn },
{ .name = "pxa260", .initfn = pxa260_initfn },
{ .name = "pxa261", .initfn = pxa261_initfn },
{ .name = "pxa262", .initfn = pxa262_initfn },
/* "pxa270" is an alias for "pxa270-a0" */
{ .name = "pxa270", .initfn = pxa270a0_initfn },
{ .name = "pxa270-a0", .initfn = pxa270a0_initfn },
{ .name = "pxa270-a1", .initfn = pxa270a1_initfn },
{ .name = "pxa270-b0", .initfn = pxa270b0_initfn },
{ .name = "pxa270-b1", .initfn = pxa270b1_initfn },
{ .name = "pxa270-c0", .initfn = pxa270c0_initfn },
{ .name = "pxa270-c5", .initfn = pxa270c5_initfn },
};
static void arm_tcg_cpu_register_types(void)
{
size_t i;
for (i = 0; i < ARRAY_SIZE(arm_tcg_cpus); ++i) {
arm_cpu_register(&arm_tcg_cpus[i]);
}
}
type_init(arm_tcg_cpu_register_types)
#endif /* !CONFIG_USER_ONLY || !TARGET_AARCH64 */

View File

@ -1099,25 +1099,40 @@ DEF_HELPER_FLAGS_6(sve_fcadd_s, TCG_CALL_NO_RWG,
DEF_HELPER_FLAGS_6(sve_fcadd_d, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_3(sve_fmla_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
DEF_HELPER_FLAGS_3(sve_fmla_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
DEF_HELPER_FLAGS_3(sve_fmla_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
DEF_HELPER_FLAGS_7(sve_fmla_zpzzz_h, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_7(sve_fmla_zpzzz_s, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_7(sve_fmla_zpzzz_d, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_3(sve_fmls_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
DEF_HELPER_FLAGS_3(sve_fmls_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
DEF_HELPER_FLAGS_3(sve_fmls_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
DEF_HELPER_FLAGS_7(sve_fmls_zpzzz_h, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_7(sve_fmls_zpzzz_s, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_7(sve_fmls_zpzzz_d, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_3(sve_fnmla_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
DEF_HELPER_FLAGS_3(sve_fnmla_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
DEF_HELPER_FLAGS_3(sve_fnmla_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
DEF_HELPER_FLAGS_7(sve_fnmla_zpzzz_h, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_7(sve_fnmla_zpzzz_s, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_7(sve_fnmla_zpzzz_d, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
DEF_HELPER_FLAGS_7(sve_fnmls_zpzzz_h, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_7(sve_fnmls_zpzzz_s, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_7(sve_fnmls_zpzzz_d, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_3(sve_fcmla_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
DEF_HELPER_FLAGS_3(sve_fcmla_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
DEF_HELPER_FLAGS_3(sve_fcmla_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
DEF_HELPER_FLAGS_7(sve_fcmla_zpzzz_h, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_7(sve_fcmla_zpzzz_s, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_7(sve_fcmla_zpzzz_d, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(sve_ftmad_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_5(sve_ftmad_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)

View File

@ -503,35 +503,19 @@ void init_cpreg_list(ARMCPU *cpu)
}
/*
* Some registers are not accessible if EL3.NS=0 and EL3 is using AArch32 but
* they are accessible when EL3 is using AArch64 regardless of EL3.NS.
*
* access_el3_aa32ns: Used to check AArch32 register views.
* access_el3_aa32ns_aa64any: Used to check both AArch32/64 register views.
* Some registers are not accessible from AArch32 EL3 if SCR.NS == 0.
*/
static CPAccessResult access_el3_aa32ns(CPUARMState *env,
const ARMCPRegInfo *ri,
bool isread)
{
bool secure = arm_is_secure_below_el3(env);
assert(!arm_el_is_aa64(env, 3));
if (secure) {
if (!is_a64(env) && arm_current_el(env) == 3 &&
arm_is_secure_below_el3(env)) {
return CP_ACCESS_TRAP_UNCATEGORIZED;
}
return CP_ACCESS_OK;
}
static CPAccessResult access_el3_aa32ns_aa64any(CPUARMState *env,
const ARMCPRegInfo *ri,
bool isread)
{
if (!arm_el_is_aa64(env, 3)) {
return access_el3_aa32ns(env, ri, isread);
}
return CP_ACCESS_OK;
}
/* Some secure-only AArch32 registers trap to EL3 if used from
* Secure EL1 (but are just ordinary UNDEF in other non-EL3 contexts).
* Note that an access from Secure EL1 can only happen if EL3 is AArch64.
@ -5147,7 +5131,7 @@ static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = {
.access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "VTCR_EL2", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 2,
.access = PL2_RW, .accessfn = access_el3_aa32ns_aa64any,
.access = PL2_RW, .accessfn = access_el3_aa32ns,
.type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "VTTBR", .state = ARM_CP_STATE_AA32,
.cp = 15, .opc1 = 6, .crm = 2,
@ -5195,7 +5179,7 @@ static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = {
.type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "HPFAR_EL2", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 4,
.access = PL2_RW, .accessfn = access_el3_aa32ns_aa64any,
.access = PL2_RW, .accessfn = access_el3_aa32ns,
.type = ARM_CP_CONST, .resetvalue = 0 },
{ .name = "HSTR_EL2", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 3,
@ -7537,12 +7521,12 @@ void register_cp_regs_for_features(ARMCPU *cpu)
ARMCPRegInfo vpidr_regs[] = {
{ .name = "VPIDR_EL2", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 0,
.access = PL2_RW, .accessfn = access_el3_aa32ns_aa64any,
.access = PL2_RW, .accessfn = access_el3_aa32ns,
.type = ARM_CP_CONST, .resetvalue = cpu->midr,
.fieldoffset = offsetof(CPUARMState, cp15.vpidr_el2) },
{ .name = "VMPIDR_EL2", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 5,
.access = PL2_RW, .accessfn = access_el3_aa32ns_aa64any,
.access = PL2_RW, .accessfn = access_el3_aa32ns,
.type = ARM_CP_NO_RAW,
.writefn = arm_cp_write_ignore, .readfn = mpidr_read },
REGINFO_SENTINEL

View File

@ -979,11 +979,6 @@ static inline int arm_num_ctx_cmps(ARMCPU *cpu)
}
}
/* Note make_memop_idx reserves 4 bits for mmu_idx, and MO_BSWAP is bit 3.
* Thus a TCGMemOpIdx, without any MO_ALIGN bits, fits in 8 bits.
*/
#define MEMOPIDX_SHIFT 8
/**
* v7m_using_psp: Return true if using process stack pointer
* Return true if the CPU is currently using the process stack

View File

@ -22,11 +22,6 @@
#include "internals.h"
#include "qemu/log.h"
static inline void set_feature(uint64_t *features, int feature)
{
*features |= 1ULL << feature;
}
static int read_sys_reg32(int fd, uint32_t *pret, uint64_t id)
{
struct kvm_one_reg idreg = { .id = id, .addr = (uintptr_t)pret };
@ -146,14 +141,14 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
* timers; this in turn implies most of the other feature
* bits, but a few must be tested.
*/
set_feature(&features, ARM_FEATURE_V7VE);
set_feature(&features, ARM_FEATURE_GENERIC_TIMER);
features |= 1ULL << ARM_FEATURE_V7VE;
features |= 1ULL << ARM_FEATURE_GENERIC_TIMER;
if (extract32(id_pfr0, 12, 4) == 1) {
set_feature(&features, ARM_FEATURE_THUMB2EE);
features |= 1ULL << ARM_FEATURE_THUMB2EE;
}
if (extract32(ahcf->isar.mvfr1, 12, 4) == 1) {
set_feature(&features, ARM_FEATURE_NEON);
features |= 1ULL << ARM_FEATURE_NEON;
}
ahcf->features = features;

View File

@ -447,16 +447,6 @@ void kvm_arm_pmu_set_irq(CPUState *cs, int irq)
}
}
static inline void set_feature(uint64_t *features, int feature)
{
*features |= 1ULL << feature;
}
static inline void unset_feature(uint64_t *features, int feature)
{
*features &= ~(1ULL << feature);
}
static int read_sys_reg32(int fd, uint32_t *pret, uint64_t id)
{
uint64_t ret;
@ -648,11 +638,11 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
* with VFPv4+Neon; this in turn implies most of the other
* feature bits.
*/
set_feature(&features, ARM_FEATURE_V8);
set_feature(&features, ARM_FEATURE_NEON);
set_feature(&features, ARM_FEATURE_AARCH64);
set_feature(&features, ARM_FEATURE_PMU);
set_feature(&features, ARM_FEATURE_GENERIC_TIMER);
features |= 1ULL << ARM_FEATURE_V8;
features |= 1ULL << ARM_FEATURE_NEON;
features |= 1ULL << ARM_FEATURE_AARCH64;
features |= 1ULL << ARM_FEATURE_PMU;
features |= 1ULL << ARM_FEATURE_GENERIC_TIMER;
ahcf->features = features;
@ -802,7 +792,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
if (cpu->has_pmu) {
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_PMU_V3;
} else {
unset_feature(&env->features, ARM_FEATURE_PMU);
env->features &= ~(1ULL << ARM_FEATURE_PMU);
}
if (cpu_isar_feature(aa64_sve, cpu)) {
assert(kvm_arm_sve_supported(cs));

File diff suppressed because it is too large Load Diff

View File

@ -2044,7 +2044,11 @@ static bool trans_DUP_x(DisasContext *s, arg_DUP_x *a)
unsigned nofs = vec_reg_offset(s, a->rn, index, esz);
tcg_gen_gvec_dup_mem(esz, dofs, nofs, vsz, vsz);
} else {
tcg_gen_gvec_dup_imm(esz, dofs, vsz, vsz, 0);
/*
* While dup_mem handles 128-bit elements, dup_imm does not.
* Thankfully element size doesn't matter for splatting zero.
*/
tcg_gen_gvec_dup_imm(MO_64, dofs, vsz, vsz, 0);
}
}
return true;
@ -3946,42 +3950,30 @@ static bool trans_FCADD(DisasContext *s, arg_FCADD *a)
return true;
}
typedef void gen_helper_sve_fmla(TCGv_env, TCGv_ptr, TCGv_i32);
static bool do_fmla(DisasContext *s, arg_rprrr_esz *a, gen_helper_sve_fmla *fn)
static bool do_fmla(DisasContext *s, arg_rprrr_esz *a,
gen_helper_gvec_5_ptr *fn)
{
if (fn == NULL) {
if (a->esz == 0) {
return false;
}
if (!sve_access_check(s)) {
return true;
if (sve_access_check(s)) {
unsigned vsz = vec_full_reg_size(s);
TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
tcg_gen_gvec_5_ptr(vec_full_reg_offset(s, a->rd),
vec_full_reg_offset(s, a->rn),
vec_full_reg_offset(s, a->rm),
vec_full_reg_offset(s, a->ra),
pred_full_reg_offset(s, a->pg),
status, vsz, vsz, 0, fn);
tcg_temp_free_ptr(status);
}
unsigned vsz = vec_full_reg_size(s);
unsigned desc;
TCGv_i32 t_desc;
TCGv_ptr pg = tcg_temp_new_ptr();
/* We would need 7 operands to pass these arguments "properly".
* So we encode all the register numbers into the descriptor.
*/
desc = deposit32(a->rd, 5, 5, a->rn);
desc = deposit32(desc, 10, 5, a->rm);
desc = deposit32(desc, 15, 5, a->ra);
desc = simd_desc(vsz, vsz, desc);
t_desc = tcg_const_i32(desc);
tcg_gen_addi_ptr(pg, cpu_env, pred_full_reg_offset(s, a->pg));
fn(cpu_env, pg, t_desc);
tcg_temp_free_i32(t_desc);
tcg_temp_free_ptr(pg);
return true;
}
#define DO_FMLA(NAME, name) \
static bool trans_##NAME(DisasContext *s, arg_rprrr_esz *a) \
{ \
static gen_helper_sve_fmla * const fns[4] = { \
static gen_helper_gvec_5_ptr * const fns[4] = { \
NULL, gen_helper_sve_##name##_h, \
gen_helper_sve_##name##_s, gen_helper_sve_##name##_d \
}; \
@ -3997,7 +3989,8 @@ DO_FMLA(FNMLS_zpzzz, fnmls_zpzzz)
static bool trans_FCMLA_zpzzz(DisasContext *s, arg_FCMLA_zpzzz *a)
{
static gen_helper_sve_fmla * const fns[3] = {
static gen_helper_gvec_5_ptr * const fns[4] = {
NULL,
gen_helper_sve_fcmla_zpzzz_h,
gen_helper_sve_fcmla_zpzzz_s,
gen_helper_sve_fcmla_zpzzz_d,
@ -4008,25 +4001,14 @@ static bool trans_FCMLA_zpzzz(DisasContext *s, arg_FCMLA_zpzzz *a)
}
if (sve_access_check(s)) {
unsigned vsz = vec_full_reg_size(s);
unsigned desc;
TCGv_i32 t_desc;
TCGv_ptr pg = tcg_temp_new_ptr();
/* We would need 7 operands to pass these arguments "properly".
* So we encode all the register numbers into the descriptor.
*/
desc = deposit32(a->rd, 5, 5, a->rn);
desc = deposit32(desc, 10, 5, a->rm);
desc = deposit32(desc, 15, 5, a->ra);
desc = deposit32(desc, 20, 2, a->rot);
desc = sextract32(desc, 0, 22);
desc = simd_desc(vsz, vsz, desc);
t_desc = tcg_const_i32(desc);
tcg_gen_addi_ptr(pg, cpu_env, pred_full_reg_offset(s, a->pg));
fns[a->esz - 1](cpu_env, pg, t_desc);
tcg_temp_free_i32(t_desc);
tcg_temp_free_ptr(pg);
TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
tcg_gen_gvec_5_ptr(vec_full_reg_offset(s, a->rd),
vec_full_reg_offset(s, a->rn),
vec_full_reg_offset(s, a->rm),
vec_full_reg_offset(s, a->ra),
pred_full_reg_offset(s, a->pg),
status, vsz, vsz, a->rot, fns[a->esz]);
tcg_temp_free_ptr(status);
}
return true;
}
@ -4582,11 +4564,6 @@ static const uint8_t dtype_esz[16] = {
3, 2, 1, 3
};
static TCGMemOpIdx sve_memopidx(DisasContext *s, int dtype)
{
return make_memop_idx(s->be_data | dtype_mop[dtype], get_mem_index(s));
}
static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
int dtype, gen_helper_gvec_mem *fn)
{
@ -4599,9 +4576,7 @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
* registers as pointers, so encode the regno into the data field.
* For consistency, do this even for LD1.
*/
desc = sve_memopidx(s, dtype);
desc |= zt << MEMOPIDX_SHIFT;
desc = simd_desc(vsz, vsz, desc);
desc = simd_desc(vsz, vsz, zt);
t_desc = tcg_const_i32(desc);
t_pg = tcg_temp_new_ptr();
@ -4833,9 +4808,7 @@ static void do_ldrq(DisasContext *s, int zt, int pg, TCGv_i64 addr, int msz)
int desc, poff;
/* Load the first quadword using the normal predicated load helpers. */
desc = sve_memopidx(s, msz_dtype(s, msz));
desc |= zt << MEMOPIDX_SHIFT;
desc = simd_desc(16, 16, desc);
desc = simd_desc(16, 16, zt);
t_desc = tcg_const_i32(desc);
poff = pred_full_reg_offset(s, pg);
@ -5064,9 +5037,7 @@ static void do_mem_zpz(DisasContext *s, int zt, int pg, int zm,
TCGv_i32 t_desc;
int desc;
desc = sve_memopidx(s, msz_dtype(s, msz));
desc |= scale << MEMOPIDX_SHIFT;
desc = simd_desc(vsz, vsz, desc);
desc = simd_desc(vsz, vsz, scale);
t_desc = tcg_const_i32(desc);
tcg_gen_addi_ptr(t_pg, cpu_env, pred_full_reg_offset(s, pg));