OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gdb/] [gdb-6.8/] [sim/] [scarts_16/] [scarts_16-plugins.c] - Rev 26

Compare with Previous | Blame | View Log

/* SCARTS (16-bit) target-dependent code for the GNU simulator.
   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
   Free Software Foundation, Inc.
   Contributed by Martin Walter <mwalter@opencores.org>
 
   This file is part of the GNU simulators.
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.
 
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
 
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
#include <dirent.h>
#include <dlfcn.h>
#include <pwd.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include "modules.h"
#include "scarts_16-plugins.h"
 
/* Macros for preprocessor macro stringification. */
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
 
#define SCARTS_TOOLCHAIN_LIB_SIM_DIR_STR TOSTRING(SCARTS_TOOLCHAIN_LIB_SIM_DIR)
 
int              num_plugins;
static scarts_plugin_t  plugins[SCARTS_MAX_PLUGINS];
 
static int              filter_plugin (const struct dirent *entry);
static scarts_plugin_t *load_plugin   (char *name);
 
static int
filter_plugin (const struct dirent *entry)
{
  char *p;
  int result;
 
  result = 0;
 
  /* Check if '.so' is contained in the entry's name. */
  p = strstr (entry->d_name, ".so");
  if (p != NULL)
  {
    /* Check if '.so' terminates the entry's name. */
    if (*(p + 3) == '\0')
      result = 1;
  }
 
  return result;
}
 
static scarts_plugin_t*
load_plugin (char *name)
{
  char path[SCARTS_MAX_PLUGIN_PATH_LEN + 1];
  uint16_t addr, size;
  scarts_plugin_t *plugin;
 
  plugin = &plugins[num_plugins];
 
  if (num_plugins >= SCARTS_MAX_PLUGINS - 1)
  {
    fprintf (stderr, "Please recompile GDB with increased SCARTS_MAX_PLUGINS.\n");
    return NULL;
  }
 
  strncpy (path, SCARTS_TOOLCHAIN_LIB_SIM_DIR_STR, SCARTS_MAX_PLUGIN_PATH_LEN - (9 + SCARTS_MAX_PLUGIN_NAME_LEN));
  strcat (path, "/scarts_16/");
  strncat (path, name, SCARTS_MAX_PLUGIN_NAME_LEN);
 
  plugin->handle = dlopen (path, RTLD_LAZY);
  if (!plugin->handle)
  {
    fprintf (stderr, "Unable to open object file %s\n", path);
    return NULL;
  }
 
  strncpy (plugin->name, name, SCARTS_MAX_PLUGIN_NAME_LEN);
 
  dlerror();
 
  *(void **) (&plugin->get_mem) = dlsym (plugin->handle, "get_mem");
  if (dlerror() != NULL)
  {
    fprintf (stderr, "Unable to find symbol '%s' in object file %s\n", "get_mem", path);
    return NULL;
  }
 
  *(void **) (&plugin->get_mem_map) = dlsym (plugin->handle, "get_mem_map");
  if (dlerror() != NULL)
  {
    fprintf (stderr, "Unable to find symbol '%s' in object file %s\n", "get_mem_map", path);
    return NULL;
  }
 
  *(void **) (&plugin->get_status) = dlsym (plugin->handle, "get_status");
  if (dlerror() != NULL)
    plugin->get_status = NULL;
 
  *(void **) (&plugin->mem_read) = dlsym (plugin->handle, "mem_read");
  if (dlerror() != NULL)
  {
    fprintf (stderr, "Unable to find symbol '%s' in object file %s\n", "mem_read", path);
    return NULL;
  }
 
  *(void **) (&plugin->mem_write) = dlsym (plugin->handle, "mem_write");
  if (dlerror() != NULL)
  {
    fprintf (stderr, "Unable to find symbol '%s' in object file %s\n", "mem_write", path);
    return NULL;
  }
 
  *(void **) (&plugin->reset) = dlsym (plugin->handle, "reset");
  if (dlerror() != NULL)
  {
    fprintf (stderr, "Unable to find symbol '%s' in object file %s\n", "reset", path);
    return NULL;
  }
 
  *(void **) (&plugin->set_codemem_read_fptr) = dlsym (plugin->handle, "set_codemem_read_fptr");
  if (dlerror() != NULL)
    plugin->set_codemem_read_fptr = NULL;
 
  *(void **) (&plugin->set_codemem_write_fptr) = dlsym (plugin->handle, "set_codemem_write_fptr");
  if (dlerror() != NULL)
    plugin->set_codemem_write_fptr = NULL;
 
  *(void **) (&plugin->set_datamem_read_fptr) = dlsym (plugin->handle, "set_datamem_read_fptr");
  if (dlerror() != NULL)
    plugin->set_datamem_read_fptr = NULL;
 
  *(void **) (&plugin->set_datamem_write_fptr) = dlsym (plugin->handle, "set_datamem_write_fptr");
  if (dlerror() != NULL)
    plugin->set_datamem_write_fptr = NULL;
 
  *(void **) (&plugin->tick) = dlsym (plugin->handle, "tick");
  if (dlerror() != NULL)
  {
    fprintf (stderr, "Unable to find symbol '%s' in object file %s\n", "tick", path);
    return NULL;
  }
 
  /* Check if the plugin is connected to an interrupt line. */
  plugin->int_num = -1;
  if (plugin->get_status != NULL)
  {
    int path_len = strlen (path);
 
    strcat (path, ".int");
    FILE* fint = fopen (path, "r");
    if (fint != NULL)
    {
      if (fscanf (fint, "%d", &(plugin->int_num)) == EOF || plugin->int_num > SCARTS_MAX_INTERRUPT_NUM)
        plugin->int_num = -1;
 
      fclose (fint);
    }
 
    /* Remove the '.int' extension before printing any messages. */
    path[path_len] = '\0';
  }
 
  /* Get the start address and size (bytes) of the plugin. */
  (*plugin->get_mem_map) (&addr, &size);
 
  if (plugin->int_num != -1) 
    fprintf (stdout, "Plugin: %s, Address: 0x%X - %X, Interrupt: %d\n", path, addr, addr + size - 1, plugin->int_num);
  else
    fprintf (stdout, "Plugin: %s, Address: 0x%X - %X\n", path, addr, addr + size - 1);
 
  ++num_plugins;
  return plugin;
}
 
scarts_plugin_t*
scarts_get_plugin (uint16_t addr)
{
  int i;
  uint16_t start, size;
 
  for (i = 0; i < num_plugins; ++i)
  {
    (*plugins[i].get_mem_map) (&start, &size);
 
    if (addr >= start && addr < start + size)
      return &plugins[i];
  }
 
  return NULL;
}
 
void
scarts_load_plugins (void)
{
  char path[SCARTS_MAX_PLUGIN_PATH_LEN + 1];
  int n;
  struct dirent **entries;
 
  num_plugins = 0;
 
  strncpy (path, SCARTS_TOOLCHAIN_LIB_SIM_DIR_STR, SCARTS_MAX_PLUGIN_PATH_LEN - (8 + SCARTS_MAX_PLUGIN_NAME_LEN));
  strcat (path, "/scarts_16");
 
  fprintf (stdout, "Scanning for plugins in %s\n", path);
  n = scandir (path, &entries, filter_plugin, alphasort);
  if (n >= 0)
  {
    while (n--)
    {
      load_plugin (entries[n]->d_name);
      free (entries[n]);
    }
 
    free (entries);
  }
  else
    fprintf (stderr, "Unable to scan directory %s\n", path);
}
 
void
scarts_reset_plugins (void)
{
  int i;
 
  for (i = 0; i < num_plugins; ++i)
    plugins[i].reset ();
}
 
void
scarts_tick_plugins (uint16_t *pc)
{
  int i;
 
  for (i = 0; i < num_plugins; ++i)
    plugins[i].tick (*pc);
}
 
int
scarts_get_plugin_int_request (void)
{
  int i;
  scarts_plugin_t *plugin;
 
  for (i = 0; i < num_plugins; ++i)
  {
    plugin = &plugins[i];
 
    if (plugin->int_num != -1)
    {
      /* Check if a plugin requested an interrupt. */
      if (plugin->get_status != NULL && (*plugin->get_status() & (1 << PROC_CTRL_STATUS_INT)))
        return plugin->int_num;
    }
  }
 
  return -1;
}
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.