⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ide.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 5 页
字号:
                        buf[6] |= 1 << 1;                    buf[15] = 0x00;                    cpu_to_ube16(&buf[16], 706);                    buf[18] = 0;                    buf[19] = 2;                    cpu_to_ube16(&buf[20], 512);                    cpu_to_ube16(&buf[22], 706);                    buf[24] = 0;                    buf[25] = 0;                    buf[26] = 0;                    buf[27] = 0;                    ide_atapi_cmd_reply(s, 28, max_len);                    break;                default:                    goto error_cmd;                }                break;            case 1: /* changeable values */                goto error_cmd;            case 2: /* default values */                goto error_cmd;            default:            case 3: /* saved values */                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,                                     ASC_SAVING_PARAMETERS_NOT_SUPPORTED);                break;            }        }        break;    case GPCMD_REQUEST_SENSE:        max_len = packet[4];        memset(buf, 0, 18);        buf[0] = 0x70 | (1 << 7);        buf[2] = s->sense_key;        buf[7] = 10;        buf[12] = s->asc;        ide_atapi_cmd_reply(s, 18, max_len);        break;    case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL:        if (bdrv_is_inserted(s->bs)) {            bdrv_set_locked(s->bs, packet[4] & 1);            ide_atapi_cmd_ok(s);        } else {            ide_atapi_cmd_error(s, SENSE_NOT_READY,                                 ASC_MEDIUM_NOT_PRESENT);        }        break;    case GPCMD_READ_10:    case GPCMD_READ_12:        {            int nb_sectors, lba;            if (!bdrv_is_inserted(s->bs)) {                ide_atapi_cmd_error(s, SENSE_NOT_READY,                                     ASC_MEDIUM_NOT_PRESENT);                break;            }            if (packet[0] == GPCMD_READ_10)                nb_sectors = ube16_to_cpu(packet + 7);            else                nb_sectors = ube32_to_cpu(packet + 6);            lba = ube32_to_cpu(packet + 2);            if (nb_sectors == 0) {                ide_atapi_cmd_ok(s);                break;            }            if (((int64_t)(lba + nb_sectors) << 2) > s->nb_sectors) {                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,                                     ASC_LOGICAL_BLOCK_OOR);                break;            }            ide_atapi_cmd_read(s, lba, nb_sectors, 2048);        }        break;    case GPCMD_READ_CD:        {            int nb_sectors, lba, transfer_request;            if (!bdrv_is_inserted(s->bs)) {                ide_atapi_cmd_error(s, SENSE_NOT_READY,                                     ASC_MEDIUM_NOT_PRESENT);                break;            }            nb_sectors = (packet[6] << 16) | (packet[7] << 8) | packet[8];            lba = ube32_to_cpu(packet + 2);            if (nb_sectors == 0) {                ide_atapi_cmd_ok(s);                break;            }            if (((int64_t)(lba + nb_sectors) << 2) > s->nb_sectors) {                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,                                     ASC_LOGICAL_BLOCK_OOR);                break;            }            transfer_request = packet[9];            switch(transfer_request & 0xf8) {            case 0x00:                /* nothing */                ide_atapi_cmd_ok(s);                break;            case 0x10:                /* normal read */                ide_atapi_cmd_read(s, lba, nb_sectors, 2048);                break;            case 0xf8:                /* read all data */                ide_atapi_cmd_read(s, lba, nb_sectors, 2352);                break;            default:                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,                                     ASC_INV_FIELD_IN_CMD_PACKET);                break;            }        }        break;    case GPCMD_SEEK:        {            int lba;            if (!bdrv_is_inserted(s->bs)) {                ide_atapi_cmd_error(s, SENSE_NOT_READY,                                     ASC_MEDIUM_NOT_PRESENT);                break;            }            lba = ube32_to_cpu(packet + 2);            if (((int64_t)lba << 2) > s->nb_sectors) {                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,                                     ASC_LOGICAL_BLOCK_OOR);                break;            }            ide_atapi_cmd_ok(s);        }        break;    case GPCMD_START_STOP_UNIT:        {            int start, eject;            start = packet[4] & 1;            eject = (packet[4] >> 1) & 1;                        if (eject && !start) {                /* eject the disk */                bdrv_close(s->bs);            }            ide_atapi_cmd_ok(s);        }        break;    case GPCMD_MECHANISM_STATUS:        {            max_len = ube16_to_cpu(packet + 8);            cpu_to_ube16(buf, 0);            /* no current LBA */            buf[2] = 0;            buf[3] = 0;            buf[4] = 0;            buf[5] = 1;            cpu_to_ube16(buf + 6, 0);            ide_atapi_cmd_reply(s, 8, max_len);        }        break;    case GPCMD_READ_TOC_PMA_ATIP:        {            int format, msf, start_track, len;            if (!bdrv_is_inserted(s->bs)) {                ide_atapi_cmd_error(s, SENSE_NOT_READY,                                     ASC_MEDIUM_NOT_PRESENT);                break;            }            max_len = ube16_to_cpu(packet + 7);            format = packet[9] >> 6;            msf = (packet[1] >> 1) & 1;            start_track = packet[6];            switch(format) {            case 0:                len = cdrom_read_toc(s, buf, msf, start_track);                if (len < 0)                    goto error_cmd;                ide_atapi_cmd_reply(s, len, max_len);                break;            case 1:                /* multi session : only a single session defined */                memset(buf, 0, 12);                buf[1] = 0x0a;                buf[2] = 0x01;                buf[3] = 0x01;                ide_atapi_cmd_reply(s, 12, max_len);                break;            case 2:                len = cdrom_read_toc_raw(s, buf, msf, start_track);                if (len < 0)                    goto error_cmd;                ide_atapi_cmd_reply(s, len, max_len);                break;            default:            error_cmd:                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,                                     ASC_INV_FIELD_IN_CMD_PACKET);                break;            }        }        break;    case GPCMD_READ_CDVD_CAPACITY:        if (!bdrv_is_inserted(s->bs)) {            ide_atapi_cmd_error(s, SENSE_NOT_READY,                                 ASC_MEDIUM_NOT_PRESENT);            break;        }        /* NOTE: it is really the number of sectors minus 1 */        cpu_to_ube32(buf, (s->nb_sectors >> 2) - 1);        cpu_to_ube32(buf + 4, 2048);        ide_atapi_cmd_reply(s, 8, 8);        break;    case GPCMD_INQUIRY:        max_len = packet[4];        buf[0] = 0x05; /* CD-ROM */        buf[1] = 0x80; /* removable */        buf[2] = 0x00; /* ISO */        buf[3] = 0x21; /* ATAPI-2 (XXX: put ATAPI-4 ?) */        buf[4] = 31; /* additionnal length */        buf[5] = 0; /* reserved */        buf[6] = 0; /* reserved */        buf[7] = 0; /* reserved */        padstr8(buf + 8, 8, "QEMU");        padstr8(buf + 16, 16, "QEMU CD-ROM");        padstr8(buf + 32, 4, QEMU_VERSION);        ide_atapi_cmd_reply(s, 36, max_len);        break;    default:        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,                             ASC_ILLEGAL_OPCODE);        break;    }}/* called when the inserted state of the media has changed */static void cdrom_change_cb(void *opaque){    IDEState *s = opaque;    int64_t nb_sectors;    /* XXX: send interrupt too */    bdrv_get_geometry(s->bs, &nb_sectors);    s->nb_sectors = nb_sectors;}static void ide_cmd_lba48_transform(IDEState *s, int lba48){    s->lba48 = lba48;    /* handle the 'magic' 0 nsector count conversion here. to avoid     * fiddling with the rest of the read logic, we just store the     * full sector count in ->nsector and ignore ->hob_nsector from now     */    if (!s->lba48) {	if (!s->nsector)	    s->nsector = 256;    } else {	if (!s->nsector && !s->hob_nsector)	    s->nsector = 65536;	else {	    int lo = s->nsector;	    int hi = s->hob_nsector;	    s->nsector = (hi << 8) | lo;	}    }}static void ide_clear_hob(IDEState *ide_if){    /* any write clears HOB high bit of device control register */    ide_if[0].select &= ~(1 << 7);    ide_if[1].select &= ~(1 << 7);}static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val){    IDEState *ide_if = opaque;    IDEState *s;    int unit, n;    int lba48 = 0;#ifdef DEBUG_IDE    printf("IDE: write addr=0x%x val=0x%02x\n", addr, val);#endif    addr &= 7;    switch(addr) {    case 0:        break;    case 1:	ide_clear_hob(ide_if);        /* NOTE: data is written to the two drives */	ide_if[0].hob_feature = ide_if[0].feature;	ide_if[1].hob_feature = ide_if[1].feature;        ide_if[0].feature = val;        ide_if[1].feature = val;        break;    case 2:	ide_clear_hob(ide_if);	ide_if[0].hob_nsector = ide_if[0].nsector;	ide_if[1].hob_nsector = ide_if[1].nsector;        ide_if[0].nsector = val;        ide_if[1].nsector = val;        break;    case 3:	ide_clear_hob(ide_if);	ide_if[0].hob_sector = ide_if[0].sector;	ide_if[1].hob_sector = ide_if[1].sector;        ide_if[0].sector = val;        ide_if[1].sector = val;        break;    case 4:	ide_clear_hob(ide_if);	ide_if[0].hob_lcyl = ide_if[0].lcyl;	ide_if[1].hob_lcyl = ide_if[1].lcyl;        ide_if[0].lcyl = val;        ide_if[1].lcyl = val;        break;    case 5:	ide_clear_hob(ide_if);	ide_if[0].hob_hcyl = ide_if[0].hcyl;	ide_if[1].hob_hcyl = ide_if[1].hcyl;        ide_if[0].hcyl = val;        ide_if[1].hcyl = val;        break;    case 6:	/* FIXME: HOB readback uses bit 7 */        ide_if[0].select = (val & ~0x10) | 0xa0;        ide_if[1].select = (val | 0x10) | 0xa0;        /* select drive */        unit = (val >> 4) & 1;        s = ide_if + unit;        ide_if->cur_drive = s;        break;    default:    case 7:        /* command */#if defined(DEBUG_IDE)        printf("ide: CMD=%02x\n", val);#endif        s = ide_if->cur_drive;        /* ignore commands to non existant slave */        if (s != ide_if && !s->bs)             break;        switch(val) {        case WIN_IDENTIFY:            if (s->bs && !s->is_cdrom) {                ide_identify(s);                s->status = READY_STAT | SEEK_STAT;                ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);            } else {                if (s->is_cdrom) {                    ide_set_signature(s);                }                ide_abort_command(s);            }            ide_set_irq(s);            break;        case WIN_SPECIFY:        case WIN_RECAL:            s->error = 0;            s->status = READY_STAT | SEEK_STAT;            ide_set_irq(s);            break;        case WIN_SETMULT:            if (s->nsector > MAX_MULT_SECTORS ||                 s->nsector == 0 ||                (s->nsector & (s->nsector - 1)) != 0) {                ide_abort_command(s);            } else {                s->mult_sectors = s->nsector;                s->status = READY_STAT;            }            ide_set_irq(s);            break;        case WIN_VERIFY_EXT:	    lba48 = 1;        case WIN_VERIFY:        case WIN_VERIFY_ONCE:            /* do sector number check ? */	    ide_cmd_lba48_transform(s, lba48);            s->status = READY_STAT;            ide_set_irq(s);            break;	case WIN_READ_EXT:	    lba48 = 1;        case WIN_READ:        case WIN_READ_ONCE:            if (!s->bs)                 goto abort_cmd;	    ide_cmd_lba48_transform(s, lba48);            s->req_nb_sectors = 1;            ide_sector_read(s);            break;	case WIN_WRITE_EXT:	    lba48 = 1;        case WIN_WRITE:        case WIN_WRITE_ONCE:	    ide_cmd_lba48_transform(s, lba48);            s->error = 0;            s->status = SEEK_STAT | READY_STAT;            s->req_nb_sectors = 1;            ide_transfer_start(s, s->io_buffer, 512, ide_sector_write);            break;	case WIN_MULTREAD_EXT:	    lba48 = 1;        case WIN_MULTREAD:            if (!s->mult_sectors)                goto abort_cmd;	    ide_cmd_lba48_transform(s, lba48);            s->req_nb_sectors = s->mult_sectors;            ide_sector_read(s);            break;        case WIN_MULTWRITE_EXT:	    lba48 = 1;        case WIN_MULTWRITE:            if (!s->mult_sectors)                goto abort_cmd;	    ide_cmd_lba48_transform(s, lba48);            s->error = 0;            s->status = SEEK_STAT | READY_STAT;            s->req_nb_sectors = s->mult_sectors;            n = s->nsector;            if (n > s->req_nb_sectors)                n = s->req_nb_sectors;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -