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:
commit
de2f658b6b
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
2
exec.c
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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), µbit_i2c_ops, s,
|
||||
"microbit.twi", NRF51_TWI_SIZE);
|
||||
"microbit.twi", NRF51_PERIPHERAL_SIZE);
|
||||
sysbus_init_mmio(sbd, &s->iomem);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
662
target/arm/cpu.c
662
target/arm/cpu.c
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
664
target/arm/cpu_tcg.c
Normal 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 */
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
@ -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));
|
||||
|
|
Loading…
Reference in a new issue