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

Subversion Repositories or1k

[/] [or1k/] [tags/] [stable_0_2_0_rc1/] [or1ksim/] [peripheral/] [mc.c] - Diff between revs 1359 and 1373

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 1359 Rev 1373
Line 43... Line 43...
#include "sim-config.h"
#include "sim-config.h"
#include "debug.h"
#include "debug.h"
 
 
extern struct dev_memarea *dev_list;
extern struct dev_memarea *dev_list;
 
 
static struct mc mc;
void set_csc_tms (int cs, unsigned long csc, unsigned long tms, struct mc *mc) {
 
 
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 = mc.ba_mask << 22;
      mem_dev->addr_mask = mc->ba_mask << 22;
      mem_dev->addr_compare = ((csc >> MC_CSC_SEL_OFFSET) /* & 0xff*/) << 22;
      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);
Line 76... Line 74...
}
}
 
 
/* Set a specific MC register with value. */
/* Set a specific MC register with value. */
void mc_write_word(oraddr_t addr, uint32_t value, void *dat)
void mc_write_word(oraddr_t addr, uint32_t value, void *dat)
{
{
 
    struct mc *mc = dat;
        int chipsel;
        int chipsel;
 
 
        debug(5, "mc_write_word(%"PRIxADDR",%08"PRIx32")\n", addr, value);
        debug(5, "mc_write_word(%"PRIxADDR",%08"PRIx32")\n", addr, value);
 
 
  addr -= config.mc.baseaddr;
  addr -= 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], mc);
            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], mc);
                    break;
                    break;
                  } else
                  } else
                        debug(1, "write out of range (addr %"PRIxADDR")\n", addr + config.mc.baseaddr);
                        debug(1, "write out of range (addr %"PRIxADDR")\n", addr + mc->baseaddr);
        }
        }
}
}
 
 
/* Read a specific MC register. */
/* Read a specific MC register. */
uint32_t mc_read_word(oraddr_t addr, void *dat)
uint32_t mc_read_word(oraddr_t addr, void *dat)
{
{
 
    struct mc *mc = dat;
        uint32_t value = 0;
        uint32_t value = 0;
 
 
        debug(5, "mc_read_word(%"PRIxADDR")", addr);
        debug(5, "mc_read_word(%"PRIxADDR")", addr);
 
 
  addr -= config.mc.baseaddr;
  addr -= 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 %"PRIxADDR")\n", addr + config.mc.baseaddr);
                        debug(1, " read out of range (addr %"PRIxADDR")\n", addr + mc->baseaddr);
            break;
            break;
        }
        }
        debug(5, " value(%"PRIx32")\n", value);
        debug(5, " value(%"PRIx32")\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(void *dat)
{
{
 
  struct mc *mc = dat;
  struct dev_memarea *mem_dev = dev_list;
  struct dev_memarea *mem_dev = dev_list;
 
 
  if (config.mc.enabled) {
 
        PRINTF("Resetting memory controller.\n");
        PRINTF("Resetting memory controller.\n");
        memset(&mc, 0, sizeof(struct mc));
 
 
 
    mc.poc = config.mc.POC;
  memset(mc->csc, 0, sizeof(mc->csc));
 
  memset(mc->tms, 0, sizeof(mc->tms));
 
 
 
  mc->csr = 0;
 
  mc->ba_mask = 0;
 
 
    /* 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] = (((mc->poc & 0x0c) >> 2) << MC_CSC_MEMTYPE_OFFSET) | ((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], mc);
 
 
        register_memoryarea(config.mc.baseaddr, MC_ADDR_SPACE, 4, 1, mc_read_word, mc_write_word, NULL);
 
  }
 
}
 
 
 
inline void mc_clock()
 
{
 
}
}
 
 
void mc_status()
void mc_status(void *dat)
{
{
 
    struct mc *mc = dat;
    int i;
    int i;
 
 
    PRINTF( "\nMemory Controller at 0x%lX:\n", config.mc.baseaddr );
    PRINTF( "\nMemory Controller at 0x%"PRIxADDR":\n", mc->baseaddr );
    PRINTF( "POC: 0x%08lX\n", mc.poc );
    PRINTF( "POC: 0x%08lX\n", mc->poc );
    PRINTF( "BAS: 0x%08lX\n", mc.ba_mask );
    PRINTF( "BAS: 0x%08lX\n", mc->ba_mask );
    PRINTF( "CSR: 0x%08lX\n", mc.csr );
    PRINTF( "CSR: 0x%08lX\n", mc->csr );
 
 
    for (i=0; i<N_CE; i++) {
    for (i=0; i<N_CE; i++) {
        PRINTF( "CE %02d -  CSC: 0x%08lX  TMS: 0x%08lX\n", i, mc.csc[i],
        PRINTF( "CE %02d -  CSC: 0x%08lX  TMS: 0x%08lX\n", i, mc->csc[i],
               mc.tms[i]);
               mc->tms[i]);
    }
    }
}
}
 
 
/*-----------------------------------------------------[ MC configuration }---*/
/*-----------------------------------------------------[ MC configuration }---*/
void mc_enabled(union param_val val, void *dat)
void mc_enabled(union param_val val, void *dat)
{
{
  config.mc.enabled = val.int_val;
  struct mc *mc = dat;
 
  mc->enabled = val.int_val;
}
}
 
 
void mc_baseaddr(union param_val val, void *dat)
void mc_baseaddr(union param_val val, void *dat)
{
{
  config.mc.baseaddr = val.addr_val;
  struct mc *mc = dat;
 
  mc->baseaddr = val.addr_val;
}
}
 
 
void mc_POC(union param_val val, void *dat)
void mc_POC(union param_val val, void *dat)
{
{
  config.mc.POC = val.int_val;
  struct mc *mc = dat;
 
  mc->poc = val.int_val;
 
}
 
 
 
void *mc_sec_start(void)
 
{
 
  struct mc *new = malloc(sizeof(struct mc));
 
 
 
  if(!new) {
 
    fprintf(stderr, "Peripheral MC: Run out of memory\n");
 
    exit(-1);
 
  }
 
 
 
  new->enabled = 0;
 
 
 
  return new;
 
}
 
 
 
void mc_sec_end(void *dat)
 
{
 
  struct mc *mc = dat;
 
 
 
  if(mc->enabled) {
 
    register_memoryarea(mc->baseaddr, MC_ADDR_SPACE, 4, 1, mc_read_word, mc_write_word, dat);
 
    reg_sim_reset(mc_reset, dat);
 
    reg_sim_stat(mc_status, dat);
 
  }
}
}
 
 
void reg_mc_sec(void)
void reg_mc_sec(void)
{
{
  struct config_section *sec = reg_config_sec("mc", NULL, NULL);
  struct config_section *sec = reg_config_sec("mc", mc_sec_start, mc_sec_end);
 
 
  reg_config_param(sec, "enabled", paramt_int, mc_enabled);
  reg_config_param(sec, "enabled", paramt_int, mc_enabled);
  reg_config_param(sec, "baseaddr", paramt_addr, mc_baseaddr);
  reg_config_param(sec, "baseaddr", paramt_addr, mc_baseaddr);
  reg_config_param(sec, "POC", paramt_int, mc_POC);
  reg_config_param(sec, "POC", paramt_int, mc_POC);
}
}

powered by: WebSVN 2.1.0

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