/[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 22 by dpavlin, Mon Oct 8 16:19:37 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2004-2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2004-2006  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.63 2006/02/18 13:15:21 debug Exp $
29   *   *
30   *  Standard "wdc" IDE controller.   *  Standard "wdc" IDE controller.
31   */   */
# Line 66  extern int quiet_mode; Line 66  extern int quiet_mode;
66    
67  struct wdc_data {  struct wdc_data {
68          int             irq_nr;          int             irq_nr;
69            int             addr_mult;
70          int             base_drive;          int             base_drive;
71          int             data_debug;          int             data_debug;
72    
# Line 101  struct wdc_data { Line 102  struct wdc_data {
102          int             atapi_phase;          int             atapi_phase;
103          struct scsi_transfer *atapi_st;          struct scsi_transfer *atapi_st;
104          int             atapi_len;          int             atapi_len;
105          int             atapi_received;          size_t          atapi_received;
106    
107          unsigned char   identify_struct[512];          unsigned char   identify_struct[512];
108  };  };
# Line 211  static void wdc_initialize_identify_stru Line 212  static void wdc_initialize_identify_stru
212          /*  27-46: Model number  */          /*  27-46: Model number  */
213          if (diskimage_getname(cpu->machine, d->drive + d->base_drive,          if (diskimage_getname(cpu->machine, d->drive + d->base_drive,
214              DISKIMAGE_IDE, namebuf, sizeof(namebuf))) {              DISKIMAGE_IDE, namebuf, sizeof(namebuf))) {
215                  int i;                  size_t i;
216                  for (i=0; i<sizeof(namebuf); i++)                  for (i=0; i<sizeof(namebuf); i++)
217                          if (namebuf[i] == 0) {                          if (namebuf[i] == 0) {
218                                  for (; i<sizeof(namebuf); i++)                                  for (; i<sizeof(namebuf); i++)
# Line 368  static int status_byte(struct wdc_data * Line 369  static int status_byte(struct wdc_data *
369  /*  /*
370   *  dev_wdc_altstatus_access():   *  dev_wdc_altstatus_access():
371   */   */
372  int dev_wdc_altstatus_access(struct cpu *cpu, struct memory *mem,  DEVICE_ACCESS(wdc_altstatus)
         uint64_t relative_addr, unsigned char *data, size_t len,  
         int writeflag, void *extra)  
373  {  {
374          struct wdc_data *d = extra;          struct wdc_data *d = extra;
375          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
# Line 402  int dev_wdc_altstatus_access(struct cpu Line 401  int dev_wdc_altstatus_access(struct cpu
401   */   */
402  void wdc_command(struct cpu *cpu, struct wdc_data *d, int idata)  void wdc_command(struct cpu *cpu, struct wdc_data *d, int idata)
403  {  {
404          int i;          size_t i;
405    
406          d->cur_command = idata;          d->cur_command = idata;
407          d->atapi_cmd_in_progress = 0;          d->atapi_cmd_in_progress = 0;
# Line 518  void wdc_command(struct cpu *cpu, struct Line 517  void wdc_command(struct cpu *cpu, struct
517                  d->atapi_phase = PHASE_CMDOUT;                  d->atapi_phase = PHASE_CMDOUT;
518                  break;                  break;
519    
520            case WDCC_DIAGNOSE:
521                    debug("[ wdc: WDCC_DIAGNOSE drive %i: TODO ]\n", d->drive);
522                    /*  TODO: interrupt here?  */
523                    d->delayed_interrupt = INT_DELAY;
524                    d->error = 1;           /*  No error?  */
525                    break;
526    
527          /*  Unsupported commands, without warning:  */          /*  Unsupported commands, without warning:  */
528          case WDCC_SEC_SET_PASSWORD:          case WDCC_SEC_SET_PASSWORD:
529          case WDCC_SEC_UNLOCK:          case WDCC_SEC_UNLOCK:
# Line 541  void wdc_command(struct cpu *cpu, struct Line 547  void wdc_command(struct cpu *cpu, struct
547  /*  /*
548   *  dev_wdc_access():   *  dev_wdc_access():
549   */   */
550  int dev_wdc_access(struct cpu *cpu, struct memory *mem,  DEVICE_ACCESS(wdc)
         uint64_t relative_addr, unsigned char *data, size_t len,  
         int writeflag, void *extra)  
551  {  {
552          struct wdc_data *d = extra;          struct wdc_data *d = extra;
553          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
554          int i;          int i;
555    
556            relative_addr /= d->addr_mult;
557    
558          if (writeflag == MEM_WRITE) {          if (writeflag == MEM_WRITE) {
559                  if (relative_addr == wd_data)                  if (relative_addr == wd_data)
560                          idata = memory_readmax64(cpu, data, len);                          idata = memory_readmax64(cpu, data, len);
# Line 563  int dev_wdc_access(struct cpu *cpu, stru Line 569  int dev_wdc_access(struct cpu *cpu, stru
569    
570          case wd_data:   /*  0: data  */          case wd_data:   /*  0: data  */
571                  if (writeflag == MEM_READ) {                  if (writeflag == MEM_READ) {
572                          odata = 0;                          odata = wdc_get_inbuf(d);
   
                         odata += wdc_get_inbuf(d);  
573    
574                          if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {                          if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
575                                  if (len >= 2)                                  if (len >= 2)
# 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 906  int dev_wdc_access(struct cpu *cpu, stru Line 909  int dev_wdc_access(struct cpu *cpu, stru
909  }  }
910    
911    
912  /*  DEVINIT(wdc)
  *  devinit_wdc():  
  */  
 int devinit_wdc(struct devinit *devinit)  
913  {  {
914          struct wdc_data *d;          struct wdc_data *d;
915          uint64_t alt_status_addr;          uint64_t alt_status_addr;
# Line 921  int devinit_wdc(struct devinit *devinit) Line 921  int devinit_wdc(struct devinit *devinit)
921                  exit(1);                  exit(1);
922          }          }
923          memset(d, 0, sizeof(struct wdc_data));          memset(d, 0, sizeof(struct wdc_data));
924          d->irq_nr = devinit->irq_nr;          d->irq_nr     = devinit->irq_nr;
925            d->addr_mult  = devinit->addr_mult;
926          d->data_debug = 1;          d->data_debug = 1;
927    
928          d->inbuf = zeroed_alloc(WDC_INBUF_SIZE);          d->inbuf = zeroed_alloc(WDC_INBUF_SIZE);
# 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);
965    
966          if (devinit->machine->machine_type != MACHINE_HPCMIPS &&          if (devinit->machine->machine_type != MACHINE_HPCMIPS &&
967              devinit->machine->machine_type != MACHINE_EVBMIPS)              devinit->machine->machine_type != MACHINE_EVBMIPS)

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

  ViewVC Help
Powered by ViewVC 1.1.26