diff options
Diffstat (limited to 'hw/spapr_iommu.c')
-rw-r--r-- | hw/spapr_iommu.c | 40 |
1 files changed, 22 insertions, 18 deletions
diff --git a/hw/spapr_iommu.c b/hw/spapr_iommu.c index 5a769b9f4a..388ffa4b22 100644 --- a/hw/spapr_iommu.c +++ b/hw/spapr_iommu.c @@ -162,6 +162,22 @@ void spapr_tce_free(DMAContext *dma) } } +static target_ulong put_tce_emu(sPAPRTCETable *tcet, target_ulong ioba, + target_ulong tce) +{ + sPAPRTCE *tcep; + + if (ioba >= tcet->window_size) { + hcall_dprintf("spapr_vio_put_tce on out-of-boards IOBA 0x" + TARGET_FMT_lx "\n", ioba); + return H_PARAMETER; + } + + tcep = tcet->table + (ioba >> SPAPR_TCE_PAGE_SHIFT); + tcep->tce = tce; + + return H_SUCCESS; +} static target_ulong h_put_tce(CPUPPCState *env, sPAPREnvironment *spapr, target_ulong opcode, target_ulong *args) @@ -170,37 +186,25 @@ static target_ulong h_put_tce(CPUPPCState *env, sPAPREnvironment *spapr, target_ulong ioba = args[1]; target_ulong tce = args[2]; sPAPRTCETable *tcet = spapr_tce_find_by_liobn(liobn); - sPAPRTCE *tcep; if (liobn & 0xFFFFFFFF00000000ULL) { hcall_dprintf("spapr_vio_put_tce on out-of-boundsw LIOBN " TARGET_FMT_lx "\n", liobn); return H_PARAMETER; } - if (!tcet) { - hcall_dprintf("spapr_vio_put_tce on non-existent LIOBN " - TARGET_FMT_lx "\n", liobn); - return H_PARAMETER; - } ioba &= ~(SPAPR_TCE_PAGE_SIZE - 1); + if (tcet) { + return put_tce_emu(tcet, ioba, tce); + } #ifdef DEBUG_TCE - fprintf(stderr, "spapr_vio_put_tce on liobn=" TARGET_FMT_lx /*%s*/ + fprintf(stderr, "%s on liobn=" TARGET_FMT_lx /*%s*/ " ioba 0x" TARGET_FMT_lx " TCE 0x" TARGET_FMT_lx "\n", - liobn, /*dev->qdev.id, */ioba, tce); + __func__, liobn, /*dev->qdev.id, */ioba, tce); #endif - if (ioba >= tcet->window_size) { - hcall_dprintf("spapr_vio_put_tce on out-of-boards IOBA 0x" - TARGET_FMT_lx "\n", ioba); - return H_PARAMETER; - } - - tcep = tcet->table + (ioba >> SPAPR_TCE_PAGE_SHIFT); - tcep->tce = tce; - - return H_SUCCESS; + return H_PARAMETER; } void spapr_iommu_init(void) |