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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_61/] [or1ksim/] [sim-config.c] - Rev 306

Go to most recent revision | Compare with Previous | Blame | View Log

/* config.c -- Simulator configuration
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
 
This file is part of OpenRISC 1000 Architectural Simulator.
 
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
/* Simulator configuration. Eventually this one will be a lot bigger. */
 
#include <stdlib.h>
#include "sim-config.h"
#include "abstract.h"
#include "spr_defs.h"
#include "pic.h"
 
struct config config;
 
void init_defconfig()
{
  unsigned long val;
 
  memset(&config, 0, sizeof(config));
  /* Sim */
  config.script_file = "sim.cfg";
 
  config.sim.exe_log = 0;
  config.sim.fexe_log = 0;
  strcpy (config.sim.exe_log_fn, "executed.log");
 
  config.sim.debug = 0;
  config.sim.verbose = 1;
  config.sim.iprompt = 0;
 
  config.sim.profile = 0;
  config.sim.fprof = 0;
  strcpy (config.sim.prof_fn, "sim.profile");
 
  /* Memory */
  config.memory.type = MT_PATTERN;
  config.memory.pattern = 0;
  config.memory.random_seed = -1;  /* Generate new seed */
  strcpy(config.memory.memory_table_file, "simmem.cfg");
 
  /* Memory Controller */
  config.mc.enabled = 0;
 
  /* Uarts */
  config.nuarts = 0;
  config.uarts_enabled = 0;
 
  /* DMAs */
  config.ndmas = 0;
  config.dmas_enabled = 0;
 
  /* CPU */
  config.cpu.superscalar = 0;
  config.cpu.history = 0;
  config.cpu.hazards = 0;
  config.cpu.dependstats = 0;
  config.cpu.dependency = 0;
  config.cpu.slp = 0;
  config.cpu.upr = SPR_UPR_UP | SPR_UPR_DCP | SPR_UPR_ICP | SPR_UPR_DMP
                 | SPR_UPR_IMP | SPR_UPR_OB32P | SPR_UPR_DUP | SPR_UPR_PICP
                 | SPR_UPR_PMP | SPR_UPR_TTP;
 
  /* Debug */
  config.debug.enabled = 0;
  config.debug.gdb_enabled = 0;
  config.debug.server_port = 0;
 
  /* VAPI */
  config.vapi.enabled = 0;
 
  /* Ethernet */
  config.ethernets_enabled = 0;
 
  /* Old */
  config.dc.tagtype = NONE/*VIRTUAL*/;
  config.ic.tagtype = NONE/*VIRTUAL*/;
  config.clkcycle_ns = 4; /* 4 for 4ns (250MHz) */
  config.ethernets[0].baseaddr = 0x88000000;
  config.ethernets[0].dma = 0;
  config.ethernets[0].tx_channel = 0;
  config.ethernets[0].rx_channel = 1;
  config.ethernets[0].rxfile = "/tmp/eth0.rx";
  config.ethernets[0].txfile = "/tmp/eth0.tx";
}
 
int parse_args(int argc, char *argv[])
{
  unsigned long val;
 
  argv++; argc--;
  while (argc) {
    if (argc && (*argv[0] != '-')) {
      config.filename = argv[0];
      argc--;
      argv++;
    } else
    if (strcmp(*argv, "-f") == 0 || strcmp(*argv, "--file") == 0) {      
      argv++; argc--;
      config.script_file = argv[0];
      argv++; argc--;
    } else
    if (strcmp(*argv, "--nosrv") == 0) {  /* (CZ) */
      config.debug.gdb_enabled = 0;
      argv++; argc--;
    } else
    if (strcmp(*argv, "--srv") == 0) {  /* (CZ) */
      char *s;
      if(!--argc)
        return 1;
      config.debug.enabled = 1;
      config.debug.gdb_enabled = 0;
      config.debug.server_port = strtol(*(++argv),&s,10);
      if(*s)
        return 1;
      argv++; argc--;
    } else
    if (strcmp(*argv, "-i") == 0) {
      config.sim.iprompt = 1;
      argv++; argc--;
    } else
    if (strcmp(*argv, "-v") == 0) {
      version();
      exit(0);
    } else
    if (strcmp(*argv, "--profile") == 0) {
      config.sim.profile = 1;
      argv++; argc--;
    } else {
      printf("Unknown option: %s\n", *argv);
      return 1;
    }
  }
 
  if (!argc)
    return 0;
 
  return 0;
}
 
#define CNV(x) ((isblank(x) || (x) == 0) ? ' ' : (x))
 
/* Substitute for less powerful fscanf */
int fscanf_ex (FILE *f, char *fmt, void *buf) {
  char tmp[STR_SIZE];
  char ch;
  int i = 0;
  while (*fmt) {
    switch (*fmt) {
      case '%':
        while(*fmt != 0 && !isalpha (*fmt))
          tmp[i++] = *(fmt++);
        tmp[i++] = *(fmt++);
        if (tmp[i - 1] == 's') {
          char *cbuf = (char *)buf;
          i = 0;
          while (ch = fgetc (f), isblank(ch))
            if (feof (f)) return 1;
          ungetc (ch, f);
          while ((*(cbuf++) = ch = fgetc (f), CNV(ch) ) != *fmt) {
            if (feof (f)) return 1;
            if (++i >= STR_SIZE) {
              fprintf (stderr, "ERROR: string too long.\n");
              return 1;
            }
          }
          *(--cbuf) = 0;
          fmt++;
        } else {
          tmp[i++] = 0;
          fscanf (f, tmp, buf);
        }
        break;
      default:
        while ((ch = fgetc (f)) != *fmt) {
          if (!isblank (ch))
            fprintf (stderr, "WARNING: unexpected char '%c' (expecting '%c')\n", ch, *fmt);
          if (feof (f)) return 1;
        }
        fmt++;
        break;
    }
  }
  return 0;
}
 
void print_config()
{
  printf("Machine initialization...\n");
  if (testsprbits(SPR_UPR, SPR_UPR_DCP))
    printf("Data cache tag: %s\n", config.dc.tagtype == VIRTUAL ? "virtual" : "physical");
  else
    printf("No data cache.\n");
  if (testsprbits(SPR_UPR, SPR_UPR_ICP))
    printf("Insn cache tag: %s\n", config.ic.tagtype == VIRTUAL ? "virtual" : "physical");
  else
    printf("No instruction cache.\n");
  /*if (config.cpu.bpb_sim)
    printf("BPB simulation on.\n");
  else
    printf("BPB simulation off.\n");
  if (config.cpu.btic_sim)
    printf("BTIC simulation on.\n");
  else
    printf("BTIC simulation off.\n");*/
  printf("Clock cycle: %d ns\n", config.clkcycle_ns);
 
  if (config.sim.debug)
    printf("simdebug on, ");
  else
    printf("simdebug off, ");
  if (config.sim.iprompt)
    printf("interactive prompt on\n");
  else
    printf("interactive prompt off\n");
}
 
void change_device ();
void end_device ();
void uart_baseaddr ();
void uart_rxfile ();
void uart_txfile ();
void uart_jitter ();
void dma_baseaddr ();
void dma_irq ();
void memory_type ();
void eth_baseaddr ();
void eth_dma ();
 
unsigned long tempL;
unsigned long tempUL;
char tempS[STR_SIZE];
 
#define CPF_SUBSECTION 1
#define CPF_SUBFIELD   2
 
struct section {
  char *name;
  int flags;
} sections[] = {
  {"",       0},
  {"mc",     0},
  {"uart",   0},
  {"dma",    0},
  {"memory", 0},
  {"cpu",    0},
  {"sim",    0},
  {"debug",  0},
  {"VAPI",   0},
  {"ethernet",0}
};
 
/* *INDENT-OFF* */
 
/* Parameter definitions */
struct config_params {
  int section;
  char *name;
  char *type;
  void (*func)();
  void *addr;
} config_params[] = {
  {1, "enabled",            "=%i",         NULL,          (void *)(&config.mc.enabled)},
  {1, "baseaddr",           "=0x%x",       NULL,          (void *)(&config.mc.baseaddr)},
  {1, "POC",                "=0x%x",       NULL,          (void *)(&config.mc.POC)},
 
  {2, "enabled",            "=%i",         NULL,          (void *)(&config.uarts_enabled)},
  {2, "nuarts",             "=%i",         NULL,          (void *)(&config.nuarts)},
  {2, "device",             "%i",          change_device, (void *)(&tempL)},
  {2, "enddevice",          "",            end_device,    NULL},
  {2, "baseaddr",           "=0x%x",       uart_baseaddr, (void *)(&tempUL)},
  {2, "jitter",             "=%i",         uart_jitter,   (void *)(&tempL)},
  {2, "rxfile",             "=\"%s\"",     uart_rxfile,   (void *)(&tempS[0])},
  {2, "txfile",             "=\"%s\"",     uart_txfile,   (void *)(&tempS[0])},
 
  {3, "enabled",            "=%i",         NULL,          (void *)(&config.dmas_enabled)},
  {3, "ndmas",              "=%i",         NULL,          (void *)(&config.ndmas)},
  {3, "device",             "%i",          change_device, (void *)(&tempL)},
  {3, "enddevice",          "",            end_device,    NULL},
  {3, "baseaddr",           "=0x%x",       dma_baseaddr,  (void *)(&tempUL)},
  {3, "irq",                "=%i",         dma_baseaddr,  (void *)(&tempL)},
 
  {4, "memory_table_file",  "=\"%s\"",     NULL,          (void *)(&config.memory.memory_table_file[0])},
  {4, "random_seed",        "=%i",         NULL,          (void *)(&config.memory.random_seed)},
  {4, "pattern",            "=%i",         NULL,          (void *)(&config.memory.pattern)},
  {4, "type",               "=%s ",        memory_type,   (void *)(&tempS[0])},
 
  {5, "ver",                "=0x%x",       NULL,          (void *)(&config.cpu.ver)},
  {5, "rev",                "=0x%x",       NULL,          (void *)(&config.cpu.rev)},
  {5, "upr",                "=0x%x",       NULL,          (void *)(&config.cpu.upr)},
  {5, "hazards",            "=%i",         NULL,          (void *)(&config.cpu.hazards)},
  {5, "history",            "=%i",         NULL,          (void *)(&config.cpu.history)},
  {5, "superscalar",        "=%i",         NULL,          (void *)(&config.cpu.superscalar)},
  {5, "dependstats",        "=%i",         NULL,          (void *)(&config.cpu.dependstats)},
  {5, "dependency",         "=%i",         NULL,          (void *)(&config.cpu.dependency)},
  {5, "slp",                "=%i",         NULL,          (void *)(&config.cpu.slp)},
  {5, "bpb",                "=%i",         NULL,          (void *)(&config.cpu.bpb)},
  {5, "btic",               "=%i",         NULL,          (void *)(&config.cpu.btic)},
 
  {6, "debug",              "=%i",         NULL,          (void *)(&config.sim.debug)},
  {6, "iprompt",            "=%i",         NULL,          (void *)(&config.sim.iprompt)},
  {6, "verbose",            "=%i",         NULL,          (void *)(&config.sim.verbose)},
  {6, "profile",            "=%i",         NULL,          (void *)(&config.sim.profile)},
  {6, "prof_fn",            "=\"%s\"",     NULL,          (void *)(&config.sim.prof_fn[0])},
 
  {6, "exe_log",            "=%i",         NULL,          (void *)(&config.sim.exe_log)},
  {6, "exe_log_fn",         "=\"%s\"",     NULL,          (void *)(&config.sim.exe_log_fn[0])},
 
  {7, "enabled",            "=%i",         NULL,          (void *)(&config.debug.enabled)},
  {7, "gdb_enabled",        "=%i",         NULL,          (void *)(&config.debug.gdb_enabled)},
  {7, "server_port",        "=%i",         NULL,          (void *)(&config.debug.server_port)},
 
  {8, "enabled",            "=%i",         NULL,          (void *)(&config.vapi.enabled)},
  {8, "server_port",        "=%i",         NULL,          (void *)(&config.vapi.server_port)},
 
  {9, "enabled",            "=%i",         NULL,          (void *)(&config.ethernets_enabled)},
  {9, "neths",              "=%i",         NULL,          (void *)(&config.nethernets)},
  {9, "device",             "%i",          change_device, (void *)(&tempL)},
  {9, "enddevice",          "",            end_device,    NULL},
  {9, "baseaddr",           "=0x%x",       eth_baseaddr,  (void *)(&tempUL)},
  {9, "dma",                "=%i",         eth_dma,       (void *)(&tempL)}
};
 
/* *INDENT-ON* */
 
int current_device = -1;
void change_device () {
  current_device = tempL;
}
 
void end_device () {
  current_device = -1;
}
 
void uart_baseaddr () {
  if (current_device >= 0 && current_device < config.nuarts)
    config.uarts[current_device].baseaddr = tempUL;
  else {
    fprintf (stderr, "ERROR: invalid device number.");
    exit (-1);
  }
}
 
void uart_jitter () {
  if (current_device >= 0 && current_device < config.nuarts)
    config.uarts[current_device].jitter = tempL;
  else {
    fprintf (stderr, "ERROR: invalid device number.");
    exit (-1);
  }
}
 
void uart_rxfile () {
  if (current_device >= 0 && current_device < config.nuarts)
    strcpy (config.uarts[current_device].rxfile, tempS);
  else {
    fprintf (stderr, "ERROR: invalid device number.");
    exit (-1);
  }
}
 
void uart_txfile () {
  if (current_device >= 0 && current_device < config.nuarts)
    strcpy (config.uarts[current_device].txfile, tempS);
  else {
    fprintf (stderr, "ERROR: invalid device number.");
    exit (-1);
  }
}
 
void dma_baseaddr () {
  if (current_device >= 0 && current_device < config.ndmas)
    config.dmas[current_device].baseaddr = tempUL;
  else {
    fprintf (stderr, "ERROR: invalid device number.");
    exit (-1);
  }
}
 
void dma_irq () {
  if (current_device >= 0 && current_device < config.ndmas)
    config.dmas[current_device].irq = tempL;
  else {
    fprintf (stderr, "ERROR: invalid device number.");
    exit (-1);
  }
}
 
void memory_type () {
  if (strcmp (tempS, "unknown") == 0)
    config.memory.type = MT_UNKNOWN;
  else if (strcmp (tempS, "random") == 0)
    config.memory.type = MT_RANDOM;
  else if (strcmp (tempS, "pattern") == 0)
    config.memory.type = MT_PATTERN;
  else if (strcmp (tempS, "zero") == 0) {
    config.memory.type = MT_PATTERN;
    config.memory.pattern = 0;
  } else {
    fprintf (stderr, "ERROR: invalid memory type '%s'.\n", tempS);
    exit (-1);
  }
}
 
void eth_baseaddr () {
  if (current_device >= 0 && current_device < config.nethernets)
    config.ethernets[current_device].baseaddr = tempUL;
  else {
    fprintf (stderr, "ERROR: invalid device number.");
    exit (-1);
  }
}
 
void eth_dma () {
  if (current_device >= 0 && current_device < config.nethernets)
    config.ethernets[current_device].dma = tempL;
  else {
    fprintf (stderr, "ERROR: invalid device number.");
    exit (-1);
  }
}
 
/* Read environment from a script file. Does not fail - assumes defaukt configuration instead.
   The syntax of script file is:
   param = value
   section x
     data
     param = value
   end
 
   Example:
   section mc
     memory_table_file = sim.mem
     enable = 1
     POC = 0x47892344
   end
 
 */
 
void read_script_file (char *filename)
{  
  FILE *f;
  unsigned long memory_needed = 0;
  char *home = getenv("HOME");
  char ctmp[STR_SIZE];
  int local = 1;
  int section = 0;
 
  sprintf(ctmp, "%s/.or1k/%s", home, filename);
  if ((f = fopen (filename, "rt")) != NULL
      || home != NULL && !(local = 0) && (f = fopen (ctmp, "rt")) != NULL) {
    unsigned long start, length;
    char type[STR_SIZE];
    int nparam;
    int rd, wd;
    printf ("Reading script file from '%s':\n", local ? filename : ctmp);
    while (!feof(f)) {
      char param[STR_SIZE];
      if (fscanf(f, "%s ", &param) != 1) break;
      /* Is this a sections? */
      if (strcmp (param, "section") == 0) {
        int i;
        section = 0;
        if (fscanf (f, "%s\n", &param) != 1) {
          fprintf (stderr, "%s: ERROR: Section name required.\n", local ? filename : ctmp);
          exit (-1);
        }
        for (i = 1; i < sizeof(sections) / sizeof(struct section); i++)
          if (strcmp (sections[i].name, param) == 0) {
            section = i;
            break;
          }
        if (!section) {
          fprintf (stderr, "%s: WARNING: Unknown section: %s; ignoring.\n", local ? filename : ctmp, param);
          /* just skip section */
          while (fscanf (f, "%s\n", &param) != 1 && strcmp (param, "end"));
        }
      } else if (strcmp (param, "end") == 0) {
        section = 0;
      } else if (strncmp (param, "/*", 2) == 0) {
        char c0 = 0, c1 = 0;
        while (c0 != '*' || c1 != '/') {
          c0 = c1;
          c1 = fgetc(f);
          if (feof(f)) {
            fprintf (stderr, "%s: ERROR: Comment reached EOF.\n", local ? filename : ctmp);
            exit (-1);
          }
        }
      } else {
        int i, found = -1;        
        for (i = 0; i < sizeof(config_params)/sizeof(struct config_params); i++)
          if (config_params[i].section == section && strcmp (config_params[i].name, param) == 0) {
            found = i;
            break;
          }
        if (found < 0) {
          fprintf (stderr, "%s: WARNING: Invalid parameter: %s; ignoring.\n", local ? filename : ctmp, param);
          while (fgetc(f) != '\n' || feof(f));
          continue;
        }
 
        /* Parse parameter value */
        {
          if (config_params[found].type[0])
            if(fscanf_ex (f, config_params[found].type, config_params[found].addr))
              exit (1);
        }
        if (config_params[found].func)
          config_params[found].func();
      }
    }
    fclose (f);
  } else {
    fprintf (stderr, "Cannot read script file from '%s',\nneither '%s'; assuming standard configuration.\n", filename, ctmp);
  }
 
  /* Initialize memory table.  */
  sim_read_memory_table (config.memory.memory_table_file);
}
 

Go to most recent revision | 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.