diff --git a/qnx/src/ipc3x_dev/ti/syslink/build/Qnx/resmgr/syslink_main.c b/qnx/src/ipc3x_dev/ti/syslink/build/Qnx/resmgr/syslink_main.c
index b2cfd0afcee93f67bddbb93691826bd1b01a959e..52f536657a676952bb6ee1d73086c853b3628413 100644 (file)
*
* ============================================================================
*
- * Copyright (c) 2011-2013, Texas Instruments Incorporated
+ * Copyright (c) 2011-2014, Texas Instruments Incorporated
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#include <sys/siginfo.h>
#include <signal.h>
#include <stdbool.h>
-#if defined(SYSLINK_PLATFORM_OMAP4430)
-#include <login.h>
-#endif
#include <IpcKnl.h>
#include <ti/syslink/utils/List.h>
#include <ti/syslink/utils/MemoryOS.h>
#include <ti/ipc/MultiProc.h>
+#include <ti/ipc/NameServer.h>
#include <_MultiProc.h>
+#include <_NameServer.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(SYSLINK_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;
+
+/* 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(SYSLINK_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)
+#if !defined(SYSLINK_PLATFORM_OMAP5430)
#define PM_HIB_DEFAULT_TIME 5000
#endif
uint32_t syslink_hib_timeout = PM_HIB_DEFAULT_TIME;
uint16_t proc_id;
char * proc;
char * firmware;
+ 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 */
} syslink_firmware_info;
static syslink_firmware_info syslink_firmware[MultiProc_MAXPROCESSORS];
+
+/* Number of valid entries in syslink_firmware array */
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);
+int init_ipc(syslink_dev_t * dev, syslink_firmware_info * firmware,
+ bool recover);
+int deinit_ipc(syslink_dev_t * dev, syslink_firmware_info * firmware,
+ bool recover);
+int init_syslink_trace_device(syslink_dev_t *dev);
+int deinit_syslink_trace_device(syslink_dev_t *dev);
+
+Int syslink_error_cb (UInt16 procId, ProcMgr_Handle handle,
+ ProcMgr_State fromState, ProcMgr_State toState,
+ ProcMgr_EventStatus status, Ptr args);
static RscTable_Handle rscHandle[MultiProc_MAXPROCESSORS];
ProcMgr_State_Watchdog,
ProcMgr_State_EndValue};
+/* Processor states */
+#define RESET_STATE 0
+#define RUNNING_STATE 1
+
+static String procStateNames[] = { "In reset",
+ "Running" };
+
typedef struct syslink_trace_info_t {
uintptr_t va;
uint32_t len;
static syslink_trace_info proc_traces[MultiProc_MAXPROCESSORS];
+static int runSlave(syslink_dev_t *dev, uint16_t procId,
+ syslink_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,
+ "init_ipc",
+ 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,
+ "init_ipc",
+ status,
+ "ProcMgr_load failed!");
+ goto procmgrload_fail;
+ }
+ }
+
+ status = Ipc_attach(procId);
+ if (status < 0) {
+ GT_setFailureReason(curTrace,
+ GT_4CLASS,
+ "init_ipc",
+ status,
+ "Ipc_attach failed!");
+ goto ipcattach_fail;
+ }
+
+ status = ProcMgr_registerNotify(procH[procId], syslink_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,
+ "init_ipc",
+ status,
+ "ProcMgr_start failed!");
+ goto procmgrstart_fail;
+ }
+ }
+
+ Osal_printf("runSlave successful for core %d\n", procId);
+
+ return 0;
+
+procmgrstart_fail:
+ ProcMgr_unregisterNotify(procH[procId], syslink_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(syslink_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], syslink_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;
+}
+
+static int slave_state_read(resmgr_context_t *ctp, io_read_t *msg,
+ syslink_ocb_t *ocb)
+{
+ int nbytes;
+ int nparts;
+ int status;
+ int nleft;
+ int i;
+ uint16_t procid = ocb->ocb.attr->procid;
+ syslink_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 < syslink_num_cores; i++) {
+ if (syslink_firmware[i].proc_id == procid) {
+ break;
+ }
+ }
+ if (i == syslink_num_cores) {
+ if ((syslink_num_cores < MultiProc_MAXPROCESSORS)) {
+ syslink_firmware[syslink_num_cores].proc =
+ MultiProc_getName(procid);
+ syslink_firmware[syslink_num_cores].proc_id = procid;
+ syslink_firmware[syslink_num_cores].attachOnly = false;
+ syslink_firmware[syslink_num_cores].reload = false;
+ syslink_firmware[syslink_num_cores].procState = RESET_STATE;
+ syslink_firmware[syslink_num_cores].freeString = false;
+ syslink_firmware[syslink_num_cores++].firmware = NULL;
+ }
+ else {
+ pthread_mutex_unlock(&dev->firmwareLock);
+ return (EBADSLT);
+ }
+ }
+
+ if (ocb->ocb.offset == 0) {
+ /* latch onto new state, so that we print out complete strings */
+ syslink_firmware[i].readProcState = syslink_firmware[i].procState;
+ }
+
+ nleft = strlen(procStateNames[syslink_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[syslink_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,
+ syslink_ocb_t *ocb)
+{
+ int status;
+ char * buf;
+ uint16_t procid = ocb->ocb.attr->procid;
+ int i;
+ char * ptr;
+ syslink_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 < syslink_num_cores; i++) {
+ if (syslink_firmware[i].proc_id == procid) {
+ break;
+ }
+ }
+ if (i == syslink_num_cores) {
+ if ((syslink_num_cores < MultiProc_MAXPROCESSORS)) {
+ syslink_firmware[syslink_num_cores].proc =
+ MultiProc_getName(procid);
+ syslink_firmware[syslink_num_cores].proc_id = procid;
+ syslink_firmware[syslink_num_cores].attachOnly = false;
+ syslink_firmware[syslink_num_cores].reload = false;
+ syslink_firmware[syslink_num_cores].procState = RESET_STATE;
+ syslink_firmware[syslink_num_cores].freeString = false;
+ syslink_firmware[syslink_num_cores++].firmware = NULL;
+ }
+ else {
+ pthread_mutex_unlock(&dev->firmwareLock);
+ return (EBADSLT);
+ }
+ }
+
+ if (strcmp("1", buf) == 0) {
+ if ((syslink_firmware[i].procState == RESET_STATE) &&
+ (syslink_firmware[i].firmware != NULL)) {
+ runSlave(ocb->ocb.attr->dev, procid, &syslink_firmware[i]);
+#if defined(SYSLINK_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);
+ 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",
+ syslink_firmware[i].firmware);
+ syslink_firmware[i].procState = RUNNING_STATE;
+ syslink_firmware[i].reload = true;
+ status = init_syslink_trace_device(dev);
+ if (status < 0) {
+ pthread_mutex_unlock(&dev->firmwareLock);
+ free(buf);
+ return (EIO);
+ }
+ printf("Core %s has been started.\n", MultiProc_getName(procid));
+ }
+ }
+ else if (strcmp("0", buf) == 0) {
+ if (syslink_firmware[i].procState == RUNNING_STATE) {
+#if defined(SYSLINK_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
+ resetSlave(ocb->ocb.attr->dev, procid);
+ syslink_firmware[i].procState = RESET_STATE;
+ syslink_firmware[i].reload = false;
+ status = deinit_syslink_trace_device(dev);
+ if (status < 0) {
+ pthread_mutex_unlock(&dev->firmwareLock);
+ free(buf);
+ Osal_printf("IPC: deinit_syslink_trace_device failed %d",
+ 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,
+ syslink_ocb_t *ocb)
+{
+ int nbytes;
+ int nparts;
+ int status;
+ int nleft;
+ int i;
+ uint16_t procid = ocb->ocb.attr->procid;
+ syslink_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 < syslink_num_cores; i++) {
+ if (syslink_firmware[i].proc_id == procid) {
+ break;
+ }
+ }
+
+ if (i == syslink_num_cores) {
+ if ((syslink_num_cores < MultiProc_MAXPROCESSORS)) {
+ syslink_firmware[syslink_num_cores].proc =
+ MultiProc_getName(procid);
+ syslink_firmware[syslink_num_cores].proc_id = procid;
+ syslink_firmware[syslink_num_cores].attachOnly = false;
+ syslink_firmware[syslink_num_cores].reload = false;
+ syslink_firmware[syslink_num_cores].procState = RESET_STATE;
+ syslink_firmware[syslink_num_cores].freeString = false;
+ syslink_firmware[syslink_num_cores++].firmware = NULL;
+ }
+ else {
+ pthread_mutex_unlock(&dev->firmwareLock);
+ return (EBADSLT);
+ }
+ }
+
+ if (syslink_firmware[i].firmware == NULL) {
+ nbytes = 0;
+ }
+ else {
+ nleft = strlen(syslink_firmware[i].firmware)
+ - 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 *)syslink_firmware[i].firmware
+ + ocb->ocb.offset, nbytes);
+
+ /* set up the number of bytes (returned by client's read()) */
+ _IO_SET_READ_NBYTES(ctp, nbytes);
+
+ ocb->ocb.offset += nbytes;
+
+ nparts = 1;
+ }
+ 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,
+ syslink_ocb_t *ocb)
+{
+ int status;
+ char * buf;
+ uint16_t procid = ocb->ocb.attr->procid;
+ int i;
+ char * absPath;
+ char * ptr;
+ syslink_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 syslink_firmware already exists for this core.
+ * If not, create one. Otherwise just update the firmware path.
+ */
+ for (i = 0; i < syslink_num_cores; i++) {
+ if (syslink_firmware[i].proc_id == procid) {
+ break;
+ }
+ }
+ if (i == syslink_num_cores) {
+ if (syslink_num_cores < MultiProc_MAXPROCESSORS) {
+ syslink_firmware[syslink_num_cores].proc =
+ MultiProc_getName(procid);
+ syslink_firmware[syslink_num_cores].proc_id = procid;
+ syslink_firmware[syslink_num_cores].attachOnly = false;
+ syslink_firmware[syslink_num_cores].reload = false;
+ syslink_firmware[syslink_num_cores].procState = RESET_STATE;
+ syslink_firmware[syslink_num_cores].freeString = true;
+ syslink_firmware[syslink_num_cores++].firmware = absPath;
+ }
+ else {
+ pthread_mutex_unlock(&dev->firmwareLock);
+ free(absPath);
+ return (EBADSLT);
+ }
+ }
+ else {
+ /* Free previously allocated string */
+ if ((syslink_firmware[syslink_num_cores].freeString) &&
+ (syslink_firmware[syslink_num_cores].firmware)) {
+ free(syslink_firmware[i].firmware);
+ }
+ syslink_firmware[i].firmware = absPath;
+ }
+
+ pthread_mutex_unlock(&dev->firmwareLock);
+
+ if (msg->i.nbytes > 0) {
+ ocb->ocb.attr->attr.flags |= IOFUNC_ATTR_MTIME | IOFUNC_ATTR_CTIME;
+ }
+
+ return (_RESMGR_NPARTS(0));
+}
+
int syslink_read(resmgr_context_t *ctp, io_read_t *msg, syslink_ocb_t *ocb)
{
int nbytes;
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);
syslink_ocb_t * ocb = (syslink_ocb_t *)i_ocb;
if (ocb) {
+#ifndef SYSLINK_PLATFORM_VAYU
GateHWSpinlock_LeaveLockForPID(ocb->pid);
+#endif
free (ocb);
}
}
+int init_slave_devices(syslink_dev_t *dev)
+{
+ resmgr_attr_t resmgr_attr;
+ int i;
+ syslink_attr_t * slave_attr;
+ int status = 0;
+
+ memset(&resmgr_attr, 0, sizeof resmgr_attr);
+ resmgr_attr.nparts_max = 1;
+ resmgr_attr.msg_max_size = _POSIX_PATH_MAX;
+
+ for (i = 1; i < MultiProc_getNumProcessors(); i++) {
+ iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &dev->syslink.cfuncs_state[i],
+ _RESMGR_IO_NFUNCS, &dev->syslink.iofuncs_state[i]);
+ slave_attr = &dev->syslink.cattr_slave[i];
+ iofunc_attr_init(&slave_attr->attr,
+ S_IFCHR | 0777, NULL, NULL);
+ slave_attr->attr.mount = &dev->syslink.mattr;
+ slave_attr->procid = i;
+ slave_attr->dev = (Ptr)dev;
+ iofunc_time_update(&slave_attr->attr);
+ snprintf(dev->syslink.device_name, _POSIX_PATH_MAX,
+ "%s-state/%s", IPC_DEVICE_PATH, MultiProc_getName(i));
+ dev->syslink.iofuncs_state[i].read = slave_state_read;
+ dev->syslink.iofuncs_state[i].write = slave_state_write;
+
+ if (-1 == (dev->syslink.resmgr_id_state[i] =
+ resmgr_attach(dev->dpp, &resmgr_attr,
+ dev->syslink.device_name, _FTYPE_ANY, 0,
+ &dev->syslink.cfuncs_state[i],
+ &dev->syslink.iofuncs_state[i],
+ &slave_attr->attr))) {
+ GT_setFailureReason(curTrace, GT_4CLASS, "init_slave_devices",
+ status, "resmgr_attach failed");
+ return (-1);
+ }
+ }
+
+ for (i = 1; i < MultiProc_getNumProcessors(); i++) {
+ iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &dev->syslink.cfuncs_file[i],
+ _RESMGR_IO_NFUNCS, &dev->syslink.iofuncs_file[i]);
+ slave_attr = &dev->syslink.cattr_slave[i];
+ iofunc_attr_init(&slave_attr->attr,
+ S_IFCHR | 0777, NULL, NULL);
+ slave_attr->attr.mount = &dev->syslink.mattr;
+ slave_attr->procid = i;
+ slave_attr->dev = (Ptr)dev;
+ iofunc_time_update(&slave_attr->attr);
+ snprintf(dev->syslink.device_name, _POSIX_PATH_MAX,
+ "%s-file/%s", IPC_DEVICE_PATH, MultiProc_getName(i));
+ dev->syslink.iofuncs_file[i].read = slave_file_read;
+ dev->syslink.iofuncs_file[i].write = slave_file_write;
+
+ if (-1 == (dev->syslink.resmgr_id_file[i] =
+ resmgr_attach(dev->dpp, &resmgr_attr,
+ dev->syslink.device_name, _FTYPE_ANY, 0,
+ &dev->syslink.cfuncs_file[i],
+ &dev->syslink.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(syslink_dev_t *dev)
+{
+ int status = EOK;
+ int i = 0;
+
+ for (i = 1; i < MultiProc_getNumProcessors(); i++) {
+ status = resmgr_detach(dev->dpp, dev->syslink.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->syslink.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_syslink_trace_device(syslink_dev_t *dev)
{
resmgr_attr_t resmgr_attr;
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,
+ /*
+ * Initialize trace device only for cores that are running and their
+ * device is not yet setup.
+ */
+ if ((syslink_firmware[i].procState == RUNNING_STATE) &&
+ (proc_traces[i].va == NULL)) {
+ 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,
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,
+ 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 =
+ 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 =
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_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;
}
- 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->syslink.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],
&trace_attr->attr))) {
- GT_setFailureReason(curTrace, GT_4CLASS, "init_syslink_trace_device",
- status, "resmgr_attach failed");
- return(-1);
+ GT_setFailureReason(curTrace, GT_4CLASS,
+ "init_syslink_trace_device",
+ status, "resmgr_attach failed");
+ return(-1);
+ }
}
}
+ return (status);
}
int deinit_syslink_trace_device(syslink_dev_t *dev)
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,
+ /* Only disable trace device on cores in RESET state */
+ if ((syslink_firmware[i].procState == RESET_STATE) &&
+ (proc_traces[i].va != NULL)) {
+ status = resmgr_detach(dev->dpp, dev->syslink.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 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;
return(-1);
}
+ status = init_slave_devices(dev);
+ if (status < 0) {
+ return status;
+ }
+
status = init_syslink_trace_device(dev);
if (status < 0) {
return status;
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);
+ Osal_printf("IPC: resmgr_detach of %s failed: %d",
+ IPC_DEVICE_PATH, errno);
status = errno;
}
status = deinit_syslink_trace_device(dev);
+ if (status < 0) {
+ Osal_printf("IPC: deinit_syslink_trace_device failed %d", status);
+ }
+
+ status = deinit_slave_devices(dev);
+ if (status < 0) {
+ Osal_printf("IPC: deinit_slave_devices failed %d", status);
+ }
return(status);
}
int init_devices(syslink_dev_t *dev)
{
if (init_syslink_device(dev) < 0) {
- Osal_printf("syslink: syslink device init failed");
+ Osal_printf("IPC: device init failed");
return(-1);
}
int status = EOK;
if ((status = deinit_syslink_device(dev)) < 0) {
- fprintf( stderr, "syslink: syslink device de-init failed %d\n", status);
+ fprintf( stderr, "IPC: device de-init failed %d\n", status);
status = errno;
}
{
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);
+ if (!disableRecovery) {
+ /* Protect the syslink_firmware array as we recover */
+ pthread_mutex_lock(&dev->firmwareLock);
+ deinit_ipc(dev, syslink_firmware, TRUE);
+ deinit_syslink_trace_device(dev);
+ init_ipc(dev, syslink_firmware, TRUE);
+ init_syslink_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,
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
-#else
-// only need mem for DEVMEM entries, rest is allocated dynamically
-#define IPU_MEM_SIZE 90 * 1024 * 1024
-#define IPU_MEM_ALIGN 0x0
-
-#endif
-
-unsigned int syslink_ipu_mem_size = IPU_MEM_SIZE;
-#if defined(SYSLINK_PLATFORM_OMAP5430)
-unsigned int syslink_dsp_mem_size = IPU_MEM_SIZE;
-#endif
-
/*
* Initialize the syslink ipc
*
int init_ipc(syslink_dev_t * dev, syslink_firmware_info * firmware, bool recover)
{
int status = 0;
-#if defined(SYSLINK_PLATFORM_OMAP4430) || defined(SYSLINK_PLATFORM_OMAP5430)
- 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) || defined(SYSLINK_PLATFORM_OMAP5430)
- /* 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
-#if defined(SYSLINK_PLATFORM_OMAP5430)
- dev->da_tesla_virt =
-#endif
- 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 {
-#if defined(SYSLINK_PLATFORM_OMAP4430)
- 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);
-#else
- pa = paddr;
- da = dev->da_virt;
-#endif
- }
-#endif
- if (status != 0)
- goto memoryos_fail;
- }
-#endif
-
-#if defined(SYSLINK_PLATFORM_OMAP5430)
- if (status >= 0) {
- iCfg.pAddr_dsp = (uint32_t)pa;
- iCfg.vAddr_dsp = (uint32_t)da;
- }
-#endif
if (status >= 0) {
if (!recover) {
/* Set up the MemoryOS module */
@@ -676,15 +1263,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) || defined(SYSLINK_PLATFORM_OMAP5430)
-#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;
@@ -709,97 +1287,50 @@ int init_ipc(syslink_dev_t * dev, syslink_firmware_info * firmware, bool recover
pthread_mutex_unlock(&dev->lock);
}
+ memset(procH_fileId, 0, sizeof(procH_fileId));
+
for (i = 0; i < syslink_num_cores; i++) {
procId = firmware[i].proc_id = MultiProc_getId(firmware[i].proc);
- if (procId >= MultiProc_MAXPROCESSORS || procH[procId]) {
- GT_setFailureReason (curTrace,
- GT_4CLASS,
- "init_ipc",
- status,
- "invalid proc!");
+ if (procId >= MultiProc_MAXPROCESSORS) {
+ status = -1;
+ fprintf(stderr, "Invalid processor name specified\n");
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) {
+ if (procH[procId]) {
GT_setFailureReason (curTrace,
GT_4CLASS,
"init_ipc",
status,
- "ProcMgr_attach failed!");
- goto procmgrattach_fail;
+ "invalid proc!");
+ break;
}
- 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) {
+ /*
+ * if we are in recovery, we load the cores we previously
+ * attached to
+ */
+ firmware[i].attachOnly = false;
}
- status = Ipc_attach (procId);
- if (status < 0) {
- GT_setFailureReason (curTrace,
- GT_4CLASS,
- "init_ipc",
- status,
- "Ipc_attach failed!");
- goto ipcattach_fail;
+ if ((!recover) || (firmware[i].reload)) {
+ status = runSlave(dev, procId, &firmware[i]);
+ if (status == 0) {
+ firmware[i].procState = RUNNING_STATE;
+ continue;
+ }
+ else {
+ break;
+ }
}
-
- 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)
if (status < 0)
goto rpcsetup_fail;
+#if defined(SYSLINK_PLATFORM_VAYU)
+ if (gatempEnabled) {
+ Int32 sr0ProcId;
+
+ /* Set up NameServer for resource manager process */
+ status = NameServer_setup();
+ if (status < 0) {
+ goto nameserversetup_fail;
+ }
+
+ /* Set up GateMP */
+ 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)
+gatempsetup_fail:
+ NameServer_destroy();
+nameserversetup_fail:
+ rpmsg_rpc_destroy();
+#endif
rpcsetup_fail:
ti_ipc_destroy(recover);
tiipcsetup_fail:
for (i-=1; i >= 0; i--) {
procId = firmware[i].proc_id;
+ if (procId >= MultiProc_MAXPROCESSORS) {
+ continue;
+ }
ProcMgr_unregisterNotify(procH[procId], syslink_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]);
ipcsetup_fail:
MemoryOS_destroy();
memoryos_fail:
-#if defined(SYSLINK_PLATFORM_OMAP4430) || defined(SYSLINK_PLATFORM_OMAP5430)
- 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(syslink_dev_t * dev, syslink_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 (gatempEnabled) {
+ GateMP_destroy(TRUE);
+
+ NameServer_destroy();
+ }
+#endif
+
rpmsg_rpc_destroy();
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 < syslink_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 < syslink_num_cores; id++) {
+ firmware[id].procState = RESET_STATE;
+ }
+
status = Ipc_destroy();
if (status < 0) {
printf("Ipc_destroy() failed 0x%x", status);
if (status < 0) {
printf("MemoryOS_destroy() failed 0x%x", status);
}
-#if defined(SYSLINK_PLATFORM_OMAP4430) || defined(SYSLINK_PLATFORM_OMAP5430)
- 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%s: [-fHT]\n", app);
- printf (" -f specify the binary file to load to the remote cores)\n");
+ printf("\n\nUsage:\n");
#if defined(SYSLINK_PLATFORM_OMAP5430)
- printf (" -d specify the binary file to load to the dsp)\n");
+ 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 <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: [-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(" 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 (" -H enable/disable hibernation, 1: ON, 0: OFF, Default: 1)\n");
- printf (" -T specify the hibernation timeout in ms, Default: 5000 ms)\n");
+ 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);
}
syslink_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;
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, "f:d:H:T:U:v:");
+ c = getopt (argc, argv, "H:T:U:gc:dv:a:");
if (c == -1)
break;
switch (c)
{
- case 'f':
- /* for backward compatibility, "-f" option loaded Ducati/Benelli */
- syslink_firmware[syslink_num_cores].firmware = optarg;
-#if defined(SYSLINK_PLATFORM_OMAP4430)
- syslink_firmware[syslink_num_cores].proc = "SYSM3";
-#else
-#ifndef SYSLINK_SYSBIOS_SMP
- syslink_firmware[syslink_num_cores].proc = "CORE0";
-#else
- syslink_firmware[syslink_num_cores].proc = "IPU";
-#endif
-#endif
- syslink_num_cores++;
-#ifndef SYSLINK_SYSBIOS_SMP
- syslink_firmware[syslink_num_cores].firmware = NULL;
-#if defined(SYSLINK_PLATFORM_OMAP4430)
- syslink_firmware[syslink_num_cores].proc = "APPM3";
-#else
- syslink_firmware[syslink_num_cores].proc = "CORE1";
-#endif
- syslink_num_cores++;
-#endif
- break;
#if defined(SYSLINK_PLATFORM_OMAP5430)
- case 'd':
- syslink_firmware[syslink_num_cores].firmware = optarg;
- syslink_firmware[syslink_num_cores].proc = "DSP";
- syslink_num_cores++;
- break;
-#endif
case 'H':
hib_enable = atoi(optarg);
if (hib_enable != 0 && hib_enable != 1) {
case 'T':
hib_timeout = atoi(optarg);
break;
+#endif
case 'U':
user_parm = optarg;
break;
+ 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)
+ case 'g':
+ printf("GateMP support enabled on host\n");
+ gatempEnabled = true;
+ break;
+#endif
default:
fprintf (stderr, "Unrecognized argument\n");
}
return (error);
}
syslink_firmware[syslink_num_cores].proc = argv [optind];
+ syslink_firmware[syslink_num_cores].attachOnly =
+ ((numAttach-- > 0) ? true : false);
+ syslink_firmware[syslink_num_cores].reload = true;
+ syslink_firmware[syslink_num_cores].freeString = false;
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, "-f or -d or <core_id> option must be specified");
+ fprintf(stderr, "At least one core_id and executable must be "\
+ "specified");
printUsage(argv[0]);
return (error);
}
return (error);
}
+ /* Get the abs path for all firmware files */
+ for (i = 0; i < syslink_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)) {
+ fprintf (stderr, "invalid path to executable\n");
+ return -1;
+ }
+ syslink_firmware[i].firmware = abs_path;
+ }
+
/* allocate the device structure */
if (NULL == (dev = calloc(1, sizeof(syslink_dev_t)))) {
- Osal_printf("syslink: calloc() failed");
+ Osal_printf("IPC: calloc() failed");
return (-1);
}
/* create the dispatch structure */
if (NULL == (dev->dpp = syslink_dpp = dispatch_create_channel (channelid, 0))) {
- Osal_printf("syslink: dispatch_create() failed");
+ Osal_printf("IPC: dispatch_create() failed");
return(-1);
}
+ /*
+ * Mask out all signals before creating a thread pool.
+ * This prevents other threads in the thread pool
+ * from intercepting signals such as SIGTERM.
+ */
+ sigfillset(&set);
+ pthread_sigmask(SIG_BLOCK, &set, NULL);
+
/* Initialize the thread pool */
memset (&tattr, 0x00, sizeof (thread_pool_attr_t));
tattr.handle = dev->dpp;
/* 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);
if (status < 0) {
- Osal_printf("syslink: IPC init failed");
+ Osal_printf("IPC: init failed");
return(-1);
}
/* init the syslink device */
status = init_devices(dev);
if (status < 0) {
- Osal_printf("syslink: device init failed");
+ Osal_printf("IPC: device init failed");
return(-1);
}
/* 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;
- }
-
- /* Mask out unnecessary signals */
- sigfillset (&set);
+ /* Unmask signals to be caught */
sigdelset (&set, SIGINT);
sigdelset (&set, SIGTERM);
pthread_sigmask (SIG_BLOCK, &set, NULL);
sigaddset (&set, SIGQUIT);
sigaddset (&set, SIGTERM);
- Osal_printf("Syslink resource manager started");
+ Osal_printf("IPC resource manager started");
/* Wait for a signal */
while (1)
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, syslink_firmware, FALSE);
deinit_devices(dev);
free(dev);
- return (EOK);
+
+ /* Free the abs path of firmware files if necessary */
+ for (i = 0; i < syslink_num_cores; i++) {
+ if ((syslink_firmware[i].freeString) &&
+ (syslink_firmware[i].firmware)) {
+ free(syslink_firmware[i].firmware);
+ }
+ }
+
+ return (error);
}