summaryrefslogtreecommitdiff
path: root/drivers/dsp/bridge/wmd/mmu_fault.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dsp/bridge/wmd/mmu_fault.c')
-rw-r--r--drivers/dsp/bridge/wmd/mmu_fault.c172
1 files changed, 172 insertions, 0 deletions
diff --git a/drivers/dsp/bridge/wmd/mmu_fault.c b/drivers/dsp/bridge/wmd/mmu_fault.c
new file mode 100644
index 000000000000..5585cdb4c8ce
--- /dev/null
+++ b/drivers/dsp/bridge/wmd/mmu_fault.c
@@ -0,0 +1,172 @@
+/*
+ * mmu_fault.c
+ *
+ * DSP-BIOS Bridge driver support functions for TI OMAP processors.
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ * ======== mmu_fault.c ========
+ * Description:
+ * Implements DSP MMU fault handling functions.
+ *
+ *! Revision History:
+ *! ================
+ *! 26-Dec-2004 hn: Support for IVA MMU exception.
+ *! 06-Mar-2003 sb: Print MMU fault address. Cosmetic changes.
+ *! 16-Feb-2003 vp: Fixed warning in MMU_FaultIsr
+ *! 05-Jan-2004 vp: Updated support for 24xx silicon
+ *! 19-Feb-2003 vp: Code review updates.
+ *! - Cosmetic changes.
+ *! 18-Oct-2002 sb: Ported to Linux platform.
+ *! 10-Sep-2001 kc: created.
+ */
+
+/* ----------------------------------- DSP/BIOS Bridge */
+#include <dspbridge/std.h>
+#include <dspbridge/dbdefs.h>
+#include <dspbridge/errbase.h>
+
+/* ----------------------------------- Trace & Debug */
+#include <dspbridge/host_os.h>
+#include <dspbridge/dbc.h>
+#include <dspbridge/dbg.h>
+
+/* ----------------------------------- OS Adaptation Layer */
+#include <dspbridge/dpc.h>
+#include <dspbridge/mem.h>
+#include <dspbridge/drv.h>
+
+/* ----------------------------------- Link Driver */
+#include <dspbridge/wmddeh.h>
+
+/* ------------------------------------ Hardware Abstraction Layer */
+#include <hw_defs.h>
+#include <hw_mmu.h>
+
+/* ----------------------------------- This */
+#include "_deh.h"
+#include <dspbridge/cfg.h>
+#include "_tiomap_mmu.h"
+#include "_tiomap.h"
+#include "mmu_fault.h"
+
+static u32 dmmuEventMask;
+u32 faultAddr;
+
+static bool MMU_CheckIfFault(struct WMD_DEV_CONTEXT *pDevContext);
+
+/*
+ * ======== MMU_FaultDpc ========
+ * Deferred procedure call to handle DSP MMU fault.
+ */
+void MMU_FaultDpc(IN void *pRefData)
+{
+ struct DEH_MGR *hDehMgr = (struct DEH_MGR *)pRefData;
+ struct DEH_MGR *pDehMgr = (struct DEH_MGR *)hDehMgr;
+
+ DBG_Trace(DBG_LEVEL1, "MMU_FaultDpc Enter: 0x%x\n", pRefData);
+
+ if (pDehMgr)
+ WMD_DEH_Notify(hDehMgr, DSP_MMUFAULT, 0L);
+
+ DBG_Trace(DBG_LEVEL1, "MMU_FaultDpc Exit: 0x%x\n", pRefData);
+}
+
+/*
+ * ======== MMU_FaultIsr ========
+ * ISR to be triggered by a DSP MMU fault interrupt.
+ */
+irqreturn_t MMU_FaultIsr(int irq, IN void *pRefData)
+{
+ struct DEH_MGR *pDehMgr = (struct DEH_MGR *)pRefData;
+ struct WMD_DEV_CONTEXT *pDevContext;
+ struct CFG_HOSTRES resources;
+ DSP_STATUS status = DSP_SOK;
+
+
+ DBG_Trace(DBG_LEVEL1, "Entering DEH_DspMmuIsr: 0x%x\n", pRefData);
+ DBC_Require(irq == INT_DSP_MMU_IRQ);
+ DBC_Require(MEM_IsValidHandle(pDehMgr, SIGNATURE));
+
+ if (MEM_IsValidHandle(pDehMgr, SIGNATURE)) {
+
+ pDevContext = (struct WMD_DEV_CONTEXT *)pDehMgr->hWmdContext;
+ status = CFG_GetHostResources(
+ (struct CFG_DEVNODE *)DRV_GetFirstDevExtension(),
+ &resources);
+ if (DSP_FAILED(status))
+ DBG_Trace(DBG_LEVEL7,
+ "**Failed to get Host Resources "
+ "in MMU ISR **\n");
+ if (MMU_CheckIfFault(pDevContext)) {
+ printk(KERN_INFO "***** DSPMMU FAULT ***** IRQStatus "
+ "0x%x\n", dmmuEventMask);
+ printk(KERN_INFO "***** DSPMMU FAULT ***** faultAddr "
+ "0x%x\n", faultAddr);
+ /* Disable the MMU events, else once we clear it will
+ * start to raise INTs again */
+ /*
+ * Schedule a DPC directly. In the future, it may be
+ * necessary to check if DSP MMU fault is intended for
+ * Bridge.
+ */
+ DPC_Schedule(pDehMgr->hMmuFaultDpc);
+ /* Reset errInfo structure before use. */
+ pDehMgr->errInfo.dwErrMask = DSP_MMUFAULT;
+ pDehMgr->errInfo.dwVal1 = faultAddr >> 16;
+ pDehMgr->errInfo.dwVal2 = faultAddr & 0xFFFF;
+ pDehMgr->errInfo.dwVal3 = 0L;
+ /* Disable the MMU events, else once we clear it will
+ * start to raise INTs again */
+ HW_MMU_EventDisable(resources.dwDmmuBase,
+ HW_MMU_TRANSLATION_FAULT);
+ } else {
+ DBG_Trace(DBG_LEVEL7,
+ "***** MMU FAULT ***** faultcode 0x%x\n",
+ dmmuEventMask);
+ HW_MMU_EventDisable(resources.dwDmmuBase,
+ HW_MMU_ALL_INTERRUPTS);
+ }
+ }
+ return IRQ_HANDLED;
+}
+
+
+/*
+ * ======== MMU_CheckIfFault ========
+ * Check to see if MMU Fault is valid TLB miss from DSP
+ * Note: This function is called from an ISR
+ */
+static bool MMU_CheckIfFault(struct WMD_DEV_CONTEXT *pDevContext)
+{
+
+
+ bool retVal = false;
+ DSP_STATUS status = DSP_SOK;
+ HW_STATUS hwStatus;
+ struct CFG_HOSTRES resources;
+ status = CFG_GetHostResources(
+ (struct CFG_DEVNODE *)DRV_GetFirstDevExtension(), &resources);
+ if (DSP_FAILED(status))
+ DBG_Trace(DBG_LEVEL7, "**Failed to get Host Resources in "
+ "MMU_CheckIfFault **\n");
+
+ hwStatus = HW_MMU_EventStatus(resources.dwDmmuBase, &dmmuEventMask);
+ if (dmmuEventMask == HW_MMU_TRANSLATION_FAULT) {
+ HW_MMU_FaultAddrRead(resources.dwDmmuBase, &faultAddr);
+ DBG_Trace(DBG_LEVEL1, "WMD_DEH_Notify: DSP_MMUFAULT, fault "
+ "address = 0x%x\n", faultAddr);
+ retVal = true;
+ }
+ return retVal;
+}