Ejemplo n.º 1
0
int ReadVideoCoreStringBySymbol( VC_MEM_ACCESS_HANDLE_T vcHandle,
                                 const char *symbol,
                                 char *buf,
                                 size_t bufSize )
{
    VC_MEM_ADDR_T   vcMemAddr;
    size_t          vcMemSize;

    if ( !LookupVideoCoreSymbol( vcHandle, symbol, &vcMemAddr, &vcMemSize ))
    {
        ERR( "Symbol not found: '%s'", symbol );
        return 0;
    }

    if ( vcMemSize > bufSize )
    {
        vcMemSize = bufSize;
    }

    if ( !ReadVideoCoreMemory( vcHandle, buf, vcMemAddr, vcMemSize ))
    {
        ERR( "Unable to read %zu bytes @ 0x%08x", vcMemSize, vcMemAddr );
        return 0;
    }

    // Make sure that the result is null-terminated

    buf[vcMemSize-1] = '\0';
    return 1;
}
Ejemplo n.º 2
0
static int do_components(int argc, const char **argv)
{
   VC_MEM_ACCESS_HANDLE_T vc;
   VC_MEM_ADDR_T addr, statsaddr;
   size_t size;
   MMAL_VC_STATS_T stats;
   int rc;


   if (argc > 2 && (strcasecmp(argv[2], "update") == 0))
   {
      MMAL_STATUS_T status;
      do_connect();
      status = mmal_vc_get_stats(&stats, 0);
      if (status != MMAL_SUCCESS)
      {
         fprintf(stderr, "Failed to update MMAL stats. error %s",
              mmal_status_to_string(status));
         return -1;
      }
   }
   else
   {
      if ((rc = OpenVideoCoreMemory(&vc)) < 0)
      {
         fprintf(stderr,"Unable to open videocore memory: %d\n", rc);
         return -1;
      }
      if (!LookupVideoCoreSymbol(vc, "mmal_vc_stats", &addr, &size))
      {
         fprintf(stderr,"Could not get MMAL stats address\n");
         goto fail;
      }
      if (!ReadVideoCoreUInt32(vc, &statsaddr, addr))
      {
         fprintf(stderr,"Could not read MMAL stats pointer at address 0x%x\n",
               addr);
         goto fail;
      }
      if (!ReadVideoCoreMemory(vc, &stats, statsaddr, sizeof(stats)))
      {
         fprintf(stderr,"Could not read MMAL stats at address 0x%x\n", addr);
         goto fail;
      }
      CloseVideoCoreMemory(vc);
   }
   rc = print_component_stats(&stats);
   return rc;

fail:
   CloseVideoCoreMemory(vc);
   return -1;
}
Ejemplo n.º 3
0
int ReadVideoCoreMemoryBySymbol( VC_MEM_ACCESS_HANDLE_T vcHandle, const char *symbol, void *buf, size_t bufSize )
{
    VC_MEM_ADDR_T   vcMemAddr;
    size_t          vcMemSize;

    if ( !LookupVideoCoreSymbol( vcHandle, symbol, &vcMemAddr, &vcMemSize ))
    {
        ERR( "Symbol not found: '%s'", symbol );
        return 0;
    }

    if ( vcMemSize > bufSize )
    {
        vcMemSize = bufSize;
    }

    if ( !ReadVideoCoreMemory( vcHandle, buf, vcMemAddr, vcMemSize ))
    {
        ERR( "Unable to read %zu bytes @ 0x%08x", vcMemSize, vcMemAddr );
        return 0;
    }
    return 1;
}
Ejemplo n.º 4
0
static int do_imageconv_stats(int argc, const char **argv)
{
   VC_MEM_ACCESS_HANDLE_T vc;
   VC_MEM_ADDR_T addr, statsaddr;
   size_t size;
   IMAGECONV_STATS_T stats;
   long convert_time;
   double frame_rate;
   int rc;
   int reset_stats = 0;

   if (argc > 2)
      reset_stats = strcasecmp(argv[2], "reset") == 0;

   if ((rc = OpenVideoCoreMemory(&vc)) < 0)
   {
      fprintf(stderr,"Unable to open videocore memory: %d\n", rc);
      return -1;
   }
   if (!LookupVideoCoreSymbol(vc, "imageconv_stats", &addr, &size))
   {
      fprintf(stderr,"Could not get imageconv stats address\n");
      goto fail;
   }
   if (!ReadVideoCoreUInt32(vc, &statsaddr, addr))
   {
      fprintf(stderr, "Could not read imageconv stats address\n");
      goto fail;
   }

   if (reset_stats)
   {
      memset(&stats, 0, sizeof(stats));
      stats.magic = IMAGECONV_STATS_MAGIC;
      if (!WriteVideoCoreMemory(vc, &stats, statsaddr, sizeof(stats)))
      {
         fprintf(stderr, "Could not write stats at 0x%x\n", statsaddr);
         goto fail;
      }
   }

   if (!ReadVideoCoreMemory(vc, &stats, statsaddr, sizeof(stats)))
   {
      fprintf(stderr, "Could not read stats at 0x%x\n", statsaddr);
      goto fail;
   }

   if (stats.magic != IMAGECONV_STATS_MAGIC)
   {
      fprintf(stderr, "Bad magic 0x%x\n", stats.magic);
      goto fail;
   }

   if (stats.conversions)
      convert_time = stats.time_spent / stats.conversions;
   else
      convert_time = 0;

   if (stats.conversions)
      frame_rate = 1000000.0 * stats.conversions /
         (stats.last_image_ts - stats.first_image_ts);
   else
      frame_rate = 0;

   printf("%-25s:\t%d\n", "conversions", stats.conversions);
   printf("%-25s:\t%d\n", "size requests", stats.size_requests);
   printf("%-25s:\t%d\n", "max vrf delay", stats.max_vrf_delay);
   printf("%-25s:\t%d\n", "vrf wait time", stats.vrf_wait_time);
   printf("%-25s:\t%d\n", "duplicate conversions", stats.duplicate_conversions);
   printf("%-25s:\t%d\n", "failures", stats.failures);
   printf("%-25s:\t%ld\n", "convert time / image (us)", convert_time);
   printf("%-25s:\t%.1f\n", "client frame_rate", frame_rate);
   printf("%-25s:\t%d us\n", "max delay to consume", stats.max_delay);

   CloseVideoCoreMemory(vc);
   return 0;
fail:
   CloseVideoCoreMemory(vc);
   return -1;

}
Ejemplo n.º 5
0
static int do_eventlog(int argc, const char **argv)
{
   VC_MEM_ACCESS_HANDLE_T vc;
   VC_MEM_ADDR_T addr;     /** The address of the pointer to the log */
   size_t size;
   VC_MEM_ADDR_T logaddr;       /** The address of the log itself */
   MMAL_DBG_LOG_T log;

   (void)argc; (void)argv;
   int rc;
   if ((rc = OpenVideoCoreMemory(&vc)) < 0)
   {
      fprintf(stderr,"Unable to open videocore memory: %d\n", rc);
      return -1;
   }
   if (!LookupVideoCoreSymbol(vc, "mmal_dbg_log", &addr, &size))
   {
      fprintf(stderr,"Could not get MMAL log address\n");
      goto fail;
   }
   if (!ReadVideoCoreUInt32(vc, &logaddr, addr))
   {
      fprintf(stderr,"Could not read MMAL log pointer at address 0x%x\n",
              addr);
      goto fail;
   }
   if (!ReadVideoCoreMemory(vc, &log, logaddr, sizeof(log)))
   {
      fprintf(stderr,"Could not read MMAL log at address 0x%x\n",
              logaddr);
      goto fail;
   }
   if (log.magic != MMAL_MAGIC)
   {
      fprintf(stderr,"Bad magic 0x%08x in log at 0x%x\n", log.magic, logaddr);
      goto fail;
   }
   if (log.size != sizeof(log))
   {
      fprintf(stderr,"MMAL Log size mismatch (got %d, expected %d)\n",
              log.size, sizeof(log));
      goto fail;
   }
   if (log.elemsize != sizeof(MMAL_DBG_ENTRY_T))
   {
      fprintf(stderr,"MMAL log element size mismatch (got %d, expected %d)\n",
              log.elemsize, sizeof(MMAL_DBG_ENTRY_T));
      goto fail;
   }

   printf("reading MMAL log at 0x%x version %d magic %x\n",
          logaddr, log.version, log.magic);
   printf("%d events, %d entries each size %d\n", log.index, log.num_entries,
          log.elemsize);
   print_mmal_event_log(vc, &log);

   CloseVideoCoreMemory(vc);
   return 0;
fail:
   CloseVideoCoreMemory(vc);
   return -1;

}
Ejemplo n.º 6
0
int OpenVideoCoreMemoryFileWithOffset( const char *filename, VC_MEM_ACCESS_HANDLE_T *vcHandlePtr, size_t loadOffset )
{
    int                     rc = 0;
    VC_MEM_ACCESS_HANDLE_T  newHandle;
    VC_DEBUG_SYMBOL_T       debug_sym;
    VC_MEM_ADDR_T           symAddr;
    size_t                  symTableSize;
    unsigned                symIdx;

    struct
    {
        VC_DEBUG_HEADER_T header;
        VC_DEBUG_PARAMS_T params;

    } vc_dbg;

    vcos_log_register( "debug_sym", &debug_sym_log_category );

    if (( newHandle = calloc( 1, sizeof( *newHandle ))) == NULL )
    {
        return -ENOMEM;
    }

    if ( filename == NULL )
    {
        newHandle->use_vc_mem = 1;
        filename = "/dev/vc-mem";
    }
    else
    {
        newHandle->use_vc_mem = 0;
    }

    if (( newHandle->memFd = open( filename, ( newHandle->use_vc_mem ? O_RDWR : O_RDONLY ) | O_SYNC )) < 0 )
    {
        ERR( "Unable to open '%s': %s(%d)\n", filename, strerror( errno ), errno );
        free(newHandle);
        return -errno;
    }
    DBG( "Opened %s memFd = %d", filename, newHandle->memFd );

    if ( newHandle->use_vc_mem )
    {
        newHandle->memFdBase = 0;

#if defined(WIN32) || defined(__CYGWIN__)
#define VC_MEM_SIZE  (128 * 1024 * 1024)
        newHandle->vcMemSize = VC_MEM_SIZE;
        newHandle->vcMemBase = 0;
        newHandle->vcMemLoad = 0;
        newHandle->vcMemPhys = 0;
#else
        if ( ioctl( newHandle->memFd, VC_MEM_IOC_MEM_SIZE, &newHandle->vcMemSize ) != 0 )
        {
            ERR( "Failed to get memory size via ioctl: %s(%d)\n",
                strerror( errno ), errno );
            free(newHandle);
            return -errno;
        }
        if ( ioctl( newHandle->memFd, VC_MEM_IOC_MEM_BASE, &newHandle->vcMemBase ) != 0 )
        {
            ERR( "Failed to get memory base via ioctl: %s(%d)\n",
                strerror( errno ), errno );
            free(newHandle);
            return -errno;
        }
        if ( ioctl( newHandle->memFd, VC_MEM_IOC_MEM_LOAD, &newHandle->vcMemLoad ) != 0 )
        {
            ERR( "Failed to get memory load via ioctl: %s(%d)\n",
                strerror( errno ), errno );
				/* Backward compatibility. */
            newHandle->vcMemLoad = newHandle->vcMemBase;
        }
        if ( ioctl( newHandle->memFd, VC_MEM_IOC_MEM_PHYS_ADDR, &newHandle->vcMemPhys ) != 0 )
        {
            ERR( "Failed to get memory physical address via ioctl: %s(%d)\n",
                strerror( errno ), errno );
            free(newHandle);
            return -errno;
        }
#endif
    }
    else
    {
        off_t len = lseek( newHandle->memFd, 0, SEEK_END );
        if ( len < 0 )
        {
            ERR( "Failed to seek to end of file: %s(%d)\n", strerror( errno ), errno );
            free(newHandle);
            return -errno;
        }
        newHandle->vcMemPhys = 0;
        newHandle->vcMemSize = len;
        newHandle->vcMemBase = 0;
        newHandle->vcMemLoad = loadOffset;
        newHandle->memFdBase = 0;
    }

    DBG( "vcMemSize = %08x", newHandle->vcMemSize );
    DBG( "vcMemBase = %08x", newHandle->vcMemBase );
    DBG( "vcMemLoad = %08x", newHandle->vcMemLoad );
    DBG( "vcMemPhys = %08x", newHandle->vcMemPhys );

    newHandle->vcMemEnd = newHandle->vcMemBase + newHandle->vcMemSize - 1;

    // See if we can detect the symbol table
    if ( !ReadVideoCoreMemory( newHandle,
                               &newHandle->vcSymbolTableOffset,
                               newHandle->vcMemLoad + VC_SYMBOL_BASE_OFFSET,
                               sizeof( newHandle->vcSymbolTableOffset )))
    {
        ERR( "ReadVideoCoreMemory @VC_SYMBOL_BASE_OFFSET (0x%08x) failed\n", VC_SYMBOL_BASE_OFFSET );
        rc = -EIO;
        goto err_exit;
    }

    // When reading from a file, the VC binary is read into a buffer and the effective base is 0.
    // But that may not be the actual base address the binary is intended to be loaded to.  The
    // following reads the debug header to find out what the actual base address is.
    if( !newHandle->use_vc_mem )
    {
        // Read the complete debug header
        if ( !ReadVideoCoreMemory( newHandle,
                                   &vc_dbg,
                                   newHandle->vcMemLoad + VC_SYMBOL_BASE_OFFSET,
                                   sizeof( vc_dbg )))
        {
            ERR( "ReadVideoCoreMemory @VC_SYMBOL_BASE_OFFSET (0x%08x) failed\n", VC_SYMBOL_BASE_OFFSET );
            rc = -EIO;
            goto err_exit;
        }
        // The vc_dbg header gives the "base" address of the VC binary,
        // which debug_sym calls the "load" address, so we need to adjust
        // it by loadOffset to find the base of the whole memory dump file
        newHandle->memFdBase = vc_dbg.params.vcMemBase - loadOffset;
        newHandle->vcMemBase = vc_dbg.params.vcMemBase - loadOffset;
        newHandle->vcMemLoad = vc_dbg.params.vcMemBase;
        newHandle->vcMemEnd = newHandle->memFdBase + newHandle->vcMemSize - 1;

        DBG( "Updated from debug header:" );
        DBG( "vcMemSize = %08x", newHandle->vcMemSize );
        DBG( "vcMemBase = %08x", newHandle->vcMemBase );
        DBG( "vcMemLoad = %08x", newHandle->vcMemLoad );
        DBG( "vcMemPhys = %08x", newHandle->vcMemPhys );
    }

    DBG( "vcSymbolTableOffset = 0x%08x", newHandle->vcSymbolTableOffset );

    // Make sure that the pointer points into the first few megabytes of
    // the memory space.
    if ( (newHandle->vcSymbolTableOffset - newHandle->vcMemLoad) > ( MAX_VC_SIZE * 1024 * 1024 ))
    {
        ERR( "newHandle->vcSymbolTableOffset (0x%x - 0x%x) > %dMB\n", newHandle->vcSymbolTableOffset, newHandle->vcMemLoad, MAX_VC_SIZE );
        rc = -EIO;
        goto err_exit;
    }

    // Make a pass to count how many symbols there are.

    symAddr = newHandle->vcSymbolTableOffset;
    newHandle->numSymbols = 0;
    do
    {
        if ( !ReadVideoCoreMemory( newHandle,
                                   &debug_sym,
                                   symAddr,
                                   sizeof( debug_sym )))
        {
            ERR( "ReadVideoCoreMemory @ symAddr(0x%08x) failed\n", symAddr );
            rc = -EIO;
            goto err_exit;
        }

        newHandle->numSymbols++;

        DBG( "Symbol %d: label: 0x%p addr: 0x%08x size: %zu",
             newHandle->numSymbols,
             debug_sym.label,
             debug_sym.addr,
             debug_sym.size );

        if ( newHandle->numSymbols > 1024 )
        {
            // Something isn't sane.

            ERR( "numSymbols (%d) > 1024 - looks wrong\n", newHandle->numSymbols );
            rc = -EIO;
            goto err_exit;
        }
        symAddr += sizeof( debug_sym );

    } while ( debug_sym.label != 0 );
    newHandle->numSymbols--;

    DBG( "Detected %d symbols", newHandle->numSymbols );

    // Allocate some memory to hold the symbols, and read them in.

    symTableSize = newHandle->numSymbols * sizeof( debug_sym );
    if (( newHandle->symbol = malloc( symTableSize )) == NULL )
    {
        rc = -ENOMEM;
        goto err_exit;
    }
    if ( !ReadVideoCoreMemory( newHandle,
                               newHandle->symbol,
                               newHandle->vcSymbolTableOffset,
                               symTableSize ))
    {
        ERR( "ReadVideoCoreMemory @ newHandle->vcSymbolTableOffset(0x%08x) failed\n", newHandle->vcSymbolTableOffset );
        rc = -EIO;
        goto err_exit;
    }

    // The names of the symbols are pointers in videocore space. We want
    // to have them available locally, so we make copies and fixup
    // the pointer.

    for ( symIdx = 0; symIdx < newHandle->numSymbols; symIdx++ )
    {
        VC_DEBUG_SYMBOL_T   *sym;
        char                 symName[ 256 ];

        sym = &newHandle->symbol[ symIdx ];

        DBG( "Symbol %d: label: 0x%p addr: 0x%08x size: %zu",
             symIdx,
             sym->label,
             sym->addr,
             sym->size );

        if ( !ReadVideoCoreMemory( newHandle,
                                   symName,
                                   TO_VC_MEM_ADDR(sym->label),
                                   sizeof( symName )))
        {
            ERR( "ReadVideoCoreMemory @ sym->label(0x%08x) failed\n", TO_VC_MEM_ADDR(sym->label) );
            rc = -EIO;
            goto err_exit;
        }
        symName[ sizeof( symName ) - 1 ] = '\0';
        sym->label = vcos_strdup( symName );

        DBG( "Symbol %d (@0x%p): label: '%s' addr: 0x%08x size: %zu",
             symIdx,
             sym,
             sym->label,
             sym->addr,
             sym->size );
    }

    *vcHandlePtr = newHandle;
    return 0;

err_exit:
    close( newHandle->memFd );
    free( newHandle );

    return rc;
}