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,
|
static bool get_phys_addr(CPUARMState *env, target_ulong address,
|
||||||
int access_type, ARMMMUIdx mmu_idx,
|
int access_type, ARMMMUIdx mmu_idx,
|
||||||
hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
|
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 */
|
/* Definitions for the PMCCNTR and PMCR registers */
|
||||||
#define PMCRD 0x8
|
#define PMCRD 0x8
|
||||||
@ -1778,9 +1779,10 @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
|
|||||||
bool ret;
|
bool ret;
|
||||||
uint64_t par64;
|
uint64_t par64;
|
||||||
MemTxAttrs attrs = {};
|
MemTxAttrs attrs = {};
|
||||||
|
ARMMMUFaultInfo fi = {};
|
||||||
|
|
||||||
ret = get_phys_addr(env, value, access_type, mmu_idx,
|
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)) {
|
if (extended_addresses_enabled(env)) {
|
||||||
/* fsr is a DFSR/IFSR value for the long descriptor
|
/* fsr is a DFSR/IFSR value for the long descriptor
|
||||||
* translation table format, but with WnR always clear.
|
* 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,
|
static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
|
||||||
int access_type, ARMMMUIdx mmu_idx,
|
int access_type, ARMMMUIdx mmu_idx,
|
||||||
hwaddr *phys_ptr, int *prot,
|
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));
|
CPUState *cs = CPU(arm_env_get_cpu(env));
|
||||||
int code;
|
int code;
|
||||||
@ -6344,7 +6347,8 @@ do_fault:
|
|||||||
static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
|
static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
|
||||||
int access_type, ARMMMUIdx mmu_idx,
|
int access_type, ARMMMUIdx mmu_idx,
|
||||||
hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
|
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));
|
CPUState *cs = CPU(arm_env_get_cpu(env));
|
||||||
int code;
|
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,
|
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
|
||||||
int access_type, ARMMMUIdx mmu_idx,
|
int access_type, ARMMMUIdx mmu_idx,
|
||||||
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
|
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);
|
ARMCPU *cpu = arm_env_get_cpu(env);
|
||||||
CPUState *cs = CPU(cpu);
|
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,
|
static bool get_phys_addr(CPUARMState *env, target_ulong address,
|
||||||
int access_type, ARMMMUIdx mmu_idx,
|
int access_type, ARMMMUIdx mmu_idx,
|
||||||
hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
|
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) {
|
if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) {
|
||||||
/* TODO: when we support EL2 we should here call ourselves recursively
|
/* 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)) {
|
if (regime_using_lpae_format(env, mmu_idx)) {
|
||||||
return get_phys_addr_lpae(env, address, access_type, mmu_idx, phys_ptr,
|
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) {
|
} else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
|
||||||
return get_phys_addr_v6(env, address, access_type, mmu_idx, phys_ptr,
|
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 {
|
} else {
|
||||||
return get_phys_addr_v5(env, address, access_type, mmu_idx, phys_ptr,
|
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.
|
* fsr with ARM DFSR/IFSR fault register format value on failure.
|
||||||
*/
|
*/
|
||||||
bool arm_tlb_fill(CPUState *cs, vaddr address,
|
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);
|
ARMCPU *cpu = ARM_CPU(cs);
|
||||||
CPUARMState *env = &cpu->env;
|
CPUARMState *env = &cpu->env;
|
||||||
@ -7214,7 +7221,7 @@ bool arm_tlb_fill(CPUState *cs, vaddr address,
|
|||||||
MemTxAttrs attrs = {};
|
MemTxAttrs attrs = {};
|
||||||
|
|
||||||
ret = get_phys_addr(env, address, access_type, mmu_idx, &phys_addr,
|
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) {
|
if (!ret) {
|
||||||
/* Map a single [sub]page. */
|
/* Map a single [sub]page. */
|
||||||
phys_addr &= TARGET_PAGE_MASK;
|
phys_addr &= TARGET_PAGE_MASK;
|
||||||
@ -7237,9 +7244,10 @@ hwaddr arm_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
|||||||
bool ret;
|
bool ret;
|
||||||
uint32_t fsr;
|
uint32_t fsr;
|
||||||
MemTxAttrs attrs = {};
|
MemTxAttrs attrs = {};
|
||||||
|
ARMMMUFaultInfo fi = {};
|
||||||
|
|
||||||
ret = get_phys_addr(env, addr, 0, cpu_mmu_index(env, false), &phys_addr,
|
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) {
|
if (ret) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -414,8 +414,21 @@ bool arm_is_psci_call(ARMCPU *cpu, int excp_type);
|
|||||||
void arm_handle_psci_call(ARMCPU *cpu);
|
void arm_handle_psci_call(ARMCPU *cpu);
|
||||||
#endif
|
#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 */
|
/* 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,
|
bool arm_tlb_fill(CPUState *cpu, vaddr address, int rw, int mmu_idx,
|
||||||
uint32_t *fsr);
|
uint32_t *fsr, ARMMMUFaultInfo *fi);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -83,8 +83,9 @@ void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
|
|||||||
{
|
{
|
||||||
bool ret;
|
bool ret;
|
||||||
uint32_t fsr = 0;
|
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)) {
|
if (unlikely(ret)) {
|
||||||
ARMCPU *cpu = ARM_CPU(cs);
|
ARMCPU *cpu = ARM_CPU(cs);
|
||||||
CPUARMState *env = &cpu->env;
|
CPUARMState *env = &cpu->env;
|
||||||
|
Loading…
Reference in New Issue
Block a user