Commit a0fcac9c authored by Laurent Dufour's avatar Laurent Dufour Committed by Alexander Graf
Browse files

target-ppc: Introduce hypervisor call H_GET_TCE



This patch introduces the hypervisor call H_GET_TCE which is basically the
reverse of H_PUT_TCE, as defined in the Power Architecture Platform
Requirements (PAPR).

The hcall H_GET_TCE is required by the kdump kernel which is calling it to
retrieve the TCE set up by the panicing kernel.

Signed-off-by: default avatarLaurent Dufour <ldufour@linux.vnet.ibm.com>
Signed-off-by: default avatarAlexander Graf <agraf@suse.de>
parent c1385933
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
@@ -243,6 +243,42 @@ static target_ulong h_put_tce(PowerPCCPU *cpu, sPAPREnvironment *spapr,
    return ret;
}

static target_ulong get_tce_emu(sPAPRTCETable *tcet, target_ulong ioba,
                                target_ulong *tce)
{
    if (ioba >= tcet->window_size) {
        hcall_dprintf("spapr_iommu_get_tce on out-of-bounds IOBA 0x"
                      TARGET_FMT_lx "\n", ioba);
        return H_PARAMETER;
    }

    *tce = tcet->table[ioba >> SPAPR_TCE_PAGE_SHIFT];

    return H_SUCCESS;
}

static target_ulong h_get_tce(PowerPCCPU *cpu, sPAPREnvironment *spapr,
                              target_ulong opcode, target_ulong *args)
{
    target_ulong liobn = args[0];
    target_ulong ioba = args[1];
    target_ulong tce = 0;
    target_ulong ret = H_PARAMETER;
    sPAPRTCETable *tcet = spapr_tce_find_by_liobn(liobn);

    ioba &= ~(SPAPR_TCE_PAGE_SIZE - 1);

    if (tcet) {
        ret = get_tce_emu(tcet, ioba, &tce);
        if (!ret) {
            args[0] = tce;
        }
    }
    trace_spapr_iommu_get(liobn, ioba, ret, tce);

    return ret;
}

int spapr_dma_dt(void *fdt, int node_off, const char *propname,
                 uint32_t liobn, uint64_t window, uint32_t size)
{
@@ -295,6 +331,7 @@ static void spapr_tce_table_class_init(ObjectClass *klass, void *data)

    /* hcall-tce */
    spapr_register_hypercall(H_PUT_TCE, h_put_tce);
    spapr_register_hypercall(H_GET_TCE, h_get_tce);
}

static TypeInfo spapr_tce_table_info = {
+1 −0
Original line number Diff line number Diff line
@@ -1136,6 +1136,7 @@ xics_ics_eoi(int nr) "ics_eoi: irq %#x"

# hw/ppc/spapr_iommu.c
spapr_iommu_put(uint64_t liobn, uint64_t ioba, uint64_t tce, uint64_t ret) "liobn=%"PRIx64" ioba=0x%"PRIx64" tce=0x%"PRIx64" ret=%"PRId64
spapr_iommu_get(uint64_t liobn, uint64_t ioba, uint64_t ret, uint64_t tce) "liobn=%"PRIx64" ioba=0x%"PRIx64" ret=%"PRId64" tce=0x%"PRIx64
spapr_iommu_xlate(uint64_t liobn, uint64_t ioba, uint64_t tce, unsigned perm, unsigned pgsize) "liobn=%"PRIx64" 0x%"PRIx64" -> 0x%"PRIx64" perm=%u mask=%x"
spapr_iommu_new_table(uint64_t liobn, void *tcet, void *table, int fd) "liobn=%"PRIx64" tcet=%p table=%p fd=%d"