/[gxemul]/trunk/src/devices/dev_wdc.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/src/devices/dev_wdc.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 20 by dpavlin, Mon Oct 8 16:19:23 2007 UTC revision 42 by dpavlin, Mon Oct 8 16:22:32 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2004-2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2004-2007  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: dev_wdc.c,v 1.56 2005/11/23 23:31:36 debug Exp $   *  $Id: dev_wdc.c,v 1.76 2007/06/15 19:57:34 debug Exp $
29   *   *
30   *  Standard "wdc" IDE controller.   *  COMMENT: Standard "wdc" IDE controller
31   */   */
32    
33  #include <stdio.h>  #include <stdio.h>
# Line 48  Line 48 
48  #define WDC_MAX_SECTORS         512  #define WDC_MAX_SECTORS         512
49  #define WDC_INBUF_SIZE          (512*(WDC_MAX_SECTORS+1))  #define WDC_INBUF_SIZE          (512*(WDC_MAX_SECTORS+1))
50    
 /*  
  *  INT_DELAY: This is an old hack which only exists because (some versions of)  
  *  NetBSD for hpcmips have interrupt problems. These problems are probably not  
  *  specific to GXemul, but are also triggered on real hardware.  
  *  
  *  See the following URL for more info:  
  *  http://mail-index.netbsd.org/port-hpcmips/2004/12/30/0003.html  
  *  
  *  NetBSD/malta also bugs out if wdc interrupts come too quickly. Hm.  
  */  
 #define INT_DELAY               1  
   
51  extern int quiet_mode;  extern int quiet_mode;
52    
53  /*  #define debug fatal  */  /*  #define debug fatal  */
54    
55  struct wdc_data {  struct wdc_data {
56          int             irq_nr;          struct interrupt irq;
57            int             addr_mult;
58          int             base_drive;          int             base_drive;
59          int             data_debug;          int             data_debug;
60            int             io_enabled;
61    
62          /*  Cached values:  */          /*  Cached values:  */
63          int             cyls[2];          int             cyls[2];
# Line 78  struct wdc_data { Line 68  struct wdc_data {
68          int             inbuf_head;          int             inbuf_head;
69          int             inbuf_tail;          int             inbuf_tail;
70    
71          int             delayed_interrupt;          int             int_assert;
         int             int_asserted;  
72    
73          int             write_in_progress;          int             write_in_progress;
74          int             write_count;          int             write_count;
# Line 101  struct wdc_data { Line 90  struct wdc_data {
90          int             atapi_phase;          int             atapi_phase;
91          struct scsi_transfer *atapi_st;          struct scsi_transfer *atapi_st;
92          int             atapi_len;          int             atapi_len;
93          int             atapi_received;          size_t          atapi_received;
94    
95          unsigned char   identify_struct[512];          unsigned char   identify_struct[512];
96  };  };
# Line 110  struct wdc_data { Line 99  struct wdc_data {
99  #define COMMAND_RESET   0x100  #define COMMAND_RESET   0x100
100    
101    
102  /*  DEVICE_TICK(wdc)
  *  dev_wdc_tick():  
  */  
 void dev_wdc_tick(struct cpu *cpu, void *extra)  
103  {  {
104          struct wdc_data *d = extra;          struct wdc_data *d = extra;
         int old_di = d->delayed_interrupt;  
105    
106          if (d->delayed_interrupt)          if (d->int_assert)
107                  d->delayed_interrupt --;                  INTERRUPT_ASSERT(d->irq);
108    }
109    
110          if (old_di == 1 || d->int_asserted) {  
111                  cpu_interrupt(cpu, d->irq_nr);  /*
112                  d->int_asserted = 1;   *  wdc_set_io_enabled():
113          }   *
114     *  Set io_enabled to zero to disable the I/O registers temporarily (e.g.
115     *  used by PCI code in NetBSD to detect whether multiple controllers collide
116     *  in I/O space).
117     *
118     *  Return value is old contents of the io_enabled variable.
119     */
120    int wdc_set_io_enabled(struct wdc_data *d, int io_enabled)
121    {
122            int old = d->io_enabled;
123            d->io_enabled = io_enabled;
124            return old;
125  }  }
126    
127    
# Line 211  static void wdc_initialize_identify_stru Line 208  static void wdc_initialize_identify_stru
208          /*  27-46: Model number  */          /*  27-46: Model number  */
209          if (diskimage_getname(cpu->machine, d->drive + d->base_drive,          if (diskimage_getname(cpu->machine, d->drive + d->base_drive,
210              DISKIMAGE_IDE, namebuf, sizeof(namebuf))) {              DISKIMAGE_IDE, namebuf, sizeof(namebuf))) {
211                  int i;                  size_t i;
212                  for (i=0; i<sizeof(namebuf); i++)                  for (i=0; i<sizeof(namebuf); i++)
213                          if (namebuf[i] == 0) {                          if (namebuf[i] == 0) {
214                                  for (; i<sizeof(namebuf); i++)                                  for (; i<sizeof(namebuf); i++)
# Line 275  void wdc__read(struct cpu *cpu, struct w Line 272  void wdc__read(struct cpu *cpu, struct w
272          int i, cyl = d->cyl_hi * 256+ d->cyl_lo;          int i, cyl = d->cyl_hi * 256+ d->cyl_lo;
273          int count = d->seccnt? d->seccnt : 256;          int count = d->seccnt? d->seccnt : 256;
274          uint64_t offset = 512 * (d->sector - 1          uint64_t offset = 512 * (d->sector - 1
275              + d->head * d->sectors_per_track[d->drive] +              + (int64_t)d->head * d->sectors_per_track[d->drive] +
276              d->heads[d->drive] * d->sectors_per_track[d->drive] * cyl);              (int64_t)d->heads[d->drive] * d->sectors_per_track[d->drive] * cyl);
277    
278  #if 0  #if 0
279          /*  LBA:  */          /*  LBA:  */
# Line 310  void wdc__read(struct cpu *cpu, struct w Line 307  void wdc__read(struct cpu *cpu, struct w
307                  count -= to_read;                  count -= to_read;
308          }          }
309    
310          d->delayed_interrupt = INT_DELAY;          d->int_assert = 1;
311  }  }
312    
313    
# Line 322  void wdc__write(struct cpu *cpu, struct Line 319  void wdc__write(struct cpu *cpu, struct
319          int cyl = d->cyl_hi * 256+ d->cyl_lo;          int cyl = d->cyl_hi * 256+ d->cyl_lo;
320          int count = d->seccnt? d->seccnt : 256;          int count = d->seccnt? d->seccnt : 256;
321          uint64_t offset = 512 * (d->sector - 1          uint64_t offset = 512 * (d->sector - 1
322              + d->head * d->sectors_per_track[d->drive] +              + (int64_t)d->head * d->sectors_per_track[d->drive] +
323              d->heads[d->drive] * d->sectors_per_track[d->drive] * cyl);              (int64_t)d->heads[d->drive] * d->sectors_per_track[d->drive] * cyl);
324  #if 0  #if 0
325          /*  LBA:  */          /*  LBA:  */
326          if (d->lba)          if (d->lba)
# Line 365  static int status_byte(struct wdc_data * Line 362  static int status_byte(struct wdc_data *
362  }  }
363    
364    
365  /*  DEVICE_ACCESS(wdc_altstatus)
  *  dev_wdc_altstatus_access():  
  */  
 int dev_wdc_altstatus_access(struct cpu *cpu, struct memory *mem,  
         uint64_t relative_addr, unsigned char *data, size_t len,  
         int writeflag, void *extra)  
366  {  {
367          struct wdc_data *d = extra;          struct wdc_data *d = extra;
368          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
# Line 402  int dev_wdc_altstatus_access(struct cpu Line 394  int dev_wdc_altstatus_access(struct cpu
394   */   */
395  void wdc_command(struct cpu *cpu, struct wdc_data *d, int idata)  void wdc_command(struct cpu *cpu, struct wdc_data *d, int idata)
396  {  {
397          int i;          size_t i;
398    
399          d->cur_command = idata;          d->cur_command = idata;
400          d->atapi_cmd_in_progress = 0;          d->atapi_cmd_in_progress = 0;
# Line 420  void wdc_command(struct cpu *cpu, struct Line 412  void wdc_command(struct cpu *cpu, struct
412                  debug("[ wdc: command 0x%02x drive %i, but no disk image ]\n",                  debug("[ wdc: command 0x%02x drive %i, but no disk image ]\n",
413                      d->cur_command, d->drive + d->base_drive);                      d->cur_command, d->drive + d->base_drive);
414                  d->error |= WDCE_ABRT;                  d->error |= WDCE_ABRT;
415                  d->delayed_interrupt = INT_DELAY;                  d->int_assert = 1;
416                  return;                  return;
417          }          }
418          if (diskimage_is_a_cdrom(cpu->machine, d->drive + d->base_drive,          if (diskimage_is_a_cdrom(cpu->machine, d->drive + d->base_drive,
# Line 428  void wdc_command(struct cpu *cpu, struct Line 420  void wdc_command(struct cpu *cpu, struct
420                  debug("[ wdc: IDENTIFY drive %i, but it is an ATAPI "                  debug("[ wdc: IDENTIFY drive %i, but it is an ATAPI "
421                      "drive ]\n", d->drive + d->base_drive);                      "drive ]\n", d->drive + d->base_drive);
422                  d->error |= WDCE_ABRT;                  d->error |= WDCE_ABRT;
423                  d->delayed_interrupt = INT_DELAY;                  d->int_assert = 1;
424                  return;                  return;
425          }          }
426    
# Line 456  void wdc_command(struct cpu *cpu, struct Line 448  void wdc_command(struct cpu *cpu, struct
448          case WDCC_IDP:  /*  Initialize drive parameters  */          case WDCC_IDP:  /*  Initialize drive parameters  */
449                  debug("[ wdc: IDP drive %i (TODO) ]\n", d->drive);                  debug("[ wdc: IDP drive %i (TODO) ]\n", d->drive);
450                  /*  TODO  */                  /*  TODO  */
451                  d->delayed_interrupt = INT_DELAY;                  d->int_assert = 1;
452                  break;                  break;
453    
454          case SET_FEATURES:          case SET_FEATURES:
# Line 471  void wdc_command(struct cpu *cpu, struct Line 463  void wdc_command(struct cpu *cpu, struct
463                  default:d->error |= WDCE_ABRT;                  default:d->error |= WDCE_ABRT;
464                  }                  }
465                  /*  TODO: always interrupt?  */                  /*  TODO: always interrupt?  */
466                  d->delayed_interrupt = INT_DELAY;                  d->int_assert = 1;
467                  break;                  break;
468    
469          case WDCC_RECAL:          case WDCC_RECAL:
470                  debug("[ wdc: RECAL drive %i ]\n", d->drive);                  debug("[ wdc: RECAL drive %i ]\n", d->drive);
471                  d->delayed_interrupt = INT_DELAY;                  d->int_assert = 1;
472                  break;                  break;
473    
474          case WDCC_IDENTIFY:          case WDCC_IDENTIFY:
# Line 489  void wdc_command(struct cpu *cpu, struct Line 481  void wdc_command(struct cpu *cpu, struct
481                          wdc_addtoinbuf(d, d->identify_struct[i+1]);                          wdc_addtoinbuf(d, d->identify_struct[i+1]);
482                          wdc_addtoinbuf(d, d->identify_struct[i+0]);                          wdc_addtoinbuf(d, d->identify_struct[i+0]);
483                  }                  }
484                  d->delayed_interrupt = INT_DELAY;                  d->int_assert = 1;
485                  break;                  break;
486    
487          case WDCC_IDLE_IMMED:          case WDCC_IDLE_IMMED:
488                  debug("[ wdc: IDLE_IMMED drive %i ]\n", d->drive);                  debug("[ wdc: IDLE_IMMED drive %i ]\n", d->drive);
489                  /*  TODO: interrupt here?  */                  /*  TODO: interrupt here?  */
490                  d->delayed_interrupt = INT_DELAY;                  d->int_assert = 1;
491                  break;                  break;
492    
493          case WDCC_SETMULTI:          case WDCC_SETMULTI:
494                  debug("[ wdc: SETMULTI drive %i ]\n", d->drive);                  debug("[ wdc: SETMULTI drive %i ]\n", d->drive);
495                  /*  TODO: interrupt here?  */                  /*  TODO: interrupt here?  */
496                  d->delayed_interrupt = INT_DELAY;                  d->int_assert = 1;
497                  break;                  break;
498    
499          case ATAPI_SOFT_RESET:          case ATAPI_SOFT_RESET:
500                  debug("[ wdc: ATAPI_SOFT_RESET drive %i ]\n", d->drive);                  debug("[ wdc: ATAPI_SOFT_RESET drive %i ]\n", d->drive);
501                  /*  TODO: interrupt here?  */                  /*  TODO: interrupt here?  */
502                  d->delayed_interrupt = INT_DELAY;                  d->int_assert = 1;
503                  break;                  break;
504    
505          case ATAPI_PKT_CMD:          case ATAPI_PKT_CMD:
506                  debug("[ wdc: ATAPI_PKT_CMD drive %i ]\n", d->drive);                  debug("[ wdc: ATAPI_PKT_CMD drive %i ]\n", d->drive);
507                  /*  TODO: interrupt here?  */                  /*  TODO: interrupt here?  */
508                  /*  d->delayed_interrupt = INT_DELAY;  */                  /*  d->int_assert = 1;  */
509                  d->atapi_cmd_in_progress = 1;                  d->atapi_cmd_in_progress = 1;
510                  d->atapi_phase = PHASE_CMDOUT;                  d->atapi_phase = PHASE_CMDOUT;
511                  break;                  break;
512    
513            case WDCC_DIAGNOSE:
514                    debug("[ wdc: WDCC_DIAGNOSE drive %i: TODO ]\n", d->drive);
515                    /*  TODO: interrupt here?  */
516                    d->int_assert = 1;
517                    d->error = 1;           /*  No error?  */
518                    break;
519    
520          /*  Unsupported commands, without warning:  */          /*  Unsupported commands, without warning:  */
521          case WDCC_SEC_SET_PASSWORD:          case WDCC_SEC_SET_PASSWORD:
522          case WDCC_SEC_UNLOCK:          case WDCC_SEC_UNLOCK:
# Line 538  void wdc_command(struct cpu *cpu, struct Line 537  void wdc_command(struct cpu *cpu, struct
537  }  }
538    
539    
540  /*  DEVICE_ACCESS(wdc)
  *  dev_wdc_access():  
  */  
 int dev_wdc_access(struct cpu *cpu, struct memory *mem,  
         uint64_t relative_addr, unsigned char *data, size_t len,  
         int writeflag, void *extra)  
541  {  {
542          struct wdc_data *d = extra;          struct wdc_data *d = extra;
543          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
544          int i;          int i;
545    
546            relative_addr /= d->addr_mult;
547    
548            if (!d->io_enabled)
549                    goto ret;
550    
551          if (writeflag == MEM_WRITE) {          if (writeflag == MEM_WRITE) {
552                  if (relative_addr == wd_data)                  if (relative_addr == wd_data)
553                          idata = memory_readmax64(cpu, data, len);                          idata = memory_readmax64(cpu, data, len);
# Line 563  int dev_wdc_access(struct cpu *cpu, stru Line 562  int dev_wdc_access(struct cpu *cpu, stru
562    
563          case wd_data:   /*  0: data  */          case wd_data:   /*  0: data  */
564                  if (writeflag == MEM_READ) {                  if (writeflag == MEM_READ) {
565                          odata = 0;                          odata = wdc_get_inbuf(d);
   
                         odata += wdc_get_inbuf(d);  
566    
567                          if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {                          if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
568                                  if (len >= 2)                                  if (len >= 2)
# Line 584  int dev_wdc_access(struct cpu *cpu, stru Line 581  int dev_wdc_access(struct cpu *cpu, stru
581                          }                          }
582    
583                          if (d->data_debug) {                          if (d->data_debug) {
584                                  char *s = "0x%04llx ]\n";                                  char *s = "0x%04"PRIx64" ]\n";
585                                  if (len == 1)                                  if (len == 1)
586                                          s = "0x%02llx ]\n";                                          s = "0x%02"PRIx64" ]\n";
587                                  if (len == 4)                                  if (len == 4)
588                                          s = "0x%08llx ]\n";                                          s = "0x%08"PRIx64" ]\n";
589                                  if (len == 8)                                  if (len == 8)
590                                          s = "0x%016llx ]\n";                                          s = "0x%016"PRIx64" ]\n";
591                                  debug("[ wdc: read from DATA: ");                                  debug("[ wdc: read from DATA: ");
592                                  debug(s, (long long)odata);                                  debug(s, (uint64_t) odata);
593                          }                          }
594    
595                          if (d->atapi_cmd_in_progress) {                          if (d->atapi_cmd_in_progress) {
# Line 610  int dev_wdc_access(struct cpu *cpu, stru Line 607  int dev_wdc_access(struct cpu *cpu, stru
607                                          } else                                          } else
608                                                  d->atapi_phase =                                                  d->atapi_phase =
609                                                      PHASE_COMPLETED;                                                      PHASE_COMPLETED;
610                                          d->delayed_interrupt = INT_DELAY;                                          d->int_assert = 1;
611                                  }                                  }
612                          } else {                          } else {
613  #if 0  #if 0
# Line 620  int dev_wdc_access(struct cpu *cpu, stru Line 617  int dev_wdc_access(struct cpu *cpu, stru
617                                      ((d->inbuf_tail - d->inbuf_head) % 512)                                      ((d->inbuf_tail - d->inbuf_head) % 512)
618                                      == 0)                                      == 0)
619  #endif  #endif
620                                          d->delayed_interrupt = INT_DELAY;                                          d->int_assert = 1;
621                          }                          }
622                  } else {                  } else {
623                          int inbuf_len;                          int inbuf_len;
624                          if (d->data_debug) {                          if (d->data_debug) {
625                                  char *s = "0x%04llx ]\n";                                  char *s = "0x%04"PRIx64" ]\n";
626                                  if (len == 1)                                  if (len == 1)
627                                          s = "0x%02llx ]\n";                                          s = "0x%02"PRIx64" ]\n";
628                                  if (len == 4)                                  if (len == 4)
629                                          s = "0x%08llx ]\n";                                          s = "0x%08"PRIx64" ]\n";
630                                  if (len == 8)                                  if (len == 8)
631                                          s = "0x%016llx ]\n";                                          s = "0x%016"PRIx64" ]\n";
632                                  debug("[ wdc: write to DATA: ");                                  debug("[ wdc: write to DATA: ");
633                                  debug(s, (long long)idata);                                  debug(s, (uint64_t) idata);
634                          }                          }
635                          if (!d->write_in_progress &&                          if (!d->write_in_progress &&
636                              !d->atapi_cmd_in_progress) {                              !d->atapi_cmd_in_progress) {
# Line 679  int dev_wdc_access(struct cpu *cpu, stru Line 676  int dev_wdc_access(struct cpu *cpu, stru
676                                  inbuf_len += WDC_INBUF_SIZE;                                  inbuf_len += WDC_INBUF_SIZE;
677    
678                          if (d->atapi_cmd_in_progress && inbuf_len == 12) {                          if (d->atapi_cmd_in_progress && inbuf_len == 12) {
679                                  unsigned char *scsi_cmd = malloc(12);                                  unsigned char *scsi_cmd;
680                                  int x = 0, res;                                  int x = 0, res;
681    
682                                    CHECK_ALLOCATION(scsi_cmd = malloc(12));
683    
684                                  if (d->atapi_st != NULL)                                  if (d->atapi_st != NULL)
685                                          scsi_transfer_free(d->atapi_st);                                          scsi_transfer_free(d->atapi_st);
686                                  d->atapi_st = scsi_transfer_alloc();                                  d->atapi_st = scsi_transfer_alloc();
# Line 735  int dev_wdc_access(struct cpu *cpu, stru Line 734  int dev_wdc_access(struct cpu *cpu, stru
734                                          exit(1);                                          exit(1);
735                                  }                                  }
736    
737                                  d->delayed_interrupt = INT_DELAY;                                  d->int_assert = 1;
738                          }                          }
739    
740                          if (( d->write_in_progress == WDCC_WRITEMULTI &&                          if (( d->write_in_progress == WDCC_WRITEMULTI &&
# Line 745  int dev_wdc_access(struct cpu *cpu, stru Line 744  int dev_wdc_access(struct cpu *cpu, stru
744                              inbuf_len % 512 == 0) ) {                              inbuf_len % 512 == 0) ) {
745                                  int count = (d->write_in_progress ==                                  int count = (d->write_in_progress ==
746                                      WDCC_WRITEMULTI)? d->write_count : 1;                                      WDCC_WRITEMULTI)? d->write_count : 1;
747                                  unsigned char buf[512 * count];                                  unsigned char *buf, *b;
748                                  unsigned char *b = buf;  
749                                    CHECK_ALLOCATION(buf = malloc(512 * count));
750                                    b = buf;
751    
752                                  if (d->inbuf_tail+512*count <= WDC_INBUF_SIZE) {                                  if (d->inbuf_tail+512*count <= WDC_INBUF_SIZE) {
753                                          b = d->inbuf + d->inbuf_tail;                                          b = d->inbuf + d->inbuf_tail;
# Line 764  int dev_wdc_access(struct cpu *cpu, stru Line 765  int dev_wdc_access(struct cpu *cpu, stru
765                                  d->write_count -= count;                                  d->write_count -= count;
766                                  d->write_offset += 512 * count;                                  d->write_offset += 512 * count;
767    
768                                  d->delayed_interrupt = INT_DELAY;                                  d->int_assert = 1;
769    
770                                  if (d->write_count == 0)                                  if (d->write_count == 0)
771                                          d->write_in_progress = 0;                                          d->write_in_progress = 0;
772    
773                                    free(buf);
774                          }                          }
775                  }                  }
776                  break;                  break;
# Line 775  int dev_wdc_access(struct cpu *cpu, stru Line 778  int dev_wdc_access(struct cpu *cpu, stru
778          case wd_error:  /*  1: error (r), precomp (w)  */          case wd_error:  /*  1: error (r), precomp (w)  */
779                  if (writeflag == MEM_READ) {                  if (writeflag == MEM_READ) {
780                          odata = d->error;                          odata = d->error;
781                          debug("[ wdc: read from ERROR: 0x%02x ]\n",                          debug("[ wdc: read from ERROR: 0x%02x ]\n", (int)odata);
                             (int)odata);  
782                          /*  TODO:  is the error value cleared on read?  */                          /*  TODO:  is the error value cleared on read?  */
783                          d->error = 0;                          d->error = 0;
784                  } else {                  } else {
# Line 872  int dev_wdc_access(struct cpu *cpu, stru Line 874  int dev_wdc_access(struct cpu *cpu, stru
874                          if (!quiet_mode)                          if (!quiet_mode)
875                                  debug("[ wdc: read from STATUS: 0x%02x ]\n",                                  debug("[ wdc: read from STATUS: 0x%02x ]\n",
876                                      (int)odata);                                      (int)odata);
877                          cpu_interrupt_ack(cpu, d->irq_nr);                          INTERRUPT_DEASSERT(d->irq);
878                          d->int_asserted = 0;                          d->int_assert = 0;
                         d->delayed_interrupt = 0;  
879                  } else {                  } else {
880                          debug("[ wdc: write to COMMAND: 0x%02x ]\n",(int)idata);                          debug("[ wdc: write to COMMAND: 0x%02x ]\n",(int)idata);
881                          wdc_command(cpu, d, idata);                          wdc_command(cpu, d, idata);
# Line 890  int dev_wdc_access(struct cpu *cpu, stru Line 891  int dev_wdc_access(struct cpu *cpu, stru
891                              (int)relative_addr, (int)idata);                              (int)relative_addr, (int)idata);
892          }          }
893    
894          if (cpu->machine->machine_type != MACHINE_HPCMIPS &&          /*  Assert interrupt, if necessary:  */
895              cpu->machine->machine_type != MACHINE_EVBMIPS &&          dev_wdc_tick(cpu, extra);
             cpu->machine->machine_type != MACHINE_BEBOX)  
                 dev_wdc_tick(cpu, extra);  
896    
897    ret:
898          if (writeflag == MEM_READ) {          if (writeflag == MEM_READ) {
899                  if (relative_addr == wd_data)                  if (relative_addr == wd_data)
900                          memory_writemax64(cpu, data, len, odata);                          memory_writemax64(cpu, data, len, odata);
# Line 906  int dev_wdc_access(struct cpu *cpu, stru Line 906  int dev_wdc_access(struct cpu *cpu, stru
906  }  }
907    
908    
909  /*  DEVINIT(wdc)
  *  devinit_wdc():  
  */  
 int devinit_wdc(struct devinit *devinit)  
910  {  {
911          struct wdc_data *d;          struct wdc_data *d;
912          uint64_t alt_status_addr;          uint64_t alt_status_addr;
913          int i, tick_shift = WDC_TICK_SHIFT;          int i, tick_shift = WDC_TICK_SHIFT;
914    
915          d = malloc(sizeof(struct wdc_data));          CHECK_ALLOCATION(d = malloc(sizeof(struct wdc_data)));
         if (d == NULL) {  
                 fprintf(stderr, "out of memory\n");  
                 exit(1);  
         }  
916          memset(d, 0, sizeof(struct wdc_data));          memset(d, 0, sizeof(struct wdc_data));
         d->irq_nr = devinit->irq_nr;  
917    
918            INTERRUPT_CONNECT(devinit->interrupt_path, d->irq);
919            d->addr_mult  = devinit->addr_mult;
920          d->data_debug = 1;          d->data_debug = 1;
921            d->io_enabled = 1;
922    
923          d->inbuf = zeroed_alloc(WDC_INBUF_SIZE);          d->inbuf = zeroed_alloc(WDC_INBUF_SIZE);
924    
# Line 934  int devinit_wdc(struct devinit *devinit) Line 929  int devinit_wdc(struct devinit *devinit)
929    
930          alt_status_addr = devinit->addr + 0x206;          alt_status_addr = devinit->addr + 0x206;
931    
932          /*  Special hack for pcic/hpcmips:  TODO: Fix  */          /*  Special hacks for individual machines:  */
933          if (devinit->addr == 0x14000180)          switch (devinit->machine->machine_type) {
934                  alt_status_addr = 0x14000386;          case MACHINE_MACPPC:
935                    alt_status_addr = devinit->addr + 0x160;
936                    break;
937            case MACHINE_HPCMIPS:
938                    /*  TODO: Fix  */
939                    if (devinit->addr == 0x14000180)
940                            alt_status_addr = 0x14000386;
941                    break;
942            case MACHINE_IQ80321:
943                    alt_status_addr = devinit->addr + 0x402;
944                    break;
945            }
946    
947          /*  Get disk geometries:  */          /*  Get disk geometries:  */
948          for (i=0; i<2; i++)          for (i=0; i<2; i++)
# Line 949  int devinit_wdc(struct devinit *devinit) Line 955  int devinit_wdc(struct devinit *devinit)
955          memory_device_register(devinit->machine->memory, "wdc_altstatus",          memory_device_register(devinit->machine->memory, "wdc_altstatus",
956              alt_status_addr, 2, dev_wdc_altstatus_access, d, DM_DEFAULT, NULL);              alt_status_addr, 2, dev_wdc_altstatus_access, d, DM_DEFAULT, NULL);
957          memory_device_register(devinit->machine->memory, devinit->name,          memory_device_register(devinit->machine->memory, devinit->name,
958              devinit->addr, DEV_WDC_LENGTH, dev_wdc_access, d, DM_DEFAULT,              devinit->addr, DEV_WDC_LENGTH * devinit->addr_mult, dev_wdc_access,
959              NULL);              d, DM_DEFAULT, NULL);
   
         if (devinit->machine->machine_type != MACHINE_HPCMIPS &&  
             devinit->machine->machine_type != MACHINE_EVBMIPS)  
                 tick_shift += 1;  
960    
961          machine_add_tickfunction(devinit->machine, dev_wdc_tick,          machine_add_tickfunction(devinit->machine, dev_wdc_tick,
962              d, tick_shift);              d, tick_shift);
963    
964            devinit->return_ptr = d;
965    
966          return 1;          return 1;
967  }  }
968    

Legend:
Removed from v.20  
changed lines
  Added in v.42

  ViewVC Help
Powered by ViewVC 1.1.26