--- trunk/src/devices/dev_wdc.c 2007/10/08 16:19:23 20 +++ trunk/src/devices/dev_wdc.c 2007/10/08 16:19:37 22 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2005 Anders Gavare. All rights reserved. + * Copyright (C) 2004-2006 Anders Gavare. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * - * $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 $ * * Standard "wdc" IDE controller. */ @@ -66,6 +66,7 @@ struct wdc_data { int irq_nr; + int addr_mult; int base_drive; int data_debug; @@ -101,7 +102,7 @@ int atapi_phase; struct scsi_transfer *atapi_st; int atapi_len; - int atapi_received; + size_t atapi_received; unsigned char identify_struct[512]; }; @@ -211,7 +212,7 @@ /* 27-46: Model number */ if (diskimage_getname(cpu->machine, d->drive + d->base_drive, DISKIMAGE_IDE, namebuf, sizeof(namebuf))) { - int i; + size_t i; for (i=0; icur_command = idata; d->atapi_cmd_in_progress = 0; @@ -518,6 +517,13 @@ d->atapi_phase = PHASE_CMDOUT; break; + case WDCC_DIAGNOSE: + debug("[ wdc: WDCC_DIAGNOSE drive %i: TODO ]\n", d->drive); + /* TODO: interrupt here? */ + d->delayed_interrupt = INT_DELAY; + d->error = 1; /* No error? */ + break; + /* Unsupported commands, without warning: */ case WDCC_SEC_SET_PASSWORD: case WDCC_SEC_UNLOCK: @@ -541,14 +547,14 @@ /* * 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) +DEVICE_ACCESS(wdc) { struct wdc_data *d = extra; uint64_t idata = 0, odata = 0; int i; + relative_addr /= d->addr_mult; + if (writeflag == MEM_WRITE) { if (relative_addr == wd_data) idata = memory_readmax64(cpu, data, len); @@ -563,9 +569,7 @@ case wd_data: /* 0: data */ if (writeflag == MEM_READ) { - odata = 0; - - odata += wdc_get_inbuf(d); + odata = wdc_get_inbuf(d); if (cpu->byte_order == EMUL_LITTLE_ENDIAN) { if (len >= 2) @@ -775,8 +779,7 @@ case wd_error: /* 1: error (r), precomp (w) */ if (writeflag == MEM_READ) { odata = d->error; - debug("[ wdc: read from ERROR: 0x%02x ]\n", - (int)odata); + debug("[ wdc: read from ERROR: 0x%02x ]\n", (int)odata); /* TODO: is the error value cleared on read? */ d->error = 0; } else { @@ -906,10 +909,7 @@ } -/* - * devinit_wdc(): - */ -int devinit_wdc(struct devinit *devinit) +DEVINIT(wdc) { struct wdc_data *d; uint64_t alt_status_addr; @@ -921,8 +921,8 @@ exit(1); } memset(d, 0, sizeof(struct wdc_data)); - d->irq_nr = devinit->irq_nr; - + d->irq_nr = devinit->irq_nr; + d->addr_mult = devinit->addr_mult; d->data_debug = 1; d->inbuf = zeroed_alloc(WDC_INBUF_SIZE); @@ -934,9 +934,20 @@ alt_status_addr = devinit->addr + 0x206; - /* Special hack for pcic/hpcmips: TODO: Fix */ - if (devinit->addr == 0x14000180) - alt_status_addr = 0x14000386; + /* Special hacks for individual machines: */ + switch (devinit->machine->machine_type) { + case MACHINE_MACPPC: + alt_status_addr = devinit->addr + 0x160; + break; + case MACHINE_HPCMIPS: + /* TODO: Fix */ + if (devinit->addr == 0x14000180) + alt_status_addr = 0x14000386; + break; + case MACHINE_IQ80321: + alt_status_addr = devinit->addr + 0x402; + break; + } /* Get disk geometries: */ for (i=0; i<2; i++) @@ -949,8 +960,8 @@ memory_device_register(devinit->machine->memory, "wdc_altstatus", alt_status_addr, 2, dev_wdc_altstatus_access, d, DM_DEFAULT, NULL); memory_device_register(devinit->machine->memory, devinit->name, - devinit->addr, DEV_WDC_LENGTH, dev_wdc_access, d, DM_DEFAULT, - NULL); + devinit->addr, DEV_WDC_LENGTH * devinit->addr_mult, dev_wdc_access, + d, DM_DEFAULT, NULL); if (devinit->machine->machine_type != MACHINE_HPCMIPS && devinit->machine->machine_type != MACHINE_EVBMIPS)