Annotation of qemu/hw/ide/microdrive.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * QEMU IDE Emulation: microdrive (CF / PCMCIA)
        !             3:  *
        !             4:  * Copyright (c) 2003 Fabrice Bellard
        !             5:  * Copyright (c) 2006 Openedhand Ltd.
        !             6:  *
        !             7:  * Permission is hereby granted, free of charge, to any person obtaining a copy
        !             8:  * of this software and associated documentation files (the "Software"), to deal
        !             9:  * in the Software without restriction, including without limitation the rights
        !            10:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        !            11:  * copies of the Software, and to permit persons to whom the Software is
        !            12:  * furnished to do so, subject to the following conditions:
        !            13:  *
        !            14:  * The above copyright notice and this permission notice shall be included in
        !            15:  * all copies or substantial portions of the Software.
        !            16:  *
        !            17:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        !            18:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        !            19:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
        !            20:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        !            21:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        !            22:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
        !            23:  * THE SOFTWARE.
        !            24:  */
        !            25: #include <hw/hw.h>
        !            26: #include <hw/pc.h>
        !            27: #include <hw/pcmcia.h>
        !            28: #include "block.h"
        !            29: #include "block_int.h"
        !            30: #include "sysemu.h"
        !            31: #include "dma.h"
        !            32: 
        !            33: #include <hw/ide/internal.h>
        !            34: 
        !            35: /***********************************************************/
        !            36: /* CF-ATA Microdrive */
        !            37: 
        !            38: #define METADATA_SIZE  0x20
        !            39: 
        !            40: /* DSCM-1XXXX Microdrive hard disk with CF+ II / PCMCIA interface.  */
        !            41: typedef struct {
        !            42:     IDEBus bus;
        !            43:     PCMCIACardState card;
        !            44:     uint32_t attr_base;
        !            45:     uint32_t io_base;
        !            46: 
        !            47:     /* Card state */
        !            48:     uint8_t opt;
        !            49:     uint8_t stat;
        !            50:     uint8_t pins;
        !            51: 
        !            52:     uint8_t ctrl;
        !            53:     uint16_t io;
        !            54:     uint8_t cycle;
        !            55: } MicroDriveState;
        !            56: 
        !            57: /* Register bitfields */
        !            58: enum md_opt {
        !            59:     OPT_MODE_MMAP      = 0,
        !            60:     OPT_MODE_IOMAP16   = 1,
        !            61:     OPT_MODE_IOMAP1    = 2,
        !            62:     OPT_MODE_IOMAP2    = 3,
        !            63:     OPT_MODE           = 0x3f,
        !            64:     OPT_LEVIREQ                = 0x40,
        !            65:     OPT_SRESET         = 0x80,
        !            66: };
        !            67: enum md_cstat {
        !            68:     STAT_INT           = 0x02,
        !            69:     STAT_PWRDWN                = 0x04,
        !            70:     STAT_XE            = 0x10,
        !            71:     STAT_IOIS8         = 0x20,
        !            72:     STAT_SIGCHG                = 0x40,
        !            73:     STAT_CHANGED       = 0x80,
        !            74: };
        !            75: enum md_pins {
        !            76:     PINS_MRDY          = 0x02,
        !            77:     PINS_CRDY          = 0x20,
        !            78: };
        !            79: enum md_ctrl {
        !            80:     CTRL_IEN           = 0x02,
        !            81:     CTRL_SRST          = 0x04,
        !            82: };
        !            83: 
        !            84: static inline void md_interrupt_update(MicroDriveState *s)
        !            85: {
        !            86:     if (!s->card.slot)
        !            87:         return;
        !            88: 
        !            89:     qemu_set_irq(s->card.slot->irq,
        !            90:                     !(s->stat & STAT_INT) &&   /* Inverted */
        !            91:                     !(s->ctrl & (CTRL_IEN | CTRL_SRST)) &&
        !            92:                     !(s->opt & OPT_SRESET));
        !            93: }
        !            94: 
        !            95: static void md_set_irq(void *opaque, int irq, int level)
        !            96: {
        !            97:     MicroDriveState *s = opaque;
        !            98:     if (level)
        !            99:         s->stat |= STAT_INT;
        !           100:     else
        !           101:         s->stat &= ~STAT_INT;
        !           102: 
        !           103:     md_interrupt_update(s);
        !           104: }
        !           105: 
        !           106: static void md_reset(MicroDriveState *s)
        !           107: {
        !           108:     s->opt = OPT_MODE_MMAP;
        !           109:     s->stat = 0;
        !           110:     s->pins = 0;
        !           111:     s->cycle = 0;
        !           112:     s->ctrl = 0;
        !           113:     ide_bus_reset(&s->bus);
        !           114: }
        !           115: 
        !           116: static uint8_t md_attr_read(void *opaque, uint32_t at)
        !           117: {
        !           118:     MicroDriveState *s = opaque;
        !           119:     if (at < s->attr_base) {
        !           120:         if (at < s->card.cis_len)
        !           121:             return s->card.cis[at];
        !           122:         else
        !           123:             return 0x00;
        !           124:     }
        !           125: 
        !           126:     at -= s->attr_base;
        !           127: 
        !           128:     switch (at) {
        !           129:     case 0x00: /* Configuration Option Register */
        !           130:         return s->opt;
        !           131:     case 0x02: /* Card Configuration Status Register */
        !           132:         if (s->ctrl & CTRL_IEN)
        !           133:             return s->stat & ~STAT_INT;
        !           134:         else
        !           135:             return s->stat;
        !           136:     case 0x04: /* Pin Replacement Register */
        !           137:         return (s->pins & PINS_CRDY) | 0x0c;
        !           138:     case 0x06: /* Socket and Copy Register */
        !           139:         return 0x00;
        !           140: #ifdef VERBOSE
        !           141:     default:
        !           142:         printf("%s: Bad attribute space register %02x\n", __FUNCTION__, at);
        !           143: #endif
        !           144:     }
        !           145: 
        !           146:     return 0;
        !           147: }
        !           148: 
        !           149: static void md_attr_write(void *opaque, uint32_t at, uint8_t value)
        !           150: {
        !           151:     MicroDriveState *s = opaque;
        !           152:     at -= s->attr_base;
        !           153: 
        !           154:     switch (at) {
        !           155:     case 0x00: /* Configuration Option Register */
        !           156:         s->opt = value & 0xcf;
        !           157:         if (value & OPT_SRESET)
        !           158:             md_reset(s);
        !           159:         md_interrupt_update(s);
        !           160:         break;
        !           161:     case 0x02: /* Card Configuration Status Register */
        !           162:         if ((s->stat ^ value) & STAT_PWRDWN)
        !           163:             s->pins |= PINS_CRDY;
        !           164:         s->stat &= 0x82;
        !           165:         s->stat |= value & 0x74;
        !           166:         md_interrupt_update(s);
        !           167:         /* Word 170 in Identify Device must be equal to STAT_XE */
        !           168:         break;
        !           169:     case 0x04: /* Pin Replacement Register */
        !           170:         s->pins &= PINS_CRDY;
        !           171:         s->pins |= value & PINS_MRDY;
        !           172:         break;
        !           173:     case 0x06: /* Socket and Copy Register */
        !           174:         break;
        !           175:     default:
        !           176:         printf("%s: Bad attribute space register %02x\n", __FUNCTION__, at);
        !           177:     }
        !           178: }
        !           179: 
        !           180: static uint16_t md_common_read(void *opaque, uint32_t at)
        !           181: {
        !           182:     MicroDriveState *s = opaque;
        !           183:     IDEState *ifs;
        !           184:     uint16_t ret;
        !           185:     at -= s->io_base;
        !           186: 
        !           187:     switch (s->opt & OPT_MODE) {
        !           188:     case OPT_MODE_MMAP:
        !           189:         if ((at & ~0x3ff) == 0x400)
        !           190:             at = 0;
        !           191:         break;
        !           192:     case OPT_MODE_IOMAP16:
        !           193:         at &= 0xf;
        !           194:         break;
        !           195:     case OPT_MODE_IOMAP1:
        !           196:         if ((at & ~0xf) == 0x3f0)
        !           197:             at -= 0x3e8;
        !           198:         else if ((at & ~0xf) == 0x1f0)
        !           199:             at -= 0x1f0;
        !           200:         break;
        !           201:     case OPT_MODE_IOMAP2:
        !           202:         if ((at & ~0xf) == 0x370)
        !           203:             at -= 0x368;
        !           204:         else if ((at & ~0xf) == 0x170)
        !           205:             at -= 0x170;
        !           206:     }
        !           207: 
        !           208:     switch (at) {
        !           209:     case 0x0:  /* Even RD Data */
        !           210:     case 0x8:
        !           211:         return ide_data_readw(&s->bus, 0);
        !           212: 
        !           213:         /* TODO: 8-bit accesses */
        !           214:         if (s->cycle)
        !           215:             ret = s->io >> 8;
        !           216:         else {
        !           217:             s->io = ide_data_readw(&s->bus, 0);
        !           218:             ret = s->io & 0xff;
        !           219:         }
        !           220:         s->cycle = !s->cycle;
        !           221:         return ret;
        !           222:     case 0x9:  /* Odd RD Data */
        !           223:         return s->io >> 8;
        !           224:     case 0xd:  /* Error */
        !           225:         return ide_ioport_read(&s->bus, 0x1);
        !           226:     case 0xe:  /* Alternate Status */
        !           227:         ifs = idebus_active_if(&s->bus);
        !           228:         if (ifs->bs)
        !           229:             return ifs->status;
        !           230:         else
        !           231:             return 0;
        !           232:     case 0xf:  /* Device Address */
        !           233:         ifs = idebus_active_if(&s->bus);
        !           234:         return 0xc2 | ((~ifs->select << 2) & 0x3c);
        !           235:     default:
        !           236:         return ide_ioport_read(&s->bus, at);
        !           237:     }
        !           238: 
        !           239:     return 0;
        !           240: }
        !           241: 
        !           242: static void md_common_write(void *opaque, uint32_t at, uint16_t value)
        !           243: {
        !           244:     MicroDriveState *s = opaque;
        !           245:     at -= s->io_base;
        !           246: 
        !           247:     switch (s->opt & OPT_MODE) {
        !           248:     case OPT_MODE_MMAP:
        !           249:         if ((at & ~0x3ff) == 0x400)
        !           250:             at = 0;
        !           251:         break;
        !           252:     case OPT_MODE_IOMAP16:
        !           253:         at &= 0xf;
        !           254:         break;
        !           255:     case OPT_MODE_IOMAP1:
        !           256:         if ((at & ~0xf) == 0x3f0)
        !           257:             at -= 0x3e8;
        !           258:         else if ((at & ~0xf) == 0x1f0)
        !           259:             at -= 0x1f0;
        !           260:         break;
        !           261:     case OPT_MODE_IOMAP2:
        !           262:         if ((at & ~0xf) == 0x370)
        !           263:             at -= 0x368;
        !           264:         else if ((at & ~0xf) == 0x170)
        !           265:             at -= 0x170;
        !           266:     }
        !           267: 
        !           268:     switch (at) {
        !           269:     case 0x0:  /* Even WR Data */
        !           270:     case 0x8:
        !           271:         ide_data_writew(&s->bus, 0, value);
        !           272:         break;
        !           273: 
        !           274:         /* TODO: 8-bit accesses */
        !           275:         if (s->cycle)
        !           276:             ide_data_writew(&s->bus, 0, s->io | (value << 8));
        !           277:         else
        !           278:             s->io = value & 0xff;
        !           279:         s->cycle = !s->cycle;
        !           280:         break;
        !           281:     case 0x9:
        !           282:         s->io = value & 0xff;
        !           283:         s->cycle = !s->cycle;
        !           284:         break;
        !           285:     case 0xd:  /* Features */
        !           286:         ide_ioport_write(&s->bus, 0x1, value);
        !           287:         break;
        !           288:     case 0xe:  /* Device Control */
        !           289:         s->ctrl = value;
        !           290:         if (value & CTRL_SRST)
        !           291:             md_reset(s);
        !           292:         md_interrupt_update(s);
        !           293:         break;
        !           294:     default:
        !           295:         if (s->stat & STAT_PWRDWN) {
        !           296:             s->pins |= PINS_CRDY;
        !           297:             s->stat &= ~STAT_PWRDWN;
        !           298:         }
        !           299:         ide_ioport_write(&s->bus, at, value);
        !           300:     }
        !           301: }
        !           302: 
        !           303: static const VMStateDescription vmstate_microdrive = {
        !           304:     .name = "microdrive",
        !           305:     .version_id = 3,
        !           306:     .minimum_version_id = 0,
        !           307:     .minimum_version_id_old = 0,
        !           308:     .fields      = (VMStateField []) {
        !           309:         VMSTATE_UINT8(opt, MicroDriveState),
        !           310:         VMSTATE_UINT8(stat, MicroDriveState),
        !           311:         VMSTATE_UINT8(pins, MicroDriveState),
        !           312:         VMSTATE_UINT8(ctrl, MicroDriveState),
        !           313:         VMSTATE_UINT16(io, MicroDriveState),
        !           314:         VMSTATE_UINT8(cycle, MicroDriveState),
        !           315:         VMSTATE_IDE_BUS(bus, MicroDriveState),
        !           316:         VMSTATE_IDE_DRIVES(bus.ifs, MicroDriveState),
        !           317:         VMSTATE_END_OF_LIST()
        !           318:     }
        !           319: };
        !           320: 
        !           321: static const uint8_t dscm1xxxx_cis[0x14a] = {
        !           322:     [0x000] = CISTPL_DEVICE,   /* 5V Device Information */
        !           323:     [0x002] = 0x03,            /* Tuple length = 4 bytes */
        !           324:     [0x004] = 0xdb,            /* ID: DTYPE_FUNCSPEC, non WP, DSPEED_150NS */
        !           325:     [0x006] = 0x01,            /* Size = 2K bytes */
        !           326:     [0x008] = CISTPL_ENDMARK,
        !           327: 
        !           328:     [0x00a] = CISTPL_DEVICE_OC,        /* Additional Device Information */
        !           329:     [0x00c] = 0x04,            /* Tuple length = 4 byest */
        !           330:     [0x00e] = 0x03,            /* Conditions: Ext = 0, Vcc 3.3V, MWAIT = 1 */
        !           331:     [0x010] = 0xdb,            /* ID: DTYPE_FUNCSPEC, non WP, DSPEED_150NS */
        !           332:     [0x012] = 0x01,            /* Size = 2K bytes */
        !           333:     [0x014] = CISTPL_ENDMARK,
        !           334: 
        !           335:     [0x016] = CISTPL_JEDEC_C,  /* JEDEC ID */
        !           336:     [0x018] = 0x02,            /* Tuple length = 2 bytes */
        !           337:     [0x01a] = 0xdf,            /* PC Card ATA with no Vpp required */
        !           338:     [0x01c] = 0x01,
        !           339: 
        !           340:     [0x01e] = CISTPL_MANFID,   /* Manufacture ID */
        !           341:     [0x020] = 0x04,            /* Tuple length = 4 bytes */
        !           342:     [0x022] = 0xa4,            /* TPLMID_MANF = 00a4 (IBM) */
        !           343:     [0x024] = 0x00,
        !           344:     [0x026] = 0x00,            /* PLMID_CARD = 0000 */
        !           345:     [0x028] = 0x00,
        !           346: 
        !           347:     [0x02a] = CISTPL_VERS_1,   /* Level 1 Version */
        !           348:     [0x02c] = 0x12,            /* Tuple length = 23 bytes */
        !           349:     [0x02e] = 0x04,            /* Major Version = JEIDA 4.2 / PCMCIA 2.1 */
        !           350:     [0x030] = 0x01,            /* Minor Version = 1 */
        !           351:     [0x032] = 'I',
        !           352:     [0x034] = 'B',
        !           353:     [0x036] = 'M',
        !           354:     [0x038] = 0x00,
        !           355:     [0x03a] = 'm',
        !           356:     [0x03c] = 'i',
        !           357:     [0x03e] = 'c',
        !           358:     [0x040] = 'r',
        !           359:     [0x042] = 'o',
        !           360:     [0x044] = 'd',
        !           361:     [0x046] = 'r',
        !           362:     [0x048] = 'i',
        !           363:     [0x04a] = 'v',
        !           364:     [0x04c] = 'e',
        !           365:     [0x04e] = 0x00,
        !           366:     [0x050] = CISTPL_ENDMARK,
        !           367: 
        !           368:     [0x052] = CISTPL_FUNCID,   /* Function ID */
        !           369:     [0x054] = 0x02,            /* Tuple length = 2 bytes */
        !           370:     [0x056] = 0x04,            /* TPLFID_FUNCTION = Fixed Disk */
        !           371:     [0x058] = 0x01,            /* TPLFID_SYSINIT: POST = 1, ROM = 0 */
        !           372: 
        !           373:     [0x05a] = CISTPL_FUNCE,    /* Function Extension */
        !           374:     [0x05c] = 0x02,            /* Tuple length = 2 bytes */
        !           375:     [0x05e] = 0x01,            /* TPLFE_TYPE = Disk Device Interface */
        !           376:     [0x060] = 0x01,            /* TPLFE_DATA = PC Card ATA Interface */
        !           377: 
        !           378:     [0x062] = CISTPL_FUNCE,    /* Function Extension */
        !           379:     [0x064] = 0x03,            /* Tuple length = 3 bytes */
        !           380:     [0x066] = 0x02,            /* TPLFE_TYPE = Basic PC Card ATA Interface */
        !           381:     [0x068] = 0x08,            /* TPLFE_DATA: Rotating, Unique, Single */
        !           382:     [0x06a] = 0x0f,            /* TPLFE_DATA: Sleep, Standby, Idle, Auto */
        !           383: 
        !           384:     [0x06c] = CISTPL_CONFIG,   /* Configuration */
        !           385:     [0x06e] = 0x05,            /* Tuple length = 5 bytes */
        !           386:     [0x070] = 0x01,            /* TPCC_RASZ = 2 bytes, TPCC_RMSZ = 1 byte */
        !           387:     [0x072] = 0x07,            /* TPCC_LAST = 7 */
        !           388:     [0x074] = 0x00,            /* TPCC_RADR = 0200 */
        !           389:     [0x076] = 0x02,
        !           390:     [0x078] = 0x0f,            /* TPCC_RMSK = 200, 202, 204, 206 */
        !           391: 
        !           392:     [0x07a] = CISTPL_CFTABLE_ENTRY,    /* 16-bit PC Card Configuration */
        !           393:     [0x07c] = 0x0b,            /* Tuple length = 11 bytes */
        !           394:     [0x07e] = 0xc0,            /* TPCE_INDX = Memory Mode, Default, Iface */
        !           395:     [0x080] = 0xc0,            /* TPCE_IF = Memory, no BVDs, no WP, READY */
        !           396:     [0x082] = 0xa1,            /* TPCE_FS = Vcc only, no I/O, Memory, Misc */
        !           397:     [0x084] = 0x27,            /* NomV = 1, MinV = 1, MaxV = 1, Peakl = 1 */
        !           398:     [0x086] = 0x55,            /* NomV: 5.0 V */
        !           399:     [0x088] = 0x4d,            /* MinV: 4.5 V */
        !           400:     [0x08a] = 0x5d,            /* MaxV: 5.5 V */
        !           401:     [0x08c] = 0x4e,            /* Peakl: 450 mA */
        !           402:     [0x08e] = 0x08,            /* TPCE_MS = 1 window, 1 byte, Host address */
        !           403:     [0x090] = 0x00,            /* Window descriptor: Window length = 0 */
        !           404:     [0x092] = 0x20,            /* TPCE_MI: support power down mode, RW */
        !           405: 
        !           406:     [0x094] = CISTPL_CFTABLE_ENTRY,    /* 16-bit PC Card Configuration */
        !           407:     [0x096] = 0x06,            /* Tuple length = 6 bytes */
        !           408:     [0x098] = 0x00,            /* TPCE_INDX = Memory Mode, no Default */
        !           409:     [0x09a] = 0x01,            /* TPCE_FS = Vcc only, no I/O, no Memory */
        !           410:     [0x09c] = 0x21,            /* NomV = 1, MinV = 0, MaxV = 0, Peakl = 1 */
        !           411:     [0x09e] = 0xb5,            /* NomV: 3.3 V */
        !           412:     [0x0a0] = 0x1e,
        !           413:     [0x0a2] = 0x3e,            /* Peakl: 350 mA */
        !           414: 
        !           415:     [0x0a4] = CISTPL_CFTABLE_ENTRY,    /* 16-bit PC Card Configuration */
        !           416:     [0x0a6] = 0x0d,            /* Tuple length = 13 bytes */
        !           417:     [0x0a8] = 0xc1,            /* TPCE_INDX = I/O and Memory Mode, Default */
        !           418:     [0x0aa] = 0x41,            /* TPCE_IF = I/O and Memory, no BVD, no WP */
        !           419:     [0x0ac] = 0x99,            /* TPCE_FS = Vcc only, I/O, Interrupt, Misc */
        !           420:     [0x0ae] = 0x27,            /* NomV = 1, MinV = 1, MaxV = 1, Peakl = 1 */
        !           421:     [0x0b0] = 0x55,            /* NomV: 5.0 V */
        !           422:     [0x0b2] = 0x4d,            /* MinV: 4.5 V */
        !           423:     [0x0b4] = 0x5d,            /* MaxV: 5.5 V */
        !           424:     [0x0b6] = 0x4e,            /* Peakl: 450 mA */
        !           425:     [0x0b8] = 0x64,            /* TPCE_IO = 16-byte boundary, 16/8 accesses */
        !           426:     [0x0ba] = 0xf0,            /* TPCE_IR =  MASK, Level, Pulse, Share */
        !           427:     [0x0bc] = 0xff,            /* IRQ0..IRQ7 supported */
        !           428:     [0x0be] = 0xff,            /* IRQ8..IRQ15 supported */
        !           429:     [0x0c0] = 0x20,            /* TPCE_MI = support power down mode */
        !           430: 
        !           431:     [0x0c2] = CISTPL_CFTABLE_ENTRY,    /* 16-bit PC Card Configuration */
        !           432:     [0x0c4] = 0x06,            /* Tuple length = 6 bytes */
        !           433:     [0x0c6] = 0x01,            /* TPCE_INDX = I/O and Memory Mode */
        !           434:     [0x0c8] = 0x01,            /* TPCE_FS = Vcc only, no I/O, no Memory */
        !           435:     [0x0ca] = 0x21,            /* NomV = 1, MinV = 0, MaxV = 0, Peakl = 1 */
        !           436:     [0x0cc] = 0xb5,            /* NomV: 3.3 V */
        !           437:     [0x0ce] = 0x1e,
        !           438:     [0x0d0] = 0x3e,            /* Peakl: 350 mA */
        !           439: 
        !           440:     [0x0d2] = CISTPL_CFTABLE_ENTRY,    /* 16-bit PC Card Configuration */
        !           441:     [0x0d4] = 0x12,            /* Tuple length = 18 bytes */
        !           442:     [0x0d6] = 0xc2,            /* TPCE_INDX = I/O Primary Mode */
        !           443:     [0x0d8] = 0x41,            /* TPCE_IF = I/O and Memory, no BVD, no WP */
        !           444:     [0x0da] = 0x99,            /* TPCE_FS = Vcc only, I/O, Interrupt, Misc */
        !           445:     [0x0dc] = 0x27,            /* NomV = 1, MinV = 1, MaxV = 1, Peakl = 1 */
        !           446:     [0x0de] = 0x55,            /* NomV: 5.0 V */
        !           447:     [0x0e0] = 0x4d,            /* MinV: 4.5 V */
        !           448:     [0x0e2] = 0x5d,            /* MaxV: 5.5 V */
        !           449:     [0x0e4] = 0x4e,            /* Peakl: 450 mA */
        !           450:     [0x0e6] = 0xea,            /* TPCE_IO = 1K boundary, 16/8 access, Range */
        !           451:     [0x0e8] = 0x61,            /* Range: 2 fields, 2 bytes addr, 1 byte len */
        !           452:     [0x0ea] = 0xf0,            /* Field 1 address = 0x01f0 */
        !           453:     [0x0ec] = 0x01,
        !           454:     [0x0ee] = 0x07,            /* Address block length = 8 */
        !           455:     [0x0f0] = 0xf6,            /* Field 2 address = 0x03f6 */
        !           456:     [0x0f2] = 0x03,
        !           457:     [0x0f4] = 0x01,            /* Address block length = 2 */
        !           458:     [0x0f6] = 0xee,            /* TPCE_IR = IRQ E, Level, Pulse, Share */
        !           459:     [0x0f8] = 0x20,            /* TPCE_MI = support power down mode */
        !           460: 
        !           461:     [0x0fa] = CISTPL_CFTABLE_ENTRY,    /* 16-bit PC Card Configuration */
        !           462:     [0x0fc] = 0x06,            /* Tuple length = 6 bytes */
        !           463:     [0x0fe] = 0x02,            /* TPCE_INDX = I/O Primary Mode, no Default */
        !           464:     [0x100] = 0x01,            /* TPCE_FS = Vcc only, no I/O, no Memory */
        !           465:     [0x102] = 0x21,            /* NomV = 1, MinV = 0, MaxV = 0, Peakl = 1 */
        !           466:     [0x104] = 0xb5,            /* NomV: 3.3 V */
        !           467:     [0x106] = 0x1e,
        !           468:     [0x108] = 0x3e,            /* Peakl: 350 mA */
        !           469: 
        !           470:     [0x10a] = CISTPL_CFTABLE_ENTRY,    /* 16-bit PC Card Configuration */
        !           471:     [0x10c] = 0x12,            /* Tuple length = 18 bytes */
        !           472:     [0x10e] = 0xc3,            /* TPCE_INDX = I/O Secondary Mode, Default */
        !           473:     [0x110] = 0x41,            /* TPCE_IF = I/O and Memory, no BVD, no WP */
        !           474:     [0x112] = 0x99,            /* TPCE_FS = Vcc only, I/O, Interrupt, Misc */
        !           475:     [0x114] = 0x27,            /* NomV = 1, MinV = 1, MaxV = 1, Peakl = 1 */
        !           476:     [0x116] = 0x55,            /* NomV: 5.0 V */
        !           477:     [0x118] = 0x4d,            /* MinV: 4.5 V */
        !           478:     [0x11a] = 0x5d,            /* MaxV: 5.5 V */
        !           479:     [0x11c] = 0x4e,            /* Peakl: 450 mA */
        !           480:     [0x11e] = 0xea,            /* TPCE_IO = 1K boundary, 16/8 access, Range */
        !           481:     [0x120] = 0x61,            /* Range: 2 fields, 2 byte addr, 1 byte len */
        !           482:     [0x122] = 0x70,            /* Field 1 address = 0x0170 */
        !           483:     [0x124] = 0x01,
        !           484:     [0x126] = 0x07,            /* Address block length = 8 */
        !           485:     [0x128] = 0x76,            /* Field 2 address = 0x0376 */
        !           486:     [0x12a] = 0x03,
        !           487:     [0x12c] = 0x01,            /* Address block length = 2 */
        !           488:     [0x12e] = 0xee,            /* TPCE_IR = IRQ E, Level, Pulse, Share */
        !           489:     [0x130] = 0x20,            /* TPCE_MI = support power down mode */
        !           490: 
        !           491:     [0x132] = CISTPL_CFTABLE_ENTRY,    /* 16-bit PC Card Configuration */
        !           492:     [0x134] = 0x06,            /* Tuple length = 6 bytes */
        !           493:     [0x136] = 0x03,            /* TPCE_INDX = I/O Secondary Mode */
        !           494:     [0x138] = 0x01,            /* TPCE_FS = Vcc only, no I/O, no Memory */
        !           495:     [0x13a] = 0x21,            /* NomV = 1, MinV = 0, MaxV = 0, Peakl = 1 */
        !           496:     [0x13c] = 0xb5,            /* NomV: 3.3 V */
        !           497:     [0x13e] = 0x1e,
        !           498:     [0x140] = 0x3e,            /* Peakl: 350 mA */
        !           499: 
        !           500:     [0x142] = CISTPL_NO_LINK,  /* No Link */
        !           501:     [0x144] = 0x00,            /* Tuple length = 0 bytes */
        !           502: 
        !           503:     [0x146] = CISTPL_END,      /* Tuple End */
        !           504: };
        !           505: 
        !           506: static int dscm1xxxx_attach(void *opaque)
        !           507: {
        !           508:     MicroDriveState *md = opaque;
        !           509:     md->card.attr_read = md_attr_read;
        !           510:     md->card.attr_write = md_attr_write;
        !           511:     md->card.common_read = md_common_read;
        !           512:     md->card.common_write = md_common_write;
        !           513:     md->card.io_read = md_common_read;
        !           514:     md->card.io_write = md_common_write;
        !           515: 
        !           516:     md->attr_base = md->card.cis[0x74] | (md->card.cis[0x76] << 8);
        !           517:     md->io_base = 0x0;
        !           518: 
        !           519:     md_reset(md);
        !           520:     md_interrupt_update(md);
        !           521: 
        !           522:     md->card.slot->card_string = "DSCM-1xxxx Hitachi Microdrive";
        !           523:     return 0;
        !           524: }
        !           525: 
        !           526: static int dscm1xxxx_detach(void *opaque)
        !           527: {
        !           528:     MicroDriveState *md = opaque;
        !           529:     md_reset(md);
        !           530:     return 0;
        !           531: }
        !           532: 
        !           533: PCMCIACardState *dscm1xxxx_init(DriveInfo *bdrv)
        !           534: {
        !           535:     MicroDriveState *md = (MicroDriveState *) qemu_mallocz(sizeof(MicroDriveState));
        !           536:     md->card.state = md;
        !           537:     md->card.attach = dscm1xxxx_attach;
        !           538:     md->card.detach = dscm1xxxx_detach;
        !           539:     md->card.cis = dscm1xxxx_cis;
        !           540:     md->card.cis_len = sizeof(dscm1xxxx_cis);
        !           541: 
        !           542:     ide_init2(&md->bus, bdrv, NULL, qemu_allocate_irqs(md_set_irq, md, 1)[0]);
        !           543:     md->bus.ifs[0].is_cf = 1;
        !           544:     md->bus.ifs[0].mdata_size = METADATA_SIZE;
        !           545:     md->bus.ifs[0].mdata_storage = (uint8_t *) qemu_mallocz(METADATA_SIZE);
        !           546: 
        !           547:     vmstate_register(-1, &vmstate_microdrive, md);
        !           548: 
        !           549:     return &md->card;
        !           550: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.