Line 77... |
Line 77... |
|
|
|
|
void ata_device_init(ata_device *device, int dev, const char *filename)
|
void ata_device_init(ata_device *device, int dev, const char *filename)
|
{
|
{
|
/* set DeviceID */
|
/* set DeviceID */
|
device->settings.dev = dev;
|
device->internals.dev = dev;
|
|
|
/* generate stream for hd_simulation */
|
/* generate stream for hd_simulation */
|
switch(device->type)
|
switch(device->type)
|
{
|
{
|
case TYPE_NO_CONNECT:
|
case TYPE_NO_CONNECT:
|
Line 172... |
Line 172... |
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 */
|
|
|
/* 1) handle device1 first */
|
/* 1) handle device1 first */
|
ata_device_hw_reset(&devices->device1, reset_signal, \
|
ata_device_hw_reset(&devices->device1, reset_signal,
|
1, \ /* assert dasp, this is device1 */
|
1, /* assert dasp, this is device1 */
|
0, \ /* negate pdiag input, no more devices */
|
0, /* negate pdiag input, no more devices */
|
0); /* negate dasp input, no more devices */
|
0); /* negate dasp input, no more devices */
|
|
|
/* 2) Then handle device0 */
|
/* 2) Then handle device0 */
|
ata_device_hw_reset(&devices->device0, reset_signal, \
|
ata_device_hw_reset(&devices->device0, reset_signal,
|
0, \
|
0,
|
devices->device1.sigs.pdiago, \
|
devices->device1.sigs.pdiago,
|
devices->device1.sigs.daspo);
|
devices->device1.sigs.daspo);
|
}
|
}
|
else if (devices->device0.stream)
|
else if (devices->device0.stream)
|
{
|
{
|
/* device0 is device0, there's no device1 */
|
/* device0 is device0, there's no device1 */
|
ata_device_hw_reset(&devices->device0, reset_signal, \
|
ata_device_hw_reset(&devices->device0, reset_signal,
|
0, \ /* negate dasp, this is device0 */
|
0, /* negate dasp, this is device0 */
|
0, \ /* negate pdiag input, there's no device1*/
|
0, /* negate pdiag input, there's no device1*/
|
0); /* negate dasp input, there's no device1 */
|
0); /* negate dasp input, there's no device1 */
|
}
|
}
|
else if (devices->device1.stream)
|
else if (devices->device1.stream)
|
{
|
{
|
/* device1 is (logical) device0, there's no (physical) device0 */
|
/* device1 is (logical) device0, there's no (physical) device0 */
|
ata_device_hw_reset(&devices->device1, reset_signal, \
|
ata_device_hw_reset(&devices->device1, reset_signal,
|
0, \ /* negate dasp, this is device0 */
|
0, /* negate dasp, this is device0 */
|
0, \ /* negate pdiag input, there's no device1*/
|
0, /* negate pdiag input, there's no device1*/
|
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");
|
ata_device_debug(1, "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)
|
{
|
{
|
/* check ata-device state */
|
/* check ata-device state */
|
if (device->settings.state == ATA_STATE_HW_RST)
|
if (device->internals.state == ATA_STATE_HW_RST)
|
{
|
{
|
if (!reset_signal)
|
if (!reset_signal)
|
{
|
{
|
/* hardware reset finished */
|
/* hardware reset finished */
|
|
|
/* set sectors_per_track & heads_per_cylinders */
|
/* set sectors_per_track & heads_per_cylinders */
|
device->settings.sectors_per_track = SECTORS;
|
device->internals.sectors_per_track = SECTORS;
|
device->settings.heads_per_cylinder = HEADS;
|
device->internals.heads_per_cylinder = HEADS;
|
|
|
/* set device1 input signals */
|
/* set device1 input signals */
|
device->sigs.pdiagi = pdiagi;
|
device->sigs.pdiagi = pdiagi;
|
device->sigs.daspi = daspi;
|
device->sigs.daspi = daspi;
|
|
|
Line 234... |
Line 234... |
/* set DRDY bit, when not a PACKET device */
|
/* set DRDY bit, when not a PACKET device */
|
if (!device->packet)
|
if (!device->packet)
|
device->regs.status |= ATA_SR_DRDY;
|
device->regs.status |= ATA_SR_DRDY;
|
|
|
/* set new state */
|
/* set new state */
|
device->settings.state = ATA_STATE_IDLE;
|
device->internals.state = ATA_STATE_IDLE;
|
}
|
}
|
}
|
}
|
else
|
else
|
if (reset_signal)
|
if (reset_signal)
|
{
|
{
|
Line 254... |
Line 254... |
/* set busy bit */
|
/* set busy bit */
|
device->regs.status |= ATA_SR_BSY;
|
device->regs.status |= ATA_SR_BSY;
|
PRINTF("setting status register BSY 0x%2X\n", device->regs.status);
|
PRINTF("setting status register BSY 0x%2X\n", device->regs.status);
|
|
|
/* set new state */
|
/* set new state */
|
device->settings.state = ATA_STATE_HW_RST;
|
device->internals.state = ATA_STATE_HW_RST;
|
}
|
}
|
}
|
}
|
|
|
|
|
/*
|
/*
|
Line 273... |
Line 273... |
/* if device not selected, respond to new values of nIEN & SRST */
|
/* if device not selected, respond to new values of nIEN & SRST */
|
|
|
/* check if SRST bit is set */
|
/* check if SRST bit is set */
|
if (device->regs.device_control & ATA_DCR_RST)
|
if (device->regs.device_control & ATA_DCR_RST)
|
{
|
{
|
if (device->settings.state == ATA_STATE_IDLE)
|
if (device->internals.state == ATA_STATE_IDLE)
|
{ /* start software reset */
|
{ /* start software reset */
|
/* negate bus signals */
|
/* negate bus signals */
|
device->sigs.pdiago = 0;
|
device->sigs.pdiago = 0;
|
device->sigs.intrq = 0;
|
device->sigs.intrq = 0;
|
device->sigs.iordy = 0;
|
device->sigs.iordy = 0;
|
Line 285... |
Line 285... |
|
|
/* set busy bit */
|
/* set busy bit */
|
device->regs.status |= ATA_SR_BSY;
|
device->regs.status |= ATA_SR_BSY;
|
|
|
/* set new state */
|
/* set new state */
|
device->settings.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");
|
ata_device_debug(2, "ata_device_sw_reset initiated.\n");
|
}
|
}
|
}
|
}
|
else if (device->settings.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 */
|
|
|
/*execute device diagnostics */
|
/*execute device diagnostics */
|
ata_execute_device_diagnostics_cmd(device);
|
ata_execute_device_diagnostics_cmd(device);
|
Line 306... |
Line 306... |
/* set DRDY bit, when not a PACKET device */
|
/* set DRDY bit, when not a PACKET device */
|
if (!device->packet)
|
if (!device->packet)
|
device->regs.status |= ATA_SR_DRDY;
|
device->regs.status |= ATA_SR_DRDY;
|
|
|
/* set new state */
|
/* set new state */
|
device->settings.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");
|
ata_device_debug(2, "ata_device_sw_reset done.\n");
|
}
|
}
|
/*
|
/*
|
Line 329... |
Line 329... |
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.");
|
MSG_WARNING("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->settings.dev )
|
if ( (device->regs.device_head & ATA_DHR_DEV) == device->internals.dev )
|
ata_device_execute_cmd(device);
|
ata_device_execute_cmd(device);
|
else
|
else
|
{
|
{
|
/* if not selected, only respond to EXECUTE DEVICE DIAGNOSTICS */
|
/* if not selected, only respond to EXECUTE DEVICE DIAGNOSTICS */
|
if (device->regs.command == EXECUTE_DEVICE_DIAGNOSTICS)
|
if (device->regs.command == EXECUTE_DEVICE_DIAGNOSTICS)
|
Line 375... |
Line 375... |
|
|
/* 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");
|
ata_device_debug(4, "alternate_status register read\n");
|
if ( (device->regs.device_head & ATA_DHR_DEV) == device->settings.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");
|
ata_device_debug(2, "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", \
|
ata_device_debug(4, "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", \
|
ata_device_debug(4, "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 :
|
ata_device_debug(4, "data register read, value = 0x%04X, cnt = %3d\n", \
|
if (!device->regs.status & ATA_SR_DRQ)
|
device->settings.dbuf[device->settings.dbuf_cnt], device->settings.dbuf_cnt);
|
{
|
return device -> settings.dbuf[device->settings.dbuf_cnt++];
|
ata_device_debug(1, "data register read, while DRQ bit negated\n" );
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
ata_device_debug(4, "data register read, value = 0x%04X, cnt = %3d\n",
|
|
*device->internals.dbuf_ptr, device->internals.dbuf_cnt);
|
|
if (!--device->internals.dbuf_cnt)
|
|
device->regs.status &= ~ATA_SR_DRQ;
|
|
return *device -> internals.dbuf_ptr++;
|
|
}
|
|
|
case ATA_DHR :
|
case ATA_DHR :
|
ata_device_debug(4, "device_head register read, value = 0x%02X\n", \
|
ata_device_debug(4, "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", \
|
ata_device_debug(4, "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", \
|
ata_device_debug(4, "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", \
|
ata_device_debug(4, "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");
|
ata_device_debug(4, "status register read\n");
|
if ( (device->regs.device_head & ATA_DHR_DEV) == device->settings.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");
|
ata_device_debug(2, "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
|