mirror of https://gitee.com/openkylin/qemu.git
target-arm: Add ARMMMUFaultInfo
Introduce ARMMMUFaultInfo to propagate MMU Fault information across the MMU translation code path. This is in preparation for adding Stage-2 translation. No functional changes. Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Message-id: 1445864527-14520-11-git-send-email-edgar.iglesias@gmail.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
af51f566ec
commit
e14b5a23d8
|
@ -18,7 +18,8 @@
|
|||
static bool get_phys_addr(CPUARMState *env, target_ulong address,
|
||||
int access_type, ARMMMUIdx mmu_idx,
|
||||
hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
|
||||
target_ulong *page_size, uint32_t *fsr);
|
||||
target_ulong *page_size, uint32_t *fsr,
|
||||
ARMMMUFaultInfo *fi);
|
||||
|
||||
/* Definitions for the PMCCNTR and PMCR registers */
|
||||
#define PMCRD 0x8
|
||||
|
@ -1778,9 +1779,10 @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
|
|||
bool ret;
|
||||
uint64_t par64;
|
||||
MemTxAttrs attrs = {};
|
||||
ARMMMUFaultInfo fi = {};
|
||||
|
||||
ret = get_phys_addr(env, value, access_type, mmu_idx,
|
||||
&phys_addr, &attrs, &prot, &page_size, &fsr);
|
||||
&phys_addr, &attrs, &prot, &page_size, &fsr, &fi);
|
||||
if (extended_addresses_enabled(env)) {
|
||||
/* fsr is a DFSR/IFSR value for the long descriptor
|
||||
* translation table format, but with WnR always clear.
|
||||
|
@ -6231,7 +6233,8 @@ static uint64_t arm_ldq_ptw(CPUState *cs, hwaddr addr, bool is_secure)
|
|||
static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
|
||||
int access_type, ARMMMUIdx mmu_idx,
|
||||
hwaddr *phys_ptr, int *prot,
|
||||
target_ulong *page_size, uint32_t *fsr)
|
||||
target_ulong *page_size, uint32_t *fsr,
|
||||
ARMMMUFaultInfo *fi)
|
||||
{
|
||||
CPUState *cs = CPU(arm_env_get_cpu(env));
|
||||
int code;
|
||||
|
@ -6344,7 +6347,8 @@ do_fault:
|
|||
static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
|
||||
int access_type, ARMMMUIdx mmu_idx,
|
||||
hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
|
||||
target_ulong *page_size, uint32_t *fsr)
|
||||
target_ulong *page_size, uint32_t *fsr,
|
||||
ARMMMUFaultInfo *fi)
|
||||
{
|
||||
CPUState *cs = CPU(arm_env_get_cpu(env));
|
||||
int code;
|
||||
|
@ -6554,7 +6558,8 @@ static bool check_s2_startlevel(ARMCPU *cpu, bool is_aa64, int level,
|
|||
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
|
||||
int access_type, ARMMMUIdx mmu_idx,
|
||||
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
|
||||
target_ulong *page_size_ptr, uint32_t *fsr)
|
||||
target_ulong *page_size_ptr, uint32_t *fsr,
|
||||
ARMMMUFaultInfo *fi)
|
||||
{
|
||||
ARMCPU *cpu = arm_env_get_cpu(env);
|
||||
CPUState *cs = CPU(cpu);
|
||||
|
@ -7129,7 +7134,8 @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
|
|||
static bool get_phys_addr(CPUARMState *env, target_ulong address,
|
||||
int access_type, ARMMMUIdx mmu_idx,
|
||||
hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
|
||||
target_ulong *page_size, uint32_t *fsr)
|
||||
target_ulong *page_size, uint32_t *fsr,
|
||||
ARMMMUFaultInfo *fi)
|
||||
{
|
||||
if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) {
|
||||
/* TODO: when we support EL2 we should here call ourselves recursively
|
||||
|
@ -7188,13 +7194,13 @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
|
|||
|
||||
if (regime_using_lpae_format(env, mmu_idx)) {
|
||||
return get_phys_addr_lpae(env, address, access_type, mmu_idx, phys_ptr,
|
||||
attrs, prot, page_size, fsr);
|
||||
attrs, prot, page_size, fsr, fi);
|
||||
} else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
|
||||
return get_phys_addr_v6(env, address, access_type, mmu_idx, phys_ptr,
|
||||
attrs, prot, page_size, fsr);
|
||||
attrs, prot, page_size, fsr, fi);
|
||||
} else {
|
||||
return get_phys_addr_v5(env, address, access_type, mmu_idx, phys_ptr,
|
||||
prot, page_size, fsr);
|
||||
prot, page_size, fsr, fi);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7203,7 +7209,8 @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
|
|||
* fsr with ARM DFSR/IFSR fault register format value on failure.
|
||||
*/
|
||||
bool arm_tlb_fill(CPUState *cs, vaddr address,
|
||||
int access_type, int mmu_idx, uint32_t *fsr)
|
||||
int access_type, int mmu_idx, uint32_t *fsr,
|
||||
ARMMMUFaultInfo *fi)
|
||||
{
|
||||
ARMCPU *cpu = ARM_CPU(cs);
|
||||
CPUARMState *env = &cpu->env;
|
||||
|
@ -7214,7 +7221,7 @@ bool arm_tlb_fill(CPUState *cs, vaddr address,
|
|||
MemTxAttrs attrs = {};
|
||||
|
||||
ret = get_phys_addr(env, address, access_type, mmu_idx, &phys_addr,
|
||||
&attrs, &prot, &page_size, fsr);
|
||||
&attrs, &prot, &page_size, fsr, fi);
|
||||
if (!ret) {
|
||||
/* Map a single [sub]page. */
|
||||
phys_addr &= TARGET_PAGE_MASK;
|
||||
|
@ -7237,9 +7244,10 @@ hwaddr arm_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
|||
bool ret;
|
||||
uint32_t fsr;
|
||||
MemTxAttrs attrs = {};
|
||||
ARMMMUFaultInfo fi = {};
|
||||
|
||||
ret = get_phys_addr(env, addr, 0, cpu_mmu_index(env, false), &phys_addr,
|
||||
&attrs, &prot, &page_size, &fsr);
|
||||
&attrs, &prot, &page_size, &fsr, &fi);
|
||||
|
||||
if (ret) {
|
||||
return -1;
|
||||
|
|
|
@ -414,8 +414,21 @@ bool arm_is_psci_call(ARMCPU *cpu, int excp_type);
|
|||
void arm_handle_psci_call(ARMCPU *cpu);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* ARMMMUFaultInfo: Information describing an ARM MMU Fault
|
||||
* @s2addr: Address that caused a fault at stage 2
|
||||
* @stage2: True if we faulted at stage 2
|
||||
* @s1ptw: True if we faulted at stage 2 while doing a stage 1 page-table walk
|
||||
*/
|
||||
typedef struct ARMMMUFaultInfo ARMMMUFaultInfo;
|
||||
struct ARMMMUFaultInfo {
|
||||
target_ulong s2addr;
|
||||
bool stage2;
|
||||
bool s1ptw;
|
||||
};
|
||||
|
||||
/* Do a page table walk and add page to TLB if possible */
|
||||
bool arm_tlb_fill(CPUState *cpu, vaddr address, int rw, int mmu_idx,
|
||||
uint32_t *fsr);
|
||||
uint32_t *fsr, ARMMMUFaultInfo *fi);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -83,8 +83,9 @@ void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
|
|||
{
|
||||
bool ret;
|
||||
uint32_t fsr = 0;
|
||||
ARMMMUFaultInfo fi = {};
|
||||
|
||||
ret = arm_tlb_fill(cs, addr, is_write, mmu_idx, &fsr);
|
||||
ret = arm_tlb_fill(cs, addr, is_write, mmu_idx, &fsr, &fi);
|
||||
if (unlikely(ret)) {
|
||||
ARMCPU *cpu = ARM_CPU(cs);
|
||||
CPUARMState *env = &cpu->env;
|
||||
|
|
Loading…
Reference in New Issue