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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_47/] [or1ksim/] [cpu/] [common/] [abstract.c] - Rev 897

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

/* abstract.c -- Abstract entities
   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. */
 
/* Abstract memory and routines that go with this. I need to
add all sorts of other abstract entities. Currently we have
only memory. */
 
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
 
#include "config.h"
#include "sim-config.h"
 
#include "parse.h"
#include "abstract.h"
#include "labels.h"
#include "arch.h"
#include "execute.h"
#include "sprs.h"
#include "stats.h"
#include "except.h"
#include "debug_unit.h"
#include "opcode/or32.h"
#include "support/profile.h"
 
extern unsigned long reg[];
extern char *disassembled;
 
/* This is an abstract+physical memory array rather than only physical
   memory array */
static unsigned long *simmem32;
 
/* Pointer to memory area descriptions that are assigned to individual
   peripheral devices. */
struct dev_memarea *dev_list;
 
/* Temporary variable to increase speed.  */
struct dev_memarea *cur_area;
 
/* These are set by mmu if cache inhibit bit is set for current acces.  */
int data_ci, insn_ci;
 
/* Virtual address of current access. */
unsigned long cur_vadd;
 
/* Calculates bit mask to fit the data */
unsigned long bit_mask (unsigned long data) {
  int i = 0;
  data--;
  while (data >> i)
    data |= 1 << i++;
  return data;
}
 
/* Register read and write function for a memory area.
   addr is inside the area, if addr & addr_mask == addr_compare
   (used also by peripheral devices like 16450 UART etc.) */
void register_memoryarea_mask(unsigned long addr_mask, unsigned long addr_compare,
                         unsigned long size, unsigned granularity,
                         unsigned long (readfunc)(unsigned long),
                         void (writefunc)(unsigned long, unsigned long))
{
  struct dev_memarea **pptmp;
  unsigned long size_mask = bit_mask (size);
  int found_error = 0;
  addr_compare &= addr_mask;
 
  debug(5, "addr & %08x == %08x to %08x, size %08x, gran %iB\n", addr_mask, addr_compare, addr_compare | bit_mask (size), size, granularity);
  /* Go to the end of the list. */
  for(pptmp = &dev_list; *pptmp; pptmp = &(*pptmp)->next)
    if ((addr_compare >= (*pptmp)->addr_compare) && (addr_compare < (*pptmp)->addr_compare + (*pptmp)->size)
     || (addr_compare + size > (*pptmp)->addr_compare) && (addr_compare < (*pptmp)->addr_compare + (*pptmp)->size)) {
      if (!found_error) {
        fprintf (stderr, "ERROR: Overlapping memory area(s):\n");
        fprintf (stderr, "\taddr & %08x == %08x to %08x, size %08x, gran %iB\n", addr_mask, addr_compare, addr_compare | bit_mask (size), size, granularity);
      }
      found_error = 1;
      fprintf (stderr, "and\taddr & %08x == %08x to %08x, size %08x, gran %iB\n", (*pptmp)->addr_mask, (*pptmp)->addr_compare,
        (*pptmp)->addr_compare | (*pptmp)->size_mask, (*pptmp)->size, (*pptmp)->granularity);
    }
 
  if (found_error)
    exit (-1);
 
  cur_area = *pptmp = (struct dev_memarea *)malloc(sizeof(struct dev_memarea));
  (*pptmp)->addr_mask = addr_mask;
  (*pptmp)->addr_compare = addr_compare;
  (*pptmp)->size = size;
  (*pptmp)->size_mask = size_mask;
  (*pptmp)->granularity = granularity;
  (*pptmp)->readfunc = readfunc;
  (*pptmp)->writefunc = writefunc;
  (*pptmp)->log = 0;
  (*pptmp)->delayr = 2;
  (*pptmp)->delayw = 2;
  (*pptmp)->next = NULL;
}
 
/* Register read and write function for a memory area.   
   Memory areas should be aligned. Memory area is rounded up to
   fit the nearest 2^n aligment.
   (used also by peripheral devices like 16450 UART etc.) */
void register_memoryarea(unsigned long addr,
                         unsigned long size, unsigned granularity,
                         unsigned long (readfunc)(unsigned long),
                         void (writefunc)(unsigned long, unsigned long))
{
  unsigned long size_mask = bit_mask (size);
  unsigned long addr_mask = ~size_mask;
  register_memoryarea_mask (addr_mask, addr & addr_mask,
                      size_mask + 1, granularity,
                      readfunc, writefunc);
}
 
 
/* Check if access is to registered area of memory. */
inline struct dev_memarea *verify_memoryarea(unsigned long addr)
{
  struct dev_memarea *ptmp;
 
  /* Check cached value first */
  if (cur_area && (addr & cur_area->addr_mask) == (cur_area->addr_compare & cur_area->addr_mask))
    return cur_area;
 
  /* When mc is enabled, we must check valid also, otherwise we assume it is nonzero */
  IFF (config.mc.enabled) {
    /* Check list of registered devices. */
    for(ptmp = dev_list; ptmp; ptmp = ptmp->next)
      if ((addr & ptmp->addr_mask) == (ptmp->addr_compare & ptmp->addr_mask) && ptmp->valid)
        return cur_area = ptmp;
  } else {
    /* Check list of registered devices. */
    for(ptmp = dev_list; ptmp; ptmp = ptmp->next)
      if ((addr & ptmp->addr_mask) == (ptmp->addr_compare & ptmp->addr_mask))
        return cur_area = ptmp;
  }
  return cur_area = NULL;
}
 
/* Finds the memory area for the address and adjust the read and write delays for it. */
void adjust_rw_delay(unsigned long memaddr, unsigned long delayr, unsigned long delayw)
{
  if (verify_memoryarea(memaddr)) {
    cur_area->delayr = delayr;
    cur_area->delayw = delayw;
  }
}
 
inline unsigned long evalsim_mem32(unsigned long memaddr)
{
  unsigned long temp;
 
  if (verify_memoryarea(memaddr)) {
    switch(cur_area->granularity) {
    case 4:
      temp = cur_area->readfunc(memaddr);
      runtime.sim.mem_cycles += cur_area->delayr;
      break;
    case 1:
      temp = cur_area->readfunc(memaddr) << 24;
      temp |= cur_area->readfunc(memaddr + 1) << 16;
      temp |= cur_area->readfunc(memaddr + 2) << 8;
      temp |= cur_area->readfunc(memaddr + 3);
      runtime.sim.mem_cycles += cur_area->delayr * 4;
      break;
    case 2:
      temp = cur_area->readfunc(memaddr) << 16;
      temp |= cur_area->readfunc(memaddr + 2);
      runtime.sim.mem_cycles += cur_area->delayr * 2;
      break;
    }
  }
  return temp;
}
 
unsigned short evalsim_mem16(unsigned long memaddr)
{
  unsigned long temp;
 
  if (verify_memoryarea(memaddr)) {
    switch(cur_area->granularity) {
    case 1:
      temp = cur_area->readfunc(memaddr) << 8;
      temp |= cur_area->readfunc(memaddr + 1);
      runtime.sim.mem_cycles += cur_area->delayr * 2;
      break;
    case 2:
      temp = cur_area->readfunc(memaddr);
      runtime.sim.mem_cycles += cur_area->delayr;
      break;
    case 4:
      temp = evalsim_mem32 (memaddr & ~3ul);
      if (memaddr & 2)
        temp &= 0xffff;
      else
        temp >>= 16;
      break;
    } 
  }
  return temp;
}
 
unsigned char evalsim_mem8(unsigned long memaddr)
{
  unsigned long temp;
 
  if (verify_memoryarea(memaddr)) {
    switch(cur_area->granularity) {
    case 1:
      temp = cur_area->readfunc(memaddr);
      runtime.sim.mem_cycles += cur_area->delayr;
      break;
    case 2:
      temp = evalsim_mem16 (memaddr & ~1ul);
      if (memaddr & 1)
        temp &= 0xff;
      else
        temp >>= 8;
      break;
    case 4:
      temp = evalsim_mem32 (memaddr & ~3ul);
      temp >>= 8 * (3 - (memaddr & 3));
      temp &= 0xff;
      break;
    } 
  }
  return temp;
}
 
/* Returns 32-bit values from mem array. Big endian version. */
unsigned long read_mem(unsigned long memaddr,int* breakpoint)
{
  unsigned long temp;
  struct dev_memarea *dev;
 
  cur_vadd = memaddr;
  if (config.debug.enabled)
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
  temp = evalsim_mem32(memaddr);
  if (!cur_area) {
    printf("EXCEPTION: read out of memory (16-bit access to %.8lx)\n", memaddr);
    except_handle(EXCEPT_BUSERR, cur_vadd);
    temp = 0;
  }
 
  if (!pending.valid && cur_area->log)
    fprintf (cur_area->log, "[%08x] -> read %08x\n", memaddr, temp);
  if (config.debug.enabled)
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
  return temp;
}
 
/* Returns 32-bit values from mem array. Big endian version. */
unsigned long eval_mem32(unsigned long memaddr,int* breakpoint)
{
 
  unsigned long temp;
  struct dev_memarea *dev;
 
  if (config.sim.mprofile)
    mprofile (memaddr, MPROF_32 | MPROF_READ);
 
  if (memaddr & 3) {
    except_handle (EXCEPT_ALIGN, memaddr);
    return 0;
  }
 
  if (config.debug.enabled)
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
 
  cur_vadd = memaddr;
 
  memaddr = dmmu_translate(memaddr, 0);
  if (pending.valid)
    return 0;
 
  temp = dc_simulate_read(memaddr, 4);
  if (!cur_area) {
    printf("EXCEPTION: read out of memory (32-bit access to %.8lx)\n", memaddr);
    except_handle(EXCEPT_BUSERR, cur_vadd);
    temp = 0;
  }
 
  if (!pending.valid && cur_area->log)
    fprintf (cur_area->log, "[%08x] -> read %08x\n", memaddr, temp);
  if (config.debug.enabled)
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
  return temp;
}
 
/* Returns 32-bit values from mem array. Big endian version. */
unsigned long eval_insn(unsigned long memaddr,int* breakpoint)
{
  unsigned long temp;
  struct dev_memarea *dev;
 
  if (config.sim.mprofile)
    mprofile (memaddr, MPROF_32 | MPROF_FETCH);
//  memaddr = simulate_ic_mmu_fetch(memaddr);
  cur_vadd = pc;
  if (config.debug.enabled)
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
  if (config.ic.enabled) 
    temp = ic_simulate_fetch(memaddr);
  else
    temp = evalsim_mem32(memaddr);
  if (!cur_area) {
    printf("EXCEPTION: read out of memory (32-bit access to %.8lx)\n", memaddr);
    except_handle(EXCEPT_BUSERR, cur_vadd);
    temp = 0;
  }
 
  if (!pending.valid && cur_area->log)
    fprintf (cur_area->log, "[%08x] -> read %08x\n", memaddr, temp);
  if (config.debug.enabled)
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
  return temp;
}
 
/* Returns 16-bit values from mem array. Big endian version. */
 
unsigned short eval_mem16(unsigned long memaddr,int* breakpoint)
{
  unsigned short temp;
 
  if (config.sim.mprofile)
    mprofile (memaddr, MPROF_16 | MPROF_READ);
 
  if (memaddr & 1) {
    except_handle (EXCEPT_ALIGN, memaddr);
    return 0;
  }
 
  if (config.debug.enabled)
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
 
  cur_vadd = memaddr;
 
  memaddr = dmmu_translate(memaddr, 0);
  if (pending.valid)
    return 0;
 
  temp = (unsigned short)dc_simulate_read(memaddr, 2);
  if (!cur_area) {
    printf("EXCEPTION: read out of memory (16-bit access to %.8lx)\n", memaddr);
    except_handle(EXCEPT_BUSERR, cur_vadd);
    temp = 0;
  }
 
  if (!pending.valid && cur_area->log)
    fprintf (cur_area->log, "[%08x] -> read %08x\n", memaddr, temp);
  if (config.debug.enabled)
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
  return temp;
}
 
/* Returns 8-bit values from mem array. */
 
unsigned char eval_mem8(unsigned long memaddr,int* breakpoint)
{
  unsigned char temp;
 
  if (config.sim.mprofile)
    mprofile (memaddr, MPROF_8 | MPROF_READ);
 
  if (config.debug.enabled)
    *breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr);  /* 28/05/01 CZ */
 
  cur_vadd = memaddr;
 
  memaddr = dmmu_translate(memaddr, 0);
  if (pending.valid)
    return 0;
 
  temp = (unsigned char)dc_simulate_read(memaddr, 1);
  if (!cur_area) {
    printf("EXCEPTION: read out of memory (8-bit access to %.8lx)\n", memaddr);
    except_handle(EXCEPT_BUSERR, cur_vadd);
    temp = 0;
  }
 
  if (!pending.valid && cur_area->log)
    fprintf (cur_area->log, "[%08x] -> read %08x\n", memaddr, temp);
  if (config.debug.enabled)
    *breakpoint += CheckDebugUnit(DebugLoadData,temp);  /* MM170901 */
  return temp;
}
 
void setsim_mem32(unsigned long memaddr, unsigned long value)
{
  struct dev_memarea *dev;
 
  if (verify_memoryarea(memaddr)) {
    switch(cur_area->granularity) {
    case 4:
      cur_area->writefunc(memaddr, value);
      runtime.sim.mem_cycles += cur_area->delayw;
      break;
    case 1:
      cur_area->writefunc(memaddr    , (value >> 24) & 0xFF);
      cur_area->writefunc(memaddr + 1, (value >> 16) & 0xFF);
      cur_area->writefunc(memaddr + 2, (value >>  8) & 0xFF);
      cur_area->writefunc(memaddr + 3, (value      ) & 0xFF);
      runtime.sim.mem_cycles += cur_area->delayw * 4;
      break;
    case 2:
      cur_area->writefunc(memaddr, (value >> 16) & 0xFFFF);
      cur_area->writefunc(memaddr + 2, value & 0xFFFF);
      runtime.sim.mem_cycles += cur_area->delayw * 2;
      break;
    }
  } else {
    printf("EXCEPTION: write out of memory (32-bit access to %.8lx)\n", memaddr);
    except_handle(EXCEPT_BUSERR, cur_vadd);
  }
}
 
void setsim_mem16(unsigned long memaddr, unsigned short value)
{
  unsigned long temp;
  if (verify_memoryarea(memaddr)) {
    switch(cur_area->granularity) {
    case 1:
      cur_area->writefunc(memaddr, (value >> 8) & 0xFF);
      cur_area->writefunc(memaddr + 1, value & 0xFF);
      runtime.sim.mem_cycles += cur_area->delayw * 2;
      break;
    case 2:
      cur_area->writefunc(memaddr, value & 0xFFFF);
      runtime.sim.mem_cycles += cur_area->delayw;
      break;
    case 4:
      temp = evalsim_mem32 (memaddr & ~3ul);
      temp &= 0xffff << ((memaddr & 2) ? 16 : 0);
      temp |= (unsigned long)(value & 0xffff) << ((memaddr & 2) ? 0 : 16);
      setsim_mem32 (memaddr & ~3ul, temp);
      break;
    } 
  } else {
    printf("EXCEPTION: write out of memory (16-bit access to %.8lx)\n", memaddr);
    except_handle(EXCEPT_BUSERR, cur_vadd);
  }
}
 
void setsim_mem8(unsigned long memaddr, unsigned char value)
{
  unsigned long temp;
  if (verify_memoryarea(memaddr)) {
    switch (cur_area->granularity) {
    case 1:
      cur_area->writefunc(memaddr, value);
      runtime.sim.mem_cycles += cur_area->delayw;
      break;
    case 2:
      temp = evalsim_mem16 (memaddr & ~1ul);
      temp &= 0xff << ((memaddr & 1) ? 8 : 0);
      temp |= (unsigned short)(value & 0xff) << ((memaddr & 1) ? 0 : 8);
      setsim_mem16 (memaddr & ~1ul, temp);
      break;
    case 4:
      temp = evalsim_mem32 (memaddr & ~3ul);
      temp &= ~(0xff << (8 * (3 - (memaddr & 3))));
      temp |= (unsigned long)(value & 0xff) << (8 * (3 - (memaddr & 3)));
      setsim_mem32 (memaddr & ~3ul, temp);
      break;
    }
  } else {
    printf("EXCEPTION: write out of memory (8-bit access to %.8lx)\n", memaddr);
    except_handle(EXCEPT_BUSERR, cur_vadd);
  }
}
 
/* Set mem, 32-bit. Big endian version. */
 
void set_mem32(unsigned long memaddr, unsigned long value,int* breakpoint)
{
  if (config.sim.mprofile)
    mprofile (memaddr, MPROF_32 | MPROF_WRITE);
 
  if (memaddr & 3) {
    except_handle (EXCEPT_ALIGN, memaddr);
    return;
  }
 
  cur_vadd = memaddr;
  memaddr = dmmu_translate(memaddr, 1);;
  /* If we produced exception don't set anything */
  if (pending.valid)
    return;
 
  if (config.debug.enabled) {
    *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr);  /* 28/05/01 CZ */
    *breakpoint += CheckDebugUnit(DebugStoreData,value);
  }
 
  if (cur_area->log)
    fprintf (cur_area->log, "[%08x] -> write %08x\n", memaddr, value);
 
  dc_simulate_write(memaddr, value, 4); 
}
 
/* Set mem, 16-bit. Big endian version. */
 
void set_mem16(unsigned long memaddr, unsigned short value,int* breakpoint)
{
  if (config.sim.mprofile)
    mprofile (memaddr, MPROF_16 | MPROF_WRITE);
 
  if (memaddr & 1) {
    except_handle (EXCEPT_ALIGN, memaddr);
    return;
  }
 
  cur_vadd = memaddr;
  memaddr = dmmu_translate(memaddr, 1);;
  /* If we produced exception don't set anything */
  if (pending.valid)
    return;
 
  if (config.debug.enabled) {
    *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr);  /* 28/05/01 CZ */
    *breakpoint += CheckDebugUnit(DebugStoreData,value);
  }
 
  if (cur_area->log)
    fprintf (cur_area->log, "[%08x] -> write %08x\n", memaddr, value);
 
  dc_simulate_write(memaddr, (unsigned long)value, 2); 
}
 
/* Set mem, 8-bit. */
 
void set_mem8(unsigned long memaddr, unsigned char value,int* breakpoint)
{
  if (config.sim.mprofile)
    mprofile (memaddr, MPROF_8 | MPROF_WRITE);
 
  cur_vadd = memaddr;
  memaddr = dmmu_translate(memaddr, 1);;
  /* If we produced exception don't set anything */
  if (pending.valid) return;
 
  if (config.debug.enabled) {
    *breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr);  /* 28/05/01 CZ */
    *breakpoint += CheckDebugUnit(DebugStoreData,value);
  }
 
  if (cur_area->log)
    fprintf (cur_area->log, "[%08x] -> write %08x\n", memaddr, value);
 
  dc_simulate_write(memaddr, (unsigned long)value, 1); 
}
 
void dumpmemory(unsigned int from, unsigned int to, int disasm, int nl)
{
  unsigned int i, j;
  struct label_entry *tmp;
  int breakpoint = 0;
  int ilen = disasm ? 4 : 16;
 
  for(i = from; i < to; i += ilen) {
    printf("%.8x: ", i);
    for (j = 0; j < ilen;) {
      int data = -1;
      if (!disasm) {
        tmp = NULL;
        if (verify_memoryarea(i+j)) {
          struct label_entry *entry;
          entry = get_label(i + j);
          if (entry)
            printf("(%s)", entry->name);
          printf("%02x ", data = evalsim_mem8(i+j));
        } else printf("XX ");  
        j++;
      } else {
        int breakpoint;
        unsigned int _insn = read_mem(i, &breakpoint);
        int index = insn_decode (_insn);
        int len = insn_len (index);
 
        tmp = NULL;
        if (verify_memoryarea(i+j)) {
          struct label_entry *entry;
          entry = get_label(i + j);
          if (entry)
            printf("(%s)", entry->name);
 
          printf(": %08x ", (unsigned long)_insn);
          if (index >= 0) {
            disassemble_insn (_insn);
            printf(" %s", disassembled);
          } else
            printf("<invalid>");
        } else printf("XXXXXXXX");
        j += len;
      }
    }
    if (nl)
      printf ("\n");
  }
}
 
unsigned long simmem_read_word(unsigned long addr) {
  return simmem32[(cur_area->misc + (addr & cur_area->size_mask)) >> 2];
}
 
void simmem_write_word(unsigned long addr, unsigned long value) {
  simmem32[(cur_area->misc + (addr & cur_area->size_mask)) >> 2] = value;
}
 
unsigned long simmem_read_zero(unsigned long addr) {
  if (config.sim.verbose)
    fprintf (stderr, "WARNING: memory read from non-read memory area 0x%08x.\n", addr);
  return 0;
}
 
void simmem_write_null(unsigned long addr, unsigned long value) {
  if (config.sim.verbose)
    fprintf (stderr, "WARNING: memory write to 0x%08x, non-write memory area (value 0x%08x).\n", addr, value);
}
 
/* Initialize memory table from a config struct */
 
void init_memory_table ()
{
  unsigned long memory_needed = 0;
 
  /* If nothing was defined, use default memory block */
  if (config.memory.nmemories) {
    int i;
    for (i = 0; i < config.memory.nmemories; i++) {
      unsigned long start = config.memory.table[i].baseaddr;
      unsigned long length = config.memory.table[i].size;
      char *type = config.memory.table[i].name;
      int rd = config.memory.table[i].delayr;
      int wd = config.memory.table[i].delayw;
      int ce = config.memory.table[i].ce;
      if (config.sim.verbose)
        debug (1, "%08X %08X (%i KB): %s (activated by CE%i; read delay = %icyc, write delay = %icyc)\n",
          start, length, length >> 10, type, ce, rd, wd);
      register_memoryarea(start, length, 4, &simmem_read_word, &simmem_write_word);
      cur_area->misc = memory_needed;
      cur_area->chip_select = ce;
      cur_area->valid = 1;
      cur_area->delayw = wd;
      cur_area->delayr = rd;
      if (config.memory.table[i].log[0] != '\0') {
        if ((cur_area->log = fopen (config.memory.table[i].log, "wt+")) == NULL)
          fprintf (stderr, "WARNING: Cannot open '%s'.\n", config.memory.table[i].log);
      } else
        cur_area->log = NULL;
      memory_needed += cur_area->size;
    }
    printf ("\n");
  } else {
    if (config.sim.verbose)
      fprintf (stderr, "WARNING: Memory not defined, assuming standard configuration.\n");
    register_memoryarea(DEFAULT_MEMORY_START, DEFAULT_MEMORY_LEN, 4, &simmem_read_word, &simmem_write_word);
    cur_area->misc = memory_needed;
    cur_area->chip_select = 0;
    cur_area->valid = 1;
    cur_area->delayw = 1;
    cur_area->delayr = 1;
    cur_area->log = NULL;      
    memory_needed += cur_area->size;
  }
 
  simmem32 = (unsigned long *) malloc (sizeof (unsigned long) * ((memory_needed + 3) / 4));
  if (!simmem32) {
    fprintf (stderr, "Failed to allocate sim memory. Aborting\n");
    exit (-1);
  }
}
 
/* Changes read/write memory in read/write only */
 
void lock_memory_table ()
{
  struct dev_memarea *ptmp;
 
  /* Check list of registered devices. */
  for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
    if (ptmp->delayr < 0 && ptmp->readfunc == &simmem_read_word)
      ptmp->readfunc = &simmem_read_zero;
    if (ptmp->delayw < 0 && ptmp->writefunc == &simmem_write_word)
      ptmp->writefunc = &simmem_write_null;
 
    /* If this mem area is not for memory chip under MC control
       then this area is valid all the time */
    if (ptmp->readfunc != &simmem_read_word) {
      ptmp->valid = 1;
      ptmp->chip_select = -1;
    }
  }
}
 
/* Closes files, etc. */
 
void done_memory_table ()
{
  struct dev_memarea *ptmp;
 
  /* Check list of registered devices. */
  for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
    if (ptmp->log)
      fclose (ptmp->log);
  }
}
 
/* Displays current memory configuration */
 
void memory_table_status ()
{
  struct dev_memarea *ptmp;
 
  /* Check list of registered devices. */
  for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
    printf ("addr & %08x == %08x to %08x, size %08x, gran %iB\n",
      ptmp->addr_mask, ptmp->addr_compare, ptmp->addr_compare | bit_mask (ptmp->size),
      ptmp->size, ptmp->granularity);
    printf ("\t");
    if (ptmp->delayr >= 0)
      printf ("read delay = %i cycles, ", ptmp->delayr);
    else
      printf ("reads not possible, ");
 
    if (ptmp->delayw >= 0)
      printf ("write delay = %i cycles", ptmp->delayw);
    else
      printf ("writes not possible");
 
    if (ptmp->log)
      printf (", (logged)\n");
    else
      printf ("\n");
  }
}
 
/* Outputs time in pretty form to dest string */
 
char *generate_time_pretty (char *dest, long time_ps)
{
  int exp3 = 0;
  if (time_ps) {
    while ((time_ps % 1000) == 0) {
      time_ps /= 1000;
      exp3++;
    }
  }
  sprintf (dest, "%i%cs", time_ps, "pnum"[exp3]);
  return dest;
}
 

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.