QNX IPC: Add IPU2 MMU Fault Handling
authorAngela Stegmaier <angelabaker@ti.com>
Tue, 7 May 2013 09:02:45 +0000 (04:02 -0500)
committerChris Ring <cring@ti.com>
Thu, 9 May 2013 17:47:36 +0000 (10:47 -0700)
There is no default interrupt mapped to the IPU2 MMU
for Vayu. This patch programs the interrupt crossbar
for the IPU2 MMU interrupt to MPU interrupt 142.

Also, this patch enables receiving the interrupt in the
case of an MMU fault event in order to print the required
information, as well as schedule recovery.

Signed-off-by: Angela Stegmaier <angelabaker@ti.com>
qnx/src/ipc3x_dev/ti/syslink/build/Qnx/resmgr/syslink_main.c
qnx/src/ipc3x_dev/ti/syslink/family/common/vayu/vayuipu/VAYUIpuHal.c
qnx/src/ipc3x_dev/ti/syslink/family/common/vayu/vayuipu/VAYUIpuPhyShmem.c
qnx/src/ipc3x_dev/ti/syslink/family/common/vayu/vayuipu/vayucore0/VAYUIpuCore0Proc.c
qnx/src/ipc3x_dev/ti/syslink/family/vayu/vayuipu/VAYUIpuHalMmu.c
qnx/src/ipc3x_dev/ti/syslink/inc/knl/VAYUIpuHal.h
qnx/src/ipc3x_dev/ti/syslink/inc/knl/VAYUIpuPhyShmem.h

index 502b294f29e5a24ea4e5ab004dbed8e260b4aac3..3512cc6e11d080e3c94cfad161738e4527573ead 100644 (file)
@@ -302,55 +302,20 @@ syslink_ocb_free (IOFUNC_OCB_T * i_ocb)
     }
 }
 
-/* Initialize the syslink device */
-int init_syslink_device(syslink_dev_t *dev)
+int init_syslink_trace_device(syslink_dev_t *dev)
 {
-    iofunc_attr_t *  attr;
-    syslink_attr_t * trace_attr;
     resmgr_attr_t    resmgr_attr;
     int              i;
+    syslink_attr_t * trace_attr;
     char             trace_name[_POSIX_PATH_MAX];
     int              status = 0;
     u32              da = 0, pa = 0;
     u32              len;
 
-    pthread_mutex_init(&dev->lock, NULL);
-
     memset(&resmgr_attr, 0, sizeof resmgr_attr);
     resmgr_attr.nparts_max = 10;
     resmgr_attr.msg_max_size = 2048;
 
-    memset(&dev->syslink.mattr, 0, sizeof(iofunc_mount_t));
-    dev->syslink.mattr.flags = ST_NOSUID | ST_NOEXEC;
-    dev->syslink.mattr.conf = IOFUNC_PC_CHOWN_RESTRICTED |
-                              IOFUNC_PC_NO_TRUNC |
-                              IOFUNC_PC_SYNC_IO;
-    dev->syslink.mattr.funcs = &dev->syslink.mfuncs;
-
-    memset(&dev->syslink.mfuncs, 0, sizeof(iofunc_funcs_t));
-    dev->syslink.mfuncs.nfuncs = _IOFUNC_NFUNCS;
-
-    iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &dev->syslink.cfuncs,
-                    _RESMGR_IO_NFUNCS, &dev->syslink.iofuncs);
-
-    iofunc_attr_init(attr = &dev->syslink.cattr, S_IFCHR | 0777, NULL, NULL);
-
-    dev->syslink.mfuncs.ocb_calloc = syslink_ocb_calloc;
-    dev->syslink.mfuncs.ocb_free = syslink_ocb_free;
-    dev->syslink.iofuncs.devctl = syslink_devctl;
-    dev->syslink.iofuncs.unblock = syslink_unblock;
-
-    attr->mount = &dev->syslink.mattr;
-    iofunc_time_update(attr);
-
-    if (-1 == (dev->syslink.resmgr_id =
-        resmgr_attach(dev->dpp, &resmgr_attr,
-                      IPC_DEVICE_PATH, _FTYPE_ANY, 0,
-                      &dev->syslink.cfuncs,
-                      &dev->syslink.iofuncs, attr))) {
-        return(-1);
-    }
-
     for (i = 0; i < syslink_num_cores; i++) {
         iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &dev->syslink.cfuncs_trace[i],
                          _RESMGR_IO_NFUNCS, &dev->syslink.iofuncs_trace[i]);
@@ -377,6 +342,10 @@ int init_syslink_device(syslink_dev_t *dev)
                                                 (Ptr) da,
                                                 ProcMgr_AddrType_SlaveVirt);
             }
+            else {
+                GT_setFailureReason(curTrace, GT_4CLASS, "init_syslink_trace_device",
+                                    status, "not performing ProcMgr_translate");
+            }
             /* map length aligned to page size */
             proc_traces[i].va =
                     mmap_device_io (((len + 0x1000 - 1) / 0x1000) * 0x1000, pa);
@@ -385,11 +354,16 @@ int init_syslink_device(syslink_dev_t *dev)
             proc_traces[i].ridx = (uint32_t *)((uint32_t)proc_traces[i].widx + \
                                                sizeof(uint32_t));
             if (proc_traces[i].va == MAP_DEVICE_FAILED) {
+                GT_setFailureReason(curTrace, GT_4CLASS, "init_syslink_trace_device",
+                                    status, "mmap_device_io failed");
+                GT_1trace(curTrace, GT_4CLASS, "errno %d", errno);
                 proc_traces[i].va = NULL;
             }
             proc_traces[i].firstRead = TRUE;
         }
         else {
+            GT_setFailureReason(curTrace, GT_4CLASS, "init_syslink_trace_device",
+                                status, "RscTable_getInfo failed");
             proc_traces[i].va = NULL;
         }
         if (-1 == (dev->syslink.resmgr_id_trace[i] =
@@ -398,25 +372,19 @@ int init_syslink_device(syslink_dev_t *dev)
                                      &dev->syslink.cfuncs_trace[i],
                                      &dev->syslink.iofuncs_trace[i],
                                      &trace_attr->attr))) {
+            GT_setFailureReason(curTrace, GT_4CLASS, "init_syslink_trace_device",
+                                status, "resmgr_attach failed");
             return(-1);
         }
     }
 
-    return(0);
 }
 
-/* De-initialize the syslink device */
-int deinit_syslink_device(syslink_dev_t *dev)
+int deinit_syslink_trace_device(syslink_dev_t *dev)
 {
     int status = EOK;
     int i = 0;
 
-    status = resmgr_detach(dev->dpp, dev->syslink.resmgr_id, 0);
-    if (status < 0) {
-        Osal_printf("syslink: resmgr_detach failed %d", errno);
-        status = errno;
-    }
-
     for (i = 0; i < syslink_num_cores; i++) {
         status = resmgr_detach(dev->dpp, dev->syslink.resmgr_id_trace[i], 0);
         if (status < 0) {
@@ -428,6 +396,78 @@ int deinit_syslink_device(syslink_dev_t *dev)
                    ((proc_traces[i].len + 8 + 0x1000 - 1) / 0x1000) * 0x1000);
         proc_traces[i].va = NULL;
     }
+}
+
+/* Initialize the syslink device */
+int init_syslink_device(syslink_dev_t *dev)
+{
+    iofunc_attr_t *  attr;
+    syslink_attr_t * trace_attr;
+    resmgr_attr_t    resmgr_attr;
+    int              i;
+    char             trace_name[_POSIX_PATH_MAX];
+    int              status = 0;
+    u32              da = 0, pa = 0;
+    u32              len;
+
+    pthread_mutex_init(&dev->lock, NULL);
+
+    memset(&resmgr_attr, 0, sizeof resmgr_attr);
+    resmgr_attr.nparts_max = 10;
+    resmgr_attr.msg_max_size = 2048;
+
+    memset(&dev->syslink.mattr, 0, sizeof(iofunc_mount_t));
+    dev->syslink.mattr.flags = ST_NOSUID | ST_NOEXEC;
+    dev->syslink.mattr.conf = IOFUNC_PC_CHOWN_RESTRICTED |
+                              IOFUNC_PC_NO_TRUNC |
+                              IOFUNC_PC_SYNC_IO;
+    dev->syslink.mattr.funcs = &dev->syslink.mfuncs;
+
+    memset(&dev->syslink.mfuncs, 0, sizeof(iofunc_funcs_t));
+    dev->syslink.mfuncs.nfuncs = _IOFUNC_NFUNCS;
+
+    iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &dev->syslink.cfuncs,
+                    _RESMGR_IO_NFUNCS, &dev->syslink.iofuncs);
+
+    iofunc_attr_init(attr = &dev->syslink.cattr, S_IFCHR | 0777, NULL, NULL);
+
+    dev->syslink.mfuncs.ocb_calloc = syslink_ocb_calloc;
+    dev->syslink.mfuncs.ocb_free = syslink_ocb_free;
+    dev->syslink.iofuncs.devctl = syslink_devctl;
+    dev->syslink.iofuncs.unblock = syslink_unblock;
+
+    attr->mount = &dev->syslink.mattr;
+    iofunc_time_update(attr);
+
+    if (-1 == (dev->syslink.resmgr_id =
+        resmgr_attach(dev->dpp, &resmgr_attr,
+                      IPC_DEVICE_PATH, _FTYPE_ANY, 0,
+                      &dev->syslink.cfuncs,
+                      &dev->syslink.iofuncs, attr))) {
+        return(-1);
+    }
+
+    status = init_syslink_trace_device(dev);
+    if (status < 0) {
+        return status;
+    }
+
+    return(0);
+}
+
+/* De-initialize the syslink device */
+int deinit_syslink_device(syslink_dev_t *dev)
+{
+    int status = EOK;
+    int i = 0;
+
+    status = resmgr_detach(dev->dpp, dev->syslink.resmgr_id, 0);
+    if (status < 0) {
+        Osal_printf("syslink: resmgr_detach failed %d", errno);
+        status = errno;
+    }
+
+    status = deinit_syslink_trace_device(dev);
 
     return(status);
 }
@@ -464,6 +504,8 @@ static void ipc_recover(Ptr args)
 
     deinit_ipc(dev, TRUE);
     init_ipc(dev, syslink_firmware, TRUE);
+    deinit_syslink_trace_device(dev);
+    init_syslink_trace_device(dev);
 }
 
 Int syslink_error_cb (UInt16 procId, ProcMgr_Handle handle,
index 5ba22837848c18aa54aed0d7d56ff9f1ea6344c3..2b6199bf4491900203263d05f656f3b6d0c0a39a 100644 (file)
@@ -92,6 +92,7 @@ VAYUIPU_halInit (Ptr * halObj, Ptr params)
 {
     Int                 status    = PROCESSOR_SUCCESS;
     VAYUIPU_HalObject * halObject = NULL;
+    VAYUIPU_HalParams * halParams = NULL;
 
     GT_2trace (curTrace, GT_ENTER, "VAYUIPU_halInit", halObj, params);
 
@@ -99,7 +100,7 @@ VAYUIPU_halInit (Ptr * halObj, Ptr params)
 
     halObject = (VAYUIPU_HalObject *) halObj ;
 
-    (Void) params ; /* Not used. */
+    halParams = (VAYUIPU_HalParams *)params ;
 
     *halObj = Memory_calloc (NULL, sizeof (VAYUIPU_HalObject), 0, NULL);
     if (halObject == NULL) {
@@ -112,6 +113,9 @@ VAYUIPU_halInit (Ptr * halObj, Ptr params)
                              "Memory allocation failed for HAL object!");
     }
     else {
+        halObject = (VAYUIPU_HalObject *) *halObj ;
+        halObject->procId = halParams->procId;
+
         status = VAYUIPU_phyShmemInit (*halObj);
 #if !defined(SYSLINK_BUILD_OPTIMIZE)
         if (status < 0) {
index f5a1b1aa03a13733110cb283073fc01d07a0c734..0d23ed7a416fbbeedd7254d4e9016a5f10816043 100644 (file)
@@ -155,6 +155,22 @@ VAYUIPU_phyShmemInit (Ptr halObj)
         halObject->mmuBase = mapInfo.dst;
     }
 
+    mapInfo.src      = CTRL_MODULE_BASE;
+    mapInfo.size     = CTRL_MODULE_SIZE;
+    mapInfo.isCached = FALSE;
+    status = Memory_map (&mapInfo);
+    if (status < 0) {
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "VAYUIPU_phyShmemInit",
+                             status,
+                             "Failure in Memory_map for Ctrl Module base registers");
+        halObject->ctrlModBase = 0;
+    }
+    else {
+        halObject->ctrlModBase = mapInfo.dst;
+    }
+
     GT_1trace (curTrace, GT_LEAVE, "VAYUIPU_phyShmemInit", status);
 
     /*! @retval PROCESSOR_SUCCESS Operation successful */
@@ -183,6 +199,21 @@ VAYUIPU_phyShmemExit (Ptr halObj)
 
     halObject = (VAYUIPU_HalObject *) halObj;
 
+    unmapInfo.addr = halObject->ctrlModBase;
+    unmapInfo.size = CTRL_MODULE_SIZE;
+    unmapInfo.isCached = FALSE;
+    if (unmapInfo.addr != 0) {
+        status = Memory_unmap (&unmapInfo);
+        if (status < 0) {
+            GT_setFailureReason (curTrace,
+                              GT_4CLASS,
+                              "VAYUIPU_phyShmemExit",
+                              status,
+                              "Failure in Memory_Unmap for Ctrl Module base registers");
+        }
+        halObject->ctrlModBase = 0 ;
+    }
+
     unmapInfo.addr = halObject->mmuBase;
     unmapInfo.size = MMU_SIZE;
     unmapInfo.isCached = FALSE;
index 98a9d57e2fa9a69d4cc510b450b24c9873b92176..1e9b7d06f5f886fd5f5cbc2a3d98b8cf6da0074b 100644 (file)
@@ -496,6 +496,7 @@ VAYUIPUCORE0PROC_create (      UInt16                procId,
                 else {
                     handle->procId = procId;
                     object = (VAYUIPUCORE0PROC_Object *) handle->object;
+                    object->procHandle = (Processor_Handle)handle;
                     object->halObject = NULL;
                     /* Copy params into instance object. */
                     Memory_copy (&(object->params),
@@ -504,7 +505,7 @@ VAYUIPUCORE0PROC_create (      UInt16                procId,
 
                     /* Set the handle in the state object. */
                     VAYUIPUCORE0PROC_state.procHandles [procId] =
-                                                 (VAYUIPUCORE0PROC_Handle) handle;
+                                                 (VAYUIPUCORE0PROC_Handle) object;
                     /* Initialize the list of listeners */
                     List_Params_init(&listParams);
                     handle->registeredNotifiers = List_create(&listParams);
@@ -838,6 +839,7 @@ VAYUIPUCORE0PROC_attach(
     Char                        configProp[PARAMS_MAX_NAMELENGTH];
     UInt32                      numCarveouts = 0;
     VAYUIPU_HalMmuCtrlArgs_Enable mmuEnableArgs;
+    VAYUIPU_HalParams           halParams;
 
     GT_2trace(curTrace, GT_ENTER,
               "VAYUIPUCORE0PROC_attach", handle, params);
@@ -994,7 +996,8 @@ VAYUIPUCORE0PROC_attach(
             memcpy((Ptr)params->memEntries, (Ptr)object->params.memEntries,
                 sizeof(ProcMgr_AddrInfo) * params->numMemEntries);
 
-            status = VAYUIPU_halInit(&(object->halObject), NULL);
+            halParams.procId = procHandle->procId;
+            status = VAYUIPU_halInit(&(object->halObject), &halParams);
 
 #if !defined(SYSLINK_BUILD_OPTIMIZE)
             if (status < 0) {
index 94758c2f2e5994a4c46e660e915a70611f455716..9f4b9b4534c798631da6ccfd425ee3eb81782ed9 100644 (file)
@@ -86,10 +86,13 @@ extern "C" {
  */
 #define MMU_RAM_DEFAULT         0
 
+#define MPU_INT_OFFSET               32
+
 /*!
- *  @brief  Interrupt Id for IPU MMU faults
+ *  @brief  Interrupt Id for IPU2 MMU faults
  */
-#define MMU_FAULT_INTERRUPT     132
+#define MMU_FAULT_INTERRUPT_IPU2     142
+#define MMU_XBAR_INTERRUPT_IPU2      396
 
 /*!
  *  @brief  CAM register field values
@@ -122,6 +125,32 @@ extern "C" {
 
 #define MMUPAGE_ALIGN(size, psz)  (((size) + psz - 1) & ~(psz -1))
 
+/*!
+ *  @def    CTRL_MODULE_MMR_OFFSET
+ *  @brief  offset in ctrl module to MMR LOCK reg.
+ */
+#define CTRL_MODULE_MMR_OFFSET           0x544
+
+/*!
+ *  @def    CTRL_MODULE_MPU_OFFSET
+ *  @brief  offset in ctrl module to MPU INTs.
+ */
+#define CTRL_MODULE_MPU_OFFSET           0xA4C
+
+/*!
+ *  @def    CTRL_MODULE_INT_BASE
+ *  @brief  interrupt num at offset.
+ */
+#define CTRL_MODULE_INT_BASE             0x8
+
+/*!
+ *  @def    CTRL_MODULE_INT_m_OFFSET
+ *  @brief  interrupt num at offset.
+ */
+#define CTRL_MODULE_INT_m_OFFSET(m)      CTRL_MODULE_MPU_OFFSET + \
+                                         ((((m) - CTRL_MODULE_INT_BASE) / 2) * 4) - \
+                                         (((m) > 131) ? 4 : 0)
+
 /*!
  *  @def    REG32
  *  @brief  Regsiter access method.
@@ -421,11 +450,15 @@ _VAYUIPU_halMmuInt_isr (Ptr arg)
 {
     VAYUIPU_HalObject * halObject = (VAYUIPU_HalObject *)arg;
     VAYUIPUCORE0PROC_Object * procObject = NULL;
+    Int32 status;
 
     GT_1trace (curTrace, GT_ENTER, "_VAYUIPU_halMmuInt_isr", arg);
-    VAYUIPUCORE0PROC_open((VAYUIPUCORE0PROC_Handle *)&procObject, halObject->procId);
-    Processor_setState(procObject->procHandle, ProcMgr_State_Mmu_Fault);
-    VAYUIPUCORE0PROC_close((VAYUIPUCORE0PROC_Handle *)&procObject);
+    status = VAYUIPUCORE0PROC_open((VAYUIPUCORE0PROC_Handle *)&procObject,
+                                     halObject->procId);
+    if (status >= 0) {
+        Processor_setState(procObject->procHandle, ProcMgr_State_Mmu_Fault);
+        VAYUIPUCORE0PROC_close((VAYUIPUCORE0PROC_Handle *)&procObject);
+    }
 
     GT_1trace (curTrace, GT_LEAVE, "_VAYUIPU_halMmuInt_isr", TRUE);
 
@@ -450,6 +483,7 @@ _VAYUIPU_halMmuEnable (VAYUIPU_HalObject * halObject,
     Int                           status    = PROCESSOR_SUCCESS;
     VAYUIPU_HalMmuObject *   mmuObj;
     OsalIsr_Params                isrParams;
+    UInt32 reg = 0;
 
     GT_3trace (curTrace, GT_ENTER, "_VAYUIPU_halMmuEnable",
                halObject, numMemEntries, memTable);
@@ -461,11 +495,26 @@ _VAYUIPU_halMmuEnable (VAYUIPU_HalObject * halObject,
      */
     mmuObj = &(halObject->mmuObj);
 
+    /* Program the MMR lock registers to access the SCM
+     * IRQ crossbar register address range */
+    REG32(halObject->ctrlModBase + CTRL_MODULE_MMR_OFFSET) = 0xF757FDC0;
+
+    /* Program the IntXbar */
+    reg = REG32(halObject->ctrlModBase + CTRL_MODULE_INT_m_OFFSET(MMU_FAULT_INTERRUPT_IPU2));
+    if ((MMU_FAULT_INTERRUPT_IPU2 - CTRL_MODULE_INT_BASE) % 2) {
+        REG32(halObject->ctrlModBase + CTRL_MODULE_INT_m_OFFSET(MMU_FAULT_INTERRUPT_IPU2)) =
+            (reg & 0x0000FFFF) | (MMU_XBAR_INTERRUPT_IPU2 << 16);
+    }
+    else {
+        REG32(halObject->ctrlModBase + CTRL_MODULE_INT_m_OFFSET(MMU_FAULT_INTERRUPT_IPU2)) =
+            (reg & 0xFFFF0000) | (MMU_XBAR_INTERRUPT_IPU2);
+    }
+
     /* Create the ISR to listen for MMU Faults */
     isrParams.sharedInt        = FALSE;
     isrParams.checkAndClearFxn = &_VAYUIPU_halMmuCheckAndClearFunc;
     isrParams.fxnArgs          = halObject;
-    isrParams.intId            = MMU_FAULT_INTERRUPT;
+    isrParams.intId            = MMU_FAULT_INTERRUPT_IPU2 + MPU_INT_OFFSET;
     mmuObj->isrHandle = OsalIsr_create (&_VAYUIPU_halMmuInt_isr,
                                         halObject,
                                         &isrParams);
index 672d4b9f784dfa3d34343fc4c7a5e26e32d35933..b1051a168f00872328f5fec050205a945057819f 100644 (file)
@@ -82,12 +82,22 @@ typedef struct VAYUIPU_HalObject_tag {
     /*!< Virtual base address of the General Control module. */
     UInt32                    mmuBase;
     /*!< Base address of the MMU module. */
+    UInt32                    ctrlModBase;
+    /*!< Base address of the control module. */
     UInt32                    procId;
     /*!< Processor ID. */
     VAYUIPU_HalMmuObject mmuObj;
     /*!< MMU abstraction. */
 } VAYUIPU_HalObject;
 
+/*!
+ *  @brief  Hardware Abstraction object.
+ */
+typedef struct VAYUIPU_HalParams_tag {
+    UInt16                    procId;
+    /*!< ProcId of the IPU being created. */
+} VAYUIPU_HalParams;
+
 
 /* =============================================================================
  *  APIs
index b6c0d3cfb26d0ff287b2bc3712f537928b51547c..893ff85086160f9989a3ec0708283d43bcdb1f95 100644 (file)
@@ -96,6 +96,18 @@ extern "C" {
  */
 #define MMU_SIZE                   0x1000
 
+/*!
+ *  @def    CTRL_MODULE_BASE
+ *  @brief  configuration address.
+ */
+#define CTRL_MODULE_BASE           0x4A002000
+
+/*!
+ *  @def    CTRL_MODULE_SIZE
+ *  @brief  size to be ioremapped.
+ */
+#define CTRL_MODULE_SIZE           0x1000
+
 /* =============================================================================
  *  APIs
  * =============================================================================