Commit 36b486bb74ca651d07968372cebd6e742114e144

Authored by bellard
1 parent 4ad06a29

hardware level IDE CD-ROM emulation - added second IDE interface for up to 4 IDE…

… disks emulation - added -boot command to enable CD boot


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@444 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 744 additions and 71 deletions
... ... @@ -63,6 +63,7 @@
63 63  
64 64 /* debug IDE devices */
65 65 //#define DEBUG_IDE
  66 +//#define DEBUG_IDE_ATAPI
66 67  
67 68 /* debug PIC */
68 69 //#define DEBUG_PIC
... ... @@ -85,7 +86,7 @@
85 86  
86 87 #define GUI_REFRESH_INTERVAL 30
87 88  
88   -#define MAX_DISKS 2
  89 +#define MAX_DISKS 4
89 90  
90 91 /* from plex86 (BSD license) */
91 92 struct __attribute__ ((packed)) linux_params {
... ... @@ -216,6 +217,7 @@ static DisplayState display_state;
216 217 int nographic;
217 218 int term_inited;
218 219 int64_t ticks_per_sec;
  220 +int boot_device = 'c';
219 221  
220 222 /***********************************************************/
221 223 /* x86 io ports */
... ... @@ -533,8 +535,19 @@ void cmos_init(void)
533 535 cmos_data[0x34] = val;
534 536 cmos_data[0x35] = val >> 8;
535 537  
536   - cmos_data[0x3d] = 0x02; /* hard drive boot */
537   -
  538 + switch(boot_device) {
  539 + case 'a':
  540 + cmos_data[0x3d] = 0x01; /* floppy boot */
  541 + break;
  542 + default:
  543 + case 'c':
  544 + cmos_data[0x3d] = 0x02; /* hard drive boot */
  545 + break;
  546 + case 'd':
  547 + cmos_data[0x3d] = 0x03; /* CD-ROM boot */
  548 + break;
  549 + }
  550 +
538 551 register_ioport_write(0x70, 2, cmos_ioport_write, 1);
539 552 register_ioport_read(0x70, 2, cmos_ioport_read, 1);
540 553 }
... ... @@ -1045,7 +1058,7 @@ static inline void pit_load_count(PITChannelState *s, int val)
1045 1058 s->count = val;
1046 1059 if (s == &pit_channels[0] && val <= pit_min_timer_count) {
1047 1060 fprintf(stderr,
1048   - "\nWARNING: vl: on your system, accurate timer emulation is impossible if its frequency is more than %d Hz. If using a 2.5.xx Linux kernel, you must patch asm/param.h to change HZ from 1000 to 100.\n\n",
  1061 + "\nWARNING: qemu: on your system, accurate timer emulation is impossible if its frequency is more than %d Hz. If using a 2.5.xx Linux kernel, you must patch asm/param.h to change HZ from 1000 to 100.\n\n",
1049 1062 PIT_FREQ / pit_min_timer_count);
1050 1063 }
1051 1064 }
... ... @@ -2014,12 +2027,111 @@ void ne2000_init(void)
2014 2027 /* set to 1 set disable mult support */
2015 2028 #define MAX_MULT_SECTORS 8
2016 2029  
  2030 +/* ATAPI defines */
  2031 +
  2032 +#define ATAPI_PACKET_SIZE 12
  2033 +
  2034 +/* The generic packet command opcodes for CD/DVD Logical Units,
  2035 + * From Table 57 of the SFF8090 Ver. 3 (Mt. Fuji) draft standard. */
  2036 +#define GPCMD_BLANK 0xa1
  2037 +#define GPCMD_CLOSE_TRACK 0x5b
  2038 +#define GPCMD_FLUSH_CACHE 0x35
  2039 +#define GPCMD_FORMAT_UNIT 0x04
  2040 +#define GPCMD_GET_CONFIGURATION 0x46
  2041 +#define GPCMD_GET_EVENT_STATUS_NOTIFICATION 0x4a
  2042 +#define GPCMD_GET_PERFORMANCE 0xac
  2043 +#define GPCMD_INQUIRY 0x12
  2044 +#define GPCMD_LOAD_UNLOAD 0xa6
  2045 +#define GPCMD_MECHANISM_STATUS 0xbd
  2046 +#define GPCMD_MODE_SELECT_10 0x55
  2047 +#define GPCMD_MODE_SENSE_10 0x5a
  2048 +#define GPCMD_PAUSE_RESUME 0x4b
  2049 +#define GPCMD_PLAY_AUDIO_10 0x45
  2050 +#define GPCMD_PLAY_AUDIO_MSF 0x47
  2051 +#define GPCMD_PLAY_AUDIO_TI 0x48
  2052 +#define GPCMD_PLAY_CD 0xbc
  2053 +#define GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e
  2054 +#define GPCMD_READ_10 0x28
  2055 +#define GPCMD_READ_12 0xa8
  2056 +#define GPCMD_READ_CDVD_CAPACITY 0x25
  2057 +#define GPCMD_READ_CD 0xbe
  2058 +#define GPCMD_READ_CD_MSF 0xb9
  2059 +#define GPCMD_READ_DISC_INFO 0x51
  2060 +#define GPCMD_READ_DVD_STRUCTURE 0xad
  2061 +#define GPCMD_READ_FORMAT_CAPACITIES 0x23
  2062 +#define GPCMD_READ_HEADER 0x44
  2063 +#define GPCMD_READ_TRACK_RZONE_INFO 0x52
  2064 +#define GPCMD_READ_SUBCHANNEL 0x42
  2065 +#define GPCMD_READ_TOC_PMA_ATIP 0x43
  2066 +#define GPCMD_REPAIR_RZONE_TRACK 0x58
  2067 +#define GPCMD_REPORT_KEY 0xa4
  2068 +#define GPCMD_REQUEST_SENSE 0x03
  2069 +#define GPCMD_RESERVE_RZONE_TRACK 0x53
  2070 +#define GPCMD_SCAN 0xba
  2071 +#define GPCMD_SEEK 0x2b
  2072 +#define GPCMD_SEND_DVD_STRUCTURE 0xad
  2073 +#define GPCMD_SEND_EVENT 0xa2
  2074 +#define GPCMD_SEND_KEY 0xa3
  2075 +#define GPCMD_SEND_OPC 0x54
  2076 +#define GPCMD_SET_READ_AHEAD 0xa7
  2077 +#define GPCMD_SET_STREAMING 0xb6
  2078 +#define GPCMD_START_STOP_UNIT 0x1b
  2079 +#define GPCMD_STOP_PLAY_SCAN 0x4e
  2080 +#define GPCMD_TEST_UNIT_READY 0x00
  2081 +#define GPCMD_VERIFY_10 0x2f
  2082 +#define GPCMD_WRITE_10 0x2a
  2083 +#define GPCMD_WRITE_AND_VERIFY_10 0x2e
  2084 +/* This is listed as optional in ATAPI 2.6, but is (curiously)
  2085 + * missing from Mt. Fuji, Table 57. It _is_ mentioned in Mt. Fuji
  2086 + * Table 377 as an MMC command for SCSi devices though... Most ATAPI
  2087 + * drives support it. */
  2088 +#define GPCMD_SET_SPEED 0xbb
  2089 +/* This seems to be a SCSI specific CD-ROM opcode
  2090 + * to play data at track/index */
  2091 +#define GPCMD_PLAYAUDIO_TI 0x48
  2092 +/*
  2093 + * From MS Media Status Notification Support Specification. For
  2094 + * older drives only.
  2095 + */
  2096 +#define GPCMD_GET_MEDIA_STATUS 0xda
  2097 +
  2098 +/* Mode page codes for mode sense/set */
  2099 +#define GPMODE_R_W_ERROR_PAGE 0x01
  2100 +#define GPMODE_WRITE_PARMS_PAGE 0x05
  2101 +#define GPMODE_AUDIO_CTL_PAGE 0x0e
  2102 +#define GPMODE_POWER_PAGE 0x1a
  2103 +#define GPMODE_FAULT_FAIL_PAGE 0x1c
  2104 +#define GPMODE_TO_PROTECT_PAGE 0x1d
  2105 +#define GPMODE_CAPABILITIES_PAGE 0x2a
  2106 +#define GPMODE_ALL_PAGES 0x3f
  2107 +/* Not in Mt. Fuji, but in ATAPI 2.6 -- depricated now in favor
  2108 + * of MODE_SENSE_POWER_PAGE */
  2109 +#define GPMODE_CDROM_PAGE 0x0d
  2110 +
  2111 +#define ATAPI_INT_REASON_CD 0x01 /* 0 = data transfer */
  2112 +#define ATAPI_INT_REASON_IO 0x02 /* 1 = transfer to the host */
  2113 +#define ATAPI_INT_REASON_REL 0x04
  2114 +#define ATAPI_INT_REASON_TAG 0xf8
  2115 +
  2116 +/* same constants as bochs */
  2117 +#define ASC_LOGICAL_BLOCK_OOR 0x21
  2118 +#define ASC_INV_FIELD_IN_CMD_PACKET 0x24
  2119 +#define ASC_MEDIUM_NOT_PRESENT 0x3a
  2120 +#define ASC_SAVING_PARAMETERS_NOT_SUPPORTED 0x39
  2121 +
  2122 +#define SENSE_NONE 0
  2123 +#define SENSE_NOT_READY 2
  2124 +#define SENSE_ILLEGAL_REQUEST 5
  2125 +#define SENSE_UNIT_ATTENTION 6
  2126 +
2017 2127 struct IDEState;
2018 2128  
2019 2129 typedef void EndTransferFunc(struct IDEState *);
2020 2130  
2021 2131 typedef struct IDEState {
2022 2132 /* ide config */
  2133 + int is_cdrom;
  2134 + int cdrom_locked;
2023 2135 int cylinders, heads, sectors;
2024 2136 int64_t nb_sectors;
2025 2137 int mult_sectors;
... ... @@ -2038,6 +2150,14 @@ typedef struct IDEState {
2038 2150 /* depends on bit 4 in select, only meaningful for drive 0 */
2039 2151 struct IDEState *cur_drive;
2040 2152 BlockDriverState *bs;
  2153 + /* ATAPI specific */
  2154 + uint8_t sense_key;
  2155 + uint8_t asc;
  2156 + int packet_transfer_size;
  2157 + int elementary_transfer_size;
  2158 + int io_buffer_index;
  2159 + int lba;
  2160 + /* transfer handling */
2041 2161 int req_nb_sectors; /* number of sectors per interrupt */
2042 2162 EndTransferFunc *end_transfer_func;
2043 2163 uint8_t *data_ptr;
... ... @@ -2046,6 +2166,12 @@ typedef struct IDEState {
2046 2166 } IDEState;
2047 2167  
2048 2168 IDEState ide_state[MAX_DISKS];
  2169 +IDEState *ide_table[0x400 >> 3];
  2170 +
  2171 +static inline IDEState *get_ide_interface(uint32_t addr)
  2172 +{
  2173 + return ide_table[addr >> 3];
  2174 +}
2049 2175  
2050 2176 static void padstr(char *str, const char *src, int len)
2051 2177 {
... ... @@ -2073,10 +2199,12 @@ static void ide_identify(IDEState *s)
2073 2199 stw_raw(p + 4, 512 * s->sectors); /* sectors */
2074 2200 stw_raw(p + 5, 512); /* sector size */
2075 2201 stw_raw(p + 6, s->sectors);
  2202 + padstr((uint8_t *)(p + 10), "QM00001", 20); /* serial number */
2076 2203 stw_raw(p + 20, 3); /* buffer type */
2077 2204 stw_raw(p + 21, 512); /* cache size in sectors */
2078 2205 stw_raw(p + 22, 4); /* ecc bytes */
2079   - padstr((uint8_t *)(p + 27), "QEMU HARDDISK", 40);
  2206 + padstr((uint8_t *)(p + 23), QEMU_VERSION, 8); /* firmware version */
  2207 + padstr((uint8_t *)(p + 27), "QEMU HARDDISK", 40); /* model */
2080 2208 #if MAX_MULT_SECTORS > 1
2081 2209 stw_raw(p + 47, MAX_MULT_SECTORS);
2082 2210 #endif
... ... @@ -2103,6 +2231,59 @@ static void ide_identify(IDEState *s)
2103 2231 stw_raw(p + 87, (1 << 14));
2104 2232 }
2105 2233  
  2234 +static void ide_atapi_identify(IDEState *s)
  2235 +{
  2236 + uint16_t *p;
  2237 +
  2238 + memset(s->io_buffer, 0, 512);
  2239 + p = (uint16_t *)s->io_buffer;
  2240 + /* Removable CDROM, 50us response, 12 byte packets */
  2241 + stw_raw(p + 0, (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0));
  2242 + stw_raw(p + 1, s->cylinders);
  2243 + stw_raw(p + 3, s->heads);
  2244 + stw_raw(p + 4, 512 * s->sectors); /* sectors */
  2245 + stw_raw(p + 5, 512); /* sector size */
  2246 + stw_raw(p + 6, s->sectors);
  2247 + padstr((uint8_t *)(p + 10), "QM00001", 20); /* serial number */
  2248 + stw_raw(p + 20, 3); /* buffer type */
  2249 + stw_raw(p + 21, 512); /* cache size in sectors */
  2250 + stw_raw(p + 22, 4); /* ecc bytes */
  2251 + padstr((uint8_t *)(p + 23), QEMU_VERSION, 8); /* firmware version */
  2252 + padstr((uint8_t *)(p + 27), "QEMU CD-ROM", 40); /* model */
  2253 + stw_raw(p + 48, 1); /* dword I/O (XXX: should not be set on CDROM) */
  2254 + stw_raw(p + 49, 1 << 9); /* LBA supported, no DMA */
  2255 + stw_raw(p + 53, 3); /* words 64-70, 54-58 valid */
  2256 + stw_raw(p + 63, 0x103); /* DMA modes XXX: may be incorrect */
  2257 + stw_raw(p + 64, 1); /* PIO modes */
  2258 + stw_raw(p + 65, 0xb4); /* minimum DMA multiword tx cycle time */
  2259 + stw_raw(p + 66, 0xb4); /* recommended DMA multiword tx cycle time */
  2260 + stw_raw(p + 67, 0x12c); /* minimum PIO cycle time without flow control */
  2261 + stw_raw(p + 68, 0xb4); /* minimum PIO cycle time with IORDY flow control */
  2262 +
  2263 + stw_raw(p + 71, 30); /* in ns */
  2264 + stw_raw(p + 72, 30); /* in ns */
  2265 +
  2266 + stw_raw(p + 80, 0x1e); /* support up to ATA/ATAPI-4 */
  2267 +}
  2268 +
  2269 +static void ide_set_signature(IDEState *s)
  2270 +{
  2271 + s->select &= 0xf0; /* clear head */
  2272 + /* put signature */
  2273 + s->nsector = 1;
  2274 + s->sector = 1;
  2275 + if (s->is_cdrom) {
  2276 + s->lcyl = 0x14;
  2277 + s->hcyl = 0xeb;
  2278 + } else if (s->bs) {
  2279 + s->lcyl = 0;
  2280 + s->hcyl = 0;
  2281 + } else {
  2282 + s->lcyl = 0xff;
  2283 + s->hcyl = 0xff;
  2284 + }
  2285 +}
  2286 +
2106 2287 static inline void ide_abort_command(IDEState *s)
2107 2288 {
2108 2289 s->status = READY_STAT | ERR_STAT;
... ... @@ -2111,18 +2292,18 @@ static inline void ide_abort_command(IDEState *s)
2111 2292  
2112 2293 static inline void ide_set_irq(IDEState *s)
2113 2294 {
2114   - if (!(ide_state[0].cmd & IDE_CMD_DISABLE_IRQ)) {
  2295 + if (!(s->cmd & IDE_CMD_DISABLE_IRQ)) {
2115 2296 pic_set_irq(s->irq, 1);
2116 2297 }
2117 2298 }
2118 2299  
2119 2300 /* prepare data transfer and tell what to do after */
2120   -static void ide_transfer_start(IDEState *s, int size,
  2301 +static void ide_transfer_start(IDEState *s, uint8_t *buf, int size,
2121 2302 EndTransferFunc *end_transfer_func)
2122 2303 {
2123 2304 s->end_transfer_func = end_transfer_func;
2124   - s->data_ptr = s->io_buffer;
2125   - s->data_end = s->io_buffer + size;
  2305 + s->data_ptr = buf;
  2306 + s->data_end = buf + size;
2126 2307 s->status |= DRQ_STAT;
2127 2308 }
2128 2309  
... ... @@ -2185,7 +2366,7 @@ static void ide_sector_read(IDEState *s)
2185 2366 if (n > s->req_nb_sectors)
2186 2367 n = s->req_nb_sectors;
2187 2368 ret = bdrv_read(s->bs, sector_num, s->io_buffer, n);
2188   - ide_transfer_start(s, 512 * n, ide_sector_read);
  2369 + ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_read);
2189 2370 ide_set_irq(s);
2190 2371 ide_set_sector(s, sector_num + n);
2191 2372 s->nsector -= n;
... ... @@ -2214,21 +2395,457 @@ static void ide_sector_write(IDEState *s)
2214 2395 n1 = s->nsector;
2215 2396 if (n1 > s->req_nb_sectors)
2216 2397 n1 = s->req_nb_sectors;
2217   - ide_transfer_start(s, 512 * n1, ide_sector_write);
  2398 + ide_transfer_start(s, s->io_buffer, 512 * n1, ide_sector_write);
2218 2399 }
2219 2400 ide_set_sector(s, sector_num + n);
2220 2401 ide_set_irq(s);
2221 2402 }
2222 2403  
  2404 +static void ide_atapi_cmd_ok(IDEState *s)
  2405 +{
  2406 + s->error = 0;
  2407 + s->status = READY_STAT;
  2408 + s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
  2409 + ide_set_irq(s);
  2410 +}
  2411 +
  2412 +static void ide_atapi_cmd_error(IDEState *s, int sense_key, int asc)
  2413 +{
  2414 +#ifdef DEBUG_IDE_ATAPI
  2415 + printf("atapi_cmd_error: sense=0x%x asc=0x%x\n", sense_key, asc);
  2416 +#endif
  2417 + s->error = sense_key << 4;
  2418 + s->status = READY_STAT | ERR_STAT;
  2419 + s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
  2420 + s->sense_key = sense_key;
  2421 + s->asc = asc;
  2422 + ide_set_irq(s);
  2423 +}
  2424 +
  2425 +static inline void cpu_to_ube16(uint8_t *buf, int val)
  2426 +{
  2427 + buf[0] = val >> 8;
  2428 + buf[1] = val;
  2429 +}
  2430 +
  2431 +static inline void cpu_to_ube32(uint8_t *buf, unsigned int val)
  2432 +{
  2433 + buf[0] = val >> 24;
  2434 + buf[1] = val >> 16;
  2435 + buf[2] = val >> 8;
  2436 + buf[3] = val;
  2437 +}
  2438 +
  2439 +static inline int ube16_to_cpu(const uint8_t *buf)
  2440 +{
  2441 + return (buf[0] << 8) | buf[1];
  2442 +}
  2443 +
  2444 +static inline int ube32_to_cpu(const uint8_t *buf)
  2445 +{
  2446 + return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
  2447 +}
  2448 +
  2449 +/* The whole ATAPI transfer logic is handled in this function */
  2450 +static void ide_atapi_cmd_reply_end(IDEState *s)
  2451 +{
  2452 + int byte_count_limit, size;
  2453 +#ifdef DEBUG_IDE_ATAPI
  2454 + printf("reply: tx_size=%d elem_tx_size=%d index=%d\n",
  2455 + s->packet_transfer_size,
  2456 + s->elementary_transfer_size,
  2457 + s->io_buffer_index);
  2458 +#endif
  2459 + if (s->packet_transfer_size <= 0) {
  2460 + /* end of transfer */
  2461 + ide_transfer_stop(s);
  2462 + s->status = READY_STAT;
  2463 + s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
  2464 + ide_set_irq(s);
  2465 +#ifdef DEBUG_IDE_ATAPI
  2466 + printf("status=0x%x\n", s->status);
  2467 +#endif
  2468 + } else {
  2469 + /* see if a new sector must be read */
  2470 + if (s->lba != -1 && s->io_buffer_index >= 2048) {
  2471 + bdrv_read(s->bs, (int64_t)s->lba << 2, s->io_buffer, 4);
  2472 + s->lba++;
  2473 + s->io_buffer_index = 0;
  2474 + }
  2475 + if (s->elementary_transfer_size > 0) {
  2476 + /* there are some data left to transmit in this elementary
  2477 + transfer */
  2478 + size = 2048 - s->io_buffer_index;
  2479 + if (size > s->elementary_transfer_size)
  2480 + size = s->elementary_transfer_size;
  2481 + ide_transfer_start(s, s->io_buffer + s->io_buffer_index,
  2482 + size, ide_atapi_cmd_reply_end);
  2483 + s->packet_transfer_size -= size;
  2484 + s->elementary_transfer_size -= size;
  2485 + s->io_buffer_index += size;
  2486 + } else {
  2487 + /* a new transfer is needed */
  2488 + s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO;
  2489 + byte_count_limit = s->lcyl | (s->hcyl << 8);
  2490 +#ifdef DEBUG_IDE_ATAPI
  2491 + printf("byte_count_limit=%d\n", byte_count_limit);
  2492 +#endif
  2493 + if (byte_count_limit == 0xffff)
  2494 + byte_count_limit--;
  2495 + size = s->packet_transfer_size;
  2496 + if (size > byte_count_limit) {
  2497 + /* byte count limit must be even if this case */
  2498 + if (byte_count_limit & 1)
  2499 + byte_count_limit--;
  2500 + size = byte_count_limit;
  2501 + } else {
  2502 + s->lcyl = size;
  2503 + s->hcyl = size >> 8;
  2504 + }
  2505 + s->elementary_transfer_size = size;
  2506 + /* we cannot transmit more than one sector at a time */
  2507 + if (s->lba != -1) {
  2508 + if (size > (2048 - s->io_buffer_index))
  2509 + size = (2048 - s->io_buffer_index);
  2510 + }
  2511 + ide_transfer_start(s, s->io_buffer + s->io_buffer_index,
  2512 + size, ide_atapi_cmd_reply_end);
  2513 + s->packet_transfer_size -= size;
  2514 + s->elementary_transfer_size -= size;
  2515 + s->io_buffer_index += size;
  2516 + ide_set_irq(s);
  2517 +#ifdef DEBUG_IDE_ATAPI
  2518 + printf("status=0x%x\n", s->status);
  2519 +#endif
  2520 + }
  2521 + }
  2522 +}
  2523 +
  2524 +/* send a reply of 'size' bytes in s->io_buffer to an ATAPI command */
  2525 +static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size)
  2526 +{
  2527 + if (size > max_size)
  2528 + size = max_size;
  2529 + s->lba = -1; /* no sector read */
  2530 + s->packet_transfer_size = size;
  2531 + s->elementary_transfer_size = 0;
  2532 + s->io_buffer_index = 0;
  2533 +
  2534 + s->status = READY_STAT;
  2535 + ide_atapi_cmd_reply_end(s);
  2536 +}
  2537 +
  2538 +/* start a CD-CDROM read command */
  2539 +static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors)
  2540 +{
  2541 +#ifdef DEBUG_IDE_ATAPI
  2542 + printf("read: LBA=%d nb_sectors=%d\n", lba, nb_sectors);
  2543 +#endif
  2544 + s->lba = lba;
  2545 + s->packet_transfer_size = nb_sectors * 2048;
  2546 + s->elementary_transfer_size = 0;
  2547 + s->io_buffer_index = 2048;
  2548 +
  2549 + s->status = READY_STAT;
  2550 + ide_atapi_cmd_reply_end(s);
  2551 +}
  2552 +
  2553 +/* same toc as bochs. Return -1 if error or the toc length */
  2554 +static int cdrom_read_toc(IDEState *s, uint8_t *buf, int msf, int start_track)
  2555 +{
  2556 + uint8_t *q;
  2557 + int nb_sectors, len;
  2558 +
  2559 + if (start_track > 1 && start_track != 0xaa)
  2560 + return -1;
  2561 + q = buf + 2;
  2562 + *q++ = 1;
  2563 + *q++ = 1;
  2564 + if (start_track <= 1) {
  2565 + *q++ = 0; /* reserved */
  2566 + *q++ = 0x14; /* ADR, control */
  2567 + *q++ = 1; /* track number */
  2568 + *q++ = 0; /* reserved */
  2569 + if (msf) {
  2570 + *q++ = 0; /* reserved */
  2571 + *q++ = 0; /* minute */
  2572 + *q++ = 2; /* second */
  2573 + *q++ = 0; /* frame */
  2574 + } else {
  2575 + /* sector 0 */
  2576 + cpu_to_ube32(q, 0);
  2577 + q += 4;
  2578 + }
  2579 + }
  2580 + /* lead out track */
  2581 + *q++ = 0; /* reserved */
  2582 + *q++ = 0x16; /* ADR, control */
  2583 + *q++ = 0xaa; /* track number */
  2584 + *q++ = 0; /* reserved */
  2585 + nb_sectors = s->nb_sectors >> 2;
  2586 + if (msf) {
  2587 + *q++ = 0; /* reserved */
  2588 + *q++ = ((nb_sectors + 150) / 75) / 60;
  2589 + *q++ = ((nb_sectors + 150) / 75) % 60;
  2590 + *q++ = (nb_sectors + 150) % 75;
  2591 + } else {
  2592 + cpu_to_ube32(q, nb_sectors);
  2593 + q += 4;
  2594 + }
  2595 + len = q - buf;
  2596 + cpu_to_ube16(buf, len - 2);
  2597 + return len;
  2598 +}
  2599 +
  2600 +static void ide_atapi_cmd(IDEState *s)
  2601 +{
  2602 + const uint8_t *packet;
  2603 + uint8_t *buf;
  2604 + int max_len;
  2605 +
  2606 + packet = s->io_buffer;
  2607 + buf = s->io_buffer;
  2608 +#ifdef DEBUG_IDE_ATAPI
  2609 + {
  2610 + int i;
  2611 + printf("ATAPI limit=0x%x packet:", s->lcyl | (s->hcyl << 8));
  2612 + for(i = 0; i < ATAPI_PACKET_SIZE; i++) {
  2613 + printf(" %02x", packet[i]);
  2614 + }
  2615 + printf("\n");
  2616 + }
  2617 +#endif
  2618 + switch(s->io_buffer[0]) {
  2619 + case GPCMD_TEST_UNIT_READY:
  2620 + if (s->bs) {
  2621 + ide_atapi_cmd_ok(s);
  2622 + } else {
  2623 + ide_atapi_cmd_error(s, SENSE_NOT_READY,
  2624 + ASC_MEDIUM_NOT_PRESENT);
  2625 + }
  2626 + break;
  2627 + case GPCMD_MODE_SENSE_10:
  2628 + {
  2629 + int action, code;
  2630 + max_len = ube16_to_cpu(packet + 7);
  2631 + action = packet[2] >> 6;
  2632 + code = packet[2] & 0x3f;
  2633 + switch(action) {
  2634 + case 0: /* current values */
  2635 + switch(code) {
  2636 + case 0x01: /* error recovery */
  2637 + cpu_to_ube16(&buf[0], 16 + 6);
  2638 + buf[2] = 0x70;
  2639 + buf[3] = 0;
  2640 + buf[4] = 0;
  2641 + buf[5] = 0;
  2642 + buf[6] = 0;
  2643 + buf[7] = 0;
  2644 +
  2645 + buf[8] = 0x01;
  2646 + buf[9] = 0x06;
  2647 + buf[10] = 0x00;
  2648 + buf[11] = 0x05;
  2649 + buf[12] = 0x00;
  2650 + buf[13] = 0x00;
  2651 + buf[14] = 0x00;
  2652 + buf[15] = 0x00;
  2653 + ide_atapi_cmd_reply(s, 16, max_len);
  2654 + break;
  2655 + case 0x2a:
  2656 + cpu_to_ube16(&buf[0], 28 + 6);
  2657 + buf[2] = 0x70;
  2658 + buf[3] = 0;
  2659 + buf[4] = 0;
  2660 + buf[5] = 0;
  2661 + buf[6] = 0;
  2662 + buf[7] = 0;
  2663 +
  2664 + buf[8] = 0x2a;
  2665 + buf[9] = 0x12;
  2666 + buf[10] = 0x00;
  2667 + buf[11] = 0x00;
  2668 +
  2669 + buf[12] = 0x70;
  2670 + buf[13] = 3 << 5;
  2671 + buf[14] = (1 << 0) | (1 << 3) | (1 << 5);
  2672 + if (s->cdrom_locked)
  2673 + buf[6] |= 1 << 1;
  2674 + buf[15] = 0x00;
  2675 + cpu_to_ube16(&buf[16], 706);
  2676 + buf[18] = 0;
  2677 + buf[19] = 2;
  2678 + cpu_to_ube16(&buf[20], 512);
  2679 + cpu_to_ube16(&buf[22], 706);
  2680 + buf[24] = 0;
  2681 + buf[25] = 0;
  2682 + buf[26] = 0;
  2683 + buf[27] = 0;
  2684 + ide_atapi_cmd_reply(s, 28, max_len);
  2685 + break;
  2686 + default:
  2687 + goto error_cmd;
  2688 + }
  2689 + break;
  2690 + case 1: /* changeable values */
  2691 + goto error_cmd;
  2692 + case 2: /* default values */
  2693 + goto error_cmd;
  2694 + default:
  2695 + case 3: /* saved values */
  2696 + ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
  2697 + ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
  2698 + break;
  2699 + }
  2700 + }
  2701 + break;
  2702 + case GPCMD_REQUEST_SENSE:
  2703 + max_len = packet[4];
  2704 + memset(buf, 0, 18);
  2705 + buf[0] = 0x70 | (1 << 7);
  2706 + buf[2] = s->sense_key;
  2707 + buf[7] = 10;
  2708 + buf[12] = s->asc;
  2709 + ide_atapi_cmd_reply(s, 18, max_len);
  2710 + break;
  2711 + case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
  2712 + if (s->bs) {
  2713 + s->cdrom_locked = packet[4] & 1;
  2714 + ide_atapi_cmd_ok(s);
  2715 + } else {
  2716 + ide_atapi_cmd_error(s, SENSE_NOT_READY,
  2717 + ASC_MEDIUM_NOT_PRESENT);
  2718 + }
  2719 + break;
  2720 + case GPCMD_READ_10:
  2721 + case GPCMD_READ_12:
  2722 + {
  2723 + int nb_sectors, lba;
  2724 +
  2725 + if (!s->bs) {
  2726 + ide_atapi_cmd_error(s, SENSE_NOT_READY,
  2727 + ASC_MEDIUM_NOT_PRESENT);
  2728 + break;
  2729 + }
  2730 + if (packet[0] == GPCMD_READ_10)
  2731 + nb_sectors = ube16_to_cpu(packet + 7);
  2732 + else
  2733 + nb_sectors = ube32_to_cpu(packet + 6);
  2734 + lba = ube32_to_cpu(packet + 2);
  2735 + if (nb_sectors == 0) {
  2736 + ide_atapi_cmd_ok(s);
  2737 + break;
  2738 + }
  2739 + if (((int64_t)(lba + nb_sectors) << 2) > s->nb_sectors) {
  2740 + ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
  2741 + ASC_LOGICAL_BLOCK_OOR);
  2742 + break;
  2743 + }
  2744 + ide_atapi_cmd_read(s, lba, nb_sectors);
  2745 + }
  2746 + break;
  2747 + case GPCMD_SEEK:
  2748 + {
  2749 + int lba;
  2750 + if (!s->bs) {
  2751 + ide_atapi_cmd_error(s, SENSE_NOT_READY,
  2752 + ASC_MEDIUM_NOT_PRESENT);
  2753 + break;
  2754 + }
  2755 + lba = ube32_to_cpu(packet + 2);
  2756 + if (((int64_t)lba << 2) > s->nb_sectors) {
  2757 + ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
  2758 + ASC_LOGICAL_BLOCK_OOR);
  2759 + break;
  2760 + }
  2761 + ide_atapi_cmd_ok(s);
  2762 + }
  2763 + break;
  2764 + case GPCMD_START_STOP_UNIT:
  2765 + {
  2766 + int start, eject;
  2767 + start = packet[4] & 1;
  2768 + eject = (packet[4] >> 1) & 1;
  2769 +
  2770 + /* XXX: currently none implemented */
  2771 + ide_atapi_cmd_ok(s);
  2772 + }
  2773 + break;
  2774 + case GPCMD_MECHANISM_STATUS:
  2775 + {
  2776 + max_len = ube16_to_cpu(packet + 8);
  2777 + cpu_to_ube16(buf, 0);
  2778 + /* no current LBA */
  2779 + buf[2] = 0;
  2780 + buf[3] = 0;
  2781 + buf[4] = 0;
  2782 + buf[5] = 1;
  2783 + cpu_to_ube16(buf + 6, 0);
  2784 + ide_atapi_cmd_reply(s, 8, max_len);
  2785 + }
  2786 + break;
  2787 + case GPCMD_READ_TOC_PMA_ATIP:
  2788 + {
  2789 + int format, msf, start_track, len;
  2790 +
  2791 + if (!s->bs) {
  2792 + ide_atapi_cmd_error(s, SENSE_NOT_READY,
  2793 + ASC_MEDIUM_NOT_PRESENT);
  2794 + break;
  2795 + }
  2796 + max_len = ube16_to_cpu(packet + 7);
  2797 + format = packet[9] >> 6;
  2798 + msf = (packet[1] >> 1) & 1;
  2799 + start_track = packet[6];
  2800 + switch(format) {
  2801 + case 0:
  2802 + len = cdrom_read_toc(s, buf, msf, start_track);
  2803 + if (len < 0)
  2804 + goto error_cmd;
  2805 + ide_atapi_cmd_reply(s, len, max_len);
  2806 + break;
  2807 + case 1:
  2808 + /* multi session : only a single session defined */
  2809 + memset(buf, 0, 12);
  2810 + buf[1] = 0x0a;
  2811 + buf[2] = 0x01;
  2812 + buf[3] = 0x01;
  2813 + ide_atapi_cmd_reply(s, 12, max_len);
  2814 + break;
  2815 + default:
  2816 + goto error_cmd;
  2817 + }
  2818 + }
  2819 + break;
  2820 + case GPCMD_READ_CDVD_CAPACITY:
  2821 + if (!s->bs) {
  2822 + ide_atapi_cmd_error(s, SENSE_NOT_READY,
  2823 + ASC_MEDIUM_NOT_PRESENT);
  2824 + break;
  2825 + }
  2826 + /* NOTE: it is really the number of sectors minus 1 */
  2827 + cpu_to_ube32(buf, (s->nb_sectors >> 2) - 1);
  2828 + cpu_to_ube32(buf + 4, 2048);
  2829 + ide_atapi_cmd_reply(s, 8, 8);
  2830 + break;
  2831 + default:
  2832 + error_cmd:
  2833 + ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
  2834 + ASC_INV_FIELD_IN_CMD_PACKET);
  2835 + break;
  2836 + }
  2837 +}
  2838 +
2223 2839 void ide_ioport_write(CPUX86State *env, uint32_t addr, uint32_t val)
2224 2840 {
2225   - IDEState *s = ide_state[0].cur_drive;
  2841 + IDEState *ide_if = get_ide_interface(addr);
  2842 + IDEState *s = ide_if->cur_drive;
2226 2843 int unit, n;
2227 2844  
2228   - addr &= 7;
2229 2845 #ifdef DEBUG_IDE
2230 2846 printf("IDE: write addr=0x%x val=0x%02x\n", addr, val);
2231 2847 #endif
  2848 + addr &= 7;
2232 2849 switch(addr) {
2233 2850 case 0:
2234 2851 break;
... ... @@ -2252,8 +2869,8 @@ void ide_ioport_write(CPUX86State *env, uint32_t addr, uint32_t val)
2252 2869 case 6:
2253 2870 /* select drive */
2254 2871 unit = (val >> 4) & 1;
2255   - s = &ide_state[unit];
2256   - ide_state[0].cur_drive = s;
  2872 + s = ide_if + unit;
  2873 + ide_if->cur_drive = s;
2257 2874 s->select = val;
2258 2875 break;
2259 2876 default:
... ... @@ -2263,13 +2880,15 @@ void ide_ioport_write(CPUX86State *env, uint32_t addr, uint32_t val)
2263 2880 printf("ide: CMD=%02x\n", val);
2264 2881 #endif
2265 2882 switch(val) {
2266   - case WIN_PIDENTIFY:
2267 2883 case WIN_IDENTIFY:
2268   - if (s->bs) {
  2884 + if (s->bs && !s->is_cdrom) {
2269 2885 ide_identify(s);
2270 2886 s->status = READY_STAT;
2271   - ide_transfer_start(s, 512, ide_transfer_stop);
  2887 + ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
2272 2888 } else {
  2889 + if (s->is_cdrom) {
  2890 + ide_set_signature(s);
  2891 + }
2273 2892 ide_abort_command(s);
2274 2893 }
2275 2894 ide_set_irq(s);
... ... @@ -2299,7 +2918,7 @@ void ide_ioport_write(CPUX86State *env, uint32_t addr, uint32_t val)
2299 2918 case WIN_WRITE_ONCE:
2300 2919 s->status = SEEK_STAT;
2301 2920 s->req_nb_sectors = 1;
2302   - ide_transfer_start(s, 512, ide_sector_write);
  2921 + ide_transfer_start(s, s->io_buffer, 512, ide_sector_write);
2303 2922 break;
2304 2923 case WIN_MULTREAD:
2305 2924 if (!s->mult_sectors)
... ... @@ -2315,13 +2934,42 @@ void ide_ioport_write(CPUX86State *env, uint32_t addr, uint32_t val)
2315 2934 n = s->nsector;
2316 2935 if (n > s->req_nb_sectors)
2317 2936 n = s->req_nb_sectors;
2318   - ide_transfer_start(s, 512 * n, ide_sector_write);
  2937 + ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
2319 2938 break;
2320 2939 case WIN_READ_NATIVE_MAX:
2321 2940 ide_set_sector(s, s->nb_sectors - 1);
2322 2941 s->status = READY_STAT;
2323 2942 ide_set_irq(s);
2324 2943 break;
  2944 +
  2945 + /* ATAPI commands */
  2946 + case WIN_PIDENTIFY:
  2947 + if (s->is_cdrom) {
  2948 + ide_atapi_identify(s);
  2949 + s->status = READY_STAT;
  2950 + ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
  2951 + } else {
  2952 + ide_abort_command(s);
  2953 + }
  2954 + ide_set_irq(s);
  2955 + break;
  2956 + case WIN_SRST:
  2957 + if (!s->is_cdrom)
  2958 + goto abort_cmd;
  2959 + ide_set_signature(s);
  2960 + s->status = READY_STAT;
  2961 + s->error = 0x01;
  2962 + break;
  2963 + case WIN_PACKETCMD:
  2964 + if (!s->is_cdrom)
  2965 + goto abort_cmd;
  2966 + /* DMA or overlapping commands not supported */
  2967 + if ((s->feature & 0x03) != 0)
  2968 + goto abort_cmd;
  2969 + s->nsector = 1;
  2970 + ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE,
  2971 + ide_atapi_cmd);
  2972 + break;
2325 2973 default:
2326 2974 abort_cmd:
2327 2975 ide_abort_command(s);
... ... @@ -2331,12 +2979,13 @@ void ide_ioport_write(CPUX86State *env, uint32_t addr, uint32_t val)
2331 2979 }
2332 2980 }
2333 2981  
2334   -uint32_t ide_ioport_read(CPUX86State *env, uint32_t addr)
  2982 +uint32_t ide_ioport_read(CPUX86State *env, uint32_t addr1)
2335 2983 {
2336   - IDEState *s = ide_state[0].cur_drive;
  2984 + IDEState *s = get_ide_interface(addr1)->cur_drive;
  2985 + uint32_t addr;
2337 2986 int ret;
2338 2987  
2339   - addr &= 7;
  2988 + addr = addr1 & 7;
2340 2989 switch(addr) {
2341 2990 case 0:
2342 2991 ret = 0xff;
... ... @@ -2366,66 +3015,57 @@ uint32_t ide_ioport_read(CPUX86State *env, uint32_t addr)
2366 3015 break;
2367 3016 }
2368 3017 #ifdef DEBUG_IDE
2369   - printf("ide: read addr=0x%x val=%02x\n", addr, ret);
  3018 + printf("ide: read addr=0x%x val=%02x\n", addr1, ret);
2370 3019 #endif
2371 3020 return ret;
2372 3021 }
2373 3022  
2374 3023 uint32_t ide_status_read(CPUX86State *env, uint32_t addr)
2375 3024 {
2376   - IDEState *s = ide_state[0].cur_drive;
  3025 + IDEState *s = get_ide_interface(addr)->cur_drive;
2377 3026 int ret;
2378 3027 ret = s->status;
2379 3028 #ifdef DEBUG_IDE
2380   - printf("ide: read status val=%02x\n", ret);
  3029 + printf("ide: read status addr=0x%x val=%02x\n", addr, ret);
2381 3030 #endif
2382 3031 return ret;
2383 3032 }
2384 3033  
2385 3034 void ide_cmd_write(CPUX86State *env, uint32_t addr, uint32_t val)
2386 3035 {
  3036 + IDEState *ide_if = get_ide_interface(addr);
2387 3037 IDEState *s;
2388 3038 int i;
2389 3039  
2390 3040 #ifdef DEBUG_IDE
2391   - printf("ide: write control val=%02x\n", val);
  3041 + printf("ide: write control addr=0x%x val=%02x\n", addr, val);
2392 3042 #endif
2393 3043 /* common for both drives */
2394   - if (!(ide_state[0].cmd & IDE_CMD_RESET) &&
  3044 + if (!(ide_if[0].cmd & IDE_CMD_RESET) &&
2395 3045 (val & IDE_CMD_RESET)) {
2396 3046 /* reset low to high */
2397 3047 for(i = 0;i < 2; i++) {
2398   - s = &ide_state[i];
  3048 + s = &ide_if[i];
2399 3049 s->status = BUSY_STAT | SEEK_STAT;
2400 3050 s->error = 0x01;
2401 3051 }
2402   - } else if ((ide_state[0].cmd & IDE_CMD_RESET) &&
  3052 + } else if ((ide_if[0].cmd & IDE_CMD_RESET) &&
2403 3053 !(val & IDE_CMD_RESET)) {
2404 3054 /* high to low */
2405 3055 for(i = 0;i < 2; i++) {
2406   - s = &ide_state[i];
  3056 + s = &ide_if[i];
2407 3057 s->status = READY_STAT;
2408   - /* set hard disk drive ID */
2409   - s->select &= 0xf0; /* clear head */
2410   - s->nsector = 1;
2411   - s->sector = 1;
2412   - if (s->nb_sectors == 0) {
2413   - /* no disk present */
2414   - s->lcyl = 0x12;
2415   - s->hcyl = 0x34;
2416   - } else {
2417   - s->lcyl = 0;
2418   - s->hcyl = 0;
2419   - }
  3058 + ide_set_signature(s);
2420 3059 }
2421 3060 }
2422 3061  
2423   - ide_state[0].cmd = val;
  3062 + ide_if[0].cmd = val;
  3063 + ide_if[1].cmd = val;
2424 3064 }
2425 3065  
2426 3066 void ide_data_writew(CPUX86State *env, uint32_t addr, uint32_t val)
2427 3067 {
2428   - IDEState *s = ide_state[0].cur_drive;
  3068 + IDEState *s = get_ide_interface(addr)->cur_drive;
2429 3069 uint8_t *p;
2430 3070  
2431 3071 p = s->data_ptr;
... ... @@ -2438,10 +3078,9 @@ void ide_data_writew(CPUX86State *env, uint32_t addr, uint32_t val)
2438 3078  
2439 3079 uint32_t ide_data_readw(CPUX86State *env, uint32_t addr)
2440 3080 {
2441   - IDEState *s = ide_state[0].cur_drive;
  3081 + IDEState *s = get_ide_interface(addr)->cur_drive;
2442 3082 uint8_t *p;
2443 3083 int ret;
2444   -
2445 3084 p = s->data_ptr;
2446 3085 ret = tswap16(*(uint16_t *)p);
2447 3086 p += 2;
... ... @@ -2453,7 +3092,7 @@ uint32_t ide_data_readw(CPUX86State *env, uint32_t addr)
2453 3092  
2454 3093 void ide_data_writel(CPUX86State *env, uint32_t addr, uint32_t val)
2455 3094 {
2456   - IDEState *s = ide_state[0].cur_drive;
  3095 + IDEState *s = get_ide_interface(addr)->cur_drive;
2457 3096 uint8_t *p;
2458 3097  
2459 3098 p = s->data_ptr;
... ... @@ -2466,7 +3105,7 @@ void ide_data_writel(CPUX86State *env, uint32_t addr, uint32_t val)
2466 3105  
2467 3106 uint32_t ide_data_readl(CPUX86State *env, uint32_t addr)
2468 3107 {
2469   - IDEState *s = ide_state[0].cur_drive;
  3108 + IDEState *s = get_ide_interface(addr)->cur_drive;
2470 3109 uint8_t *p;
2471 3110 int ret;
2472 3111  
... ... @@ -2482,9 +3121,10 @@ uint32_t ide_data_readl(CPUX86State *env, uint32_t addr)
2482 3121 void ide_reset(IDEState *s)
2483 3122 {
2484 3123 s->mult_sectors = MAX_MULT_SECTORS;
2485   - s->status = READY_STAT;
2486 3124 s->cur_drive = s;
2487 3125 s->select = 0xa0;
  3126 + s->status = READY_STAT;
  3127 + ide_set_signature(s);
2488 3128 }
2489 3129  
2490 3130 struct partition {
... ... @@ -2536,8 +3176,11 @@ void ide_guess_geometry(IDEState *s)
2536 3176 void ide_init(void)
2537 3177 {
2538 3178 IDEState *s;
2539   - int i, cylinders;
  3179 + int i, cylinders, iobase, iobase2;
2540 3180 int64_t nb_sectors;
  3181 + static const int ide_iobase[2] = { 0x1f0, 0x170 };
  3182 + static const int ide_iobase2[2] = { 0x3f6, 0x376 };
  3183 + static const int ide_irq[2] = { 14, 15 };
2541 3184  
2542 3185 for(i = 0; i < MAX_DISKS; i++) {
2543 3186 s = &ide_state[i];
... ... @@ -2558,19 +3201,26 @@ void ide_init(void)
2558 3201 s->sectors = 63;
2559 3202 }
2560 3203 }
2561   - s->irq = 14;
  3204 + s->irq = ide_irq[i >> 1];
2562 3205 ide_reset(s);
2563 3206 }
2564   - register_ioport_write(0x1f0, 8, ide_ioport_write, 1);
2565   - register_ioport_read(0x1f0, 8, ide_ioport_read, 1);
2566   - register_ioport_read(0x3f6, 1, ide_status_read, 1);
2567   - register_ioport_write(0x3f6, 1, ide_cmd_write, 1);
2568   -
2569   - /* data ports */
2570   - register_ioport_write(0x1f0, 2, ide_data_writew, 2);
2571   - register_ioport_read(0x1f0, 2, ide_data_readw, 2);
2572   - register_ioport_write(0x1f0, 4, ide_data_writel, 4);
2573   - register_ioport_read(0x1f0, 4, ide_data_readl, 4);
  3207 + for(i = 0; i < (MAX_DISKS / 2); i++) {
  3208 + iobase = ide_iobase[i];
  3209 + iobase2 = ide_iobase2[i];
  3210 + ide_table[iobase >> 3] = &ide_state[2 * i];
  3211 + if (ide_iobase2[i])
  3212 + ide_table[iobase2 >> 3] = &ide_state[2 * i];
  3213 + register_ioport_write(iobase, 8, ide_ioport_write, 1);
  3214 + register_ioport_read(iobase, 8, ide_ioport_read, 1);
  3215 + register_ioport_read(iobase2, 1, ide_status_read, 1);
  3216 + register_ioport_write(iobase2, 1, ide_cmd_write, 1);
  3217 +
  3218 + /* data ports */
  3219 + register_ioport_write(iobase, 2, ide_data_writew, 2);
  3220 + register_ioport_read(iobase, 2, ide_data_readw, 2);
  3221 + register_ioport_write(iobase, 4, ide_data_writel, 4);
  3222 + register_ioport_read(iobase, 4, ide_data_readl, 4);
  3223 + }
2574 3224 }
2575 3225  
2576 3226 /***********************************************************/
... ... @@ -2811,7 +3461,7 @@ void kbd_write_command(CPUX86State *env, uint32_t addr, uint32_t val)
2811 3461 cpu_x86_interrupt(global_env, CPU_INTERRUPT_EXIT);
2812 3462 break;
2813 3463 default:
2814   - fprintf(stderr, "vl: unsupported keyboard cmd=0x%02x\n", val);
  3464 + fprintf(stderr, "qemu: unsupported keyboard cmd=0x%02x\n", val);
2815 3465 break;
2816 3466 }
2817 3467 }
... ... @@ -3458,8 +4108,10 @@ void help(void)
3458 4108 "'disk_image' is a raw hard image image for IDE hard disk 0\n"
3459 4109 "\n"
3460 4110 "Standard options:\n"
3461   - "-hda file use 'file' as IDE hard disk 0 image\n"
3462   - "-hdb file use 'file' as IDE hard disk 1 image\n"
  4111 + "-hda/-hdb file use 'file' as IDE hard disk 0/1 image\n"
  4112 + "-hdc/-hdd file use 'file' as IDE hard disk 2/3 image\n"
  4113 + "-cdrom file use 'file' as IDE cdrom 2 image\n"
  4114 + "-boot [c|d] boot on hard disk or CD-ROM\n"
3463 4115 "-snapshot write to temporary files instead of disk image files\n"
3464 4116 "-m megs set virtual RAM size to megs MB\n"
3465 4117 "-n script set network init script [default=%s]\n"
... ... @@ -3506,6 +4158,10 @@ struct option long_options[] = {
3506 4158 { "kernel", 1, NULL, 0, },
3507 4159 { "append", 1, NULL, 0, },
3508 4160 { "tun-fd", 1, NULL, 0, },
  4161 + { "hdc", 1, NULL, 0, },
  4162 + { "hdd", 1, NULL, 0, },
  4163 + { "cdrom", 1, NULL, 0, },
  4164 + { "boot", 1, NULL, 0, },
3509 4165 { NULL, 0, NULL, 0 },
3510 4166 };
3511 4167  
... ... @@ -3601,6 +4257,23 @@ int main(int argc, char **argv)
3601 4257 case 8:
3602 4258 net_fd = atoi(optarg);
3603 4259 break;
  4260 + case 9:
  4261 + hd_filename[2] = optarg;
  4262 + break;
  4263 + case 10:
  4264 + hd_filename[3] = optarg;
  4265 + break;
  4266 + case 11:
  4267 + hd_filename[2] = optarg;
  4268 + ide_state[2].is_cdrom = 1;
  4269 + break;
  4270 + case 12:
  4271 + boot_device = optarg[0];
  4272 + if (boot_device != 'c' && boot_device != 'd') {
  4273 + fprintf(stderr, "qemu: invalid boot device '%c'\n", boot_device);
  4274 + exit(1);
  4275 + }
  4276 + break;
3604 4277 }
3605 4278 break;
3606 4279 case 'h':
... ... @@ -3611,7 +4284,7 @@ int main(int argc, char **argv)
3611 4284 if (phys_ram_size <= 0)
3612 4285 help();
3613 4286 if (phys_ram_size > PHYS_RAM_MAX_SIZE) {
3614   - fprintf(stderr, "vl: at most %d MB RAM can be simulated\n",
  4287 + fprintf(stderr, "qemu: at most %d MB RAM can be simulated\n",
3615 4288 PHYS_RAM_MAX_SIZE / (1024 * 1024));
3616 4289 exit(1);
3617 4290 }
... ... @@ -3640,7 +4313,7 @@ int main(int argc, char **argv)
3640 4313  
3641 4314 linux_boot = (kernel_filename != NULL);
3642 4315  
3643   - if (!linux_boot && hd_filename[0] == '\0')
  4316 + if (!linux_boot && hd_filename[0] == '\0' && hd_filename[2] == '\0')
3644 4317 help();
3645 4318  
3646 4319 /* init debug */
... ... @@ -3698,7 +4371,7 @@ int main(int argc, char **argv)
3698 4371 if (hd_filename[i]) {
3699 4372 bs_table[i] = bdrv_open(hd_filename[i], snapshot);
3700 4373 if (!bs_table[i]) {
3701   - fprintf(stderr, "vl: could not open hard disk image '%s\n",
  4374 + fprintf(stderr, "qemu: could not open hard disk image '%s\n",
3702 4375 hd_filename[i]);
3703 4376 exit(1);
3704 4377 }
... ... @@ -3719,7 +4392,7 @@ int main(int argc, char **argv)
3719 4392 /* now we can load the kernel */
3720 4393 ret = load_kernel(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
3721 4394 if (ret < 0) {
3722   - fprintf(stderr, "vl: could not load kernel '%s'\n",
  4395 + fprintf(stderr, "qemu: could not load kernel '%s'\n",
3723 4396 kernel_filename);
3724 4397 exit(1);
3725 4398 }
... ... @@ -3729,7 +4402,7 @@ int main(int argc, char **argv)
3729 4402 if (initrd_filename) {
3730 4403 initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
3731 4404 if (initrd_size < 0) {
3732   - fprintf(stderr, "vl: could not load initial ram disk '%s'\n",
  4405 + fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
3733 4406 initrd_filename);
3734 4407 exit(1);
3735 4408 }
... ... @@ -3788,7 +4461,7 @@ int main(int argc, char **argv)
3788 4461 snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
3789 4462 ret = load_image(buf, phys_ram_base + 0x000f0000);
3790 4463 if (ret != 0x10000) {
3791   - fprintf(stderr, "vl: could not load PC bios '%s'\n", buf);
  4464 + fprintf(stderr, "qemu: could not load PC bios '%s'\n", buf);
3792 4465 exit(1);
3793 4466 }
3794 4467  
... ...