static void vtd_do_iommu_translate(IntelIOMMUState *s, uint8_t bus_num,

                                   uint8_t devfn, hwaddr addr, bool is_write,

                                   IOMMUTLBEntry *entry)

{

    VTDContextEntry ce;

    uint64_t slpte;

    uint32_t level;

    uint16_t source_id = vtd_make_source_id(bus_num, devfn);

    int ret_fr;

    bool is_fpd_set = false;

    bool reads = true;

    bool writes = true;



    /* Check if the request is in interrupt address range */

    if (vtd_is_interrupt_addr(addr)) {

        if (is_write) {

            /* FIXME: since we don't know the length of the access here, we

             * treat Non-DWORD length write requests without PASID as

             * interrupt requests, too. Withoud interrupt remapping support,

             * we just use 1:1 mapping.

             */

            VTD_DPRINTF(MMU, "write request to interrupt address "

                        "gpa 0x%"PRIx64, addr);

            entry->iova = addr & VTD_PAGE_MASK_4K;

            entry->translated_addr = addr & VTD_PAGE_MASK_4K;

            entry->addr_mask = ~VTD_PAGE_MASK_4K;

            entry->perm = IOMMU_WO;

            return;

        } else {

            VTD_DPRINTF(GENERAL, "error: read request from interrupt address "

                        "gpa 0x%"PRIx64, addr);

            vtd_report_dmar_fault(s, source_id, addr, VTD_FR_READ, is_write);

            return;

        }

    }



    ret_fr = vtd_dev_to_context_entry(s, bus_num, devfn, &ce);

    is_fpd_set = ce.lo & VTD_CONTEXT_ENTRY_FPD;

    if (ret_fr) {

        ret_fr = -ret_fr;

        if (is_fpd_set && vtd_is_qualified_fault(ret_fr)) {

            VTD_DPRINTF(FLOG, "fault processing is disabled for DMA requests "

                        "through this context-entry (with FPD Set)");

        } else {

            vtd_report_dmar_fault(s, source_id, addr, ret_fr, is_write);

        }

        return;

    }



    ret_fr = vtd_gpa_to_slpte(&ce, addr, is_write, &slpte, &level,

                              &reads, &writes);

    if (ret_fr) {

        ret_fr = -ret_fr;

        if (is_fpd_set && vtd_is_qualified_fault(ret_fr)) {

            VTD_DPRINTF(FLOG, "fault processing is disabled for DMA requests "

                        "through this context-entry (with FPD Set)");

        } else {

            vtd_report_dmar_fault(s, source_id, addr, ret_fr, is_write);

        }

        return;

    }



    entry->iova = addr & VTD_PAGE_MASK_4K;

    entry->translated_addr = vtd_get_slpte_addr(slpte) & VTD_PAGE_MASK_4K;

    entry->addr_mask = ~VTD_PAGE_MASK_4K;

    entry->perm = (writes ? 2 : 0) + (reads ? 1 : 0);

}

static void vtd_do_iommu_translate(IntelIOMMUState *s, uint8_t bus_num,

                                   uint8_t devfn, hwaddr addr, bool is_write,

                                   IOMMUTLBEntry *entry)

{

    VTDContextEntry ce;

    uint64_t slpte;

    uint32_t level;

    uint16_t source_id = vtd_make_source_id(bus_num, devfn);

    int ret_fr;

    bool is_fpd_set = false;

    bool reads = true;

    bool writes = true;



    

    if (vtd_is_interrupt_addr(addr)) {

        if (is_write) {

            









            VTD_DPRINTF(MMU, "write request to interrupt address "

                        "gpa 0x%"PRIx64, addr);

            entry->iova = addr & VTD_PAGE_MASK_4K;

            entry->translated_addr = addr & VTD_PAGE_MASK_4K;

            entry->addr_mask = ~VTD_PAGE_MASK_4K;

            entry->perm = IOMMU_WO;

            return;

        } else {

            VTD_DPRINTF(GENERAL, "error: read request from interrupt address "

                        "gpa 0x%"PRIx64, addr);

            vtd_report_dmar_fault(s, source_id, addr, VTD_FR_READ, is_write);

            return;

        }

    }



    ret_fr = vtd_dev_to_context_entry(s, bus_num, devfn, &ce);

    is_fpd_set = ce.lo & VTD_CONTEXT_ENTRY_FPD;

    if (ret_fr) {

        ret_fr = -ret_fr;

        if (is_fpd_set && vtd_is_qualified_fault(ret_fr)) {

            VTD_DPRINTF(FLOG, "fault processing is disabled for DMA requests "

                        "through this context-entry (with FPD Set)");

        } else {

            vtd_report_dmar_fault(s, source_id, addr, ret_fr, is_write);

        }

        return;

    }



    ret_fr = vtd_gpa_to_slpte(&ce, addr, is_write, &slpte, &level,

                              &reads, &writes);

    if (ret_fr) {

        ret_fr = -ret_fr;

        if (is_fpd_set && vtd_is_qualified_fault(ret_fr)) {

            VTD_DPRINTF(FLOG, "fault processing is disabled for DMA requests "

                        "through this context-entry (with FPD Set)");

        } else {

            vtd_report_dmar_fault(s, source_id, addr, ret_fr, is_write);

        }

        return;

    }



    entry->iova = addr & VTD_PAGE_MASK_4K;

    entry->translated_addr = vtd_get_slpte_addr(slpte) & VTD_PAGE_MASK_4K;

    entry->addr_mask = ~VTD_PAGE_MASK_4K;

    entry->perm = (writes ? 2 : 0) + (reads ? 1 : 0);

}

static void FUNC_0(IntelIOMMUState *VAR_0, uint8_t VAR_1,

                                   uint8_t VAR_2, hwaddr VAR_3, bool VAR_4,

                                   IOMMUTLBEntry *VAR_5)

{

    VTDContextEntry ce;

    uint64_t slpte;

    uint32_t level;

    uint16_t source_id = vtd_make_source_id(VAR_1, VAR_2);

    int VAR_6;

    bool is_fpd_set = false;

    bool reads = true;

    bool writes = true;



    

    if (vtd_is_interrupt_addr(VAR_3)) {

        if (VAR_4) {

            









            VTD_DPRINTF(MMU, "write request to interrupt address "

                        "gpa 0x%"PRIx64, VAR_3);

            VAR_5->iova = VAR_3 & VTD_PAGE_MASK_4K;

            VAR_5->translated_addr = VAR_3 & VTD_PAGE_MASK_4K;

            VAR_5->addr_mask = ~VTD_PAGE_MASK_4K;

            VAR_5->perm = IOMMU_WO;

            return;

        } else {

            VTD_DPRINTF(GENERAL, "error: read request from interrupt address "

                        "gpa 0x%"PRIx64, VAR_3);

            vtd_report_dmar_fault(VAR_0, source_id, VAR_3, VTD_FR_READ, VAR_4);

            return;

        }

    }



    VAR_6 = vtd_dev_to_context_entry(VAR_0, VAR_1, VAR_2, &ce);

    is_fpd_set = ce.lo & VTD_CONTEXT_ENTRY_FPD;

    if (VAR_6) {

        VAR_6 = -VAR_6;

        if (is_fpd_set && vtd_is_qualified_fault(VAR_6)) {

            VTD_DPRINTF(FLOG, "fault processing is disabled for DMA requests "

                        "through this context-VAR_5 (with FPD Set)");

        } else {

            vtd_report_dmar_fault(VAR_0, source_id, VAR_3, VAR_6, VAR_4);

        }

        return;

    }



    VAR_6 = vtd_gpa_to_slpte(&ce, VAR_3, VAR_4, &slpte, &level,

                              &reads, &writes);

    if (VAR_6) {

        VAR_6 = -VAR_6;

        if (is_fpd_set && vtd_is_qualified_fault(VAR_6)) {

            VTD_DPRINTF(FLOG, "fault processing is disabled for DMA requests "

                        "through this context-VAR_5 (with FPD Set)");

        } else {

            vtd_report_dmar_fault(VAR_0, source_id, VAR_3, VAR_6, VAR_4);

        }

        return;

    }



    VAR_5->iova = VAR_3 & VTD_PAGE_MASK_4K;

    VAR_5->translated_addr = vtd_get_slpte_addr(slpte) & VTD_PAGE_MASK_4K;

    VAR_5->addr_mask = ~VTD_PAGE_MASK_4K;

    VAR_5->perm = (writes ? 2 : 0) + (reads ? 1 : 0);

}

static void FUNC_0(IntelIOMMUState *VAR_0, uint8_t VAR_1,
uint8_t VAR_2, hwaddr VAR_3, bool VAR_4,
IOMMUTLBEntry *VAR_5)
{ VTDContextEntry ce; uint64_t slpte; uint32_t level; uint16_t source_id = vtd_make_source_id(VAR_1, VAR_2); int VAR_6; bool is_fpd_set = false; bool reads = true; bool writes = true; if (vtd_is_interrupt_addr(VAR_3)) { if (VAR_4) { VTD_DPRINTF(MMU, "write request to interrupt address "
"gpa 0x%"PRIx64, VAR_3); VAR_5->iova = VAR_3 & VTD_PAGE_MASK_4K; VAR_5->translated_addr = VAR_3 & VTD_PAGE_MASK_4K; VAR_5->addr_mask = ~VTD_PAGE_MASK_4K; VAR_5->perm = IOMMU_WO; return; } else { VTD_DPRINTF(GENERAL, "error: read request from interrupt address "
"gpa 0x%"PRIx64, VAR_3); vtd_report_dmar_fault(VAR_0, source_id, VAR_3, VTD_FR_READ, VAR_4); return; } } VAR_6 = vtd_dev_to_context_entry(VAR_0, VAR_1, VAR_2, &ce); is_fpd_set = ce.lo & VTD_CONTEXT_ENTRY_FPD; if (VAR_6) { VAR_6 = -VAR_6; if (is_fpd_set && vtd_is_qualified_fault(VAR_6)) { VTD_DPRINTF(FLOG, "fault processing is disabled for DMA requests "
"through this context-VAR_5 (with FPD Set)"); } else { vtd_report_dmar_fault(VAR_0, source_id, VAR_3, VAR_6, VAR_4); } return; } VAR_6 = vtd_gpa_to_slpte(&ce, VAR_3, VAR_4, &slpte, &level,
&reads, &writes); if (VAR_6) { VAR_6 = -VAR_6; if (is_fpd_set && vtd_is_qualified_fault(VAR_6)) { VTD_DPRINTF(FLOG, "fault processing is disabled for DMA requests "
"through this context-VAR_5 (with FPD Set)"); } else { vtd_report_dmar_fault(VAR_0, source_id, VAR_3, VAR_6, VAR_4); } return; } VAR_5->iova = VAR_3 & VTD_PAGE_MASK_4K; VAR_5->translated_addr = vtd_get_slpte_addr(slpte) & VTD_PAGE_MASK_4K; VAR_5->addr_mask = ~VTD_PAGE_MASK_4K; VAR_5->perm = (writes ? 2 : 0) + (reads ? 1 : 0); }