Statistics
| Branch: | Revision:

root / hw / ide.c @ 24c7b0e3

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