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

Subversion Repositories or1k

[/] [or1k/] [tags/] [stable_0_2_0_rc2/] [or1ksim/] [peripheral/] [atadevice.c] - Diff between revs 1365 and 1488

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

Rev 1365 Rev 1488
Line 31... Line 31...
 
 
#include "port.h"
#include "port.h"
#include "arch.h"
#include "arch.h"
#include "abstract.h"
#include "abstract.h"
 
 
#include "messages.h"
 
#include "atadevice.h"
#include "atadevice.h"
#include "atacmd.h"
#include "atacmd.h"
#include "sim-config.h"
#include "sim-config.h"
#include "atadevice_cmdi.h"
#include "atadevice_cmdi.h"
 
 
 
#include "debug.h"
 
 
 
DEFAULT_DEBUG_CHANNEL(ata);
 
 
/*
/*
 mandatory commands:
 mandatory commands:
 - execute device diagnostics       (done)
 - execute device diagnostics       (done)
 - flush cache
 - flush cache
 - identify device                  (done)
 - identify device                  (done)
Line 90... Line 93...
 
 
  /* generate stream for hd_simulation                                */
  /* generate stream for hd_simulation                                */
  switch(device->type)
  switch(device->type)
  {
  {
    case TYPE_NO_CONNECT:
    case TYPE_NO_CONNECT:
      MSG_NOTE("ata_device, using type NO_CONNECT.");
      TRACE("ata_device, using type NO_CONNECT.\n");
      device->stream = NULL;
      device->stream = NULL;
      break;
      break;
 
 
    case TYPE_FILE:
    case TYPE_FILE:
      MSG_NOTE("ata_device, using device type FILE.");
      TRACE("ata_device, using device type FILE.\n");
      device->stream = open_file(&device->size, device->file);
      device->stream = open_file(&device->size, device->file);
      break;
      break;
 
 
    case TYPE_LOCAL:
    case TYPE_LOCAL:
      MSG_NOTE("ata_device, using device type LOCAL.");
      TRACE("ata_device, using device type LOCAL.\n");
      device->stream = open_local();
      device->stream = open_local();
      break;
      break;
 
 
    default:
    default:
      MSG_FATAL("ata_device, illegal device-type.");
      ERR("Illegal device-type.  Defaulting to type NO_CONNECT.\n");
      MSG_EMPTY("defaulting to type NO_CONNECT.");
 
      device->stream = NULL;
      device->stream = NULL;
      break;
      break;
  }
  }
}
}
 
 
Line 124... Line 126...
 
 
   /* check if a file with name 'filename' already exists             */
   /* check if a file with name 'filename' already exists             */
   if ( !(fp = fopen(filename, "rb+")) )
   if ( !(fp = fopen(filename, "rb+")) )
     if ( !(fp = fopen(filename, "wb+")) )
     if ( !(fp = fopen(filename, "wb+")) )
     {
     {
       MSG_FATAL( strcat("ata_open_file, cannot open hd-file ", filename) );
       ERR( "ata_open_file, cannot open hd-file %s\n", filename );
       return NULL;
       return NULL;
     }
     }
     else
     else
     {
     {
       /* TODO create a file 'size' large */
       /* TODO create a file 'size' large */
       /* create a file 'size' large                                  */
       /* create a file 'size' large                                  */
       MSG_NOTE("ata_device; generating a new hard disk file.");
       TRACE("ata_device; generating a new hard disk file.\n");
       MSG_EMPTY("This may take a while, depending on the requested size.");
       TRACE("This may take a while, depending on the requested size.\n");
       for (n=0; n < (*size << 20); n++)
       for (n=0; n < (*size << 20); n++)
         fputc(0, fp);
         fputc(0, fp);
     }
     }
   else /* file already exist                                         */
   else /* file already exist                                         */
     fprintf(stderr, "file %s already exists. Using existing file.\n", filename);
     fprintf(stderr, "file %s already exists. Using existing file.\n", filename);
 
 
 
 
   ata_device_debug(1, "requested filesize was: %d (MBytes).\n", *size);
   TRACE("requested filesize was: %ld (MBytes).\n", *size);
 
 
   /* get the size of the file. This is also the size of the harddisk*/
   /* get the size of the file. This is also the size of the harddisk*/
   fseek(fp, 0, SEEK_END);
   fseek(fp, 0, SEEK_END);
   *size = ftell(fp);
   *size = ftell(fp);
 
 
   ata_device_debug(1, "actual filesize is: %d (MBytes).\n", *size >> 20);
   TRACE("actual filesize is: %ld (MBytes).\n", *size >> 20);
 
 
   return fp;
   return fp;
}
}
 
 
 
 
/* Use a the local filesystem as a hard-disk                          */
/* Use a the local filesystem as a hard-disk                          */
FILE *open_local(void)
FILE *open_local(void)
{
{
 // TODO:
 // TODO:
 MSG_WARNING("ata_device; device type LOCAL is not supported yet.");
 FIXME("Device type LOCAL is not yet supported. Defaulting to device type NO_CONNECT.");
 MSG_EMPTY("defaulting to device type NO_CONNECT.");
 
 return NULL;
 return NULL;
}
}
 
 
 
 
 
 
Line 171... Line 172...
*/
*/
/* power-on and hardware reset                                        */
/* power-on and hardware reset                                        */
void ata_devices_hw_reset(ata_devices *devices, int reset_signal)
void ata_devices_hw_reset(ata_devices *devices, int reset_signal)
{
{
  /* display debug information                                        */
  /* display debug information                                        */
  ata_device_debug(2, "ata_devices_hw_reset.\n");
  TRACE("ata_devices_hw_reset.\n");
 
 
  /* find device 0                                                    */
  /* find device 0                                                    */
  if ( (devices->device0.stream) && (devices->device1.stream) )
  if ( (devices->device0.stream) && (devices->device1.stream) )
  {
  {
    /* this one is simple, device0 is device0                         */
    /* this one is simple, device0 is device0                         */
Line 209... Line 210...
                        0);  /* negate dasp input, there's no device1 */
                        0);  /* negate dasp input, there's no device1 */
  }
  }
  else
  else
  {
  {
    /* no devices connected                                           */
    /* no devices connected                                           */
    ata_device_debug(1, "ata_device_hw_reset, no devices connected.\n");
    TRACE("ata_device_hw_reset, no devices connected.\n");
  }
  }
}
}
 
 
void ata_device_hw_reset(ata_device *device, int reset_signal,
void ata_device_hw_reset(ata_device *device, int reset_signal,
  int daspo, int pdiagi, int daspi)
  int daspo, int pdiagi, int daspi)
Line 295... Line 296...
 
 
        /* set new state                                              */
        /* set new state                                              */
        device->internals.state = ATA_STATE_SW_RST;
        device->internals.state = ATA_STATE_SW_RST;
 
 
        /* display debug information                                  */
        /* display debug information                                  */
        ata_device_debug(2, "ata_device_sw_reset initiated.\n");
        TRACE("ata_device_sw_reset initiated.\n");
    }
    }
  }
  }
  else if (device->internals.state == ATA_STATE_SW_RST)
  else if (device->internals.state == ATA_STATE_SW_RST)
  {   /* are we doing a software reset ??                             */
  {   /* are we doing a software reset ??                             */
      /* SRST bit cleared, end of software reset                      */
      /* SRST bit cleared, end of software reset                      */
Line 316... Line 317...
 
 
      /* set new state                                                */
      /* set new state                                                */
      device->internals.state = ATA_STATE_IDLE;
      device->internals.state = ATA_STATE_IDLE;
 
 
      /* display debug information                                    */
      /* display debug information                                    */
      ata_device_debug(2, "ata_device_sw_reset done.\n");
      TRACE("ata_device_sw_reset done.\n");
  }
  }
  /*
  /*
  <else> We are doing a hardware reset (or similar)
  <else> We are doing a hardware reset (or similar)
         ignore command
         ignore command
  */
  */
Line 333... Line 334...
void ata_device_do_command_register(ata_device *device)
void ata_device_do_command_register(ata_device *device)
{
{
  /* check BSY & DRQ                                                  */
  /* check BSY & DRQ                                                  */
  if ( (device->regs.status & ATA_SR_BSY) || (device->regs.status & ATA_SR_DRQ) )
  if ( (device->regs.status & ATA_SR_BSY) || (device->regs.status & ATA_SR_DRQ) )
     if (device->regs.command != DEVICE_RESET)
     if (device->regs.command != DEVICE_RESET)
        MSG_WARNING("ata_device_write, writing a command while BSY or DRQ asserted.");
        WARN("ata_device_write, writing a command while BSY or DRQ asserted.");
 
 
  /* check if device selected                                         */
  /* check if device selected                                         */
  if ( (device->regs.device_head & ATA_DHR_DEV) == device->internals.dev )
  if ( (device->regs.device_head & ATA_DHR_DEV) == device->internals.dev )
      ata_device_execute_cmd(device);
      ata_device_execute_cmd(device);
  else
  else
Line 357... Line 358...
{
{
    ata_device *device;
    ata_device *device;
 
 
    /* check for no connected devices                                 */
    /* check for no connected devices                                 */
    if ( (!devices->device0.stream) && (!devices->device1.stream) )
    if ( (!devices->device0.stream) && (!devices->device1.stream) )
        MSG_ERROR("ata_devices_read, no ata devices connected.");
        ERR("ata_devices_read, no ata devices connected.\n");
    else
    else
    {
    {
      /* check if both device0 and device1 are connected              */
      /* check if both device0 and device1 are connected              */
      if ( (devices->device0.stream) && (devices->device1.stream) )
      if ( (devices->device0.stream) && (devices->device1.stream) )
      {
      {
Line 381... Line 382...
      }
      }
 
 
      /* return data provided by selected device                      */
      /* return data provided by selected device                      */
      switch (adr) {
      switch (adr) {
        case ATA_ASR :
        case ATA_ASR :
          ata_device_debug(4, "alternate_status register read\n");
          TRACE("alternate_status register read\n");
          if ( (device->regs.device_head & ATA_DHR_DEV) ==  device->internals.dev )
          if ( (device->regs.device_head & ATA_DHR_DEV) ==  device->internals.dev )
              return device -> regs.status;
              return device -> regs.status;
          else
          else
          {
          {
              ata_device_debug(2, "device0 responds for device1, asr = 0x00\n");
              TRACE("device0 responds for device1, asr = 0x00\n");
              return 0; // return 0 when device0 responds for device1
              return 0; // return 0 when device0 responds for device1
          }
          }
 
 
        case ATA_CHR :
        case ATA_CHR :
          ata_device_debug(4, "cylinder_high register read, value = 0x%02X\n",
          TRACE("cylinder_high register read, value = 0x%02X\n",
                 device->regs.cylinder_high);
                 device->regs.cylinder_high);
          return device -> regs.cylinder_high;
          return device -> regs.cylinder_high;
 
 
        case ATA_CLR :
        case ATA_CLR :
          ata_device_debug(4, "cylinder_low register read, value = 0x%02X\n",
          TRACE("cylinder_low register read, value = 0x%02X\n",
                 device->regs.cylinder_low);
                 device->regs.cylinder_low);
          return device -> regs.cylinder_low;
          return device -> regs.cylinder_low;
 
 
        case ATA_DR  :
        case ATA_DR  :
          if (!device->regs.status & ATA_SR_DRQ)
          if (!device->regs.status & ATA_SR_DRQ)
          {
          {
             ata_device_debug(1, "data register read, while DRQ bit negated\n" );
             TRACE("data register read, while DRQ bit negated\n" );
             return 0;
             return 0;
          }
          }
          else
          else
          {
          {
              ata_device_debug(4, "data register read, value = 0x%04X, cnt = %3d\n",
              TRACE("data register read, value = 0x%04X, cnt = %3d\n",
                     *device->internals.dbuf_ptr, device->internals.dbuf_cnt);
                     *device->internals.dbuf_ptr, device->internals.dbuf_cnt);
              if (!--device->internals.dbuf_cnt)
              if (!--device->internals.dbuf_cnt)
                   device->regs.status &= ~ATA_SR_DRQ;
                   device->regs.status &= ~ATA_SR_DRQ;
              return *device -> internals.dbuf_ptr++;
              return *device -> internals.dbuf_ptr++;
          }
          }
 
 
        case ATA_DHR :
        case ATA_DHR :
          ata_device_debug(4, "device_head register read, value = 0x%02X\n",
          TRACE("device_head register read, value = 0x%02X\n",
                 device->regs.device_head);
                 device->regs.device_head);
          return device -> regs.device_head;
          return device -> regs.device_head;
 
 
        case ATA_ERR :
        case ATA_ERR :
          ata_device_debug(4, "error register read, value = 0x%02X\n",
          TRACE("error register read, value = 0x%02X\n",
                 device->regs.error);
                 device->regs.error);
          return device -> regs.error;
          return device -> regs.error;
 
 
        case ATA_SCR :
        case ATA_SCR :
          ata_device_debug(4, "sectorcount register read, value = 0x%02X\n",
          TRACE("sectorcount register read, value = 0x%02X\n",
                 device->regs.sector_count);
                 device->regs.sector_count);
          return device -> regs.sector_count;
          return device -> regs.sector_count;
 
 
        case ATA_SNR :
        case ATA_SNR :
          ata_device_debug(4, "sectornumber register read, value = 0x%02X\n",
          TRACE("sectornumber register read, value = 0x%02X\n",
                 device->regs.sector_number);
                 device->regs.sector_number);
          return device -> regs.sector_number;
          return device -> regs.sector_number;
 
 
        case ATA_SR  :
        case ATA_SR  :
          ata_device_debug(4, "status register read\n");
          TRACE("status register read\n");
          if ( (device->regs.device_head & ATA_DHR_DEV) ==  device->internals.dev)
          if ( (device->regs.device_head & ATA_DHR_DEV) ==  device->internals.dev)
              return device -> regs.status;
              return device -> regs.status;
          else
          else
          {
          {
              ata_device_debug(2, "device0 responds for device1, sr = 0x00\n");
              TRACE("device0 responds for device1, sr = 0x00\n");
              return 0; // return 0 when device0 responds for device1
              return 0; // return 0 when device0 responds for device1
          }
          }
 
 
//        case ATA_DA   :
//        case ATA_DA   :
//          return device -> regs.status;
//          return device -> regs.status;
Line 460... Line 461...
/* Write to devices                                                   */
/* Write to devices                                                   */
void ata_devices_write(ata_devices *devices, char adr, short value)
void ata_devices_write(ata_devices *devices, char adr, short value)
{
{
    /* check for no connected devices                                 */
    /* check for no connected devices                                 */
    if (!devices->device0.stream && !devices->device1.stream)
    if (!devices->device0.stream && !devices->device1.stream)
        MSG_ERROR("ata_devices_write, no ata devices connected.");
        ERR("ata_devices_write, no ata devices connected.\n");
    else
    else
    {
    {
      /* first device                                                 */
      /* first device                                                 */
      if (devices->device0.stream)
      if (devices->device0.stream)
          ata_device_write(&devices->device0, adr, value);
          ata_device_write(&devices->device0, adr, value);
Line 479... Line 480...
void ata_device_write(ata_device *device, char adr, short value)
void ata_device_write(ata_device *device, char adr, short value)
{
{
    switch (adr) {
    switch (adr) {
        case ATA_CR  :
        case ATA_CR  :
            /*display debug information                               */
            /*display debug information                               */
            ata_device_debug(4, "command register written, value = 0x%02X\n", value);
            TRACE("command register written, value = 0x%02X\n", value);
 
 
            device->regs.command = value;
            device->regs.command = value;
 
 
            /* check command register settings and execute command    */
            /* check command register settings and execute command    */
            ata_device_do_command_register(device);
            ata_device_do_command_register(device);
            break;
            break;
 
 
 
 
        case ATA_CHR :
        case ATA_CHR :
            /*display debug information                               */
            /*display debug information                               */
            ata_device_debug(4, "cylinder high register written, value = 0x%02X\n", value);
            TRACE("cylinder high register written, value = 0x%02X\n", value);
 
 
            device->regs.cylinder_high = value;
            device->regs.cylinder_high = value;
            break;
            break;
 
 
        case ATA_CLR :
        case ATA_CLR :
            /*display debug information                               */
            /*display debug information                               */
            ata_device_debug(4, "cylinder low register written, value = 0x%02X\n", value);
            TRACE("cylinder low register written, value = 0x%02X\n", value);
 
 
            device->regs.cylinder_low = value;
            device->regs.cylinder_low = value;
            break;
            break;
 
 
        case ATA_DR :
        case ATA_DR :
            /*display debug information                               */
            /*display debug information                               */
            ata_device_debug(4, "data register written, value = 0x%04X\n", value);
            TRACE("data register written, value = 0x%04X\n", value);
 
 
            device->regs.dataport_i = value;
            device->regs.dataport_i = value;
            break;
            break;
 
 
        case ATA_DCR :
        case ATA_DCR :
            /*display debug information                               */
            /*display debug information                               */
            ata_device_debug(4, "device control register written, value = 0x%02X\n", value);
            TRACE("device control register written, value = 0x%02X\n", value);
 
 
            device->regs.device_control = value;
            device->regs.device_control = value;
            ata_device_do_control_register(device);
            ata_device_do_control_register(device);
            break;
            break;
 
 
        case ATA_DHR :
        case ATA_DHR :
            /*display debug information                               */
            /*display debug information                               */
            ata_device_debug(4, "device head register written, value = 0x%02X\n", value);
            TRACE("device head register written, value = 0x%02X\n", value);
 
 
            device->regs.device_head = value;
            device->regs.device_head = value;
            break;
            break;
 
 
        case ATA_FR  :
        case ATA_FR  :
            /*display debug information                               */
            /*display debug information                               */
            ata_device_debug(4, "features register written, value = 0x%02X\n", value);
            TRACE("features register written, value = 0x%02X\n", value);
 
 
            device->regs.features = value;
            device->regs.features = value;
            break;
            break;
 
 
        case ATA_SCR :
        case ATA_SCR :
            /*display debug information                               */
            /*display debug information                               */
            ata_device_debug(4, "sectorcount register written, value = 0x%02X\n", value);
            TRACE("sectorcount register written, value = 0x%02X\n", value);
 
 
            device->regs.sector_count = value;
            device->regs.sector_count = value;
            break;
            break;
 
 
        case ATA_SNR :
        case ATA_SNR :
            /*display debug information                               */
            /*display debug information                               */
            ata_device_debug(4, "sectornumber register written, value = 0x%02X\n", value);
            TRACE("sectornumber register written, value = 0x%02X\n", value);
 
 
            device->regs.sector_number = value;
            device->regs.sector_number = value;
            break;
            break;
 
 
    } //endcase
    } //endcase
}
}
 
 
 
 
/* --------------------------                                         */
 
/* -- print debug messages --                                         */
 
/* --------------------------                                         */
 
int ata_device_debug(int lvl, char *format, ...)
 
{
 
  va_list ap;
 
 
 
  va_start(ap, format);
 
 
 
  if (ATA_DEVICE_DEBUG_LVL >= lvl)
 
  {
 
    fprintf(stderr, "ata_device_debug: ");
 
    vfprintf(stderr, format, ap);
 
  }
 
 
 
  va_end(ap);
 
  return 0;
 
}
 
 
 
 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.