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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_50/] [or1ksim/] [peripheral/] [mc.c] - Diff between revs 804 and 970

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 804 Rev 970
/* mc.c -- Simulation of Memory Controller
/* mc.c -- Simulation of Memory Controller
         Copyright (C) 2001 by Marko Mlinar, markom@opencores.org
         Copyright (C) 2001 by Marko Mlinar, markom@opencores.org
 
 
         This file is part of OpenRISC 1000 Architectural Simulator.
         This file is part of OpenRISC 1000 Architectural Simulator.
 
 
         This program is free software; you can redistribute it and/or modify
         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
         it under the terms of the GNU General Public License as published by
         the Free Software Foundation; either version 2 of the License, or
         the Free Software Foundation; either version 2 of the License, or
         (at your option) any later version.
         (at your option) any later version.
 
 
         This program is distributed in the hope that it will be useful,
         This program is distributed in the hope that it will be useful,
         but WITHOUT ANY WARRANTY; without even the implied warranty of
         but WITHOUT ANY WARRANTY; without even the implied warranty of
         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
         GNU General Public License for more details.
         GNU General Public License for more details.
 
 
         You should have received a copy of the GNU General Public License
         You should have received a copy of the GNU General Public License
         along with this program; if not, write to the Free Software
         along with this program; if not, write to the Free Software
         Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
         Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
*/
 
 
/* Enable memory controller, via:
/* Enable memory controller, via:
  section mc
  section mc
    enable = 1
    enable = 1
    POC = 0x13243545
    POC = 0x13243545
  end
  end
 
 
   Limitations:
   Limitations:
    - memory refresh is not simulated
    - memory refresh is not simulated
*/
*/
 
 
#include "mc.h"
#include "mc.h"
#include "abstract.h"
#include "abstract.h"
#include "sim-config.h"
#include "sim-config.h"
 
 
extern struct dev_memarea *dev_list;
extern struct dev_memarea *dev_list;
 
 
static struct mc mc;
static struct mc mc;
 
 
void set_csc_tms (int cs, unsigned long csc, unsigned long tms) {
void set_csc_tms (int cs, unsigned long csc, unsigned long tms) {
  struct dev_memarea *mem_dev = dev_list;
  struct dev_memarea *mem_dev = dev_list;
 
 
  while (mem_dev) {
  while (mem_dev) {
    if (mem_dev->chip_select == cs) {
    if (mem_dev->chip_select == cs) {
      mem_dev->addr_mask = 0xe0000000 | mc.ba_mask << 21;
      mem_dev->addr_mask = mc.ba_mask << 22;
      mem_dev->addr_compare = ((csc >> MC_CSC_SEL_OFFSET) /* & 0xff*/) << 21;
      mem_dev->addr_compare = ((csc >> MC_CSC_SEL_OFFSET) /* & 0xff*/) << 22;
      mem_dev->valid = (csc >> MC_CSC_EN_OFFSET) & 0x01;
      mem_dev->valid = (csc >> MC_CSC_EN_OFFSET) & 0x01;
 
 
      if ((csc >> MC_CSC_MEMTYPE_OFFSET) && 0x07 == MC_CSC_MEMTYPE_ASYNC) {
      if ((csc >> MC_CSC_MEMTYPE_OFFSET) && 0x07 == MC_CSC_MEMTYPE_ASYNC) {
        mem_dev->delayr = (tms & 0xff) + ((tms >> 8) & 0x0f);
        mem_dev->delayr = (tms & 0xff) + ((tms >> 8) & 0x0f);
        mem_dev->delayw = ((tms >> 12)  & 0x0f) + ((tms >> 16) & 0x0f) + ((tms >> 20) & 0x3f);
        mem_dev->delayw = ((tms >> 12)  & 0x0f) + ((tms >> 16) & 0x0f) + ((tms >> 20) & 0x3f);
      } else if ((csc >> MC_CSC_MEMTYPE_OFFSET) && 0x07 == MC_CSC_MEMTYPE_SDRAM) {
      } else if ((csc >> MC_CSC_MEMTYPE_OFFSET) && 0x07 == MC_CSC_MEMTYPE_SDRAM) {
        mem_dev->delayr = 3 + ((tms >> 4) & 0x03);
        mem_dev->delayr = 3 + ((tms >> 4) & 0x03);
        mem_dev->delayw = 3 + ((tms >> 4) & 0x03);
        mem_dev->delayw = 3 + ((tms >> 4) & 0x03);
      } else if ((csc >> MC_CSC_MEMTYPE_OFFSET) && 0x07 == MC_CSC_MEMTYPE_SSRAM) {
      } else if ((csc >> MC_CSC_MEMTYPE_OFFSET) && 0x07 == MC_CSC_MEMTYPE_SSRAM) {
        mem_dev->delayr = 2;
        mem_dev->delayr = 2;
        mem_dev->delayw = 2;
        mem_dev->delayw = 2;
      } else if ((csc >> MC_CSC_MEMTYPE_OFFSET) && 0x07 == MC_CSC_MEMTYPE_SYNC) {
      } else if ((csc >> MC_CSC_MEMTYPE_OFFSET) && 0x07 == MC_CSC_MEMTYPE_SYNC) {
        mem_dev->delayr = 2;
        mem_dev->delayr = 2;
        mem_dev->delayw = 2;
        mem_dev->delayw = 2;
      }
      }
      return;
      return;
    }
    }
    mem_dev = mem_dev->next;
    mem_dev = mem_dev->next;
  }
  }
}
}
 
 
/* Set a specific MC register with value. */
/* Set a specific MC register with value. */
void mc_write_word(unsigned long addr, unsigned long value)
void mc_write_word(unsigned long addr, unsigned long value)
{
{
        int chipsel;
        int chipsel;
 
 
        debug(5, "mc_write_word(%x,%08x)\n", addr, (unsigned)value);
        debug(5, "mc_write_word(%x,%08x)\n", addr, (unsigned)value);
 
 
  addr -= config.mc.baseaddr;
  addr -= config.mc.baseaddr;
 
 
        switch (addr) {
        switch (addr) {
          case MC_CSR:
          case MC_CSR:
            mc.csr = value;
            mc.csr = value;
            break;
            break;
          case MC_POC:
          case MC_POC:
            fprintf (stderr, "warning: write to MC's POC register!");
            fprintf (stderr, "warning: write to MC's POC register!");
            break;
            break;
          case MC_BA_MASK:
          case MC_BA_MASK:
            mc.ba_mask = value & MC_BA_MASK_VALID;
            mc.ba_mask = value & MC_BA_MASK_VALID;
      for (chipsel = 0; chipsel < N_CE; chipsel++)
      for (chipsel = 0; chipsel < N_CE; chipsel++)
        set_csc_tms (chipsel, mc.csc[chipsel], mc.tms[chipsel]);
        set_csc_tms (chipsel, mc.csc[chipsel], mc.tms[chipsel]);
            break;
            break;
                default:
                default:
                  if (addr >= MC_CSC(0) && addr <= MC_TMS(N_CE - 1)) {
                  if (addr >= MC_CSC(0) && addr <= MC_TMS(N_CE - 1)) {
                    addr -= MC_CSC(0);
                    addr -= MC_CSC(0);
                    if ((addr >> 2) & 1)
                    if ((addr >> 2) & 1)
                      mc.tms[addr >> 3] = value;
                      mc.tms[addr >> 3] = value;
                    else
                    else
                      mc.csc[addr >> 3] = value;
                      mc.csc[addr >> 3] = value;
 
 
                    set_csc_tms (addr >> 3, mc.csc[addr >> 3], mc.tms[addr >> 3]);
                    set_csc_tms (addr >> 3, mc.csc[addr >> 3], mc.tms[addr >> 3]);
                    break;
                    break;
                  } else
                  } else
                        debug(1, "write out of range (addr %x)\n", addr + config.mc.baseaddr);
                        debug(1, "write out of range (addr %x)\n", addr + config.mc.baseaddr);
        }
        }
}
}
 
 
/* Read a specific MC register. */
/* Read a specific MC register. */
unsigned long mc_read_word(unsigned long addr)
unsigned long mc_read_word(unsigned long addr)
{
{
        unsigned long value = 0;
        unsigned long value = 0;
        int chipsel;
        int chipsel;
 
 
        debug(5, "mc_read_word(%x)", addr);
        debug(5, "mc_read_word(%x)", addr);
 
 
  addr -= config.mc.baseaddr;
  addr -= config.mc.baseaddr;
 
 
        switch (addr) {
        switch (addr) {
          case MC_CSR:
          case MC_CSR:
            value = mc.csr;
            value = mc.csr;
            break;
            break;
          case MC_POC:
          case MC_POC:
            value = mc.poc;
            value = mc.poc;
            break;
            break;
          case MC_BA_MASK:
          case MC_BA_MASK:
            value = mc.ba_mask;
            value = mc.ba_mask;
            break;
            break;
                default:
                default:
                  if (addr >= MC_CSC(0) && addr <= MC_TMS(N_CE - 1)) {
                  if (addr >= MC_CSC(0) && addr <= MC_TMS(N_CE - 1)) {
                    addr -= MC_CSC(0);
                    addr -= MC_CSC(0);
                    if ((addr >> 2) & 1)
                    if ((addr >> 2) & 1)
                      value = mc.tms[addr >> 3];
                      value = mc.tms[addr >> 3];
                    else
                    else
                      value = mc.csc[addr >> 3];
                      value = mc.csc[addr >> 3];
                  } else
                  } else
                        debug(1, " read out of range (addr %x)\n", addr + config.mc.baseaddr);
                        debug(1, " read out of range (addr %x)\n", addr + config.mc.baseaddr);
            break;
            break;
        }
        }
        debug(5, " value(%x)\n", value);
        debug(5, " value(%x)\n", value);
        return value;
        return value;
}
}
 
 
/* Read POC register and init memory controler regs. */
/* Read POC register and init memory controler regs. */
void mc_reset()
void mc_reset()
{
{
  struct dev_memarea *mem_dev = dev_list;
  struct dev_memarea *mem_dev = dev_list;
 
 
  if (config.mc.enabled) {
  if (config.mc.enabled) {
        printf("Resetting memory controller.\n");
        printf("Resetting memory controller.\n");
        memset(&mc, 0, sizeof(struct mc));
        memset(&mc, 0, sizeof(struct mc));
 
 
    mc.poc = config.mc.POC;
    mc.poc = config.mc.POC;
 
 
    /* Set CS0 */
    /* Set CS0 */
    mc.csc[0] = (((config.mc.POC & 0x0c) >> 2) << MC_CSC_MEMTYPE_OFFSET) | ((config.mc.POC & 0x03) << MC_CSC_BW_OFFSET) | 1;
    mc.csc[0] = (((config.mc.POC & 0x0c) >> 2) << MC_CSC_MEMTYPE_OFFSET) | ((config.mc.POC & 0x03) << MC_CSC_BW_OFFSET) | 1;
 
 
    if ((mc.csc[0] >> MC_CSC_MEMTYPE_OFFSET) && 0x07 == MC_CSC_MEMTYPE_ASYNC) {
    if ((mc.csc[0] >> MC_CSC_MEMTYPE_OFFSET) && 0x07 == MC_CSC_MEMTYPE_ASYNC) {
      mc.tms[0] = MC_TMS_ASYNC_VALID;
      mc.tms[0] = MC_TMS_ASYNC_VALID;
    } else if ((mc.csc[0] >> MC_CSC_MEMTYPE_OFFSET) && 0x07 == MC_CSC_MEMTYPE_SDRAM) {
    } else if ((mc.csc[0] >> MC_CSC_MEMTYPE_OFFSET) && 0x07 == MC_CSC_MEMTYPE_SDRAM) {
      mc.tms[0] = MC_TMS_SDRAM_VALID;
      mc.tms[0] = MC_TMS_SDRAM_VALID;
    } else if ((mc.csc[0] >> MC_CSC_MEMTYPE_OFFSET) && 0x07 == MC_CSC_MEMTYPE_SSRAM) {
    } else if ((mc.csc[0] >> MC_CSC_MEMTYPE_OFFSET) && 0x07 == MC_CSC_MEMTYPE_SSRAM) {
      mc.tms[0] = MC_TMS_SSRAM_VALID;
      mc.tms[0] = MC_TMS_SSRAM_VALID;
    } else if ((mc.csc[0] >> MC_CSC_MEMTYPE_OFFSET) && 0x07 == MC_CSC_MEMTYPE_SYNC) {
    } else if ((mc.csc[0] >> MC_CSC_MEMTYPE_OFFSET) && 0x07 == MC_CSC_MEMTYPE_SYNC) {
      mc.tms[0] = MC_TMS_SYNC_VALID;
      mc.tms[0] = MC_TMS_SYNC_VALID;
    }
    }
 
 
    while (mem_dev) {
    while (mem_dev) {
      mem_dev->valid = 0;
      mem_dev->valid = 0;
      mem_dev = mem_dev->next;
      mem_dev = mem_dev->next;
    }
    }
 
 
    set_csc_tms (0, mc.csc[0], mc.tms[0]);
    set_csc_tms (0, mc.csc[0], mc.tms[0]);
 
 
        register_memoryarea(config.mc.baseaddr, MC_ADDR_SPACE, 4, mc_read_word, mc_write_word);
        register_memoryarea(config.mc.baseaddr, MC_ADDR_SPACE, 4, 1, mc_read_word, mc_write_word);
  }
  }
}
}
 
 
inline void mc_clock()
inline void mc_clock()
{
{
}
}
 
 
void mc_status()
void mc_status()
{
{
    int i;
    int i;
 
 
    printf( "\nMemory Controller at 0x%08X:\n", config.mc.baseaddr );
    printf( "\nMemory Controller at 0x%08X:\n", config.mc.baseaddr );
    printf( "POC: 0x%08X\n", mc.poc );
    printf( "POC: 0x%08X\n", mc.poc );
    printf( "BAS: 0x%08X\n", mc.ba_mask );
    printf( "BAS: 0x%08X\n", mc.ba_mask );
    printf( "CSR: 0x%08X\n", mc.csr );
    printf( "CSR: 0x%08X\n", mc.csr );
 
 
    for (i=0; i<N_CE; i++) {
    for (i=0; i<N_CE; i++) {
        printf( "CE %02d -  CSC: 0x%08X  TMS: 0x%08X\n", i, mc.csc[i], mc.tms[i]);
        printf( "CE %02d -  CSC: 0x%08X  TMS: 0x%08X\n", i, mc.csc[i], mc.tms[i]);
    }
    }
}
}
 
 

powered by: WebSVN 2.1.0

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