Statistics
| Branch: | Revision:

root / hw / ide.c @ 09b26c5e

History | View | Annotate | Download (74.9 kB)

1 5391d806 bellard
/*
2 5391d806 bellard
 * QEMU IDE disk and CD-ROM Emulator
3 5391d806 bellard
 * 
4 5391d806 bellard
 * Copyright (c) 2003 Fabrice Bellard
5 5391d806 bellard
 * 
6 5391d806 bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 5391d806 bellard
 * of this software and associated documentation files (the "Software"), to deal
8 5391d806 bellard
 * in the Software without restriction, including without limitation the rights
9 5391d806 bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 5391d806 bellard
 * copies of the Software, and to permit persons to whom the Software is
11 5391d806 bellard
 * furnished to do so, subject to the following conditions:
12 5391d806 bellard
 *
13 5391d806 bellard
 * The above copyright notice and this permission notice shall be included in
14 5391d806 bellard
 * all copies or substantial portions of the Software.
15 5391d806 bellard
 *
16 5391d806 bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 5391d806 bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 5391d806 bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 5391d806 bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 5391d806 bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 5391d806 bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 5391d806 bellard
 * THE SOFTWARE.
23 5391d806 bellard
 */
24 5391d806 bellard
#include "vl.h"
25 5391d806 bellard
26 5391d806 bellard
/* debug IDE devices */
27 5391d806 bellard
//#define DEBUG_IDE
28 5391d806 bellard
//#define DEBUG_IDE_ATAPI
29 5391d806 bellard
30 5391d806 bellard
/* Bits of HD_STATUS */
31 5391d806 bellard
#define ERR_STAT                0x01
32 5391d806 bellard
#define INDEX_STAT                0x02
33 5391d806 bellard
#define ECC_STAT                0x04        /* Corrected error */
34 5391d806 bellard
#define DRQ_STAT                0x08
35 5391d806 bellard
#define SEEK_STAT                0x10
36 5391d806 bellard
#define SRV_STAT                0x10
37 5391d806 bellard
#define WRERR_STAT                0x20
38 5391d806 bellard
#define READY_STAT                0x40
39 5391d806 bellard
#define BUSY_STAT                0x80
40 5391d806 bellard
41 5391d806 bellard
/* Bits for HD_ERROR */
42 5391d806 bellard
#define MARK_ERR                0x01        /* Bad address mark */
43 5391d806 bellard
#define TRK0_ERR                0x02        /* couldn't find track 0 */
44 5391d806 bellard
#define ABRT_ERR                0x04        /* Command aborted */
45 5391d806 bellard
#define MCR_ERR                        0x08        /* media change request */
46 5391d806 bellard
#define ID_ERR                        0x10        /* ID field not found */
47 5391d806 bellard
#define MC_ERR                        0x20        /* media changed */
48 5391d806 bellard
#define ECC_ERR                        0x40        /* Uncorrectable ECC error */
49 5391d806 bellard
#define BBD_ERR                        0x80        /* pre-EIDE meaning:  block marked bad */
50 5391d806 bellard
#define ICRC_ERR                0x80        /* new meaning:  CRC error during transfer */
51 5391d806 bellard
52 5391d806 bellard
/* Bits of HD_NSECTOR */
53 5391d806 bellard
#define CD                        0x01
54 5391d806 bellard
#define IO                        0x02
55 5391d806 bellard
#define REL                        0x04
56 5391d806 bellard
#define TAG_MASK                0xf8
57 5391d806 bellard
58 5391d806 bellard
#define IDE_CMD_RESET           0x04
59 5391d806 bellard
#define IDE_CMD_DISABLE_IRQ     0x02
60 5391d806 bellard
61 5391d806 bellard
/* ATA/ATAPI Commands pre T13 Spec */
62 5391d806 bellard
#define WIN_NOP                                0x00
63 5391d806 bellard
/*
64 5391d806 bellard
 *        0x01->0x02 Reserved
65 5391d806 bellard
 */
66 5391d806 bellard
#define CFA_REQ_EXT_ERROR_CODE                0x03 /* CFA Request Extended Error Code */
67 5391d806 bellard
/*
68 5391d806 bellard
 *        0x04->0x07 Reserved
69 5391d806 bellard
 */
70 5391d806 bellard
#define WIN_SRST                        0x08 /* ATAPI soft reset command */
71 5391d806 bellard
#define WIN_DEVICE_RESET                0x08
72 5391d806 bellard
/*
73 5391d806 bellard
 *        0x09->0x0F Reserved
74 5391d806 bellard
 */
75 5391d806 bellard
#define WIN_RECAL                        0x10
76 5391d806 bellard
#define WIN_RESTORE                        WIN_RECAL
77 5391d806 bellard
/*
78 5391d806 bellard
 *        0x10->0x1F Reserved
79 5391d806 bellard
 */
80 5391d806 bellard
#define WIN_READ                        0x20 /* 28-Bit */
81 5391d806 bellard
#define WIN_READ_ONCE                        0x21 /* 28-Bit without retries */
82 5391d806 bellard
#define WIN_READ_LONG                        0x22 /* 28-Bit */
83 5391d806 bellard
#define WIN_READ_LONG_ONCE                0x23 /* 28-Bit without retries */
84 5391d806 bellard
#define WIN_READ_EXT                        0x24 /* 48-Bit */
85 5391d806 bellard
#define WIN_READDMA_EXT                        0x25 /* 48-Bit */
86 5391d806 bellard
#define WIN_READDMA_QUEUED_EXT                0x26 /* 48-Bit */
87 5391d806 bellard
#define WIN_READ_NATIVE_MAX_EXT                0x27 /* 48-Bit */
88 5391d806 bellard
/*
89 5391d806 bellard
 *        0x28
90 5391d806 bellard
 */
91 5391d806 bellard
#define WIN_MULTREAD_EXT                0x29 /* 48-Bit */
92 5391d806 bellard
/*
93 5391d806 bellard
 *        0x2A->0x2F Reserved
94 5391d806 bellard
 */
95 5391d806 bellard
#define WIN_WRITE                        0x30 /* 28-Bit */
96 5391d806 bellard
#define WIN_WRITE_ONCE                        0x31 /* 28-Bit without retries */
97 5391d806 bellard
#define WIN_WRITE_LONG                        0x32 /* 28-Bit */
98 5391d806 bellard
#define WIN_WRITE_LONG_ONCE                0x33 /* 28-Bit without retries */
99 5391d806 bellard
#define WIN_WRITE_EXT                        0x34 /* 48-Bit */
100 5391d806 bellard
#define WIN_WRITEDMA_EXT                0x35 /* 48-Bit */
101 5391d806 bellard
#define WIN_WRITEDMA_QUEUED_EXT                0x36 /* 48-Bit */
102 5391d806 bellard
#define WIN_SET_MAX_EXT                        0x37 /* 48-Bit */
103 5391d806 bellard
#define CFA_WRITE_SECT_WO_ERASE                0x38 /* CFA Write Sectors without erase */
104 5391d806 bellard
#define WIN_MULTWRITE_EXT                0x39 /* 48-Bit */
105 5391d806 bellard
/*
106 5391d806 bellard
 *        0x3A->0x3B Reserved
107 5391d806 bellard
 */
108 5391d806 bellard
#define WIN_WRITE_VERIFY                0x3C /* 28-Bit */
109 5391d806 bellard
/*
110 5391d806 bellard
 *        0x3D->0x3F Reserved
111 5391d806 bellard
 */
112 5391d806 bellard
#define WIN_VERIFY                        0x40 /* 28-Bit - Read Verify Sectors */
113 5391d806 bellard
#define WIN_VERIFY_ONCE                        0x41 /* 28-Bit - without retries */
114 5391d806 bellard
#define WIN_VERIFY_EXT                        0x42 /* 48-Bit */
115 5391d806 bellard
/*
116 5391d806 bellard
 *        0x43->0x4F Reserved
117 5391d806 bellard
 */
118 5391d806 bellard
#define WIN_FORMAT                        0x50
119 5391d806 bellard
/*
120 5391d806 bellard
 *        0x51->0x5F Reserved
121 5391d806 bellard
 */
122 5391d806 bellard
#define WIN_INIT                        0x60
123 5391d806 bellard
/*
124 5391d806 bellard
 *        0x61->0x5F Reserved
125 5391d806 bellard
 */
126 5391d806 bellard
#define WIN_SEEK                        0x70 /* 0x70-0x7F Reserved */
127 5391d806 bellard
#define CFA_TRANSLATE_SECTOR                0x87 /* CFA Translate Sector */
128 5391d806 bellard
#define WIN_DIAGNOSE                        0x90
129 5391d806 bellard
#define WIN_SPECIFY                        0x91 /* set drive geometry translation */
130 5391d806 bellard
#define WIN_DOWNLOAD_MICROCODE                0x92
131 5391d806 bellard
#define WIN_STANDBYNOW2                        0x94
132 5391d806 bellard
#define WIN_STANDBY2                        0x96
133 5391d806 bellard
#define WIN_SETIDLE2                        0x97
134 5391d806 bellard
#define WIN_CHECKPOWERMODE2                0x98
135 5391d806 bellard
#define WIN_SLEEPNOW2                        0x99
136 5391d806 bellard
/*
137 5391d806 bellard
 *        0x9A VENDOR
138 5391d806 bellard
 */
139 5391d806 bellard
#define WIN_PACKETCMD                        0xA0 /* Send a packet command. */
140 5391d806 bellard
#define WIN_PIDENTIFY                        0xA1 /* identify ATAPI device        */
141 5391d806 bellard
#define WIN_QUEUED_SERVICE                0xA2
142 5391d806 bellard
#define WIN_SMART                        0xB0 /* self-monitoring and reporting */
143 5391d806 bellard
#define CFA_ERASE_SECTORS               0xC0
144 5391d806 bellard
#define WIN_MULTREAD                        0xC4 /* read sectors using multiple mode*/
145 5391d806 bellard
#define WIN_MULTWRITE                        0xC5 /* write sectors using multiple mode */
146 5391d806 bellard
#define WIN_SETMULT                        0xC6 /* enable/disable multiple mode */
147 5391d806 bellard
#define WIN_READDMA_QUEUED                0xC7 /* read sectors using Queued DMA transfers */
148 5391d806 bellard
#define WIN_READDMA                        0xC8 /* read sectors using DMA transfers */
149 5391d806 bellard
#define WIN_READDMA_ONCE                0xC9 /* 28-Bit - without retries */
150 5391d806 bellard
#define WIN_WRITEDMA                        0xCA /* write sectors using DMA transfers */
151 5391d806 bellard
#define WIN_WRITEDMA_ONCE                0xCB /* 28-Bit - without retries */
152 5391d806 bellard
#define WIN_WRITEDMA_QUEUED                0xCC /* write sectors using Queued DMA transfers */
153 5391d806 bellard
#define CFA_WRITE_MULTI_WO_ERASE        0xCD /* CFA Write multiple without erase */
154 5391d806 bellard
#define WIN_GETMEDIASTATUS                0xDA        
155 5391d806 bellard
#define WIN_ACKMEDIACHANGE                0xDB /* ATA-1, ATA-2 vendor */
156 5391d806 bellard
#define WIN_POSTBOOT                        0xDC
157 5391d806 bellard
#define WIN_PREBOOT                        0xDD
158 5391d806 bellard
#define WIN_DOORLOCK                        0xDE /* lock door on removable drives */
159 5391d806 bellard
#define WIN_DOORUNLOCK                        0xDF /* unlock door on removable drives */
160 5391d806 bellard
#define WIN_STANDBYNOW1                        0xE0
161 5391d806 bellard
#define WIN_IDLEIMMEDIATE                0xE1 /* force drive to become "ready" */
162 5391d806 bellard
#define WIN_STANDBY                     0xE2 /* Set device in Standby Mode */
163 5391d806 bellard
#define WIN_SETIDLE1                        0xE3
164 5391d806 bellard
#define WIN_READ_BUFFER                        0xE4 /* force read only 1 sector */
165 5391d806 bellard
#define WIN_CHECKPOWERMODE1                0xE5
166 5391d806 bellard
#define WIN_SLEEPNOW1                        0xE6
167 5391d806 bellard
#define WIN_FLUSH_CACHE                        0xE7
168 5391d806 bellard
#define WIN_WRITE_BUFFER                0xE8 /* force write only 1 sector */
169 5391d806 bellard
#define WIN_WRITE_SAME                        0xE9 /* read ata-2 to use */
170 5391d806 bellard
        /* SET_FEATURES 0x22 or 0xDD */
171 5391d806 bellard
#define WIN_FLUSH_CACHE_EXT                0xEA /* 48-Bit */
172 5391d806 bellard
#define WIN_IDENTIFY                        0xEC /* ask drive to identify itself        */
173 5391d806 bellard
#define WIN_MEDIAEJECT                        0xED
174 5391d806 bellard
#define WIN_IDENTIFY_DMA                0xEE /* same as WIN_IDENTIFY, but DMA */
175 5391d806 bellard
#define WIN_SETFEATURES                        0xEF /* set special drive features */
176 5391d806 bellard
#define EXABYTE_ENABLE_NEST                0xF0
177 5391d806 bellard
#define WIN_SECURITY_SET_PASS                0xF1
178 5391d806 bellard
#define WIN_SECURITY_UNLOCK                0xF2
179 5391d806 bellard
#define WIN_SECURITY_ERASE_PREPARE        0xF3
180 5391d806 bellard
#define WIN_SECURITY_ERASE_UNIT                0xF4
181 5391d806 bellard
#define WIN_SECURITY_FREEZE_LOCK        0xF5
182 5391d806 bellard
#define WIN_SECURITY_DISABLE                0xF6
183 5391d806 bellard
#define WIN_READ_NATIVE_MAX                0xF8 /* return the native maximum address */
184 5391d806 bellard
#define WIN_SET_MAX                        0xF9
185 5391d806 bellard
#define DISABLE_SEAGATE                        0xFB
186 5391d806 bellard
187 5391d806 bellard
/* set to 1 set disable mult support */
188 f66723fa bellard
#define MAX_MULT_SECTORS 16
189 5391d806 bellard
190 5391d806 bellard
/* ATAPI defines */
191 5391d806 bellard
192 5391d806 bellard
#define ATAPI_PACKET_SIZE 12
193 5391d806 bellard
194 5391d806 bellard
/* The generic packet command opcodes for CD/DVD Logical Units,
195 5391d806 bellard
 * From Table 57 of the SFF8090 Ver. 3 (Mt. Fuji) draft standard. */
196 5391d806 bellard
#define GPCMD_BLANK                            0xa1
197 5391d806 bellard
#define GPCMD_CLOSE_TRACK                    0x5b
198 5391d806 bellard
#define GPCMD_FLUSH_CACHE                    0x35
199 5391d806 bellard
#define GPCMD_FORMAT_UNIT                    0x04
200 5391d806 bellard
#define GPCMD_GET_CONFIGURATION                    0x46
201 5391d806 bellard
#define GPCMD_GET_EVENT_STATUS_NOTIFICATION 0x4a
202 5391d806 bellard
#define GPCMD_GET_PERFORMANCE                    0xac
203 5391d806 bellard
#define GPCMD_INQUIRY                            0x12
204 5391d806 bellard
#define GPCMD_LOAD_UNLOAD                    0xa6
205 5391d806 bellard
#define GPCMD_MECHANISM_STATUS                    0xbd
206 5391d806 bellard
#define GPCMD_MODE_SELECT_10                    0x55
207 5391d806 bellard
#define GPCMD_MODE_SENSE_10                    0x5a
208 5391d806 bellard
#define GPCMD_PAUSE_RESUME                    0x4b
209 5391d806 bellard
#define GPCMD_PLAY_AUDIO_10                    0x45
210 5391d806 bellard
#define GPCMD_PLAY_AUDIO_MSF                    0x47
211 5391d806 bellard
#define GPCMD_PLAY_AUDIO_TI                    0x48
212 5391d806 bellard
#define GPCMD_PLAY_CD                            0xbc
213 5391d806 bellard
#define GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL  0x1e
214 5391d806 bellard
#define GPCMD_READ_10                            0x28
215 5391d806 bellard
#define GPCMD_READ_12                            0xa8
216 5391d806 bellard
#define GPCMD_READ_CDVD_CAPACITY            0x25
217 5391d806 bellard
#define GPCMD_READ_CD                            0xbe
218 5391d806 bellard
#define GPCMD_READ_CD_MSF                    0xb9
219 5391d806 bellard
#define GPCMD_READ_DISC_INFO                    0x51
220 5391d806 bellard
#define GPCMD_READ_DVD_STRUCTURE            0xad
221 5391d806 bellard
#define GPCMD_READ_FORMAT_CAPACITIES            0x23
222 5391d806 bellard
#define GPCMD_READ_HEADER                    0x44
223 5391d806 bellard
#define GPCMD_READ_TRACK_RZONE_INFO            0x52
224 5391d806 bellard
#define GPCMD_READ_SUBCHANNEL                    0x42
225 5391d806 bellard
#define GPCMD_READ_TOC_PMA_ATIP                    0x43
226 5391d806 bellard
#define GPCMD_REPAIR_RZONE_TRACK            0x58
227 5391d806 bellard
#define GPCMD_REPORT_KEY                    0xa4
228 5391d806 bellard
#define GPCMD_REQUEST_SENSE                    0x03
229 5391d806 bellard
#define GPCMD_RESERVE_RZONE_TRACK            0x53
230 5391d806 bellard
#define GPCMD_SCAN                            0xba
231 5391d806 bellard
#define GPCMD_SEEK                            0x2b
232 5391d806 bellard
#define GPCMD_SEND_DVD_STRUCTURE            0xad
233 5391d806 bellard
#define GPCMD_SEND_EVENT                    0xa2
234 5391d806 bellard
#define GPCMD_SEND_KEY                            0xa3
235 5391d806 bellard
#define GPCMD_SEND_OPC                            0x54
236 5391d806 bellard
#define GPCMD_SET_READ_AHEAD                    0xa7
237 5391d806 bellard
#define GPCMD_SET_STREAMING                    0xb6
238 5391d806 bellard
#define GPCMD_START_STOP_UNIT                    0x1b
239 5391d806 bellard
#define GPCMD_STOP_PLAY_SCAN                    0x4e
240 5391d806 bellard
#define GPCMD_TEST_UNIT_READY                    0x00
241 5391d806 bellard
#define GPCMD_VERIFY_10                            0x2f
242 5391d806 bellard
#define GPCMD_WRITE_10                            0x2a
243 5391d806 bellard
#define GPCMD_WRITE_AND_VERIFY_10            0x2e
244 5391d806 bellard
/* This is listed as optional in ATAPI 2.6, but is (curiously) 
245 5391d806 bellard
 * missing from Mt. Fuji, Table 57.  It _is_ mentioned in Mt. Fuji
246 5391d806 bellard
 * Table 377 as an MMC command for SCSi devices though...  Most ATAPI
247 5391d806 bellard
 * drives support it. */
248 5391d806 bellard
#define GPCMD_SET_SPEED                            0xbb
249 5391d806 bellard
/* This seems to be a SCSI specific CD-ROM opcode 
250 5391d806 bellard
 * to play data at track/index */
251 5391d806 bellard
#define GPCMD_PLAYAUDIO_TI                    0x48
252 5391d806 bellard
/*
253 5391d806 bellard
 * From MS Media Status Notification Support Specification. For
254 5391d806 bellard
 * older drives only.
255 5391d806 bellard
 */
256 5391d806 bellard
#define GPCMD_GET_MEDIA_STATUS                    0xda
257 5391d806 bellard
258 5391d806 bellard
/* Mode page codes for mode sense/set */
259 5391d806 bellard
#define GPMODE_R_W_ERROR_PAGE                0x01
260 5391d806 bellard
#define GPMODE_WRITE_PARMS_PAGE                0x05
261 5391d806 bellard
#define GPMODE_AUDIO_CTL_PAGE                0x0e
262 5391d806 bellard
#define GPMODE_POWER_PAGE                0x1a
263 5391d806 bellard
#define GPMODE_FAULT_FAIL_PAGE                0x1c
264 5391d806 bellard
#define GPMODE_TO_PROTECT_PAGE                0x1d
265 5391d806 bellard
#define GPMODE_CAPABILITIES_PAGE        0x2a
266 5391d806 bellard
#define GPMODE_ALL_PAGES                0x3f
267 5391d806 bellard
/* Not in Mt. Fuji, but in ATAPI 2.6 -- depricated now in favor
268 5391d806 bellard
 * of MODE_SENSE_POWER_PAGE */
269 5391d806 bellard
#define GPMODE_CDROM_PAGE                0x0d
270 5391d806 bellard
271 5391d806 bellard
#define ATAPI_INT_REASON_CD             0x01 /* 0 = data transfer */
272 5391d806 bellard
#define ATAPI_INT_REASON_IO             0x02 /* 1 = transfer to the host */
273 5391d806 bellard
#define ATAPI_INT_REASON_REL            0x04
274 5391d806 bellard
#define ATAPI_INT_REASON_TAG            0xf8
275 5391d806 bellard
276 5391d806 bellard
/* same constants as bochs */
277 7f777bf3 bellard
#define ASC_ILLEGAL_OPCODE                   0x20
278 5391d806 bellard
#define ASC_LOGICAL_BLOCK_OOR                0x21
279 5391d806 bellard
#define ASC_INV_FIELD_IN_CMD_PACKET          0x24
280 5391d806 bellard
#define ASC_MEDIUM_NOT_PRESENT               0x3a
281 5391d806 bellard
#define ASC_SAVING_PARAMETERS_NOT_SUPPORTED  0x39
282 5391d806 bellard
283 5391d806 bellard
#define SENSE_NONE            0
284 5391d806 bellard
#define SENSE_NOT_READY       2
285 5391d806 bellard
#define SENSE_ILLEGAL_REQUEST 5
286 5391d806 bellard
#define SENSE_UNIT_ATTENTION  6
287 5391d806 bellard
288 5391d806 bellard
struct IDEState;
289 5391d806 bellard
290 5391d806 bellard
typedef void EndTransferFunc(struct IDEState *);
291 5391d806 bellard
292 caed8802 bellard
/* NOTE: IDEState represents in fact one drive */
293 5391d806 bellard
typedef struct IDEState {
294 5391d806 bellard
    /* ide config */
295 5391d806 bellard
    int is_cdrom;
296 5391d806 bellard
    int cylinders, heads, sectors;
297 5391d806 bellard
    int64_t nb_sectors;
298 5391d806 bellard
    int mult_sectors;
299 94458802 bellard
    int identify_set;
300 94458802 bellard
    uint16_t identify_data[256];
301 5457c8ce bellard
    SetIRQFunc *set_irq;
302 5457c8ce bellard
    void *irq_opaque;
303 5391d806 bellard
    int irq;
304 34e538ae bellard
    PCIDevice *pci_dev;
305 98087450 bellard
    struct BMDMAState *bmdma;
306 aedf5382 bellard
    int drive_serial;
307 5391d806 bellard
    /* ide regs */
308 5391d806 bellard
    uint8_t feature;
309 5391d806 bellard
    uint8_t error;
310 5391d806 bellard
    uint16_t nsector; /* 0 is 256 to ease computations */
311 5391d806 bellard
    uint8_t sector;
312 5391d806 bellard
    uint8_t lcyl;
313 5391d806 bellard
    uint8_t hcyl;
314 5391d806 bellard
    uint8_t select;
315 5391d806 bellard
    uint8_t status;
316 5391d806 bellard
    /* 0x3f6 command, only meaningful for drive 0 */
317 5391d806 bellard
    uint8_t cmd;
318 5391d806 bellard
    /* depends on bit 4 in select, only meaningful for drive 0 */
319 5391d806 bellard
    struct IDEState *cur_drive; 
320 5391d806 bellard
    BlockDriverState *bs;
321 5391d806 bellard
    /* ATAPI specific */
322 5391d806 bellard
    uint8_t sense_key;
323 5391d806 bellard
    uint8_t asc;
324 5391d806 bellard
    int packet_transfer_size;
325 5391d806 bellard
    int elementary_transfer_size;
326 5391d806 bellard
    int io_buffer_index;
327 5391d806 bellard
    int lba;
328 98087450 bellard
    int cd_sector_size;
329 98087450 bellard
    int atapi_dma; /* true if dma is requested for the packet cmd */
330 98087450 bellard
    /* ATA DMA state */
331 98087450 bellard
    int io_buffer_size;
332 98087450 bellard
    /* PIO transfer handling */
333 5391d806 bellard
    int req_nb_sectors; /* number of sectors per interrupt */
334 5391d806 bellard
    EndTransferFunc *end_transfer_func;
335 5391d806 bellard
    uint8_t *data_ptr;
336 5391d806 bellard
    uint8_t *data_end;
337 5391d806 bellard
    uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4];
338 a09db21f bellard
    QEMUTimer *sector_write_timer; /* only used for win2k instal hack */
339 5391d806 bellard
} IDEState;
340 5391d806 bellard
341 98087450 bellard
#define BM_STATUS_DMAING 0x01
342 98087450 bellard
#define BM_STATUS_ERROR  0x02
343 98087450 bellard
#define BM_STATUS_INT    0x04
344 98087450 bellard
345 98087450 bellard
#define BM_CMD_START     0x01
346 98087450 bellard
#define BM_CMD_READ      0x08
347 98087450 bellard
348 5457c8ce bellard
#define IDE_TYPE_PIIX3   0
349 5457c8ce bellard
#define IDE_TYPE_CMD646  1
350 5457c8ce bellard
351 5457c8ce bellard
/* CMD646 specific */
352 5457c8ce bellard
#define MRDMODE                0x71
353 5457c8ce bellard
#define   MRDMODE_INTR_CH0        0x04
354 5457c8ce bellard
#define   MRDMODE_INTR_CH1        0x08
355 5457c8ce bellard
#define   MRDMODE_BLK_CH0        0x10
356 5457c8ce bellard
#define   MRDMODE_BLK_CH1        0x20
357 5457c8ce bellard
#define UDIDETCR0        0x73
358 5457c8ce bellard
#define UDIDETCR1        0x7B
359 5457c8ce bellard
360 98087450 bellard
typedef int IDEDMAFunc(IDEState *s, 
361 98087450 bellard
                       target_phys_addr_t phys_addr, 
362 98087450 bellard
                       int transfer_size1);
363 98087450 bellard
364 98087450 bellard
typedef struct BMDMAState {
365 98087450 bellard
    uint8_t cmd;
366 98087450 bellard
    uint8_t status;
367 98087450 bellard
    uint32_t addr;
368 5457c8ce bellard
369 5457c8ce bellard
    struct PCIIDEState *pci_dev;
370 98087450 bellard
    /* current transfer state */
371 98087450 bellard
    IDEState *ide_if;
372 98087450 bellard
    IDEDMAFunc *dma_cb;
373 98087450 bellard
} BMDMAState;
374 98087450 bellard
375 98087450 bellard
typedef struct PCIIDEState {
376 98087450 bellard
    PCIDevice dev;
377 98087450 bellard
    IDEState ide_if[4];
378 98087450 bellard
    BMDMAState bmdma[2];
379 5457c8ce bellard
    int type; /* see IDE_TYPE_xxx */
380 98087450 bellard
} PCIIDEState;
381 98087450 bellard
382 98087450 bellard
static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb);
383 98087450 bellard
384 5391d806 bellard
static void padstr(char *str, const char *src, int len)
385 5391d806 bellard
{
386 5391d806 bellard
    int i, v;
387 5391d806 bellard
    for(i = 0; i < len; i++) {
388 5391d806 bellard
        if (*src)
389 5391d806 bellard
            v = *src++;
390 5391d806 bellard
        else
391 5391d806 bellard
            v = ' ';
392 5391d806 bellard
        *(char *)((long)str ^ 1) = v;
393 5391d806 bellard
        str++;
394 5391d806 bellard
    }
395 5391d806 bellard
}
396 5391d806 bellard
397 bd0d90b2 bellard
static void padstr8(uint8_t *buf, int buf_size, const char *src)
398 bd0d90b2 bellard
{
399 bd0d90b2 bellard
    int i;
400 bd0d90b2 bellard
    for(i = 0; i < buf_size; i++) {
401 bd0d90b2 bellard
        if (*src)
402 bd0d90b2 bellard
            buf[i] = *src++;
403 bd0d90b2 bellard
        else
404 bd0d90b2 bellard
            buf[i] = ' ';
405 bd0d90b2 bellard
    }
406 bd0d90b2 bellard
}
407 bd0d90b2 bellard
408 67b915a5 bellard
static void put_le16(uint16_t *p, unsigned int v)
409 67b915a5 bellard
{
410 0c4ad8dc bellard
    *p = cpu_to_le16(v);
411 67b915a5 bellard
}
412 67b915a5 bellard
413 5391d806 bellard
static void ide_identify(IDEState *s)
414 5391d806 bellard
{
415 5391d806 bellard
    uint16_t *p;
416 5391d806 bellard
    unsigned int oldsize;
417 aedf5382 bellard
    char buf[20];
418 5391d806 bellard
419 94458802 bellard
    if (s->identify_set) {
420 94458802 bellard
        memcpy(s->io_buffer, s->identify_data, sizeof(s->identify_data));
421 94458802 bellard
        return;
422 94458802 bellard
    }
423 94458802 bellard
424 5391d806 bellard
    memset(s->io_buffer, 0, 512);
425 5391d806 bellard
    p = (uint16_t *)s->io_buffer;
426 67b915a5 bellard
    put_le16(p + 0, 0x0040);
427 67b915a5 bellard
    put_le16(p + 1, s->cylinders); 
428 67b915a5 bellard
    put_le16(p + 3, s->heads);
429 67b915a5 bellard
    put_le16(p + 4, 512 * s->sectors); /* XXX: retired, remove ? */
430 67b915a5 bellard
    put_le16(p + 5, 512); /* XXX: retired, remove ? */
431 67b915a5 bellard
    put_le16(p + 6, s->sectors); 
432 aedf5382 bellard
    snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial);
433 aedf5382 bellard
    padstr((uint8_t *)(p + 10), buf, 20); /* serial number */
434 67b915a5 bellard
    put_le16(p + 20, 3); /* XXX: retired, remove ? */
435 67b915a5 bellard
    put_le16(p + 21, 512); /* cache size in sectors */
436 67b915a5 bellard
    put_le16(p + 22, 4); /* ecc bytes */
437 5391d806 bellard
    padstr((uint8_t *)(p + 23), QEMU_VERSION, 8); /* firmware version */
438 5391d806 bellard
    padstr((uint8_t *)(p + 27), "QEMU HARDDISK", 40); /* model */
439 5391d806 bellard
#if MAX_MULT_SECTORS > 1    
440 67b915a5 bellard
    put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
441 5391d806 bellard
#endif
442 67b915a5 bellard
    put_le16(p + 48, 1); /* dword I/O */
443 94458802 bellard
    put_le16(p + 49, (1 << 11) | (1 << 9) | (1 << 8)); /* DMA and LBA supported */
444 67b915a5 bellard
    put_le16(p + 51, 0x200); /* PIO transfer cycle */
445 67b915a5 bellard
    put_le16(p + 52, 0x200); /* DMA transfer cycle */
446 94458802 bellard
    put_le16(p + 53, 1 | (1 << 1) | (1 << 2)); /* words 54-58,64-70,88 are valid */
447 67b915a5 bellard
    put_le16(p + 54, s->cylinders);
448 67b915a5 bellard
    put_le16(p + 55, s->heads);
449 67b915a5 bellard
    put_le16(p + 56, s->sectors);
450 5391d806 bellard
    oldsize = s->cylinders * s->heads * s->sectors;
451 67b915a5 bellard
    put_le16(p + 57, oldsize);
452 67b915a5 bellard
    put_le16(p + 58, oldsize >> 16);
453 5391d806 bellard
    if (s->mult_sectors)
454 67b915a5 bellard
        put_le16(p + 59, 0x100 | s->mult_sectors);
455 67b915a5 bellard
    put_le16(p + 60, s->nb_sectors);
456 67b915a5 bellard
    put_le16(p + 61, s->nb_sectors >> 16);
457 94458802 bellard
    put_le16(p + 63, 0x07); /* mdma0-2 supported */
458 94458802 bellard
    put_le16(p + 65, 120);
459 94458802 bellard
    put_le16(p + 66, 120);
460 94458802 bellard
    put_le16(p + 67, 120);
461 94458802 bellard
    put_le16(p + 68, 120);
462 94458802 bellard
    put_le16(p + 80, 0xf0); /* ata3 -> ata6 supported */
463 94458802 bellard
    put_le16(p + 81, 0x16); /* conforms to ata5 */
464 67b915a5 bellard
    put_le16(p + 82, (1 << 14));
465 67b915a5 bellard
    put_le16(p + 83, (1 << 14));
466 67b915a5 bellard
    put_le16(p + 84, (1 << 14));
467 67b915a5 bellard
    put_le16(p + 85, (1 << 14));
468 67b915a5 bellard
    put_le16(p + 86, 0);
469 67b915a5 bellard
    put_le16(p + 87, (1 << 14));
470 94458802 bellard
    put_le16(p + 88, 0x3f | (1 << 13)); /* udma5 set and supported */
471 94458802 bellard
    put_le16(p + 93, 1 | (1 << 14) | 0x2000);
472 94458802 bellard
473 94458802 bellard
    memcpy(s->identify_data, p, sizeof(s->identify_data));
474 94458802 bellard
    s->identify_set = 1;
475 5391d806 bellard
}
476 5391d806 bellard
477 5391d806 bellard
static void ide_atapi_identify(IDEState *s)
478 5391d806 bellard
{
479 5391d806 bellard
    uint16_t *p;
480 aedf5382 bellard
    char buf[20];
481 5391d806 bellard
482 94458802 bellard
    if (s->identify_set) {
483 94458802 bellard
        memcpy(s->io_buffer, s->identify_data, sizeof(s->identify_data));
484 94458802 bellard
        return;
485 94458802 bellard
    }
486 94458802 bellard
487 5391d806 bellard
    memset(s->io_buffer, 0, 512);
488 5391d806 bellard
    p = (uint16_t *)s->io_buffer;
489 5391d806 bellard
    /* Removable CDROM, 50us response, 12 byte packets */
490 67b915a5 bellard
    put_le16(p + 0, (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0));
491 aedf5382 bellard
    snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial);
492 aedf5382 bellard
    padstr((uint8_t *)(p + 10), buf, 20); /* serial number */
493 67b915a5 bellard
    put_le16(p + 20, 3); /* buffer type */
494 67b915a5 bellard
    put_le16(p + 21, 512); /* cache size in sectors */
495 67b915a5 bellard
    put_le16(p + 22, 4); /* ecc bytes */
496 5391d806 bellard
    padstr((uint8_t *)(p + 23), QEMU_VERSION, 8); /* firmware version */
497 5391d806 bellard
    padstr((uint8_t *)(p + 27), "QEMU CD-ROM", 40); /* model */
498 67b915a5 bellard
    put_le16(p + 48, 1); /* dword I/O (XXX: should not be set on CDROM) */
499 67b915a5 bellard
    put_le16(p + 49, 1 << 9); /* LBA supported, no DMA */
500 67b915a5 bellard
    put_le16(p + 53, 3); /* words 64-70, 54-58 valid */
501 67b915a5 bellard
    put_le16(p + 63, 0x103); /* DMA modes XXX: may be incorrect */
502 67b915a5 bellard
    put_le16(p + 64, 1); /* PIO modes */
503 67b915a5 bellard
    put_le16(p + 65, 0xb4); /* minimum DMA multiword tx cycle time */
504 67b915a5 bellard
    put_le16(p + 66, 0xb4); /* recommended DMA multiword tx cycle time */
505 67b915a5 bellard
    put_le16(p + 67, 0x12c); /* minimum PIO cycle time without flow control */
506 67b915a5 bellard
    put_le16(p + 68, 0xb4); /* minimum PIO cycle time with IORDY flow control */
507 94458802 bellard
508 67b915a5 bellard
    put_le16(p + 71, 30); /* in ns */
509 67b915a5 bellard
    put_le16(p + 72, 30); /* in ns */
510 5391d806 bellard
511 67b915a5 bellard
    put_le16(p + 80, 0x1e); /* support up to ATA/ATAPI-4 */
512 94458802 bellard
513 94458802 bellard
    memcpy(s->identify_data, p, sizeof(s->identify_data));
514 94458802 bellard
    s->identify_set = 1;
515 5391d806 bellard
}
516 5391d806 bellard
517 5391d806 bellard
static void ide_set_signature(IDEState *s)
518 5391d806 bellard
{
519 5391d806 bellard
    s->select &= 0xf0; /* clear head */
520 5391d806 bellard
    /* put signature */
521 5391d806 bellard
    s->nsector = 1;
522 5391d806 bellard
    s->sector = 1;
523 5391d806 bellard
    if (s->is_cdrom) {
524 5391d806 bellard
        s->lcyl = 0x14;
525 5391d806 bellard
        s->hcyl = 0xeb;
526 5391d806 bellard
    } else if (s->bs) {
527 5391d806 bellard
        s->lcyl = 0;
528 5391d806 bellard
        s->hcyl = 0;
529 5391d806 bellard
    } else {
530 5391d806 bellard
        s->lcyl = 0xff;
531 5391d806 bellard
        s->hcyl = 0xff;
532 5391d806 bellard
    }
533 5391d806 bellard
}
534 5391d806 bellard
535 5391d806 bellard
static inline void ide_abort_command(IDEState *s)
536 5391d806 bellard
{
537 5391d806 bellard
    s->status = READY_STAT | ERR_STAT;
538 5391d806 bellard
    s->error = ABRT_ERR;
539 5391d806 bellard
}
540 5391d806 bellard
541 5391d806 bellard
static inline void ide_set_irq(IDEState *s)
542 5391d806 bellard
{
543 98ff7d30 bellard
    BMDMAState *bm = s->bmdma;
544 5391d806 bellard
    if (!(s->cmd & IDE_CMD_DISABLE_IRQ)) {
545 5457c8ce bellard
        if (bm) {
546 98ff7d30 bellard
            bm->status |= BM_STATUS_INT;
547 5457c8ce bellard
        }
548 5457c8ce bellard
        s->set_irq(s->irq_opaque, s->irq, 1);
549 5391d806 bellard
    }
550 5391d806 bellard
}
551 5391d806 bellard
552 5391d806 bellard
/* prepare data transfer and tell what to do after */
553 5391d806 bellard
static void ide_transfer_start(IDEState *s, uint8_t *buf, int size, 
554 5391d806 bellard
                               EndTransferFunc *end_transfer_func)
555 5391d806 bellard
{
556 5391d806 bellard
    s->end_transfer_func = end_transfer_func;
557 5391d806 bellard
    s->data_ptr = buf;
558 5391d806 bellard
    s->data_end = buf + size;
559 5391d806 bellard
    s->status |= DRQ_STAT;
560 5391d806 bellard
}
561 5391d806 bellard
562 5391d806 bellard
static void ide_transfer_stop(IDEState *s)
563 5391d806 bellard
{
564 5391d806 bellard
    s->end_transfer_func = ide_transfer_stop;
565 5391d806 bellard
    s->data_ptr = s->io_buffer;
566 5391d806 bellard
    s->data_end = s->io_buffer;
567 5391d806 bellard
    s->status &= ~DRQ_STAT;
568 5391d806 bellard
}
569 5391d806 bellard
570 5391d806 bellard
static int64_t ide_get_sector(IDEState *s)
571 5391d806 bellard
{
572 5391d806 bellard
    int64_t sector_num;
573 5391d806 bellard
    if (s->select & 0x40) {
574 5391d806 bellard
        /* lba */
575 5391d806 bellard
        sector_num = ((s->select & 0x0f) << 24) | (s->hcyl << 16) | 
576 5391d806 bellard
            (s->lcyl << 8) | s->sector;
577 5391d806 bellard
    } else {
578 5391d806 bellard
        sector_num = ((s->hcyl << 8) | s->lcyl) * s->heads * s->sectors +
579 5391d806 bellard
            (s->select & 0x0f) * s->sectors + 
580 5391d806 bellard
            (s->sector - 1);
581 5391d806 bellard
    }
582 5391d806 bellard
    return sector_num;
583 5391d806 bellard
}
584 5391d806 bellard
585 5391d806 bellard
static void ide_set_sector(IDEState *s, int64_t sector_num)
586 5391d806 bellard
{
587 5391d806 bellard
    unsigned int cyl, r;
588 5391d806 bellard
    if (s->select & 0x40) {
589 5391d806 bellard
        s->select = (s->select & 0xf0) | (sector_num >> 24);
590 5391d806 bellard
        s->hcyl = (sector_num >> 16);
591 5391d806 bellard
        s->lcyl = (sector_num >> 8);
592 5391d806 bellard
        s->sector = (sector_num);
593 5391d806 bellard
    } else {
594 5391d806 bellard
        cyl = sector_num / (s->heads * s->sectors);
595 5391d806 bellard
        r = sector_num % (s->heads * s->sectors);
596 5391d806 bellard
        s->hcyl = cyl >> 8;
597 5391d806 bellard
        s->lcyl = cyl;
598 1b8eb456 bellard
        s->select = (s->select & 0xf0) | ((r / s->sectors) & 0x0f);
599 5391d806 bellard
        s->sector = (r % s->sectors) + 1;
600 5391d806 bellard
    }
601 5391d806 bellard
}
602 5391d806 bellard
603 5391d806 bellard
static void ide_sector_read(IDEState *s)
604 5391d806 bellard
{
605 5391d806 bellard
    int64_t sector_num;
606 5391d806 bellard
    int ret, n;
607 5391d806 bellard
608 5391d806 bellard
    s->status = READY_STAT | SEEK_STAT;
609 a136e5a8 bellard
    s->error = 0; /* not needed by IDE spec, but needed by Windows */
610 5391d806 bellard
    sector_num = ide_get_sector(s);
611 5391d806 bellard
    n = s->nsector;
612 5391d806 bellard
    if (n == 0) {
613 5391d806 bellard
        /* no more sector to read from disk */
614 5391d806 bellard
        ide_transfer_stop(s);
615 5391d806 bellard
    } else {
616 5391d806 bellard
#if defined(DEBUG_IDE)
617 5391d806 bellard
        printf("read sector=%Ld\n", sector_num);
618 5391d806 bellard
#endif
619 5391d806 bellard
        if (n > s->req_nb_sectors)
620 5391d806 bellard
            n = s->req_nb_sectors;
621 5391d806 bellard
        ret = bdrv_read(s->bs, sector_num, s->io_buffer, n);
622 5391d806 bellard
        ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_read);
623 5391d806 bellard
        ide_set_irq(s);
624 5391d806 bellard
        ide_set_sector(s, sector_num + n);
625 5391d806 bellard
        s->nsector -= n;
626 5391d806 bellard
    }
627 5391d806 bellard
}
628 5391d806 bellard
629 98087450 bellard
static int ide_read_dma_cb(IDEState *s, 
630 98087450 bellard
                           target_phys_addr_t phys_addr, 
631 98087450 bellard
                           int transfer_size1)
632 98087450 bellard
{
633 98087450 bellard
    int len, transfer_size, n;
634 98087450 bellard
    int64_t sector_num;
635 98087450 bellard
636 98087450 bellard
    transfer_size = transfer_size1;
637 98087450 bellard
    while (transfer_size > 0) {
638 98087450 bellard
        len = s->io_buffer_size - s->io_buffer_index;
639 98087450 bellard
        if (len <= 0) {
640 98087450 bellard
            /* transfert next data */
641 98087450 bellard
            n = s->nsector;
642 98087450 bellard
            if (n == 0)
643 98087450 bellard
                break;
644 98087450 bellard
            if (n > MAX_MULT_SECTORS)
645 98087450 bellard
                n = MAX_MULT_SECTORS;
646 98087450 bellard
            sector_num = ide_get_sector(s);
647 98087450 bellard
            bdrv_read(s->bs, sector_num, s->io_buffer, n);
648 98087450 bellard
            s->io_buffer_index = 0;
649 98087450 bellard
            s->io_buffer_size = n * 512;
650 98087450 bellard
            len = s->io_buffer_size;
651 98087450 bellard
            sector_num += n;
652 98087450 bellard
            ide_set_sector(s, sector_num);
653 98087450 bellard
            s->nsector -= n;
654 98087450 bellard
        }
655 98087450 bellard
        if (len > transfer_size)
656 98087450 bellard
            len = transfer_size;
657 98087450 bellard
        cpu_physical_memory_write(phys_addr, 
658 98087450 bellard
                                  s->io_buffer + s->io_buffer_index, len);
659 98087450 bellard
        s->io_buffer_index += len;
660 98087450 bellard
        transfer_size -= len;
661 98087450 bellard
        phys_addr += len;
662 98087450 bellard
    }
663 98087450 bellard
    if (s->io_buffer_index >= s->io_buffer_size && s->nsector == 0) {
664 98087450 bellard
        s->status = READY_STAT | SEEK_STAT;
665 98087450 bellard
        ide_set_irq(s);
666 98087450 bellard
#ifdef DEBUG_IDE_ATAPI
667 98087450 bellard
        printf("dma status=0x%x\n", s->status);
668 98087450 bellard
#endif
669 98087450 bellard
        return 0;
670 98087450 bellard
    }
671 98087450 bellard
    return transfer_size1 - transfer_size;
672 98087450 bellard
}
673 98087450 bellard
674 98087450 bellard
static void ide_sector_read_dma(IDEState *s)
675 98087450 bellard
{
676 98087450 bellard
    s->status = READY_STAT | SEEK_STAT | DRQ_STAT;
677 98087450 bellard
    s->io_buffer_index = 0;
678 98087450 bellard
    s->io_buffer_size = 0;
679 98087450 bellard
    ide_dma_start(s, ide_read_dma_cb);
680 98087450 bellard
}
681 98087450 bellard
682 a09db21f bellard
static void ide_sector_write_timer_cb(void *opaque)
683 a09db21f bellard
{
684 a09db21f bellard
    IDEState *s = opaque;
685 a09db21f bellard
    ide_set_irq(s);
686 a09db21f bellard
}
687 a09db21f bellard
688 5391d806 bellard
static void ide_sector_write(IDEState *s)
689 5391d806 bellard
{
690 5391d806 bellard
    int64_t sector_num;
691 5391d806 bellard
    int ret, n, n1;
692 5391d806 bellard
693 5391d806 bellard
    s->status = READY_STAT | SEEK_STAT;
694 5391d806 bellard
    sector_num = ide_get_sector(s);
695 5391d806 bellard
#if defined(DEBUG_IDE)
696 5391d806 bellard
    printf("write sector=%Ld\n", sector_num);
697 5391d806 bellard
#endif
698 5391d806 bellard
    n = s->nsector;
699 5391d806 bellard
    if (n > s->req_nb_sectors)
700 5391d806 bellard
        n = s->req_nb_sectors;
701 5391d806 bellard
    ret = bdrv_write(s->bs, sector_num, s->io_buffer, n);
702 5391d806 bellard
    s->nsector -= n;
703 5391d806 bellard
    if (s->nsector == 0) {
704 5391d806 bellard
        /* no more sector to write */
705 5391d806 bellard
        ide_transfer_stop(s);
706 5391d806 bellard
    } else {
707 5391d806 bellard
        n1 = s->nsector;
708 5391d806 bellard
        if (n1 > s->req_nb_sectors)
709 5391d806 bellard
            n1 = s->req_nb_sectors;
710 5391d806 bellard
        ide_transfer_start(s, s->io_buffer, 512 * n1, ide_sector_write);
711 5391d806 bellard
    }
712 5391d806 bellard
    ide_set_sector(s, sector_num + n);
713 a09db21f bellard
    
714 a09db21f bellard
#ifdef TARGET_I386
715 a09db21f bellard
    if (win2k_install_hack) {
716 a09db21f bellard
        /* It seems there is a bug in the Windows 2000 installer HDD
717 a09db21f bellard
           IDE driver which fills the disk with empty logs when the
718 a09db21f bellard
           IDE write IRQ comes too early. This hack tries to correct
719 a09db21f bellard
           that at the expense of slower write performances. Use this
720 a09db21f bellard
           option _only_ to install Windows 2000. You must disable it
721 a09db21f bellard
           for normal use. */
722 a09db21f bellard
        qemu_mod_timer(s->sector_write_timer, 
723 a09db21f bellard
                       qemu_get_clock(vm_clock) + (ticks_per_sec / 1000));
724 a09db21f bellard
    } else 
725 a09db21f bellard
#endif
726 a09db21f bellard
    {
727 a09db21f bellard
        ide_set_irq(s);
728 a09db21f bellard
    }
729 5391d806 bellard
}
730 5391d806 bellard
731 98087450 bellard
static int ide_write_dma_cb(IDEState *s, 
732 98087450 bellard
                            target_phys_addr_t phys_addr, 
733 98087450 bellard
                            int transfer_size1)
734 98087450 bellard
{
735 98087450 bellard
    int len, transfer_size, n;
736 98087450 bellard
    int64_t sector_num;
737 98087450 bellard
738 98087450 bellard
    transfer_size = transfer_size1;
739 98087450 bellard
    for(;;) {
740 98087450 bellard
        len = s->io_buffer_size - s->io_buffer_index;
741 98087450 bellard
        if (len == 0) {
742 98087450 bellard
            n = s->io_buffer_size >> 9;
743 98087450 bellard
            sector_num = ide_get_sector(s);
744 98087450 bellard
            bdrv_write(s->bs, sector_num, s->io_buffer, 
745 98087450 bellard
                       s->io_buffer_size >> 9);
746 98087450 bellard
            sector_num += n;
747 98087450 bellard
            ide_set_sector(s, sector_num);
748 98087450 bellard
            s->nsector -= n;
749 98087450 bellard
            n = s->nsector;
750 98087450 bellard
            if (n == 0) {
751 98087450 bellard
                /* end of transfer */
752 98087450 bellard
                s->status = READY_STAT | SEEK_STAT;
753 98087450 bellard
                ide_set_irq(s);
754 98087450 bellard
                return 0;
755 98087450 bellard
            }
756 98087450 bellard
            if (n > MAX_MULT_SECTORS)
757 98087450 bellard
                n = MAX_MULT_SECTORS;
758 98087450 bellard
            s->io_buffer_index = 0;
759 98087450 bellard
            s->io_buffer_size = n * 512;
760 98087450 bellard
            len = s->io_buffer_size;
761 98087450 bellard
        }
762 98087450 bellard
        if (transfer_size <= 0)
763 98087450 bellard
            break;
764 98087450 bellard
        if (len > transfer_size)
765 98087450 bellard
            len = transfer_size;
766 98087450 bellard
        cpu_physical_memory_read(phys_addr, 
767 98087450 bellard
                                 s->io_buffer + s->io_buffer_index, len);
768 98087450 bellard
        s->io_buffer_index += len;
769 98087450 bellard
        transfer_size -= len;
770 98087450 bellard
        phys_addr += len;
771 98087450 bellard
    }
772 98087450 bellard
    return transfer_size1 - transfer_size;
773 98087450 bellard
}
774 98087450 bellard
775 98087450 bellard
static void ide_sector_write_dma(IDEState *s)
776 98087450 bellard
{
777 98087450 bellard
    int n;
778 98087450 bellard
    s->status = READY_STAT | SEEK_STAT | DRQ_STAT;
779 98087450 bellard
    n = s->nsector;
780 98087450 bellard
    if (n > MAX_MULT_SECTORS)
781 98087450 bellard
        n = MAX_MULT_SECTORS;
782 98087450 bellard
    s->io_buffer_index = 0;
783 98087450 bellard
    s->io_buffer_size = n * 512;
784 98087450 bellard
    ide_dma_start(s, ide_write_dma_cb);
785 98087450 bellard
}
786 98087450 bellard
787 5391d806 bellard
static void ide_atapi_cmd_ok(IDEState *s)
788 5391d806 bellard
{
789 5391d806 bellard
    s->error = 0;
790 5391d806 bellard
    s->status = READY_STAT;
791 5391d806 bellard
    s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
792 5391d806 bellard
    ide_set_irq(s);
793 5391d806 bellard
}
794 5391d806 bellard
795 5391d806 bellard
static void ide_atapi_cmd_error(IDEState *s, int sense_key, int asc)
796 5391d806 bellard
{
797 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
798 5391d806 bellard
    printf("atapi_cmd_error: sense=0x%x asc=0x%x\n", sense_key, asc);
799 5391d806 bellard
#endif
800 5391d806 bellard
    s->error = sense_key << 4;
801 5391d806 bellard
    s->status = READY_STAT | ERR_STAT;
802 5391d806 bellard
    s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
803 5391d806 bellard
    s->sense_key = sense_key;
804 5391d806 bellard
    s->asc = asc;
805 5391d806 bellard
    ide_set_irq(s);
806 5391d806 bellard
}
807 5391d806 bellard
808 5391d806 bellard
static inline void cpu_to_ube16(uint8_t *buf, int val)
809 5391d806 bellard
{
810 5391d806 bellard
    buf[0] = val >> 8;
811 5391d806 bellard
    buf[1] = val;
812 5391d806 bellard
}
813 5391d806 bellard
814 5391d806 bellard
static inline void cpu_to_ube32(uint8_t *buf, unsigned int val)
815 5391d806 bellard
{
816 5391d806 bellard
    buf[0] = val >> 24;
817 5391d806 bellard
    buf[1] = val >> 16;
818 5391d806 bellard
    buf[2] = val >> 8;
819 5391d806 bellard
    buf[3] = val;
820 5391d806 bellard
}
821 5391d806 bellard
822 5391d806 bellard
static inline int ube16_to_cpu(const uint8_t *buf)
823 5391d806 bellard
{
824 5391d806 bellard
    return (buf[0] << 8) | buf[1];
825 5391d806 bellard
}
826 5391d806 bellard
827 5391d806 bellard
static inline int ube32_to_cpu(const uint8_t *buf)
828 5391d806 bellard
{
829 5391d806 bellard
    return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
830 5391d806 bellard
}
831 5391d806 bellard
832 98087450 bellard
static void lba_to_msf(uint8_t *buf, int lba)
833 98087450 bellard
{
834 98087450 bellard
    lba += 150;
835 98087450 bellard
    buf[0] = (lba / 75) / 60;
836 98087450 bellard
    buf[1] = (lba / 75) % 60;
837 98087450 bellard
    buf[2] = lba % 75;
838 98087450 bellard
}
839 98087450 bellard
840 98087450 bellard
static void cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf, 
841 98087450 bellard
                           int sector_size)
842 98087450 bellard
{
843 98087450 bellard
    switch(sector_size) {
844 98087450 bellard
    case 2048:
845 98087450 bellard
        bdrv_read(bs, (int64_t)lba << 2, buf, 4);
846 98087450 bellard
        break;
847 98087450 bellard
    case 2352:
848 98087450 bellard
        /* sync bytes */
849 98087450 bellard
        buf[0] = 0x00;
850 5457c8ce bellard
        memset(buf + 1, 0xff, 10);
851 5457c8ce bellard
        buf[11] = 0x00;
852 98087450 bellard
        buf += 12;
853 98087450 bellard
        /* MSF */
854 98087450 bellard
        lba_to_msf(buf, lba);
855 98087450 bellard
        buf[3] = 0x01; /* mode 1 data */
856 98087450 bellard
        buf += 4;
857 98087450 bellard
        /* data */
858 98087450 bellard
        bdrv_read(bs, (int64_t)lba << 2, buf, 4);
859 98087450 bellard
        buf += 2048;
860 98087450 bellard
        /* ECC */
861 98087450 bellard
        memset(buf, 0, 288);
862 98087450 bellard
        break;
863 98087450 bellard
    default:
864 98087450 bellard
        break;
865 98087450 bellard
    }
866 98087450 bellard
}
867 98087450 bellard
868 5391d806 bellard
/* The whole ATAPI transfer logic is handled in this function */
869 5391d806 bellard
static void ide_atapi_cmd_reply_end(IDEState *s)
870 5391d806 bellard
{
871 5391d806 bellard
    int byte_count_limit, size;
872 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
873 5391d806 bellard
    printf("reply: tx_size=%d elem_tx_size=%d index=%d\n", 
874 5391d806 bellard
           s->packet_transfer_size,
875 5391d806 bellard
           s->elementary_transfer_size,
876 5391d806 bellard
           s->io_buffer_index);
877 5391d806 bellard
#endif
878 5391d806 bellard
    if (s->packet_transfer_size <= 0) {
879 5391d806 bellard
        /* end of transfer */
880 5391d806 bellard
        ide_transfer_stop(s);
881 5391d806 bellard
        s->status = READY_STAT;
882 5391d806 bellard
        s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
883 5391d806 bellard
        ide_set_irq(s);
884 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
885 5391d806 bellard
        printf("status=0x%x\n", s->status);
886 5391d806 bellard
#endif
887 5391d806 bellard
    } else {
888 5391d806 bellard
        /* see if a new sector must be read */
889 98087450 bellard
        if (s->lba != -1 && s->io_buffer_index >= s->cd_sector_size) {
890 98087450 bellard
            cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size);
891 5391d806 bellard
            s->lba++;
892 5391d806 bellard
            s->io_buffer_index = 0;
893 5391d806 bellard
        }
894 5391d806 bellard
        if (s->elementary_transfer_size > 0) {
895 5391d806 bellard
            /* there are some data left to transmit in this elementary
896 5391d806 bellard
               transfer */
897 98087450 bellard
            size = s->cd_sector_size - s->io_buffer_index;
898 5391d806 bellard
            if (size > s->elementary_transfer_size)
899 5391d806 bellard
                size = s->elementary_transfer_size;
900 5391d806 bellard
            ide_transfer_start(s, s->io_buffer + s->io_buffer_index, 
901 5391d806 bellard
                               size, ide_atapi_cmd_reply_end);
902 5391d806 bellard
            s->packet_transfer_size -= size;
903 5391d806 bellard
            s->elementary_transfer_size -= size;
904 5391d806 bellard
            s->io_buffer_index += size;
905 5391d806 bellard
        } else {
906 5391d806 bellard
            /* a new transfer is needed */
907 5391d806 bellard
            s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO;
908 5391d806 bellard
            byte_count_limit = s->lcyl | (s->hcyl << 8);
909 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
910 5391d806 bellard
            printf("byte_count_limit=%d\n", byte_count_limit);
911 5391d806 bellard
#endif
912 5391d806 bellard
            if (byte_count_limit == 0xffff)
913 5391d806 bellard
                byte_count_limit--;
914 5391d806 bellard
            size = s->packet_transfer_size;
915 5391d806 bellard
            if (size > byte_count_limit) {
916 5391d806 bellard
                /* byte count limit must be even if this case */
917 5391d806 bellard
                if (byte_count_limit & 1)
918 5391d806 bellard
                    byte_count_limit--;
919 5391d806 bellard
                size = byte_count_limit;
920 5391d806 bellard
            }
921 a136e5a8 bellard
            s->lcyl = size;
922 a136e5a8 bellard
            s->hcyl = size >> 8;
923 5391d806 bellard
            s->elementary_transfer_size = size;
924 5391d806 bellard
            /* we cannot transmit more than one sector at a time */
925 5391d806 bellard
            if (s->lba != -1) {
926 98087450 bellard
                if (size > (s->cd_sector_size - s->io_buffer_index))
927 98087450 bellard
                    size = (s->cd_sector_size - s->io_buffer_index);
928 5391d806 bellard
            }
929 5391d806 bellard
            ide_transfer_start(s, s->io_buffer + s->io_buffer_index, 
930 5391d806 bellard
                               size, ide_atapi_cmd_reply_end);
931 5391d806 bellard
            s->packet_transfer_size -= size;
932 5391d806 bellard
            s->elementary_transfer_size -= size;
933 5391d806 bellard
            s->io_buffer_index += size;
934 5391d806 bellard
            ide_set_irq(s);
935 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
936 5391d806 bellard
            printf("status=0x%x\n", s->status);
937 5391d806 bellard
#endif
938 5391d806 bellard
        }
939 5391d806 bellard
    }
940 5391d806 bellard
}
941 5391d806 bellard
942 5391d806 bellard
/* send a reply of 'size' bytes in s->io_buffer to an ATAPI command */
943 5391d806 bellard
static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size)
944 5391d806 bellard
{
945 5391d806 bellard
    if (size > max_size)
946 5391d806 bellard
        size = max_size;
947 5391d806 bellard
    s->lba = -1; /* no sector read */
948 5391d806 bellard
    s->packet_transfer_size = size;
949 5391d806 bellard
    s->elementary_transfer_size = 0;
950 5391d806 bellard
    s->io_buffer_index = 0;
951 5391d806 bellard
952 5391d806 bellard
    s->status = READY_STAT;
953 5391d806 bellard
    ide_atapi_cmd_reply_end(s);
954 5391d806 bellard
}
955 5391d806 bellard
956 5391d806 bellard
/* start a CD-CDROM read command */
957 98087450 bellard
static void ide_atapi_cmd_read_pio(IDEState *s, int lba, int nb_sectors,
958 98087450 bellard
                                   int sector_size)
959 5391d806 bellard
{
960 5391d806 bellard
    s->lba = lba;
961 98087450 bellard
    s->packet_transfer_size = nb_sectors * sector_size;
962 5391d806 bellard
    s->elementary_transfer_size = 0;
963 98087450 bellard
    s->io_buffer_index = sector_size;
964 98087450 bellard
    s->cd_sector_size = sector_size;
965 5391d806 bellard
966 5391d806 bellard
    s->status = READY_STAT;
967 5391d806 bellard
    ide_atapi_cmd_reply_end(s);
968 5391d806 bellard
}
969 5391d806 bellard
970 98087450 bellard
/* ATAPI DMA support */
971 98087450 bellard
static int ide_atapi_cmd_read_dma_cb(IDEState *s, 
972 98087450 bellard
                                     target_phys_addr_t phys_addr, 
973 98087450 bellard
                                     int transfer_size1)
974 98087450 bellard
{
975 98087450 bellard
    int len, transfer_size;
976 98087450 bellard
    
977 98087450 bellard
    transfer_size = transfer_size1;
978 98087450 bellard
    while (transfer_size > 0) {
979 5457c8ce bellard
#ifdef DEBUG_IDE_ATAPI
980 5457c8ce bellard
        printf("transfer_size: %d phys_addr=%08x\n", transfer_size, phys_addr);
981 5457c8ce bellard
#endif
982 98087450 bellard
        if (s->packet_transfer_size <= 0)
983 98087450 bellard
            break;
984 98087450 bellard
        len = s->cd_sector_size - s->io_buffer_index;
985 98087450 bellard
        if (len <= 0) {
986 98087450 bellard
            /* transfert next data */
987 98087450 bellard
            cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size);
988 98087450 bellard
            s->lba++;
989 98087450 bellard
            s->io_buffer_index = 0;
990 98087450 bellard
            len = s->cd_sector_size;
991 98087450 bellard
        }
992 98087450 bellard
        if (len > transfer_size)
993 98087450 bellard
            len = transfer_size;
994 98087450 bellard
        cpu_physical_memory_write(phys_addr, 
995 98087450 bellard
                                  s->io_buffer + s->io_buffer_index, len);
996 98087450 bellard
        s->packet_transfer_size -= len;
997 98087450 bellard
        s->io_buffer_index += len;
998 98087450 bellard
        transfer_size -= len;
999 98087450 bellard
        phys_addr += len;
1000 98087450 bellard
    }
1001 98087450 bellard
    if (s->packet_transfer_size <= 0) {
1002 98087450 bellard
        s->status = READY_STAT;
1003 98087450 bellard
        s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
1004 98087450 bellard
        ide_set_irq(s);
1005 98087450 bellard
#ifdef DEBUG_IDE_ATAPI
1006 98087450 bellard
        printf("dma status=0x%x\n", s->status);
1007 98087450 bellard
#endif
1008 98087450 bellard
        return 0;
1009 98087450 bellard
    }
1010 98087450 bellard
    return transfer_size1 - transfer_size;
1011 98087450 bellard
}
1012 98087450 bellard
1013 98087450 bellard
/* start a CD-CDROM read command with DMA */
1014 98087450 bellard
/* XXX: test if DMA is available */
1015 98087450 bellard
static void ide_atapi_cmd_read_dma(IDEState *s, int lba, int nb_sectors,
1016 98087450 bellard
                                   int sector_size)
1017 98087450 bellard
{
1018 98087450 bellard
    s->lba = lba;
1019 98087450 bellard
    s->packet_transfer_size = nb_sectors * sector_size;
1020 98087450 bellard
    s->io_buffer_index = sector_size;
1021 98087450 bellard
    s->cd_sector_size = sector_size;
1022 98087450 bellard
1023 98087450 bellard
    s->status = READY_STAT | DRQ_STAT;
1024 98087450 bellard
    ide_dma_start(s, ide_atapi_cmd_read_dma_cb);
1025 98087450 bellard
}
1026 98087450 bellard
1027 98087450 bellard
static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors, 
1028 98087450 bellard
                               int sector_size)
1029 98087450 bellard
{
1030 98087450 bellard
#ifdef DEBUG_IDE_ATAPI
1031 98087450 bellard
    printf("read: LBA=%d nb_sectors=%d\n", lba, nb_sectors);
1032 98087450 bellard
#endif
1033 98087450 bellard
    if (s->atapi_dma) {
1034 98087450 bellard
        ide_atapi_cmd_read_dma(s, lba, nb_sectors, sector_size);
1035 98087450 bellard
    } else {
1036 98087450 bellard
        ide_atapi_cmd_read_pio(s, lba, nb_sectors, sector_size);
1037 98087450 bellard
    }
1038 98087450 bellard
}
1039 98087450 bellard
1040 5391d806 bellard
/* same toc as bochs. Return -1 if error or the toc length */
1041 98087450 bellard
/* XXX: check this */
1042 5391d806 bellard
static int cdrom_read_toc(IDEState *s, uint8_t *buf, int msf, int start_track)
1043 5391d806 bellard
{
1044 5391d806 bellard
    uint8_t *q;
1045 5391d806 bellard
    int nb_sectors, len;
1046 5391d806 bellard
    
1047 5391d806 bellard
    if (start_track > 1 && start_track != 0xaa)
1048 5391d806 bellard
        return -1;
1049 5391d806 bellard
    q = buf + 2;
1050 98087450 bellard
    *q++ = 1; /* first session */
1051 98087450 bellard
    *q++ = 1; /* last session */
1052 5391d806 bellard
    if (start_track <= 1) {
1053 5391d806 bellard
        *q++ = 0; /* reserved */
1054 5391d806 bellard
        *q++ = 0x14; /* ADR, control */
1055 5391d806 bellard
        *q++ = 1;    /* track number */
1056 5391d806 bellard
        *q++ = 0; /* reserved */
1057 5391d806 bellard
        if (msf) {
1058 5391d806 bellard
            *q++ = 0; /* reserved */
1059 5457c8ce bellard
            lba_to_msf(q, 0);
1060 5457c8ce bellard
            q += 3;
1061 5391d806 bellard
        } else {
1062 5391d806 bellard
            /* sector 0 */
1063 5391d806 bellard
            cpu_to_ube32(q, 0);
1064 5391d806 bellard
            q += 4;
1065 5391d806 bellard
        }
1066 5391d806 bellard
    }
1067 5391d806 bellard
    /* lead out track */
1068 5391d806 bellard
    *q++ = 0; /* reserved */
1069 5391d806 bellard
    *q++ = 0x16; /* ADR, control */
1070 5391d806 bellard
    *q++ = 0xaa; /* track number */
1071 5391d806 bellard
    *q++ = 0; /* reserved */
1072 5391d806 bellard
    nb_sectors = s->nb_sectors >> 2;
1073 5391d806 bellard
    if (msf) {
1074 5391d806 bellard
        *q++ = 0; /* reserved */
1075 98087450 bellard
        lba_to_msf(q, nb_sectors);
1076 98087450 bellard
        q += 3;
1077 98087450 bellard
    } else {
1078 98087450 bellard
        cpu_to_ube32(q, nb_sectors);
1079 98087450 bellard
        q += 4;
1080 98087450 bellard
    }
1081 98087450 bellard
    len = q - buf;
1082 98087450 bellard
    cpu_to_ube16(buf, len - 2);
1083 98087450 bellard
    return len;
1084 98087450 bellard
}
1085 98087450 bellard
1086 98087450 bellard
/* mostly same info as PearPc */
1087 98087450 bellard
static int cdrom_read_toc_raw(IDEState *s, uint8_t *buf, int msf, 
1088 98087450 bellard
                              int session_num)
1089 98087450 bellard
{
1090 98087450 bellard
    uint8_t *q;
1091 98087450 bellard
    int nb_sectors, len;
1092 98087450 bellard
    
1093 98087450 bellard
    q = buf + 2;
1094 98087450 bellard
    *q++ = 1; /* first session */
1095 98087450 bellard
    *q++ = 1; /* last session */
1096 98087450 bellard
1097 98087450 bellard
    *q++ = 1; /* session number */
1098 98087450 bellard
    *q++ = 0x14; /* data track */
1099 98087450 bellard
    *q++ = 0; /* track number */
1100 98087450 bellard
    *q++ = 0xa0; /* lead-in */
1101 98087450 bellard
    *q++ = 0; /* min */
1102 98087450 bellard
    *q++ = 0; /* sec */
1103 98087450 bellard
    *q++ = 0; /* frame */
1104 98087450 bellard
    *q++ = 0;
1105 98087450 bellard
    *q++ = 1; /* first track */
1106 98087450 bellard
    *q++ = 0x00; /* disk type */
1107 98087450 bellard
    *q++ = 0x00;
1108 98087450 bellard
    
1109 98087450 bellard
    *q++ = 1; /* session number */
1110 98087450 bellard
    *q++ = 0x14; /* data track */
1111 98087450 bellard
    *q++ = 0; /* track number */
1112 98087450 bellard
    *q++ = 0xa1;
1113 98087450 bellard
    *q++ = 0; /* min */
1114 98087450 bellard
    *q++ = 0; /* sec */
1115 98087450 bellard
    *q++ = 0; /* frame */
1116 98087450 bellard
    *q++ = 0;
1117 98087450 bellard
    *q++ = 1; /* last track */
1118 98087450 bellard
    *q++ = 0x00;
1119 98087450 bellard
    *q++ = 0x00;
1120 98087450 bellard
    
1121 98087450 bellard
    *q++ = 1; /* session number */
1122 98087450 bellard
    *q++ = 0x14; /* data track */
1123 98087450 bellard
    *q++ = 0; /* track number */
1124 98087450 bellard
    *q++ = 0xa2; /* lead-out */
1125 98087450 bellard
    *q++ = 0; /* min */
1126 98087450 bellard
    *q++ = 0; /* sec */
1127 98087450 bellard
    *q++ = 0; /* frame */
1128 98087450 bellard
    nb_sectors = s->nb_sectors >> 2;
1129 98087450 bellard
    if (msf) {
1130 98087450 bellard
        *q++ = 0; /* reserved */
1131 98087450 bellard
        lba_to_msf(q, nb_sectors);
1132 98087450 bellard
        q += 3;
1133 5391d806 bellard
    } else {
1134 5391d806 bellard
        cpu_to_ube32(q, nb_sectors);
1135 5391d806 bellard
        q += 4;
1136 5391d806 bellard
    }
1137 98087450 bellard
1138 98087450 bellard
    *q++ = 1; /* session number */
1139 98087450 bellard
    *q++ = 0x14; /* ADR, control */
1140 98087450 bellard
    *q++ = 0;    /* track number */
1141 98087450 bellard
    *q++ = 1;    /* point */
1142 98087450 bellard
    *q++ = 0; /* min */
1143 98087450 bellard
    *q++ = 0; /* sec */
1144 98087450 bellard
    *q++ = 0; /* frame */
1145 a368741b bellard
    if (msf) {
1146 a368741b bellard
        *q++ = 0; 
1147 a368741b bellard
        lba_to_msf(q, 0);
1148 a368741b bellard
        q += 3;
1149 a368741b bellard
    } else {
1150 a368741b bellard
        *q++ = 0; 
1151 a368741b bellard
        *q++ = 0; 
1152 a368741b bellard
        *q++ = 0; 
1153 a368741b bellard
        *q++ = 0; 
1154 a368741b bellard
    }
1155 98087450 bellard
1156 5391d806 bellard
    len = q - buf;
1157 5391d806 bellard
    cpu_to_ube16(buf, len - 2);
1158 5391d806 bellard
    return len;
1159 5391d806 bellard
}
1160 5391d806 bellard
1161 5391d806 bellard
static void ide_atapi_cmd(IDEState *s)
1162 5391d806 bellard
{
1163 5391d806 bellard
    const uint8_t *packet;
1164 5391d806 bellard
    uint8_t *buf;
1165 5391d806 bellard
    int max_len;
1166 5391d806 bellard
1167 5391d806 bellard
    packet = s->io_buffer;
1168 5391d806 bellard
    buf = s->io_buffer;
1169 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
1170 5391d806 bellard
    {
1171 5391d806 bellard
        int i;
1172 5391d806 bellard
        printf("ATAPI limit=0x%x packet:", s->lcyl | (s->hcyl << 8));
1173 5391d806 bellard
        for(i = 0; i < ATAPI_PACKET_SIZE; i++) {
1174 5391d806 bellard
            printf(" %02x", packet[i]);
1175 5391d806 bellard
        }
1176 5391d806 bellard
        printf("\n");
1177 5391d806 bellard
    }
1178 5391d806 bellard
#endif
1179 5391d806 bellard
    switch(s->io_buffer[0]) {
1180 5391d806 bellard
    case GPCMD_TEST_UNIT_READY:
1181 caed8802 bellard
        if (bdrv_is_inserted(s->bs)) {
1182 5391d806 bellard
            ide_atapi_cmd_ok(s);
1183 5391d806 bellard
        } else {
1184 5391d806 bellard
            ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1185 5391d806 bellard
                                ASC_MEDIUM_NOT_PRESENT);
1186 5391d806 bellard
        }
1187 5391d806 bellard
        break;
1188 5391d806 bellard
    case GPCMD_MODE_SENSE_10:
1189 5391d806 bellard
        {
1190 5391d806 bellard
            int action, code;
1191 5391d806 bellard
            max_len = ube16_to_cpu(packet + 7);
1192 5391d806 bellard
            action = packet[2] >> 6;
1193 5391d806 bellard
            code = packet[2] & 0x3f;
1194 5391d806 bellard
            switch(action) {
1195 5391d806 bellard
            case 0: /* current values */
1196 5391d806 bellard
                switch(code) {
1197 5391d806 bellard
                case 0x01: /* error recovery */
1198 5391d806 bellard
                    cpu_to_ube16(&buf[0], 16 + 6);
1199 5391d806 bellard
                    buf[2] = 0x70;
1200 5391d806 bellard
                    buf[3] = 0;
1201 5391d806 bellard
                    buf[4] = 0;
1202 5391d806 bellard
                    buf[5] = 0;
1203 5391d806 bellard
                    buf[6] = 0;
1204 5391d806 bellard
                    buf[7] = 0;
1205 5391d806 bellard
1206 5391d806 bellard
                    buf[8] = 0x01;
1207 5391d806 bellard
                    buf[9] = 0x06;
1208 5391d806 bellard
                    buf[10] = 0x00;
1209 5391d806 bellard
                    buf[11] = 0x05;
1210 5391d806 bellard
                    buf[12] = 0x00;
1211 5391d806 bellard
                    buf[13] = 0x00;
1212 5391d806 bellard
                    buf[14] = 0x00;
1213 5391d806 bellard
                    buf[15] = 0x00;
1214 5391d806 bellard
                    ide_atapi_cmd_reply(s, 16, max_len);
1215 5391d806 bellard
                    break;
1216 5391d806 bellard
                case 0x2a:
1217 5391d806 bellard
                    cpu_to_ube16(&buf[0], 28 + 6);
1218 5391d806 bellard
                    buf[2] = 0x70;
1219 5391d806 bellard
                    buf[3] = 0;
1220 5391d806 bellard
                    buf[4] = 0;
1221 5391d806 bellard
                    buf[5] = 0;
1222 5391d806 bellard
                    buf[6] = 0;
1223 5391d806 bellard
                    buf[7] = 0;
1224 5391d806 bellard
1225 5391d806 bellard
                    buf[8] = 0x2a;
1226 5391d806 bellard
                    buf[9] = 0x12;
1227 5391d806 bellard
                    buf[10] = 0x00;
1228 5391d806 bellard
                    buf[11] = 0x00;
1229 5391d806 bellard
                    
1230 5391d806 bellard
                    buf[12] = 0x70;
1231 5391d806 bellard
                    buf[13] = 3 << 5;
1232 5391d806 bellard
                    buf[14] = (1 << 0) | (1 << 3) | (1 << 5);
1233 caed8802 bellard
                    if (bdrv_is_locked(s->bs))
1234 5391d806 bellard
                        buf[6] |= 1 << 1;
1235 5391d806 bellard
                    buf[15] = 0x00;
1236 5391d806 bellard
                    cpu_to_ube16(&buf[16], 706);
1237 5391d806 bellard
                    buf[18] = 0;
1238 5391d806 bellard
                    buf[19] = 2;
1239 5391d806 bellard
                    cpu_to_ube16(&buf[20], 512);
1240 5391d806 bellard
                    cpu_to_ube16(&buf[22], 706);
1241 5391d806 bellard
                    buf[24] = 0;
1242 5391d806 bellard
                    buf[25] = 0;
1243 5391d806 bellard
                    buf[26] = 0;
1244 5391d806 bellard
                    buf[27] = 0;
1245 5391d806 bellard
                    ide_atapi_cmd_reply(s, 28, max_len);
1246 5391d806 bellard
                    break;
1247 5391d806 bellard
                default:
1248 5391d806 bellard
                    goto error_cmd;
1249 5391d806 bellard
                }
1250 5391d806 bellard
                break;
1251 5391d806 bellard
            case 1: /* changeable values */
1252 5391d806 bellard
                goto error_cmd;
1253 5391d806 bellard
            case 2: /* default values */
1254 5391d806 bellard
                goto error_cmd;
1255 5391d806 bellard
            default:
1256 5391d806 bellard
            case 3: /* saved values */
1257 5391d806 bellard
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1258 5391d806 bellard
                                    ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
1259 5391d806 bellard
                break;
1260 5391d806 bellard
            }
1261 5391d806 bellard
        }
1262 5391d806 bellard
        break;
1263 5391d806 bellard
    case GPCMD_REQUEST_SENSE:
1264 5391d806 bellard
        max_len = packet[4];
1265 5391d806 bellard
        memset(buf, 0, 18);
1266 5391d806 bellard
        buf[0] = 0x70 | (1 << 7);
1267 5391d806 bellard
        buf[2] = s->sense_key;
1268 5391d806 bellard
        buf[7] = 10;
1269 5391d806 bellard
        buf[12] = s->asc;
1270 5391d806 bellard
        ide_atapi_cmd_reply(s, 18, max_len);
1271 5391d806 bellard
        break;
1272 5391d806 bellard
    case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
1273 caed8802 bellard
        if (bdrv_is_inserted(s->bs)) {
1274 caed8802 bellard
            bdrv_set_locked(s->bs, packet[4] & 1);
1275 5391d806 bellard
            ide_atapi_cmd_ok(s);
1276 5391d806 bellard
        } else {
1277 5391d806 bellard
            ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1278 5391d806 bellard
                                ASC_MEDIUM_NOT_PRESENT);
1279 5391d806 bellard
        }
1280 5391d806 bellard
        break;
1281 5391d806 bellard
    case GPCMD_READ_10:
1282 5391d806 bellard
    case GPCMD_READ_12:
1283 5391d806 bellard
        {
1284 5391d806 bellard
            int nb_sectors, lba;
1285 5391d806 bellard
1286 caed8802 bellard
            if (!bdrv_is_inserted(s->bs)) {
1287 5391d806 bellard
                ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1288 5391d806 bellard
                                    ASC_MEDIUM_NOT_PRESENT);
1289 5391d806 bellard
                break;
1290 5391d806 bellard
            }
1291 5391d806 bellard
            if (packet[0] == GPCMD_READ_10)
1292 5391d806 bellard
                nb_sectors = ube16_to_cpu(packet + 7);
1293 5391d806 bellard
            else
1294 5391d806 bellard
                nb_sectors = ube32_to_cpu(packet + 6);
1295 5391d806 bellard
            lba = ube32_to_cpu(packet + 2);
1296 5391d806 bellard
            if (nb_sectors == 0) {
1297 5391d806 bellard
                ide_atapi_cmd_ok(s);
1298 5391d806 bellard
                break;
1299 5391d806 bellard
            }
1300 5391d806 bellard
            if (((int64_t)(lba + nb_sectors) << 2) > s->nb_sectors) {
1301 5391d806 bellard
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1302 5391d806 bellard
                                    ASC_LOGICAL_BLOCK_OOR);
1303 5391d806 bellard
                break;
1304 5391d806 bellard
            }
1305 98087450 bellard
            ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
1306 98087450 bellard
        }
1307 98087450 bellard
        break;
1308 98087450 bellard
    case GPCMD_READ_CD:
1309 98087450 bellard
        {
1310 98087450 bellard
            int nb_sectors, lba, transfer_request;
1311 98087450 bellard
1312 98087450 bellard
            if (!bdrv_is_inserted(s->bs)) {
1313 98087450 bellard
                ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1314 98087450 bellard
                                    ASC_MEDIUM_NOT_PRESENT);
1315 98087450 bellard
                break;
1316 98087450 bellard
            }
1317 98087450 bellard
            nb_sectors = (packet[6] << 16) | (packet[7] << 8) | packet[8];
1318 98087450 bellard
            lba = ube32_to_cpu(packet + 2);
1319 98087450 bellard
            if (nb_sectors == 0) {
1320 98087450 bellard
                ide_atapi_cmd_ok(s);
1321 98087450 bellard
                break;
1322 98087450 bellard
            }
1323 98087450 bellard
            if (((int64_t)(lba + nb_sectors) << 2) > s->nb_sectors) {
1324 98087450 bellard
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1325 98087450 bellard
                                    ASC_LOGICAL_BLOCK_OOR);
1326 98087450 bellard
                break;
1327 98087450 bellard
            }
1328 98087450 bellard
            transfer_request = packet[9];
1329 98087450 bellard
            switch(transfer_request & 0xf8) {
1330 98087450 bellard
            case 0x00:
1331 98087450 bellard
                /* nothing */
1332 98087450 bellard
                ide_atapi_cmd_ok(s);
1333 98087450 bellard
                break;
1334 98087450 bellard
            case 0x10:
1335 98087450 bellard
                /* normal read */
1336 98087450 bellard
                ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
1337 98087450 bellard
                break;
1338 98087450 bellard
            case 0xf8:
1339 98087450 bellard
                /* read all data */
1340 98087450 bellard
                ide_atapi_cmd_read(s, lba, nb_sectors, 2352);
1341 98087450 bellard
                break;
1342 98087450 bellard
            default:
1343 98087450 bellard
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1344 98087450 bellard
                                    ASC_INV_FIELD_IN_CMD_PACKET);
1345 98087450 bellard
                break;
1346 98087450 bellard
            }
1347 5391d806 bellard
        }
1348 5391d806 bellard
        break;
1349 5391d806 bellard
    case GPCMD_SEEK:
1350 5391d806 bellard
        {
1351 5391d806 bellard
            int lba;
1352 caed8802 bellard
            if (!bdrv_is_inserted(s->bs)) {
1353 5391d806 bellard
                ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1354 5391d806 bellard
                                    ASC_MEDIUM_NOT_PRESENT);
1355 5391d806 bellard
                break;
1356 5391d806 bellard
            }
1357 5391d806 bellard
            lba = ube32_to_cpu(packet + 2);
1358 5391d806 bellard
            if (((int64_t)lba << 2) > s->nb_sectors) {
1359 5391d806 bellard
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1360 5391d806 bellard
                                    ASC_LOGICAL_BLOCK_OOR);
1361 5391d806 bellard
                break;
1362 5391d806 bellard
            }
1363 5391d806 bellard
            ide_atapi_cmd_ok(s);
1364 5391d806 bellard
        }
1365 5391d806 bellard
        break;
1366 5391d806 bellard
    case GPCMD_START_STOP_UNIT:
1367 5391d806 bellard
        {
1368 5391d806 bellard
            int start, eject;
1369 5391d806 bellard
            start = packet[4] & 1;
1370 5391d806 bellard
            eject = (packet[4] >> 1) & 1;
1371 5391d806 bellard
            
1372 caed8802 bellard
            if (eject && !start) {
1373 caed8802 bellard
                /* eject the disk */
1374 caed8802 bellard
                bdrv_close(s->bs);
1375 caed8802 bellard
            }
1376 5391d806 bellard
            ide_atapi_cmd_ok(s);
1377 5391d806 bellard
        }
1378 5391d806 bellard
        break;
1379 5391d806 bellard
    case GPCMD_MECHANISM_STATUS:
1380 5391d806 bellard
        {
1381 5391d806 bellard
            max_len = ube16_to_cpu(packet + 8);
1382 5391d806 bellard
            cpu_to_ube16(buf, 0);
1383 5391d806 bellard
            /* no current LBA */
1384 5391d806 bellard
            buf[2] = 0;
1385 5391d806 bellard
            buf[3] = 0;
1386 5391d806 bellard
            buf[4] = 0;
1387 5391d806 bellard
            buf[5] = 1;
1388 5391d806 bellard
            cpu_to_ube16(buf + 6, 0);
1389 5391d806 bellard
            ide_atapi_cmd_reply(s, 8, max_len);
1390 5391d806 bellard
        }
1391 5391d806 bellard
        break;
1392 5391d806 bellard
    case GPCMD_READ_TOC_PMA_ATIP:
1393 5391d806 bellard
        {
1394 5391d806 bellard
            int format, msf, start_track, len;
1395 5391d806 bellard
1396 caed8802 bellard
            if (!bdrv_is_inserted(s->bs)) {
1397 5391d806 bellard
                ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1398 5391d806 bellard
                                    ASC_MEDIUM_NOT_PRESENT);
1399 5391d806 bellard
                break;
1400 5391d806 bellard
            }
1401 5391d806 bellard
            max_len = ube16_to_cpu(packet + 7);
1402 5391d806 bellard
            format = packet[9] >> 6;
1403 5391d806 bellard
            msf = (packet[1] >> 1) & 1;
1404 5391d806 bellard
            start_track = packet[6];
1405 5391d806 bellard
            switch(format) {
1406 5391d806 bellard
            case 0:
1407 5391d806 bellard
                len = cdrom_read_toc(s, buf, msf, start_track);
1408 5391d806 bellard
                if (len < 0)
1409 5391d806 bellard
                    goto error_cmd;
1410 5391d806 bellard
                ide_atapi_cmd_reply(s, len, max_len);
1411 5391d806 bellard
                break;
1412 5391d806 bellard
            case 1:
1413 5391d806 bellard
                /* multi session : only a single session defined */
1414 5391d806 bellard
                memset(buf, 0, 12);
1415 5391d806 bellard
                buf[1] = 0x0a;
1416 5391d806 bellard
                buf[2] = 0x01;
1417 5391d806 bellard
                buf[3] = 0x01;
1418 5391d806 bellard
                ide_atapi_cmd_reply(s, 12, max_len);
1419 5391d806 bellard
                break;
1420 98087450 bellard
            case 2:
1421 98087450 bellard
                len = cdrom_read_toc_raw(s, buf, msf, start_track);
1422 98087450 bellard
                if (len < 0)
1423 98087450 bellard
                    goto error_cmd;
1424 98087450 bellard
                ide_atapi_cmd_reply(s, len, max_len);
1425 98087450 bellard
                break;
1426 5391d806 bellard
            default:
1427 7f777bf3 bellard
            error_cmd:
1428 7f777bf3 bellard
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1429 7f777bf3 bellard
                                    ASC_INV_FIELD_IN_CMD_PACKET);
1430 7f777bf3 bellard
                break;
1431 5391d806 bellard
            }
1432 5391d806 bellard
        }
1433 5391d806 bellard
        break;
1434 5391d806 bellard
    case GPCMD_READ_CDVD_CAPACITY:
1435 caed8802 bellard
        if (!bdrv_is_inserted(s->bs)) {
1436 5391d806 bellard
            ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1437 5391d806 bellard
                                ASC_MEDIUM_NOT_PRESENT);
1438 5391d806 bellard
            break;
1439 5391d806 bellard
        }
1440 5391d806 bellard
        /* NOTE: it is really the number of sectors minus 1 */
1441 5391d806 bellard
        cpu_to_ube32(buf, (s->nb_sectors >> 2) - 1);
1442 5391d806 bellard
        cpu_to_ube32(buf + 4, 2048);
1443 5391d806 bellard
        ide_atapi_cmd_reply(s, 8, 8);
1444 5391d806 bellard
        break;
1445 bd0d90b2 bellard
    case GPCMD_INQUIRY:
1446 bd0d90b2 bellard
        max_len = packet[4];
1447 bd0d90b2 bellard
        buf[0] = 0x05; /* CD-ROM */
1448 bd0d90b2 bellard
        buf[1] = 0x80; /* removable */
1449 bd0d90b2 bellard
        buf[2] = 0x00; /* ISO */
1450 bd0d90b2 bellard
        buf[3] = 0x21; /* ATAPI-2 (XXX: put ATAPI-4 ?) */
1451 bd0d90b2 bellard
        buf[4] = 31; /* additionnal length */
1452 bd0d90b2 bellard
        buf[5] = 0; /* reserved */
1453 bd0d90b2 bellard
        buf[6] = 0; /* reserved */
1454 bd0d90b2 bellard
        buf[7] = 0; /* reserved */
1455 bd0d90b2 bellard
        padstr8(buf + 8, 8, "QEMU");
1456 bd0d90b2 bellard
        padstr8(buf + 16, 16, "QEMU CD-ROM");
1457 bd0d90b2 bellard
        padstr8(buf + 32, 4, QEMU_VERSION);
1458 bd0d90b2 bellard
        ide_atapi_cmd_reply(s, 36, max_len);
1459 bd0d90b2 bellard
        break;
1460 5391d806 bellard
    default:
1461 5391d806 bellard
        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1462 7f777bf3 bellard
                            ASC_ILLEGAL_OPCODE);
1463 5391d806 bellard
        break;
1464 5391d806 bellard
    }
1465 5391d806 bellard
}
1466 5391d806 bellard
1467 caed8802 bellard
/* called when the inserted state of the media has changed */
1468 caed8802 bellard
static void cdrom_change_cb(void *opaque)
1469 5391d806 bellard
{
1470 caed8802 bellard
    IDEState *s = opaque;
1471 caed8802 bellard
    int64_t nb_sectors;
1472 caed8802 bellard
1473 caed8802 bellard
    /* XXX: send interrupt too */
1474 caed8802 bellard
    bdrv_get_geometry(s->bs, &nb_sectors);
1475 caed8802 bellard
    s->nb_sectors = nb_sectors;
1476 caed8802 bellard
}
1477 caed8802 bellard
1478 caed8802 bellard
static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
1479 caed8802 bellard
{
1480 caed8802 bellard
    IDEState *ide_if = opaque;
1481 c45c3d00 bellard
    IDEState *s;
1482 5391d806 bellard
    int unit, n;
1483 5391d806 bellard
1484 5391d806 bellard
#ifdef DEBUG_IDE
1485 5391d806 bellard
    printf("IDE: write addr=0x%x val=0x%02x\n", addr, val);
1486 5391d806 bellard
#endif
1487 5391d806 bellard
    addr &= 7;
1488 5391d806 bellard
    switch(addr) {
1489 5391d806 bellard
    case 0:
1490 5391d806 bellard
        break;
1491 5391d806 bellard
    case 1:
1492 c45c3d00 bellard
        /* NOTE: data is written to the two drives */
1493 c45c3d00 bellard
        ide_if[0].feature = val;
1494 c45c3d00 bellard
        ide_if[1].feature = val;
1495 5391d806 bellard
        break;
1496 5391d806 bellard
    case 2:
1497 5391d806 bellard
        if (val == 0)
1498 5391d806 bellard
            val = 256;
1499 c45c3d00 bellard
        ide_if[0].nsector = val;
1500 c45c3d00 bellard
        ide_if[1].nsector = val;
1501 5391d806 bellard
        break;
1502 5391d806 bellard
    case 3:
1503 c45c3d00 bellard
        ide_if[0].sector = val;
1504 c45c3d00 bellard
        ide_if[1].sector = val;
1505 5391d806 bellard
        break;
1506 5391d806 bellard
    case 4:
1507 c45c3d00 bellard
        ide_if[0].lcyl = val;
1508 c45c3d00 bellard
        ide_if[1].lcyl = val;
1509 5391d806 bellard
        break;
1510 5391d806 bellard
    case 5:
1511 c45c3d00 bellard
        ide_if[0].hcyl = val;
1512 c45c3d00 bellard
        ide_if[1].hcyl = val;
1513 5391d806 bellard
        break;
1514 5391d806 bellard
    case 6:
1515 7ae98627 bellard
        ide_if[0].select = (val & ~0x10) | 0xa0;
1516 7ae98627 bellard
        ide_if[1].select = (val | 0x10) | 0xa0;
1517 5391d806 bellard
        /* select drive */
1518 5391d806 bellard
        unit = (val >> 4) & 1;
1519 5391d806 bellard
        s = ide_if + unit;
1520 5391d806 bellard
        ide_if->cur_drive = s;
1521 5391d806 bellard
        break;
1522 5391d806 bellard
    default:
1523 5391d806 bellard
    case 7:
1524 5391d806 bellard
        /* command */
1525 5391d806 bellard
#if defined(DEBUG_IDE)
1526 5391d806 bellard
        printf("ide: CMD=%02x\n", val);
1527 5391d806 bellard
#endif
1528 c45c3d00 bellard
        s = ide_if->cur_drive;
1529 66201e2d bellard
        /* ignore commands to non existant slave */
1530 66201e2d bellard
        if (s != ide_if && !s->bs) 
1531 66201e2d bellard
            break;
1532 5391d806 bellard
        switch(val) {
1533 5391d806 bellard
        case WIN_IDENTIFY:
1534 5391d806 bellard
            if (s->bs && !s->is_cdrom) {
1535 5391d806 bellard
                ide_identify(s);
1536 2a282056 bellard
                s->status = READY_STAT | SEEK_STAT;
1537 5391d806 bellard
                ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
1538 5391d806 bellard
            } else {
1539 5391d806 bellard
                if (s->is_cdrom) {
1540 5391d806 bellard
                    ide_set_signature(s);
1541 5391d806 bellard
                }
1542 5391d806 bellard
                ide_abort_command(s);
1543 5391d806 bellard
            }
1544 5391d806 bellard
            ide_set_irq(s);
1545 5391d806 bellard
            break;
1546 5391d806 bellard
        case WIN_SPECIFY:
1547 5391d806 bellard
        case WIN_RECAL:
1548 a136e5a8 bellard
            s->error = 0;
1549 769bec72 bellard
            s->status = READY_STAT | SEEK_STAT;
1550 5391d806 bellard
            ide_set_irq(s);
1551 5391d806 bellard
            break;
1552 5391d806 bellard
        case WIN_SETMULT:
1553 5391d806 bellard
            if (s->nsector > MAX_MULT_SECTORS || 
1554 5391d806 bellard
                s->nsector == 0 ||
1555 5391d806 bellard
                (s->nsector & (s->nsector - 1)) != 0) {
1556 5391d806 bellard
                ide_abort_command(s);
1557 5391d806 bellard
            } else {
1558 5391d806 bellard
                s->mult_sectors = s->nsector;
1559 5391d806 bellard
                s->status = READY_STAT;
1560 5391d806 bellard
            }
1561 5391d806 bellard
            ide_set_irq(s);
1562 5391d806 bellard
            break;
1563 4ce900b4 bellard
        case WIN_VERIFY:
1564 4ce900b4 bellard
        case WIN_VERIFY_ONCE:
1565 4ce900b4 bellard
            /* do sector number check ? */
1566 4ce900b4 bellard
            s->status = READY_STAT;
1567 4ce900b4 bellard
            ide_set_irq(s);
1568 4ce900b4 bellard
            break;
1569 5391d806 bellard
        case WIN_READ:
1570 5391d806 bellard
        case WIN_READ_ONCE:
1571 6b136f9e bellard
            if (!s->bs) 
1572 6b136f9e bellard
                goto abort_cmd;
1573 5391d806 bellard
            s->req_nb_sectors = 1;
1574 5391d806 bellard
            ide_sector_read(s);
1575 5391d806 bellard
            break;
1576 5391d806 bellard
        case WIN_WRITE:
1577 5391d806 bellard
        case WIN_WRITE_ONCE:
1578 a136e5a8 bellard
            s->error = 0;
1579 f66723fa bellard
            s->status = SEEK_STAT | READY_STAT;
1580 5391d806 bellard
            s->req_nb_sectors = 1;
1581 5391d806 bellard
            ide_transfer_start(s, s->io_buffer, 512, ide_sector_write);
1582 5391d806 bellard
            break;
1583 5391d806 bellard
        case WIN_MULTREAD:
1584 5391d806 bellard
            if (!s->mult_sectors)
1585 5391d806 bellard
                goto abort_cmd;
1586 5391d806 bellard
            s->req_nb_sectors = s->mult_sectors;
1587 5391d806 bellard
            ide_sector_read(s);
1588 5391d806 bellard
            break;
1589 5391d806 bellard
        case WIN_MULTWRITE:
1590 5391d806 bellard
            if (!s->mult_sectors)
1591 5391d806 bellard
                goto abort_cmd;
1592 a136e5a8 bellard
            s->error = 0;
1593 f66723fa bellard
            s->status = SEEK_STAT | READY_STAT;
1594 5391d806 bellard
            s->req_nb_sectors = s->mult_sectors;
1595 5391d806 bellard
            n = s->nsector;
1596 5391d806 bellard
            if (n > s->req_nb_sectors)
1597 5391d806 bellard
                n = s->req_nb_sectors;
1598 5391d806 bellard
            ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
1599 5391d806 bellard
            break;
1600 98087450 bellard
        case WIN_READDMA:
1601 98087450 bellard
        case WIN_READDMA_ONCE:
1602 98087450 bellard
            if (!s->bs) 
1603 98087450 bellard
                goto abort_cmd;
1604 98087450 bellard
            ide_sector_read_dma(s);
1605 98087450 bellard
            break;
1606 98087450 bellard
        case WIN_WRITEDMA:
1607 98087450 bellard
        case WIN_WRITEDMA_ONCE:
1608 98087450 bellard
            if (!s->bs) 
1609 98087450 bellard
                goto abort_cmd;
1610 98087450 bellard
            ide_sector_write_dma(s);
1611 98087450 bellard
            break;
1612 5391d806 bellard
        case WIN_READ_NATIVE_MAX:
1613 5391d806 bellard
            ide_set_sector(s, s->nb_sectors - 1);
1614 5391d806 bellard
            s->status = READY_STAT;
1615 5391d806 bellard
            ide_set_irq(s);
1616 5391d806 bellard
            break;
1617 a136e5a8 bellard
        case WIN_CHECKPOWERMODE1:
1618 a136e5a8 bellard
            s->nsector = 0xff; /* device active or idle */
1619 a136e5a8 bellard
            s->status = READY_STAT;
1620 a136e5a8 bellard
            ide_set_irq(s);
1621 a136e5a8 bellard
            break;
1622 34e538ae bellard
        case WIN_SETFEATURES:
1623 34e538ae bellard
            if (!s->bs)
1624 34e538ae bellard
                goto abort_cmd;
1625 34e538ae bellard
            /* XXX: valid for CDROM ? */
1626 34e538ae bellard
            switch(s->feature) {
1627 34e538ae bellard
            case 0x02: /* write cache enable */
1628 34e538ae bellard
            case 0x82: /* write cache disable */
1629 34e538ae bellard
            case 0xaa: /* read look-ahead enable */
1630 34e538ae bellard
            case 0x55: /* read look-ahead disable */
1631 e0fe67aa bellard
                s->status = READY_STAT | SEEK_STAT;
1632 34e538ae bellard
                ide_set_irq(s);
1633 34e538ae bellard
                break;
1634 94458802 bellard
            case 0x03: { /* set transfer mode */
1635 94458802 bellard
                uint8_t val = s->nsector & 0x07;
1636 94458802 bellard
1637 94458802 bellard
                switch (s->nsector >> 3) {
1638 94458802 bellard
                    case 0x00: /* pio default */
1639 94458802 bellard
                    case 0x01: /* pio mode */
1640 94458802 bellard
                        put_le16(s->identify_data + 63,0x07);
1641 94458802 bellard
                        put_le16(s->identify_data + 88,0x3f);
1642 94458802 bellard
                        break;
1643 94458802 bellard
                    case 0x04: /* mdma mode */
1644 94458802 bellard
                        put_le16(s->identify_data + 63,0x07 | (1 << (val + 8)));
1645 94458802 bellard
                        put_le16(s->identify_data + 88,0x3f);
1646 94458802 bellard
                        break;
1647 94458802 bellard
                    case 0x08: /* udma mode */
1648 94458802 bellard
                        put_le16(s->identify_data + 63,0x07);
1649 94458802 bellard
                        put_le16(s->identify_data + 88,0x3f | (1 << (val + 8)));
1650 94458802 bellard
                        break;
1651 94458802 bellard
                    default:
1652 94458802 bellard
                        goto abort_cmd;
1653 94458802 bellard
                }
1654 94458802 bellard
                s->status = READY_STAT | SEEK_STAT;
1655 94458802 bellard
                ide_set_irq(s);
1656 94458802 bellard
                break;
1657 94458802 bellard
            }
1658 34e538ae bellard
            default:
1659 34e538ae bellard
                goto abort_cmd;
1660 34e538ae bellard
            }
1661 34e538ae bellard
            break;
1662 a7dfe172 bellard
        case WIN_STANDBYNOW1:
1663 c451ee71 bellard
        case WIN_IDLEIMMEDIATE:
1664 5457c8ce bellard
        case WIN_FLUSH_CACHE:
1665 a7dfe172 bellard
            s->status = READY_STAT;
1666 a7dfe172 bellard
            ide_set_irq(s);
1667 a7dfe172 bellard
            break;
1668 5391d806 bellard
            /* ATAPI commands */
1669 5391d806 bellard
        case WIN_PIDENTIFY:
1670 5391d806 bellard
            if (s->is_cdrom) {
1671 5391d806 bellard
                ide_atapi_identify(s);
1672 1298fe63 bellard
                s->status = READY_STAT | SEEK_STAT;
1673 5391d806 bellard
                ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
1674 5391d806 bellard
            } else {
1675 5391d806 bellard
                ide_abort_command(s);
1676 5391d806 bellard
            }
1677 5391d806 bellard
            ide_set_irq(s);
1678 5391d806 bellard
            break;
1679 c451ee71 bellard
        case WIN_DIAGNOSE:
1680 c451ee71 bellard
            ide_set_signature(s);
1681 c451ee71 bellard
            s->status = 0x00; /* NOTE: READY is _not_ set */
1682 c451ee71 bellard
            s->error = 0x01;
1683 c451ee71 bellard
            break;
1684 5391d806 bellard
        case WIN_SRST:
1685 5391d806 bellard
            if (!s->is_cdrom)
1686 5391d806 bellard
                goto abort_cmd;
1687 5391d806 bellard
            ide_set_signature(s);
1688 6b136f9e bellard
            s->status = 0x00; /* NOTE: READY is _not_ set */
1689 5391d806 bellard
            s->error = 0x01;
1690 5391d806 bellard
            break;
1691 5391d806 bellard
        case WIN_PACKETCMD:
1692 5391d806 bellard
            if (!s->is_cdrom)
1693 5391d806 bellard
                goto abort_cmd;
1694 98087450 bellard
            /* overlapping commands not supported */
1695 98087450 bellard
            if (s->feature & 0x02)
1696 5391d806 bellard
                goto abort_cmd;
1697 98087450 bellard
            s->atapi_dma = s->feature & 1;
1698 5391d806 bellard
            s->nsector = 1;
1699 5391d806 bellard
            ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE, 
1700 5391d806 bellard
                               ide_atapi_cmd);
1701 5391d806 bellard
            break;
1702 5391d806 bellard
        default:
1703 5391d806 bellard
        abort_cmd:
1704 5391d806 bellard
            ide_abort_command(s);
1705 5391d806 bellard
            ide_set_irq(s);
1706 5391d806 bellard
            break;
1707 5391d806 bellard
        }
1708 5391d806 bellard
    }
1709 5391d806 bellard
}
1710 5391d806 bellard
1711 caed8802 bellard
static uint32_t ide_ioport_read(void *opaque, uint32_t addr1)
1712 5391d806 bellard
{
1713 7ae98627 bellard
    IDEState *ide_if = opaque;
1714 7ae98627 bellard
    IDEState *s = ide_if->cur_drive;
1715 5391d806 bellard
    uint32_t addr;
1716 5391d806 bellard
    int ret;
1717 5391d806 bellard
1718 5391d806 bellard
    addr = addr1 & 7;
1719 5391d806 bellard
    switch(addr) {
1720 5391d806 bellard
    case 0:
1721 5391d806 bellard
        ret = 0xff;
1722 5391d806 bellard
        break;
1723 5391d806 bellard
    case 1:
1724 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
1725 c45c3d00 bellard
            ret = 0;
1726 c45c3d00 bellard
        else
1727 c45c3d00 bellard
            ret = s->error;
1728 5391d806 bellard
        break;
1729 5391d806 bellard
    case 2:
1730 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
1731 c45c3d00 bellard
            ret = 0;
1732 c45c3d00 bellard
        else
1733 c45c3d00 bellard
            ret = s->nsector & 0xff;
1734 5391d806 bellard
        break;
1735 5391d806 bellard
    case 3:
1736 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
1737 c45c3d00 bellard
            ret = 0;
1738 c45c3d00 bellard
        else
1739 c45c3d00 bellard
            ret = s->sector;
1740 5391d806 bellard
        break;
1741 5391d806 bellard
    case 4:
1742 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
1743 c45c3d00 bellard
            ret = 0;
1744 c45c3d00 bellard
        else
1745 c45c3d00 bellard
            ret = s->lcyl;
1746 5391d806 bellard
        break;
1747 5391d806 bellard
    case 5:
1748 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
1749 c45c3d00 bellard
            ret = 0;
1750 c45c3d00 bellard
        else
1751 c45c3d00 bellard
            ret = s->hcyl;
1752 5391d806 bellard
        break;
1753 5391d806 bellard
    case 6:
1754 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
1755 c45c3d00 bellard
            ret = 0;
1756 c45c3d00 bellard
        else
1757 7ae98627 bellard
            ret = s->select;
1758 5391d806 bellard
        break;
1759 5391d806 bellard
    default:
1760 5391d806 bellard
    case 7:
1761 66201e2d bellard
        if ((!ide_if[0].bs && !ide_if[1].bs) ||
1762 66201e2d bellard
            (s != ide_if && !s->bs))
1763 c45c3d00 bellard
            ret = 0;
1764 c45c3d00 bellard
        else
1765 c45c3d00 bellard
            ret = s->status;
1766 5457c8ce bellard
        s->set_irq(s->irq_opaque, s->irq, 0);
1767 5391d806 bellard
        break;
1768 5391d806 bellard
    }
1769 5391d806 bellard
#ifdef DEBUG_IDE
1770 5391d806 bellard
    printf("ide: read addr=0x%x val=%02x\n", addr1, ret);
1771 5391d806 bellard
#endif
1772 5391d806 bellard
    return ret;
1773 5391d806 bellard
}
1774 5391d806 bellard
1775 caed8802 bellard
static uint32_t ide_status_read(void *opaque, uint32_t addr)
1776 5391d806 bellard
{
1777 7ae98627 bellard
    IDEState *ide_if = opaque;
1778 7ae98627 bellard
    IDEState *s = ide_if->cur_drive;
1779 5391d806 bellard
    int ret;
1780 7ae98627 bellard
1781 66201e2d bellard
    if ((!ide_if[0].bs && !ide_if[1].bs) ||
1782 66201e2d bellard
        (s != ide_if && !s->bs))
1783 7ae98627 bellard
        ret = 0;
1784 7ae98627 bellard
    else
1785 7ae98627 bellard
        ret = s->status;
1786 5391d806 bellard
#ifdef DEBUG_IDE
1787 5391d806 bellard
    printf("ide: read status addr=0x%x val=%02x\n", addr, ret);
1788 5391d806 bellard
#endif
1789 5391d806 bellard
    return ret;
1790 5391d806 bellard
}
1791 5391d806 bellard
1792 caed8802 bellard
static void ide_cmd_write(void *opaque, uint32_t addr, uint32_t val)
1793 5391d806 bellard
{
1794 caed8802 bellard
    IDEState *ide_if = opaque;
1795 5391d806 bellard
    IDEState *s;
1796 5391d806 bellard
    int i;
1797 5391d806 bellard
1798 5391d806 bellard
#ifdef DEBUG_IDE
1799 5391d806 bellard
    printf("ide: write control addr=0x%x val=%02x\n", addr, val);
1800 5391d806 bellard
#endif
1801 5391d806 bellard
    /* common for both drives */
1802 5391d806 bellard
    if (!(ide_if[0].cmd & IDE_CMD_RESET) &&
1803 5391d806 bellard
        (val & IDE_CMD_RESET)) {
1804 5391d806 bellard
        /* reset low to high */
1805 5391d806 bellard
        for(i = 0;i < 2; i++) {
1806 5391d806 bellard
            s = &ide_if[i];
1807 5391d806 bellard
            s->status = BUSY_STAT | SEEK_STAT;
1808 5391d806 bellard
            s->error = 0x01;
1809 5391d806 bellard
        }
1810 5391d806 bellard
    } else if ((ide_if[0].cmd & IDE_CMD_RESET) &&
1811 5391d806 bellard
               !(val & IDE_CMD_RESET)) {
1812 5391d806 bellard
        /* high to low */
1813 5391d806 bellard
        for(i = 0;i < 2; i++) {
1814 5391d806 bellard
            s = &ide_if[i];
1815 6b136f9e bellard
            if (s->is_cdrom)
1816 6b136f9e bellard
                s->status = 0x00; /* NOTE: READY is _not_ set */
1817 6b136f9e bellard
            else
1818 56bf1d37 bellard
                s->status = READY_STAT | SEEK_STAT;
1819 5391d806 bellard
            ide_set_signature(s);
1820 5391d806 bellard
        }
1821 5391d806 bellard
    }
1822 5391d806 bellard
1823 5391d806 bellard
    ide_if[0].cmd = val;
1824 5391d806 bellard
    ide_if[1].cmd = val;
1825 5391d806 bellard
}
1826 5391d806 bellard
1827 caed8802 bellard
static void ide_data_writew(void *opaque, uint32_t addr, uint32_t val)
1828 5391d806 bellard
{
1829 caed8802 bellard
    IDEState *s = ((IDEState *)opaque)->cur_drive;
1830 5391d806 bellard
    uint8_t *p;
1831 5391d806 bellard
1832 5391d806 bellard
    p = s->data_ptr;
1833 0c4ad8dc bellard
    *(uint16_t *)p = le16_to_cpu(val);
1834 5391d806 bellard
    p += 2;
1835 5391d806 bellard
    s->data_ptr = p;
1836 5391d806 bellard
    if (p >= s->data_end)
1837 5391d806 bellard
        s->end_transfer_func(s);
1838 5391d806 bellard
}
1839 5391d806 bellard
1840 caed8802 bellard
static uint32_t ide_data_readw(void *opaque, uint32_t addr)
1841 5391d806 bellard
{
1842 caed8802 bellard
    IDEState *s = ((IDEState *)opaque)->cur_drive;
1843 5391d806 bellard
    uint8_t *p;
1844 5391d806 bellard
    int ret;
1845 5391d806 bellard
    p = s->data_ptr;
1846 0c4ad8dc bellard
    ret = cpu_to_le16(*(uint16_t *)p);
1847 5391d806 bellard
    p += 2;
1848 5391d806 bellard
    s->data_ptr = p;
1849 5391d806 bellard
    if (p >= s->data_end)
1850 5391d806 bellard
        s->end_transfer_func(s);
1851 5391d806 bellard
    return ret;
1852 5391d806 bellard
}
1853 5391d806 bellard
1854 caed8802 bellard
static void ide_data_writel(void *opaque, uint32_t addr, uint32_t val)
1855 5391d806 bellard
{
1856 caed8802 bellard
    IDEState *s = ((IDEState *)opaque)->cur_drive;
1857 5391d806 bellard
    uint8_t *p;
1858 5391d806 bellard
1859 5391d806 bellard
    p = s->data_ptr;
1860 0c4ad8dc bellard
    *(uint32_t *)p = le32_to_cpu(val);
1861 5391d806 bellard
    p += 4;
1862 5391d806 bellard
    s->data_ptr = p;
1863 5391d806 bellard
    if (p >= s->data_end)
1864 5391d806 bellard
        s->end_transfer_func(s);
1865 5391d806 bellard
}
1866 5391d806 bellard
1867 caed8802 bellard
static uint32_t ide_data_readl(void *opaque, uint32_t addr)
1868 5391d806 bellard
{
1869 caed8802 bellard
    IDEState *s = ((IDEState *)opaque)->cur_drive;
1870 5391d806 bellard
    uint8_t *p;
1871 5391d806 bellard
    int ret;
1872 5391d806 bellard
    
1873 5391d806 bellard
    p = s->data_ptr;
1874 0c4ad8dc bellard
    ret = cpu_to_le32(*(uint32_t *)p);
1875 5391d806 bellard
    p += 4;
1876 5391d806 bellard
    s->data_ptr = p;
1877 5391d806 bellard
    if (p >= s->data_end)
1878 5391d806 bellard
        s->end_transfer_func(s);
1879 5391d806 bellard
    return ret;
1880 5391d806 bellard
}
1881 5391d806 bellard
1882 a7dfe172 bellard
static void ide_dummy_transfer_stop(IDEState *s)
1883 a7dfe172 bellard
{
1884 a7dfe172 bellard
    s->data_ptr = s->io_buffer;
1885 a7dfe172 bellard
    s->data_end = s->io_buffer;
1886 a7dfe172 bellard
    s->io_buffer[0] = 0xff;
1887 a7dfe172 bellard
    s->io_buffer[1] = 0xff;
1888 a7dfe172 bellard
    s->io_buffer[2] = 0xff;
1889 a7dfe172 bellard
    s->io_buffer[3] = 0xff;
1890 a7dfe172 bellard
}
1891 a7dfe172 bellard
1892 5391d806 bellard
static void ide_reset(IDEState *s)
1893 5391d806 bellard
{
1894 5391d806 bellard
    s->mult_sectors = MAX_MULT_SECTORS;
1895 5391d806 bellard
    s->cur_drive = s;
1896 5391d806 bellard
    s->select = 0xa0;
1897 5391d806 bellard
    s->status = READY_STAT;
1898 5391d806 bellard
    ide_set_signature(s);
1899 a7dfe172 bellard
    /* init the transfer handler so that 0xffff is returned on data
1900 a7dfe172 bellard
       accesses */
1901 a7dfe172 bellard
    s->end_transfer_func = ide_dummy_transfer_stop;
1902 a7dfe172 bellard
    ide_dummy_transfer_stop(s);
1903 5391d806 bellard
}
1904 5391d806 bellard
1905 5391d806 bellard
struct partition {
1906 5391d806 bellard
        uint8_t boot_ind;                /* 0x80 - active */
1907 5391d806 bellard
        uint8_t head;                /* starting head */
1908 5391d806 bellard
        uint8_t sector;                /* starting sector */
1909 5391d806 bellard
        uint8_t cyl;                /* starting cylinder */
1910 5391d806 bellard
        uint8_t sys_ind;                /* What partition type */
1911 5391d806 bellard
        uint8_t end_head;                /* end head */
1912 5391d806 bellard
        uint8_t end_sector;        /* end sector */
1913 5391d806 bellard
        uint8_t end_cyl;                /* end cylinder */
1914 5391d806 bellard
        uint32_t start_sect;        /* starting sector counting from 0 */
1915 5391d806 bellard
        uint32_t nr_sects;                /* nr of sectors in partition */
1916 5391d806 bellard
} __attribute__((packed));
1917 5391d806 bellard
1918 bf1b938f bellard
/* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */
1919 bf1b938f bellard
static int guess_disk_lchs(IDEState *s, 
1920 bf1b938f bellard
                           int *pcylinders, int *pheads, int *psectors)
1921 5391d806 bellard
{
1922 5391d806 bellard
    uint8_t buf[512];
1923 46d4767d bellard
    int ret, i, heads, sectors, cylinders;
1924 5391d806 bellard
    struct partition *p;
1925 5391d806 bellard
    uint32_t nr_sects;
1926 5391d806 bellard
1927 5391d806 bellard
    ret = bdrv_read(s->bs, 0, buf, 1);
1928 5391d806 bellard
    if (ret < 0)
1929 bf1b938f bellard
        return -1;
1930 5391d806 bellard
    /* test msdos magic */
1931 5391d806 bellard
    if (buf[510] != 0x55 || buf[511] != 0xaa)
1932 bf1b938f bellard
        return -1;
1933 5391d806 bellard
    for(i = 0; i < 4; i++) {
1934 5391d806 bellard
        p = ((struct partition *)(buf + 0x1be)) + i;
1935 0c4ad8dc bellard
        nr_sects = le32_to_cpu(p->nr_sects);
1936 5391d806 bellard
        if (nr_sects && p->end_head) {
1937 5391d806 bellard
            /* We make the assumption that the partition terminates on
1938 5391d806 bellard
               a cylinder boundary */
1939 46d4767d bellard
            heads = p->end_head + 1;
1940 46d4767d bellard
            sectors = p->end_sector & 63;
1941 46d4767d bellard
            if (sectors == 0)
1942 46d4767d bellard
                continue;
1943 46d4767d bellard
            cylinders = s->nb_sectors / (heads * sectors);
1944 46d4767d bellard
            if (cylinders < 1 || cylinders > 16383)
1945 46d4767d bellard
                continue;
1946 bf1b938f bellard
            *pheads = heads;
1947 bf1b938f bellard
            *psectors = sectors;
1948 bf1b938f bellard
            *pcylinders = cylinders;
1949 5391d806 bellard
#if 0
1950 bf1b938f bellard
            printf("guessed geometry: LCHS=%d %d %d\n", 
1951 bf1b938f bellard
                   cylinders, heads, sectors);
1952 5391d806 bellard
#endif
1953 bf1b938f bellard
            return 0;
1954 5391d806 bellard
        }
1955 5391d806 bellard
    }
1956 bf1b938f bellard
    return -1;
1957 5391d806 bellard
}
1958 5391d806 bellard
1959 5457c8ce bellard
static void ide_init2(IDEState *ide_state,
1960 5457c8ce bellard
                      BlockDriverState *hd0, BlockDriverState *hd1,
1961 5457c8ce bellard
                      SetIRQFunc *set_irq, void *irq_opaque, int irq)
1962 5391d806 bellard
{
1963 69b91039 bellard
    IDEState *s;
1964 aedf5382 bellard
    static int drive_serial = 1;
1965 bf1b938f bellard
    int i, cylinders, heads, secs, translation;
1966 5391d806 bellard
    int64_t nb_sectors;
1967 5391d806 bellard
1968 caed8802 bellard
    for(i = 0; i < 2; i++) {
1969 caed8802 bellard
        s = ide_state + i;
1970 caed8802 bellard
        if (i == 0)
1971 caed8802 bellard
            s->bs = hd0;
1972 caed8802 bellard
        else
1973 caed8802 bellard
            s->bs = hd1;
1974 5391d806 bellard
        if (s->bs) {
1975 5391d806 bellard
            bdrv_get_geometry(s->bs, &nb_sectors);
1976 5391d806 bellard
            s->nb_sectors = nb_sectors;
1977 caed8802 bellard
            /* if a geometry hint is available, use it */
1978 caed8802 bellard
            bdrv_get_geometry_hint(s->bs, &cylinders, &heads, &secs);
1979 caed8802 bellard
            if (cylinders != 0) {
1980 5391d806 bellard
                s->cylinders = cylinders;
1981 caed8802 bellard
                s->heads = heads;
1982 caed8802 bellard
                s->sectors = secs;
1983 caed8802 bellard
            } else {
1984 bf1b938f bellard
                if (guess_disk_lchs(s, &cylinders, &heads, &secs) == 0) {
1985 bf1b938f bellard
                    if (heads > 16) {
1986 bf1b938f bellard
                        /* if heads > 16, it means that a BIOS LBA
1987 bf1b938f bellard
                           translation was active, so the default
1988 bf1b938f bellard
                           hardware geometry is OK */
1989 bf1b938f bellard
                        goto default_geometry;
1990 bf1b938f bellard
                    } else {
1991 bf1b938f bellard
                        s->cylinders = cylinders;
1992 bf1b938f bellard
                        s->heads = heads;
1993 bf1b938f bellard
                        s->sectors = secs;
1994 bf1b938f bellard
                        /* disable any translation to be in sync with
1995 bf1b938f bellard
                           the logical geometry */
1996 bf1b938f bellard
                        translation = bdrv_get_translation_hint(s->bs);
1997 bf1b938f bellard
                        if (translation == BIOS_ATA_TRANSLATION_AUTO) {
1998 bf1b938f bellard
                            bdrv_set_translation_hint(s->bs,
1999 bf1b938f bellard
                                                      BIOS_ATA_TRANSLATION_NONE);
2000 bf1b938f bellard
                        }
2001 bf1b938f bellard
                    }
2002 bf1b938f bellard
                } else {
2003 bf1b938f bellard
                default_geometry:
2004 46d4767d bellard
                    /* if no geometry, use a standard physical disk geometry */
2005 caed8802 bellard
                    cylinders = nb_sectors / (16 * 63);
2006 caed8802 bellard
                    if (cylinders > 16383)
2007 caed8802 bellard
                        cylinders = 16383;
2008 caed8802 bellard
                    else if (cylinders < 2)
2009 caed8802 bellard
                        cylinders = 2;
2010 caed8802 bellard
                    s->cylinders = cylinders;
2011 caed8802 bellard
                    s->heads = 16;
2012 caed8802 bellard
                    s->sectors = 63;
2013 caed8802 bellard
                }
2014 769bec72 bellard
                bdrv_set_geometry_hint(s->bs, s->cylinders, s->heads, s->sectors);
2015 caed8802 bellard
            }
2016 caed8802 bellard
            if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) {
2017 caed8802 bellard
                s->is_cdrom = 1;
2018 caed8802 bellard
                bdrv_set_change_cb(s->bs, cdrom_change_cb, s);
2019 5391d806 bellard
            }
2020 5391d806 bellard
        }
2021 aedf5382 bellard
        s->drive_serial = drive_serial++;
2022 5457c8ce bellard
        s->set_irq = set_irq;
2023 5457c8ce bellard
        s->irq_opaque = irq_opaque;
2024 caed8802 bellard
        s->irq = irq;
2025 a09db21f bellard
        s->sector_write_timer = qemu_new_timer(vm_clock, 
2026 a09db21f bellard
                                               ide_sector_write_timer_cb, s);
2027 5391d806 bellard
        ide_reset(s);
2028 5391d806 bellard
    }
2029 69b91039 bellard
}
2030 69b91039 bellard
2031 34e538ae bellard
static void ide_init_ioport(IDEState *ide_state, int iobase, int iobase2)
2032 69b91039 bellard
{
2033 caed8802 bellard
    register_ioport_write(iobase, 8, 1, ide_ioport_write, ide_state);
2034 caed8802 bellard
    register_ioport_read(iobase, 8, 1, ide_ioport_read, ide_state);
2035 caed8802 bellard
    if (iobase2) {
2036 caed8802 bellard
        register_ioport_read(iobase2, 1, 1, ide_status_read, ide_state);
2037 caed8802 bellard
        register_ioport_write(iobase2, 1, 1, ide_cmd_write, ide_state);
2038 5391d806 bellard
    }
2039 caed8802 bellard
    
2040 caed8802 bellard
    /* data ports */
2041 caed8802 bellard
    register_ioport_write(iobase, 2, 2, ide_data_writew, ide_state);
2042 caed8802 bellard
    register_ioport_read(iobase, 2, 2, ide_data_readw, ide_state);
2043 caed8802 bellard
    register_ioport_write(iobase, 4, 4, ide_data_writel, ide_state);
2044 caed8802 bellard
    register_ioport_read(iobase, 4, 4, ide_data_readl, ide_state);
2045 5391d806 bellard
}
2046 69b91039 bellard
2047 69b91039 bellard
/***********************************************************/
2048 34e538ae bellard
/* ISA IDE definitions */
2049 34e538ae bellard
2050 34e538ae bellard
void isa_ide_init(int iobase, int iobase2, int irq,
2051 34e538ae bellard
                  BlockDriverState *hd0, BlockDriverState *hd1)
2052 34e538ae bellard
{
2053 34e538ae bellard
    IDEState *ide_state;
2054 34e538ae bellard
2055 34e538ae bellard
    ide_state = qemu_mallocz(sizeof(IDEState) * 2);
2056 34e538ae bellard
    if (!ide_state)
2057 34e538ae bellard
        return;
2058 34e538ae bellard
    
2059 3de388f6 bellard
    ide_init2(ide_state, hd0, hd1, pic_set_irq_new, isa_pic, irq);
2060 34e538ae bellard
    ide_init_ioport(ide_state, iobase, iobase2);
2061 34e538ae bellard
}
2062 34e538ae bellard
2063 34e538ae bellard
/***********************************************************/
2064 69b91039 bellard
/* PCI IDE definitions */
2065 69b91039 bellard
2066 5457c8ce bellard
static void cmd646_update_irq(PCIIDEState *d);
2067 5457c8ce bellard
2068 69b91039 bellard
static void ide_map(PCIDevice *pci_dev, int region_num, 
2069 69b91039 bellard
                    uint32_t addr, uint32_t size, int type)
2070 69b91039 bellard
{
2071 69b91039 bellard
    PCIIDEState *d = (PCIIDEState *)pci_dev;
2072 69b91039 bellard
    IDEState *ide_state;
2073 69b91039 bellard
2074 69b91039 bellard
    if (region_num <= 3) {
2075 69b91039 bellard
        ide_state = &d->ide_if[(region_num >> 1) * 2];
2076 69b91039 bellard
        if (region_num & 1) {
2077 69b91039 bellard
            register_ioport_read(addr + 2, 1, 1, ide_status_read, ide_state);
2078 69b91039 bellard
            register_ioport_write(addr + 2, 1, 1, ide_cmd_write, ide_state);
2079 69b91039 bellard
        } else {
2080 69b91039 bellard
            register_ioport_write(addr, 8, 1, ide_ioport_write, ide_state);
2081 69b91039 bellard
            register_ioport_read(addr, 8, 1, ide_ioport_read, ide_state);
2082 69b91039 bellard
2083 69b91039 bellard
            /* data ports */
2084 69b91039 bellard
            register_ioport_write(addr, 2, 2, ide_data_writew, ide_state);
2085 69b91039 bellard
            register_ioport_read(addr, 2, 2, ide_data_readw, ide_state);
2086 69b91039 bellard
            register_ioport_write(addr, 4, 4, ide_data_writel, ide_state);
2087 69b91039 bellard
            register_ioport_read(addr, 4, 4, ide_data_readl, ide_state);
2088 69b91039 bellard
        }
2089 69b91039 bellard
    }
2090 69b91039 bellard
}
2091 69b91039 bellard
2092 98087450 bellard
/* XXX: full callback usage to prepare non blocking I/Os support -
2093 98087450 bellard
   error handling */
2094 98087450 bellard
static void ide_dma_loop(BMDMAState *bm)
2095 98087450 bellard
{
2096 98087450 bellard
    struct {
2097 98087450 bellard
        uint32_t addr;
2098 98087450 bellard
        uint32_t size;
2099 98087450 bellard
    } prd;
2100 98087450 bellard
    target_phys_addr_t cur_addr;
2101 98087450 bellard
    int len, i, len1;
2102 98087450 bellard
2103 98087450 bellard
    cur_addr = bm->addr;
2104 98087450 bellard
    /* at most one page to avoid hanging if erroneous parameters */
2105 98087450 bellard
    for(i = 0; i < 512; i++) {
2106 98087450 bellard
        cpu_physical_memory_read(cur_addr, (uint8_t *)&prd, 8);
2107 98087450 bellard
        prd.addr = le32_to_cpu(prd.addr);
2108 98087450 bellard
        prd.size = le32_to_cpu(prd.size);
2109 98087450 bellard
#ifdef DEBUG_IDE
2110 98087450 bellard
        printf("ide: dma: prd: %08x: addr=0x%08x size=0x%08x\n", 
2111 98087450 bellard
               (int)cur_addr, prd.addr, prd.size);
2112 98087450 bellard
#endif
2113 98087450 bellard
        len = prd.size & 0xfffe;
2114 98087450 bellard
        if (len == 0)
2115 98087450 bellard
            len = 0x10000;
2116 98087450 bellard
        while (len > 0) {
2117 98087450 bellard
            len1 = bm->dma_cb(bm->ide_if, prd.addr, len);
2118 98087450 bellard
            if (len1 == 0)
2119 98087450 bellard
                goto the_end;
2120 98087450 bellard
            prd.addr += len1;
2121 98087450 bellard
            len -= len1;
2122 98087450 bellard
        }
2123 98087450 bellard
        /* end of transfer */
2124 98087450 bellard
        if (prd.size & 0x80000000)
2125 98087450 bellard
            break;
2126 98087450 bellard
        cur_addr += 8;
2127 98087450 bellard
    }
2128 98087450 bellard
    /* end of transfer */
2129 98087450 bellard
 the_end:
2130 98087450 bellard
    bm->status &= ~BM_STATUS_DMAING;
2131 98087450 bellard
    bm->status |= BM_STATUS_INT;
2132 98087450 bellard
    bm->dma_cb = NULL;
2133 98087450 bellard
    bm->ide_if = NULL;
2134 98087450 bellard
}
2135 98087450 bellard
2136 98087450 bellard
static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb)
2137 98087450 bellard
{
2138 98087450 bellard
    BMDMAState *bm = s->bmdma;
2139 98087450 bellard
    if(!bm)
2140 98087450 bellard
        return;
2141 98087450 bellard
    bm->ide_if = s;
2142 98087450 bellard
    bm->dma_cb = dma_cb;
2143 98087450 bellard
    if (bm->status & BM_STATUS_DMAING) {
2144 98087450 bellard
        ide_dma_loop(bm);
2145 98087450 bellard
    }
2146 98087450 bellard
}
2147 98087450 bellard
2148 98087450 bellard
static void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)
2149 98087450 bellard
{
2150 98087450 bellard
    BMDMAState *bm = opaque;
2151 98087450 bellard
#ifdef DEBUG_IDE
2152 98087450 bellard
    printf("%s: 0x%08x\n", __func__, val);
2153 98087450 bellard
#endif
2154 98087450 bellard
    if (!(val & BM_CMD_START)) {
2155 98087450 bellard
        /* XXX: do it better */
2156 98087450 bellard
        bm->status &= ~BM_STATUS_DMAING;
2157 98087450 bellard
        bm->cmd = val & 0x09;
2158 98087450 bellard
    } else {
2159 98087450 bellard
        bm->status |= BM_STATUS_DMAING;
2160 98087450 bellard
        bm->cmd = val & 0x09;
2161 98087450 bellard
        /* start dma transfer if possible */
2162 98087450 bellard
        if (bm->dma_cb)
2163 98087450 bellard
            ide_dma_loop(bm);
2164 98087450 bellard
    }
2165 98087450 bellard
}
2166 98087450 bellard
2167 5457c8ce bellard
static uint32_t bmdma_readb(void *opaque, uint32_t addr)
2168 98087450 bellard
{
2169 98087450 bellard
    BMDMAState *bm = opaque;
2170 5457c8ce bellard
    PCIIDEState *pci_dev;
2171 98087450 bellard
    uint32_t val;
2172 5457c8ce bellard
    
2173 5457c8ce bellard
    switch(addr & 3) {
2174 5457c8ce bellard
    case 0: 
2175 5457c8ce bellard
        val = bm->cmd;
2176 5457c8ce bellard
        break;
2177 5457c8ce bellard
    case 1:
2178 5457c8ce bellard
        pci_dev = bm->pci_dev;
2179 5457c8ce bellard
        if (pci_dev->type == IDE_TYPE_CMD646) {
2180 5457c8ce bellard
            val = pci_dev->dev.config[MRDMODE];
2181 5457c8ce bellard
        } else {
2182 5457c8ce bellard
            val = 0xff;
2183 5457c8ce bellard
        }
2184 5457c8ce bellard
        break;
2185 5457c8ce bellard
    case 2:
2186 5457c8ce bellard
        val = bm->status;
2187 5457c8ce bellard
        break;
2188 5457c8ce bellard
    case 3:
2189 5457c8ce bellard
        pci_dev = bm->pci_dev;
2190 5457c8ce bellard
        if (pci_dev->type == IDE_TYPE_CMD646) {
2191 5457c8ce bellard
            if (bm == &pci_dev->bmdma[0])
2192 5457c8ce bellard
                val = pci_dev->dev.config[UDIDETCR0];
2193 5457c8ce bellard
            else
2194 5457c8ce bellard
                val = pci_dev->dev.config[UDIDETCR1];
2195 5457c8ce bellard
        } else {
2196 5457c8ce bellard
            val = 0xff;
2197 5457c8ce bellard
        }
2198 5457c8ce bellard
        break;
2199 5457c8ce bellard
    default:
2200 5457c8ce bellard
        val = 0xff;
2201 5457c8ce bellard
        break;
2202 5457c8ce bellard
    }
2203 98087450 bellard
#ifdef DEBUG_IDE
2204 5457c8ce bellard
    printf("bmdma: readb 0x%02x : 0x%02x\n", addr, val);
2205 98087450 bellard
#endif
2206 98087450 bellard
    return val;
2207 98087450 bellard
}
2208 98087450 bellard
2209 5457c8ce bellard
static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val)
2210 98087450 bellard
{
2211 98087450 bellard
    BMDMAState *bm = opaque;
2212 5457c8ce bellard
    PCIIDEState *pci_dev;
2213 98087450 bellard
#ifdef DEBUG_IDE
2214 5457c8ce bellard
    printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val);
2215 98087450 bellard
#endif
2216 5457c8ce bellard
    switch(addr & 3) {
2217 5457c8ce bellard
    case 1:
2218 5457c8ce bellard
        pci_dev = bm->pci_dev;
2219 5457c8ce bellard
        if (pci_dev->type == IDE_TYPE_CMD646) {
2220 5457c8ce bellard
            pci_dev->dev.config[MRDMODE] = 
2221 5457c8ce bellard
                (pci_dev->dev.config[MRDMODE] & ~0x30) | (val & 0x30);
2222 5457c8ce bellard
            cmd646_update_irq(pci_dev);
2223 5457c8ce bellard
        }
2224 5457c8ce bellard
        break;
2225 5457c8ce bellard
    case 2:
2226 5457c8ce bellard
        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
2227 5457c8ce bellard
        break;
2228 5457c8ce bellard
    case 3:
2229 5457c8ce bellard
        pci_dev = bm->pci_dev;
2230 5457c8ce bellard
        if (pci_dev->type == IDE_TYPE_CMD646) {
2231 5457c8ce bellard
            if (bm == &pci_dev->bmdma[0])
2232 5457c8ce bellard
                pci_dev->dev.config[UDIDETCR0] = val;
2233 5457c8ce bellard
            else
2234 5457c8ce bellard
                pci_dev->dev.config[UDIDETCR1] = val;
2235 5457c8ce bellard
        }
2236 5457c8ce bellard
        break;
2237 5457c8ce bellard
    }
2238 98087450 bellard
}
2239 98087450 bellard
2240 98087450 bellard
static uint32_t bmdma_addr_readl(void *opaque, uint32_t addr)
2241 98087450 bellard
{
2242 98087450 bellard
    BMDMAState *bm = opaque;
2243 98087450 bellard
    uint32_t val;
2244 98087450 bellard
    val = bm->addr;
2245 98087450 bellard
#ifdef DEBUG_IDE
2246 98087450 bellard
    printf("%s: 0x%08x\n", __func__, val);
2247 98087450 bellard
#endif
2248 98087450 bellard
    return val;
2249 98087450 bellard
}
2250 98087450 bellard
2251 98087450 bellard
static void bmdma_addr_writel(void *opaque, uint32_t addr, uint32_t val)
2252 98087450 bellard
{
2253 98087450 bellard
    BMDMAState *bm = opaque;
2254 98087450 bellard
#ifdef DEBUG_IDE
2255 98087450 bellard
    printf("%s: 0x%08x\n", __func__, val);
2256 98087450 bellard
#endif
2257 98087450 bellard
    bm->addr = val & ~3;
2258 98087450 bellard
}
2259 98087450 bellard
2260 98087450 bellard
static void bmdma_map(PCIDevice *pci_dev, int region_num, 
2261 98087450 bellard
                    uint32_t addr, uint32_t size, int type)
2262 98087450 bellard
{
2263 98087450 bellard
    PCIIDEState *d = (PCIIDEState *)pci_dev;
2264 98087450 bellard
    int i;
2265 98087450 bellard
2266 98087450 bellard
    for(i = 0;i < 2; i++) {
2267 98087450 bellard
        BMDMAState *bm = &d->bmdma[i];
2268 98087450 bellard
        d->ide_if[2 * i].bmdma = bm;
2269 98087450 bellard
        d->ide_if[2 * i + 1].bmdma = bm;
2270 5457c8ce bellard
        bm->pci_dev = (PCIIDEState *)pci_dev;
2271 5457c8ce bellard
2272 98087450 bellard
        register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);
2273 98087450 bellard
2274 5457c8ce bellard
        register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm);
2275 5457c8ce bellard
        register_ioport_read(addr, 4, 1, bmdma_readb, bm);
2276 98087450 bellard
2277 98087450 bellard
        register_ioport_write(addr + 4, 4, 4, bmdma_addr_writel, bm);
2278 98087450 bellard
        register_ioport_read(addr + 4, 4, 4, bmdma_addr_readl, bm);
2279 98087450 bellard
        addr += 8;
2280 98087450 bellard
    }
2281 98087450 bellard
}
2282 98087450 bellard
2283 5457c8ce bellard
/* XXX: call it also when the MRDMODE is changed from the PCI config
2284 5457c8ce bellard
   registers */
2285 5457c8ce bellard
static void cmd646_update_irq(PCIIDEState *d)
2286 5457c8ce bellard
{
2287 5457c8ce bellard
    int pci_level;
2288 5457c8ce bellard
    pci_level = ((d->dev.config[MRDMODE] & MRDMODE_INTR_CH0) &&
2289 5457c8ce bellard
                 !(d->dev.config[MRDMODE] & MRDMODE_BLK_CH0)) ||
2290 5457c8ce bellard
        ((d->dev.config[MRDMODE] & MRDMODE_INTR_CH1) &&
2291 5457c8ce bellard
         !(d->dev.config[MRDMODE] & MRDMODE_BLK_CH1));
2292 5457c8ce bellard
    pci_set_irq((PCIDevice *)d, 0, pci_level);
2293 5457c8ce bellard
}
2294 5457c8ce bellard
2295 5457c8ce bellard
/* the PCI irq level is the logical OR of the two channels */
2296 5457c8ce bellard
static void cmd646_set_irq(void *opaque, int channel, int level)
2297 5457c8ce bellard
{
2298 5457c8ce bellard
    PCIIDEState *d = opaque;
2299 5457c8ce bellard
    int irq_mask;
2300 5457c8ce bellard
2301 5457c8ce bellard
    irq_mask = MRDMODE_INTR_CH0 << channel;
2302 5457c8ce bellard
    if (level)
2303 5457c8ce bellard
        d->dev.config[MRDMODE] |= irq_mask;
2304 5457c8ce bellard
    else
2305 5457c8ce bellard
        d->dev.config[MRDMODE] &= ~irq_mask;
2306 5457c8ce bellard
    cmd646_update_irq(d);
2307 5457c8ce bellard
}
2308 5457c8ce bellard
2309 5457c8ce bellard
/* CMD646 PCI IDE controller */
2310 5457c8ce bellard
void pci_cmd646_ide_init(PCIBus *bus, BlockDriverState **hd_table,
2311 5457c8ce bellard
                         int secondary_ide_enabled)
2312 69b91039 bellard
{
2313 69b91039 bellard
    PCIIDEState *d;
2314 69b91039 bellard
    uint8_t *pci_conf;
2315 34e538ae bellard
    int i;
2316 34e538ae bellard
2317 5457c8ce bellard
    d = (PCIIDEState *)pci_register_device(bus, "CMD646 IDE", 
2318 5457c8ce bellard
                                           sizeof(PCIIDEState),
2319 46e50e9d bellard
                                           -1, 
2320 73c11f63 bellard
                                           NULL, NULL);
2321 5457c8ce bellard
    d->type = IDE_TYPE_CMD646;
2322 69b91039 bellard
    pci_conf = d->dev.config;
2323 5457c8ce bellard
    pci_conf[0x00] = 0x95; // CMD646
2324 5457c8ce bellard
    pci_conf[0x01] = 0x10;
2325 5457c8ce bellard
    pci_conf[0x02] = 0x46;
2326 5457c8ce bellard
    pci_conf[0x03] = 0x06;
2327 5457c8ce bellard
2328 5457c8ce bellard
    pci_conf[0x08] = 0x07; // IDE controller revision
2329 5457c8ce bellard
    pci_conf[0x09] = 0x8f; 
2330 5457c8ce bellard
2331 69b91039 bellard
    pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
2332 69b91039 bellard
    pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
2333 5457c8ce bellard
    pci_conf[0x0e] = 0x00; // header_type
2334 5457c8ce bellard
    
2335 5457c8ce bellard
    if (secondary_ide_enabled) {
2336 5457c8ce bellard
        /* XXX: if not enabled, really disable the seconday IDE controller */
2337 5457c8ce bellard
        pci_conf[0x51] = 0x80; /* enable IDE1 */
2338 5457c8ce bellard
    }
2339 69b91039 bellard
2340 69b91039 bellard
    pci_register_io_region((PCIDevice *)d, 0, 0x8, 
2341 69b91039 bellard
                           PCI_ADDRESS_SPACE_IO, ide_map);
2342 69b91039 bellard
    pci_register_io_region((PCIDevice *)d, 1, 0x4, 
2343 69b91039 bellard
                           PCI_ADDRESS_SPACE_IO, ide_map);
2344 69b91039 bellard
    pci_register_io_region((PCIDevice *)d, 2, 0x8, 
2345 69b91039 bellard
                           PCI_ADDRESS_SPACE_IO, ide_map);
2346 69b91039 bellard
    pci_register_io_region((PCIDevice *)d, 3, 0x4, 
2347 69b91039 bellard
                           PCI_ADDRESS_SPACE_IO, ide_map);
2348 98087450 bellard
    pci_register_io_region((PCIDevice *)d, 4, 0x10, 
2349 98087450 bellard
                           PCI_ADDRESS_SPACE_IO, bmdma_map);
2350 69b91039 bellard
2351 34e538ae bellard
    pci_conf[0x3d] = 0x01; // interrupt on pin 1
2352 5457c8ce bellard
    
2353 34e538ae bellard
    for(i = 0; i < 4; i++)
2354 34e538ae bellard
        d->ide_if[i].pci_dev = (PCIDevice *)d;
2355 5457c8ce bellard
    ide_init2(&d->ide_if[0], hd_table[0], hd_table[1],
2356 5457c8ce bellard
              cmd646_set_irq, d, 0);
2357 5457c8ce bellard
    ide_init2(&d->ide_if[2], hd_table[2], hd_table[3],
2358 5457c8ce bellard
              cmd646_set_irq, d, 1);
2359 34e538ae bellard
}
2360 34e538ae bellard
2361 34e538ae bellard
/* hd_table must contain 4 block drivers */
2362 34e538ae bellard
/* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
2363 46e50e9d bellard
void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table)
2364 34e538ae bellard
{
2365 34e538ae bellard
    PCIIDEState *d;
2366 34e538ae bellard
    uint8_t *pci_conf;
2367 34e538ae bellard
    
2368 34e538ae bellard
    /* register a function 1 of PIIX3 */
2369 46e50e9d bellard
    d = (PCIIDEState *)pci_register_device(bus, "PIIX3 IDE", 
2370 46e50e9d bellard
                                           sizeof(PCIIDEState),
2371 46e50e9d bellard
                                           ((PCIDevice *)piix3_state)->devfn + 1, 
2372 34e538ae bellard
                                           NULL, NULL);
2373 5457c8ce bellard
    d->type = IDE_TYPE_PIIX3;
2374 5457c8ce bellard
2375 34e538ae bellard
    pci_conf = d->dev.config;
2376 34e538ae bellard
    pci_conf[0x00] = 0x86; // Intel
2377 34e538ae bellard
    pci_conf[0x01] = 0x80;
2378 34e538ae bellard
    pci_conf[0x02] = 0x10;
2379 34e538ae bellard
    pci_conf[0x03] = 0x70;
2380 92510b8c bellard
    pci_conf[0x09] = 0x80; // legacy ATA mode
2381 34e538ae bellard
    pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
2382 34e538ae bellard
    pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
2383 34e538ae bellard
    pci_conf[0x0e] = 0x00; // header_type
2384 34e538ae bellard
2385 98087450 bellard
    pci_register_io_region((PCIDevice *)d, 4, 0x10, 
2386 98087450 bellard
                           PCI_ADDRESS_SPACE_IO, bmdma_map);
2387 34e538ae bellard
2388 5457c8ce bellard
    ide_init2(&d->ide_if[0], hd_table[0], hd_table[1],
2389 3de388f6 bellard
              pic_set_irq_new, isa_pic, 14);
2390 5457c8ce bellard
    ide_init2(&d->ide_if[2], hd_table[2], hd_table[3],
2391 3de388f6 bellard
              pic_set_irq_new, isa_pic, 15);
2392 34e538ae bellard
    ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
2393 34e538ae bellard
    ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
2394 69b91039 bellard
}
2395 1ade1de2 bellard
2396 1ade1de2 bellard
/***********************************************************/
2397 1ade1de2 bellard
/* MacIO based PowerPC IDE */
2398 1ade1de2 bellard
2399 1ade1de2 bellard
/* PowerMac IDE memory IO */
2400 1ade1de2 bellard
static void pmac_ide_writeb (void *opaque,
2401 1ade1de2 bellard
                             target_phys_addr_t addr, uint32_t val)
2402 1ade1de2 bellard
{
2403 1ade1de2 bellard
    addr = (addr & 0xFFF) >> 4; 
2404 1ade1de2 bellard
    switch (addr) {
2405 1ade1de2 bellard
    case 1 ... 7:
2406 1ade1de2 bellard
        ide_ioport_write(opaque, addr, val);
2407 1ade1de2 bellard
        break;
2408 1ade1de2 bellard
    case 8:
2409 1ade1de2 bellard
    case 22:
2410 1ade1de2 bellard
        ide_cmd_write(opaque, 0, val);
2411 1ade1de2 bellard
        break;
2412 1ade1de2 bellard
    default:
2413 1ade1de2 bellard
        break;
2414 1ade1de2 bellard
    }
2415 1ade1de2 bellard
}
2416 1ade1de2 bellard
2417 1ade1de2 bellard
static uint32_t pmac_ide_readb (void *opaque,target_phys_addr_t addr)
2418 1ade1de2 bellard
{
2419 1ade1de2 bellard
    uint8_t retval;
2420 1ade1de2 bellard
2421 1ade1de2 bellard
    addr = (addr & 0xFFF) >> 4;
2422 1ade1de2 bellard
    switch (addr) {
2423 1ade1de2 bellard
    case 1 ... 7:
2424 1ade1de2 bellard
        retval = ide_ioport_read(opaque, addr);
2425 1ade1de2 bellard
        break;
2426 1ade1de2 bellard
    case 8:
2427 1ade1de2 bellard
    case 22:
2428 1ade1de2 bellard
        retval = ide_status_read(opaque, 0);
2429 1ade1de2 bellard
        break;
2430 1ade1de2 bellard
    default:
2431 1ade1de2 bellard
        retval = 0xFF;
2432 1ade1de2 bellard
        break;
2433 1ade1de2 bellard
    }
2434 1ade1de2 bellard
    return retval;
2435 1ade1de2 bellard
}
2436 1ade1de2 bellard
2437 1ade1de2 bellard
static void pmac_ide_writew (void *opaque,
2438 1ade1de2 bellard
                             target_phys_addr_t addr, uint32_t val)
2439 1ade1de2 bellard
{
2440 1ade1de2 bellard
    addr = (addr & 0xFFF) >> 4; 
2441 1ade1de2 bellard
#ifdef TARGET_WORDS_BIGENDIAN
2442 1ade1de2 bellard
    val = bswap16(val);
2443 1ade1de2 bellard
#endif
2444 1ade1de2 bellard
    if (addr == 0) {
2445 1ade1de2 bellard
        ide_data_writew(opaque, 0, val);
2446 1ade1de2 bellard
    }
2447 1ade1de2 bellard
}
2448 1ade1de2 bellard
2449 1ade1de2 bellard
static uint32_t pmac_ide_readw (void *opaque,target_phys_addr_t addr)
2450 1ade1de2 bellard
{
2451 1ade1de2 bellard
    uint16_t retval;
2452 1ade1de2 bellard
2453 1ade1de2 bellard
    addr = (addr & 0xFFF) >> 4; 
2454 1ade1de2 bellard
    if (addr == 0) {
2455 1ade1de2 bellard
        retval = ide_data_readw(opaque, 0);
2456 1ade1de2 bellard
    } else {
2457 1ade1de2 bellard
        retval = 0xFFFF;
2458 1ade1de2 bellard
    }
2459 1ade1de2 bellard
#ifdef TARGET_WORDS_BIGENDIAN
2460 1ade1de2 bellard
    retval = bswap16(retval);
2461 1ade1de2 bellard
#endif
2462 1ade1de2 bellard
    return retval;
2463 1ade1de2 bellard
}
2464 1ade1de2 bellard
2465 1ade1de2 bellard
static void pmac_ide_writel (void *opaque,
2466 1ade1de2 bellard
                             target_phys_addr_t addr, uint32_t val)
2467 1ade1de2 bellard
{
2468 1ade1de2 bellard
    addr = (addr & 0xFFF) >> 4; 
2469 1ade1de2 bellard
#ifdef TARGET_WORDS_BIGENDIAN
2470 1ade1de2 bellard
    val = bswap32(val);
2471 1ade1de2 bellard
#endif
2472 1ade1de2 bellard
    if (addr == 0) {
2473 1ade1de2 bellard
        ide_data_writel(opaque, 0, val);
2474 1ade1de2 bellard
    }
2475 1ade1de2 bellard
}
2476 1ade1de2 bellard
2477 1ade1de2 bellard
static uint32_t pmac_ide_readl (void *opaque,target_phys_addr_t addr)
2478 1ade1de2 bellard
{
2479 1ade1de2 bellard
    uint32_t retval;
2480 1ade1de2 bellard
2481 1ade1de2 bellard
    addr = (addr & 0xFFF) >> 4; 
2482 1ade1de2 bellard
    if (addr == 0) {
2483 1ade1de2 bellard
        retval = ide_data_readl(opaque, 0);
2484 1ade1de2 bellard
    } else {
2485 1ade1de2 bellard
        retval = 0xFFFFFFFF;
2486 1ade1de2 bellard
    }
2487 1ade1de2 bellard
#ifdef TARGET_WORDS_BIGENDIAN
2488 1ade1de2 bellard
    retval = bswap32(retval);
2489 1ade1de2 bellard
#endif
2490 1ade1de2 bellard
    return retval;
2491 1ade1de2 bellard
}
2492 1ade1de2 bellard
2493 1ade1de2 bellard
static CPUWriteMemoryFunc *pmac_ide_write[] = {
2494 1ade1de2 bellard
    pmac_ide_writeb,
2495 1ade1de2 bellard
    pmac_ide_writew,
2496 1ade1de2 bellard
    pmac_ide_writel,
2497 1ade1de2 bellard
};
2498 1ade1de2 bellard
2499 1ade1de2 bellard
static CPUReadMemoryFunc *pmac_ide_read[] = {
2500 1ade1de2 bellard
    pmac_ide_readb,
2501 1ade1de2 bellard
    pmac_ide_readw,
2502 1ade1de2 bellard
    pmac_ide_readl,
2503 1ade1de2 bellard
};
2504 1ade1de2 bellard
2505 1ade1de2 bellard
/* hd_table must contain 4 block drivers */
2506 1ade1de2 bellard
/* PowerMac uses memory mapped registers, not I/O. Return the memory
2507 1ade1de2 bellard
   I/O index to access the ide. */
2508 1ade1de2 bellard
int pmac_ide_init (BlockDriverState **hd_table,
2509 5457c8ce bellard
                   SetIRQFunc *set_irq, void *irq_opaque, int irq)
2510 1ade1de2 bellard
{
2511 1ade1de2 bellard
    IDEState *ide_if;
2512 1ade1de2 bellard
    int pmac_ide_memory;
2513 1ade1de2 bellard
2514 1ade1de2 bellard
    ide_if = qemu_mallocz(sizeof(IDEState) * 2);
2515 5457c8ce bellard
    ide_init2(&ide_if[0], hd_table[0], hd_table[1],
2516 5457c8ce bellard
              set_irq, irq_opaque, irq);
2517 1ade1de2 bellard
    
2518 1ade1de2 bellard
    pmac_ide_memory = cpu_register_io_memory(0, pmac_ide_read,
2519 1ade1de2 bellard
                                             pmac_ide_write, &ide_if[0]);
2520 1ade1de2 bellard
    return pmac_ide_memory;
2521 1ade1de2 bellard
}