Commit 201a51fc386c0a2b55b13ad99589b1dfd1f39a5d
1 parent
01179c38
PCMCIA bus support. Parts of CF-ATA command set. Hitachi DSCM microdrive emulation.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2748 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
831 additions
and
4 deletions
hw/ide.c
| @@ -2,6 +2,7 @@ | @@ -2,6 +2,7 @@ | ||
| 2 | * QEMU IDE disk and CD-ROM Emulator | 2 | * QEMU IDE disk and CD-ROM Emulator |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2003 Fabrice Bellard | 4 | * Copyright (c) 2003 Fabrice Bellard |
| 5 | + * Copyright (c) 2006 Openedhand Ltd. | ||
| 5 | * | 6 | * |
| 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy | 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
| 7 | * of this software and associated documentation files (the "Software"), to deal | 8 | * of this software and associated documentation files (the "Software"), to deal |
| @@ -131,6 +132,7 @@ | @@ -131,6 +132,7 @@ | ||
| 131 | #define WIN_SPECIFY 0x91 /* set drive geometry translation */ | 132 | #define WIN_SPECIFY 0x91 /* set drive geometry translation */ |
| 132 | #define WIN_DOWNLOAD_MICROCODE 0x92 | 133 | #define WIN_DOWNLOAD_MICROCODE 0x92 |
| 133 | #define WIN_STANDBYNOW2 0x94 | 134 | #define WIN_STANDBYNOW2 0x94 |
| 135 | +#define CFA_IDLEIMMEDIATE 0x95 /* force drive to become "ready" */ | ||
| 134 | #define WIN_STANDBY2 0x96 | 136 | #define WIN_STANDBY2 0x96 |
| 135 | #define WIN_SETIDLE2 0x97 | 137 | #define WIN_SETIDLE2 0x97 |
| 136 | #define WIN_CHECKPOWERMODE2 0x98 | 138 | #define WIN_CHECKPOWERMODE2 0x98 |
| @@ -142,7 +144,8 @@ | @@ -142,7 +144,8 @@ | ||
| 142 | #define WIN_PIDENTIFY 0xA1 /* identify ATAPI device */ | 144 | #define WIN_PIDENTIFY 0xA1 /* identify ATAPI device */ |
| 143 | #define WIN_QUEUED_SERVICE 0xA2 | 145 | #define WIN_QUEUED_SERVICE 0xA2 |
| 144 | #define WIN_SMART 0xB0 /* self-monitoring and reporting */ | 146 | #define WIN_SMART 0xB0 /* self-monitoring and reporting */ |
| 145 | -#define CFA_ERASE_SECTORS 0xC0 | 147 | +#define CFA_ACCESS_METADATA_STORAGE 0xB8 |
| 148 | +#define CFA_ERASE_SECTORS 0xC0 /* microdrives implement as NOP */ | ||
| 146 | #define WIN_MULTREAD 0xC4 /* read sectors using multiple mode*/ | 149 | #define WIN_MULTREAD 0xC4 /* read sectors using multiple mode*/ |
| 147 | #define WIN_MULTWRITE 0xC5 /* write sectors using multiple mode */ | 150 | #define WIN_MULTWRITE 0xC5 /* write sectors using multiple mode */ |
| 148 | #define WIN_SETMULT 0xC6 /* enable/disable multiple mode */ | 151 | #define WIN_SETMULT 0xC6 /* enable/disable multiple mode */ |
| @@ -176,11 +179,13 @@ | @@ -176,11 +179,13 @@ | ||
| 176 | #define WIN_IDENTIFY_DMA 0xEE /* same as WIN_IDENTIFY, but DMA */ | 179 | #define WIN_IDENTIFY_DMA 0xEE /* same as WIN_IDENTIFY, but DMA */ |
| 177 | #define WIN_SETFEATURES 0xEF /* set special drive features */ | 180 | #define WIN_SETFEATURES 0xEF /* set special drive features */ |
| 178 | #define EXABYTE_ENABLE_NEST 0xF0 | 181 | #define EXABYTE_ENABLE_NEST 0xF0 |
| 182 | +#define IBM_SENSE_CONDITION 0xF0 /* measure disk temperature */ | ||
| 179 | #define WIN_SECURITY_SET_PASS 0xF1 | 183 | #define WIN_SECURITY_SET_PASS 0xF1 |
| 180 | #define WIN_SECURITY_UNLOCK 0xF2 | 184 | #define WIN_SECURITY_UNLOCK 0xF2 |
| 181 | #define WIN_SECURITY_ERASE_PREPARE 0xF3 | 185 | #define WIN_SECURITY_ERASE_PREPARE 0xF3 |
| 182 | #define WIN_SECURITY_ERASE_UNIT 0xF4 | 186 | #define WIN_SECURITY_ERASE_UNIT 0xF4 |
| 183 | #define WIN_SECURITY_FREEZE_LOCK 0xF5 | 187 | #define WIN_SECURITY_FREEZE_LOCK 0xF5 |
| 188 | +#define CFA_WEAR_LEVEL 0xF5 /* microdrives implement as NOP */ | ||
| 184 | #define WIN_SECURITY_DISABLE 0xF6 | 189 | #define WIN_SECURITY_DISABLE 0xF6 |
| 185 | #define WIN_READ_NATIVE_MAX 0xF8 /* return the native maximum address */ | 190 | #define WIN_READ_NATIVE_MAX 0xF8 /* return the native maximum address */ |
| 186 | #define WIN_SET_MAX 0xF9 | 191 | #define WIN_SET_MAX 0xF9 |
| @@ -282,6 +287,12 @@ | @@ -282,6 +287,12 @@ | ||
| 282 | #define ASC_MEDIUM_NOT_PRESENT 0x3a | 287 | #define ASC_MEDIUM_NOT_PRESENT 0x3a |
| 283 | #define ASC_SAVING_PARAMETERS_NOT_SUPPORTED 0x39 | 288 | #define ASC_SAVING_PARAMETERS_NOT_SUPPORTED 0x39 |
| 284 | 289 | ||
| 290 | +#define CFA_NO_ERROR 0x00 | ||
| 291 | +#define CFA_MISC_ERROR 0x09 | ||
| 292 | +#define CFA_INVALID_COMMAND 0x20 | ||
| 293 | +#define CFA_INVALID_ADDRESS 0x21 | ||
| 294 | +#define CFA_ADDRESS_OVERFLOW 0x2f | ||
| 295 | + | ||
| 285 | #define SENSE_NONE 0 | 296 | #define SENSE_NONE 0 |
| 286 | #define SENSE_NOT_READY 2 | 297 | #define SENSE_NOT_READY 2 |
| 287 | #define SENSE_ILLEGAL_REQUEST 5 | 298 | #define SENSE_ILLEGAL_REQUEST 5 |
| @@ -295,6 +306,7 @@ typedef void EndTransferFunc(struct IDEState *); | @@ -295,6 +306,7 @@ typedef void EndTransferFunc(struct IDEState *); | ||
| 295 | typedef struct IDEState { | 306 | typedef struct IDEState { |
| 296 | /* ide config */ | 307 | /* ide config */ |
| 297 | int is_cdrom; | 308 | int is_cdrom; |
| 309 | + int is_cf; | ||
| 298 | int cylinders, heads, sectors; | 310 | int cylinders, heads, sectors; |
| 299 | int64_t nb_sectors; | 311 | int64_t nb_sectors; |
| 300 | int mult_sectors; | 312 | int mult_sectors; |
| @@ -347,6 +359,12 @@ typedef struct IDEState { | @@ -347,6 +359,12 @@ typedef struct IDEState { | ||
| 347 | uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4]; | 359 | uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4]; |
| 348 | QEMUTimer *sector_write_timer; /* only used for win2k instal hack */ | 360 | QEMUTimer *sector_write_timer; /* only used for win2k instal hack */ |
| 349 | uint32_t irq_count; /* counts IRQs when using win2k install hack */ | 361 | uint32_t irq_count; /* counts IRQs when using win2k install hack */ |
| 362 | + /* CF-ATA extended error */ | ||
| 363 | + uint8_t ext_error; | ||
| 364 | + /* CF-ATA metadata storage */ | ||
| 365 | + uint32_t mdata_size; | ||
| 366 | + uint8_t *mdata_storage; | ||
| 367 | + int media_changed; | ||
| 350 | } IDEState; | 368 | } IDEState; |
| 351 | 369 | ||
| 352 | #define BM_STATUS_DMAING 0x01 | 370 | #define BM_STATUS_DMAING 0x01 |
| @@ -542,6 +560,74 @@ static void ide_atapi_identify(IDEState *s) | @@ -542,6 +560,74 @@ static void ide_atapi_identify(IDEState *s) | ||
| 542 | s->identify_set = 1; | 560 | s->identify_set = 1; |
| 543 | } | 561 | } |
| 544 | 562 | ||
| 563 | +static void ide_cfata_identify(IDEState *s) | ||
| 564 | +{ | ||
| 565 | + uint16_t *p; | ||
| 566 | + uint32_t cur_sec; | ||
| 567 | + char buf[20]; | ||
| 568 | + | ||
| 569 | + p = (uint16_t *) s->identify_data; | ||
| 570 | + if (s->identify_set) | ||
| 571 | + goto fill_buffer; | ||
| 572 | + | ||
| 573 | + memset(p, 0, sizeof(s->identify_data)); | ||
| 574 | + | ||
| 575 | + cur_sec = s->cylinders * s->heads * s->sectors; | ||
| 576 | + | ||
| 577 | + put_le16(p + 0, 0x848a); /* CF Storage Card signature */ | ||
| 578 | + put_le16(p + 1, s->cylinders); /* Default cylinders */ | ||
| 579 | + put_le16(p + 3, s->heads); /* Default heads */ | ||
| 580 | + put_le16(p + 6, s->sectors); /* Default sectors per track */ | ||
| 581 | + put_le16(p + 7, s->nb_sectors >> 16); /* Sectors per card */ | ||
| 582 | + put_le16(p + 8, s->nb_sectors); /* Sectors per card */ | ||
| 583 | + snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial); | ||
| 584 | + padstr((uint8_t *)(p + 10), buf, 20); /* Serial number in ASCII */ | ||
| 585 | + put_le16(p + 22, 0x0004); /* ECC bytes */ | ||
| 586 | + padstr((uint8_t *) (p + 23), QEMU_VERSION, 8); /* Firmware Revision */ | ||
| 587 | + padstr((uint8_t *) (p + 27), "QEMU MICRODRIVE", 40);/* Model number */ | ||
| 588 | +#if MAX_MULT_SECTORS > 1 | ||
| 589 | + put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS); | ||
| 590 | +#else | ||
| 591 | + put_le16(p + 47, 0x0000); | ||
| 592 | +#endif | ||
| 593 | + put_le16(p + 49, 0x0f00); /* Capabilities */ | ||
| 594 | + put_le16(p + 51, 0x0002); /* PIO cycle timing mode */ | ||
| 595 | + put_le16(p + 52, 0x0001); /* DMA cycle timing mode */ | ||
| 596 | + put_le16(p + 53, 0x0003); /* Translation params valid */ | ||
| 597 | + put_le16(p + 54, s->cylinders); /* Current cylinders */ | ||
| 598 | + put_le16(p + 55, s->heads); /* Current heads */ | ||
| 599 | + put_le16(p + 56, s->sectors); /* Current sectors */ | ||
| 600 | + put_le16(p + 57, cur_sec); /* Current capacity */ | ||
| 601 | + put_le16(p + 58, cur_sec >> 16); /* Current capacity */ | ||
| 602 | + if (s->mult_sectors) /* Multiple sector setting */ | ||
| 603 | + put_le16(p + 59, 0x100 | s->mult_sectors); | ||
| 604 | + put_le16(p + 60, s->nb_sectors); /* Total LBA sectors */ | ||
| 605 | + put_le16(p + 61, s->nb_sectors >> 16); /* Total LBA sectors */ | ||
| 606 | + put_le16(p + 63, 0x0203); /* Multiword DMA capability */ | ||
| 607 | + put_le16(p + 64, 0x0001); /* Flow Control PIO support */ | ||
| 608 | + put_le16(p + 65, 0x0096); /* Min. Multiword DMA cycle */ | ||
| 609 | + put_le16(p + 66, 0x0096); /* Rec. Multiword DMA cycle */ | ||
| 610 | + put_le16(p + 68, 0x00b4); /* Min. PIO cycle time */ | ||
| 611 | + put_le16(p + 82, 0x400c); /* Command Set supported */ | ||
| 612 | + put_le16(p + 83, 0x7068); /* Command Set supported */ | ||
| 613 | + put_le16(p + 84, 0x4000); /* Features supported */ | ||
| 614 | + put_le16(p + 85, 0x000c); /* Command Set enabled */ | ||
| 615 | + put_le16(p + 86, 0x7044); /* Command Set enabled */ | ||
| 616 | + put_le16(p + 87, 0x4000); /* Features enabled */ | ||
| 617 | + put_le16(p + 91, 0x4060); /* Current APM level */ | ||
| 618 | + put_le16(p + 129, 0x0002); /* Current features option */ | ||
| 619 | + put_le16(p + 130, 0x0005); /* Reassigned sectors */ | ||
| 620 | + put_le16(p + 131, 0x0001); /* Initial power mode */ | ||
| 621 | + put_le16(p + 132, 0x0000); /* User signature */ | ||
| 622 | + put_le16(p + 160, 0x8100); /* Power requirement */ | ||
| 623 | + put_le16(p + 161, 0x8001); /* CF command set */ | ||
| 624 | + | ||
| 625 | + s->identify_set = 1; | ||
| 626 | + | ||
| 627 | +fill_buffer: | ||
| 628 | + memcpy(s->io_buffer, p, sizeof(s->identify_data)); | ||
| 629 | +} | ||
| 630 | + | ||
| 545 | static void ide_set_signature(IDEState *s) | 631 | static void ide_set_signature(IDEState *s) |
| 546 | { | 632 | { |
| 547 | s->select &= 0xf0; /* clear head */ | 633 | s->select &= 0xf0; /* clear head */ |
| @@ -1496,6 +1582,59 @@ static void ide_atapi_cmd(IDEState *s) | @@ -1496,6 +1582,59 @@ static void ide_atapi_cmd(IDEState *s) | ||
| 1496 | } | 1582 | } |
| 1497 | } | 1583 | } |
| 1498 | 1584 | ||
| 1585 | +static void ide_cfata_metadata_inquiry(IDEState *s) | ||
| 1586 | +{ | ||
| 1587 | + uint16_t *p; | ||
| 1588 | + uint32_t spd; | ||
| 1589 | + | ||
| 1590 | + p = (uint16_t *) s->io_buffer; | ||
| 1591 | + memset(p, 0, 0x200); | ||
| 1592 | + spd = ((s->mdata_size - 1) >> 9) + 1; | ||
| 1593 | + | ||
| 1594 | + put_le16(p + 0, 0x0001); /* Data format revision */ | ||
| 1595 | + put_le16(p + 1, 0x0000); /* Media property: silicon */ | ||
| 1596 | + put_le16(p + 2, s->media_changed); /* Media status */ | ||
| 1597 | + put_le16(p + 3, s->mdata_size & 0xffff); /* Capacity in bytes (low) */ | ||
| 1598 | + put_le16(p + 4, s->mdata_size >> 16); /* Capacity in bytes (high) */ | ||
| 1599 | + put_le16(p + 5, spd & 0xffff); /* Sectors per device (low) */ | ||
| 1600 | + put_le16(p + 6, spd >> 16); /* Sectors per device (high) */ | ||
| 1601 | +} | ||
| 1602 | + | ||
| 1603 | +static void ide_cfata_metadata_read(IDEState *s) | ||
| 1604 | +{ | ||
| 1605 | + uint16_t *p; | ||
| 1606 | + | ||
| 1607 | + if (((s->hcyl << 16) | s->lcyl) << 9 > s->mdata_size + 2) { | ||
| 1608 | + s->status = ERR_STAT; | ||
| 1609 | + s->error = ABRT_ERR; | ||
| 1610 | + return; | ||
| 1611 | + } | ||
| 1612 | + | ||
| 1613 | + p = (uint16_t *) s->io_buffer; | ||
| 1614 | + memset(p, 0, 0x200); | ||
| 1615 | + | ||
| 1616 | + put_le16(p + 0, s->media_changed); /* Media status */ | ||
| 1617 | + memcpy(p + 1, s->mdata_storage + (((s->hcyl << 16) | s->lcyl) << 9), | ||
| 1618 | + MIN(MIN(s->mdata_size - (((s->hcyl << 16) | s->lcyl) << 9), | ||
| 1619 | + s->nsector << 9), 0x200 - 2)); | ||
| 1620 | +} | ||
| 1621 | + | ||
| 1622 | +static void ide_cfata_metadata_write(IDEState *s) | ||
| 1623 | +{ | ||
| 1624 | + if (((s->hcyl << 16) | s->lcyl) << 9 > s->mdata_size + 2) { | ||
| 1625 | + s->status = ERR_STAT; | ||
| 1626 | + s->error = ABRT_ERR; | ||
| 1627 | + return; | ||
| 1628 | + } | ||
| 1629 | + | ||
| 1630 | + s->media_changed = 0; | ||
| 1631 | + | ||
| 1632 | + memcpy(s->mdata_storage + (((s->hcyl << 16) | s->lcyl) << 9), | ||
| 1633 | + s->io_buffer + 2, | ||
| 1634 | + MIN(MIN(s->mdata_size - (((s->hcyl << 16) | s->lcyl) << 9), | ||
| 1635 | + s->nsector << 9), 0x200 - 2)); | ||
| 1636 | +} | ||
| 1637 | + | ||
| 1499 | /* called when the inserted state of the media has changed */ | 1638 | /* called when the inserted state of the media has changed */ |
| 1500 | static void cdrom_change_cb(void *opaque) | 1639 | static void cdrom_change_cb(void *opaque) |
| 1501 | { | 1640 | { |
| @@ -1611,7 +1750,10 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) | @@ -1611,7 +1750,10 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) | ||
| 1611 | switch(val) { | 1750 | switch(val) { |
| 1612 | case WIN_IDENTIFY: | 1751 | case WIN_IDENTIFY: |
| 1613 | if (s->bs && !s->is_cdrom) { | 1752 | if (s->bs && !s->is_cdrom) { |
| 1614 | - ide_identify(s); | 1753 | + if (!s->is_cf) |
| 1754 | + ide_identify(s); | ||
| 1755 | + else | ||
| 1756 | + ide_cfata_identify(s); | ||
| 1615 | s->status = READY_STAT | SEEK_STAT; | 1757 | s->status = READY_STAT | SEEK_STAT; |
| 1616 | ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop); | 1758 | ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop); |
| 1617 | } else { | 1759 | } else { |
| @@ -1629,7 +1771,11 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) | @@ -1629,7 +1771,11 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) | ||
| 1629 | ide_set_irq(s); | 1771 | ide_set_irq(s); |
| 1630 | break; | 1772 | break; |
| 1631 | case WIN_SETMULT: | 1773 | case WIN_SETMULT: |
| 1632 | - if ((s->nsector & 0xff) != 0 && | 1774 | + if (s->is_cf && s->nsector == 0) { |
| 1775 | + /* Disable Read and Write Multiple */ | ||
| 1776 | + s->mult_sectors = 0; | ||
| 1777 | + s->status = READY_STAT; | ||
| 1778 | + } else if ((s->nsector & 0xff) != 0 && | ||
| 1633 | ((s->nsector & 0xff) > MAX_MULT_SECTORS || | 1779 | ((s->nsector & 0xff) > MAX_MULT_SECTORS || |
| 1634 | (s->nsector & (s->nsector - 1)) != 0)) { | 1780 | (s->nsector & (s->nsector - 1)) != 0)) { |
| 1635 | ide_abort_command(s); | 1781 | ide_abort_command(s); |
| @@ -1662,11 +1808,14 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) | @@ -1662,11 +1808,14 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) | ||
| 1662 | lba48 = 1; | 1808 | lba48 = 1; |
| 1663 | case WIN_WRITE: | 1809 | case WIN_WRITE: |
| 1664 | case WIN_WRITE_ONCE: | 1810 | case WIN_WRITE_ONCE: |
| 1811 | + case CFA_WRITE_SECT_WO_ERASE: | ||
| 1812 | + case WIN_WRITE_VERIFY: | ||
| 1665 | ide_cmd_lba48_transform(s, lba48); | 1813 | ide_cmd_lba48_transform(s, lba48); |
| 1666 | s->error = 0; | 1814 | s->error = 0; |
| 1667 | s->status = SEEK_STAT | READY_STAT; | 1815 | s->status = SEEK_STAT | READY_STAT; |
| 1668 | s->req_nb_sectors = 1; | 1816 | s->req_nb_sectors = 1; |
| 1669 | ide_transfer_start(s, s->io_buffer, 512, ide_sector_write); | 1817 | ide_transfer_start(s, s->io_buffer, 512, ide_sector_write); |
| 1818 | + s->media_changed = 1; | ||
| 1670 | break; | 1819 | break; |
| 1671 | case WIN_MULTREAD_EXT: | 1820 | case WIN_MULTREAD_EXT: |
| 1672 | lba48 = 1; | 1821 | lba48 = 1; |
| @@ -1680,6 +1829,7 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) | @@ -1680,6 +1829,7 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) | ||
| 1680 | case WIN_MULTWRITE_EXT: | 1829 | case WIN_MULTWRITE_EXT: |
| 1681 | lba48 = 1; | 1830 | lba48 = 1; |
| 1682 | case WIN_MULTWRITE: | 1831 | case WIN_MULTWRITE: |
| 1832 | + case CFA_WRITE_MULTI_WO_ERASE: | ||
| 1683 | if (!s->mult_sectors) | 1833 | if (!s->mult_sectors) |
| 1684 | goto abort_cmd; | 1834 | goto abort_cmd; |
| 1685 | ide_cmd_lba48_transform(s, lba48); | 1835 | ide_cmd_lba48_transform(s, lba48); |
| @@ -1690,6 +1840,7 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) | @@ -1690,6 +1840,7 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) | ||
| 1690 | if (n > s->req_nb_sectors) | 1840 | if (n > s->req_nb_sectors) |
| 1691 | n = s->req_nb_sectors; | 1841 | n = s->req_nb_sectors; |
| 1692 | ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write); | 1842 | ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write); |
| 1843 | + s->media_changed = 1; | ||
| 1693 | break; | 1844 | break; |
| 1694 | case WIN_READDMA_EXT: | 1845 | case WIN_READDMA_EXT: |
| 1695 | lba48 = 1; | 1846 | lba48 = 1; |
| @@ -1708,6 +1859,7 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) | @@ -1708,6 +1859,7 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) | ||
| 1708 | goto abort_cmd; | 1859 | goto abort_cmd; |
| 1709 | ide_cmd_lba48_transform(s, lba48); | 1860 | ide_cmd_lba48_transform(s, lba48); |
| 1710 | ide_sector_write_dma(s); | 1861 | ide_sector_write_dma(s); |
| 1862 | + s->media_changed = 1; | ||
| 1711 | break; | 1863 | break; |
| 1712 | case WIN_READ_NATIVE_MAX_EXT: | 1864 | case WIN_READ_NATIVE_MAX_EXT: |
| 1713 | lba48 = 1; | 1865 | lba48 = 1; |
| @@ -1718,6 +1870,7 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) | @@ -1718,6 +1870,7 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) | ||
| 1718 | ide_set_irq(s); | 1870 | ide_set_irq(s); |
| 1719 | break; | 1871 | break; |
| 1720 | case WIN_CHECKPOWERMODE1: | 1872 | case WIN_CHECKPOWERMODE1: |
| 1873 | + case WIN_CHECKPOWERMODE2: | ||
| 1721 | s->nsector = 0xff; /* device active or idle */ | 1874 | s->nsector = 0xff; /* device active or idle */ |
| 1722 | s->status = READY_STAT; | 1875 | s->status = READY_STAT; |
| 1723 | ide_set_irq(s); | 1876 | ide_set_irq(s); |
| @@ -1733,6 +1886,12 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) | @@ -1733,6 +1886,12 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) | ||
| 1733 | case 0x82: /* write cache disable */ | 1886 | case 0x82: /* write cache disable */ |
| 1734 | case 0xaa: /* read look-ahead enable */ | 1887 | case 0xaa: /* read look-ahead enable */ |
| 1735 | case 0x55: /* read look-ahead disable */ | 1888 | case 0x55: /* read look-ahead disable */ |
| 1889 | + case 0x05: /* set advanced power management mode */ | ||
| 1890 | + case 0x85: /* disable advanced power management mode */ | ||
| 1891 | + case 0x69: /* NOP */ | ||
| 1892 | + case 0x67: /* NOP */ | ||
| 1893 | + case 0x96: /* NOP */ | ||
| 1894 | + case 0x9a: /* NOP */ | ||
| 1736 | s->status = READY_STAT | SEEK_STAT; | 1895 | s->status = READY_STAT | SEEK_STAT; |
| 1737 | ide_set_irq(s); | 1896 | ide_set_irq(s); |
| 1738 | break; | 1897 | break; |
| @@ -1772,7 +1931,11 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) | @@ -1772,7 +1931,11 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) | ||
| 1772 | ide_set_irq(s); | 1931 | ide_set_irq(s); |
| 1773 | break; | 1932 | break; |
| 1774 | case WIN_STANDBYNOW1: | 1933 | case WIN_STANDBYNOW1: |
| 1934 | + case WIN_STANDBYNOW2: | ||
| 1775 | case WIN_IDLEIMMEDIATE: | 1935 | case WIN_IDLEIMMEDIATE: |
| 1936 | + case CFA_IDLEIMMEDIATE: | ||
| 1937 | + case WIN_SETIDLE1: | ||
| 1938 | + case WIN_SETIDLE2: | ||
| 1776 | s->status = READY_STAT; | 1939 | s->status = READY_STAT; |
| 1777 | ide_set_irq(s); | 1940 | ide_set_irq(s); |
| 1778 | break; | 1941 | break; |
| @@ -1810,6 +1973,79 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) | @@ -1810,6 +1973,79 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) | ||
| 1810 | ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE, | 1973 | ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE, |
| 1811 | ide_atapi_cmd); | 1974 | ide_atapi_cmd); |
| 1812 | break; | 1975 | break; |
| 1976 | + /* CF-ATA commands */ | ||
| 1977 | + case CFA_REQ_EXT_ERROR_CODE: | ||
| 1978 | + if (!s->is_cf) | ||
| 1979 | + goto abort_cmd; | ||
| 1980 | + s->error = 0x09; /* miscellaneous error */ | ||
| 1981 | + s->status = READY_STAT; | ||
| 1982 | + ide_set_irq(s); | ||
| 1983 | + break; | ||
| 1984 | + case CFA_ERASE_SECTORS: | ||
| 1985 | + case CFA_WEAR_LEVEL: | ||
| 1986 | + if (!s->is_cf) | ||
| 1987 | + goto abort_cmd; | ||
| 1988 | + if (val == CFA_WEAR_LEVEL) | ||
| 1989 | + s->nsector = 0; | ||
| 1990 | + if (val == CFA_ERASE_SECTORS) | ||
| 1991 | + s->media_changed = 1; | ||
| 1992 | + s->error = 0x00; | ||
| 1993 | + s->status = READY_STAT; | ||
| 1994 | + ide_set_irq(s); | ||
| 1995 | + break; | ||
| 1996 | + case CFA_TRANSLATE_SECTOR: | ||
| 1997 | + if (!s->is_cf) | ||
| 1998 | + goto abort_cmd; | ||
| 1999 | + s->error = 0x00; | ||
| 2000 | + s->status = READY_STAT; | ||
| 2001 | + memset(s->io_buffer, 0, 0x200); | ||
| 2002 | + s->io_buffer[0x00] = s->hcyl; /* Cyl MSB */ | ||
| 2003 | + s->io_buffer[0x01] = s->lcyl; /* Cyl LSB */ | ||
| 2004 | + s->io_buffer[0x02] = s->select; /* Head */ | ||
| 2005 | + s->io_buffer[0x03] = s->sector; /* Sector */ | ||
| 2006 | + s->io_buffer[0x04] = ide_get_sector(s) >> 16; /* LBA MSB */ | ||
| 2007 | + s->io_buffer[0x05] = ide_get_sector(s) >> 8; /* LBA */ | ||
| 2008 | + s->io_buffer[0x06] = ide_get_sector(s) >> 0; /* LBA LSB */ | ||
| 2009 | + s->io_buffer[0x13] = 0x00; /* Erase flag */ | ||
| 2010 | + s->io_buffer[0x18] = 0x00; /* Hot count */ | ||
| 2011 | + s->io_buffer[0x19] = 0x00; /* Hot count */ | ||
| 2012 | + s->io_buffer[0x1a] = 0x01; /* Hot count */ | ||
| 2013 | + ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop); | ||
| 2014 | + ide_set_irq(s); | ||
| 2015 | + break; | ||
| 2016 | + case CFA_ACCESS_METADATA_STORAGE: | ||
| 2017 | + if (!s->is_cf) | ||
| 2018 | + goto abort_cmd; | ||
| 2019 | + switch (s->feature) { | ||
| 2020 | + case 0x02: /* Inquiry Metadata Storage */ | ||
| 2021 | + ide_cfata_metadata_inquiry(s); | ||
| 2022 | + break; | ||
| 2023 | + case 0x03: /* Read Metadata Storage */ | ||
| 2024 | + ide_cfata_metadata_read(s); | ||
| 2025 | + break; | ||
| 2026 | + case 0x04: /* Write Metadata Storage */ | ||
| 2027 | + ide_cfata_metadata_write(s); | ||
| 2028 | + break; | ||
| 2029 | + default: | ||
| 2030 | + goto abort_cmd; | ||
| 2031 | + } | ||
| 2032 | + ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop); | ||
| 2033 | + s->status = 0x00; /* NOTE: READY is _not_ set */ | ||
| 2034 | + ide_set_irq(s); | ||
| 2035 | + break; | ||
| 2036 | + case IBM_SENSE_CONDITION: | ||
| 2037 | + if (!s->is_cf) | ||
| 2038 | + goto abort_cmd; | ||
| 2039 | + switch (s->feature) { | ||
| 2040 | + case 0x01: /* sense temperature in device */ | ||
| 2041 | + s->nsector = 0x50; /* +20 C */ | ||
| 2042 | + break; | ||
| 2043 | + default: | ||
| 2044 | + goto abort_cmd; | ||
| 2045 | + } | ||
| 2046 | + s->status = READY_STAT; | ||
| 2047 | + ide_set_irq(s); | ||
| 2048 | + break; | ||
| 1813 | default: | 2049 | default: |
| 1814 | abort_cmd: | 2050 | abort_cmd: |
| 1815 | ide_abort_command(s); | 2051 | ide_abort_command(s); |
| @@ -2015,7 +2251,10 @@ static void ide_dummy_transfer_stop(IDEState *s) | @@ -2015,7 +2251,10 @@ static void ide_dummy_transfer_stop(IDEState *s) | ||
| 2015 | 2251 | ||
| 2016 | static void ide_reset(IDEState *s) | 2252 | static void ide_reset(IDEState *s) |
| 2017 | { | 2253 | { |
| 2018 | - s->mult_sectors = MAX_MULT_SECTORS; | 2254 | + if (s->is_cf) |
| 2255 | + s->mult_sectors = 0; | ||
| 2256 | + else | ||
| 2257 | + s->mult_sectors = MAX_MULT_SECTORS; | ||
| 2019 | s->cur_drive = s; | 2258 | s->cur_drive = s; |
| 2020 | s->select = 0xa0; | 2259 | s->select = 0xa0; |
| 2021 | s->status = READY_STAT; | 2260 | s->status = READY_STAT; |
| @@ -2024,6 +2263,7 @@ static void ide_reset(IDEState *s) | @@ -2024,6 +2263,7 @@ static void ide_reset(IDEState *s) | ||
| 2024 | accesses */ | 2263 | accesses */ |
| 2025 | s->end_transfer_func = ide_dummy_transfer_stop; | 2264 | s->end_transfer_func = ide_dummy_transfer_stop; |
| 2026 | ide_dummy_transfer_stop(s); | 2265 | ide_dummy_transfer_stop(s); |
| 2266 | + s->media_changed = 0; | ||
| 2027 | } | 2267 | } |
| 2028 | 2268 | ||
| 2029 | struct partition { | 2269 | struct partition { |
| @@ -2749,3 +2989,496 @@ int pmac_ide_init (BlockDriverState **hd_table, qemu_irq irq) | @@ -2749,3 +2989,496 @@ int pmac_ide_init (BlockDriverState **hd_table, qemu_irq irq) | ||
| 2749 | pmac_ide_write, &ide_if[0]); | 2989 | pmac_ide_write, &ide_if[0]); |
| 2750 | return pmac_ide_memory; | 2990 | return pmac_ide_memory; |
| 2751 | } | 2991 | } |
| 2992 | + | ||
| 2993 | +/***********************************************************/ | ||
| 2994 | +/* CF-ATA Microdrive */ | ||
| 2995 | + | ||
| 2996 | +#define METADATA_SIZE 0x20 | ||
| 2997 | + | ||
| 2998 | +/* DSCM-1XXXX Microdrive hard disk with CF+ II / PCMCIA interface. */ | ||
| 2999 | +struct md_s { | ||
| 3000 | + IDEState ide[2]; | ||
| 3001 | + struct pcmcia_card_s card; | ||
| 3002 | + uint32_t attr_base; | ||
| 3003 | + uint32_t io_base; | ||
| 3004 | + | ||
| 3005 | + /* Card state */ | ||
| 3006 | + uint8_t opt; | ||
| 3007 | + uint8_t stat; | ||
| 3008 | + uint8_t pins; | ||
| 3009 | + | ||
| 3010 | + uint8_t ctrl; | ||
| 3011 | + uint16_t io; | ||
| 3012 | + int cycle; | ||
| 3013 | +}; | ||
| 3014 | + | ||
| 3015 | +/* Register bitfields */ | ||
| 3016 | +enum md_opt { | ||
| 3017 | + OPT_MODE_MMAP = 0, | ||
| 3018 | + OPT_MODE_IOMAP16 = 1, | ||
| 3019 | + OPT_MODE_IOMAP1 = 2, | ||
| 3020 | + OPT_MODE_IOMAP2 = 3, | ||
| 3021 | + OPT_MODE = 0x3f, | ||
| 3022 | + OPT_LEVIREQ = 0x40, | ||
| 3023 | + OPT_SRESET = 0x80, | ||
| 3024 | +}; | ||
| 3025 | +enum md_cstat { | ||
| 3026 | + STAT_INT = 0x02, | ||
| 3027 | + STAT_PWRDWN = 0x04, | ||
| 3028 | + STAT_XE = 0x10, | ||
| 3029 | + STAT_IOIS8 = 0x20, | ||
| 3030 | + STAT_SIGCHG = 0x40, | ||
| 3031 | + STAT_CHANGED = 0x80, | ||
| 3032 | +}; | ||
| 3033 | +enum md_pins { | ||
| 3034 | + PINS_MRDY = 0x02, | ||
| 3035 | + PINS_CRDY = 0x20, | ||
| 3036 | +}; | ||
| 3037 | +enum md_ctrl { | ||
| 3038 | + CTRL_IEN = 0x02, | ||
| 3039 | + CTRL_SRST = 0x04, | ||
| 3040 | +}; | ||
| 3041 | + | ||
| 3042 | +static inline void md_interrupt_update(struct md_s *s) | ||
| 3043 | +{ | ||
| 3044 | + if (!s->card.slot) | ||
| 3045 | + return; | ||
| 3046 | + | ||
| 3047 | + qemu_set_irq(s->card.slot->irq, | ||
| 3048 | + !(s->stat & STAT_INT) && /* Inverted */ | ||
| 3049 | + !(s->ctrl & (CTRL_IEN | CTRL_SRST)) && | ||
| 3050 | + !(s->opt & OPT_SRESET)); | ||
| 3051 | +} | ||
| 3052 | + | ||
| 3053 | +static void md_set_irq(void *opaque, int irq, int level) | ||
| 3054 | +{ | ||
| 3055 | + struct md_s *s = (struct md_s *) opaque; | ||
| 3056 | + if (level) | ||
| 3057 | + s->stat |= STAT_INT; | ||
| 3058 | + else | ||
| 3059 | + s->stat &= ~STAT_INT; | ||
| 3060 | + | ||
| 3061 | + md_interrupt_update(s); | ||
| 3062 | +} | ||
| 3063 | + | ||
| 3064 | +static void md_reset(struct md_s *s) | ||
| 3065 | +{ | ||
| 3066 | + s->opt = OPT_MODE_MMAP; | ||
| 3067 | + s->stat = 0; | ||
| 3068 | + s->pins = 0; | ||
| 3069 | + s->cycle = 0; | ||
| 3070 | + s->ctrl = 0; | ||
| 3071 | + ide_reset(s->ide); | ||
| 3072 | +} | ||
| 3073 | + | ||
| 3074 | +static uint8_t md_attr_read(void *opaque, uint16_t at) | ||
| 3075 | +{ | ||
| 3076 | + struct md_s *s = (struct md_s *) opaque; | ||
| 3077 | + if (at < s->attr_base) { | ||
| 3078 | + if (at < s->card.cis_len) | ||
| 3079 | + return s->card.cis[at]; | ||
| 3080 | + else | ||
| 3081 | + return 0x00; | ||
| 3082 | + } | ||
| 3083 | + | ||
| 3084 | + at -= s->attr_base; | ||
| 3085 | + | ||
| 3086 | + switch (at) { | ||
| 3087 | + case 0x00: /* Configuration Option Register */ | ||
| 3088 | + return s->opt; | ||
| 3089 | + case 0x02: /* Card Configuration Status Register */ | ||
| 3090 | + if (s->ctrl & CTRL_IEN) | ||
| 3091 | + return s->stat & ~STAT_INT; | ||
| 3092 | + else | ||
| 3093 | + return s->stat; | ||
| 3094 | + case 0x04: /* Pin Replacement Register */ | ||
| 3095 | + return (s->pins & PINS_CRDY) | 0x0c; | ||
| 3096 | + case 0x06: /* Socket and Copy Register */ | ||
| 3097 | + return 0x00; | ||
| 3098 | +#ifdef VERBOSE | ||
| 3099 | + default: | ||
| 3100 | + printf("%s: Bad attribute space register %02x\n", __FUNCTION__, at); | ||
| 3101 | +#endif | ||
| 3102 | + } | ||
| 3103 | + | ||
| 3104 | + return 0; | ||
| 3105 | +} | ||
| 3106 | + | ||
| 3107 | +static void md_attr_write(void *opaque, uint16_t at, uint8_t value) | ||
| 3108 | +{ | ||
| 3109 | + struct md_s *s = (struct md_s *) opaque; | ||
| 3110 | + at -= s->attr_base; | ||
| 3111 | + | ||
| 3112 | + switch (at) { | ||
| 3113 | + case 0x00: /* Configuration Option Register */ | ||
| 3114 | + s->opt = value & 0xcf; | ||
| 3115 | + if (value & OPT_SRESET) | ||
| 3116 | + md_reset(s); | ||
| 3117 | + md_interrupt_update(s); | ||
| 3118 | + break; | ||
| 3119 | + case 0x02: /* Card Configuration Status Register */ | ||
| 3120 | + if ((s->stat ^ value) & STAT_PWRDWN) | ||
| 3121 | + s->pins |= PINS_CRDY; | ||
| 3122 | + s->stat &= 0x82; | ||
| 3123 | + s->stat |= value & 0x74; | ||
| 3124 | + md_interrupt_update(s); | ||
| 3125 | + /* Word 170 in Identify Device must be equal to STAT_XE */ | ||
| 3126 | + break; | ||
| 3127 | + case 0x04: /* Pin Replacement Register */ | ||
| 3128 | + s->pins &= PINS_CRDY; | ||
| 3129 | + s->pins |= value & PINS_MRDY; | ||
| 3130 | + break; | ||
| 3131 | + case 0x06: /* Socket and Copy Register */ | ||
| 3132 | + break; | ||
| 3133 | + default: | ||
| 3134 | + printf("%s: Bad attribute space register %02x\n", __FUNCTION__, at); | ||
| 3135 | + } | ||
| 3136 | +} | ||
| 3137 | + | ||
| 3138 | +static uint16_t md_common_read(void *opaque, uint16_t at) | ||
| 3139 | +{ | ||
| 3140 | + struct md_s *s = (struct md_s *) opaque; | ||
| 3141 | + uint16_t ret; | ||
| 3142 | + at -= s->io_base; | ||
| 3143 | + | ||
| 3144 | + switch (s->opt & OPT_MODE) { | ||
| 3145 | + case OPT_MODE_MMAP: | ||
| 3146 | + if ((at & ~0x3ff) == 0x400) | ||
| 3147 | + at = 0; | ||
| 3148 | + break; | ||
| 3149 | + case OPT_MODE_IOMAP16: | ||
| 3150 | + at &= 0xf; | ||
| 3151 | + break; | ||
| 3152 | + case OPT_MODE_IOMAP1: | ||
| 3153 | + if ((at & ~0xf) == 0x3f0) | ||
| 3154 | + at -= 0x3e8; | ||
| 3155 | + else if ((at & ~0xf) == 0x1f0) | ||
| 3156 | + at -= 0x1f0; | ||
| 3157 | + break; | ||
| 3158 | + case OPT_MODE_IOMAP2: | ||
| 3159 | + if ((at & ~0xf) == 0x370) | ||
| 3160 | + at -= 0x368; | ||
| 3161 | + else if ((at & ~0xf) == 0x170) | ||
| 3162 | + at -= 0x170; | ||
| 3163 | + } | ||
| 3164 | + | ||
| 3165 | + switch (at) { | ||
| 3166 | + case 0x0: /* Even RD Data */ | ||
| 3167 | + case 0x8: | ||
| 3168 | + return ide_data_readw(s->ide, 0); | ||
| 3169 | + | ||
| 3170 | + /* TODO: 8-bit accesses */ | ||
| 3171 | + if (s->cycle) | ||
| 3172 | + ret = s->io >> 8; | ||
| 3173 | + else { | ||
| 3174 | + s->io = ide_data_readw(s->ide, 0); | ||
| 3175 | + ret = s->io & 0xff; | ||
| 3176 | + } | ||
| 3177 | + s->cycle = !s->cycle; | ||
| 3178 | + return ret; | ||
| 3179 | + case 0x9: /* Odd RD Data */ | ||
| 3180 | + return s->io >> 8; | ||
| 3181 | + case 0xd: /* Error */ | ||
| 3182 | + return ide_ioport_read(s->ide, 0x1); | ||
| 3183 | + case 0xe: /* Alternate Status */ | ||
| 3184 | + if (s->ide->cur_drive->bs) | ||
| 3185 | + return s->ide->cur_drive->status; | ||
| 3186 | + else | ||
| 3187 | + return 0; | ||
| 3188 | + case 0xf: /* Device Address */ | ||
| 3189 | + return 0xc2 | ((~s->ide->select << 2) & 0x3c); | ||
| 3190 | + default: | ||
| 3191 | + return ide_ioport_read(s->ide, at); | ||
| 3192 | + } | ||
| 3193 | + | ||
| 3194 | + return 0; | ||
| 3195 | +} | ||
| 3196 | + | ||
| 3197 | +static void md_common_write(void *opaque, uint16_t at, uint16_t value) | ||
| 3198 | +{ | ||
| 3199 | + struct md_s *s = (struct md_s *) opaque; | ||
| 3200 | + at -= s->io_base; | ||
| 3201 | + | ||
| 3202 | + switch (s->opt & OPT_MODE) { | ||
| 3203 | + case OPT_MODE_MMAP: | ||
| 3204 | + if ((at & ~0x3ff) == 0x400) | ||
| 3205 | + at = 0; | ||
| 3206 | + break; | ||
| 3207 | + case OPT_MODE_IOMAP16: | ||
| 3208 | + at &= 0xf; | ||
| 3209 | + break; | ||
| 3210 | + case OPT_MODE_IOMAP1: | ||
| 3211 | + if ((at & ~0xf) == 0x3f0) | ||
| 3212 | + at -= 0x3e8; | ||
| 3213 | + else if ((at & ~0xf) == 0x1f0) | ||
| 3214 | + at -= 0x1f0; | ||
| 3215 | + break; | ||
| 3216 | + case OPT_MODE_IOMAP2: | ||
| 3217 | + if ((at & ~0xf) == 0x370) | ||
| 3218 | + at -= 0x368; | ||
| 3219 | + else if ((at & ~0xf) == 0x170) | ||
| 3220 | + at -= 0x170; | ||
| 3221 | + } | ||
| 3222 | + | ||
| 3223 | + switch (at) { | ||
| 3224 | + case 0x0: /* Even WR Data */ | ||
| 3225 | + case 0x8: | ||
| 3226 | + ide_data_writew(s->ide, 0, value); | ||
| 3227 | + break; | ||
| 3228 | + | ||
| 3229 | + /* TODO: 8-bit accesses */ | ||
| 3230 | + if (s->cycle) | ||
| 3231 | + ide_data_writew(s->ide, 0, s->io | (value << 8)); | ||
| 3232 | + else | ||
| 3233 | + s->io = value & 0xff; | ||
| 3234 | + s->cycle = !s->cycle; | ||
| 3235 | + break; | ||
| 3236 | + case 0x9: | ||
| 3237 | + s->io = value & 0xff; | ||
| 3238 | + s->cycle = !s->cycle; | ||
| 3239 | + break; | ||
| 3240 | + case 0xd: /* Features */ | ||
| 3241 | + ide_ioport_write(s->ide, 0x1, value); | ||
| 3242 | + break; | ||
| 3243 | + case 0xe: /* Device Control */ | ||
| 3244 | + s->ctrl = value; | ||
| 3245 | + if (value & CTRL_SRST) | ||
| 3246 | + md_reset(s); | ||
| 3247 | + md_interrupt_update(s); | ||
| 3248 | + break; | ||
| 3249 | + default: | ||
| 3250 | + if (s->stat & STAT_PWRDWN) { | ||
| 3251 | + s->pins |= PINS_CRDY; | ||
| 3252 | + s->stat &= ~STAT_PWRDWN; | ||
| 3253 | + } | ||
| 3254 | + ide_ioport_write(s->ide, at, value); | ||
| 3255 | + } | ||
| 3256 | +} | ||
| 3257 | + | ||
| 3258 | +static const uint8_t dscm1xxxx_cis[0x14a] = { | ||
| 3259 | + [0x000] = CISTPL_DEVICE, /* 5V Device Information */ | ||
| 3260 | + [0x002] = 0x03, /* Tuple length = 4 bytes */ | ||
| 3261 | + [0x004] = 0xdb, /* ID: DTYPE_FUNCSPEC, non WP, DSPEED_150NS */ | ||
| 3262 | + [0x006] = 0x01, /* Size = 2K bytes */ | ||
| 3263 | + [0x008] = CISTPL_ENDMARK, | ||
| 3264 | + | ||
| 3265 | + [0x00a] = CISTPL_DEVICE_OC, /* Additional Device Information */ | ||
| 3266 | + [0x00c] = 0x04, /* Tuple length = 4 byest */ | ||
| 3267 | + [0x00e] = 0x03, /* Conditions: Ext = 0, Vcc 3.3V, MWAIT = 1 */ | ||
| 3268 | + [0x010] = 0xdb, /* ID: DTYPE_FUNCSPEC, non WP, DSPEED_150NS */ | ||
| 3269 | + [0x012] = 0x01, /* Size = 2K bytes */ | ||
| 3270 | + [0x014] = CISTPL_ENDMARK, | ||
| 3271 | + | ||
| 3272 | + [0x016] = CISTPL_JEDEC_C, /* JEDEC ID */ | ||
| 3273 | + [0x018] = 0x02, /* Tuple length = 2 bytes */ | ||
| 3274 | + [0x01a] = 0xdf, /* PC Card ATA with no Vpp required */ | ||
| 3275 | + [0x01c] = 0x01, | ||
| 3276 | + | ||
| 3277 | + [0x01e] = CISTPL_MANFID, /* Manufacture ID */ | ||
| 3278 | + [0x020] = 0x04, /* Tuple length = 4 bytes */ | ||
| 3279 | + [0x022] = 0xa4, /* TPLMID_MANF = 00a4 (IBM) */ | ||
| 3280 | + [0x024] = 0x00, | ||
| 3281 | + [0x026] = 0x00, /* PLMID_CARD = 0000 */ | ||
| 3282 | + [0x028] = 0x00, | ||
| 3283 | + | ||
| 3284 | + [0x02a] = CISTPL_VERS_1, /* Level 1 Version */ | ||
| 3285 | + [0x02c] = 0x12, /* Tuple length = 23 bytes */ | ||
| 3286 | + [0x02e] = 0x04, /* Major Version = JEIDA 4.2 / PCMCIA 2.1 */ | ||
| 3287 | + [0x030] = 0x01, /* Minor Version = 1 */ | ||
| 3288 | + [0x032] = 'I', | ||
| 3289 | + [0x034] = 'B', | ||
| 3290 | + [0x036] = 'M', | ||
| 3291 | + [0x038] = 0x00, | ||
| 3292 | + [0x03a] = 'm', | ||
| 3293 | + [0x03c] = 'i', | ||
| 3294 | + [0x03e] = 'c', | ||
| 3295 | + [0x040] = 'r', | ||
| 3296 | + [0x042] = 'o', | ||
| 3297 | + [0x044] = 'd', | ||
| 3298 | + [0x046] = 'r', | ||
| 3299 | + [0x048] = 'i', | ||
| 3300 | + [0x04a] = 'v', | ||
| 3301 | + [0x04c] = 'e', | ||
| 3302 | + [0x04e] = 0x00, | ||
| 3303 | + [0x050] = CISTPL_ENDMARK, | ||
| 3304 | + | ||
| 3305 | + [0x052] = CISTPL_FUNCID, /* Function ID */ | ||
| 3306 | + [0x054] = 0x02, /* Tuple length = 2 bytes */ | ||
| 3307 | + [0x056] = 0x04, /* TPLFID_FUNCTION = Fixed Disk */ | ||
| 3308 | + [0x058] = 0x01, /* TPLFID_SYSINIT: POST = 1, ROM = 0 */ | ||
| 3309 | + | ||
| 3310 | + [0x05a] = CISTPL_FUNCE, /* Function Extension */ | ||
| 3311 | + [0x05c] = 0x02, /* Tuple length = 2 bytes */ | ||
| 3312 | + [0x05e] = 0x01, /* TPLFE_TYPE = Disk Device Interface */ | ||
| 3313 | + [0x060] = 0x01, /* TPLFE_DATA = PC Card ATA Interface */ | ||
| 3314 | + | ||
| 3315 | + [0x062] = CISTPL_FUNCE, /* Function Extension */ | ||
| 3316 | + [0x064] = 0x03, /* Tuple length = 3 bytes */ | ||
| 3317 | + [0x066] = 0x02, /* TPLFE_TYPE = Basic PC Card ATA Interface */ | ||
| 3318 | + [0x068] = 0x08, /* TPLFE_DATA: Rotating, Unique, Single */ | ||
| 3319 | + [0x06a] = 0x0f, /* TPLFE_DATA: Sleep, Standby, Idle, Auto */ | ||
| 3320 | + | ||
| 3321 | + [0x06c] = CISTPL_CONFIG, /* Configuration */ | ||
| 3322 | + [0x06e] = 0x05, /* Tuple length = 5 bytes */ | ||
| 3323 | + [0x070] = 0x01, /* TPCC_RASZ = 2 bytes, TPCC_RMSZ = 1 byte */ | ||
| 3324 | + [0x072] = 0x07, /* TPCC_LAST = 7 */ | ||
| 3325 | + [0x074] = 0x00, /* TPCC_RADR = 0200 */ | ||
| 3326 | + [0x076] = 0x02, | ||
| 3327 | + [0x078] = 0x0f, /* TPCC_RMSK = 200, 202, 204, 206 */ | ||
| 3328 | + | ||
| 3329 | + [0x07a] = CISTPL_CFTABLE_ENTRY, /* 16-bit PC Card Configuration */ | ||
| 3330 | + [0x07c] = 0x0b, /* Tuple length = 11 bytes */ | ||
| 3331 | + [0x07e] = 0xc0, /* TPCE_INDX = Memory Mode, Default, Iface */ | ||
| 3332 | + [0x080] = 0xc0, /* TPCE_IF = Memory, no BVDs, no WP, READY */ | ||
| 3333 | + [0x082] = 0xa1, /* TPCE_FS = Vcc only, no I/O, Memory, Misc */ | ||
| 3334 | + [0x084] = 0x27, /* NomV = 1, MinV = 1, MaxV = 1, Peakl = 1 */ | ||
| 3335 | + [0x086] = 0x55, /* NomV: 5.0 V */ | ||
| 3336 | + [0x088] = 0x4d, /* MinV: 4.5 V */ | ||
| 3337 | + [0x08a] = 0x5d, /* MaxV: 5.5 V */ | ||
| 3338 | + [0x08c] = 0x4e, /* Peakl: 450 mA */ | ||
| 3339 | + [0x08e] = 0x08, /* TPCE_MS = 1 window, 1 byte, Host address */ | ||
| 3340 | + [0x090] = 0x00, /* Window descriptor: Window length = 0 */ | ||
| 3341 | + [0x092] = 0x20, /* TPCE_MI: support power down mode, RW */ | ||
| 3342 | + | ||
| 3343 | + [0x094] = CISTPL_CFTABLE_ENTRY, /* 16-bit PC Card Configuration */ | ||
| 3344 | + [0x096] = 0x06, /* Tuple length = 6 bytes */ | ||
| 3345 | + [0x098] = 0x00, /* TPCE_INDX = Memory Mode, no Default */ | ||
| 3346 | + [0x09a] = 0x01, /* TPCE_FS = Vcc only, no I/O, no Memory */ | ||
| 3347 | + [0x09c] = 0x21, /* NomV = 1, MinV = 0, MaxV = 0, Peakl = 1 */ | ||
| 3348 | + [0x09e] = 0xb5, /* NomV: 3.3 V */ | ||
| 3349 | + [0x0a0] = 0x1e, | ||
| 3350 | + [0x0a2] = 0x3e, /* Peakl: 350 mA */ | ||
| 3351 | + | ||
| 3352 | + [0x0a4] = CISTPL_CFTABLE_ENTRY, /* 16-bit PC Card Configuration */ | ||
| 3353 | + [0x0a6] = 0x0d, /* Tuple length = 13 bytes */ | ||
| 3354 | + [0x0a8] = 0xc1, /* TPCE_INDX = I/O and Memory Mode, Default */ | ||
| 3355 | + [0x0aa] = 0x41, /* TPCE_IF = I/O and Memory, no BVD, no WP */ | ||
| 3356 | + [0x0ac] = 0x99, /* TPCE_FS = Vcc only, I/O, Interrupt, Misc */ | ||
| 3357 | + [0x0ae] = 0x27, /* NomV = 1, MinV = 1, MaxV = 1, Peakl = 1 */ | ||
| 3358 | + [0x0b0] = 0x55, /* NomV: 5.0 V */ | ||
| 3359 | + [0x0b2] = 0x4d, /* MinV: 4.5 V */ | ||
| 3360 | + [0x0b4] = 0x5d, /* MaxV: 5.5 V */ | ||
| 3361 | + [0x0b6] = 0x4e, /* Peakl: 450 mA */ | ||
| 3362 | + [0x0b8] = 0x64, /* TPCE_IO = 16-byte boundary, 16/8 accesses */ | ||
| 3363 | + [0x0ba] = 0xf0, /* TPCE_IR = MASK, Level, Pulse, Share */ | ||
| 3364 | + [0x0bc] = 0xff, /* IRQ0..IRQ7 supported */ | ||
| 3365 | + [0x0be] = 0xff, /* IRQ8..IRQ15 supported */ | ||
| 3366 | + [0x0c0] = 0x20, /* TPCE_MI = support power down mode */ | ||
| 3367 | + | ||
| 3368 | + [0x0c2] = CISTPL_CFTABLE_ENTRY, /* 16-bit PC Card Configuration */ | ||
| 3369 | + [0x0c4] = 0x06, /* Tuple length = 6 bytes */ | ||
| 3370 | + [0x0c6] = 0x01, /* TPCE_INDX = I/O and Memory Mode */ | ||
| 3371 | + [0x0c8] = 0x01, /* TPCE_FS = Vcc only, no I/O, no Memory */ | ||
| 3372 | + [0x0ca] = 0x21, /* NomV = 1, MinV = 0, MaxV = 0, Peakl = 1 */ | ||
| 3373 | + [0x0cc] = 0xb5, /* NomV: 3.3 V */ | ||
| 3374 | + [0x0ce] = 0x1e, | ||
| 3375 | + [0x0d0] = 0x3e, /* Peakl: 350 mA */ | ||
| 3376 | + | ||
| 3377 | + [0x0d2] = CISTPL_CFTABLE_ENTRY, /* 16-bit PC Card Configuration */ | ||
| 3378 | + [0x0d4] = 0x12, /* Tuple length = 18 bytes */ | ||
| 3379 | + [0x0d6] = 0xc2, /* TPCE_INDX = I/O Primary Mode */ | ||
| 3380 | + [0x0d8] = 0x41, /* TPCE_IF = I/O and Memory, no BVD, no WP */ | ||
| 3381 | + [0x0da] = 0x99, /* TPCE_FS = Vcc only, I/O, Interrupt, Misc */ | ||
| 3382 | + [0x0dc] = 0x27, /* NomV = 1, MinV = 1, MaxV = 1, Peakl = 1 */ | ||
| 3383 | + [0x0de] = 0x55, /* NomV: 5.0 V */ | ||
| 3384 | + [0x0e0] = 0x4d, /* MinV: 4.5 V */ | ||
| 3385 | + [0x0e2] = 0x5d, /* MaxV: 5.5 V */ | ||
| 3386 | + [0x0e4] = 0x4e, /* Peakl: 450 mA */ | ||
| 3387 | + [0x0e6] = 0xea, /* TPCE_IO = 1K boundary, 16/8 access, Range */ | ||
| 3388 | + [0x0e8] = 0x61, /* Range: 2 fields, 2 bytes addr, 1 byte len */ | ||
| 3389 | + [0x0ea] = 0xf0, /* Field 1 address = 0x01f0 */ | ||
| 3390 | + [0x0ec] = 0x01, | ||
| 3391 | + [0x0ee] = 0x07, /* Address block length = 8 */ | ||
| 3392 | + [0x0f0] = 0xf6, /* Field 2 address = 0x03f6 */ | ||
| 3393 | + [0x0f2] = 0x03, | ||
| 3394 | + [0x0f4] = 0x01, /* Address block length = 2 */ | ||
| 3395 | + [0x0f6] = 0xee, /* TPCE_IR = IRQ E, Level, Pulse, Share */ | ||
| 3396 | + [0x0f8] = 0x20, /* TPCE_MI = support power down mode */ | ||
| 3397 | + | ||
| 3398 | + [0x0fa] = CISTPL_CFTABLE_ENTRY, /* 16-bit PC Card Configuration */ | ||
| 3399 | + [0x0fc] = 0x06, /* Tuple length = 6 bytes */ | ||
| 3400 | + [0x0fe] = 0x02, /* TPCE_INDX = I/O Primary Mode, no Default */ | ||
| 3401 | + [0x100] = 0x01, /* TPCE_FS = Vcc only, no I/O, no Memory */ | ||
| 3402 | + [0x102] = 0x21, /* NomV = 1, MinV = 0, MaxV = 0, Peakl = 1 */ | ||
| 3403 | + [0x104] = 0xb5, /* NomV: 3.3 V */ | ||
| 3404 | + [0x106] = 0x1e, | ||
| 3405 | + [0x108] = 0x3e, /* Peakl: 350 mA */ | ||
| 3406 | + | ||
| 3407 | + [0x10a] = CISTPL_CFTABLE_ENTRY, /* 16-bit PC Card Configuration */ | ||
| 3408 | + [0x10c] = 0x12, /* Tuple length = 18 bytes */ | ||
| 3409 | + [0x10e] = 0xc3, /* TPCE_INDX = I/O Secondary Mode, Default */ | ||
| 3410 | + [0x110] = 0x41, /* TPCE_IF = I/O and Memory, no BVD, no WP */ | ||
| 3411 | + [0x112] = 0x99, /* TPCE_FS = Vcc only, I/O, Interrupt, Misc */ | ||
| 3412 | + [0x114] = 0x27, /* NomV = 1, MinV = 1, MaxV = 1, Peakl = 1 */ | ||
| 3413 | + [0x116] = 0x55, /* NomV: 5.0 V */ | ||
| 3414 | + [0x118] = 0x4d, /* MinV: 4.5 V */ | ||
| 3415 | + [0x11a] = 0x5d, /* MaxV: 5.5 V */ | ||
| 3416 | + [0x11c] = 0x4e, /* Peakl: 450 mA */ | ||
| 3417 | + [0x11e] = 0xea, /* TPCE_IO = 1K boundary, 16/8 access, Range */ | ||
| 3418 | + [0x120] = 0x61, /* Range: 2 fields, 2 byte addr, 1 byte len */ | ||
| 3419 | + [0x122] = 0x70, /* Field 1 address = 0x0170 */ | ||
| 3420 | + [0x124] = 0x01, | ||
| 3421 | + [0x126] = 0x07, /* Address block length = 8 */ | ||
| 3422 | + [0x128] = 0x76, /* Field 2 address = 0x0376 */ | ||
| 3423 | + [0x12a] = 0x03, | ||
| 3424 | + [0x12c] = 0x01, /* Address block length = 2 */ | ||
| 3425 | + [0x12e] = 0xee, /* TPCE_IR = IRQ E, Level, Pulse, Share */ | ||
| 3426 | + [0x130] = 0x20, /* TPCE_MI = support power down mode */ | ||
| 3427 | + | ||
| 3428 | + [0x132] = CISTPL_CFTABLE_ENTRY, /* 16-bit PC Card Configuration */ | ||
| 3429 | + [0x134] = 0x06, /* Tuple length = 6 bytes */ | ||
| 3430 | + [0x136] = 0x03, /* TPCE_INDX = I/O Secondary Mode */ | ||
| 3431 | + [0x138] = 0x01, /* TPCE_FS = Vcc only, no I/O, no Memory */ | ||
| 3432 | + [0x13a] = 0x21, /* NomV = 1, MinV = 0, MaxV = 0, Peakl = 1 */ | ||
| 3433 | + [0x13c] = 0xb5, /* NomV: 3.3 V */ | ||
| 3434 | + [0x13e] = 0x1e, | ||
| 3435 | + [0x140] = 0x3e, /* Peakl: 350 mA */ | ||
| 3436 | + | ||
| 3437 | + [0x142] = CISTPL_NO_LINK, /* No Link */ | ||
| 3438 | + [0x144] = 0x00, /* Tuple length = 0 bytes */ | ||
| 3439 | + | ||
| 3440 | + [0x146] = CISTPL_END, /* Tuple End */ | ||
| 3441 | +}; | ||
| 3442 | + | ||
| 3443 | +static int dscm1xxxx_attach(void *opaque) | ||
| 3444 | +{ | ||
| 3445 | + struct md_s *md = (struct md_s *) opaque; | ||
| 3446 | + md->card.attr_read = md_attr_read; | ||
| 3447 | + md->card.attr_write = md_attr_write; | ||
| 3448 | + md->card.common_read = md_common_read; | ||
| 3449 | + md->card.common_write = md_common_write; | ||
| 3450 | + md->card.io_read = md_common_read; | ||
| 3451 | + md->card.io_write = md_common_write; | ||
| 3452 | + | ||
| 3453 | + md->attr_base = md->card.cis[0x74] | (md->card.cis[0x76] << 8); | ||
| 3454 | + md->io_base = 0x0; | ||
| 3455 | + | ||
| 3456 | + md_reset(md); | ||
| 3457 | + md_interrupt_update(md); | ||
| 3458 | + | ||
| 3459 | + md->card.slot->card_string = "DSCM-1xxxx Hitachi Microdrive"; | ||
| 3460 | + return 0; | ||
| 3461 | +} | ||
| 3462 | + | ||
| 3463 | +static int dscm1xxxx_detach(void *opaque) | ||
| 3464 | +{ | ||
| 3465 | + struct md_s *md = (struct md_s *) opaque; | ||
| 3466 | + md_reset(md); | ||
| 3467 | + return 0; | ||
| 3468 | +} | ||
| 3469 | + | ||
| 3470 | +struct pcmcia_card_s *dscm1xxxx_init(BlockDriverState *bdrv) | ||
| 3471 | +{ | ||
| 3472 | + struct md_s *md = (struct md_s *) qemu_mallocz(sizeof(struct md_s)); | ||
| 3473 | + md->card.state = md; | ||
| 3474 | + md->card.attach = dscm1xxxx_attach; | ||
| 3475 | + md->card.detach = dscm1xxxx_detach; | ||
| 3476 | + md->card.cis = dscm1xxxx_cis; | ||
| 3477 | + md->card.cis_len = sizeof(dscm1xxxx_cis); | ||
| 3478 | + | ||
| 3479 | + ide_init2(md->ide, bdrv, 0, qemu_allocate_irqs(md_set_irq, md, 1)[0]); | ||
| 3480 | + md->ide->is_cf = 1; | ||
| 3481 | + md->ide->mdata_size = METADATA_SIZE; | ||
| 3482 | + md->ide->mdata_storage = (uint8_t *) qemu_mallocz(METADATA_SIZE); | ||
| 3483 | + return &md->card; | ||
| 3484 | +} |
monitor.c
| @@ -1316,6 +1316,8 @@ static term_cmd_t info_cmds[] = { | @@ -1316,6 +1316,8 @@ static term_cmd_t info_cmds[] = { | ||
| 1316 | "", "show capture information" }, | 1316 | "", "show capture information" }, |
| 1317 | { "snapshots", "", do_info_snapshots, | 1317 | { "snapshots", "", do_info_snapshots, |
| 1318 | "", "show the currently saved VM snapshots" }, | 1318 | "", "show the currently saved VM snapshots" }, |
| 1319 | + { "pcmcia", "", pcmcia_info, | ||
| 1320 | + "", "show guest PCMCIA status" }, | ||
| 1319 | { "mice", "", do_info_mice, | 1321 | { "mice", "", do_info_mice, |
| 1320 | "", "show which guest mouse is receiving events" }, | 1322 | "", "show which guest mouse is receiving events" }, |
| 1321 | { "vnc", "", do_info_vnc, | 1323 | { "vnc", "", do_info_vnc, |
vl.c
| @@ -4412,6 +4412,48 @@ void usb_info(void) | @@ -4412,6 +4412,48 @@ void usb_info(void) | ||
| 4412 | } | 4412 | } |
| 4413 | 4413 | ||
| 4414 | /***********************************************************/ | 4414 | /***********************************************************/ |
| 4415 | +/* PCMCIA/Cardbus */ | ||
| 4416 | + | ||
| 4417 | +static struct pcmcia_socket_entry_s { | ||
| 4418 | + struct pcmcia_socket_s *socket; | ||
| 4419 | + struct pcmcia_socket_entry_s *next; | ||
| 4420 | +} *pcmcia_sockets = 0; | ||
| 4421 | + | ||
| 4422 | +void pcmcia_socket_register(struct pcmcia_socket_s *socket) | ||
| 4423 | +{ | ||
| 4424 | + struct pcmcia_socket_entry_s *entry; | ||
| 4425 | + | ||
| 4426 | + entry = qemu_malloc(sizeof(struct pcmcia_socket_entry_s)); | ||
| 4427 | + entry->socket = socket; | ||
| 4428 | + entry->next = pcmcia_sockets; | ||
| 4429 | + pcmcia_sockets = entry; | ||
| 4430 | +} | ||
| 4431 | + | ||
| 4432 | +void pcmcia_socket_unregister(struct pcmcia_socket_s *socket) | ||
| 4433 | +{ | ||
| 4434 | + struct pcmcia_socket_entry_s *entry, **ptr; | ||
| 4435 | + | ||
| 4436 | + ptr = &pcmcia_sockets; | ||
| 4437 | + for (entry = *ptr; entry; ptr = &entry->next, entry = *ptr) | ||
| 4438 | + if (entry->socket == socket) { | ||
| 4439 | + *ptr = entry->next; | ||
| 4440 | + qemu_free(entry); | ||
| 4441 | + } | ||
| 4442 | +} | ||
| 4443 | + | ||
| 4444 | +void pcmcia_info(void) | ||
| 4445 | +{ | ||
| 4446 | + struct pcmcia_socket_entry_s *iter; | ||
| 4447 | + if (!pcmcia_sockets) | ||
| 4448 | + term_printf("No PCMCIA sockets\n"); | ||
| 4449 | + | ||
| 4450 | + for (iter = pcmcia_sockets; iter; iter = iter->next) | ||
| 4451 | + term_printf("%s: %s\n", iter->socket->slot_string, | ||
| 4452 | + iter->socket->attached ? iter->socket->card_string : | ||
| 4453 | + "Empty"); | ||
| 4454 | +} | ||
| 4455 | + | ||
| 4456 | +/***********************************************************/ | ||
| 4415 | /* dumb display */ | 4457 | /* dumb display */ |
| 4416 | 4458 | ||
| 4417 | static void dumb_update(DisplayState *ds, int x, int y, int w, int h) | 4459 | static void dumb_update(DisplayState *ds, int x, int y, int w, int h) |
vl.h
| @@ -1475,6 +1475,56 @@ pflash_t *pflash_register (target_ulong base, ram_addr_t off, | @@ -1475,6 +1475,56 @@ pflash_t *pflash_register (target_ulong base, ram_addr_t off, | ||
| 1475 | uint16_t id0, uint16_t id1, | 1475 | uint16_t id0, uint16_t id1, |
| 1476 | uint16_t id2, uint16_t id3); | 1476 | uint16_t id2, uint16_t id3); |
| 1477 | 1477 | ||
| 1478 | +/* PCMCIA/Cardbus */ | ||
| 1479 | + | ||
| 1480 | +struct pcmcia_socket_s { | ||
| 1481 | + qemu_irq irq; | ||
| 1482 | + int attached; | ||
| 1483 | + const char *slot_string; | ||
| 1484 | + const char *card_string; | ||
| 1485 | +}; | ||
| 1486 | + | ||
| 1487 | +void pcmcia_socket_register(struct pcmcia_socket_s *socket); | ||
| 1488 | +void pcmcia_socket_unregister(struct pcmcia_socket_s *socket); | ||
| 1489 | +void pcmcia_info(void); | ||
| 1490 | + | ||
| 1491 | +struct pcmcia_card_s { | ||
| 1492 | + void *state; | ||
| 1493 | + struct pcmcia_socket_s *slot; | ||
| 1494 | + int (*attach)(void *state); | ||
| 1495 | + int (*detach)(void *state); | ||
| 1496 | + const uint8_t *cis; | ||
| 1497 | + int cis_len; | ||
| 1498 | + | ||
| 1499 | + /* Only valid if attached */ | ||
| 1500 | + uint8_t (*attr_read)(void *state, uint16_t address); | ||
| 1501 | + void (*attr_write)(void *state, uint16_t address, uint8_t value); | ||
| 1502 | + uint16_t (*common_read)(void *state, uint16_t address); | ||
| 1503 | + void (*common_write)(void *state, uint16_t address, uint16_t value); | ||
| 1504 | + uint16_t (*io_read)(void *state, uint16_t address); | ||
| 1505 | + void (*io_write)(void *state, uint16_t address, uint16_t value); | ||
| 1506 | +}; | ||
| 1507 | + | ||
| 1508 | +#define CISTPL_DEVICE 0x01 /* 5V Device Information Tuple */ | ||
| 1509 | +#define CISTPL_NO_LINK 0x14 /* No Link Tuple */ | ||
| 1510 | +#define CISTPL_VERS_1 0x15 /* Level 1 Version Tuple */ | ||
| 1511 | +#define CISTPL_JEDEC_C 0x18 /* JEDEC ID Tuple */ | ||
| 1512 | +#define CISTPL_JEDEC_A 0x19 /* JEDEC ID Tuple */ | ||
| 1513 | +#define CISTPL_CONFIG 0x1a /* Configuration Tuple */ | ||
| 1514 | +#define CISTPL_CFTABLE_ENTRY 0x1b /* 16-bit PCCard Configuration */ | ||
| 1515 | +#define CISTPL_DEVICE_OC 0x1c /* Additional Device Information */ | ||
| 1516 | +#define CISTPL_DEVICE_OA 0x1d /* Additional Device Information */ | ||
| 1517 | +#define CISTPL_DEVICE_GEO 0x1e /* Additional Device Information */ | ||
| 1518 | +#define CISTPL_DEVICE_GEO_A 0x1f /* Additional Device Information */ | ||
| 1519 | +#define CISTPL_MANFID 0x20 /* Manufacture ID Tuple */ | ||
| 1520 | +#define CISTPL_FUNCID 0x21 /* Function ID Tuple */ | ||
| 1521 | +#define CISTPL_FUNCE 0x22 /* Function Extension Tuple */ | ||
| 1522 | +#define CISTPL_END 0xff /* Tuple End */ | ||
| 1523 | +#define CISTPL_ENDMARK 0xff | ||
| 1524 | + | ||
| 1525 | +/* dscm1xxxx.c */ | ||
| 1526 | +struct pcmcia_card_s *dscm1xxxx_init(BlockDriverState *bdrv); | ||
| 1527 | + | ||
| 1478 | #include "gdbstub.h" | 1528 | #include "gdbstub.h" |
| 1479 | 1529 | ||
| 1480 | #endif /* defined(QEMU_TOOL) */ | 1530 | #endif /* defined(QEMU_TOOL) */ |