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

Subversion Repositories or1k

[/] [or1k/] [tags/] [stable_0_2_0_rc2/] [or1ksim/] [peripheral/] [atahost.c] - Diff between revs 1359 and 1364

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

Rev 1359 Rev 1364
Line 17... Line 17...
    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.
*/
*/
 
 
 
#include <string.h>
 
 
#include "config.h"
#include "config.h"
 
 
#ifdef HAVE_INTTYPES_H
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#include <inttypes.h>
#endif
#endif
Line 35... Line 37...
/* all user defineable settings are in 'atahost_define.h'             */
/* all user defineable settings are in 'atahost_define.h'             */
#include "atahost_define.h"
#include "atahost_define.h"
#include "atahost.h"
#include "atahost.h"
#include "messages.h"
#include "messages.h"
 
 
static ata_host atas[MAX_ATAS];
 
 
 
/* reset and initialize ATA host core(s) */
/* reset and initialize ATA host core(s) */
void ata_reset(void)
void ata_reset(void *dat)
{
 
   static int first_time=0;
 
 
 
   unsigned i;
 
   ata_host *ata;
 
 
 
   // for all ATA cores
 
   for (i=0; i < config.natas; i++)
 
   {
   {
     ata = &(atas[i]);
   ata_host *ata = dat;
 
 
     // reset the core registers
     // reset the core registers
     ata->regs.ctrl  = 0x0001;
     ata->regs.ctrl  = 0x0001;
     ata->regs.stat  = (DEV_ID << 28) | (REV << 24);
     ata->regs.stat  = (DEV_ID << 28) | (REV << 24);
     ata->regs.pctr  = (PIO_MODE0_TEOC << ATA_TEOC) | (PIO_MODE0_T4 << ATA_T4) | (PIO_MODE0_T2 << ATA_T2) | (PIO_MODE0_T1 << ATA_T1);
     ata->regs.pctr  = (PIO_MODE0_TEOC << ATA_TEOC) | (PIO_MODE0_T4 << ATA_T4) | (PIO_MODE0_T2 << ATA_T2) | (PIO_MODE0_T1 << ATA_T1);
Line 60... Line 52...
     ata->regs.pftr1 = (PIO_MODE0_TEOC << ATA_TEOC) | (PIO_MODE0_T4 << ATA_T4) | (PIO_MODE0_T2 << ATA_T2) | (PIO_MODE0_T1 << ATA_T1);
     ata->regs.pftr1 = (PIO_MODE0_TEOC << ATA_TEOC) | (PIO_MODE0_T4 << ATA_T4) | (PIO_MODE0_T2 << ATA_T2) | (PIO_MODE0_T1 << ATA_T1);
     ata->regs.dtr0  = (DMA_MODE0_TEOC << ATA_TEOC) | (DMA_MODE0_TD << ATA_TD) | (DMA_MODE0_TM << ATA_TM);
     ata->regs.dtr0  = (DMA_MODE0_TEOC << ATA_TEOC) | (DMA_MODE0_TD << ATA_TD) | (DMA_MODE0_TM << ATA_TM);
     ata->regs.dtr1  = (DMA_MODE0_TEOC << ATA_TEOC) | (DMA_MODE0_TD << ATA_TD) | (DMA_MODE0_TM << ATA_TM);
     ata->regs.dtr1  = (DMA_MODE0_TEOC << ATA_TEOC) | (DMA_MODE0_TD << ATA_TD) | (DMA_MODE0_TM << ATA_TM);
     ata->regs.txb   = 0;
     ata->regs.txb   = 0;
 
 
     // copy the config settings
 
     ata->ata_number = i;
 
     ata->irq        = config.atas[i].irq;
 
     ata->baseaddr   = config.atas[i].baseaddr;
 
 
 
     ata->devices.device0.size   = config.atas[i].dev_size0;
 
     ata->devices.device0.type   = config.atas[i].dev_type0;
 
     ata->devices.device0.packet = config.atas[i].dev_packet0;
 
     ata->devices.device1.size   = config.atas[i].dev_size1;
 
     ata->devices.device1.type   = config.atas[i].dev_type1;
 
     ata->devices.device1.packet = config.atas[i].dev_packet1;
 
 
 
     // inform simulator about new read/write delay timings
     // inform simulator about new read/write delay timings
     adjust_rw_delay( ata->baseaddr, ata_pio_delay(ata->regs.pctr), ata_pio_delay(ata->regs.pctr) );
     adjust_rw_delay( ata->baseaddr, ata_pio_delay(ata->regs.pctr), ata_pio_delay(ata->regs.pctr) );
 
 
     /* initialize simulator & ata_devices                                */
 
     if (!first_time)
 
     {
 
       /* Connect ata_devices.                                            */
 
       ata_devices_init(&ata->devices, config.atas[i].dev_file0, config.atas[i].dev_file1);
 
 
 
       register_memoryarea(ata->baseaddr, ATA_ADDR_SPACE, 4, 0, ata_read32, ata_write32, NULL);
 
     }
 
 
 
     /* the reset bit in the control register 'ctrl' is set, reset connect ata-devices */
     /* the reset bit in the control register 'ctrl' is set, reset connect ata-devices */
     ata_devices_hw_reset(&ata->devices, 1);
     ata_devices_hw_reset(&ata->devices, 1);
   }
   }
 
 
   first_time++;
 
}
 
/* ========================================================================= */
 
 
 
 
 
/* Convert a memory address to a device struct and relative address.
 
 * Return nonzero on success */
 
int ata_find_device( oraddr_t addr, ata_host **ata, oraddr_t *reladdr )
 
{
 
  unsigned i;
 
  *ata = NULL;
 
 
 
  for ( i = 0; i < config.natas && *ata == NULL; ++ i ) {
 
    if ( (addr >= atas[i].baseaddr) && (addr < atas[i].baseaddr + ATA_ADDR_SPACE) )
 
      *ata = &(atas[i]);
 
  }
 
 
 
  /* verify we found a device */
 
  if ( *ata == NULL )
 
    return 0;
 
 
 
  /* Verify legal address */
 
  if ( (addr - (*ata)->baseaddr) % 4 != 0 )
 
    return 0;
 
 
 
  *reladdr = addr - (*ata) -> baseaddr;
 
  return 1;
 
}
 
/* ========================================================================= */
/* ========================================================================= */
 
 
 
 
/*
/*
  Read a register
  Read a register
*/
*/
uint32_t ata_read32( oraddr_t addr, void *dat )
uint32_t ata_read32( oraddr_t addr, void *dat )
{
{
    ata_host *ata;
    ata_host *ata = dat;
 
 
    if ( !ata_find_device( addr, &ata, &addr ) )    {
    addr -= ata->baseaddr;
        fprintf(stderr, "ata_read32( 0x%"PRIxADDR" ): Not in registered range(s)\n", addr );
 
        return 0;
 
    }
 
 
 
    /* determine if ata_host or ata_device addressed */
    /* determine if ata_host or ata_device addressed */
    if (is_ata_hostadr(addr))
    if (is_ata_hostadr(addr))
    {
    {
        // Accesses to internal register take 2cycles
        // Accesses to internal register take 2cycles
Line 198... Line 137...
/*
/*
  Write a register
  Write a register
*/
*/
void ata_write32( oraddr_t addr, uint32_t value, void *dat )
void ata_write32( oraddr_t addr, uint32_t value, void *dat )
{
{
    ata_host *ata;
    ata_host *ata = dat;
 
 
    if ( !ata_find_device( addr, &ata, &addr ) )
    addr -= ata->baseaddr;
    {
 
        fprintf(stderr, "ata_write32( 0x%"PRIxADDR" ): Not in registered range(s)\n", addr );
 
        return;
 
    }
 
 
 
    /* determine if ata_host or ata_device addressed */
    /* determine if ata_host or ata_device addressed */
    if (is_ata_hostadr(addr))
    if (is_ata_hostadr(addr))
    {
    {
       // Accesses to internal register take 2cycles
       // Accesses to internal register take 2cycles
Line 287... Line 222...
}
}
/* ========================================================================= */
/* ========================================================================= */
 
 
 
 
/* Dump status */
/* Dump status */
void ata_status( void )
void ata_status( void *dat )
{
{
  unsigned i;
  ata_host *ata = dat;
  ata_host *ata;
 
 
 
  for ( i = 0; i < config.natas; i++ ) {
 
      ata = &(atas[i]);
 
 
 
      if ( ata->baseaddr == 0 )
      if ( ata->baseaddr == 0 )
         continue;
    return;
 
 
       PRINTF( "\nOCIDEC-%1d %u at: 0x%"PRIxADDR"\n", DEV_ID, i, ata->baseaddr );
  PRINTF( "\nOCIDEC-%1d at: 0x%"PRIxADDR"\n", DEV_ID, ata->baseaddr );
       PRINTF( "ATA CTRL     : 0x%08X\n", ata->regs.ctrl  );
       PRINTF( "ATA CTRL     : 0x%08X\n", ata->regs.ctrl  );
       PRINTF( "ATA STAT     : 0x%08x\n", ata->regs.stat  );
       PRINTF( "ATA STAT     : 0x%08x\n", ata->regs.stat  );
       PRINTF( "ATA PCTR     : 0x%08x\n", ata->regs.pctr  );
       PRINTF( "ATA PCTR     : 0x%08x\n", ata->regs.pctr  );
 
 
#if (DEV_ID > 1)
#if (DEV_ID > 1)
Line 315... Line 246...
       PRINTF( "ATA DTR1     : 0x%08lx\n", ata->regs.dtr1  );
       PRINTF( "ATA DTR1     : 0x%08lx\n", ata->regs.dtr1  );
       PRINTF( "ATA TXD      : 0x%08lx\n", ata->regs.txb   );
       PRINTF( "ATA TXD      : 0x%08lx\n", ata->regs.txb   );
       PRINTF( "ATA RXD      : 0x%08lx\n", ata->regs.rxb   );
       PRINTF( "ATA RXD      : 0x%08lx\n", ata->regs.rxb   );
#endif
#endif
  }
  }
}
 
/* ========================================================================= */
/* ========================================================================= */
 
 
/*----------------------------------------------------[ ATA Configuration ]---*/
/*----------------------------------------------------[ ATA Configuration ]---*/
void ata_natas(union param_val val, void *dat)
 
{
 
  if (val.int_val >= 0 && val.int_val < MAX_ATAS)
 
    config.natas = val.int_val;
 
  else
 
    CONFIG_ERROR("invalid number of devices.");
 
}
 
 
 
void ata_baseaddr(union param_val val, void *dat)
void ata_baseaddr(union param_val val, void *dat)
{
{
  if (current_device >= 0 && current_device < config.natas)
  ata_host *ata = dat;
    config.atas[current_device].baseaddr = val.addr_val;
  ata->baseaddr = val.addr_val;
  else
 
    CONFIG_ERROR("invalid device number.");
 
}
}
 
 
void ata_irq(union param_val val, void *dat)
void ata_irq(union param_val val, void *dat)
{
{
  if (current_device >= 0 && current_device < config.natas)
  ata_host *ata = dat;
    config.atas[current_device].irq = val.int_val;
  ata->irq = val.int_val;
  else
 
    CONFIG_ERROR("invalid device number.");
 
}
}
 
 
void ata_dev_type0(union param_val val, void *dat)
void ata_dev_type0(union param_val val, void *dat)
{
{
  if (current_device >= 0 && current_device < config.natas)
  ata_host *ata = dat;
    config.atas[current_device].dev_type0 = val.int_val;
  ata->devices.device0.type = val.int_val;
  else
 
    CONFIG_ERROR("invalid device number.");
 
}
}
 
 
void ata_dev_file0(union param_val val, void *dat)
void ata_dev_file0(union param_val val, void *dat)
{
{
  if (current_device >= 0 && current_device < config.natas)
  ata_host *ata = dat;
    strcpy (config.atas[current_device].dev_file0, val.str_val);
  if(!(ata->devices.device0.file = strdup(val.str_val))) {
  else
    fprintf(stderr, "Peripheral ATA: Run out of memory\n");
    CONFIG_ERROR("invalid device number.");
    exit(-1);
 
  }
}
}
 
 
void ata_dev_size0(union param_val val, void *dat)
void ata_dev_size0(union param_val val, void *dat)
{
{
  if (current_device >= 0 && current_device < config.natas)
  ata_host *ata = dat;
    config.atas[current_device].dev_size0 = val.int_val;
  ata->devices.device0.size = val.int_val;
  else
 
    CONFIG_ERROR("invalid device number.");
 
}
}
 
 
void ata_dev_packet0(union param_val val, void *dat)
void ata_dev_packet0(union param_val val, void *dat)
{
{
  if (current_device >= 0 && current_device < config.natas)
  ata_host *ata = dat;
    config.atas[current_device].dev_packet0 = val.int_val;
  ata->devices.device0.packet = val.int_val;
  else
 
    CONFIG_ERROR("invalid device number.");
 
}
}
 
 
void ata_dev_type1(union param_val val, void *dat)
void ata_dev_type1(union param_val val, void *dat)
{
{
  if (current_device >= 0 && current_device < config.natas)
  ata_host *ata = dat;
    config.atas[current_device].dev_type1 = val.int_val;
  ata->devices.device1.packet = val.int_val;
  else
 
    CONFIG_ERROR("invalid device number.");
 
}
}
 
 
void ata_dev_file1(union param_val val, void *dat)
void ata_dev_file1(union param_val val, void *dat)
{
{
  if (current_device >= 0 && current_device < config.natas)
  ata_host *ata = dat;
    strcpy (config.atas[current_device].dev_file1, val.str_val);
  if(!(ata->devices.device1.file = strdup(val.str_val))) {
  else
    fprintf(stderr, "Peripheral ATA: Run out of memory\n");
    CONFIG_ERROR("invalid device number.");
    exit(-1);
 
  }
}
}
 
 
void ata_dev_size1(union param_val val, void *dat)
void ata_dev_size1(union param_val val, void *dat)
{
{
  if (current_device >= 0 && current_device < config.natas)
  ata_host *ata = dat;
    config.atas[current_device].dev_size1 = val.int_val;
  ata->devices.device1.size = val.int_val;
  else
 
    CONFIG_ERROR("invalid device number.");
 
}
}
 
 
void ata_dev_packet1(union param_val val, void *dat)
void ata_dev_packet1(union param_val val, void *dat)
{
{
  if (current_device >= 0 && current_device < config.natas)
  ata_host *ata = dat;
    config.atas[current_device].dev_packet1 = val.int_val;
  ata->devices.device1.packet = val.int_val;
  else
}
    CONFIG_ERROR("invalid device number.");
 
 
void *ata_sec_start(void)
 
{
 
  ata_host *new = malloc(sizeof(ata_host));
 
 
 
  if(!new) {
 
    fprintf(stderr, "Peripheral ATA: Run out of memory\n");
 
    exit(-1);
 
  }
 
 
 
  memset(new, 0, sizeof(ata_host));
 
  return new;
 
}
 
 
 
void ata_sec_end(void *dat)
 
{
 
  ata_host *ata = dat;
 
 
 
  /* Connect ata_devices.                                            */
 
  ata_devices_init(&ata->devices);
 
 
 
  register_memoryarea(ata->baseaddr, ATA_ADDR_SPACE, 4, 0, ata_read32, ata_write32, dat);
 
 
 
  reg_sim_reset(ata_reset, dat);
 
  reg_sim_stat(ata_status, dat);
}
}
 
 
void reg_ata_sec(void)
void reg_ata_sec(void)
{
{
  struct config_section *sec = reg_config_sec("ata", NULL, NULL);
  struct config_section *sec = reg_config_sec("ata", ata_sec_start, ata_sec_end);
 
 
  reg_config_param(sec, "natas", paramt_int, ata_natas);
 
  reg_config_param(sec, "device", paramt_int, change_device);
 
  reg_config_param(sec, "baseaddr", paramt_addr, ata_baseaddr);
  reg_config_param(sec, "baseaddr", paramt_addr, ata_baseaddr);
  reg_config_param(sec, "irq", paramt_int, ata_irq);
  reg_config_param(sec, "irq", paramt_int, ata_irq);
  reg_config_param(sec, "dev_type0", paramt_int, ata_dev_type0);
  reg_config_param(sec, "dev_type0", paramt_int, ata_dev_type0);
  reg_config_param(sec, "dev_file0", paramt_str, ata_dev_file0);
  reg_config_param(sec, "dev_file0", paramt_str, ata_dev_file0);
  reg_config_param(sec, "dev_size0", paramt_int, ata_dev_size0);
  reg_config_param(sec, "dev_size0", paramt_int, ata_dev_size0);
  reg_config_param(sec, "dev_packet0", paramt_int, ata_dev_packet0);
  reg_config_param(sec, "dev_packet0", paramt_int, ata_dev_packet0);
  reg_config_param(sec, "dev_type1", paramt_int, ata_dev_type1);
  reg_config_param(sec, "dev_type1", paramt_int, ata_dev_type1);
  reg_config_param(sec, "dev_file1", paramt_str, ata_dev_file1);
  reg_config_param(sec, "dev_file1", paramt_str, ata_dev_file1);
  reg_config_param(sec, "dev_size1", paramt_int, ata_dev_size1);
  reg_config_param(sec, "dev_size1", paramt_int, ata_dev_size1);
  reg_config_param(sec, "dev_packet1", paramt_int, ata_dev_packet1);
  reg_config_param(sec, "dev_packet1", paramt_int, ata_dev_packet1);
  reg_config_param(sec, "enddevice", paramt_none, end_device);
 
}
}
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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