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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user