/[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 34 by dpavlin, Mon Oct 8 16:21:17 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.74 2007/02/16 19:57:56 debug Exp $
29   *   *
30   *  Standard "wdc" IDE controller.   *  Standard "wdc" IDE controller.
31   */   */
# 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 735  int dev_wdc_access(struct cpu *cpu, stru Line 732  int dev_wdc_access(struct cpu *cpu, stru
732                                          exit(1);                                          exit(1);
733                                  }                                  }
734    
735                                  d->delayed_interrupt = INT_DELAY;                                  d->int_assert = 1;
736                          }                          }
737    
738                          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 742  int dev_wdc_access(struct cpu *cpu, stru
742                              inbuf_len % 512 == 0) ) {                              inbuf_len % 512 == 0) ) {
743                                  int count = (d->write_in_progress ==                                  int count = (d->write_in_progress ==
744                                      WDCC_WRITEMULTI)? d->write_count : 1;                                      WDCC_WRITEMULTI)? d->write_count : 1;
745                                  unsigned char buf[512 * count];                                  unsigned char *buf = malloc(512 * count);
746                                  unsigned char *b = buf;                                  unsigned char *b = buf;
747    
748                                    if (buf == NULL) {
749                                            fprintf(stderr, "out of memory\n");
750                                            exit(1);
751                                    }
752    
753                                  if (d->inbuf_tail+512*count <= WDC_INBUF_SIZE) {                                  if (d->inbuf_tail+512*count <= WDC_INBUF_SIZE) {
754                                          b = d->inbuf + d->inbuf_tail;                                          b = d->inbuf + d->inbuf_tail;
755                                          d->inbuf_tail = (d->inbuf_tail + 512                                          d->inbuf_tail = (d->inbuf_tail + 512
# Line 764  int dev_wdc_access(struct cpu *cpu, stru Line 766  int dev_wdc_access(struct cpu *cpu, stru
766                                  d->write_count -= count;                                  d->write_count -= count;
767                                  d->write_offset += 512 * count;                                  d->write_offset += 512 * count;
768    
769                                  d->delayed_interrupt = INT_DELAY;                                  d->int_assert = 1;
770    
771                                  if (d->write_count == 0)                                  if (d->write_count == 0)
772                                          d->write_in_progress = 0;                                          d->write_in_progress = 0;
773    
774                                    free(buf);
775                          }                          }
776                  }                  }
777                  break;                  break;
# Line 775  int dev_wdc_access(struct cpu *cpu, stru Line 779  int dev_wdc_access(struct cpu *cpu, stru
779          case wd_error:  /*  1: error (r), precomp (w)  */          case wd_error:  /*  1: error (r), precomp (w)  */
780                  if (writeflag == MEM_READ) {                  if (writeflag == MEM_READ) {
781                          odata = d->error;                          odata = d->error;
782                          debug("[ wdc: read from ERROR: 0x%02x ]\n",                          debug("[ wdc: read from ERROR: 0x%02x ]\n", (int)odata);
                             (int)odata);  
783                          /*  TODO:  is the error value cleared on read?  */                          /*  TODO:  is the error value cleared on read?  */
784                          d->error = 0;                          d->error = 0;
785                  } else {                  } else {
# Line 872  int dev_wdc_access(struct cpu *cpu, stru Line 875  int dev_wdc_access(struct cpu *cpu, stru
875                          if (!quiet_mode)                          if (!quiet_mode)
876                                  debug("[ wdc: read from STATUS: 0x%02x ]\n",                                  debug("[ wdc: read from STATUS: 0x%02x ]\n",
877                                      (int)odata);                                      (int)odata);
878                          cpu_interrupt_ack(cpu, d->irq_nr);                          INTERRUPT_DEASSERT(d->irq);
879                          d->int_asserted = 0;                          d->int_assert = 0;
                         d->delayed_interrupt = 0;  
880                  } else {                  } else {
881                          debug("[ wdc: write to COMMAND: 0x%02x ]\n",(int)idata);                          debug("[ wdc: write to COMMAND: 0x%02x ]\n",(int)idata);
882                          wdc_command(cpu, d, idata);                          wdc_command(cpu, d, idata);
# Line 890  int dev_wdc_access(struct cpu *cpu, stru Line 892  int dev_wdc_access(struct cpu *cpu, stru
892                              (int)relative_addr, (int)idata);                              (int)relative_addr, (int)idata);
893          }          }
894    
895          if (cpu->machine->machine_type != MACHINE_HPCMIPS &&          /*  Assert interrupt, if necessary:  */
896              cpu->machine->machine_type != MACHINE_EVBMIPS &&          dev_wdc_tick(cpu, extra);
             cpu->machine->machine_type != MACHINE_BEBOX)  
                 dev_wdc_tick(cpu, extra);  
897    
898    ret:
899          if (writeflag == MEM_READ) {          if (writeflag == MEM_READ) {
900                  if (relative_addr == wd_data)                  if (relative_addr == wd_data)
901                          memory_writemax64(cpu, data, len, odata);                          memory_writemax64(cpu, data, len, odata);
# Line 906  int dev_wdc_access(struct cpu *cpu, stru Line 907  int dev_wdc_access(struct cpu *cpu, stru
907  }  }
908    
909    
910  /*  DEVINIT(wdc)
  *  devinit_wdc():  
  */  
 int devinit_wdc(struct devinit *devinit)  
911  {  {
912          struct wdc_data *d;          struct wdc_data *d;
913          uint64_t alt_status_addr;          uint64_t alt_status_addr;
# Line 921  int devinit_wdc(struct devinit *devinit) Line 919  int devinit_wdc(struct devinit *devinit)
919                  exit(1);                  exit(1);
920          }          }
921          memset(d, 0, sizeof(struct wdc_data));          memset(d, 0, sizeof(struct wdc_data));
         d->irq_nr = devinit->irq_nr;  
922    
923            INTERRUPT_CONNECT(devinit->interrupt_path, d->irq);
924            d->addr_mult  = devinit->addr_mult;
925          d->data_debug = 1;          d->data_debug = 1;
926            d->io_enabled = 1;
927    
928          d->inbuf = zeroed_alloc(WDC_INBUF_SIZE);          d->inbuf = zeroed_alloc(WDC_INBUF_SIZE);
929    
# Line 934  int devinit_wdc(struct devinit *devinit) Line 934  int devinit_wdc(struct devinit *devinit)
934    
935          alt_status_addr = devinit->addr + 0x206;          alt_status_addr = devinit->addr + 0x206;
936    
937          /*  Special hack for pcic/hpcmips:  TODO: Fix  */          /*  Special hacks for individual machines:  */
938          if (devinit->addr == 0x14000180)          switch (devinit->machine->machine_type) {
939                  alt_status_addr = 0x14000386;          case MACHINE_MACPPC:
940                    alt_status_addr = devinit->addr + 0x160;
941                    break;
942            case MACHINE_HPCMIPS:
943                    /*  TODO: Fix  */
944                    if (devinit->addr == 0x14000180)
945                            alt_status_addr = 0x14000386;
946                    break;
947            case MACHINE_IQ80321:
948                    alt_status_addr = devinit->addr + 0x402;
949                    break;
950            }
951    
952          /*  Get disk geometries:  */          /*  Get disk geometries:  */
953          for (i=0; i<2; i++)          for (i=0; i<2; i++)
# Line 949  int devinit_wdc(struct devinit *devinit) Line 960  int devinit_wdc(struct devinit *devinit)
960          memory_device_register(devinit->machine->memory, "wdc_altstatus",          memory_device_register(devinit->machine->memory, "wdc_altstatus",
961              alt_status_addr, 2, dev_wdc_altstatus_access, d, DM_DEFAULT, NULL);              alt_status_addr, 2, dev_wdc_altstatus_access, d, DM_DEFAULT, NULL);
962          memory_device_register(devinit->machine->memory, devinit->name,          memory_device_register(devinit->machine->memory, devinit->name,
963              devinit->addr, DEV_WDC_LENGTH, dev_wdc_access, d, DM_DEFAULT,              devinit->addr, DEV_WDC_LENGTH * devinit->addr_mult, dev_wdc_access,
964              NULL);              d, DM_DEFAULT, NULL);
   
         if (devinit->machine->machine_type != MACHINE_HPCMIPS &&  
             devinit->machine->machine_type != MACHINE_EVBMIPS)  
                 tick_shift += 1;  
965    
966          machine_add_tickfunction(devinit->machine, dev_wdc_tick,          machine_add_tickfunction(devinit->machine, dev_wdc_tick,
967              d, tick_shift);              d, tick_shift, 0.0);
968    
969            devinit->return_ptr = d;
970    
971          return 1;          return 1;
972  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.26