Statistics
| Branch: | Revision:

root / hw / ide.c @ 0986ac3b

History | View | Annotate | Download (76.2 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 c2ff060f bellard
    uint32_t nsector;
311 5391d806 bellard
    uint8_t sector;
312 5391d806 bellard
    uint8_t lcyl;
313 5391d806 bellard
    uint8_t hcyl;
314 c2ff060f bellard
    /* other part of tf for lba48 support */
315 c2ff060f bellard
    uint8_t hob_feature;
316 c2ff060f bellard
    uint8_t hob_nsector;
317 c2ff060f bellard
    uint8_t hob_sector;
318 c2ff060f bellard
    uint8_t hob_lcyl;
319 c2ff060f bellard
    uint8_t hob_hcyl;
320 c2ff060f bellard
321 5391d806 bellard
    uint8_t select;
322 5391d806 bellard
    uint8_t status;
323 c2ff060f bellard
324 5391d806 bellard
    /* 0x3f6 command, only meaningful for drive 0 */
325 5391d806 bellard
    uint8_t cmd;
326 c2ff060f bellard
    /* set for lba48 access */
327 c2ff060f bellard
    uint8_t lba48;
328 5391d806 bellard
    /* depends on bit 4 in select, only meaningful for drive 0 */
329 5391d806 bellard
    struct IDEState *cur_drive; 
330 5391d806 bellard
    BlockDriverState *bs;
331 5391d806 bellard
    /* ATAPI specific */
332 5391d806 bellard
    uint8_t sense_key;
333 5391d806 bellard
    uint8_t asc;
334 5391d806 bellard
    int packet_transfer_size;
335 5391d806 bellard
    int elementary_transfer_size;
336 5391d806 bellard
    int io_buffer_index;
337 5391d806 bellard
    int lba;
338 98087450 bellard
    int cd_sector_size;
339 98087450 bellard
    int atapi_dma; /* true if dma is requested for the packet cmd */
340 98087450 bellard
    /* ATA DMA state */
341 98087450 bellard
    int io_buffer_size;
342 98087450 bellard
    /* PIO transfer handling */
343 5391d806 bellard
    int req_nb_sectors; /* number of sectors per interrupt */
344 5391d806 bellard
    EndTransferFunc *end_transfer_func;
345 5391d806 bellard
    uint8_t *data_ptr;
346 5391d806 bellard
    uint8_t *data_end;
347 5391d806 bellard
    uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4];
348 a09db21f bellard
    QEMUTimer *sector_write_timer; /* only used for win2k instal hack */
349 e774a278 bellard
    uint32_t irq_count; /* counts IRQs when using win2k install hack */
350 5391d806 bellard
} IDEState;
351 5391d806 bellard
352 98087450 bellard
#define BM_STATUS_DMAING 0x01
353 98087450 bellard
#define BM_STATUS_ERROR  0x02
354 98087450 bellard
#define BM_STATUS_INT    0x04
355 98087450 bellard
356 98087450 bellard
#define BM_CMD_START     0x01
357 98087450 bellard
#define BM_CMD_READ      0x08
358 98087450 bellard
359 5457c8ce bellard
#define IDE_TYPE_PIIX3   0
360 5457c8ce bellard
#define IDE_TYPE_CMD646  1
361 5457c8ce bellard
362 5457c8ce bellard
/* CMD646 specific */
363 5457c8ce bellard
#define MRDMODE                0x71
364 5457c8ce bellard
#define   MRDMODE_INTR_CH0        0x04
365 5457c8ce bellard
#define   MRDMODE_INTR_CH1        0x08
366 5457c8ce bellard
#define   MRDMODE_BLK_CH0        0x10
367 5457c8ce bellard
#define   MRDMODE_BLK_CH1        0x20
368 5457c8ce bellard
#define UDIDETCR0        0x73
369 5457c8ce bellard
#define UDIDETCR1        0x7B
370 5457c8ce bellard
371 98087450 bellard
typedef int IDEDMAFunc(IDEState *s, 
372 98087450 bellard
                       target_phys_addr_t phys_addr, 
373 98087450 bellard
                       int transfer_size1);
374 98087450 bellard
375 98087450 bellard
typedef struct BMDMAState {
376 98087450 bellard
    uint8_t cmd;
377 98087450 bellard
    uint8_t status;
378 98087450 bellard
    uint32_t addr;
379 5457c8ce bellard
380 5457c8ce bellard
    struct PCIIDEState *pci_dev;
381 98087450 bellard
    /* current transfer state */
382 98087450 bellard
    IDEState *ide_if;
383 98087450 bellard
    IDEDMAFunc *dma_cb;
384 98087450 bellard
} BMDMAState;
385 98087450 bellard
386 98087450 bellard
typedef struct PCIIDEState {
387 98087450 bellard
    PCIDevice dev;
388 98087450 bellard
    IDEState ide_if[4];
389 98087450 bellard
    BMDMAState bmdma[2];
390 5457c8ce bellard
    int type; /* see IDE_TYPE_xxx */
391 98087450 bellard
} PCIIDEState;
392 98087450 bellard
393 98087450 bellard
static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb);
394 98087450 bellard
395 5391d806 bellard
static void padstr(char *str, const char *src, int len)
396 5391d806 bellard
{
397 5391d806 bellard
    int i, v;
398 5391d806 bellard
    for(i = 0; i < len; i++) {
399 5391d806 bellard
        if (*src)
400 5391d806 bellard
            v = *src++;
401 5391d806 bellard
        else
402 5391d806 bellard
            v = ' ';
403 5391d806 bellard
        *(char *)((long)str ^ 1) = v;
404 5391d806 bellard
        str++;
405 5391d806 bellard
    }
406 5391d806 bellard
}
407 5391d806 bellard
408 bd0d90b2 bellard
static void padstr8(uint8_t *buf, int buf_size, const char *src)
409 bd0d90b2 bellard
{
410 bd0d90b2 bellard
    int i;
411 bd0d90b2 bellard
    for(i = 0; i < buf_size; i++) {
412 bd0d90b2 bellard
        if (*src)
413 bd0d90b2 bellard
            buf[i] = *src++;
414 bd0d90b2 bellard
        else
415 bd0d90b2 bellard
            buf[i] = ' ';
416 bd0d90b2 bellard
    }
417 bd0d90b2 bellard
}
418 bd0d90b2 bellard
419 67b915a5 bellard
static void put_le16(uint16_t *p, unsigned int v)
420 67b915a5 bellard
{
421 0c4ad8dc bellard
    *p = cpu_to_le16(v);
422 67b915a5 bellard
}
423 67b915a5 bellard
424 5391d806 bellard
static void ide_identify(IDEState *s)
425 5391d806 bellard
{
426 5391d806 bellard
    uint16_t *p;
427 5391d806 bellard
    unsigned int oldsize;
428 aedf5382 bellard
    char buf[20];
429 5391d806 bellard
430 94458802 bellard
    if (s->identify_set) {
431 94458802 bellard
        memcpy(s->io_buffer, s->identify_data, sizeof(s->identify_data));
432 94458802 bellard
        return;
433 94458802 bellard
    }
434 94458802 bellard
435 5391d806 bellard
    memset(s->io_buffer, 0, 512);
436 5391d806 bellard
    p = (uint16_t *)s->io_buffer;
437 67b915a5 bellard
    put_le16(p + 0, 0x0040);
438 67b915a5 bellard
    put_le16(p + 1, s->cylinders); 
439 67b915a5 bellard
    put_le16(p + 3, s->heads);
440 67b915a5 bellard
    put_le16(p + 4, 512 * s->sectors); /* XXX: retired, remove ? */
441 67b915a5 bellard
    put_le16(p + 5, 512); /* XXX: retired, remove ? */
442 67b915a5 bellard
    put_le16(p + 6, s->sectors); 
443 aedf5382 bellard
    snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial);
444 aedf5382 bellard
    padstr((uint8_t *)(p + 10), buf, 20); /* serial number */
445 67b915a5 bellard
    put_le16(p + 20, 3); /* XXX: retired, remove ? */
446 67b915a5 bellard
    put_le16(p + 21, 512); /* cache size in sectors */
447 67b915a5 bellard
    put_le16(p + 22, 4); /* ecc bytes */
448 5391d806 bellard
    padstr((uint8_t *)(p + 23), QEMU_VERSION, 8); /* firmware version */
449 5391d806 bellard
    padstr((uint8_t *)(p + 27), "QEMU HARDDISK", 40); /* model */
450 5391d806 bellard
#if MAX_MULT_SECTORS > 1    
451 67b915a5 bellard
    put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
452 5391d806 bellard
#endif
453 67b915a5 bellard
    put_le16(p + 48, 1); /* dword I/O */
454 94458802 bellard
    put_le16(p + 49, (1 << 11) | (1 << 9) | (1 << 8)); /* DMA and LBA supported */
455 67b915a5 bellard
    put_le16(p + 51, 0x200); /* PIO transfer cycle */
456 67b915a5 bellard
    put_le16(p + 52, 0x200); /* DMA transfer cycle */
457 94458802 bellard
    put_le16(p + 53, 1 | (1 << 1) | (1 << 2)); /* words 54-58,64-70,88 are valid */
458 67b915a5 bellard
    put_le16(p + 54, s->cylinders);
459 67b915a5 bellard
    put_le16(p + 55, s->heads);
460 67b915a5 bellard
    put_le16(p + 56, s->sectors);
461 5391d806 bellard
    oldsize = s->cylinders * s->heads * s->sectors;
462 67b915a5 bellard
    put_le16(p + 57, oldsize);
463 67b915a5 bellard
    put_le16(p + 58, oldsize >> 16);
464 5391d806 bellard
    if (s->mult_sectors)
465 67b915a5 bellard
        put_le16(p + 59, 0x100 | s->mult_sectors);
466 67b915a5 bellard
    put_le16(p + 60, s->nb_sectors);
467 67b915a5 bellard
    put_le16(p + 61, s->nb_sectors >> 16);
468 94458802 bellard
    put_le16(p + 63, 0x07); /* mdma0-2 supported */
469 94458802 bellard
    put_le16(p + 65, 120);
470 94458802 bellard
    put_le16(p + 66, 120);
471 94458802 bellard
    put_le16(p + 67, 120);
472 94458802 bellard
    put_le16(p + 68, 120);
473 94458802 bellard
    put_le16(p + 80, 0xf0); /* ata3 -> ata6 supported */
474 94458802 bellard
    put_le16(p + 81, 0x16); /* conforms to ata5 */
475 67b915a5 bellard
    put_le16(p + 82, (1 << 14));
476 c2ff060f bellard
    /* 13=flush_cache_ext,12=flush_cache,10=lba48 */
477 c2ff060f bellard
    put_le16(p + 83, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10));
478 67b915a5 bellard
    put_le16(p + 84, (1 << 14));
479 67b915a5 bellard
    put_le16(p + 85, (1 << 14));
480 c2ff060f bellard
    /* 13=flush_cache_ext,12=flush_cache,10=lba48 */
481 c2ff060f bellard
    put_le16(p + 86, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10));
482 67b915a5 bellard
    put_le16(p + 87, (1 << 14));
483 94458802 bellard
    put_le16(p + 88, 0x3f | (1 << 13)); /* udma5 set and supported */
484 94458802 bellard
    put_le16(p + 93, 1 | (1 << 14) | 0x2000);
485 c2ff060f bellard
    put_le16(p + 100, s->nb_sectors);
486 c2ff060f bellard
    put_le16(p + 101, s->nb_sectors >> 16);
487 c2ff060f bellard
    put_le16(p + 102, s->nb_sectors >> 32);
488 c2ff060f bellard
    put_le16(p + 103, s->nb_sectors >> 48);
489 94458802 bellard
490 94458802 bellard
    memcpy(s->identify_data, p, sizeof(s->identify_data));
491 94458802 bellard
    s->identify_set = 1;
492 5391d806 bellard
}
493 5391d806 bellard
494 5391d806 bellard
static void ide_atapi_identify(IDEState *s)
495 5391d806 bellard
{
496 5391d806 bellard
    uint16_t *p;
497 aedf5382 bellard
    char buf[20];
498 5391d806 bellard
499 94458802 bellard
    if (s->identify_set) {
500 94458802 bellard
        memcpy(s->io_buffer, s->identify_data, sizeof(s->identify_data));
501 94458802 bellard
        return;
502 94458802 bellard
    }
503 94458802 bellard
504 5391d806 bellard
    memset(s->io_buffer, 0, 512);
505 5391d806 bellard
    p = (uint16_t *)s->io_buffer;
506 5391d806 bellard
    /* Removable CDROM, 50us response, 12 byte packets */
507 67b915a5 bellard
    put_le16(p + 0, (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0));
508 aedf5382 bellard
    snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial);
509 aedf5382 bellard
    padstr((uint8_t *)(p + 10), buf, 20); /* serial number */
510 67b915a5 bellard
    put_le16(p + 20, 3); /* buffer type */
511 67b915a5 bellard
    put_le16(p + 21, 512); /* cache size in sectors */
512 67b915a5 bellard
    put_le16(p + 22, 4); /* ecc bytes */
513 5391d806 bellard
    padstr((uint8_t *)(p + 23), QEMU_VERSION, 8); /* firmware version */
514 5391d806 bellard
    padstr((uint8_t *)(p + 27), "QEMU CD-ROM", 40); /* model */
515 67b915a5 bellard
    put_le16(p + 48, 1); /* dword I/O (XXX: should not be set on CDROM) */
516 67b915a5 bellard
    put_le16(p + 49, 1 << 9); /* LBA supported, no DMA */
517 67b915a5 bellard
    put_le16(p + 53, 3); /* words 64-70, 54-58 valid */
518 67b915a5 bellard
    put_le16(p + 63, 0x103); /* DMA modes XXX: may be incorrect */
519 67b915a5 bellard
    put_le16(p + 64, 1); /* PIO modes */
520 67b915a5 bellard
    put_le16(p + 65, 0xb4); /* minimum DMA multiword tx cycle time */
521 67b915a5 bellard
    put_le16(p + 66, 0xb4); /* recommended DMA multiword tx cycle time */
522 67b915a5 bellard
    put_le16(p + 67, 0x12c); /* minimum PIO cycle time without flow control */
523 67b915a5 bellard
    put_le16(p + 68, 0xb4); /* minimum PIO cycle time with IORDY flow control */
524 94458802 bellard
525 67b915a5 bellard
    put_le16(p + 71, 30); /* in ns */
526 67b915a5 bellard
    put_le16(p + 72, 30); /* in ns */
527 5391d806 bellard
528 67b915a5 bellard
    put_le16(p + 80, 0x1e); /* support up to ATA/ATAPI-4 */
529 94458802 bellard
530 94458802 bellard
    memcpy(s->identify_data, p, sizeof(s->identify_data));
531 94458802 bellard
    s->identify_set = 1;
532 5391d806 bellard
}
533 5391d806 bellard
534 5391d806 bellard
static void ide_set_signature(IDEState *s)
535 5391d806 bellard
{
536 5391d806 bellard
    s->select &= 0xf0; /* clear head */
537 5391d806 bellard
    /* put signature */
538 5391d806 bellard
    s->nsector = 1;
539 5391d806 bellard
    s->sector = 1;
540 5391d806 bellard
    if (s->is_cdrom) {
541 5391d806 bellard
        s->lcyl = 0x14;
542 5391d806 bellard
        s->hcyl = 0xeb;
543 5391d806 bellard
    } else if (s->bs) {
544 5391d806 bellard
        s->lcyl = 0;
545 5391d806 bellard
        s->hcyl = 0;
546 5391d806 bellard
    } else {
547 5391d806 bellard
        s->lcyl = 0xff;
548 5391d806 bellard
        s->hcyl = 0xff;
549 5391d806 bellard
    }
550 5391d806 bellard
}
551 5391d806 bellard
552 5391d806 bellard
static inline void ide_abort_command(IDEState *s)
553 5391d806 bellard
{
554 5391d806 bellard
    s->status = READY_STAT | ERR_STAT;
555 5391d806 bellard
    s->error = ABRT_ERR;
556 5391d806 bellard
}
557 5391d806 bellard
558 5391d806 bellard
static inline void ide_set_irq(IDEState *s)
559 5391d806 bellard
{
560 98ff7d30 bellard
    BMDMAState *bm = s->bmdma;
561 5391d806 bellard
    if (!(s->cmd & IDE_CMD_DISABLE_IRQ)) {
562 5457c8ce bellard
        if (bm) {
563 98ff7d30 bellard
            bm->status |= BM_STATUS_INT;
564 5457c8ce bellard
        }
565 5457c8ce bellard
        s->set_irq(s->irq_opaque, s->irq, 1);
566 5391d806 bellard
    }
567 5391d806 bellard
}
568 5391d806 bellard
569 5391d806 bellard
/* prepare data transfer and tell what to do after */
570 5391d806 bellard
static void ide_transfer_start(IDEState *s, uint8_t *buf, int size, 
571 5391d806 bellard
                               EndTransferFunc *end_transfer_func)
572 5391d806 bellard
{
573 5391d806 bellard
    s->end_transfer_func = end_transfer_func;
574 5391d806 bellard
    s->data_ptr = buf;
575 5391d806 bellard
    s->data_end = buf + size;
576 5391d806 bellard
    s->status |= DRQ_STAT;
577 5391d806 bellard
}
578 5391d806 bellard
579 5391d806 bellard
static void ide_transfer_stop(IDEState *s)
580 5391d806 bellard
{
581 5391d806 bellard
    s->end_transfer_func = ide_transfer_stop;
582 5391d806 bellard
    s->data_ptr = s->io_buffer;
583 5391d806 bellard
    s->data_end = s->io_buffer;
584 5391d806 bellard
    s->status &= ~DRQ_STAT;
585 5391d806 bellard
}
586 5391d806 bellard
587 5391d806 bellard
static int64_t ide_get_sector(IDEState *s)
588 5391d806 bellard
{
589 5391d806 bellard
    int64_t sector_num;
590 5391d806 bellard
    if (s->select & 0x40) {
591 5391d806 bellard
        /* lba */
592 c2ff060f bellard
        if (!s->lba48) {
593 c2ff060f bellard
            sector_num = ((s->select & 0x0f) << 24) | (s->hcyl << 16) |
594 c2ff060f bellard
                (s->lcyl << 8) | s->sector;
595 c2ff060f bellard
        } else {
596 c2ff060f bellard
            sector_num = ((int64_t)s->hob_hcyl << 40) |
597 c2ff060f bellard
                ((int64_t) s->hob_lcyl << 32) |
598 c2ff060f bellard
                ((int64_t) s->hob_sector << 24) |
599 c2ff060f bellard
                ((int64_t) s->hcyl << 16) |
600 c2ff060f bellard
                ((int64_t) s->lcyl << 8) | s->sector;
601 c2ff060f bellard
        }
602 5391d806 bellard
    } else {
603 5391d806 bellard
        sector_num = ((s->hcyl << 8) | s->lcyl) * s->heads * s->sectors +
604 c2ff060f bellard
            (s->select & 0x0f) * s->sectors + (s->sector - 1);
605 5391d806 bellard
    }
606 5391d806 bellard
    return sector_num;
607 5391d806 bellard
}
608 5391d806 bellard
609 5391d806 bellard
static void ide_set_sector(IDEState *s, int64_t sector_num)
610 5391d806 bellard
{
611 5391d806 bellard
    unsigned int cyl, r;
612 5391d806 bellard
    if (s->select & 0x40) {
613 c2ff060f bellard
        if (!s->lba48) {
614 c2ff060f bellard
            s->select = (s->select & 0xf0) | (sector_num >> 24);
615 c2ff060f bellard
            s->hcyl = (sector_num >> 16);
616 c2ff060f bellard
            s->lcyl = (sector_num >> 8);
617 c2ff060f bellard
            s->sector = (sector_num);
618 c2ff060f bellard
        } else {
619 c2ff060f bellard
            s->sector = sector_num;
620 c2ff060f bellard
            s->lcyl = sector_num >> 8;
621 c2ff060f bellard
            s->hcyl = sector_num >> 16;
622 c2ff060f bellard
            s->hob_sector = sector_num >> 24;
623 c2ff060f bellard
            s->hob_lcyl = sector_num >> 32;
624 c2ff060f bellard
            s->hob_hcyl = sector_num >> 40;
625 c2ff060f bellard
        }
626 5391d806 bellard
    } else {
627 5391d806 bellard
        cyl = sector_num / (s->heads * s->sectors);
628 5391d806 bellard
        r = sector_num % (s->heads * s->sectors);
629 5391d806 bellard
        s->hcyl = cyl >> 8;
630 5391d806 bellard
        s->lcyl = cyl;
631 1b8eb456 bellard
        s->select = (s->select & 0xf0) | ((r / s->sectors) & 0x0f);
632 5391d806 bellard
        s->sector = (r % s->sectors) + 1;
633 5391d806 bellard
    }
634 5391d806 bellard
}
635 5391d806 bellard
636 5391d806 bellard
static void ide_sector_read(IDEState *s)
637 5391d806 bellard
{
638 5391d806 bellard
    int64_t sector_num;
639 5391d806 bellard
    int ret, n;
640 5391d806 bellard
641 5391d806 bellard
    s->status = READY_STAT | SEEK_STAT;
642 a136e5a8 bellard
    s->error = 0; /* not needed by IDE spec, but needed by Windows */
643 5391d806 bellard
    sector_num = ide_get_sector(s);
644 5391d806 bellard
    n = s->nsector;
645 5391d806 bellard
    if (n == 0) {
646 5391d806 bellard
        /* no more sector to read from disk */
647 5391d806 bellard
        ide_transfer_stop(s);
648 5391d806 bellard
    } else {
649 5391d806 bellard
#if defined(DEBUG_IDE)
650 5391d806 bellard
        printf("read sector=%Ld\n", sector_num);
651 5391d806 bellard
#endif
652 5391d806 bellard
        if (n > s->req_nb_sectors)
653 5391d806 bellard
            n = s->req_nb_sectors;
654 5391d806 bellard
        ret = bdrv_read(s->bs, sector_num, s->io_buffer, n);
655 5391d806 bellard
        ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_read);
656 5391d806 bellard
        ide_set_irq(s);
657 5391d806 bellard
        ide_set_sector(s, sector_num + n);
658 5391d806 bellard
        s->nsector -= n;
659 5391d806 bellard
    }
660 5391d806 bellard
}
661 5391d806 bellard
662 98087450 bellard
static int ide_read_dma_cb(IDEState *s, 
663 98087450 bellard
                           target_phys_addr_t phys_addr, 
664 98087450 bellard
                           int transfer_size1)
665 98087450 bellard
{
666 98087450 bellard
    int len, transfer_size, n;
667 98087450 bellard
    int64_t sector_num;
668 98087450 bellard
669 98087450 bellard
    transfer_size = transfer_size1;
670 98087450 bellard
    while (transfer_size > 0) {
671 98087450 bellard
        len = s->io_buffer_size - s->io_buffer_index;
672 98087450 bellard
        if (len <= 0) {
673 98087450 bellard
            /* transfert next data */
674 98087450 bellard
            n = s->nsector;
675 98087450 bellard
            if (n == 0)
676 98087450 bellard
                break;
677 98087450 bellard
            if (n > MAX_MULT_SECTORS)
678 98087450 bellard
                n = MAX_MULT_SECTORS;
679 98087450 bellard
            sector_num = ide_get_sector(s);
680 98087450 bellard
            bdrv_read(s->bs, sector_num, s->io_buffer, n);
681 98087450 bellard
            s->io_buffer_index = 0;
682 98087450 bellard
            s->io_buffer_size = n * 512;
683 98087450 bellard
            len = s->io_buffer_size;
684 98087450 bellard
            sector_num += n;
685 98087450 bellard
            ide_set_sector(s, sector_num);
686 98087450 bellard
            s->nsector -= n;
687 98087450 bellard
        }
688 98087450 bellard
        if (len > transfer_size)
689 98087450 bellard
            len = transfer_size;
690 98087450 bellard
        cpu_physical_memory_write(phys_addr, 
691 98087450 bellard
                                  s->io_buffer + s->io_buffer_index, len);
692 98087450 bellard
        s->io_buffer_index += len;
693 98087450 bellard
        transfer_size -= len;
694 98087450 bellard
        phys_addr += len;
695 98087450 bellard
    }
696 98087450 bellard
    if (s->io_buffer_index >= s->io_buffer_size && s->nsector == 0) {
697 98087450 bellard
        s->status = READY_STAT | SEEK_STAT;
698 98087450 bellard
        ide_set_irq(s);
699 98087450 bellard
#ifdef DEBUG_IDE_ATAPI
700 98087450 bellard
        printf("dma status=0x%x\n", s->status);
701 98087450 bellard
#endif
702 98087450 bellard
        return 0;
703 98087450 bellard
    }
704 98087450 bellard
    return transfer_size1 - transfer_size;
705 98087450 bellard
}
706 98087450 bellard
707 98087450 bellard
static void ide_sector_read_dma(IDEState *s)
708 98087450 bellard
{
709 98087450 bellard
    s->status = READY_STAT | SEEK_STAT | DRQ_STAT;
710 98087450 bellard
    s->io_buffer_index = 0;
711 98087450 bellard
    s->io_buffer_size = 0;
712 98087450 bellard
    ide_dma_start(s, ide_read_dma_cb);
713 98087450 bellard
}
714 98087450 bellard
715 a09db21f bellard
static void ide_sector_write_timer_cb(void *opaque)
716 a09db21f bellard
{
717 a09db21f bellard
    IDEState *s = opaque;
718 a09db21f bellard
    ide_set_irq(s);
719 a09db21f bellard
}
720 a09db21f bellard
721 5391d806 bellard
static void ide_sector_write(IDEState *s)
722 5391d806 bellard
{
723 5391d806 bellard
    int64_t sector_num;
724 5391d806 bellard
    int ret, n, n1;
725 5391d806 bellard
726 5391d806 bellard
    s->status = READY_STAT | SEEK_STAT;
727 5391d806 bellard
    sector_num = ide_get_sector(s);
728 5391d806 bellard
#if defined(DEBUG_IDE)
729 5391d806 bellard
    printf("write sector=%Ld\n", sector_num);
730 5391d806 bellard
#endif
731 5391d806 bellard
    n = s->nsector;
732 5391d806 bellard
    if (n > s->req_nb_sectors)
733 5391d806 bellard
        n = s->req_nb_sectors;
734 5391d806 bellard
    ret = bdrv_write(s->bs, sector_num, s->io_buffer, n);
735 5391d806 bellard
    s->nsector -= n;
736 5391d806 bellard
    if (s->nsector == 0) {
737 5391d806 bellard
        /* no more sector to write */
738 5391d806 bellard
        ide_transfer_stop(s);
739 5391d806 bellard
    } else {
740 5391d806 bellard
        n1 = s->nsector;
741 5391d806 bellard
        if (n1 > s->req_nb_sectors)
742 5391d806 bellard
            n1 = s->req_nb_sectors;
743 5391d806 bellard
        ide_transfer_start(s, s->io_buffer, 512 * n1, ide_sector_write);
744 5391d806 bellard
    }
745 5391d806 bellard
    ide_set_sector(s, sector_num + n);
746 a09db21f bellard
    
747 a09db21f bellard
#ifdef TARGET_I386
748 e774a278 bellard
    if (win2k_install_hack && ((++s->irq_count % 16) == 0)) {
749 a09db21f bellard
        /* It seems there is a bug in the Windows 2000 installer HDD
750 a09db21f bellard
           IDE driver which fills the disk with empty logs when the
751 a09db21f bellard
           IDE write IRQ comes too early. This hack tries to correct
752 a09db21f bellard
           that at the expense of slower write performances. Use this
753 a09db21f bellard
           option _only_ to install Windows 2000. You must disable it
754 a09db21f bellard
           for normal use. */
755 a09db21f bellard
        qemu_mod_timer(s->sector_write_timer, 
756 a09db21f bellard
                       qemu_get_clock(vm_clock) + (ticks_per_sec / 1000));
757 a09db21f bellard
    } else 
758 a09db21f bellard
#endif
759 a09db21f bellard
    {
760 a09db21f bellard
        ide_set_irq(s);
761 a09db21f bellard
    }
762 5391d806 bellard
}
763 5391d806 bellard
764 98087450 bellard
static int ide_write_dma_cb(IDEState *s, 
765 98087450 bellard
                            target_phys_addr_t phys_addr, 
766 98087450 bellard
                            int transfer_size1)
767 98087450 bellard
{
768 98087450 bellard
    int len, transfer_size, n;
769 98087450 bellard
    int64_t sector_num;
770 98087450 bellard
771 98087450 bellard
    transfer_size = transfer_size1;
772 98087450 bellard
    for(;;) {
773 98087450 bellard
        len = s->io_buffer_size - s->io_buffer_index;
774 98087450 bellard
        if (len == 0) {
775 98087450 bellard
            n = s->io_buffer_size >> 9;
776 98087450 bellard
            sector_num = ide_get_sector(s);
777 98087450 bellard
            bdrv_write(s->bs, sector_num, s->io_buffer, 
778 98087450 bellard
                       s->io_buffer_size >> 9);
779 98087450 bellard
            sector_num += n;
780 98087450 bellard
            ide_set_sector(s, sector_num);
781 98087450 bellard
            s->nsector -= n;
782 98087450 bellard
            n = s->nsector;
783 98087450 bellard
            if (n == 0) {
784 98087450 bellard
                /* end of transfer */
785 98087450 bellard
                s->status = READY_STAT | SEEK_STAT;
786 e774a278 bellard
#ifdef TARGET_I386
787 e774a278 bellard
                if (win2k_install_hack && ((++s->irq_count % 16) == 0)) {
788 e774a278 bellard
                    /* It seems there is a bug in the Windows 2000 installer 
789 e774a278 bellard
                       HDD IDE driver which fills the disk with empty logs 
790 e774a278 bellard
                       when the IDE write IRQ comes too early. This hack tries 
791 e774a278 bellard
                       to correct that at the expense of slower write 
792 e774a278 bellard
                       performances. Use this option _only_ to install Windows 
793 e774a278 bellard
                       2000. You must disable it for normal use. */
794 e774a278 bellard
                    qemu_mod_timer(s->sector_write_timer, 
795 e774a278 bellard
                            qemu_get_clock(vm_clock) + (ticks_per_sec / 1000));
796 e774a278 bellard
                } else 
797 e774a278 bellard
#endif
798 e774a278 bellard
                    ide_set_irq(s);
799 98087450 bellard
                return 0;
800 98087450 bellard
            }
801 98087450 bellard
            if (n > MAX_MULT_SECTORS)
802 98087450 bellard
                n = MAX_MULT_SECTORS;
803 98087450 bellard
            s->io_buffer_index = 0;
804 98087450 bellard
            s->io_buffer_size = n * 512;
805 98087450 bellard
            len = s->io_buffer_size;
806 98087450 bellard
        }
807 98087450 bellard
        if (transfer_size <= 0)
808 98087450 bellard
            break;
809 98087450 bellard
        if (len > transfer_size)
810 98087450 bellard
            len = transfer_size;
811 98087450 bellard
        cpu_physical_memory_read(phys_addr, 
812 98087450 bellard
                                 s->io_buffer + s->io_buffer_index, len);
813 98087450 bellard
        s->io_buffer_index += len;
814 98087450 bellard
        transfer_size -= len;
815 98087450 bellard
        phys_addr += len;
816 98087450 bellard
    }
817 98087450 bellard
    return transfer_size1 - transfer_size;
818 98087450 bellard
}
819 98087450 bellard
820 98087450 bellard
static void ide_sector_write_dma(IDEState *s)
821 98087450 bellard
{
822 98087450 bellard
    int n;
823 98087450 bellard
    s->status = READY_STAT | SEEK_STAT | DRQ_STAT;
824 98087450 bellard
    n = s->nsector;
825 98087450 bellard
    if (n > MAX_MULT_SECTORS)
826 98087450 bellard
        n = MAX_MULT_SECTORS;
827 98087450 bellard
    s->io_buffer_index = 0;
828 98087450 bellard
    s->io_buffer_size = n * 512;
829 98087450 bellard
    ide_dma_start(s, ide_write_dma_cb);
830 98087450 bellard
}
831 98087450 bellard
832 5391d806 bellard
static void ide_atapi_cmd_ok(IDEState *s)
833 5391d806 bellard
{
834 5391d806 bellard
    s->error = 0;
835 5391d806 bellard
    s->status = READY_STAT;
836 5391d806 bellard
    s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
837 5391d806 bellard
    ide_set_irq(s);
838 5391d806 bellard
}
839 5391d806 bellard
840 5391d806 bellard
static void ide_atapi_cmd_error(IDEState *s, int sense_key, int asc)
841 5391d806 bellard
{
842 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
843 5391d806 bellard
    printf("atapi_cmd_error: sense=0x%x asc=0x%x\n", sense_key, asc);
844 5391d806 bellard
#endif
845 5391d806 bellard
    s->error = sense_key << 4;
846 5391d806 bellard
    s->status = READY_STAT | ERR_STAT;
847 5391d806 bellard
    s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
848 5391d806 bellard
    s->sense_key = sense_key;
849 5391d806 bellard
    s->asc = asc;
850 5391d806 bellard
    ide_set_irq(s);
851 5391d806 bellard
}
852 5391d806 bellard
853 5391d806 bellard
static inline void cpu_to_ube16(uint8_t *buf, int val)
854 5391d806 bellard
{
855 5391d806 bellard
    buf[0] = val >> 8;
856 5391d806 bellard
    buf[1] = val;
857 5391d806 bellard
}
858 5391d806 bellard
859 5391d806 bellard
static inline void cpu_to_ube32(uint8_t *buf, unsigned int val)
860 5391d806 bellard
{
861 5391d806 bellard
    buf[0] = val >> 24;
862 5391d806 bellard
    buf[1] = val >> 16;
863 5391d806 bellard
    buf[2] = val >> 8;
864 5391d806 bellard
    buf[3] = val;
865 5391d806 bellard
}
866 5391d806 bellard
867 5391d806 bellard
static inline int ube16_to_cpu(const uint8_t *buf)
868 5391d806 bellard
{
869 5391d806 bellard
    return (buf[0] << 8) | buf[1];
870 5391d806 bellard
}
871 5391d806 bellard
872 5391d806 bellard
static inline int ube32_to_cpu(const uint8_t *buf)
873 5391d806 bellard
{
874 5391d806 bellard
    return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
875 5391d806 bellard
}
876 5391d806 bellard
877 98087450 bellard
static void lba_to_msf(uint8_t *buf, int lba)
878 98087450 bellard
{
879 98087450 bellard
    lba += 150;
880 98087450 bellard
    buf[0] = (lba / 75) / 60;
881 98087450 bellard
    buf[1] = (lba / 75) % 60;
882 98087450 bellard
    buf[2] = lba % 75;
883 98087450 bellard
}
884 98087450 bellard
885 98087450 bellard
static void cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf, 
886 98087450 bellard
                           int sector_size)
887 98087450 bellard
{
888 98087450 bellard
    switch(sector_size) {
889 98087450 bellard
    case 2048:
890 98087450 bellard
        bdrv_read(bs, (int64_t)lba << 2, buf, 4);
891 98087450 bellard
        break;
892 98087450 bellard
    case 2352:
893 98087450 bellard
        /* sync bytes */
894 98087450 bellard
        buf[0] = 0x00;
895 5457c8ce bellard
        memset(buf + 1, 0xff, 10);
896 5457c8ce bellard
        buf[11] = 0x00;
897 98087450 bellard
        buf += 12;
898 98087450 bellard
        /* MSF */
899 98087450 bellard
        lba_to_msf(buf, lba);
900 98087450 bellard
        buf[3] = 0x01; /* mode 1 data */
901 98087450 bellard
        buf += 4;
902 98087450 bellard
        /* data */
903 98087450 bellard
        bdrv_read(bs, (int64_t)lba << 2, buf, 4);
904 98087450 bellard
        buf += 2048;
905 98087450 bellard
        /* ECC */
906 98087450 bellard
        memset(buf, 0, 288);
907 98087450 bellard
        break;
908 98087450 bellard
    default:
909 98087450 bellard
        break;
910 98087450 bellard
    }
911 98087450 bellard
}
912 98087450 bellard
913 5391d806 bellard
/* The whole ATAPI transfer logic is handled in this function */
914 5391d806 bellard
static void ide_atapi_cmd_reply_end(IDEState *s)
915 5391d806 bellard
{
916 5391d806 bellard
    int byte_count_limit, size;
917 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
918 5391d806 bellard
    printf("reply: tx_size=%d elem_tx_size=%d index=%d\n", 
919 5391d806 bellard
           s->packet_transfer_size,
920 5391d806 bellard
           s->elementary_transfer_size,
921 5391d806 bellard
           s->io_buffer_index);
922 5391d806 bellard
#endif
923 5391d806 bellard
    if (s->packet_transfer_size <= 0) {
924 5391d806 bellard
        /* end of transfer */
925 5391d806 bellard
        ide_transfer_stop(s);
926 5391d806 bellard
        s->status = READY_STAT;
927 5391d806 bellard
        s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
928 5391d806 bellard
        ide_set_irq(s);
929 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
930 5391d806 bellard
        printf("status=0x%x\n", s->status);
931 5391d806 bellard
#endif
932 5391d806 bellard
    } else {
933 5391d806 bellard
        /* see if a new sector must be read */
934 98087450 bellard
        if (s->lba != -1 && s->io_buffer_index >= s->cd_sector_size) {
935 98087450 bellard
            cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size);
936 5391d806 bellard
            s->lba++;
937 5391d806 bellard
            s->io_buffer_index = 0;
938 5391d806 bellard
        }
939 5391d806 bellard
        if (s->elementary_transfer_size > 0) {
940 5391d806 bellard
            /* there are some data left to transmit in this elementary
941 5391d806 bellard
               transfer */
942 98087450 bellard
            size = s->cd_sector_size - s->io_buffer_index;
943 5391d806 bellard
            if (size > s->elementary_transfer_size)
944 5391d806 bellard
                size = s->elementary_transfer_size;
945 5391d806 bellard
            ide_transfer_start(s, s->io_buffer + s->io_buffer_index, 
946 5391d806 bellard
                               size, ide_atapi_cmd_reply_end);
947 5391d806 bellard
            s->packet_transfer_size -= size;
948 5391d806 bellard
            s->elementary_transfer_size -= size;
949 5391d806 bellard
            s->io_buffer_index += size;
950 5391d806 bellard
        } else {
951 5391d806 bellard
            /* a new transfer is needed */
952 5391d806 bellard
            s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO;
953 5391d806 bellard
            byte_count_limit = s->lcyl | (s->hcyl << 8);
954 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
955 5391d806 bellard
            printf("byte_count_limit=%d\n", byte_count_limit);
956 5391d806 bellard
#endif
957 5391d806 bellard
            if (byte_count_limit == 0xffff)
958 5391d806 bellard
                byte_count_limit--;
959 5391d806 bellard
            size = s->packet_transfer_size;
960 5391d806 bellard
            if (size > byte_count_limit) {
961 5391d806 bellard
                /* byte count limit must be even if this case */
962 5391d806 bellard
                if (byte_count_limit & 1)
963 5391d806 bellard
                    byte_count_limit--;
964 5391d806 bellard
                size = byte_count_limit;
965 5391d806 bellard
            }
966 a136e5a8 bellard
            s->lcyl = size;
967 a136e5a8 bellard
            s->hcyl = size >> 8;
968 5391d806 bellard
            s->elementary_transfer_size = size;
969 5391d806 bellard
            /* we cannot transmit more than one sector at a time */
970 5391d806 bellard
            if (s->lba != -1) {
971 98087450 bellard
                if (size > (s->cd_sector_size - s->io_buffer_index))
972 98087450 bellard
                    size = (s->cd_sector_size - s->io_buffer_index);
973 5391d806 bellard
            }
974 5391d806 bellard
            ide_transfer_start(s, s->io_buffer + s->io_buffer_index, 
975 5391d806 bellard
                               size, ide_atapi_cmd_reply_end);
976 5391d806 bellard
            s->packet_transfer_size -= size;
977 5391d806 bellard
            s->elementary_transfer_size -= size;
978 5391d806 bellard
            s->io_buffer_index += size;
979 5391d806 bellard
            ide_set_irq(s);
980 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
981 5391d806 bellard
            printf("status=0x%x\n", s->status);
982 5391d806 bellard
#endif
983 5391d806 bellard
        }
984 5391d806 bellard
    }
985 5391d806 bellard
}
986 5391d806 bellard
987 5391d806 bellard
/* send a reply of 'size' bytes in s->io_buffer to an ATAPI command */
988 5391d806 bellard
static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size)
989 5391d806 bellard
{
990 5391d806 bellard
    if (size > max_size)
991 5391d806 bellard
        size = max_size;
992 5391d806 bellard
    s->lba = -1; /* no sector read */
993 5391d806 bellard
    s->packet_transfer_size = size;
994 5391d806 bellard
    s->elementary_transfer_size = 0;
995 5391d806 bellard
    s->io_buffer_index = 0;
996 5391d806 bellard
997 5391d806 bellard
    s->status = READY_STAT;
998 5391d806 bellard
    ide_atapi_cmd_reply_end(s);
999 5391d806 bellard
}
1000 5391d806 bellard
1001 5391d806 bellard
/* start a CD-CDROM read command */
1002 98087450 bellard
static void ide_atapi_cmd_read_pio(IDEState *s, int lba, int nb_sectors,
1003 98087450 bellard
                                   int sector_size)
1004 5391d806 bellard
{
1005 5391d806 bellard
    s->lba = lba;
1006 98087450 bellard
    s->packet_transfer_size = nb_sectors * sector_size;
1007 5391d806 bellard
    s->elementary_transfer_size = 0;
1008 98087450 bellard
    s->io_buffer_index = sector_size;
1009 98087450 bellard
    s->cd_sector_size = sector_size;
1010 5391d806 bellard
1011 5391d806 bellard
    s->status = READY_STAT;
1012 5391d806 bellard
    ide_atapi_cmd_reply_end(s);
1013 5391d806 bellard
}
1014 5391d806 bellard
1015 98087450 bellard
/* ATAPI DMA support */
1016 98087450 bellard
static int ide_atapi_cmd_read_dma_cb(IDEState *s, 
1017 98087450 bellard
                                     target_phys_addr_t phys_addr, 
1018 98087450 bellard
                                     int transfer_size1)
1019 98087450 bellard
{
1020 98087450 bellard
    int len, transfer_size;
1021 98087450 bellard
    
1022 98087450 bellard
    transfer_size = transfer_size1;
1023 98087450 bellard
    while (transfer_size > 0) {
1024 5457c8ce bellard
#ifdef DEBUG_IDE_ATAPI
1025 5457c8ce bellard
        printf("transfer_size: %d phys_addr=%08x\n", transfer_size, phys_addr);
1026 5457c8ce bellard
#endif
1027 98087450 bellard
        if (s->packet_transfer_size <= 0)
1028 98087450 bellard
            break;
1029 98087450 bellard
        len = s->cd_sector_size - s->io_buffer_index;
1030 98087450 bellard
        if (len <= 0) {
1031 98087450 bellard
            /* transfert next data */
1032 98087450 bellard
            cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size);
1033 98087450 bellard
            s->lba++;
1034 98087450 bellard
            s->io_buffer_index = 0;
1035 98087450 bellard
            len = s->cd_sector_size;
1036 98087450 bellard
        }
1037 98087450 bellard
        if (len > transfer_size)
1038 98087450 bellard
            len = transfer_size;
1039 98087450 bellard
        cpu_physical_memory_write(phys_addr, 
1040 98087450 bellard
                                  s->io_buffer + s->io_buffer_index, len);
1041 98087450 bellard
        s->packet_transfer_size -= len;
1042 98087450 bellard
        s->io_buffer_index += len;
1043 98087450 bellard
        transfer_size -= len;
1044 98087450 bellard
        phys_addr += len;
1045 98087450 bellard
    }
1046 98087450 bellard
    if (s->packet_transfer_size <= 0) {
1047 98087450 bellard
        s->status = READY_STAT;
1048 98087450 bellard
        s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
1049 98087450 bellard
        ide_set_irq(s);
1050 98087450 bellard
#ifdef DEBUG_IDE_ATAPI
1051 98087450 bellard
        printf("dma status=0x%x\n", s->status);
1052 98087450 bellard
#endif
1053 98087450 bellard
        return 0;
1054 98087450 bellard
    }
1055 98087450 bellard
    return transfer_size1 - transfer_size;
1056 98087450 bellard
}
1057 98087450 bellard
1058 98087450 bellard
/* start a CD-CDROM read command with DMA */
1059 98087450 bellard
/* XXX: test if DMA is available */
1060 98087450 bellard
static void ide_atapi_cmd_read_dma(IDEState *s, int lba, int nb_sectors,
1061 98087450 bellard
                                   int sector_size)
1062 98087450 bellard
{
1063 98087450 bellard
    s->lba = lba;
1064 98087450 bellard
    s->packet_transfer_size = nb_sectors * sector_size;
1065 98087450 bellard
    s->io_buffer_index = sector_size;
1066 98087450 bellard
    s->cd_sector_size = sector_size;
1067 98087450 bellard
1068 98087450 bellard
    s->status = READY_STAT | DRQ_STAT;
1069 98087450 bellard
    ide_dma_start(s, ide_atapi_cmd_read_dma_cb);
1070 98087450 bellard
}
1071 98087450 bellard
1072 98087450 bellard
static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors, 
1073 98087450 bellard
                               int sector_size)
1074 98087450 bellard
{
1075 98087450 bellard
#ifdef DEBUG_IDE_ATAPI
1076 98087450 bellard
    printf("read: LBA=%d nb_sectors=%d\n", lba, nb_sectors);
1077 98087450 bellard
#endif
1078 98087450 bellard
    if (s->atapi_dma) {
1079 98087450 bellard
        ide_atapi_cmd_read_dma(s, lba, nb_sectors, sector_size);
1080 98087450 bellard
    } else {
1081 98087450 bellard
        ide_atapi_cmd_read_pio(s, lba, nb_sectors, sector_size);
1082 98087450 bellard
    }
1083 98087450 bellard
}
1084 98087450 bellard
1085 5391d806 bellard
static void ide_atapi_cmd(IDEState *s)
1086 5391d806 bellard
{
1087 5391d806 bellard
    const uint8_t *packet;
1088 5391d806 bellard
    uint8_t *buf;
1089 5391d806 bellard
    int max_len;
1090 5391d806 bellard
1091 5391d806 bellard
    packet = s->io_buffer;
1092 5391d806 bellard
    buf = s->io_buffer;
1093 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
1094 5391d806 bellard
    {
1095 5391d806 bellard
        int i;
1096 5391d806 bellard
        printf("ATAPI limit=0x%x packet:", s->lcyl | (s->hcyl << 8));
1097 5391d806 bellard
        for(i = 0; i < ATAPI_PACKET_SIZE; i++) {
1098 5391d806 bellard
            printf(" %02x", packet[i]);
1099 5391d806 bellard
        }
1100 5391d806 bellard
        printf("\n");
1101 5391d806 bellard
    }
1102 5391d806 bellard
#endif
1103 5391d806 bellard
    switch(s->io_buffer[0]) {
1104 5391d806 bellard
    case GPCMD_TEST_UNIT_READY:
1105 caed8802 bellard
        if (bdrv_is_inserted(s->bs)) {
1106 5391d806 bellard
            ide_atapi_cmd_ok(s);
1107 5391d806 bellard
        } else {
1108 5391d806 bellard
            ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1109 5391d806 bellard
                                ASC_MEDIUM_NOT_PRESENT);
1110 5391d806 bellard
        }
1111 5391d806 bellard
        break;
1112 5391d806 bellard
    case GPCMD_MODE_SENSE_10:
1113 5391d806 bellard
        {
1114 5391d806 bellard
            int action, code;
1115 5391d806 bellard
            max_len = ube16_to_cpu(packet + 7);
1116 5391d806 bellard
            action = packet[2] >> 6;
1117 5391d806 bellard
            code = packet[2] & 0x3f;
1118 5391d806 bellard
            switch(action) {
1119 5391d806 bellard
            case 0: /* current values */
1120 5391d806 bellard
                switch(code) {
1121 5391d806 bellard
                case 0x01: /* error recovery */
1122 5391d806 bellard
                    cpu_to_ube16(&buf[0], 16 + 6);
1123 5391d806 bellard
                    buf[2] = 0x70;
1124 5391d806 bellard
                    buf[3] = 0;
1125 5391d806 bellard
                    buf[4] = 0;
1126 5391d806 bellard
                    buf[5] = 0;
1127 5391d806 bellard
                    buf[6] = 0;
1128 5391d806 bellard
                    buf[7] = 0;
1129 5391d806 bellard
1130 5391d806 bellard
                    buf[8] = 0x01;
1131 5391d806 bellard
                    buf[9] = 0x06;
1132 5391d806 bellard
                    buf[10] = 0x00;
1133 5391d806 bellard
                    buf[11] = 0x05;
1134 5391d806 bellard
                    buf[12] = 0x00;
1135 5391d806 bellard
                    buf[13] = 0x00;
1136 5391d806 bellard
                    buf[14] = 0x00;
1137 5391d806 bellard
                    buf[15] = 0x00;
1138 5391d806 bellard
                    ide_atapi_cmd_reply(s, 16, max_len);
1139 5391d806 bellard
                    break;
1140 5391d806 bellard
                case 0x2a:
1141 5391d806 bellard
                    cpu_to_ube16(&buf[0], 28 + 6);
1142 5391d806 bellard
                    buf[2] = 0x70;
1143 5391d806 bellard
                    buf[3] = 0;
1144 5391d806 bellard
                    buf[4] = 0;
1145 5391d806 bellard
                    buf[5] = 0;
1146 5391d806 bellard
                    buf[6] = 0;
1147 5391d806 bellard
                    buf[7] = 0;
1148 5391d806 bellard
1149 5391d806 bellard
                    buf[8] = 0x2a;
1150 5391d806 bellard
                    buf[9] = 0x12;
1151 5391d806 bellard
                    buf[10] = 0x00;
1152 5391d806 bellard
                    buf[11] = 0x00;
1153 5391d806 bellard
                    
1154 5391d806 bellard
                    buf[12] = 0x70;
1155 5391d806 bellard
                    buf[13] = 3 << 5;
1156 5391d806 bellard
                    buf[14] = (1 << 0) | (1 << 3) | (1 << 5);
1157 caed8802 bellard
                    if (bdrv_is_locked(s->bs))
1158 5391d806 bellard
                        buf[6] |= 1 << 1;
1159 5391d806 bellard
                    buf[15] = 0x00;
1160 5391d806 bellard
                    cpu_to_ube16(&buf[16], 706);
1161 5391d806 bellard
                    buf[18] = 0;
1162 5391d806 bellard
                    buf[19] = 2;
1163 5391d806 bellard
                    cpu_to_ube16(&buf[20], 512);
1164 5391d806 bellard
                    cpu_to_ube16(&buf[22], 706);
1165 5391d806 bellard
                    buf[24] = 0;
1166 5391d806 bellard
                    buf[25] = 0;
1167 5391d806 bellard
                    buf[26] = 0;
1168 5391d806 bellard
                    buf[27] = 0;
1169 5391d806 bellard
                    ide_atapi_cmd_reply(s, 28, max_len);
1170 5391d806 bellard
                    break;
1171 5391d806 bellard
                default:
1172 5391d806 bellard
                    goto error_cmd;
1173 5391d806 bellard
                }
1174 5391d806 bellard
                break;
1175 5391d806 bellard
            case 1: /* changeable values */
1176 5391d806 bellard
                goto error_cmd;
1177 5391d806 bellard
            case 2: /* default values */
1178 5391d806 bellard
                goto error_cmd;
1179 5391d806 bellard
            default:
1180 5391d806 bellard
            case 3: /* saved values */
1181 5391d806 bellard
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1182 5391d806 bellard
                                    ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
1183 5391d806 bellard
                break;
1184 5391d806 bellard
            }
1185 5391d806 bellard
        }
1186 5391d806 bellard
        break;
1187 5391d806 bellard
    case GPCMD_REQUEST_SENSE:
1188 5391d806 bellard
        max_len = packet[4];
1189 5391d806 bellard
        memset(buf, 0, 18);
1190 5391d806 bellard
        buf[0] = 0x70 | (1 << 7);
1191 5391d806 bellard
        buf[2] = s->sense_key;
1192 5391d806 bellard
        buf[7] = 10;
1193 5391d806 bellard
        buf[12] = s->asc;
1194 5391d806 bellard
        ide_atapi_cmd_reply(s, 18, max_len);
1195 5391d806 bellard
        break;
1196 5391d806 bellard
    case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
1197 caed8802 bellard
        if (bdrv_is_inserted(s->bs)) {
1198 caed8802 bellard
            bdrv_set_locked(s->bs, packet[4] & 1);
1199 5391d806 bellard
            ide_atapi_cmd_ok(s);
1200 5391d806 bellard
        } else {
1201 5391d806 bellard
            ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1202 5391d806 bellard
                                ASC_MEDIUM_NOT_PRESENT);
1203 5391d806 bellard
        }
1204 5391d806 bellard
        break;
1205 5391d806 bellard
    case GPCMD_READ_10:
1206 5391d806 bellard
    case GPCMD_READ_12:
1207 5391d806 bellard
        {
1208 5391d806 bellard
            int nb_sectors, lba;
1209 5391d806 bellard
1210 caed8802 bellard
            if (!bdrv_is_inserted(s->bs)) {
1211 5391d806 bellard
                ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1212 5391d806 bellard
                                    ASC_MEDIUM_NOT_PRESENT);
1213 5391d806 bellard
                break;
1214 5391d806 bellard
            }
1215 5391d806 bellard
            if (packet[0] == GPCMD_READ_10)
1216 5391d806 bellard
                nb_sectors = ube16_to_cpu(packet + 7);
1217 5391d806 bellard
            else
1218 5391d806 bellard
                nb_sectors = ube32_to_cpu(packet + 6);
1219 5391d806 bellard
            lba = ube32_to_cpu(packet + 2);
1220 5391d806 bellard
            if (nb_sectors == 0) {
1221 5391d806 bellard
                ide_atapi_cmd_ok(s);
1222 5391d806 bellard
                break;
1223 5391d806 bellard
            }
1224 5391d806 bellard
            if (((int64_t)(lba + nb_sectors) << 2) > s->nb_sectors) {
1225 5391d806 bellard
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1226 5391d806 bellard
                                    ASC_LOGICAL_BLOCK_OOR);
1227 5391d806 bellard
                break;
1228 5391d806 bellard
            }
1229 98087450 bellard
            ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
1230 98087450 bellard
        }
1231 98087450 bellard
        break;
1232 98087450 bellard
    case GPCMD_READ_CD:
1233 98087450 bellard
        {
1234 98087450 bellard
            int nb_sectors, lba, transfer_request;
1235 98087450 bellard
1236 98087450 bellard
            if (!bdrv_is_inserted(s->bs)) {
1237 98087450 bellard
                ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1238 98087450 bellard
                                    ASC_MEDIUM_NOT_PRESENT);
1239 98087450 bellard
                break;
1240 98087450 bellard
            }
1241 98087450 bellard
            nb_sectors = (packet[6] << 16) | (packet[7] << 8) | packet[8];
1242 98087450 bellard
            lba = ube32_to_cpu(packet + 2);
1243 98087450 bellard
            if (nb_sectors == 0) {
1244 98087450 bellard
                ide_atapi_cmd_ok(s);
1245 98087450 bellard
                break;
1246 98087450 bellard
            }
1247 98087450 bellard
            if (((int64_t)(lba + nb_sectors) << 2) > s->nb_sectors) {
1248 98087450 bellard
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1249 98087450 bellard
                                    ASC_LOGICAL_BLOCK_OOR);
1250 98087450 bellard
                break;
1251 98087450 bellard
            }
1252 98087450 bellard
            transfer_request = packet[9];
1253 98087450 bellard
            switch(transfer_request & 0xf8) {
1254 98087450 bellard
            case 0x00:
1255 98087450 bellard
                /* nothing */
1256 98087450 bellard
                ide_atapi_cmd_ok(s);
1257 98087450 bellard
                break;
1258 98087450 bellard
            case 0x10:
1259 98087450 bellard
                /* normal read */
1260 98087450 bellard
                ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
1261 98087450 bellard
                break;
1262 98087450 bellard
            case 0xf8:
1263 98087450 bellard
                /* read all data */
1264 98087450 bellard
                ide_atapi_cmd_read(s, lba, nb_sectors, 2352);
1265 98087450 bellard
                break;
1266 98087450 bellard
            default:
1267 98087450 bellard
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1268 98087450 bellard
                                    ASC_INV_FIELD_IN_CMD_PACKET);
1269 98087450 bellard
                break;
1270 98087450 bellard
            }
1271 5391d806 bellard
        }
1272 5391d806 bellard
        break;
1273 5391d806 bellard
    case GPCMD_SEEK:
1274 5391d806 bellard
        {
1275 5391d806 bellard
            int lba;
1276 caed8802 bellard
            if (!bdrv_is_inserted(s->bs)) {
1277 5391d806 bellard
                ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1278 5391d806 bellard
                                    ASC_MEDIUM_NOT_PRESENT);
1279 5391d806 bellard
                break;
1280 5391d806 bellard
            }
1281 5391d806 bellard
            lba = ube32_to_cpu(packet + 2);
1282 5391d806 bellard
            if (((int64_t)lba << 2) > s->nb_sectors) {
1283 5391d806 bellard
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1284 5391d806 bellard
                                    ASC_LOGICAL_BLOCK_OOR);
1285 5391d806 bellard
                break;
1286 5391d806 bellard
            }
1287 5391d806 bellard
            ide_atapi_cmd_ok(s);
1288 5391d806 bellard
        }
1289 5391d806 bellard
        break;
1290 5391d806 bellard
    case GPCMD_START_STOP_UNIT:
1291 5391d806 bellard
        {
1292 5391d806 bellard
            int start, eject;
1293 5391d806 bellard
            start = packet[4] & 1;
1294 5391d806 bellard
            eject = (packet[4] >> 1) & 1;
1295 5391d806 bellard
            
1296 caed8802 bellard
            if (eject && !start) {
1297 caed8802 bellard
                /* eject the disk */
1298 caed8802 bellard
                bdrv_close(s->bs);
1299 caed8802 bellard
            }
1300 5391d806 bellard
            ide_atapi_cmd_ok(s);
1301 5391d806 bellard
        }
1302 5391d806 bellard
        break;
1303 5391d806 bellard
    case GPCMD_MECHANISM_STATUS:
1304 5391d806 bellard
        {
1305 5391d806 bellard
            max_len = ube16_to_cpu(packet + 8);
1306 5391d806 bellard
            cpu_to_ube16(buf, 0);
1307 5391d806 bellard
            /* no current LBA */
1308 5391d806 bellard
            buf[2] = 0;
1309 5391d806 bellard
            buf[3] = 0;
1310 5391d806 bellard
            buf[4] = 0;
1311 5391d806 bellard
            buf[5] = 1;
1312 5391d806 bellard
            cpu_to_ube16(buf + 6, 0);
1313 5391d806 bellard
            ide_atapi_cmd_reply(s, 8, max_len);
1314 5391d806 bellard
        }
1315 5391d806 bellard
        break;
1316 5391d806 bellard
    case GPCMD_READ_TOC_PMA_ATIP:
1317 5391d806 bellard
        {
1318 5391d806 bellard
            int format, msf, start_track, len;
1319 5391d806 bellard
1320 caed8802 bellard
            if (!bdrv_is_inserted(s->bs)) {
1321 5391d806 bellard
                ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1322 5391d806 bellard
                                    ASC_MEDIUM_NOT_PRESENT);
1323 5391d806 bellard
                break;
1324 5391d806 bellard
            }
1325 5391d806 bellard
            max_len = ube16_to_cpu(packet + 7);
1326 5391d806 bellard
            format = packet[9] >> 6;
1327 5391d806 bellard
            msf = (packet[1] >> 1) & 1;
1328 5391d806 bellard
            start_track = packet[6];
1329 5391d806 bellard
            switch(format) {
1330 5391d806 bellard
            case 0:
1331 2e5d83bb pbrook
                len = cdrom_read_toc(s->nb_sectors >> 2, buf, msf, start_track);
1332 5391d806 bellard
                if (len < 0)
1333 5391d806 bellard
                    goto error_cmd;
1334 5391d806 bellard
                ide_atapi_cmd_reply(s, len, max_len);
1335 5391d806 bellard
                break;
1336 5391d806 bellard
            case 1:
1337 5391d806 bellard
                /* multi session : only a single session defined */
1338 5391d806 bellard
                memset(buf, 0, 12);
1339 5391d806 bellard
                buf[1] = 0x0a;
1340 5391d806 bellard
                buf[2] = 0x01;
1341 5391d806 bellard
                buf[3] = 0x01;
1342 5391d806 bellard
                ide_atapi_cmd_reply(s, 12, max_len);
1343 5391d806 bellard
                break;
1344 98087450 bellard
            case 2:
1345 2e5d83bb pbrook
                len = cdrom_read_toc_raw(s->nb_sectors >> 2, buf, msf, start_track);
1346 98087450 bellard
                if (len < 0)
1347 98087450 bellard
                    goto error_cmd;
1348 98087450 bellard
                ide_atapi_cmd_reply(s, len, max_len);
1349 98087450 bellard
                break;
1350 5391d806 bellard
            default:
1351 7f777bf3 bellard
            error_cmd:
1352 7f777bf3 bellard
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1353 7f777bf3 bellard
                                    ASC_INV_FIELD_IN_CMD_PACKET);
1354 7f777bf3 bellard
                break;
1355 5391d806 bellard
            }
1356 5391d806 bellard
        }
1357 5391d806 bellard
        break;
1358 5391d806 bellard
    case GPCMD_READ_CDVD_CAPACITY:
1359 caed8802 bellard
        if (!bdrv_is_inserted(s->bs)) {
1360 5391d806 bellard
            ide_atapi_cmd_error(s, SENSE_NOT_READY, 
1361 5391d806 bellard
                                ASC_MEDIUM_NOT_PRESENT);
1362 5391d806 bellard
            break;
1363 5391d806 bellard
        }
1364 5391d806 bellard
        /* NOTE: it is really the number of sectors minus 1 */
1365 5391d806 bellard
        cpu_to_ube32(buf, (s->nb_sectors >> 2) - 1);
1366 5391d806 bellard
        cpu_to_ube32(buf + 4, 2048);
1367 5391d806 bellard
        ide_atapi_cmd_reply(s, 8, 8);
1368 5391d806 bellard
        break;
1369 bd0d90b2 bellard
    case GPCMD_INQUIRY:
1370 bd0d90b2 bellard
        max_len = packet[4];
1371 bd0d90b2 bellard
        buf[0] = 0x05; /* CD-ROM */
1372 bd0d90b2 bellard
        buf[1] = 0x80; /* removable */
1373 bd0d90b2 bellard
        buf[2] = 0x00; /* ISO */
1374 bd0d90b2 bellard
        buf[3] = 0x21; /* ATAPI-2 (XXX: put ATAPI-4 ?) */
1375 bd0d90b2 bellard
        buf[4] = 31; /* additionnal length */
1376 bd0d90b2 bellard
        buf[5] = 0; /* reserved */
1377 bd0d90b2 bellard
        buf[6] = 0; /* reserved */
1378 bd0d90b2 bellard
        buf[7] = 0; /* reserved */
1379 bd0d90b2 bellard
        padstr8(buf + 8, 8, "QEMU");
1380 bd0d90b2 bellard
        padstr8(buf + 16, 16, "QEMU CD-ROM");
1381 bd0d90b2 bellard
        padstr8(buf + 32, 4, QEMU_VERSION);
1382 bd0d90b2 bellard
        ide_atapi_cmd_reply(s, 36, max_len);
1383 bd0d90b2 bellard
        break;
1384 5391d806 bellard
    default:
1385 5391d806 bellard
        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
1386 7f777bf3 bellard
                            ASC_ILLEGAL_OPCODE);
1387 5391d806 bellard
        break;
1388 5391d806 bellard
    }
1389 5391d806 bellard
}
1390 5391d806 bellard
1391 caed8802 bellard
/* called when the inserted state of the media has changed */
1392 caed8802 bellard
static void cdrom_change_cb(void *opaque)
1393 5391d806 bellard
{
1394 caed8802 bellard
    IDEState *s = opaque;
1395 caed8802 bellard
    int64_t nb_sectors;
1396 caed8802 bellard
1397 caed8802 bellard
    /* XXX: send interrupt too */
1398 caed8802 bellard
    bdrv_get_geometry(s->bs, &nb_sectors);
1399 caed8802 bellard
    s->nb_sectors = nb_sectors;
1400 caed8802 bellard
}
1401 caed8802 bellard
1402 c2ff060f bellard
static void ide_cmd_lba48_transform(IDEState *s, int lba48)
1403 c2ff060f bellard
{
1404 c2ff060f bellard
    s->lba48 = lba48;
1405 c2ff060f bellard
1406 c2ff060f bellard
    /* handle the 'magic' 0 nsector count conversion here. to avoid
1407 c2ff060f bellard
     * fiddling with the rest of the read logic, we just store the
1408 c2ff060f bellard
     * full sector count in ->nsector and ignore ->hob_nsector from now
1409 c2ff060f bellard
     */
1410 c2ff060f bellard
    if (!s->lba48) {
1411 c2ff060f bellard
        if (!s->nsector)
1412 c2ff060f bellard
            s->nsector = 256;
1413 c2ff060f bellard
    } else {
1414 c2ff060f bellard
        if (!s->nsector && !s->hob_nsector)
1415 c2ff060f bellard
            s->nsector = 65536;
1416 c2ff060f bellard
        else {
1417 c2ff060f bellard
            int lo = s->nsector;
1418 c2ff060f bellard
            int hi = s->hob_nsector;
1419 c2ff060f bellard
1420 c2ff060f bellard
            s->nsector = (hi << 8) | lo;
1421 c2ff060f bellard
        }
1422 c2ff060f bellard
    }
1423 c2ff060f bellard
}
1424 c2ff060f bellard
1425 c2ff060f bellard
static void ide_clear_hob(IDEState *ide_if)
1426 c2ff060f bellard
{
1427 c2ff060f bellard
    /* any write clears HOB high bit of device control register */
1428 c2ff060f bellard
    ide_if[0].select &= ~(1 << 7);
1429 c2ff060f bellard
    ide_if[1].select &= ~(1 << 7);
1430 c2ff060f bellard
}
1431 c2ff060f bellard
1432 caed8802 bellard
static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
1433 caed8802 bellard
{
1434 caed8802 bellard
    IDEState *ide_if = opaque;
1435 c45c3d00 bellard
    IDEState *s;
1436 5391d806 bellard
    int unit, n;
1437 c2ff060f bellard
    int lba48 = 0;
1438 5391d806 bellard
1439 5391d806 bellard
#ifdef DEBUG_IDE
1440 5391d806 bellard
    printf("IDE: write addr=0x%x val=0x%02x\n", addr, val);
1441 5391d806 bellard
#endif
1442 c2ff060f bellard
1443 5391d806 bellard
    addr &= 7;
1444 5391d806 bellard
    switch(addr) {
1445 5391d806 bellard
    case 0:
1446 5391d806 bellard
        break;
1447 5391d806 bellard
    case 1:
1448 c2ff060f bellard
        ide_clear_hob(ide_if);
1449 c45c3d00 bellard
        /* NOTE: data is written to the two drives */
1450 c2ff060f bellard
        ide_if[0].hob_feature = ide_if[0].feature;
1451 c2ff060f bellard
        ide_if[1].hob_feature = ide_if[1].feature;
1452 c45c3d00 bellard
        ide_if[0].feature = val;
1453 c45c3d00 bellard
        ide_if[1].feature = val;
1454 5391d806 bellard
        break;
1455 5391d806 bellard
    case 2:
1456 c2ff060f bellard
        ide_clear_hob(ide_if);
1457 c2ff060f bellard
        ide_if[0].hob_nsector = ide_if[0].nsector;
1458 c2ff060f bellard
        ide_if[1].hob_nsector = ide_if[1].nsector;
1459 c45c3d00 bellard
        ide_if[0].nsector = val;
1460 c45c3d00 bellard
        ide_if[1].nsector = val;
1461 5391d806 bellard
        break;
1462 5391d806 bellard
    case 3:
1463 c2ff060f bellard
        ide_clear_hob(ide_if);
1464 c2ff060f bellard
        ide_if[0].hob_sector = ide_if[0].sector;
1465 c2ff060f bellard
        ide_if[1].hob_sector = ide_if[1].sector;
1466 c45c3d00 bellard
        ide_if[0].sector = val;
1467 c45c3d00 bellard
        ide_if[1].sector = val;
1468 5391d806 bellard
        break;
1469 5391d806 bellard
    case 4:
1470 c2ff060f bellard
        ide_clear_hob(ide_if);
1471 c2ff060f bellard
        ide_if[0].hob_lcyl = ide_if[0].lcyl;
1472 c2ff060f bellard
        ide_if[1].hob_lcyl = ide_if[1].lcyl;
1473 c45c3d00 bellard
        ide_if[0].lcyl = val;
1474 c45c3d00 bellard
        ide_if[1].lcyl = val;
1475 5391d806 bellard
        break;
1476 5391d806 bellard
    case 5:
1477 c2ff060f bellard
        ide_clear_hob(ide_if);
1478 c2ff060f bellard
        ide_if[0].hob_hcyl = ide_if[0].hcyl;
1479 c2ff060f bellard
        ide_if[1].hob_hcyl = ide_if[1].hcyl;
1480 c45c3d00 bellard
        ide_if[0].hcyl = val;
1481 c45c3d00 bellard
        ide_if[1].hcyl = val;
1482 5391d806 bellard
        break;
1483 5391d806 bellard
    case 6:
1484 c2ff060f bellard
        /* FIXME: HOB readback uses bit 7 */
1485 7ae98627 bellard
        ide_if[0].select = (val & ~0x10) | 0xa0;
1486 7ae98627 bellard
        ide_if[1].select = (val | 0x10) | 0xa0;
1487 5391d806 bellard
        /* select drive */
1488 5391d806 bellard
        unit = (val >> 4) & 1;
1489 5391d806 bellard
        s = ide_if + unit;
1490 5391d806 bellard
        ide_if->cur_drive = s;
1491 5391d806 bellard
        break;
1492 5391d806 bellard
    default:
1493 5391d806 bellard
    case 7:
1494 5391d806 bellard
        /* command */
1495 5391d806 bellard
#if defined(DEBUG_IDE)
1496 5391d806 bellard
        printf("ide: CMD=%02x\n", val);
1497 5391d806 bellard
#endif
1498 c45c3d00 bellard
        s = ide_if->cur_drive;
1499 66201e2d bellard
        /* ignore commands to non existant slave */
1500 66201e2d bellard
        if (s != ide_if && !s->bs) 
1501 66201e2d bellard
            break;
1502 c2ff060f bellard
1503 5391d806 bellard
        switch(val) {
1504 5391d806 bellard
        case WIN_IDENTIFY:
1505 5391d806 bellard
            if (s->bs && !s->is_cdrom) {
1506 5391d806 bellard
                ide_identify(s);
1507 2a282056 bellard
                s->status = READY_STAT | SEEK_STAT;
1508 5391d806 bellard
                ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
1509 5391d806 bellard
            } else {
1510 5391d806 bellard
                if (s->is_cdrom) {
1511 5391d806 bellard
                    ide_set_signature(s);
1512 5391d806 bellard
                }
1513 5391d806 bellard
                ide_abort_command(s);
1514 5391d806 bellard
            }
1515 5391d806 bellard
            ide_set_irq(s);
1516 5391d806 bellard
            break;
1517 5391d806 bellard
        case WIN_SPECIFY:
1518 5391d806 bellard
        case WIN_RECAL:
1519 a136e5a8 bellard
            s->error = 0;
1520 769bec72 bellard
            s->status = READY_STAT | SEEK_STAT;
1521 5391d806 bellard
            ide_set_irq(s);
1522 5391d806 bellard
            break;
1523 5391d806 bellard
        case WIN_SETMULT:
1524 5391d806 bellard
            if (s->nsector > MAX_MULT_SECTORS || 
1525 5391d806 bellard
                s->nsector == 0 ||
1526 5391d806 bellard
                (s->nsector & (s->nsector - 1)) != 0) {
1527 5391d806 bellard
                ide_abort_command(s);
1528 5391d806 bellard
            } else {
1529 5391d806 bellard
                s->mult_sectors = s->nsector;
1530 5391d806 bellard
                s->status = READY_STAT;
1531 5391d806 bellard
            }
1532 5391d806 bellard
            ide_set_irq(s);
1533 5391d806 bellard
            break;
1534 c2ff060f bellard
        case WIN_VERIFY_EXT:
1535 c2ff060f bellard
            lba48 = 1;
1536 4ce900b4 bellard
        case WIN_VERIFY:
1537 4ce900b4 bellard
        case WIN_VERIFY_ONCE:
1538 4ce900b4 bellard
            /* do sector number check ? */
1539 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1540 4ce900b4 bellard
            s->status = READY_STAT;
1541 4ce900b4 bellard
            ide_set_irq(s);
1542 4ce900b4 bellard
            break;
1543 c2ff060f bellard
        case WIN_READ_EXT:
1544 c2ff060f bellard
            lba48 = 1;
1545 5391d806 bellard
        case WIN_READ:
1546 5391d806 bellard
        case WIN_READ_ONCE:
1547 6b136f9e bellard
            if (!s->bs) 
1548 6b136f9e bellard
                goto abort_cmd;
1549 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1550 5391d806 bellard
            s->req_nb_sectors = 1;
1551 5391d806 bellard
            ide_sector_read(s);
1552 5391d806 bellard
            break;
1553 c2ff060f bellard
        case WIN_WRITE_EXT:
1554 c2ff060f bellard
            lba48 = 1;
1555 5391d806 bellard
        case WIN_WRITE:
1556 5391d806 bellard
        case WIN_WRITE_ONCE:
1557 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1558 a136e5a8 bellard
            s->error = 0;
1559 f66723fa bellard
            s->status = SEEK_STAT | READY_STAT;
1560 5391d806 bellard
            s->req_nb_sectors = 1;
1561 5391d806 bellard
            ide_transfer_start(s, s->io_buffer, 512, ide_sector_write);
1562 5391d806 bellard
            break;
1563 c2ff060f bellard
        case WIN_MULTREAD_EXT:
1564 c2ff060f bellard
            lba48 = 1;
1565 5391d806 bellard
        case WIN_MULTREAD:
1566 5391d806 bellard
            if (!s->mult_sectors)
1567 5391d806 bellard
                goto abort_cmd;
1568 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1569 5391d806 bellard
            s->req_nb_sectors = s->mult_sectors;
1570 5391d806 bellard
            ide_sector_read(s);
1571 5391d806 bellard
            break;
1572 c2ff060f bellard
        case WIN_MULTWRITE_EXT:
1573 c2ff060f bellard
            lba48 = 1;
1574 5391d806 bellard
        case WIN_MULTWRITE:
1575 5391d806 bellard
            if (!s->mult_sectors)
1576 5391d806 bellard
                goto abort_cmd;
1577 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1578 a136e5a8 bellard
            s->error = 0;
1579 f66723fa bellard
            s->status = SEEK_STAT | READY_STAT;
1580 5391d806 bellard
            s->req_nb_sectors = s->mult_sectors;
1581 5391d806 bellard
            n = s->nsector;
1582 5391d806 bellard
            if (n > s->req_nb_sectors)
1583 5391d806 bellard
                n = s->req_nb_sectors;
1584 5391d806 bellard
            ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
1585 5391d806 bellard
            break;
1586 c2ff060f bellard
        case WIN_READDMA_EXT:
1587 c2ff060f bellard
            lba48 = 1;
1588 98087450 bellard
        case WIN_READDMA:
1589 98087450 bellard
        case WIN_READDMA_ONCE:
1590 98087450 bellard
            if (!s->bs) 
1591 98087450 bellard
                goto abort_cmd;
1592 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1593 98087450 bellard
            ide_sector_read_dma(s);
1594 98087450 bellard
            break;
1595 c2ff060f bellard
        case WIN_WRITEDMA_EXT:
1596 c2ff060f bellard
            lba48 = 1;
1597 98087450 bellard
        case WIN_WRITEDMA:
1598 98087450 bellard
        case WIN_WRITEDMA_ONCE:
1599 98087450 bellard
            if (!s->bs) 
1600 98087450 bellard
                goto abort_cmd;
1601 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1602 98087450 bellard
            ide_sector_write_dma(s);
1603 98087450 bellard
            break;
1604 c2ff060f bellard
        case WIN_READ_NATIVE_MAX_EXT:
1605 c2ff060f bellard
            lba48 = 1;
1606 5391d806 bellard
        case WIN_READ_NATIVE_MAX:
1607 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
1608 5391d806 bellard
            ide_set_sector(s, s->nb_sectors - 1);
1609 5391d806 bellard
            s->status = READY_STAT;
1610 5391d806 bellard
            ide_set_irq(s);
1611 5391d806 bellard
            break;
1612 a136e5a8 bellard
        case WIN_CHECKPOWERMODE1:
1613 a136e5a8 bellard
            s->nsector = 0xff; /* device active or idle */
1614 a136e5a8 bellard
            s->status = READY_STAT;
1615 a136e5a8 bellard
            ide_set_irq(s);
1616 a136e5a8 bellard
            break;
1617 34e538ae bellard
        case WIN_SETFEATURES:
1618 34e538ae bellard
            if (!s->bs)
1619 34e538ae bellard
                goto abort_cmd;
1620 34e538ae bellard
            /* XXX: valid for CDROM ? */
1621 34e538ae bellard
            switch(s->feature) {
1622 34e538ae bellard
            case 0x02: /* write cache enable */
1623 34e538ae bellard
            case 0x82: /* write cache disable */
1624 34e538ae bellard
            case 0xaa: /* read look-ahead enable */
1625 34e538ae bellard
            case 0x55: /* read look-ahead disable */
1626 e0fe67aa bellard
                s->status = READY_STAT | SEEK_STAT;
1627 34e538ae bellard
                ide_set_irq(s);
1628 34e538ae bellard
                break;
1629 94458802 bellard
            case 0x03: { /* set transfer mode */
1630 94458802 bellard
                uint8_t val = s->nsector & 0x07;
1631 94458802 bellard
1632 94458802 bellard
                switch (s->nsector >> 3) {
1633 94458802 bellard
                    case 0x00: /* pio default */
1634 94458802 bellard
                    case 0x01: /* pio mode */
1635 94458802 bellard
                        put_le16(s->identify_data + 63,0x07);
1636 94458802 bellard
                        put_le16(s->identify_data + 88,0x3f);
1637 94458802 bellard
                        break;
1638 94458802 bellard
                    case 0x04: /* mdma mode */
1639 94458802 bellard
                        put_le16(s->identify_data + 63,0x07 | (1 << (val + 8)));
1640 94458802 bellard
                        put_le16(s->identify_data + 88,0x3f);
1641 94458802 bellard
                        break;
1642 94458802 bellard
                    case 0x08: /* udma mode */
1643 94458802 bellard
                        put_le16(s->identify_data + 63,0x07);
1644 94458802 bellard
                        put_le16(s->identify_data + 88,0x3f | (1 << (val + 8)));
1645 94458802 bellard
                        break;
1646 94458802 bellard
                    default:
1647 94458802 bellard
                        goto abort_cmd;
1648 94458802 bellard
                }
1649 94458802 bellard
                s->status = READY_STAT | SEEK_STAT;
1650 94458802 bellard
                ide_set_irq(s);
1651 94458802 bellard
                break;
1652 94458802 bellard
            }
1653 34e538ae bellard
            default:
1654 34e538ae bellard
                goto abort_cmd;
1655 34e538ae bellard
            }
1656 34e538ae bellard
            break;
1657 c2ff060f bellard
        case WIN_FLUSH_CACHE:
1658 c2ff060f bellard
        case WIN_FLUSH_CACHE_EXT:
1659 7a6cba61 pbrook
            if (s->bs)
1660 7a6cba61 pbrook
                bdrv_flush(s->bs);
1661 7a6cba61 pbrook
            s->status = READY_STAT;
1662 7a6cba61 pbrook
            ide_set_irq(s);
1663 7a6cba61 pbrook
            break;
1664 a7dfe172 bellard
        case WIN_STANDBYNOW1:
1665 c451ee71 bellard
        case WIN_IDLEIMMEDIATE:
1666 a7dfe172 bellard
            s->status = READY_STAT;
1667 a7dfe172 bellard
            ide_set_irq(s);
1668 a7dfe172 bellard
            break;
1669 5391d806 bellard
            /* ATAPI commands */
1670 5391d806 bellard
        case WIN_PIDENTIFY:
1671 5391d806 bellard
            if (s->is_cdrom) {
1672 5391d806 bellard
                ide_atapi_identify(s);
1673 1298fe63 bellard
                s->status = READY_STAT | SEEK_STAT;
1674 5391d806 bellard
                ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
1675 5391d806 bellard
            } else {
1676 5391d806 bellard
                ide_abort_command(s);
1677 5391d806 bellard
            }
1678 5391d806 bellard
            ide_set_irq(s);
1679 5391d806 bellard
            break;
1680 c451ee71 bellard
        case WIN_DIAGNOSE:
1681 c451ee71 bellard
            ide_set_signature(s);
1682 c451ee71 bellard
            s->status = 0x00; /* NOTE: READY is _not_ set */
1683 c451ee71 bellard
            s->error = 0x01;
1684 c451ee71 bellard
            break;
1685 5391d806 bellard
        case WIN_SRST:
1686 5391d806 bellard
            if (!s->is_cdrom)
1687 5391d806 bellard
                goto abort_cmd;
1688 5391d806 bellard
            ide_set_signature(s);
1689 6b136f9e bellard
            s->status = 0x00; /* NOTE: READY is _not_ set */
1690 5391d806 bellard
            s->error = 0x01;
1691 5391d806 bellard
            break;
1692 5391d806 bellard
        case WIN_PACKETCMD:
1693 5391d806 bellard
            if (!s->is_cdrom)
1694 5391d806 bellard
                goto abort_cmd;
1695 98087450 bellard
            /* overlapping commands not supported */
1696 98087450 bellard
            if (s->feature & 0x02)
1697 5391d806 bellard
                goto abort_cmd;
1698 98087450 bellard
            s->atapi_dma = s->feature & 1;
1699 5391d806 bellard
            s->nsector = 1;
1700 5391d806 bellard
            ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE, 
1701 5391d806 bellard
                               ide_atapi_cmd);
1702 5391d806 bellard
            break;
1703 5391d806 bellard
        default:
1704 5391d806 bellard
        abort_cmd:
1705 5391d806 bellard
            ide_abort_command(s);
1706 5391d806 bellard
            ide_set_irq(s);
1707 5391d806 bellard
            break;
1708 5391d806 bellard
        }
1709 5391d806 bellard
    }
1710 5391d806 bellard
}
1711 5391d806 bellard
1712 caed8802 bellard
static uint32_t ide_ioport_read(void *opaque, uint32_t addr1)
1713 5391d806 bellard
{
1714 7ae98627 bellard
    IDEState *ide_if = opaque;
1715 7ae98627 bellard
    IDEState *s = ide_if->cur_drive;
1716 5391d806 bellard
    uint32_t addr;
1717 c2ff060f bellard
    int ret, hob;
1718 5391d806 bellard
1719 5391d806 bellard
    addr = addr1 & 7;
1720 c2ff060f bellard
    /* FIXME: HOB readback uses bit 7, but it's always set right now */
1721 c2ff060f bellard
    //hob = s->select & (1 << 7);
1722 c2ff060f bellard
    hob = 0;
1723 5391d806 bellard
    switch(addr) {
1724 5391d806 bellard
    case 0:
1725 5391d806 bellard
        ret = 0xff;
1726 5391d806 bellard
        break;
1727 5391d806 bellard
    case 1:
1728 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
1729 c45c3d00 bellard
            ret = 0;
1730 c2ff060f bellard
        else if (!hob)
1731 c45c3d00 bellard
            ret = s->error;
1732 c2ff060f bellard
        else
1733 c2ff060f bellard
            ret = s->hob_feature;
1734 5391d806 bellard
        break;
1735 5391d806 bellard
    case 2:
1736 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
1737 c45c3d00 bellard
            ret = 0;
1738 c2ff060f bellard
        else if (!hob)
1739 c45c3d00 bellard
            ret = s->nsector & 0xff;
1740 c2ff060f bellard
        else
1741 c2ff060f bellard
            ret = s->hob_nsector;
1742 5391d806 bellard
        break;
1743 5391d806 bellard
    case 3:
1744 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
1745 c45c3d00 bellard
            ret = 0;
1746 c2ff060f bellard
        else if (!hob)
1747 c45c3d00 bellard
            ret = s->sector;
1748 c2ff060f bellard
        else
1749 c2ff060f bellard
            ret = s->hob_sector;
1750 5391d806 bellard
        break;
1751 5391d806 bellard
    case 4:
1752 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
1753 c45c3d00 bellard
            ret = 0;
1754 c2ff060f bellard
        else if (!hob)
1755 c45c3d00 bellard
            ret = s->lcyl;
1756 c2ff060f bellard
        else
1757 c2ff060f bellard
            ret = s->hob_lcyl;
1758 5391d806 bellard
        break;
1759 5391d806 bellard
    case 5:
1760 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
1761 c45c3d00 bellard
            ret = 0;
1762 c2ff060f bellard
        else if (!hob)
1763 c45c3d00 bellard
            ret = s->hcyl;
1764 c2ff060f bellard
        else
1765 c2ff060f bellard
            ret = s->hob_hcyl;
1766 5391d806 bellard
        break;
1767 5391d806 bellard
    case 6:
1768 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
1769 c45c3d00 bellard
            ret = 0;
1770 c45c3d00 bellard
        else
1771 7ae98627 bellard
            ret = s->select;
1772 5391d806 bellard
        break;
1773 5391d806 bellard
    default:
1774 5391d806 bellard
    case 7:
1775 66201e2d bellard
        if ((!ide_if[0].bs && !ide_if[1].bs) ||
1776 66201e2d bellard
            (s != ide_if && !s->bs))
1777 c45c3d00 bellard
            ret = 0;
1778 c45c3d00 bellard
        else
1779 c45c3d00 bellard
            ret = s->status;
1780 5457c8ce bellard
        s->set_irq(s->irq_opaque, s->irq, 0);
1781 5391d806 bellard
        break;
1782 5391d806 bellard
    }
1783 5391d806 bellard
#ifdef DEBUG_IDE
1784 5391d806 bellard
    printf("ide: read addr=0x%x val=%02x\n", addr1, ret);
1785 5391d806 bellard
#endif
1786 5391d806 bellard
    return ret;
1787 5391d806 bellard
}
1788 5391d806 bellard
1789 caed8802 bellard
static uint32_t ide_status_read(void *opaque, uint32_t addr)
1790 5391d806 bellard
{
1791 7ae98627 bellard
    IDEState *ide_if = opaque;
1792 7ae98627 bellard
    IDEState *s = ide_if->cur_drive;
1793 5391d806 bellard
    int ret;
1794 7ae98627 bellard
1795 66201e2d bellard
    if ((!ide_if[0].bs && !ide_if[1].bs) ||
1796 66201e2d bellard
        (s != ide_if && !s->bs))
1797 7ae98627 bellard
        ret = 0;
1798 7ae98627 bellard
    else
1799 7ae98627 bellard
        ret = s->status;
1800 5391d806 bellard
#ifdef DEBUG_IDE
1801 5391d806 bellard
    printf("ide: read status addr=0x%x val=%02x\n", addr, ret);
1802 5391d806 bellard
#endif
1803 5391d806 bellard
    return ret;
1804 5391d806 bellard
}
1805 5391d806 bellard
1806 caed8802 bellard
static void ide_cmd_write(void *opaque, uint32_t addr, uint32_t val)
1807 5391d806 bellard
{
1808 caed8802 bellard
    IDEState *ide_if = opaque;
1809 5391d806 bellard
    IDEState *s;
1810 5391d806 bellard
    int i;
1811 5391d806 bellard
1812 5391d806 bellard
#ifdef DEBUG_IDE
1813 5391d806 bellard
    printf("ide: write control addr=0x%x val=%02x\n", addr, val);
1814 5391d806 bellard
#endif
1815 5391d806 bellard
    /* common for both drives */
1816 5391d806 bellard
    if (!(ide_if[0].cmd & IDE_CMD_RESET) &&
1817 5391d806 bellard
        (val & IDE_CMD_RESET)) {
1818 5391d806 bellard
        /* reset low to high */
1819 5391d806 bellard
        for(i = 0;i < 2; i++) {
1820 5391d806 bellard
            s = &ide_if[i];
1821 5391d806 bellard
            s->status = BUSY_STAT | SEEK_STAT;
1822 5391d806 bellard
            s->error = 0x01;
1823 5391d806 bellard
        }
1824 5391d806 bellard
    } else if ((ide_if[0].cmd & IDE_CMD_RESET) &&
1825 5391d806 bellard
               !(val & IDE_CMD_RESET)) {
1826 5391d806 bellard
        /* high to low */
1827 5391d806 bellard
        for(i = 0;i < 2; i++) {
1828 5391d806 bellard
            s = &ide_if[i];
1829 6b136f9e bellard
            if (s->is_cdrom)
1830 6b136f9e bellard
                s->status = 0x00; /* NOTE: READY is _not_ set */
1831 6b136f9e bellard
            else
1832 56bf1d37 bellard
                s->status = READY_STAT | SEEK_STAT;
1833 5391d806 bellard
            ide_set_signature(s);
1834 5391d806 bellard
        }
1835 5391d806 bellard
    }
1836 5391d806 bellard
1837 5391d806 bellard
    ide_if[0].cmd = val;
1838 5391d806 bellard
    ide_if[1].cmd = val;
1839 5391d806 bellard
}
1840 5391d806 bellard
1841 caed8802 bellard
static void ide_data_writew(void *opaque, uint32_t addr, uint32_t val)
1842 5391d806 bellard
{
1843 caed8802 bellard
    IDEState *s = ((IDEState *)opaque)->cur_drive;
1844 5391d806 bellard
    uint8_t *p;
1845 5391d806 bellard
1846 5391d806 bellard
    p = s->data_ptr;
1847 0c4ad8dc bellard
    *(uint16_t *)p = le16_to_cpu(val);
1848 5391d806 bellard
    p += 2;
1849 5391d806 bellard
    s->data_ptr = p;
1850 5391d806 bellard
    if (p >= s->data_end)
1851 5391d806 bellard
        s->end_transfer_func(s);
1852 5391d806 bellard
}
1853 5391d806 bellard
1854 caed8802 bellard
static uint32_t ide_data_readw(void *opaque, uint32_t addr)
1855 5391d806 bellard
{
1856 caed8802 bellard
    IDEState *s = ((IDEState *)opaque)->cur_drive;
1857 5391d806 bellard
    uint8_t *p;
1858 5391d806 bellard
    int ret;
1859 5391d806 bellard
    p = s->data_ptr;
1860 0c4ad8dc bellard
    ret = cpu_to_le16(*(uint16_t *)p);
1861 5391d806 bellard
    p += 2;
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
    return ret;
1866 5391d806 bellard
}
1867 5391d806 bellard
1868 caed8802 bellard
static void ide_data_writel(void *opaque, uint32_t addr, uint32_t val)
1869 5391d806 bellard
{
1870 caed8802 bellard
    IDEState *s = ((IDEState *)opaque)->cur_drive;
1871 5391d806 bellard
    uint8_t *p;
1872 5391d806 bellard
1873 5391d806 bellard
    p = s->data_ptr;
1874 0c4ad8dc bellard
    *(uint32_t *)p = le32_to_cpu(val);
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
}
1880 5391d806 bellard
1881 caed8802 bellard
static uint32_t ide_data_readl(void *opaque, uint32_t addr)
1882 5391d806 bellard
{
1883 caed8802 bellard
    IDEState *s = ((IDEState *)opaque)->cur_drive;
1884 5391d806 bellard
    uint8_t *p;
1885 5391d806 bellard
    int ret;
1886 5391d806 bellard
    
1887 5391d806 bellard
    p = s->data_ptr;
1888 0c4ad8dc bellard
    ret = cpu_to_le32(*(uint32_t *)p);
1889 5391d806 bellard
    p += 4;
1890 5391d806 bellard
    s->data_ptr = p;
1891 5391d806 bellard
    if (p >= s->data_end)
1892 5391d806 bellard
        s->end_transfer_func(s);
1893 5391d806 bellard
    return ret;
1894 5391d806 bellard
}
1895 5391d806 bellard
1896 a7dfe172 bellard
static void ide_dummy_transfer_stop(IDEState *s)
1897 a7dfe172 bellard
{
1898 a7dfe172 bellard
    s->data_ptr = s->io_buffer;
1899 a7dfe172 bellard
    s->data_end = s->io_buffer;
1900 a7dfe172 bellard
    s->io_buffer[0] = 0xff;
1901 a7dfe172 bellard
    s->io_buffer[1] = 0xff;
1902 a7dfe172 bellard
    s->io_buffer[2] = 0xff;
1903 a7dfe172 bellard
    s->io_buffer[3] = 0xff;
1904 a7dfe172 bellard
}
1905 a7dfe172 bellard
1906 5391d806 bellard
static void ide_reset(IDEState *s)
1907 5391d806 bellard
{
1908 5391d806 bellard
    s->mult_sectors = MAX_MULT_SECTORS;
1909 5391d806 bellard
    s->cur_drive = s;
1910 5391d806 bellard
    s->select = 0xa0;
1911 5391d806 bellard
    s->status = READY_STAT;
1912 5391d806 bellard
    ide_set_signature(s);
1913 a7dfe172 bellard
    /* init the transfer handler so that 0xffff is returned on data
1914 a7dfe172 bellard
       accesses */
1915 a7dfe172 bellard
    s->end_transfer_func = ide_dummy_transfer_stop;
1916 a7dfe172 bellard
    ide_dummy_transfer_stop(s);
1917 5391d806 bellard
}
1918 5391d806 bellard
1919 5391d806 bellard
struct partition {
1920 5391d806 bellard
        uint8_t boot_ind;                /* 0x80 - active */
1921 5391d806 bellard
        uint8_t head;                /* starting head */
1922 5391d806 bellard
        uint8_t sector;                /* starting sector */
1923 5391d806 bellard
        uint8_t cyl;                /* starting cylinder */
1924 5391d806 bellard
        uint8_t sys_ind;                /* What partition type */
1925 5391d806 bellard
        uint8_t end_head;                /* end head */
1926 5391d806 bellard
        uint8_t end_sector;        /* end sector */
1927 5391d806 bellard
        uint8_t end_cyl;                /* end cylinder */
1928 5391d806 bellard
        uint32_t start_sect;        /* starting sector counting from 0 */
1929 5391d806 bellard
        uint32_t nr_sects;                /* nr of sectors in partition */
1930 5391d806 bellard
} __attribute__((packed));
1931 5391d806 bellard
1932 bf1b938f bellard
/* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */
1933 bf1b938f bellard
static int guess_disk_lchs(IDEState *s, 
1934 bf1b938f bellard
                           int *pcylinders, int *pheads, int *psectors)
1935 5391d806 bellard
{
1936 5391d806 bellard
    uint8_t buf[512];
1937 46d4767d bellard
    int ret, i, heads, sectors, cylinders;
1938 5391d806 bellard
    struct partition *p;
1939 5391d806 bellard
    uint32_t nr_sects;
1940 5391d806 bellard
1941 5391d806 bellard
    ret = bdrv_read(s->bs, 0, buf, 1);
1942 5391d806 bellard
    if (ret < 0)
1943 bf1b938f bellard
        return -1;
1944 5391d806 bellard
    /* test msdos magic */
1945 5391d806 bellard
    if (buf[510] != 0x55 || buf[511] != 0xaa)
1946 bf1b938f bellard
        return -1;
1947 5391d806 bellard
    for(i = 0; i < 4; i++) {
1948 5391d806 bellard
        p = ((struct partition *)(buf + 0x1be)) + i;
1949 0c4ad8dc bellard
        nr_sects = le32_to_cpu(p->nr_sects);
1950 5391d806 bellard
        if (nr_sects && p->end_head) {
1951 5391d806 bellard
            /* We make the assumption that the partition terminates on
1952 5391d806 bellard
               a cylinder boundary */
1953 46d4767d bellard
            heads = p->end_head + 1;
1954 46d4767d bellard
            sectors = p->end_sector & 63;
1955 46d4767d bellard
            if (sectors == 0)
1956 46d4767d bellard
                continue;
1957 46d4767d bellard
            cylinders = s->nb_sectors / (heads * sectors);
1958 46d4767d bellard
            if (cylinders < 1 || cylinders > 16383)
1959 46d4767d bellard
                continue;
1960 bf1b938f bellard
            *pheads = heads;
1961 bf1b938f bellard
            *psectors = sectors;
1962 bf1b938f bellard
            *pcylinders = cylinders;
1963 5391d806 bellard
#if 0
1964 bf1b938f bellard
            printf("guessed geometry: LCHS=%d %d %d\n", 
1965 bf1b938f bellard
                   cylinders, heads, sectors);
1966 5391d806 bellard
#endif
1967 bf1b938f bellard
            return 0;
1968 5391d806 bellard
        }
1969 5391d806 bellard
    }
1970 bf1b938f bellard
    return -1;
1971 5391d806 bellard
}
1972 5391d806 bellard
1973 5457c8ce bellard
static void ide_init2(IDEState *ide_state,
1974 5457c8ce bellard
                      BlockDriverState *hd0, BlockDriverState *hd1,
1975 5457c8ce bellard
                      SetIRQFunc *set_irq, void *irq_opaque, int irq)
1976 5391d806 bellard
{
1977 69b91039 bellard
    IDEState *s;
1978 aedf5382 bellard
    static int drive_serial = 1;
1979 bf1b938f bellard
    int i, cylinders, heads, secs, translation;
1980 5391d806 bellard
    int64_t nb_sectors;
1981 5391d806 bellard
1982 caed8802 bellard
    for(i = 0; i < 2; i++) {
1983 caed8802 bellard
        s = ide_state + i;
1984 caed8802 bellard
        if (i == 0)
1985 caed8802 bellard
            s->bs = hd0;
1986 caed8802 bellard
        else
1987 caed8802 bellard
            s->bs = hd1;
1988 5391d806 bellard
        if (s->bs) {
1989 5391d806 bellard
            bdrv_get_geometry(s->bs, &nb_sectors);
1990 5391d806 bellard
            s->nb_sectors = nb_sectors;
1991 caed8802 bellard
            /* if a geometry hint is available, use it */
1992 caed8802 bellard
            bdrv_get_geometry_hint(s->bs, &cylinders, &heads, &secs);
1993 caed8802 bellard
            if (cylinders != 0) {
1994 5391d806 bellard
                s->cylinders = cylinders;
1995 caed8802 bellard
                s->heads = heads;
1996 caed8802 bellard
                s->sectors = secs;
1997 caed8802 bellard
            } else {
1998 bf1b938f bellard
                if (guess_disk_lchs(s, &cylinders, &heads, &secs) == 0) {
1999 bf1b938f bellard
                    if (heads > 16) {
2000 bf1b938f bellard
                        /* if heads > 16, it means that a BIOS LBA
2001 bf1b938f bellard
                           translation was active, so the default
2002 bf1b938f bellard
                           hardware geometry is OK */
2003 bf1b938f bellard
                        goto default_geometry;
2004 bf1b938f bellard
                    } else {
2005 bf1b938f bellard
                        s->cylinders = cylinders;
2006 bf1b938f bellard
                        s->heads = heads;
2007 bf1b938f bellard
                        s->sectors = secs;
2008 bf1b938f bellard
                        /* disable any translation to be in sync with
2009 bf1b938f bellard
                           the logical geometry */
2010 bf1b938f bellard
                        translation = bdrv_get_translation_hint(s->bs);
2011 bf1b938f bellard
                        if (translation == BIOS_ATA_TRANSLATION_AUTO) {
2012 bf1b938f bellard
                            bdrv_set_translation_hint(s->bs,
2013 bf1b938f bellard
                                                      BIOS_ATA_TRANSLATION_NONE);
2014 bf1b938f bellard
                        }
2015 bf1b938f bellard
                    }
2016 bf1b938f bellard
                } else {
2017 bf1b938f bellard
                default_geometry:
2018 46d4767d bellard
                    /* if no geometry, use a standard physical disk geometry */
2019 caed8802 bellard
                    cylinders = nb_sectors / (16 * 63);
2020 caed8802 bellard
                    if (cylinders > 16383)
2021 caed8802 bellard
                        cylinders = 16383;
2022 caed8802 bellard
                    else if (cylinders < 2)
2023 caed8802 bellard
                        cylinders = 2;
2024 caed8802 bellard
                    s->cylinders = cylinders;
2025 caed8802 bellard
                    s->heads = 16;
2026 caed8802 bellard
                    s->sectors = 63;
2027 caed8802 bellard
                }
2028 769bec72 bellard
                bdrv_set_geometry_hint(s->bs, s->cylinders, s->heads, s->sectors);
2029 caed8802 bellard
            }
2030 caed8802 bellard
            if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) {
2031 caed8802 bellard
                s->is_cdrom = 1;
2032 caed8802 bellard
                bdrv_set_change_cb(s->bs, cdrom_change_cb, s);
2033 5391d806 bellard
            }
2034 5391d806 bellard
        }
2035 aedf5382 bellard
        s->drive_serial = drive_serial++;
2036 5457c8ce bellard
        s->set_irq = set_irq;
2037 5457c8ce bellard
        s->irq_opaque = irq_opaque;
2038 caed8802 bellard
        s->irq = irq;
2039 a09db21f bellard
        s->sector_write_timer = qemu_new_timer(vm_clock, 
2040 a09db21f bellard
                                               ide_sector_write_timer_cb, s);
2041 5391d806 bellard
        ide_reset(s);
2042 5391d806 bellard
    }
2043 69b91039 bellard
}
2044 69b91039 bellard
2045 34e538ae bellard
static void ide_init_ioport(IDEState *ide_state, int iobase, int iobase2)
2046 69b91039 bellard
{
2047 caed8802 bellard
    register_ioport_write(iobase, 8, 1, ide_ioport_write, ide_state);
2048 caed8802 bellard
    register_ioport_read(iobase, 8, 1, ide_ioport_read, ide_state);
2049 caed8802 bellard
    if (iobase2) {
2050 caed8802 bellard
        register_ioport_read(iobase2, 1, 1, ide_status_read, ide_state);
2051 caed8802 bellard
        register_ioport_write(iobase2, 1, 1, ide_cmd_write, ide_state);
2052 5391d806 bellard
    }
2053 caed8802 bellard
    
2054 caed8802 bellard
    /* data ports */
2055 caed8802 bellard
    register_ioport_write(iobase, 2, 2, ide_data_writew, ide_state);
2056 caed8802 bellard
    register_ioport_read(iobase, 2, 2, ide_data_readw, ide_state);
2057 caed8802 bellard
    register_ioport_write(iobase, 4, 4, ide_data_writel, ide_state);
2058 caed8802 bellard
    register_ioport_read(iobase, 4, 4, ide_data_readl, ide_state);
2059 5391d806 bellard
}
2060 69b91039 bellard
2061 69b91039 bellard
/***********************************************************/
2062 34e538ae bellard
/* ISA IDE definitions */
2063 34e538ae bellard
2064 34e538ae bellard
void isa_ide_init(int iobase, int iobase2, int irq,
2065 34e538ae bellard
                  BlockDriverState *hd0, BlockDriverState *hd1)
2066 34e538ae bellard
{
2067 34e538ae bellard
    IDEState *ide_state;
2068 34e538ae bellard
2069 34e538ae bellard
    ide_state = qemu_mallocz(sizeof(IDEState) * 2);
2070 34e538ae bellard
    if (!ide_state)
2071 34e538ae bellard
        return;
2072 34e538ae bellard
    
2073 3de388f6 bellard
    ide_init2(ide_state, hd0, hd1, pic_set_irq_new, isa_pic, irq);
2074 34e538ae bellard
    ide_init_ioport(ide_state, iobase, iobase2);
2075 34e538ae bellard
}
2076 34e538ae bellard
2077 34e538ae bellard
/***********************************************************/
2078 69b91039 bellard
/* PCI IDE definitions */
2079 69b91039 bellard
2080 5457c8ce bellard
static void cmd646_update_irq(PCIIDEState *d);
2081 5457c8ce bellard
2082 69b91039 bellard
static void ide_map(PCIDevice *pci_dev, int region_num, 
2083 69b91039 bellard
                    uint32_t addr, uint32_t size, int type)
2084 69b91039 bellard
{
2085 69b91039 bellard
    PCIIDEState *d = (PCIIDEState *)pci_dev;
2086 69b91039 bellard
    IDEState *ide_state;
2087 69b91039 bellard
2088 69b91039 bellard
    if (region_num <= 3) {
2089 69b91039 bellard
        ide_state = &d->ide_if[(region_num >> 1) * 2];
2090 69b91039 bellard
        if (region_num & 1) {
2091 69b91039 bellard
            register_ioport_read(addr + 2, 1, 1, ide_status_read, ide_state);
2092 69b91039 bellard
            register_ioport_write(addr + 2, 1, 1, ide_cmd_write, ide_state);
2093 69b91039 bellard
        } else {
2094 69b91039 bellard
            register_ioport_write(addr, 8, 1, ide_ioport_write, ide_state);
2095 69b91039 bellard
            register_ioport_read(addr, 8, 1, ide_ioport_read, ide_state);
2096 69b91039 bellard
2097 69b91039 bellard
            /* data ports */
2098 69b91039 bellard
            register_ioport_write(addr, 2, 2, ide_data_writew, ide_state);
2099 69b91039 bellard
            register_ioport_read(addr, 2, 2, ide_data_readw, ide_state);
2100 69b91039 bellard
            register_ioport_write(addr, 4, 4, ide_data_writel, ide_state);
2101 69b91039 bellard
            register_ioport_read(addr, 4, 4, ide_data_readl, ide_state);
2102 69b91039 bellard
        }
2103 69b91039 bellard
    }
2104 69b91039 bellard
}
2105 69b91039 bellard
2106 98087450 bellard
/* XXX: full callback usage to prepare non blocking I/Os support -
2107 98087450 bellard
   error handling */
2108 98087450 bellard
static void ide_dma_loop(BMDMAState *bm)
2109 98087450 bellard
{
2110 98087450 bellard
    struct {
2111 98087450 bellard
        uint32_t addr;
2112 98087450 bellard
        uint32_t size;
2113 98087450 bellard
    } prd;
2114 98087450 bellard
    target_phys_addr_t cur_addr;
2115 98087450 bellard
    int len, i, len1;
2116 98087450 bellard
2117 98087450 bellard
    cur_addr = bm->addr;
2118 98087450 bellard
    /* at most one page to avoid hanging if erroneous parameters */
2119 98087450 bellard
    for(i = 0; i < 512; i++) {
2120 98087450 bellard
        cpu_physical_memory_read(cur_addr, (uint8_t *)&prd, 8);
2121 98087450 bellard
        prd.addr = le32_to_cpu(prd.addr);
2122 98087450 bellard
        prd.size = le32_to_cpu(prd.size);
2123 98087450 bellard
#ifdef DEBUG_IDE
2124 98087450 bellard
        printf("ide: dma: prd: %08x: addr=0x%08x size=0x%08x\n", 
2125 98087450 bellard
               (int)cur_addr, prd.addr, prd.size);
2126 98087450 bellard
#endif
2127 98087450 bellard
        len = prd.size & 0xfffe;
2128 98087450 bellard
        if (len == 0)
2129 98087450 bellard
            len = 0x10000;
2130 98087450 bellard
        while (len > 0) {
2131 98087450 bellard
            len1 = bm->dma_cb(bm->ide_if, prd.addr, len);
2132 98087450 bellard
            if (len1 == 0)
2133 98087450 bellard
                goto the_end;
2134 98087450 bellard
            prd.addr += len1;
2135 98087450 bellard
            len -= len1;
2136 98087450 bellard
        }
2137 98087450 bellard
        /* end of transfer */
2138 98087450 bellard
        if (prd.size & 0x80000000)
2139 98087450 bellard
            break;
2140 98087450 bellard
        cur_addr += 8;
2141 98087450 bellard
    }
2142 98087450 bellard
    /* end of transfer */
2143 98087450 bellard
 the_end:
2144 98087450 bellard
    bm->status &= ~BM_STATUS_DMAING;
2145 98087450 bellard
    bm->status |= BM_STATUS_INT;
2146 98087450 bellard
    bm->dma_cb = NULL;
2147 98087450 bellard
    bm->ide_if = NULL;
2148 98087450 bellard
}
2149 98087450 bellard
2150 98087450 bellard
static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb)
2151 98087450 bellard
{
2152 98087450 bellard
    BMDMAState *bm = s->bmdma;
2153 98087450 bellard
    if(!bm)
2154 98087450 bellard
        return;
2155 98087450 bellard
    bm->ide_if = s;
2156 98087450 bellard
    bm->dma_cb = dma_cb;
2157 98087450 bellard
    if (bm->status & BM_STATUS_DMAING) {
2158 98087450 bellard
        ide_dma_loop(bm);
2159 98087450 bellard
    }
2160 98087450 bellard
}
2161 98087450 bellard
2162 98087450 bellard
static void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)
2163 98087450 bellard
{
2164 98087450 bellard
    BMDMAState *bm = opaque;
2165 98087450 bellard
#ifdef DEBUG_IDE
2166 98087450 bellard
    printf("%s: 0x%08x\n", __func__, val);
2167 98087450 bellard
#endif
2168 98087450 bellard
    if (!(val & BM_CMD_START)) {
2169 98087450 bellard
        /* XXX: do it better */
2170 98087450 bellard
        bm->status &= ~BM_STATUS_DMAING;
2171 98087450 bellard
        bm->cmd = val & 0x09;
2172 98087450 bellard
    } else {
2173 98087450 bellard
        bm->status |= BM_STATUS_DMAING;
2174 98087450 bellard
        bm->cmd = val & 0x09;
2175 98087450 bellard
        /* start dma transfer if possible */
2176 98087450 bellard
        if (bm->dma_cb)
2177 98087450 bellard
            ide_dma_loop(bm);
2178 98087450 bellard
    }
2179 98087450 bellard
}
2180 98087450 bellard
2181 5457c8ce bellard
static uint32_t bmdma_readb(void *opaque, uint32_t addr)
2182 98087450 bellard
{
2183 98087450 bellard
    BMDMAState *bm = opaque;
2184 5457c8ce bellard
    PCIIDEState *pci_dev;
2185 98087450 bellard
    uint32_t val;
2186 5457c8ce bellard
    
2187 5457c8ce bellard
    switch(addr & 3) {
2188 5457c8ce bellard
    case 0: 
2189 5457c8ce bellard
        val = bm->cmd;
2190 5457c8ce bellard
        break;
2191 5457c8ce bellard
    case 1:
2192 5457c8ce bellard
        pci_dev = bm->pci_dev;
2193 5457c8ce bellard
        if (pci_dev->type == IDE_TYPE_CMD646) {
2194 5457c8ce bellard
            val = pci_dev->dev.config[MRDMODE];
2195 5457c8ce bellard
        } else {
2196 5457c8ce bellard
            val = 0xff;
2197 5457c8ce bellard
        }
2198 5457c8ce bellard
        break;
2199 5457c8ce bellard
    case 2:
2200 5457c8ce bellard
        val = bm->status;
2201 5457c8ce bellard
        break;
2202 5457c8ce bellard
    case 3:
2203 5457c8ce bellard
        pci_dev = bm->pci_dev;
2204 5457c8ce bellard
        if (pci_dev->type == IDE_TYPE_CMD646) {
2205 5457c8ce bellard
            if (bm == &pci_dev->bmdma[0])
2206 5457c8ce bellard
                val = pci_dev->dev.config[UDIDETCR0];
2207 5457c8ce bellard
            else
2208 5457c8ce bellard
                val = pci_dev->dev.config[UDIDETCR1];
2209 5457c8ce bellard
        } else {
2210 5457c8ce bellard
            val = 0xff;
2211 5457c8ce bellard
        }
2212 5457c8ce bellard
        break;
2213 5457c8ce bellard
    default:
2214 5457c8ce bellard
        val = 0xff;
2215 5457c8ce bellard
        break;
2216 5457c8ce bellard
    }
2217 98087450 bellard
#ifdef DEBUG_IDE
2218 5457c8ce bellard
    printf("bmdma: readb 0x%02x : 0x%02x\n", addr, val);
2219 98087450 bellard
#endif
2220 98087450 bellard
    return val;
2221 98087450 bellard
}
2222 98087450 bellard
2223 5457c8ce bellard
static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val)
2224 98087450 bellard
{
2225 98087450 bellard
    BMDMAState *bm = opaque;
2226 5457c8ce bellard
    PCIIDEState *pci_dev;
2227 98087450 bellard
#ifdef DEBUG_IDE
2228 5457c8ce bellard
    printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val);
2229 98087450 bellard
#endif
2230 5457c8ce bellard
    switch(addr & 3) {
2231 5457c8ce bellard
    case 1:
2232 5457c8ce bellard
        pci_dev = bm->pci_dev;
2233 5457c8ce bellard
        if (pci_dev->type == IDE_TYPE_CMD646) {
2234 5457c8ce bellard
            pci_dev->dev.config[MRDMODE] = 
2235 5457c8ce bellard
                (pci_dev->dev.config[MRDMODE] & ~0x30) | (val & 0x30);
2236 5457c8ce bellard
            cmd646_update_irq(pci_dev);
2237 5457c8ce bellard
        }
2238 5457c8ce bellard
        break;
2239 5457c8ce bellard
    case 2:
2240 5457c8ce bellard
        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
2241 5457c8ce bellard
        break;
2242 5457c8ce bellard
    case 3:
2243 5457c8ce bellard
        pci_dev = bm->pci_dev;
2244 5457c8ce bellard
        if (pci_dev->type == IDE_TYPE_CMD646) {
2245 5457c8ce bellard
            if (bm == &pci_dev->bmdma[0])
2246 5457c8ce bellard
                pci_dev->dev.config[UDIDETCR0] = val;
2247 5457c8ce bellard
            else
2248 5457c8ce bellard
                pci_dev->dev.config[UDIDETCR1] = val;
2249 5457c8ce bellard
        }
2250 5457c8ce bellard
        break;
2251 5457c8ce bellard
    }
2252 98087450 bellard
}
2253 98087450 bellard
2254 98087450 bellard
static uint32_t bmdma_addr_readl(void *opaque, uint32_t addr)
2255 98087450 bellard
{
2256 98087450 bellard
    BMDMAState *bm = opaque;
2257 98087450 bellard
    uint32_t val;
2258 98087450 bellard
    val = bm->addr;
2259 98087450 bellard
#ifdef DEBUG_IDE
2260 98087450 bellard
    printf("%s: 0x%08x\n", __func__, val);
2261 98087450 bellard
#endif
2262 98087450 bellard
    return val;
2263 98087450 bellard
}
2264 98087450 bellard
2265 98087450 bellard
static void bmdma_addr_writel(void *opaque, uint32_t addr, uint32_t val)
2266 98087450 bellard
{
2267 98087450 bellard
    BMDMAState *bm = opaque;
2268 98087450 bellard
#ifdef DEBUG_IDE
2269 98087450 bellard
    printf("%s: 0x%08x\n", __func__, val);
2270 98087450 bellard
#endif
2271 98087450 bellard
    bm->addr = val & ~3;
2272 98087450 bellard
}
2273 98087450 bellard
2274 98087450 bellard
static void bmdma_map(PCIDevice *pci_dev, int region_num, 
2275 98087450 bellard
                    uint32_t addr, uint32_t size, int type)
2276 98087450 bellard
{
2277 98087450 bellard
    PCIIDEState *d = (PCIIDEState *)pci_dev;
2278 98087450 bellard
    int i;
2279 98087450 bellard
2280 98087450 bellard
    for(i = 0;i < 2; i++) {
2281 98087450 bellard
        BMDMAState *bm = &d->bmdma[i];
2282 98087450 bellard
        d->ide_if[2 * i].bmdma = bm;
2283 98087450 bellard
        d->ide_if[2 * i + 1].bmdma = bm;
2284 5457c8ce bellard
        bm->pci_dev = (PCIIDEState *)pci_dev;
2285 5457c8ce bellard
2286 98087450 bellard
        register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);
2287 98087450 bellard
2288 5457c8ce bellard
        register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm);
2289 5457c8ce bellard
        register_ioport_read(addr, 4, 1, bmdma_readb, bm);
2290 98087450 bellard
2291 98087450 bellard
        register_ioport_write(addr + 4, 4, 4, bmdma_addr_writel, bm);
2292 98087450 bellard
        register_ioport_read(addr + 4, 4, 4, bmdma_addr_readl, bm);
2293 98087450 bellard
        addr += 8;
2294 98087450 bellard
    }
2295 98087450 bellard
}
2296 98087450 bellard
2297 5457c8ce bellard
/* XXX: call it also when the MRDMODE is changed from the PCI config
2298 5457c8ce bellard
   registers */
2299 5457c8ce bellard
static void cmd646_update_irq(PCIIDEState *d)
2300 5457c8ce bellard
{
2301 5457c8ce bellard
    int pci_level;
2302 5457c8ce bellard
    pci_level = ((d->dev.config[MRDMODE] & MRDMODE_INTR_CH0) &&
2303 5457c8ce bellard
                 !(d->dev.config[MRDMODE] & MRDMODE_BLK_CH0)) ||
2304 5457c8ce bellard
        ((d->dev.config[MRDMODE] & MRDMODE_INTR_CH1) &&
2305 5457c8ce bellard
         !(d->dev.config[MRDMODE] & MRDMODE_BLK_CH1));
2306 5457c8ce bellard
    pci_set_irq((PCIDevice *)d, 0, pci_level);
2307 5457c8ce bellard
}
2308 5457c8ce bellard
2309 5457c8ce bellard
/* the PCI irq level is the logical OR of the two channels */
2310 5457c8ce bellard
static void cmd646_set_irq(void *opaque, int channel, int level)
2311 5457c8ce bellard
{
2312 5457c8ce bellard
    PCIIDEState *d = opaque;
2313 5457c8ce bellard
    int irq_mask;
2314 5457c8ce bellard
2315 5457c8ce bellard
    irq_mask = MRDMODE_INTR_CH0 << channel;
2316 5457c8ce bellard
    if (level)
2317 5457c8ce bellard
        d->dev.config[MRDMODE] |= irq_mask;
2318 5457c8ce bellard
    else
2319 5457c8ce bellard
        d->dev.config[MRDMODE] &= ~irq_mask;
2320 5457c8ce bellard
    cmd646_update_irq(d);
2321 5457c8ce bellard
}
2322 5457c8ce bellard
2323 5457c8ce bellard
/* CMD646 PCI IDE controller */
2324 5457c8ce bellard
void pci_cmd646_ide_init(PCIBus *bus, BlockDriverState **hd_table,
2325 5457c8ce bellard
                         int secondary_ide_enabled)
2326 69b91039 bellard
{
2327 69b91039 bellard
    PCIIDEState *d;
2328 69b91039 bellard
    uint8_t *pci_conf;
2329 34e538ae bellard
    int i;
2330 34e538ae bellard
2331 5457c8ce bellard
    d = (PCIIDEState *)pci_register_device(bus, "CMD646 IDE", 
2332 5457c8ce bellard
                                           sizeof(PCIIDEState),
2333 46e50e9d bellard
                                           -1, 
2334 73c11f63 bellard
                                           NULL, NULL);
2335 5457c8ce bellard
    d->type = IDE_TYPE_CMD646;
2336 69b91039 bellard
    pci_conf = d->dev.config;
2337 5457c8ce bellard
    pci_conf[0x00] = 0x95; // CMD646
2338 5457c8ce bellard
    pci_conf[0x01] = 0x10;
2339 5457c8ce bellard
    pci_conf[0x02] = 0x46;
2340 5457c8ce bellard
    pci_conf[0x03] = 0x06;
2341 5457c8ce bellard
2342 5457c8ce bellard
    pci_conf[0x08] = 0x07; // IDE controller revision
2343 5457c8ce bellard
    pci_conf[0x09] = 0x8f; 
2344 5457c8ce bellard
2345 69b91039 bellard
    pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
2346 69b91039 bellard
    pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
2347 5457c8ce bellard
    pci_conf[0x0e] = 0x00; // header_type
2348 5457c8ce bellard
    
2349 5457c8ce bellard
    if (secondary_ide_enabled) {
2350 5457c8ce bellard
        /* XXX: if not enabled, really disable the seconday IDE controller */
2351 5457c8ce bellard
        pci_conf[0x51] = 0x80; /* enable IDE1 */
2352 5457c8ce bellard
    }
2353 69b91039 bellard
2354 69b91039 bellard
    pci_register_io_region((PCIDevice *)d, 0, 0x8, 
2355 69b91039 bellard
                           PCI_ADDRESS_SPACE_IO, ide_map);
2356 69b91039 bellard
    pci_register_io_region((PCIDevice *)d, 1, 0x4, 
2357 69b91039 bellard
                           PCI_ADDRESS_SPACE_IO, ide_map);
2358 69b91039 bellard
    pci_register_io_region((PCIDevice *)d, 2, 0x8, 
2359 69b91039 bellard
                           PCI_ADDRESS_SPACE_IO, ide_map);
2360 69b91039 bellard
    pci_register_io_region((PCIDevice *)d, 3, 0x4, 
2361 69b91039 bellard
                           PCI_ADDRESS_SPACE_IO, ide_map);
2362 98087450 bellard
    pci_register_io_region((PCIDevice *)d, 4, 0x10, 
2363 98087450 bellard
                           PCI_ADDRESS_SPACE_IO, bmdma_map);
2364 69b91039 bellard
2365 34e538ae bellard
    pci_conf[0x3d] = 0x01; // interrupt on pin 1
2366 5457c8ce bellard
    
2367 34e538ae bellard
    for(i = 0; i < 4; i++)
2368 34e538ae bellard
        d->ide_if[i].pci_dev = (PCIDevice *)d;
2369 5457c8ce bellard
    ide_init2(&d->ide_if[0], hd_table[0], hd_table[1],
2370 5457c8ce bellard
              cmd646_set_irq, d, 0);
2371 5457c8ce bellard
    ide_init2(&d->ide_if[2], hd_table[2], hd_table[3],
2372 5457c8ce bellard
              cmd646_set_irq, d, 1);
2373 34e538ae bellard
}
2374 34e538ae bellard
2375 34e538ae bellard
/* hd_table must contain 4 block drivers */
2376 34e538ae bellard
/* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
2377 502a5395 pbrook
void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn)
2378 34e538ae bellard
{
2379 34e538ae bellard
    PCIIDEState *d;
2380 34e538ae bellard
    uint8_t *pci_conf;
2381 34e538ae bellard
    
2382 34e538ae bellard
    /* register a function 1 of PIIX3 */
2383 46e50e9d bellard
    d = (PCIIDEState *)pci_register_device(bus, "PIIX3 IDE", 
2384 46e50e9d bellard
                                           sizeof(PCIIDEState),
2385 502a5395 pbrook
                                           devfn,
2386 34e538ae bellard
                                           NULL, NULL);
2387 5457c8ce bellard
    d->type = IDE_TYPE_PIIX3;
2388 5457c8ce bellard
2389 34e538ae bellard
    pci_conf = d->dev.config;
2390 34e538ae bellard
    pci_conf[0x00] = 0x86; // Intel
2391 34e538ae bellard
    pci_conf[0x01] = 0x80;
2392 34e538ae bellard
    pci_conf[0x02] = 0x10;
2393 34e538ae bellard
    pci_conf[0x03] = 0x70;
2394 92510b8c bellard
    pci_conf[0x09] = 0x80; // legacy ATA mode
2395 34e538ae bellard
    pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
2396 34e538ae bellard
    pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
2397 34e538ae bellard
    pci_conf[0x0e] = 0x00; // header_type
2398 34e538ae bellard
2399 98087450 bellard
    pci_register_io_region((PCIDevice *)d, 4, 0x10, 
2400 98087450 bellard
                           PCI_ADDRESS_SPACE_IO, bmdma_map);
2401 34e538ae bellard
2402 5457c8ce bellard
    ide_init2(&d->ide_if[0], hd_table[0], hd_table[1],
2403 3de388f6 bellard
              pic_set_irq_new, isa_pic, 14);
2404 5457c8ce bellard
    ide_init2(&d->ide_if[2], hd_table[2], hd_table[3],
2405 3de388f6 bellard
              pic_set_irq_new, isa_pic, 15);
2406 34e538ae bellard
    ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
2407 34e538ae bellard
    ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
2408 69b91039 bellard
}
2409 1ade1de2 bellard
2410 1ade1de2 bellard
/***********************************************************/
2411 1ade1de2 bellard
/* MacIO based PowerPC IDE */
2412 1ade1de2 bellard
2413 1ade1de2 bellard
/* PowerMac IDE memory IO */
2414 1ade1de2 bellard
static void pmac_ide_writeb (void *opaque,
2415 1ade1de2 bellard
                             target_phys_addr_t addr, uint32_t val)
2416 1ade1de2 bellard
{
2417 1ade1de2 bellard
    addr = (addr & 0xFFF) >> 4; 
2418 1ade1de2 bellard
    switch (addr) {
2419 1ade1de2 bellard
    case 1 ... 7:
2420 1ade1de2 bellard
        ide_ioport_write(opaque, addr, val);
2421 1ade1de2 bellard
        break;
2422 1ade1de2 bellard
    case 8:
2423 1ade1de2 bellard
    case 22:
2424 1ade1de2 bellard
        ide_cmd_write(opaque, 0, val);
2425 1ade1de2 bellard
        break;
2426 1ade1de2 bellard
    default:
2427 1ade1de2 bellard
        break;
2428 1ade1de2 bellard
    }
2429 1ade1de2 bellard
}
2430 1ade1de2 bellard
2431 1ade1de2 bellard
static uint32_t pmac_ide_readb (void *opaque,target_phys_addr_t addr)
2432 1ade1de2 bellard
{
2433 1ade1de2 bellard
    uint8_t retval;
2434 1ade1de2 bellard
2435 1ade1de2 bellard
    addr = (addr & 0xFFF) >> 4;
2436 1ade1de2 bellard
    switch (addr) {
2437 1ade1de2 bellard
    case 1 ... 7:
2438 1ade1de2 bellard
        retval = ide_ioport_read(opaque, addr);
2439 1ade1de2 bellard
        break;
2440 1ade1de2 bellard
    case 8:
2441 1ade1de2 bellard
    case 22:
2442 1ade1de2 bellard
        retval = ide_status_read(opaque, 0);
2443 1ade1de2 bellard
        break;
2444 1ade1de2 bellard
    default:
2445 1ade1de2 bellard
        retval = 0xFF;
2446 1ade1de2 bellard
        break;
2447 1ade1de2 bellard
    }
2448 1ade1de2 bellard
    return retval;
2449 1ade1de2 bellard
}
2450 1ade1de2 bellard
2451 1ade1de2 bellard
static void pmac_ide_writew (void *opaque,
2452 1ade1de2 bellard
                             target_phys_addr_t addr, uint32_t val)
2453 1ade1de2 bellard
{
2454 1ade1de2 bellard
    addr = (addr & 0xFFF) >> 4; 
2455 1ade1de2 bellard
#ifdef TARGET_WORDS_BIGENDIAN
2456 1ade1de2 bellard
    val = bswap16(val);
2457 1ade1de2 bellard
#endif
2458 1ade1de2 bellard
    if (addr == 0) {
2459 1ade1de2 bellard
        ide_data_writew(opaque, 0, val);
2460 1ade1de2 bellard
    }
2461 1ade1de2 bellard
}
2462 1ade1de2 bellard
2463 1ade1de2 bellard
static uint32_t pmac_ide_readw (void *opaque,target_phys_addr_t addr)
2464 1ade1de2 bellard
{
2465 1ade1de2 bellard
    uint16_t retval;
2466 1ade1de2 bellard
2467 1ade1de2 bellard
    addr = (addr & 0xFFF) >> 4; 
2468 1ade1de2 bellard
    if (addr == 0) {
2469 1ade1de2 bellard
        retval = ide_data_readw(opaque, 0);
2470 1ade1de2 bellard
    } else {
2471 1ade1de2 bellard
        retval = 0xFFFF;
2472 1ade1de2 bellard
    }
2473 1ade1de2 bellard
#ifdef TARGET_WORDS_BIGENDIAN
2474 1ade1de2 bellard
    retval = bswap16(retval);
2475 1ade1de2 bellard
#endif
2476 1ade1de2 bellard
    return retval;
2477 1ade1de2 bellard
}
2478 1ade1de2 bellard
2479 1ade1de2 bellard
static void pmac_ide_writel (void *opaque,
2480 1ade1de2 bellard
                             target_phys_addr_t addr, uint32_t val)
2481 1ade1de2 bellard
{
2482 1ade1de2 bellard
    addr = (addr & 0xFFF) >> 4; 
2483 1ade1de2 bellard
#ifdef TARGET_WORDS_BIGENDIAN
2484 1ade1de2 bellard
    val = bswap32(val);
2485 1ade1de2 bellard
#endif
2486 1ade1de2 bellard
    if (addr == 0) {
2487 1ade1de2 bellard
        ide_data_writel(opaque, 0, val);
2488 1ade1de2 bellard
    }
2489 1ade1de2 bellard
}
2490 1ade1de2 bellard
2491 1ade1de2 bellard
static uint32_t pmac_ide_readl (void *opaque,target_phys_addr_t addr)
2492 1ade1de2 bellard
{
2493 1ade1de2 bellard
    uint32_t retval;
2494 1ade1de2 bellard
2495 1ade1de2 bellard
    addr = (addr & 0xFFF) >> 4; 
2496 1ade1de2 bellard
    if (addr == 0) {
2497 1ade1de2 bellard
        retval = ide_data_readl(opaque, 0);
2498 1ade1de2 bellard
    } else {
2499 1ade1de2 bellard
        retval = 0xFFFFFFFF;
2500 1ade1de2 bellard
    }
2501 1ade1de2 bellard
#ifdef TARGET_WORDS_BIGENDIAN
2502 1ade1de2 bellard
    retval = bswap32(retval);
2503 1ade1de2 bellard
#endif
2504 1ade1de2 bellard
    return retval;
2505 1ade1de2 bellard
}
2506 1ade1de2 bellard
2507 1ade1de2 bellard
static CPUWriteMemoryFunc *pmac_ide_write[] = {
2508 1ade1de2 bellard
    pmac_ide_writeb,
2509 1ade1de2 bellard
    pmac_ide_writew,
2510 1ade1de2 bellard
    pmac_ide_writel,
2511 1ade1de2 bellard
};
2512 1ade1de2 bellard
2513 1ade1de2 bellard
static CPUReadMemoryFunc *pmac_ide_read[] = {
2514 1ade1de2 bellard
    pmac_ide_readb,
2515 1ade1de2 bellard
    pmac_ide_readw,
2516 1ade1de2 bellard
    pmac_ide_readl,
2517 1ade1de2 bellard
};
2518 1ade1de2 bellard
2519 1ade1de2 bellard
/* hd_table must contain 4 block drivers */
2520 1ade1de2 bellard
/* PowerMac uses memory mapped registers, not I/O. Return the memory
2521 1ade1de2 bellard
   I/O index to access the ide. */
2522 1ade1de2 bellard
int pmac_ide_init (BlockDriverState **hd_table,
2523 5457c8ce bellard
                   SetIRQFunc *set_irq, void *irq_opaque, int irq)
2524 1ade1de2 bellard
{
2525 1ade1de2 bellard
    IDEState *ide_if;
2526 1ade1de2 bellard
    int pmac_ide_memory;
2527 1ade1de2 bellard
2528 1ade1de2 bellard
    ide_if = qemu_mallocz(sizeof(IDEState) * 2);
2529 5457c8ce bellard
    ide_init2(&ide_if[0], hd_table[0], hd_table[1],
2530 5457c8ce bellard
              set_irq, irq_opaque, irq);
2531 1ade1de2 bellard
    
2532 1ade1de2 bellard
    pmac_ide_memory = cpu_register_io_memory(0, pmac_ide_read,
2533 1ade1de2 bellard
                                             pmac_ide_write, &ide_if[0]);
2534 1ade1de2 bellard
    return pmac_ide_memory;
2535 1ade1de2 bellard
}