hw/arm/smmu-common: Factorize some code in smmu_ptw_64()
Page and block PTE decoding can share some code. Let's first handle table PTE and factorize some code shared by page and block PTEs. Signed-off-by: Eric Auger <eric.auger@redhat.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 20200728150815.11446-2-eric.auger@redhat.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
8cbd461622
commit
1733837d7c
|
@ -186,7 +186,7 @@ static int smmu_ptw_64(SMMUTransCfg *cfg,
|
|||
uint64_t subpage_size = 1ULL << level_shift(level, granule_sz);
|
||||
uint64_t mask = subpage_size - 1;
|
||||
uint32_t offset = iova_level_offset(iova, inputsize, level, granule_sz);
|
||||
uint64_t pte;
|
||||
uint64_t pte, gpa;
|
||||
dma_addr_t pte_addr = baseaddr + offset * sizeof(pte);
|
||||
uint8_t ap;
|
||||
|
||||
|
@ -199,46 +199,10 @@ static int smmu_ptw_64(SMMUTransCfg *cfg,
|
|||
if (is_invalid_pte(pte) || is_reserved_pte(pte, level)) {
|
||||
trace_smmu_ptw_invalid_pte(stage, level, baseaddr,
|
||||
pte_addr, offset, pte);
|
||||
info->type = SMMU_PTW_ERR_TRANSLATION;
|
||||
goto error;
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_page_pte(pte, level)) {
|
||||
uint64_t gpa = get_page_pte_address(pte, granule_sz);
|
||||
|
||||
ap = PTE_AP(pte);
|
||||
if (is_permission_fault(ap, perm)) {
|
||||
info->type = SMMU_PTW_ERR_PERMISSION;
|
||||
goto error;
|
||||
}
|
||||
|
||||
tlbe->translated_addr = gpa + (iova & mask);
|
||||
tlbe->perm = PTE_AP_TO_PERM(ap);
|
||||
trace_smmu_ptw_page_pte(stage, level, iova,
|
||||
baseaddr, pte_addr, pte, gpa);
|
||||
return 0;
|
||||
}
|
||||
if (is_block_pte(pte, level)) {
|
||||
uint64_t block_size;
|
||||
hwaddr gpa = get_block_pte_address(pte, level, granule_sz,
|
||||
&block_size);
|
||||
|
||||
ap = PTE_AP(pte);
|
||||
if (is_permission_fault(ap, perm)) {
|
||||
info->type = SMMU_PTW_ERR_PERMISSION;
|
||||
goto error;
|
||||
}
|
||||
|
||||
trace_smmu_ptw_block_pte(stage, level, baseaddr,
|
||||
pte_addr, pte, iova, gpa,
|
||||
block_size >> 20);
|
||||
|
||||
tlbe->translated_addr = gpa + (iova & mask);
|
||||
tlbe->perm = PTE_AP_TO_PERM(ap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* table pte */
|
||||
if (is_table_pte(pte, level)) {
|
||||
ap = PTE_APTABLE(pte);
|
||||
|
||||
if (is_permission_fault(ap, perm)) {
|
||||
|
@ -247,8 +211,30 @@ static int smmu_ptw_64(SMMUTransCfg *cfg,
|
|||
}
|
||||
baseaddr = get_table_pte_address(pte, granule_sz);
|
||||
level++;
|
||||
continue;
|
||||
} else if (is_page_pte(pte, level)) {
|
||||
gpa = get_page_pte_address(pte, granule_sz);
|
||||
trace_smmu_ptw_page_pte(stage, level, iova,
|
||||
baseaddr, pte_addr, pte, gpa);
|
||||
} else {
|
||||
uint64_t block_size;
|
||||
|
||||
gpa = get_block_pte_address(pte, level, granule_sz,
|
||||
&block_size);
|
||||
trace_smmu_ptw_block_pte(stage, level, baseaddr,
|
||||
pte_addr, pte, iova, gpa,
|
||||
block_size >> 20);
|
||||
}
|
||||
ap = PTE_AP(pte);
|
||||
if (is_permission_fault(ap, perm)) {
|
||||
info->type = SMMU_PTW_ERR_PERMISSION;
|
||||
goto error;
|
||||
}
|
||||
|
||||
tlbe->translated_addr = gpa + (iova & mask);
|
||||
tlbe->perm = PTE_AP_TO_PERM(ap);
|
||||
return 0;
|
||||
}
|
||||
info->type = SMMU_PTW_ERR_TRANSLATION;
|
||||
|
||||
error:
|
||||
|
|
Loading…
Reference in a new issue