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:
Eric Auger 2020-07-28 17:08:05 +02:00 committed by Peter Maydell
parent 8cbd461622
commit 1733837d7c

View File

@ -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,56 +199,42 @@ 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);
if (is_table_pte(pte, level)) {
ap = PTE_APTABLE(pte);
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);
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);
return 0;
}
if (is_block_pte(pte, level)) {
} else {
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;
}
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);
tlbe->translated_addr = gpa + (iova & mask);
tlbe->perm = PTE_AP_TO_PERM(ap);
return 0;
}
/* table pte */
ap = PTE_APTABLE(pte);
ap = PTE_AP(pte);
if (is_permission_fault(ap, perm)) {
info->type = SMMU_PTW_ERR_PERMISSION;
goto error;
}
baseaddr = get_table_pte_address(pte, granule_sz);
level++;
}
tlbe->translated_addr = gpa + (iova & mask);
tlbe->perm = PTE_AP_TO_PERM(ap);
return 0;
}
info->type = SMMU_PTW_ERR_TRANSLATION;
error: