lkml.org 
[lkml]   [2010]   [Jun]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5/9] dspbridge: add mmufault support
    Date
    With changes for iommu migration mmu fault report and dsp track
    dump is broken, this patch fixes that.

    Signed-off-by: Fernando Guzman Lugo <x0095840@ti.com>
    ---
    drivers/dsp/bridge/core/mmu_fault.c | 93 ++++++---------------------------
    drivers/dsp/bridge/core/mmu_fault.h | 5 +-
    drivers/dsp/bridge/core/tiomap3430.c | 2 +
    drivers/dsp/bridge/core/ue_deh.c | 31 +++++-------
    4 files changed, 34 insertions(+), 97 deletions(-)

    diff --git a/drivers/dsp/bridge/core/mmu_fault.c b/drivers/dsp/bridge/core/mmu_fault.c
    index 5c0124f..d991c6a 100644
    --- a/drivers/dsp/bridge/core/mmu_fault.c
    +++ b/drivers/dsp/bridge/core/mmu_fault.c
    @@ -23,9 +23,12 @@
    /* ----------------------------------- Trace & Debug */
    #include <dspbridge/host_os.h>
    #include <dspbridge/dbc.h>
    +#include <plat/iommu.h>

    /* ----------------------------------- OS Adaptation Layer */
    #include <dspbridge/drv.h>
    +#include <dspbridge/dev.h>
    +

    /* ----------------------------------- Link Driver */
    #include <dspbridge/dspdeh.h>
    @@ -40,11 +43,6 @@
    #include "_tiomap.h"
    #include "mmu_fault.h"

    -static u32 dmmu_event_mask;
    -u32 fault_addr;
    -
    -static bool mmu_check_if_fault(struct bridge_dev_context *dev_context);
    -
    /*
    * ======== mmu_fault_dpc ========
    * Deferred procedure call to handle DSP MMU fault.
    @@ -62,78 +60,21 @@ void mmu_fault_dpc(IN unsigned long pRefData)
    * ======== mmu_fault_isr ========
    * ISR to be triggered by a DSP MMU fault interrupt.
    */
    -irqreturn_t mmu_fault_isr(int irq, IN void *pRefData)
    -{
    - struct deh_mgr *deh_mgr_obj = (struct deh_mgr *)pRefData;
    - struct bridge_dev_context *dev_context;
    - struct cfg_hostres *resources;
    -
    - DBC_REQUIRE(irq == INT_DSP_MMU_IRQ);
    - DBC_REQUIRE(deh_mgr_obj);
    -
    - if (deh_mgr_obj) {
    -
    - dev_context =
    - (struct bridge_dev_context *)deh_mgr_obj->hbridge_context;
    -
    - resources = dev_context->resources;
    -
    - if (!resources) {
    - dev_dbg(bridge, "%s: Failed to get Host Resources\n",
    - __func__);
    - return IRQ_HANDLED;
    - }
    - if (mmu_check_if_fault(dev_context)) {
    - printk(KERN_INFO "***** DSPMMU FAULT ***** IRQStatus "
    - "0x%x\n", dmmu_event_mask);
    - printk(KERN_INFO "***** DSPMMU FAULT ***** fault_addr "
    - "0x%x\n", fault_addr);
    - /*
    - * Schedule a DPC directly. In the future, it may be
    - * necessary to check if DSP MMU fault is intended for
    - * Bridge.
    - */
    - tasklet_schedule(&deh_mgr_obj->dpc_tasklet);
    -
    - /* Reset err_info structure before use. */
    - deh_mgr_obj->err_info.dw_err_mask = DSP_MMUFAULT;
    - deh_mgr_obj->err_info.dw_val1 = fault_addr >> 16;
    - deh_mgr_obj->err_info.dw_val2 = fault_addr & 0xFFFF;
    - deh_mgr_obj->err_info.dw_val3 = 0L;
    - /* Disable the MMU events, else once we clear it will
    - * start to raise INTs again */
    - hw_mmu_event_disable(resources->dw_dmmu_base,
    - HW_MMU_TRANSLATION_FAULT);
    - } else {
    - hw_mmu_event_disable(resources->dw_dmmu_base,
    - HW_MMU_ALL_INTERRUPTS);
    - }
    - }
    - return IRQ_HANDLED;
    -}
    +int mmu_fault_isr(struct iommu *mmu)

    -/*
    - * ======== mmu_check_if_fault ========
    - * Check to see if MMU Fault is valid TLB miss from DSP
    - * Note: This function is called from an ISR
    - */
    -static bool mmu_check_if_fault(struct bridge_dev_context *dev_context)
    {
    + struct deh_mgr *dm;
    + u32 da;
    +
    + dev_get_deh_mgr(dev_get_first(), &dm);
    +
    + if (!dm)
    + return -EPERM;
    +
    + da = iommu_read_reg(mmu, MMU_FAULT_AD);
    + iommu_write_reg(mmu, 0, MMU_IRQENABLE);
    + dm->err_info.dw_val1 = da;
    + tasklet_schedule(&dm->dpc_tasklet);

    - bool ret = false;
    - hw_status hw_status_obj;
    - struct cfg_hostres *resources = dev_context->resources;
    -
    - if (!resources) {
    - dev_dbg(bridge, "%s: Failed to get Host Resources in\n",
    - __func__);
    - return ret;
    - }
    - hw_status_obj =
    - hw_mmu_event_status(resources->dw_dmmu_base, &dmmu_event_mask);
    - if (dmmu_event_mask == HW_MMU_TRANSLATION_FAULT) {
    - hw_mmu_fault_addr_read(resources->dw_dmmu_base, &fault_addr);
    - ret = true;
    - }
    - return ret;
    + return 0;
    }
    diff --git a/drivers/dsp/bridge/core/mmu_fault.h b/drivers/dsp/bridge/core/mmu_fault.h
    index 74db489..df3fba6 100644
    --- a/drivers/dsp/bridge/core/mmu_fault.h
    +++ b/drivers/dsp/bridge/core/mmu_fault.h
    @@ -19,8 +19,6 @@
    #ifndef MMU_FAULT_
    #define MMU_FAULT_

    -extern u32 fault_addr;
    -
    /*
    * ======== mmu_fault_dpc ========
    * Deferred procedure call to handle DSP MMU fault.
    @@ -31,6 +29,7 @@ void mmu_fault_dpc(IN unsigned long pRefData);
    * ======== mmu_fault_isr ========
    * ISR to be triggered by a DSP MMU fault interrupt.
    */
    -irqreturn_t mmu_fault_isr(int irq, IN void *pRefData);
    +int mmu_fault_isr(struct iommu *mmu);
    +

    #endif /* MMU_FAULT_ */
    diff --git a/drivers/dsp/bridge/core/tiomap3430.c b/drivers/dsp/bridge/core/tiomap3430.c
    index 96cceea..89867e7 100644
    --- a/drivers/dsp/bridge/core/tiomap3430.c
    +++ b/drivers/dsp/bridge/core/tiomap3430.c
    @@ -57,6 +57,7 @@
    #include "_tiomap.h"
    #include "_tiomap_pwr.h"
    #include "tiomap_io.h"
    +#include "mmu_fault.h"

    /* Offset in shared mem to write to in order to synchronize start with DSP */
    #define SHMSYNCOFFSET 4 /* GPP byte offset */
    @@ -382,6 +383,7 @@ static int bridge_brd_start(struct bridge_dev_context *hDevContext,
    goto end;
    }
    dev_context->dsp_mmu = mmu;
    + mmu->isr = mmu_fault_isr;
    sm_sg = dev_context->sh_s;

    sm_sg->seg0_da = iommu_kmap(mmu, sm_sg->seg0_da, sm_sg->seg0_pa,
    diff --git a/drivers/dsp/bridge/core/ue_deh.c b/drivers/dsp/bridge/core/ue_deh.c
    index ce13e6c..a03d172 100644
    --- a/drivers/dsp/bridge/core/ue_deh.c
    +++ b/drivers/dsp/bridge/core/ue_deh.c
    @@ -18,6 +18,7 @@

    /* ----------------------------------- Host OS */
    #include <dspbridge/host_os.h>
    +#include <plat/iommu.h>

    /* ----------------------------------- DSP/BIOS Bridge */
    #include <dspbridge/std.h>
    @@ -51,12 +52,6 @@
    #include "_tiomap_pwr.h"
    #include <dspbridge/io_sm.h>

    -
    -static struct hw_mmu_map_attrs_t map_attrs = { HW_LITTLE_ENDIAN,
    - HW_ELEM_SIZE16BIT,
    - HW_MMU_CPUES
    -};
    -
    static void *dummy_va_addr;

    int bridge_deh_create(struct deh_mgr **ret_deh_mgr,
    @@ -154,10 +149,10 @@ int bridge_deh_register_notify(struct deh_mgr *deh_mgr, u32 event_mask,
    void bridge_deh_notify(struct deh_mgr *deh_mgr, u32 ulEventMask, u32 dwErrInfo)
    {
    struct bridge_dev_context *dev_context;
    - int status = 0;
    u32 hw_mmu_max_tlb_count = 31;
    struct cfg_hostres *resources;
    - hw_status hw_status_obj;
    + u32 fault_addr, tmp;
    + struct iotlb_entry e;

    if (!deh_mgr)
    return;
    @@ -181,6 +176,9 @@ void bridge_deh_notify(struct deh_mgr *deh_mgr, u32 ulEventMask, u32 dwErrInfo)
    break;
    case DSP_MMUFAULT:
    /* MMU fault routine should have set err info structure. */
    + fault_addr = iommu_read_reg(dev_context->dsp_mmu,
    + MMU_FAULT_AD);
    +
    deh_mgr->err_info.dw_err_mask = DSP_MMUFAULT;
    dev_err(bridge, "%s: %s, err_info = 0x%x\n",
    __func__, "DSP_MMUFAULT", dwErrInfo);
    @@ -206,21 +204,18 @@ void bridge_deh_notify(struct deh_mgr *deh_mgr, u32 ulEventMask, u32 dwErrInfo)
    dev_context->num_tlb_entries =
    dev_context->fixed_tlb_entries;
    }
    - if (DSP_SUCCEEDED(status)) {
    - hw_status_obj =
    - hw_mmu_tlb_add(resources->dw_dmmu_base,
    - virt_to_phys(dummy_va_addr), fault_addr,
    - HW_PAGE_SIZE4KB, 1,
    - &map_attrs, HW_SET, HW_SET);
    - }
    + dsp_iotlb_init(&e, fault_addr & PAGE_MASK,
    + virt_to_phys(dummy_va_addr), IOVMF_PGSZ_4K);
    + load_iotlb_entry(dev_context->dsp_mmu, &e);
    +

    dsp_clk_enable(DSP_CLK_GPT8);

    dsp_gpt_wait_overflow(DSP_CLK_GPT8, 0xfffffffe);

    - /* Clear MMU interrupt */
    - hw_mmu_event_ack(resources->dw_dmmu_base,
    - HW_MMU_TRANSLATION_FAULT);
    + tmp = iommu_read_reg(dev_context->dsp_mmu, MMU_IRQSTATUS);
    + iommu_write_reg(dev_context->dsp_mmu, tmp, MMU_IRQSTATUS);
    +
    dump_dsp_stack(deh_mgr->hbridge_context);
    dsp_clk_disable(DSP_CLK_GPT8);
    break;
    --
    1.6.3.3


    \
     
     \ /
      Last update: 2010-07-01 02:17    [W:4.695 / U:0.028 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site