]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - ipc/ipcdev.git/blobdiff - qnx/src/ipc3x_dev/ti/syslink/build/Qnx/resmgr/syslink_main.c
Remove DSP2 from invalid list and improve error handling for non-existing core
[ipc/ipcdev.git] / qnx / src / ipc3x_dev / ti / syslink / build / Qnx / resmgr / syslink_main.c
index f8ac7c0051799391d2b4717f8c8d51faf6aedc64..3f24b246ac6f44484ce2f83058a955db41f1ed47 100644 (file)
@@ -1,14 +1,14 @@
 /*
  *  @file       syslink_main.c
  *
- *  @brief      syslink main
+ *  @brief      ipc main
  *
  *
  *  @ver        02.00.00.46_alpha1
  *
  *  ============================================================================
  *
- *  Copyright (c) 2011-2013, Texas Instruments Incorporated
+ *  Copyright (c) 2011-2015, Texas Instruments Incorporated
  *
  *  Redistribution and use in source and binary forms, with or without
  *  modification, are permitted provided that the following conditions
@@ -57,9 +57,6 @@
 #include <sys/siginfo.h>
 #include <signal.h>
 #include <stdbool.h>
-#if defined(SYSLINK_PLATFORM_OMAP4430)
-#include <login.h>
-#endif
 
 #include <IpcKnl.h>
 
 #include <_GateMP_daemon.h>
 #include <OsalSemaphore.h>
 #include <ti/syslink/utils/OsalPrint.h>
-#if defined(SYSLINK_PLATFORM_OMAP4430) || defined(SYSLINK_PLATFORM_OMAP5430)
+#if defined(IPC_PLATFORM_OMAP5430)
 #include <_ipu_pm.h>
 #endif
 #include <ti/syslink/utils/Trace.h>
 #include <ti/syslink/ProcMgr.h>
 #include <Bitops.h>
 #include <RscTable.h>
-#if (_NTO_VERSION >= 800)
-#include <slog2.h>
-#endif
 
 #include <ti-ipc.h>
 
             | PROCMGR_AOP_DENY      \
             | PROCMGR_AOP_LOCK
 
-// Ducati trace to slog2 static variables and defines
-#define TRACE_BUFFER_SIZE               4096
-// polling interval in microseconds
-#define TRACE_POLLING_INTERVAL_US       1000000
 
-#if (_NTO_VERSION >= 800)
-static int verbosity = SLOG2_ERROR;
-static slog2_buffer_t buffer_handle;
-#else
 static int verbosity = 2;
-#endif
 
-#if defined(SYSLINK_PLATFORM_VAYU)
+/* Disable recovery mechanism if true */
+static int disableRecovery = false;
+static char * logFilename = NULL;
+
+/* Number of cores to attach to */
+static int numAttach = 0;
+
+#if defined(IPC_PLATFORM_VAYU)
 static bool gatempEnabled = false;
+static Int32 sr0OwnerProcId = -1;
 #endif
-static char trace_buffer[TRACE_BUFFER_SIZE];
-static pthread_mutex_t trace_mutex = PTHREAD_MUTEX_INITIALIZER;
-static Bool trace_active;
-static pthread_t thread_traces;
-
-// Syslink hibernation global variables
-Bool syslink_hib_enable = TRUE;
-#if !defined(SYSLINK_PLATFORM_OMAP4430) && !defined(SYSLINK_PLATFORM_OMAP5430)
+
+// IPC hibernation global variables
+Bool ipc_hib_enable = TRUE;
+#if !defined(IPC_PLATFORM_OMAP5430)
 #define PM_HIB_DEFAULT_TIME 5000
 #endif
-uint32_t syslink_hib_timeout = PM_HIB_DEFAULT_TIME;
-Bool syslink_hib_hibernating = FALSE;
-pthread_mutex_t syslink_hib_mutex = PTHREAD_MUTEX_INITIALIZER;
-pthread_cond_t syslink_hib_cond = PTHREAD_COND_INITIALIZER;
+uint32_t ipc_hib_timeout = PM_HIB_DEFAULT_TIME;
+Bool ipc_hib_hibernating = FALSE;
+pthread_mutex_t ipc_hib_mutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t ipc_hib_cond = PTHREAD_COND_INITIALIZER;
 
 extern Int rpmsg_rpc_setup (Void);
 extern Void rpmsg_rpc_destroy (Void);
 extern Void GateHWSpinlock_LeaveLockForPID(int pid);
 
-typedef struct syslink_firmware_info_t {
+typedef struct ipc_firmware_info_t {
     uint16_t proc_id;
     char * proc;
     char * firmware;
-} syslink_firmware_info;
-static syslink_firmware_info syslink_firmware[MultiProc_MAXPROCESSORS];
-static unsigned int syslink_num_cores = 0;
-
-int init_ipc(syslink_dev_t * dev, syslink_firmware_info * firmware, bool recover);
-int deinit_ipc(syslink_dev_t * dev, bool recover);
+    bool attachOnly;
+    int  procState;  /* state of processor - index into procStateNames array */
+    int  readProcState; /* state that is currently being printed */
+    bool reload;     /* reload core during recovery */
+    bool freeString; /* Need to free previously allocated firmware string */
+} ipc_firmware_info;
+static ipc_firmware_info ipc_firmware[MultiProc_MAXPROCESSORS];
+
+/* Number of valid entries in ipc_firmware array */
+static unsigned int ipc_num_cores = 0;
+
+int init_ipc(ipc_dev_t * dev, ipc_firmware_info * firmware,
+    bool recover);
+int deinit_ipc(ipc_dev_t * dev, ipc_firmware_info * firmware,
+    bool recover);
+int init_ipc_trace_device(ipc_dev_t *dev);
+int deinit_ipc_trace_device(ipc_dev_t *dev);
+
+Int ipc_error_cb (UInt16 procId, ProcMgr_Handle handle,
+                      ProcMgr_State fromState, ProcMgr_State toState,
+                      ProcMgr_EventStatus status, Ptr args);
 
 static RscTable_Handle rscHandle[MultiProc_MAXPROCESSORS];
 
@@ -146,17 +150,594 @@ static ProcMgr_State errStates[] = {ProcMgr_State_Mmu_Fault,
                                     ProcMgr_State_Watchdog,
                                     ProcMgr_State_EndValue};
 
-typedef struct syslink_trace_info_t {
+/* Processor states */
+#define RESET_STATE  0
+#define RUNNING_STATE 1
+
+static String procStateNames[] = { "In reset\n",
+                                   "Running\n" };
+
+typedef struct ipc_trace_info_t {
     uintptr_t   va;
     uint32_t    len;
     uint32_t *  widx;
     uint32_t *  ridx;
     Bool        firstRead;
-} syslink_trace_info;
+} ipc_trace_info;
+
+static ipc_trace_info proc_traces[MultiProc_MAXPROCESSORS];
+
+static int runSlave(ipc_dev_t *dev, uint16_t procId,
+    ipc_firmware_info * firmware_info)
+{
+    int status = 0;
+    ProcMgr_AttachParams attachParams;
+
+    if (firmware_info->firmware) {
+        rscHandle[procId] = RscTable_alloc(firmware_info->firmware, procId);
+        if (rscHandle[procId] == NULL) {
+            status = -1;
+            return status;
+        }
+    }
+
+    status = ProcMgr_open(&procH[procId], procId);
+    if (status < 0 || procH[procId] == NULL) {
+        goto procmgropen_fail;
+    }
+
+    /* Load and start the remote processor. */
+    ProcMgr_getAttachParams(procH[procId], &attachParams);
+    if (firmware_info->attachOnly) {
+        attachParams.bootMode = ProcMgr_BootMode_NoBoot;
+    }
+    status = ProcMgr_attach(procH[procId], &attachParams);
+    if (status < 0) {
+        GT_setFailureReason(curTrace,
+                            GT_4CLASS,
+                            "runSlave",
+                            status,
+                            "ProcMgr_attach failed!");
+        goto procmgrattach_fail;
+    }
+
+    if ((firmware_info->firmware) &&
+        (!firmware_info->attachOnly)) {
+        status = ProcMgr_load(procH[procId],
+            (String)firmware_info->firmware, 0, NULL,
+             NULL, &procH_fileId[procId]);
+        if (status < 0) {
+            GT_setFailureReason(curTrace,
+                                GT_4CLASS,
+                                "runSlave",
+                                status,
+                                "ProcMgr_load failed!");
+            goto procmgrload_fail;
+        }
+    }
+
+    status = Ipc_attach(procId);
+    if (status < 0) {
+        GT_setFailureReason(curTrace,
+                             GT_4CLASS,
+                             "runSlave",
+                             status,
+                             "Ipc_attach failed!");
+        goto ipcattach_fail;
+    }
+
+    status = ProcMgr_registerNotify(procH[procId], ipc_error_cb, (Ptr)dev,
+        -1, errStates);
+    if (status < 0) {
+        goto procmgrreg_fail;
+    }
+
+    if (!firmware_info->attachOnly) {
+        status = ProcMgr_start(procH[procId], NULL);
+        if (status < 0) {
+            GT_setFailureReason(curTrace,
+                                GT_4CLASS,
+                                "runSlave",
+                                status,
+                                "ProcMgr_start failed!");
+            goto procmgrstart_fail;
+        }
+    }
+
+    Osal_printf("runSlave successful for core %d\n", procId);
+
+    return 0;
+
+procmgrstart_fail:
+    ProcMgr_unregisterNotify(procH[procId], ipc_error_cb,
+        (Ptr)dev, errStates);
+procmgrreg_fail:
+    Ipc_detach(procId);
+ipcattach_fail:
+    if ((firmware_info->firmware) &&
+        (!firmware_info->attachOnly)) {
+        ProcMgr_unload(procH[procId], procH_fileId[procId]);
+    }
+procmgrload_fail:
+    ProcMgr_detach(procH[procId]);
+procmgrattach_fail:
+    ProcMgr_close(&procH[procId]);
+    procH[procId] = NULL;
+procmgropen_fail:
+    RscTable_free(&rscHandle[procId]);
+
+    return -1;
+}
+
+static int resetSlave(ipc_dev_t *dev, uint16_t procId)
+{
+    if ((procH[procId]) && (procH_fileId[procId])) {
+        GT_1trace(curTrace, GT_4CLASS, "stopping %s", MultiProc_getName(procId));
+        ProcMgr_stop(procH[procId]);
+    }
+
+    if (procH[procId]) {
+        ProcMgr_unregisterNotify(procH[procId], ipc_error_cb, (Ptr)dev,
+            errStates);
+        Ipc_detach(procId);
+        if (procH_fileId[procId]) {
+            ProcMgr_unload(procH[procId], procH_fileId[procId]);
+            procH_fileId[procId] = 0;
+        }
+        ProcMgr_detach(procH[procId]);
+        ProcMgr_close(&procH[procId]);
+        procH[procId] = NULL;
+        RscTable_free(&rscHandle[procId]);
+        rscHandle[procId] = NULL;
+    }
+
+    Osal_printf("resetSlave successful for core %d\n", procId);
+
+    return 0;
+}
+
+/* Add firmware entry after IPC is setup */
+static void addFirmware(uint16_t procId)
+{
+    ipc_firmware[ipc_num_cores].proc =
+        MultiProc_getName(procId);
+    ipc_firmware[ipc_num_cores].proc_id = procId;
+    ipc_firmware[ipc_num_cores].attachOnly = false;
+    ipc_firmware[ipc_num_cores].reload = false;
+    ipc_firmware[ipc_num_cores].procState = RESET_STATE;
+    ipc_firmware[ipc_num_cores].freeString = false;
+    ipc_firmware[ipc_num_cores++].firmware = NULL;
+
+    return;
+}
+
+static int slave_state_read(resmgr_context_t *ctp, io_read_t *msg,
+    ipc_ocb_t *ocb)
+{
+    int             nbytes;
+    int             nparts;
+    int             status;
+    int             nleft;
+    int             i;
+    uint16_t        procId = ocb->ocb.attr->procid;
+    ipc_dev_t * dev = ocb->ocb.attr->dev;
+
+    if ((status = iofunc_read_verify(ctp, msg, &ocb->ocb, NULL)) != EOK) {
+        return (status);
+    }
+
+    if ((msg->i.xtype & _IO_XTYPE_MASK) != _IO_XTYPE_NONE) {
+        return (ENOSYS);
+    }
+
+    pthread_mutex_lock(&dev->firmwareLock);
+
+    for (i = 0; i < ipc_num_cores; i++) {
+        if (ipc_firmware[i].proc_id == procId) {
+            break;
+        }
+    }
+    if (i == ipc_num_cores) {
+        if ((ipc_num_cores < MultiProc_MAXPROCESSORS)) {
+            addFirmware(procId);
+        }
+        else {
+            pthread_mutex_unlock(&dev->firmwareLock);
+            return (EBADSLT);
+        }
+    }
+
+    if (ocb->ocb.offset == 0) {
+        /* latch onto new state, so that we print out complete strings */
+        ipc_firmware[i].readProcState = ipc_firmware[i].procState;
+    }
+
+    nleft = strlen(procStateNames[ipc_firmware[i].readProcState])
+        - ocb->ocb.offset; /* the state is expressed in one byte */
+    nbytes = min(msg->i.nbytes, nleft);
+
+    /* Make sure the user has supplied a big enough buffer */
+    if (nbytes > 0) {
+        /* set up the return data IOV */
+        SETIOV(ctp->iov,
+            (char *)procStateNames[ipc_firmware[i].readProcState]
+            + ocb->ocb.offset, nbytes);
+
+        pthread_mutex_unlock(&dev->firmwareLock);
+
+        /* set up the number of bytes (returned by client's read()) */
+        _IO_SET_READ_NBYTES(ctp, nbytes);
+
+        ocb->ocb.offset += nbytes;
+
+        nparts = 1;
+    }
+    else {
+        pthread_mutex_unlock(&dev->firmwareLock);
+
+        _IO_SET_READ_NBYTES (ctp, 0);
+
+        /* reset offset */
+        ocb->ocb.offset = 0;
+
+        nparts = 0;
+    }
+
+    /* mark the access time as invalid (we just accessed it) */
+
+    if (msg->i.nbytes > 0) {
+        ocb->ocb.attr->attr.flags |= IOFUNC_ATTR_ATIME;
+    }
+
+    return (_RESMGR_NPARTS(nparts));
+}
+
+static int slave_state_write(resmgr_context_t *ctp, io_write_t *msg,
+    ipc_ocb_t *ocb)
+{
+    int             status;
+    char *          buf;
+    uint16_t        procId = ocb->ocb.attr->procid;
+    int             i;
+    char *          ptr;
+    ipc_dev_t * dev = ocb->ocb.attr->dev;
+    Int32           sr0ProcId;
+
+    if ((status = iofunc_write_verify(ctp, msg, &ocb->ocb, NULL)) != EOK) {
+        return (status);
+    }
+
+    if ((msg->i.xtype & _IO_XTYPE_MASK) != _IO_XTYPE_NONE) {
+        return (ENOSYS);
+    }
+
+    /* set up the number of bytes (returned by client's write()) */
+    _IO_SET_WRITE_NBYTES (ctp, msg->i.nbytes);
+
+    buf = (char *) malloc(msg->i.nbytes + 1);
+    if (buf == NULL) {
+        return (ENOMEM);
+    }
+
+    /*
+     *  Read the data from the sender's message buffer.
+     */
+    resmgr_msgread(ctp, buf, msg->i.nbytes, sizeof(msg->i));
+    buf[msg->i.nbytes] = '\0'; /* just in case the text is not NULL terminated */
+    if((ptr = strchr(buf, '\n')) != NULL) { /* Remove line feed if any */
+        *ptr = '\0';
+    }
+
+    pthread_mutex_lock(&dev->firmwareLock);
+    for (i = 0; i < ipc_num_cores; i++) {
+        if (ipc_firmware[i].proc_id == procId) {
+            break;
+        }
+    }
+    if (i == ipc_num_cores) {
+        if ((ipc_num_cores < MultiProc_MAXPROCESSORS)) {
+            addFirmware(procId);
+        }
+        else {
+            pthread_mutex_unlock(&dev->firmwareLock);
+            return (EBADSLT);
+        }
+    }
+
+    if (strcmp("1", buf) == 0) {
+        if ((ipc_firmware[i].procState == RESET_STATE) &&
+           (ipc_firmware[i].firmware != NULL)) {
+            status = runSlave(ocb->ocb.attr->dev, procId, &ipc_firmware[i]);
+            if (status < 0) {
+                pthread_mutex_unlock(&dev->firmwareLock);
+                free(buf);
+                fprintf(stderr, "IPC: failed to run slave core %s\n",
+                    MultiProc_getName(procId));
+                return (EIO);
+            }
+#if defined(IPC_PLATFORM_VAYU)
+            if (gatempEnabled) {
+                if (sr0OwnerProcId == -1) {
+                    /* Set up GateMP */
+                    status = GateMP_setup(&sr0ProcId);
+                    if ((status < 0) && (status != GateMP_E_NOTFOUND)) {
+                        resetSlave(ocb->ocb.attr->dev, procId);
+                        pthread_mutex_unlock(&dev->firmwareLock);
+                        free(buf);
+                        fprintf(stderr, "GateMP_setup failed\n");
+                        return (EIO);
+                    }
+                    else if (status == 0) {
+                        /* We have discovered an owner for SR0 */
+                        sr0OwnerProcId = sr0ProcId;
+                    }
+                }
+                else {
+                    /*
+                     * We have already identified SR0 owner and setup GateMP.
+                     * Do nothing.
+                     */
+                }
+            }
+#endif
+            printf("Core is now running with image '%s'\n",
+                ipc_firmware[i].firmware);
+            ipc_firmware[i].procState = RUNNING_STATE;
+            ipc_firmware[i].reload = true;
+            status = init_ipc_trace_device(dev);
+            if (status < 0) {
+#if defined(IPC_PLATFORM_VAYU)
+                if ((gatempEnabled) && (procId == sr0OwnerProcId)) {
+                    sr0OwnerProcId = -1;
+                    GateMP_destroy(FALSE);
+                }
+#endif
+                resetSlave(ocb->ocb.attr->dev, procId);
+                pthread_mutex_unlock(&dev->firmwareLock);
+                free(buf);
+                fprintf(stderr, "IPC: init_ipc_trace_device failed %d\n",
+                    status);
+                return (EIO);
+            }
+            printf("Core %s has been started.\n", MultiProc_getName(procId));
+        }
+    }
+    else if (strcmp("0", buf) == 0) {
+        if (ipc_firmware[i].procState == RUNNING_STATE) {
+#if defined(IPC_PLATFORM_VAYU)
+            if ((gatempEnabled) && (procId == sr0OwnerProcId)) {
+                sr0OwnerProcId = -1;
+                status = GateMP_destroy(FALSE);
+                if (status < 0) {
+                    pthread_mutex_unlock(&dev->firmwareLock);
+                    free(buf);
+                    fprintf(stderr, "Core %s cannot be reset. GateMP may still"
+                        " be in use by host\n", MultiProc_getName(procId));
+                    return (EIO);
+                }
+            }
+#endif
+            status = resetSlave(ocb->ocb.attr->dev, procId);
+            if (status < 0) {
+                pthread_mutex_unlock(&dev->firmwareLock);
+                free(buf);
+                fprintf(stderr, "IPC: failed to reset slave core %s\n",
+                    MultiProc_getName(procId));
+                return (EIO);
+            }
+            ipc_firmware[i].procState = RESET_STATE;
+            ipc_firmware[i].reload = false;
+            status = deinit_ipc_trace_device(dev);
+            if (status < 0) {
+                pthread_mutex_unlock(&dev->firmwareLock);
+                free(buf);
+                fprintf(stderr, "IPC: deinit_ipc_trace_device failed %d\n",
+                    status);
+                return (EIO);
+            }
+            printf("Core %s has been reset.\n", MultiProc_getName(procId));
+        }
+    }
+    else {
+        /* ignore the input as it is not recognized */
+        fprintf(stderr, "Unrecognized input\n");
+    }
+
+    pthread_mutex_unlock(&dev->firmwareLock);
+
+    free(buf);
+
+    if (msg->i.nbytes > 0) {
+        ocb->ocb.attr->attr.flags |= IOFUNC_ATTR_MTIME | IOFUNC_ATTR_CTIME;
+    }
+
+    return (_RESMGR_NPARTS(0));
+}
+
+static int slave_file_read(resmgr_context_t *ctp, io_read_t *msg,
+    ipc_ocb_t *ocb)
+{
+    int             nbytes;
+    int             nparts;
+    int             status;
+    int             nleft;
+    int             i;
+    uint16_t        procId = ocb->ocb.attr->procid;
+    ipc_dev_t * dev = ocb->ocb.attr->dev;
+
+    if ((status = iofunc_read_verify (ctp, msg, &ocb->ocb, NULL)) != EOK) {
+        return (status);
+    }
+
+    if ((msg->i.xtype & _IO_XTYPE_MASK) != _IO_XTYPE_NONE) {
+        return (ENOSYS);
+    }
+
+    pthread_mutex_lock(&dev->firmwareLock);
+    for (i = 0; i < ipc_num_cores; i++) {
+        if (ipc_firmware[i].proc_id == procId) {
+            break;
+        }
+    }
+
+    if (i == ipc_num_cores) {
+        if ((ipc_num_cores < MultiProc_MAXPROCESSORS)) {
+            addFirmware(procId);
+        }
+        else {
+            pthread_mutex_unlock(&dev->firmwareLock);
+            return (EBADSLT);
+        }
+    }
+
+    if (ipc_firmware[i].firmware == NULL) {
+        nbytes = 0;
+    }
+    else {
+        nleft = strlen(ipc_firmware[i].firmware)
+            - ocb->ocb.offset + 1; /* Add one byte for carriage return */
+        nbytes = min(msg->i.nbytes, nleft);
+    }
+
+    /* Make sure the user has supplied a big enough buffer */
+    if (nbytes > 0) {
+        if (nbytes == nleft) {
+            /* set up the return data IOV */
+            SETIOV(&ctp->iov[0], (char *)ipc_firmware[i].firmware
+                + ocb->ocb.offset, nbytes - 1);
+
+            /* add a carriage return */
+            SETIOV(&ctp->iov[1], "\n", 1);
+
+            nparts = 2;
+        }
+        else {
+            /* set up the return data IOV */
+            SETIOV(ctp->iov, (char *)ipc_firmware[i].firmware
+                + ocb->ocb.offset, nbytes);
+
+            nparts = 1;
+        }
+
+        /* set up the number of bytes (returned by client's read()) */
+        _IO_SET_READ_NBYTES(ctp, nbytes);
+
+        ocb->ocb.offset += nbytes;
+    }
+    else {
+        _IO_SET_READ_NBYTES (ctp, 0);
+
+        /* reset offset */
+        ocb->ocb.offset = 0;
+
+        nparts = 0;
+    }
+
+    pthread_mutex_unlock(&dev->firmwareLock);
+
+    /* mark the access time as invalid (we just accessed it) */
+
+    if (msg->i.nbytes > 0) {
+        ocb->ocb.attr->attr.flags |= IOFUNC_ATTR_ATIME;
+    }
+
+    return (_RESMGR_NPARTS(nparts));
+}
+
+static int slave_file_write(resmgr_context_t *ctp, io_write_t *msg,
+    ipc_ocb_t *ocb)
+{
+    int             status;
+    char *          buf;
+    uint16_t        procId = ocb->ocb.attr->procid;
+    int             i;
+    char *          absPath;
+    char *          ptr;
+    ipc_dev_t * dev = ocb->ocb.attr->dev;
+
+    if ((status = iofunc_write_verify(ctp, msg, &ocb->ocb, NULL)) != EOK) {
+        return (status);
+    }
+
+    if ((msg->i.xtype & _IO_XTYPE_MASK) != _IO_XTYPE_NONE) {
+        return (ENOSYS);
+    }
+
+    /* set up the number of bytes (returned by client's write()) */
+    _IO_SET_WRITE_NBYTES (ctp, msg->i.nbytes);
+
+    buf = (char *) malloc(msg->i.nbytes + 1);
+    if (buf == NULL) {
+        return (ENOMEM);
+    }
+
+    /*
+     *  Read the data from the sender's message buffer.
+     */
+    resmgr_msgread(ctp, buf, msg->i.nbytes, sizeof(msg->i));
+    buf[msg->i.nbytes] = '\0'; /* just in case the text is not NULL terminated */
+    if((ptr = strchr(buf, '\n')) != NULL) { /* Remove line feed if any */
+        *ptr = '\0';
+    }
+
+    /* Get the abs path for all firmware files */
+    absPath = calloc(1, PATH_MAX + 1);
+    if (absPath == NULL) {
+        free(buf);
+        return (ENOMEM);
+    }
+    if (NULL == realpath(buf, absPath)) {
+        fprintf(stderr, "invalid path to executable: %d\n", errno);
+        fprintf(stderr, "make sure you are specifying the full path to the "
+            "file.\n");
+        free(absPath);
+        free(buf);
+        return (ENOENT);
+    }
+    free(buf);
+
+    pthread_mutex_lock(&dev->firmwareLock);
+
+    /*
+     * Check if an entry in ipc_firmware already exists for this core.
+     * If not, create one. Otherwise just update the firmware path.
+     */
+    for (i = 0; i < ipc_num_cores; i++) {
+        if (ipc_firmware[i].proc_id == procId) {
+            break;
+        }
+    }
+    if (i == ipc_num_cores) {
+        if (ipc_num_cores < MultiProc_MAXPROCESSORS) {
+            addFirmware(procId);
+            ipc_firmware[ipc_num_cores - 1].freeString = true;
+            ipc_firmware[ipc_num_cores - 1].firmware = absPath;
+        }
+        else {
+            pthread_mutex_unlock(&dev->firmwareLock);
+            free(absPath);
+            return (EBADSLT);
+        }
+    }
+    else {
+        /* Free previously allocated string */
+        if ((ipc_firmware[i].freeString) &&
+           (ipc_firmware[i].firmware)) {
+            free(ipc_firmware[i].firmware);
+        }
+        ipc_firmware[i].firmware = absPath;
+    }
 
-static syslink_trace_info proc_traces[MultiProc_MAXPROCESSORS];
+    pthread_mutex_unlock(&dev->firmwareLock);
 
-int syslink_read(resmgr_context_t *ctp, io_read_t *msg, syslink_ocb_t *ocb)
+    if (msg->i.nbytes > 0) {
+        ocb->ocb.attr->attr.flags |= IOFUNC_ATTR_MTIME | IOFUNC_ATTR_CTIME;
+    }
+
+    return (_RESMGR_NPARTS(0));
+}
+
+int ipc_read(resmgr_context_t *ctp, io_read_t *msg, ipc_ocb_t *ocb)
 {
     int         nbytes;
     int         nparts;
@@ -175,22 +756,6 @@ int syslink_read(resmgr_context_t *ctp, io_read_t *msg, syslink_ocb_t *ocb)
     if (proc_traces[procid].va == NULL) {
         return (ENOSYS);
     }
-
-    /* need to abort ducati trace thread if it is running as only want one reader */
-    pthread_mutex_lock(&trace_mutex);
-    if (trace_active == TRUE) {
-        trace_active = FALSE;
-        pthread_mutex_unlock(&trace_mutex);
-        // Wake up if waiting on hibernation
-        pthread_mutex_lock(&syslink_hib_mutex);
-        syslink_hib_hibernating = FALSE;
-        pthread_cond_broadcast(&syslink_hib_cond);
-        pthread_mutex_unlock(&syslink_hib_mutex);
-        pthread_join(thread_traces, NULL);
-    } else {
-        pthread_mutex_unlock(&trace_mutex);
-    }
-
     if (ocb->ocb.offset == 0) {
         ocb->widx = *(proc_traces[procid].widx);
         ocb->ridx = *(proc_traces[procid].ridx);
@@ -247,7 +812,7 @@ int syslink_read(resmgr_context_t *ctp, io_read_t *msg, syslink_ocb_t *ocb)
 
 extern OsalSemaphore_Handle mqcopy_test_sem;
 
-int syslink_unblock(resmgr_context_t *ctp, io_pulse_t *msg, syslink_ocb_t *ocb)
+int ipc_unblock(resmgr_context_t *ctp, io_pulse_t *msg, ipc_ocb_t *ocb)
 {
     int status = _RESMGR_NOREPLY;
     struct _msg_info info;
@@ -275,12 +840,12 @@ int syslink_unblock(resmgr_context_t *ctp, io_pulse_t *msg, syslink_ocb_t *ocb)
 }
 
 IOFUNC_OCB_T *
-syslink_ocb_calloc (resmgr_context_t * ctp, IOFUNC_ATTR_T * device)
+ipc_ocb_calloc (resmgr_context_t * ctp, IOFUNC_ATTR_T * device)
 {
-    syslink_ocb_t *ocb = NULL;
+    ipc_ocb_t *ocb = NULL;
 
     /* Allocate the OCB */
-    ocb = (syslink_ocb_t *) calloc (1, sizeof (syslink_ocb_t));
+    ocb = (ipc_ocb_t *) calloc (1, sizeof (ipc_ocb_t));
     if (ocb == NULL){
         errno = ENOMEM;
         return (NULL);
@@ -292,23 +857,114 @@ syslink_ocb_calloc (resmgr_context_t * ctp, IOFUNC_ATTR_T * device)
 }
 
 void
-syslink_ocb_free (IOFUNC_OCB_T * i_ocb)
+ipc_ocb_free (IOFUNC_OCB_T * i_ocb)
 {
-    syslink_ocb_t * ocb = (syslink_ocb_t *)i_ocb;
+    ipc_ocb_t * ocb = (ipc_ocb_t *)i_ocb;
 
     if (ocb) {
-#ifndef SYSLINK_PLATFORM_VAYU
+#ifndef IPC_PLATFORM_VAYU
         GateHWSpinlock_LeaveLockForPID(ocb->pid);
 #endif
         free (ocb);
     }
 }
 
-int init_syslink_trace_device(syslink_dev_t *dev)
+int init_slave_devices(ipc_dev_t *dev)
+{
+    resmgr_attr_t    resmgr_attr;
+    int              i;
+    ipc_attr_t * slave_attr;
+    int              status = 0;
+
+    memset(&resmgr_attr, 0, sizeof resmgr_attr);
+    resmgr_attr.nparts_max = 2;
+    resmgr_attr.msg_max_size = _POSIX_PATH_MAX;
+
+    /* Populate the /dev/ipc-state namespace */
+    for (i = 1; i < MultiProc_getNumProcessors(); i++) {
+        iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &dev->ipc.cfuncs_state[i],
+                         _RESMGR_IO_NFUNCS, &dev->ipc.iofuncs_state[i]);
+        slave_attr = &dev->ipc.cattr_slave[i];
+        iofunc_attr_init(&slave_attr->attr,
+                         S_IFCHR | 0777, NULL, NULL);
+        slave_attr->attr.mount = &dev->ipc.mattr;
+        slave_attr->procid = i;
+        slave_attr->dev = (Ptr)dev;
+        iofunc_time_update(&slave_attr->attr);
+        snprintf(dev->ipc.device_name, _POSIX_PATH_MAX,
+                  "%s-state/%s", IPC_DEVICE_PATH, MultiProc_getName(i));
+        dev->ipc.iofuncs_state[i].read = slave_state_read;
+        dev->ipc.iofuncs_state[i].write = slave_state_write;
+
+        if (-1 == (dev->ipc.resmgr_id_state[i] =
+            resmgr_attach(dev->dpp, &resmgr_attr,
+                dev->ipc.device_name, _FTYPE_ANY, 0,
+                &dev->ipc.cfuncs_state[i],
+                &dev->ipc.iofuncs_state[i],
+                &slave_attr->attr))) {
+            GT_setFailureReason(curTrace, GT_4CLASS, "init_slave_devices",
+                status, "resmgr_attach failed");
+            return (-1);
+        }
+    }
+
+    /* Populate the /dev/ipc-file namespace */
+    for (i = 1; i < MultiProc_getNumProcessors(); i++) {
+        iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &dev->ipc.cfuncs_file[i],
+                         _RESMGR_IO_NFUNCS, &dev->ipc.iofuncs_file[i]);
+        slave_attr = &dev->ipc.cattr_slave[i];
+        iofunc_attr_init(&slave_attr->attr,
+                         S_IFCHR | 0777, NULL, NULL);
+        slave_attr->attr.mount = &dev->ipc.mattr;
+        slave_attr->procid = i;
+        slave_attr->dev = (Ptr)dev;
+        iofunc_time_update(&slave_attr->attr);
+        snprintf(dev->ipc.device_name, _POSIX_PATH_MAX,
+                  "%s-file/%s", IPC_DEVICE_PATH, MultiProc_getName(i));
+        dev->ipc.iofuncs_file[i].read = slave_file_read;
+        dev->ipc.iofuncs_file[i].write = slave_file_write;
+
+        if (-1 == (dev->ipc.resmgr_id_file[i] =
+            resmgr_attach(dev->dpp, &resmgr_attr,
+                dev->ipc.device_name, _FTYPE_ANY, 0,
+                &dev->ipc.cfuncs_file[i],
+                &dev->ipc.iofuncs_file[i],
+                &slave_attr->attr))) {
+            GT_setFailureReason(curTrace, GT_4CLASS, "init_slave_devices",
+                status, "resmgr_attach failed");
+            return (-1);
+        }
+    }
+
+    return (status);
+}
+
+int deinit_slave_devices(ipc_dev_t *dev)
+{
+    int status = EOK;
+    int i = 0;
+
+    for (i = 1; i < MultiProc_getNumProcessors(); i++) {
+        status = resmgr_detach(dev->dpp, dev->ipc.resmgr_id_state[i], 0);
+        if (status < 0) {
+            Osal_printf("IPC: resmgr_detach of state device %d failed: %d",
+                i, errno);
+        }
+        status = resmgr_detach(dev->dpp, dev->ipc.resmgr_id_file[i], 0);
+        if (status < 0) {
+            Osal_printf("IPC: resmgr_detach of file device %d failed: %d",
+                i, errno);
+        }
+    }
+
+    return (status);
+}
+
+int init_ipc_trace_device(ipc_dev_t *dev)
 {
     resmgr_attr_t    resmgr_attr;
     int              i;
-    syslink_attr_t * trace_attr;
+    ipc_attr_t * trace_attr;
     char             trace_name[_POSIX_PATH_MAX];
     int              status = 0;
     unsigned int     da = 0, pa = 0;
@@ -318,137 +974,164 @@ int init_syslink_trace_device(syslink_dev_t *dev)
     resmgr_attr.nparts_max = 10;
     resmgr_attr.msg_max_size = 2048;
 
-    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]);
-        trace_attr = &dev->syslink.cattr_trace[i];
-        iofunc_attr_init(&trace_attr->attr,
+    for (i = 0; i < ipc_num_cores; i++) {
+        /*
+         * Initialize trace device only for cores that are running and their
+         * device is not yet setup.
+         */
+        if ((ipc_firmware[i].procState == RUNNING_STATE) &&
+            (proc_traces[i].va == NULL)) {
+            iofunc_func_init(_RESMGR_CONNECT_NFUNCS,
+                &dev->ipc.cfuncs_trace[i],
+                _RESMGR_IO_NFUNCS, &dev->ipc.iofuncs_trace[i]);
+            trace_attr = &dev->ipc.cattr_trace[i];
+            iofunc_attr_init(&trace_attr->attr,
                          S_IFCHR | 0777, NULL, NULL);
-        trace_attr->attr.mount = &dev->syslink.mattr;
-        trace_attr->procid = i;
-        iofunc_time_update(&trace_attr->attr);
-        snprintf (dev->syslink.device_name, _POSIX_PATH_MAX,
-                  "/dev/ipc-trace%d", syslink_firmware[i].proc_id);
-        dev->syslink.iofuncs_trace[i].read = syslink_read;
-        snprintf (trace_name, _POSIX_PATH_MAX, "%d", 0);
-        pa = 0;
-        status = RscTable_getInfo(syslink_firmware[i].proc_id, TYPE_TRACE, 0, &da, &pa, &len);
-        if (status == 0) {
-            /* last 8 bytes are for writeIdx/readIdx */
-            proc_traces[i].len = len - (sizeof(uint32_t) * 2);
-            if (da && !pa) {
-                /* need to translate da->pa */
-                status = ProcMgr_translateAddr (procH[syslink_firmware[i].proc_id],
-                                                (Ptr *) &pa,
-                                                ProcMgr_AddrType_MasterPhys,
-                                                (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 =
+            trace_attr->attr.mount = &dev->ipc.mattr;
+            trace_attr->procid = i;
+            iofunc_time_update(&trace_attr->attr);
+            snprintf(dev->ipc.device_name, _POSIX_PATH_MAX,
+                "%s-trace/%s", IPC_DEVICE_PATH,
+                MultiProc_getName(ipc_firmware[i].proc_id));
+            dev->ipc.iofuncs_trace[i].read = ipc_read;
+            snprintf (trace_name, _POSIX_PATH_MAX, "%d", 0);
+            pa = 0;
+            status = RscTable_getInfo(ipc_firmware[i].proc_id, TYPE_TRACE,
+                0, &da, &pa, &len);
+            if (status == 0) {
+                /* last 8 bytes are for writeIdx/readIdx */
+                proc_traces[i].len = len - (sizeof(uint32_t) * 2);
+                if (da && !pa) {
+                    /* need to translate da->pa */
+                    status = ProcMgr_translateAddr(
+                        procH[ipc_firmware[i].proc_id],
+                        (Ptr *) &pa,
+                        ProcMgr_AddrType_MasterPhys,
+                        (Ptr) da,
+                        ProcMgr_AddrType_SlaveVirt);
+                }
+                else {
+                    GT_setFailureReason(curTrace, GT_4CLASS,
+                        "init_ipc_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);
-            proc_traces[i].widx = (uint32_t *)(proc_traces[i].va + \
+                proc_traces[i].widx = (uint32_t *)(proc_traces[i].va + \
                                                proc_traces[i].len);
-            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].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_ipc_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_ipc_trace_device",
+                    status, "RscTable_getInfo failed");
                 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] =
+            if (-1 == (dev->ipc.resmgr_id_trace[i] =
                        resmgr_attach(dev->dpp, &resmgr_attr,
-                                     dev->syslink.device_name, _FTYPE_ANY, 0,
-                                     &dev->syslink.cfuncs_trace[i],
-                                     &dev->syslink.iofuncs_trace[i],
+                                     dev->ipc.device_name, _FTYPE_ANY, 0,
+                                     &dev->ipc.cfuncs_trace[i],
+                                     &dev->ipc.iofuncs_trace[i],
                                      &trace_attr->attr))) {
-            GT_setFailureReason(curTrace, GT_4CLASS, "init_syslink_trace_device",
-                                status, "resmgr_attach failed");
-            return(-1);
+                GT_setFailureReason(curTrace, GT_4CLASS,
+                    "init_ipc_trace_device",
+                    status, "resmgr_attach failed");
+                return(-1);
+            }
         }
     }
 
     return (status);
 }
 
-int deinit_syslink_trace_device(syslink_dev_t *dev)
+int deinit_ipc_trace_device(ipc_dev_t *dev)
 {
     int status = EOK;
     int i = 0;
 
-    for (i = 0; i < syslink_num_cores; i++) {
-        status = resmgr_detach(dev->dpp, dev->syslink.resmgr_id_trace[i], 0);
-        if (status < 0) {
-            Osal_printf("syslink: resmgr_detach failed %d", errno);
-            status = errno;
-        }
-        if (proc_traces[i].va && proc_traces[i].va != MAP_DEVICE_FAILED) {
-            munmap((void *)proc_traces[i].va,
+    for (i = 0; i < ipc_num_cores; i++) {
+        /* Only disable trace device on cores in RESET state */
+        if ((ipc_firmware[i].procState == RESET_STATE) &&
+            (proc_traces[i].va != NULL)) {
+            status = resmgr_detach(dev->dpp, dev->ipc.resmgr_id_trace[i],
+                0);
+            if (status < 0) {
+                Osal_printf("IPC: resmgr_detach of trace device %d failed: %d",
+                    i, errno);
+                status = errno;
+            }
+            if (proc_traces[i].va && proc_traces[i].va != MAP_DEVICE_FAILED) {
+                munmap((void *)proc_traces[i].va,
                    ((proc_traces[i].len + 8 + 0x1000 - 1) / 0x1000) * 0x1000);
+            }
+            proc_traces[i].va = NULL;
         }
-        proc_traces[i].va = NULL;
     }
 
     return (status);
 }
 
-/* Initialize the syslink device */
-int init_syslink_device(syslink_dev_t *dev)
+/* Initialize the ipc device */
+int init_ipc_device(ipc_dev_t *dev)
 {
     iofunc_attr_t *  attr;
     resmgr_attr_t    resmgr_attr;
     int              status = 0;
 
     pthread_mutex_init(&dev->lock, NULL);
+    pthread_mutex_init(&dev->firmwareLock, 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 |
+    memset(&dev->ipc.mattr, 0, sizeof(iofunc_mount_t));
+    dev->ipc.mattr.flags = ST_NOSUID | ST_NOEXEC;
+    dev->ipc.mattr.conf = IOFUNC_PC_CHOWN_RESTRICTED |
                               IOFUNC_PC_NO_TRUNC |
                               IOFUNC_PC_SYNC_IO;
-    dev->syslink.mattr.funcs = &dev->syslink.mfuncs;
+    dev->ipc.mattr.funcs = &dev->ipc.mfuncs;
 
-    memset(&dev->syslink.mfuncs, 0, sizeof(iofunc_funcs_t));
-    dev->syslink.mfuncs.nfuncs = _IOFUNC_NFUNCS;
+    memset(&dev->ipc.mfuncs, 0, sizeof(iofunc_funcs_t));
+    dev->ipc.mfuncs.nfuncs = _IOFUNC_NFUNCS;
 
-    iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &dev->syslink.cfuncs,
-                    _RESMGR_IO_NFUNCS, &dev->syslink.iofuncs);
+    iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &dev->ipc.cfuncs,
+                    _RESMGR_IO_NFUNCS, &dev->ipc.iofuncs);
 
-    iofunc_attr_init(attr = &dev->syslink.cattr, S_IFCHR | 0777, NULL, NULL);
+    iofunc_attr_init(attr = &dev->ipc.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;
+    dev->ipc.mfuncs.ocb_calloc = ipc_ocb_calloc;
+    dev->ipc.mfuncs.ocb_free = ipc_ocb_free;
+    dev->ipc.iofuncs.devctl = ipc_devctl;
+    dev->ipc.iofuncs.unblock = ipc_unblock;
 
-    attr->mount = &dev->syslink.mattr;
+    attr->mount = &dev->ipc.mattr;
     iofunc_time_update(attr);
 
-    if (-1 == (dev->syslink.resmgr_id =
+    if (-1 == (dev->ipc.resmgr_id =
         resmgr_attach(dev->dpp, &resmgr_attr,
                       IPC_DEVICE_PATH, _FTYPE_ANY, 0,
-                      &dev->syslink.cfuncs,
-                      &dev->syslink.iofuncs, attr))) {
+                      &dev->ipc.cfuncs,
+                      &dev->ipc.iofuncs, attr))) {
         return(-1);
     }
 
-    status = init_syslink_trace_device(dev);
+    status = init_slave_devices(dev);
+    if (status < 0) {
+        return status;
+    }
+
+    status = init_ipc_trace_device(dev);
     if (status < 0) {
         return status;
     }
@@ -456,28 +1139,37 @@ int init_syslink_device(syslink_dev_t *dev)
     return(0);
 }
 
-/* De-initialize the syslink device */
-int deinit_syslink_device(syslink_dev_t *dev)
+/* De-initialize the ipc device */
+int deinit_ipc_device(ipc_dev_t *dev)
 {
     int status = EOK;
 
-    status = resmgr_detach(dev->dpp, dev->syslink.resmgr_id, 0);
+    status = resmgr_detach(dev->dpp, dev->ipc.resmgr_id, 0);
     if (status < 0) {
-        Osal_printf("syslink: resmgr_detach failed %d", errno);
+        Osal_printf("IPC: resmgr_detach of %s failed: %d",
+            IPC_DEVICE_PATH, errno);
         status = errno;
     }
 
-    status = deinit_syslink_trace_device(dev);
+    status = deinit_ipc_trace_device(dev);
+    if (status < 0) {
+        Osal_printf("IPC: deinit_ipc_trace_device failed %d", status);
+    }
+
+    status = deinit_slave_devices(dev);
+    if (status < 0) {
+        Osal_printf("IPC: deinit_slave_devices failed %d", status);
+    }
 
     return(status);
 }
 
 
 /* Initialize the devices */
-int init_devices(syslink_dev_t *dev)
+int init_devices(ipc_dev_t *dev)
 {
-    if (init_syslink_device(dev) < 0) {
-        Osal_printf("syslink: syslink device init failed");
+    if (init_ipc_device(dev) < 0) {
+        Osal_printf("IPC: device init failed");
         return(-1);
     }
 
@@ -486,12 +1178,12 @@ int init_devices(syslink_dev_t *dev)
 
 
 /* De-initialize the devices */
-int deinit_devices(syslink_dev_t *dev)
+int deinit_devices(ipc_dev_t *dev)
 {
     int status = EOK;
 
-    if ((status = deinit_syslink_device(dev)) < 0) {
-        fprintf( stderr, "syslink: syslink device de-init failed %d\n", status);
+    if ((status = deinit_ipc_device(dev)) < 0) {
+        fprintf( stderr, "IPC: device de-init failed %d\n", status);
         status = errno;
     }
 
@@ -500,21 +1192,30 @@ int deinit_devices(syslink_dev_t *dev)
 
 static void ipc_recover(Ptr args)
 {
-    syslink_dev_t * dev = (syslink_dev_t *)args;
-
-    deinit_ipc(dev, TRUE);
-    init_ipc(dev, syslink_firmware, TRUE);
-    deinit_syslink_trace_device(dev);
-    init_syslink_trace_device(dev);
+    ipc_dev_t * dev = (ipc_dev_t *)args;
+
+    if (!disableRecovery) {
+        /* Protect the ipc_firmware array as we recover */
+        pthread_mutex_lock(&dev->firmwareLock);
+        deinit_ipc(dev, ipc_firmware, TRUE);
+        deinit_ipc_trace_device(dev);
+        init_ipc(dev, ipc_firmware, TRUE);
+        init_ipc_trace_device(dev);
+        pthread_mutex_unlock(&dev->firmwareLock);
+    }
+    else {
+        GT_0trace(curTrace, GT_4CLASS,
+                  "ipc_recover: Recovery disabled.\n");
+    }
 }
 
-Int syslink_error_cb (UInt16 procId, ProcMgr_Handle handle,
+Int ipc_error_cb (UInt16 procId, ProcMgr_Handle handle,
                       ProcMgr_State fromState, ProcMgr_State toState,
                       ProcMgr_EventStatus status, Ptr args)
 {
     Int ret = 0;
     String errString = NULL;
-    syslink_dev_t * dev = (syslink_dev_t *)args;
+    ipc_dev_t * dev = (ipc_dev_t *)args;
 
     if (status == ProcMgr_EventStatus_Event) {
         switch (toState) {
@@ -533,7 +1234,7 @@ Int syslink_error_cb (UInt16 procId, ProcMgr_Handle handle,
                 break;
         }
         GT_2trace (curTrace, GT_4CLASS,
-                   "syslink_error_cb: Received Error Callback for %s : %s\n",
+                   "ipc_error_cb: Received Error Callback for %s : %s\n",
                    MultiProc_getName(procId), errString);
         /* Don't allow re-schedule of recovery until complete */
         pthread_mutex_lock(&dev->lock);
@@ -542,120 +1243,44 @@ Int syslink_error_cb (UInt16 procId, ProcMgr_Handle handle,
             dev->recover = TRUE;
             /* Activate a thread to handle the recovery. */
             GT_0trace (curTrace, GT_4CLASS,
-                       "syslink_error_cb: Scheduling recovery...");
+                       "ipc_error_cb: Scheduling recovery...");
             OsalThread_activate(dev->ipc_recovery_work);
         }
         else {
             GT_0trace (curTrace, GT_4CLASS,
-                       "syslink_error_cb: Recovery already scheduled.");
+                       "ipc_error_cb: Recovery already scheduled.");
         }
         pthread_mutex_unlock(&dev->lock);
     }
     else if (status == ProcMgr_EventStatus_Canceled) {
         GT_1trace (curTrace, GT_3CLASS,
-                   "SysLink Error Callback Cancelled for %s",
+                   "Ipc Error Callback Cancelled for %s",
                    MultiProc_getName(procId));
     }
     else {
         GT_1trace (curTrace, GT_4CLASS,
-                   "SysLink Error Callback Unexpected Event for %s",
+                   "Ipc Error Callback Unexpected Event for %s",
                    MultiProc_getName(procId));
     }
 
     return ret;
 }
 
-#if defined(SYSLINK_PLATFORM_OMAP4430)
-#define SYSLINK_CARVEOUT
-#ifdef SYSLINK_CARVEOUT
-#define IPU_MEM_SIZE  49 * 1024 * 1024
-#define IPU_MEM_PHYS  0x97F00000
-#else
-#define IPU_MEM_SIZE  104 * 1024 * 1024
-#define IPU_MEM_ALIGN 0x1000000
-#endif
-#endif
-
-
 /*
- * Initialize the syslink ipc
+ * Initialize ipc
  *
  * This function sets up the "kernel"-side IPC modules, and does any special
  * initialization required for QNX and the platform being used.  This function
  * also registers for error notifications and initializes the recovery thread.
  */
-int init_ipc(syslink_dev_t * dev, syslink_firmware_info * firmware, bool recover)
+int init_ipc(ipc_dev_t * dev, ipc_firmware_info * firmware, bool recover)
 {
     int status = 0;
-#if defined(SYSLINK_PLATFORM_OMAP4430)
-    int32_t ret = 0;
-    uint32_t len = 0;
-#ifndef SYSLINK_CARVEOUT
-    int64_t pa = 0;
-    void * da;
-#endif
-    int64_t paddr = 0;
-#endif
     Ipc_Config iCfg;
     OsalThread_Params threadParams;
-    ProcMgr_AttachParams attachParams;
     UInt16 procId;
     int i;
 
-#if defined(SYSLINK_PLATFORM_OMAP4430)
-    /* Map a contiguous memory section for ipu - currently hard-coded */
-    if (!recover) {
-#ifdef SYSLINK_CARVEOUT
-        dev->da_virt = mmap64(NULL, IPU_MEM_SIZE,
-                              PROT_NOCACHE | PROT_READ | PROT_WRITE,
-                              MAP_PHYS,
-                              NOFD,
-                              IPU_MEM_PHYS);
-#else
-        dev->da_virt = mmap64(NULL, IPU_MEM_SIZE + IPU_MEM_ALIGN,
-                              PROT_NOCACHE | PROT_READ | PROT_WRITE,
-                              MAP_ANON | MAP_PHYS | MAP_SHARED,
-                              NOFD,
-                              0);
-
-#endif
-
-        if (dev->da_virt == MAP_FAILED) {
-            status = ENOMEM;
-            goto exit;
-        }
-    }
-
-    if (status >= 0) {
-#ifdef SYSLINK_CARVEOUT
-        /* Make sure the memory is contiguous */
-        ret = mem_offset64(dev->da_virt, NOFD, IPU_MEM_SIZE, &paddr, &len);
-        if (ret)
-            status = ret;
-        else if (len != IPU_MEM_SIZE)
-            status = ENOMEM;
-#else
-        /* Make sure the memory is contiguous */
-        ret = mem_offset64(dev->da_virt, NOFD, IPU_MEM_SIZE + IPU_MEM_ALIGN,
-                           &paddr, &len);
-        if (ret)
-            status = ret;
-        else if (len != IPU_MEM_SIZE + IPU_MEM_ALIGN)
-            status = ENOMEM;
-        else {
-            pa = (paddr + IPU_MEM_ALIGN - 1) / IPU_MEM_ALIGN * IPU_MEM_ALIGN;
-            if ((pa - paddr) < 0x900000)
-                pa += 0x900000;
-            else
-                pa -= 0x700000;
-            da = dev->da_virt + (pa - paddr);
-        }
-#endif
-        if (status != 0)
-            goto memoryos_fail;
-    }
-#endif
-
     if (status >= 0) {
         if (!recover) {
             /* Set up the MemoryOS module */
@@ -665,15 +1290,6 @@ int init_ipc(syslink_dev_t * dev, syslink_firmware_info * firmware, bool recover
         }
 
         /* Setup IPC and platform-specific items */
-#if defined(SYSLINK_PLATFORM_OMAP4430)
-#ifdef SYSLINK_CARVEOUT
-        iCfg.vAddr = (uint32_t)dev->da_virt;
-        iCfg.pAddr = (uint32_t)paddr;
-#else
-        iCfg.vAddr = (uint32_t)da;
-        iCfg.pAddr = (uint32_t)pa;
-#endif
-#endif
         status = Ipc_setup (&iCfg);
         if (status < 0)
             goto ipcsetup_fail;
@@ -698,7 +1314,9 @@ int init_ipc(syslink_dev_t * dev, syslink_firmware_info * firmware, bool recover
             pthread_mutex_unlock(&dev->lock);
         }
 
-        for (i = 0; i < syslink_num_cores; i++) {
+        memset(procH_fileId, 0, sizeof(procH_fileId));
+
+        for (i = 0; i < ipc_num_cores; i++) {
             procId = firmware[i].proc_id = MultiProc_getId(firmware[i].proc);
             if (procId >= MultiProc_MAXPROCESSORS) {
                 status = -1;
@@ -715,86 +1333,33 @@ int init_ipc(syslink_dev_t * dev, syslink_firmware_info * firmware, bool recover
                 break;
             }
 
-            if (syslink_firmware[i].firmware) {
-                rscHandle[procId] = RscTable_alloc(firmware[i].firmware, procId);
-                if (rscHandle[procId] == NULL) {
-                    status = -1;
-                    break;
-                }
-            }
-
-            status = ProcMgr_open(&procH[procId], procId);
-            if (status < 0 || procH[procId] == NULL)
-                goto procmgropen_fail;
-
-            /* Load and start the remote processor. */
-            ProcMgr_getAttachParams (procH[procId], &attachParams);
-            status = ProcMgr_attach (procH[procId], &attachParams);
-            if (status < 0) {
-                GT_setFailureReason (curTrace,
-                                     GT_4CLASS,
-                                     "init_ipc",
-                                     status,
-                                     "ProcMgr_attach failed!");
-                goto procmgrattach_fail;
+            if (recover) {
+                /*
+                 * if we are in recovery, we load the cores we previously
+                 * attached to
+                 */
+                firmware[i].attachOnly = false;
             }
 
-            if (syslink_firmware[i].firmware) {
-                status = ProcMgr_load (procH[procId],
-                                       (String)firmware[i].firmware, 0, NULL,
-                                        NULL, &procH_fileId[procId]);
-                if (status < 0) {
-                    GT_setFailureReason (curTrace,
-                                         GT_4CLASS,
-                                         "init_ipc",
-                                         status,
-                                         "ProcMgr_load failed!");
-                    goto procmgrload_fail;
+            if ((!recover) || (firmware[i].reload)) {
+                status = runSlave(dev, procId, &firmware[i]);
+                if (status == 0) {
+                    firmware[i].procState = RUNNING_STATE;
+                    continue;
+                }
+                else {
+                    fprintf(stderr, "Failed to run core %s\n",
+                        MultiProc_getName(procId));
+                    break;
                 }
             }
-
-            status = Ipc_attach (procId);
-            if (status < 0) {
-                GT_setFailureReason (curTrace,
-                                     GT_4CLASS,
-                                     "init_ipc",
-                                     status,
-                                     "Ipc_attach failed!");
-                goto ipcattach_fail;
-            }
-
-            status = ProcMgr_start(procH[procId], NULL);
-            if (status < 0) {
-                GT_setFailureReason (curTrace,
-                                     GT_4CLASS,
-                                     "init_ipc",
-                                     status,
-                                     "ProcMgr_start failed!");
-                goto procmgrstart_fail;
+            else {
+                /*
+                 * During recovery, do not run cores unless they were previously
+                 * running
+                 */
+                continue;
             }
-
-            status = ProcMgr_registerNotify(procH[procId], syslink_error_cb, (Ptr)dev,
-                                            -1, errStates);
-            if (status < 0)
-                goto procmgrreg_fail;
-
-            continue;
-
-procmgrreg_fail:
-            ProcMgr_stop(procH[procId]);
-procmgrstart_fail:
-            Ipc_detach(procId);
-ipcattach_fail:
-            if (syslink_firmware[i].firmware)
-                ProcMgr_unload(procH[procId], procH_fileId[procId]);
-procmgrload_fail:
-            ProcMgr_detach(procH[procId]);
-procmgrattach_fail:
-            ProcMgr_close(&procH[procId]);
-            procH[procId] = NULL;
-procmgropen_fail:
-            RscTable_free(&rscHandle[procId]);
-            break;
         }
 
         if (status < 0)
@@ -810,8 +1375,10 @@ procmgropen_fail:
         if (status < 0)
             goto rpcsetup_fail;
 
-#if defined(SYSLINK_PLATFORM_VAYU)
+#if defined(IPC_PLATFORM_VAYU)
         if (gatempEnabled) {
+            Int32 sr0ProcId;
+
             /* Set up NameServer for resource manager process */
             status = NameServer_setup();
             if (status < 0) {
@@ -819,17 +1386,27 @@ procmgropen_fail:
             }
 
             /* Set up GateMP */
-            status = GateMP_setup();
-            if (status < 0) {
+            status = GateMP_setup(&sr0ProcId);
+            if ((status < 0) && (status != GateMP_E_NOTFOUND)) {
                 goto gatempsetup_fail;
             }
+            else if (status == 0) {
+                sr0OwnerProcId = sr0ProcId;
+            }
+            else {
+                /*
+                 * If we did not find the default gate, perhaps SR0 is
+                 * not yet loaded. This is ok.
+                 */
+                status = 0;
+            }
         }
 #endif
 
         goto exit;
     }
 
-#if defined(SYSLINK_PLATFORM_VAYU)
+#if defined(IPC_PLATFORM_VAYU)
 gatempsetup_fail:
     NameServer_destroy();
 nameserversetup_fail:
@@ -843,12 +1420,14 @@ tiipcsetup_fail:
         if (procId >= MultiProc_MAXPROCESSORS) {
             continue;
         }
-        ProcMgr_unregisterNotify(procH[procId], syslink_error_cb,
+        ProcMgr_unregisterNotify(procH[procId], ipc_error_cb,
                                 (Ptr)dev, errStates);
-        ProcMgr_stop(procH[procId]);
-        if (procH_fileId[procId]) {
-            ProcMgr_unload(procH[procId], procH_fileId[procId]);
-            procH_fileId[procId] = 0;
+        if (!firmware[i].attachOnly) {
+            ProcMgr_stop(procH[procId]);
+            if (procH_fileId[procId]) {
+                ProcMgr_unload(procH[procId], procH_fileId[procId]);
+                procH_fileId[procId] = 0;
+            }
         }
         ProcMgr_detach(procH[procId]);
         ProcMgr_close(&procH[procId]);
@@ -862,34 +1441,31 @@ osalthreadcreate_fail:
 ipcsetup_fail:
     MemoryOS_destroy();
 memoryos_fail:
-#if defined(SYSLINK_PLATFORM_OMAP4430)
-    if (dev->da_virt != MAP_FAILED)
-#ifdef SYSLINK_CARVEOUT
-        munmap(dev->da_virt, IPU_MEM_SIZE);
-#else
-        munmap(dev->da_virt, IPU_MEM_SIZE + IPU_MEM_ALIGN);
-#endif
-#endif
 exit:
     return status;
 }
 
-int deinit_ipc(syslink_dev_t * dev, bool recover)
+int deinit_ipc(ipc_dev_t * dev, ipc_firmware_info * firmware,
+    bool recover)
 {
     int status = EOK;
     uint32_t i = 0, id = 0;
 
+    if (logFilename) {
+        /* wait a little bit for traces to finish dumping */
+        sleep(1);
+    }
+
     // Stop the remote cores right away
     for (i = 0; i < MultiProc_MAXPROCESSORS; i++) {
         if (procH[i]) {
-            GT_1trace(curTrace, GT_4CLASS, "stopping %s", MultiProc_getName(i));
-            ProcMgr_stop(procH[i]);
+            resetSlave(dev, i);
         }
     }
 
-#if defined(SYSLINK_PLATFORM_VAYU)
+#if defined(IPC_PLATFORM_VAYU)
     if (gatempEnabled) {
-        GateMP_destroy();
+        GateMP_destroy(TRUE);
 
         NameServer_destroy();
     }
@@ -899,64 +1475,55 @@ int deinit_ipc(syslink_dev_t * dev, bool recover)
 
     ti_ipc_destroy(recover);
 
-    for (i = 0; i < MultiProc_MAXPROCESSORS; i++) {
-        if (procH[i]) {
-            ProcMgr_unregisterNotify (procH[i], syslink_error_cb, (Ptr)dev,
-                                      errStates);
-            Ipc_detach(i);
-            if (procH_fileId[i]) {
-                ProcMgr_unload(procH[i], procH_fileId[i]);
-                procH_fileId[i] = 0;
-            }
-            ProcMgr_detach(procH[i]);
-            ProcMgr_close(&procH[i]);
-            procH[i] = NULL;
-            RscTable_free(&rscHandle[i]);
-            rscHandle[i] = NULL;
-        }
-    }
-
     if (!recover && dev->ipc_recovery_work != NULL) {
         OsalThread_delete (&dev->ipc_recovery_work);
         dev->ipc_recovery_work = NULL;
     }
 
     if (recover) {
-        static FILE *log;
-        /* Dump the trace information */
-        Osal_printf("syslink: printing remote core trace dump to"
-                    " /var/log/ducati-m3-traces.log");
-        log = fopen ("/var/log/ducati-m3-traces.log", "a+");
-        if (log) {
-            for (id = 0; id < syslink_num_cores; id++) {
-                if (proc_traces[id].va) {
-                    /* print traces */
-                    /* wait a little bit for traces to finish dumping */
-                    sleep(1);
-                    fprintf(log, "****************************************\n");
-                    fprintf(log, "***         CORE%d TRACE DUMP         ***\n",
-                            id);
-                    fprintf(log, "****************************************\n");
-                    for (i = (*proc_traces[id].widx + 1);
-                         i < (proc_traces[id].len - 8);
-                         i++) {
-                        fprintf(log, "%c",
-                                *(char *)((uint32_t)proc_traces[id].va + i));
-                    }
-                    for (i = 0; i < *proc_traces[id].widx; i++) {
-                        fprintf(log, "%c",
-                                *(char *)((uint32_t)proc_traces[id].va + i));
+        static FILE *log = NULL;
+        if (logFilename) {
+            /* Dump the trace information */
+            Osal_printf("IPC: printing remote core trace dump");
+            log = fopen(logFilename, "a+");
+            if (log) {
+                for (id = 0; id < ipc_num_cores; id++) {
+                    if (firmware[id].procState == RUNNING_STATE) {
+                        if (proc_traces[id].va) {
+                            /* print traces */
+                            fprintf(log, "*************************************\n");
+                            fprintf(log, "***       CORE%d TRACE DUMP        ***\n",
+                                firmware[i].proc_id);
+                            fprintf(log, "*************************************\n");
+                            for (i = (*proc_traces[id].widx + 1);
+                                i < (proc_traces[id].len - 8);
+                                i++) {
+                                fprintf(log, "%c",
+                                    *(char *)((uint32_t)proc_traces[id].va + i));
+                            }
+                            for (i = 0; i < *proc_traces[id].widx; i++) {
+                                fprintf(log, "%c",
+                                    *(char *)((uint32_t)proc_traces[id].va + i));
+                            }
+                        }
                     }
                 }
+                fflush(log);
+                fclose(log);
+            }
+            else {
+                fprintf(stderr, "\nERROR: unable to open crash dump file %s\n",
+                    logFilename);
+                exit(EXIT_FAILURE);
             }
-            fclose(log);
-        }
-        else {
-            GT_setFailureReason(curTrace, GT_4CLASS, "deinit_ipc", errno,
-                                "error opening /var/log/ducati-m3-traces.log");
         }
     }
 
+    /* After printing trace, set all processor states to RESET */
+    for (id = 0; id < ipc_num_cores; id++) {
+        firmware[id].procState = RESET_STATE;
+    }
+
     status = Ipc_destroy();
     if (status < 0) {
         printf("Ipc_destroy() failed 0x%x", status);
@@ -966,251 +1533,76 @@ int deinit_ipc(syslink_dev_t * dev, bool recover)
         if (status < 0) {
             printf("MemoryOS_destroy() failed 0x%x", status);
         }
-#if defined(SYSLINK_PLATFORM_OMAP4430)
-        if (dev->da_virt != MAP_FAILED) {
-#ifdef SYSLINK_CARVEOUT
-            status = munmap(dev->da_virt, IPU_MEM_SIZE);
-#else
-            status = munmap(dev->da_virt, IPU_MEM_SIZE + IPU_MEM_ALIGN);
-#endif
-            if (status < 0) {
-               printf("munmap failed %d", errno);
-            }
-        }
-#endif
     }
 
     return status;
 }
 
 
-/* Read next line of available data for given 'core' and store it in buffer.
- * Returns the number of bytes that were written or -1 on error
- */
-static int readNextTrace(int core, char* buffer, int bufSize)
-{
-    char* readPtr;
-    uint32_t readBytes, ridx, widx;
-    syslink_trace_info* tinfo = &proc_traces[core];
-
-    /* Make sure it is valid */
-    if ( (tinfo == NULL) || (tinfo->va == NULL) ) {
-        return -1;
-    }
-
-    /* Check to see if something to read */
-    if (tinfo->ridx == tinfo->widx) {
-        return 0;
-    }
-
-    readPtr = (char*) tinfo->va;
-    ridx = *tinfo->ridx;
-    widx = *tinfo->widx;
-
-    /* If first read, make sure that core is ready by validating ridx, widx */
-    if ( (tinfo->firstRead == TRUE) && ((ridx != 0) || (widx >= tinfo->len)) ) {
-        // not ready - will try again later
-        return 0;
-    }
-
-    /* Sanity check ridx/widx to make sure they point inside the buffer */
-    if ( (ridx >= tinfo->len) || (widx >= tinfo->len) ) {
-        Osal_printf("C%d: widx=%d, ridx=%d, len=%d - out of range",
-            core, widx, ridx, tinfo->len);
-        return -1;
-    }
-
-    readBytes = 0;
-    tinfo->firstRead = FALSE;
-    /* Read until we hit newline indicating end of trace */
-    while ( (readPtr[ridx] != '\n') && (ridx != widx) && (readBytes < bufSize)) {
-        buffer[readBytes] = readPtr[ridx];
-        readBytes++;
-        ridx++;
-        // Check for wrap-around
-        if (ridx == tinfo->len) {
-            ridx = 0;
-        }
-    }
-
-    /* If did not find newline, abort since either not enough info or no room in buffer */
-    if (readPtr[ridx] != '\n') {
-        if (readBytes >= bufSize) {
-            Osal_printf("C%d: Insufficient size of buffer; read %d, buf %d",
-                core, readBytes, bufSize);
-            return -1;
-        }
-        return 0;
-    }
-
-    /* Newline may not be valid data if this was not ready to be read */
-    if (ridx == widx) {
-        return 0;
-    }
-
-    /* We read a full line - null terminate and update ridx to mark data read */
-    if (readBytes < bufSize) {
-        buffer[readBytes] = '\0';
-    } else {
-        Osal_printf("C%d: No room to write NULL character", core);
-        return -1;
-    }
-    readBytes++;
-    ridx++;
-    if (ridx == tinfo->len) {
-        ridx = 0;
-    }
-    *tinfo->ridx = ridx;
-
-    return readBytes;
-}
-
-/* Thread reading ducati traces and writing them out to slog2 */
-static void *ducatiTraceThread(void *parm)
-{
-    int32_t bytesRead;
-    int core;
-    int err;
-    Bool exit = FALSE;
-
-    pthread_setname_np(0, "ducati-trace");
-
-    pthread_mutex_lock(&trace_mutex);
-    while ( (trace_active == TRUE) && (exit == FALSE) ) {
-        for (core = 0; core < MultiProc_MAXPROCESSORS; core++) {
-            while ((bytesRead = readNextTrace(core, trace_buffer, TRACE_BUFFER_SIZE)) > 0) {
-#if (_NTO_VERSION >= 800)
-                slog2f(buffer_handle, 0, 0, "C%d:%s", core, trace_buffer);
-#else
-                slogf(42, _SLOG_NOTICE, "C%d:%s", core, trace_buffer);
-#endif
-                if (trace_active == FALSE) {
-                    break;
-                }
-            }
-            // Abort trace logger on errors as these should not occur
-            if (bytesRead < 0) {
-                trace_active = FALSE;
-            }
-            if (trace_active == FALSE) {
-                break;
-            }
-        }
-        if (trace_active == FALSE) {
-            continue;
-        }
-        pthread_mutex_unlock(&trace_mutex);
-
-        // No interrupts/events to trigger reading traces, so need to periodically poll
-        usleep(TRACE_POLLING_INTERVAL_US);
-
-        // If we are in hibernation, wait on condvar for end of hibernation
-        pthread_mutex_lock(&syslink_hib_mutex);
-        while ((syslink_hib_enable == TRUE) && (syslink_hib_hibernating == TRUE) ) {
-            err = pthread_cond_wait(&syslink_hib_cond, &syslink_hib_mutex);
-            if (err != EOK) {
-                Osal_printf("pthread_cond_wait failed with err=%d", err);
-                exit = TRUE;
-                break;
-            }
-        }
-        pthread_mutex_unlock(&syslink_hib_mutex);
-
-        pthread_mutex_lock(&trace_mutex);
-    }
-    pthread_mutex_unlock(&trace_mutex);
-    Osal_printf("ducati trace thread exited");
-    return NULL;
-}
-
-/* Initialize slog2 for Ducati traces */
-static int init_ducati_slog2(void)
-{
-#if (_NTO_VERSION >= 800)
-    slog2_buffer_set_config_t buffer_config;
-    const char * buffer_set_name = "ducati";
-    const char * buffer_name = "ducati_buffer";
-
-    // Use command line verbosity for default verbosity level
-    uint8_t verbosity_level = (uint8_t) verbosity;
-    if ( verbosity_level > SLOG2_DEBUG2) {
-        verbosity_level = SLOG2_DEBUG2;
-    }
-
-    // Initialize the buffer configuration
-    buffer_config.buffer_set_name = (char *) buffer_set_name;
-    buffer_config.num_buffers = 1;
-    buffer_config.verbosity_level = verbosity_level;
-    buffer_config.buffer_config[0].buffer_name = (char *) buffer_name;
-    buffer_config.buffer_config[0].num_pages = 8;
-
-    // Register the Buffer Set
-    if( slog2_register( &buffer_config, &buffer_handle, 0 ) == -1 ) {
-        Osal_printf("syslink error registering slogger2 buffer for Ducati!");
-        return -1;
-    }
-#endif
-
-    return 0;
-}
-
 /** print usage */
 static Void printUsage (Char * app)
 {
     printf("\n\nUsage:\n");
-#if defined(SYSLINK_PLATFORM_OMAP5430)
-    printf("\n%s: [-HT] <core_id1> <executable1> [<core_id2> <executable2> ...]\n",
+#if defined(IPC_PLATFORM_OMAP5430)
+    printf("\n%s: [-HTdca] <core_id1> <executable1> [<core_id2> <executable2> ...]\n",
         app);
     printf("  <core_id#> should be set to a core name (e.g. IPU, DSP)\n");
     printf("      followed by the path to the executable to load on that core.\n");
     printf("Options:\n");
-    printf("  -H   enable/disable hibernation, 1: ON, 0: OFF, Default: 1)\n");
-    printf("  -T   specify the hibernation timeout in ms, Default: 5000 ms)\n");
+    printf("  -H <arg>    enable/disable hibernation, 1: ON, 0: OFF,"
+        " Default: 1)\n");
+    printf("  -T <arg>    specify the hibernation timeout in ms, Default:"
+        " 5000 ms)\n");
 #else
-    printf("\n%s: [-g] <core_id1> <executable1> [<core_id2> <executable2> ...]\n",
+    printf("\n%s: [-gdca] <core_id1> <executable1> [<core_id2> <executable2> ...]\n",
         app);
-    printf("  <core_id#> should be set to a core name (e.g. DSP1, IPU2)\n");
+    printf("  <core_id#> should be set to a core name (e.g. DSP1, DSP2, IPU1, IPU2)\n");
     printf("      followed by the path to the executable to load on that core.\n");
     printf("Options:\n");
     printf("  -g   enable GateMP support on host\n");
 #endif
+    printf("  -d   disable recovery\n");
+    printf("  -c <file>   generate dump of slave trace during crashes (use\n");
+    printf("              absolute path for filename)\n");
+    printf("  -a<n> specify that the first n cores have been pre-loaded\n");
+    printf("        and started. Perform late-attach to these cores.\n");
+
     exit (EXIT_SUCCESS);
 }
 
-dispatch_t * syslink_dpp = NULL;
+dispatch_t * ipc_dpp = NULL;
 
 int main(int argc, char *argv[])
 {
-    syslink_dev_t * dev = NULL;
+    ipc_dev_t * dev = NULL;
     thread_pool_attr_t tattr;
     int status;
-    int error = 0;
+    int error = EOK;
     sigset_t set;
     int channelid = 0;
     int c;
     int hib_enable = 1;
     uint32_t hib_timeout = PM_HIB_DEFAULT_TIME;
-    char *user_parm = NULL;
     struct stat          sbuf;
     int i = 0;
     char * abs_path = NULL;
 
     if (-1 != stat(IPC_DEVICE_PATH, &sbuf)) {
-        printf ("Syslink Already Running...\n");
+        printf ("IPC Already Running...\n");
         return EXIT_FAILURE;
     }
-    printf ("Starting syslink resource manager...\n");
+    printf ("Starting IPC resource manager...\n");
 
     /* Parse the input args */
     while (1)
     {
-        c = getopt (argc, argv, "H:T:U:gv:");
+        c = getopt (argc, argv, "H:T:gc:dv:a:");
         if (c == -1)
             break;
 
         switch (c)
         {
-#if defined(SYSLINK_PLATFORM_OMAP5430)
+#if defined(IPC_PLATFORM_OMAP5430)
         case 'H':
             hib_enable = atoi(optarg);
             if (hib_enable != 0 && hib_enable != 1) {
@@ -1221,13 +1613,20 @@ int main(int argc, char *argv[])
             hib_timeout = atoi(optarg);
             break;
 #endif
-        case 'U':
-            user_parm = optarg;
+        case 'd':
+            disableRecovery = true;
+            break;
+        case 'c':
+            logFilename = optarg;
+            break;
+        case 'a':
+            numAttach = atoi(optarg);
+            printf("Late-attaching to %d core(s)\n", numAttach);
             break;
         case 'v':
             verbosity++;
             break;
-#if defined(SYSLINK_PLATFORM_VAYU)
+#if defined(IPC_PLATFORM_VAYU)
         case 'g':
             printf("GateMP support enabled on host\n");
             gatempEnabled = true;
@@ -1241,21 +1640,17 @@ int main(int argc, char *argv[])
     /* Now parse the operands, which should be in the format:
      * "<multiproc_name> <firmware_file> ..*/
     for (; optind + 1 < argc; optind+=2) {
-        if (syslink_num_cores == MultiProc_MAXPROCESSORS) {
+        if (ipc_num_cores == MultiProc_MAXPROCESSORS) {
             printUsage(argv[0]);
             return (error);
         }
-        syslink_firmware[syslink_num_cores].proc = argv [optind];
-        syslink_firmware[syslink_num_cores++].firmware = argv [optind+1];
-    }
 
-
-    /* Get the name of the binary from the input args */
-    if (!syslink_num_cores) {
-        fprintf(stderr, "At least one core_id and executable must be "\
-            "specified");
-        printUsage(argv[0]);
-        return (error);
+        ipc_firmware[ipc_num_cores].proc = argv [optind];
+        ipc_firmware[ipc_num_cores].attachOnly =
+            ((numAttach-- > 0) ? true : false);
+        ipc_firmware[ipc_num_cores].reload = true;
+        ipc_firmware[ipc_num_cores].freeString = false;
+        ipc_firmware[ipc_num_cores++].firmware = argv [optind+1];
     }
 
     /* Validate hib_enable args */
@@ -1265,10 +1660,10 @@ int main(int argc, char *argv[])
         return (error);
     }
 
-    syslink_hib_enable = (Bool)hib_enable;
-    syslink_hib_timeout = hib_timeout;
+    ipc_hib_enable = (Bool)hib_enable;
+    ipc_hib_timeout = hib_timeout;
 
-    /* Init logging for syslink */
+    /* Init logging for ipc */
     if (Osal_initlogging(verbosity) != 0) {
         return -1;
     }
@@ -1281,21 +1676,21 @@ int main(int argc, char *argv[])
     }
 
     /* Get the abs path for all firmware files */
-    for (i = 0; i < syslink_num_cores; i++) {
+    for (i = 0; i < ipc_num_cores; i++) {
         abs_path = calloc(1, PATH_MAX + 1);
         if (abs_path == NULL) {
             return -1;
         }
-        if (NULL == realpath(syslink_firmware[i].firmware, abs_path)) {
+        if (NULL == realpath(ipc_firmware[i].firmware, abs_path)) {
             fprintf (stderr, "invalid path to executable\n");
             return -1;
         }
-        syslink_firmware[i].firmware = abs_path;
+        ipc_firmware[i].firmware = abs_path;
     }
 
     /* allocate the device structure */
-    if (NULL == (dev = calloc(1, sizeof(syslink_dev_t)))) {
-        Osal_printf("syslink: calloc() failed");
+    if (NULL == (dev = calloc(1, sizeof(ipc_dev_t)))) {
+        Osal_printf("IPC: calloc() failed");
         return (-1);
     }
 
@@ -1310,8 +1705,8 @@ int main(int argc, char *argv[])
     }
 
     /* create the dispatch structure */
-    if (NULL == (dev->dpp = syslink_dpp = dispatch_create_channel (channelid, 0))) {
-        Osal_printf("syslink:  dispatch_create() failed");
+    if (NULL == (dev->dpp = ipc_dpp = dispatch_create_channel (channelid, 0))) {
+        Osal_printf("IPC: dispatch_create() failed");
         return(-1);
     }
 
@@ -1338,80 +1733,34 @@ int main(int argc, char *argv[])
 
     /* Create the thread pool */
     if ((dev->tpool = thread_pool_create(&tattr, 0)) == NULL) {
-        Osal_printf("syslink: thread pool create failed");
+        Osal_printf("IPC: thread pool create failed");
         return(-1);
     }
 
-    /* init syslink */
-    status = init_ipc(dev, syslink_firmware, FALSE);
+    /* init ipc */
+    status = init_ipc(dev, ipc_firmware, FALSE);
     if (status < 0) {
-        Osal_printf("syslink: IPC init failed");
+        Osal_printf("IPC: init failed");
         return(-1);
     }
 
-    /* init the syslink device */
+    /* init the ipc device */
     status = init_devices(dev);
     if (status < 0) {
-        Osal_printf("syslink: device init failed");
+        Osal_printf("IPC: device init failed");
         return(-1);
     }
 
-#if (_NTO_VERSION >= 800)
-    /* Relinquish privileges */
-    status = procmgr_ability(  0,
-                 DENY_ALL | PROCMGR_AID_SPAWN,
-                 DENY_ALL | PROCMGR_AID_FORK,
-                 PROCMGR_ADN_NONROOT | PROCMGR_AOP_ALLOW | PROCMGR_AID_MEM_PEER,
-                 PROCMGR_ADN_NONROOT | PROCMGR_AOP_ALLOW | PROCMGR_AID_MEM_PHYS,
-                 PROCMGR_ADN_NONROOT | PROCMGR_AOP_ALLOW | PROCMGR_AID_INTERRUPT,
-                 PROCMGR_ADN_NONROOT | PROCMGR_AOP_ALLOW | PROCMGR_AID_PATHSPACE,
-                 PROCMGR_ADN_NONROOT | PROCMGR_AOP_ALLOW | PROCMGR_AID_RSRCDBMGR,
-                 PROCMGR_ADN_ROOT | PROCMGR_AOP_ALLOW | PROCMGR_AOP_LOCK | PROCMGR_AOP_SUBRANGE | PROCMGR_AID_SETUID,
-                 (uint64_t)1, (uint64_t)~0,
-                 PROCMGR_ADN_ROOT | PROCMGR_AOP_ALLOW | PROCMGR_AOP_LOCK | PROCMGR_AOP_SUBRANGE | PROCMGR_AID_SETGID,
-                 (uint64_t)1, (uint64_t)~0,
-                 PROCMGR_ADN_ROOT | PROCMGR_AOP_DENY | PROCMGR_AOP_LOCK | PROCMGR_AID_EOL);
-
-    if (status != EOK) {
-        Osal_printf("procmgr_ability failed! errno=%d", status);
-        return EXIT_FAILURE;
-    }
-
-    /* Reduce priority to either what defined from command line or at least nobody */
-    if (user_parm != NULL) {
-        if (set_ids_from_arg(user_parm) < 0) {
-            Osal_printf("unable to set uid/gid - %s", strerror(errno));
-            return EXIT_FAILURE;
-        }
-    } else {
-        if (setuid(99) != 0) {
-            Osal_printf("unable to set uid - %s", strerror(errno));
-            return EXIT_FAILURE;
-        }
-    }
-#endif
-
     /* make this a daemon process */
     if (-1 == procmgr_daemon(EXIT_SUCCESS,
         PROCMGR_DAEMON_NOCLOSE | PROCMGR_DAEMON_NODEVNULL)) {
-        Osal_printf("syslink:  procmgr_daemon() failed");
+        Osal_printf("IPC: procmgr_daemon() failed");
         return(-1);
     }
 
     /* start the thread pool */
     thread_pool_start(dev->tpool);
 
-    /* Init slog2 and thread for Ducati traces */
-    if (init_ducati_slog2() != 0) {
-        return -1;
-    }
-    trace_active = TRUE;
-    status = pthread_create (&thread_traces, NULL, ducatiTraceThread, NULL);
-    if (status != EOK) {
-        Osal_printf("pthread_create for trace thread failed err=%d", status);
-        trace_active = FALSE;
-    }
-
     /* Unmask signals to be caught */
     sigdelset (&set, SIGINT);
     sigdelset (&set, SIGTERM);
@@ -1423,7 +1772,7 @@ int main(int argc, char *argv[])
     sigaddset (&set, SIGQUIT);
     sigaddset (&set, SIGTERM);
 
-    Osal_printf("Syslink resource manager started");
+    Osal_printf("IPC resource manager started");
 
     /* Wait for a signal */
     while (1)
@@ -1444,30 +1793,23 @@ int main(int argc, char *argv[])
     error = EOK;
 
 done:
-    GT_0trace(curTrace, GT_4CLASS, "Syslink resource manager exiting \n");
-    /* Stop ducatiTraceThread if running */
-    pthread_mutex_lock(&trace_mutex);
-    if (trace_active) {
-        trace_active = FALSE;
-        pthread_mutex_unlock(&trace_mutex);
-        // Wake up if waiting on hibernation
-        pthread_mutex_lock(&syslink_hib_mutex);
-        syslink_hib_hibernating = FALSE;
-        pthread_cond_broadcast(&syslink_hib_cond);
-        pthread_mutex_unlock(&syslink_hib_mutex);
-        error = pthread_join(thread_traces, NULL);
-        if (error < 0) {
-            Osal_printf("syslink: pthread_join failed with err=%d", error);
-        }
-    } else {
-        pthread_mutex_unlock(&trace_mutex);
-    }
+    GT_0trace(curTrace, GT_4CLASS, "IPC resource manager exiting \n");
 
     error = thread_pool_destroy(dev->tpool);
-    if (error < 0)
-        Osal_printf("syslink: thread_pool_destroy returned an error");
-    deinit_ipc(dev, FALSE);
+    if (error < 0) {
+        Osal_printf("IPC: thread_pool_destroy returned an error");
+    }
+    deinit_ipc(dev, ipc_firmware, FALSE);
     deinit_devices(dev);
     free(dev);
-    return (EOK);
+
+    /* Free the abs path of firmware files if necessary */
+    for (i = 0; i < ipc_num_cores; i++) {
+        if ((ipc_firmware[i].freeString) &&
+            (ipc_firmware[i].firmware)) {
+            free(ipc_firmware[i].firmware);
+        }
+    }
+
+    return (error);
 }