Statistics
| Branch: | Revision:

root / hw / ide.c @ fcdd25ab

History | View | Annotate | Download (121.9 kB)

1 5391d806 bellard
/*
2 38cdea7c balrog
 * QEMU IDE disk and CD/DVD-ROM Emulator
3 5fafdf24 ths
 *
4 5391d806 bellard
 * Copyright (c) 2003 Fabrice Bellard
5 201a51fc balrog
 * Copyright (c) 2006 Openedhand Ltd.
6 5fafdf24 ths
 *
7 5391d806 bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 5391d806 bellard
 * of this software and associated documentation files (the "Software"), to deal
9 5391d806 bellard
 * in the Software without restriction, including without limitation the rights
10 5391d806 bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 5391d806 bellard
 * copies of the Software, and to permit persons to whom the Software is
12 5391d806 bellard
 * furnished to do so, subject to the following conditions:
13 5391d806 bellard
 *
14 5391d806 bellard
 * The above copyright notice and this permission notice shall be included in
15 5391d806 bellard
 * all copies or substantial portions of the Software.
16 5391d806 bellard
 *
17 5391d806 bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 5391d806 bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 5391d806 bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 5391d806 bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 5391d806 bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 5391d806 bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 5391d806 bellard
 * THE SOFTWARE.
24 5391d806 bellard
 */
25 87ecb68b pbrook
#include "hw.h"
26 87ecb68b pbrook
#include "pc.h"
27 87ecb68b pbrook
#include "pci.h"
28 87ecb68b pbrook
#include "scsi-disk.h"
29 87ecb68b pbrook
#include "pcmcia.h"
30 87ecb68b pbrook
#include "block.h"
31 87ecb68b pbrook
#include "qemu-timer.h"
32 87ecb68b pbrook
#include "sysemu.h"
33 9596ebb7 pbrook
#include "ppc_mac.h"
34 5391d806 bellard
35 5391d806 bellard
/* debug IDE devices */
36 5391d806 bellard
//#define DEBUG_IDE
37 5391d806 bellard
//#define DEBUG_IDE_ATAPI
38 8ccad811 bellard
//#define DEBUG_AIO
39 8ccad811 bellard
#define USE_DMA_CDROM
40 5391d806 bellard
41 5391d806 bellard
/* Bits of HD_STATUS */
42 5391d806 bellard
#define ERR_STAT                0x01
43 5391d806 bellard
#define INDEX_STAT                0x02
44 5391d806 bellard
#define ECC_STAT                0x04        /* Corrected error */
45 5391d806 bellard
#define DRQ_STAT                0x08
46 5391d806 bellard
#define SEEK_STAT                0x10
47 5391d806 bellard
#define SRV_STAT                0x10
48 5391d806 bellard
#define WRERR_STAT                0x20
49 5391d806 bellard
#define READY_STAT                0x40
50 5391d806 bellard
#define BUSY_STAT                0x80
51 5391d806 bellard
52 5391d806 bellard
/* Bits for HD_ERROR */
53 5391d806 bellard
#define MARK_ERR                0x01        /* Bad address mark */
54 5391d806 bellard
#define TRK0_ERR                0x02        /* couldn't find track 0 */
55 5391d806 bellard
#define ABRT_ERR                0x04        /* Command aborted */
56 5391d806 bellard
#define MCR_ERR                        0x08        /* media change request */
57 5391d806 bellard
#define ID_ERR                        0x10        /* ID field not found */
58 5391d806 bellard
#define MC_ERR                        0x20        /* media changed */
59 5391d806 bellard
#define ECC_ERR                        0x40        /* Uncorrectable ECC error */
60 5391d806 bellard
#define BBD_ERR                        0x80        /* pre-EIDE meaning:  block marked bad */
61 5391d806 bellard
#define ICRC_ERR                0x80        /* new meaning:  CRC error during transfer */
62 5391d806 bellard
63 5391d806 bellard
/* Bits of HD_NSECTOR */
64 5391d806 bellard
#define CD                        0x01
65 5391d806 bellard
#define IO                        0x02
66 5391d806 bellard
#define REL                        0x04
67 5391d806 bellard
#define TAG_MASK                0xf8
68 5391d806 bellard
69 5391d806 bellard
#define IDE_CMD_RESET           0x04
70 5391d806 bellard
#define IDE_CMD_DISABLE_IRQ     0x02
71 5391d806 bellard
72 5391d806 bellard
/* ATA/ATAPI Commands pre T13 Spec */
73 5391d806 bellard
#define WIN_NOP                                0x00
74 5391d806 bellard
/*
75 5391d806 bellard
 *        0x01->0x02 Reserved
76 5391d806 bellard
 */
77 5391d806 bellard
#define CFA_REQ_EXT_ERROR_CODE                0x03 /* CFA Request Extended Error Code */
78 5391d806 bellard
/*
79 5391d806 bellard
 *        0x04->0x07 Reserved
80 5391d806 bellard
 */
81 5391d806 bellard
#define WIN_SRST                        0x08 /* ATAPI soft reset command */
82 5391d806 bellard
#define WIN_DEVICE_RESET                0x08
83 5391d806 bellard
/*
84 5391d806 bellard
 *        0x09->0x0F Reserved
85 5391d806 bellard
 */
86 5391d806 bellard
#define WIN_RECAL                        0x10
87 5391d806 bellard
#define WIN_RESTORE                        WIN_RECAL
88 5391d806 bellard
/*
89 5391d806 bellard
 *        0x10->0x1F Reserved
90 5391d806 bellard
 */
91 5391d806 bellard
#define WIN_READ                        0x20 /* 28-Bit */
92 5391d806 bellard
#define WIN_READ_ONCE                        0x21 /* 28-Bit without retries */
93 5391d806 bellard
#define WIN_READ_LONG                        0x22 /* 28-Bit */
94 5391d806 bellard
#define WIN_READ_LONG_ONCE                0x23 /* 28-Bit without retries */
95 5391d806 bellard
#define WIN_READ_EXT                        0x24 /* 48-Bit */
96 5391d806 bellard
#define WIN_READDMA_EXT                        0x25 /* 48-Bit */
97 5391d806 bellard
#define WIN_READDMA_QUEUED_EXT                0x26 /* 48-Bit */
98 5391d806 bellard
#define WIN_READ_NATIVE_MAX_EXT                0x27 /* 48-Bit */
99 5391d806 bellard
/*
100 5391d806 bellard
 *        0x28
101 5391d806 bellard
 */
102 5391d806 bellard
#define WIN_MULTREAD_EXT                0x29 /* 48-Bit */
103 5391d806 bellard
/*
104 5391d806 bellard
 *        0x2A->0x2F Reserved
105 5391d806 bellard
 */
106 5391d806 bellard
#define WIN_WRITE                        0x30 /* 28-Bit */
107 5391d806 bellard
#define WIN_WRITE_ONCE                        0x31 /* 28-Bit without retries */
108 5391d806 bellard
#define WIN_WRITE_LONG                        0x32 /* 28-Bit */
109 5391d806 bellard
#define WIN_WRITE_LONG_ONCE                0x33 /* 28-Bit without retries */
110 5391d806 bellard
#define WIN_WRITE_EXT                        0x34 /* 48-Bit */
111 5391d806 bellard
#define WIN_WRITEDMA_EXT                0x35 /* 48-Bit */
112 5391d806 bellard
#define WIN_WRITEDMA_QUEUED_EXT                0x36 /* 48-Bit */
113 5391d806 bellard
#define WIN_SET_MAX_EXT                        0x37 /* 48-Bit */
114 5391d806 bellard
#define CFA_WRITE_SECT_WO_ERASE                0x38 /* CFA Write Sectors without erase */
115 5391d806 bellard
#define WIN_MULTWRITE_EXT                0x39 /* 48-Bit */
116 5391d806 bellard
/*
117 5391d806 bellard
 *        0x3A->0x3B Reserved
118 5391d806 bellard
 */
119 5391d806 bellard
#define WIN_WRITE_VERIFY                0x3C /* 28-Bit */
120 5391d806 bellard
/*
121 5391d806 bellard
 *        0x3D->0x3F Reserved
122 5391d806 bellard
 */
123 5391d806 bellard
#define WIN_VERIFY                        0x40 /* 28-Bit - Read Verify Sectors */
124 5391d806 bellard
#define WIN_VERIFY_ONCE                        0x41 /* 28-Bit - without retries */
125 5391d806 bellard
#define WIN_VERIFY_EXT                        0x42 /* 48-Bit */
126 5391d806 bellard
/*
127 5391d806 bellard
 *        0x43->0x4F Reserved
128 5391d806 bellard
 */
129 5391d806 bellard
#define WIN_FORMAT                        0x50
130 5391d806 bellard
/*
131 5391d806 bellard
 *        0x51->0x5F Reserved
132 5391d806 bellard
 */
133 5391d806 bellard
#define WIN_INIT                        0x60
134 5391d806 bellard
/*
135 5391d806 bellard
 *        0x61->0x5F Reserved
136 5391d806 bellard
 */
137 5391d806 bellard
#define WIN_SEEK                        0x70 /* 0x70-0x7F Reserved */
138 5391d806 bellard
#define CFA_TRANSLATE_SECTOR                0x87 /* CFA Translate Sector */
139 5391d806 bellard
#define WIN_DIAGNOSE                        0x90
140 5391d806 bellard
#define WIN_SPECIFY                        0x91 /* set drive geometry translation */
141 5391d806 bellard
#define WIN_DOWNLOAD_MICROCODE                0x92
142 5391d806 bellard
#define WIN_STANDBYNOW2                        0x94
143 201a51fc balrog
#define CFA_IDLEIMMEDIATE                0x95 /* force drive to become "ready" */
144 5391d806 bellard
#define WIN_STANDBY2                        0x96
145 5391d806 bellard
#define WIN_SETIDLE2                        0x97
146 5391d806 bellard
#define WIN_CHECKPOWERMODE2                0x98
147 5391d806 bellard
#define WIN_SLEEPNOW2                        0x99
148 5391d806 bellard
/*
149 5391d806 bellard
 *        0x9A VENDOR
150 5391d806 bellard
 */
151 5391d806 bellard
#define WIN_PACKETCMD                        0xA0 /* Send a packet command. */
152 5391d806 bellard
#define WIN_PIDENTIFY                        0xA1 /* identify ATAPI device        */
153 5391d806 bellard
#define WIN_QUEUED_SERVICE                0xA2
154 5391d806 bellard
#define WIN_SMART                        0xB0 /* self-monitoring and reporting */
155 201a51fc balrog
#define CFA_ACCESS_METADATA_STORAGE        0xB8
156 201a51fc balrog
#define CFA_ERASE_SECTORS               0xC0 /* microdrives implement as NOP */
157 5391d806 bellard
#define WIN_MULTREAD                        0xC4 /* read sectors using multiple mode*/
158 5391d806 bellard
#define WIN_MULTWRITE                        0xC5 /* write sectors using multiple mode */
159 5391d806 bellard
#define WIN_SETMULT                        0xC6 /* enable/disable multiple mode */
160 5391d806 bellard
#define WIN_READDMA_QUEUED                0xC7 /* read sectors using Queued DMA transfers */
161 5391d806 bellard
#define WIN_READDMA                        0xC8 /* read sectors using DMA transfers */
162 5391d806 bellard
#define WIN_READDMA_ONCE                0xC9 /* 28-Bit - without retries */
163 5391d806 bellard
#define WIN_WRITEDMA                        0xCA /* write sectors using DMA transfers */
164 5391d806 bellard
#define WIN_WRITEDMA_ONCE                0xCB /* 28-Bit - without retries */
165 5391d806 bellard
#define WIN_WRITEDMA_QUEUED                0xCC /* write sectors using Queued DMA transfers */
166 5391d806 bellard
#define CFA_WRITE_MULTI_WO_ERASE        0xCD /* CFA Write multiple without erase */
167 5fafdf24 ths
#define WIN_GETMEDIASTATUS                0xDA
168 5391d806 bellard
#define WIN_ACKMEDIACHANGE                0xDB /* ATA-1, ATA-2 vendor */
169 5391d806 bellard
#define WIN_POSTBOOT                        0xDC
170 5391d806 bellard
#define WIN_PREBOOT                        0xDD
171 5391d806 bellard
#define WIN_DOORLOCK                        0xDE /* lock door on removable drives */
172 5391d806 bellard
#define WIN_DOORUNLOCK                        0xDF /* unlock door on removable drives */
173 5391d806 bellard
#define WIN_STANDBYNOW1                        0xE0
174 5391d806 bellard
#define WIN_IDLEIMMEDIATE                0xE1 /* force drive to become "ready" */
175 5391d806 bellard
#define WIN_STANDBY                     0xE2 /* Set device in Standby Mode */
176 5391d806 bellard
#define WIN_SETIDLE1                        0xE3
177 5391d806 bellard
#define WIN_READ_BUFFER                        0xE4 /* force read only 1 sector */
178 5391d806 bellard
#define WIN_CHECKPOWERMODE1                0xE5
179 5391d806 bellard
#define WIN_SLEEPNOW1                        0xE6
180 5391d806 bellard
#define WIN_FLUSH_CACHE                        0xE7
181 5391d806 bellard
#define WIN_WRITE_BUFFER                0xE8 /* force write only 1 sector */
182 5391d806 bellard
#define WIN_WRITE_SAME                        0xE9 /* read ata-2 to use */
183 5391d806 bellard
        /* SET_FEATURES 0x22 or 0xDD */
184 5391d806 bellard
#define WIN_FLUSH_CACHE_EXT                0xEA /* 48-Bit */
185 5391d806 bellard
#define WIN_IDENTIFY                        0xEC /* ask drive to identify itself        */
186 5391d806 bellard
#define WIN_MEDIAEJECT                        0xED
187 5391d806 bellard
#define WIN_IDENTIFY_DMA                0xEE /* same as WIN_IDENTIFY, but DMA */
188 5391d806 bellard
#define WIN_SETFEATURES                        0xEF /* set special drive features */
189 5391d806 bellard
#define EXABYTE_ENABLE_NEST                0xF0
190 201a51fc balrog
#define IBM_SENSE_CONDITION                0xF0 /* measure disk temperature */
191 5391d806 bellard
#define WIN_SECURITY_SET_PASS                0xF1
192 5391d806 bellard
#define WIN_SECURITY_UNLOCK                0xF2
193 5391d806 bellard
#define WIN_SECURITY_ERASE_PREPARE        0xF3
194 5391d806 bellard
#define WIN_SECURITY_ERASE_UNIT                0xF4
195 5391d806 bellard
#define WIN_SECURITY_FREEZE_LOCK        0xF5
196 201a51fc balrog
#define CFA_WEAR_LEVEL                        0xF5 /* microdrives implement as NOP */
197 5391d806 bellard
#define WIN_SECURITY_DISABLE                0xF6
198 5391d806 bellard
#define WIN_READ_NATIVE_MAX                0xF8 /* return the native maximum address */
199 5391d806 bellard
#define WIN_SET_MAX                        0xF9
200 5391d806 bellard
#define DISABLE_SEAGATE                        0xFB
201 5391d806 bellard
202 5391d806 bellard
/* set to 1 set disable mult support */
203 f66723fa bellard
#define MAX_MULT_SECTORS 16
204 5391d806 bellard
205 1d8cde5b aurel32
#define IDE_DMA_BUF_SECTORS 256
206 1d8cde5b aurel32
207 1d8cde5b aurel32
#if (IDE_DMA_BUF_SECTORS < MAX_MULT_SECTORS)
208 1d8cde5b aurel32
#error "IDE_DMA_BUF_SECTORS must be bigger or equal to MAX_MULT_SECTORS"
209 1d8cde5b aurel32
#endif
210 1d8cde5b aurel32
211 5391d806 bellard
/* ATAPI defines */
212 5391d806 bellard
213 5391d806 bellard
#define ATAPI_PACKET_SIZE 12
214 5391d806 bellard
215 5391d806 bellard
/* The generic packet command opcodes for CD/DVD Logical Units,
216 5391d806 bellard
 * From Table 57 of the SFF8090 Ver. 3 (Mt. Fuji) draft standard. */
217 5391d806 bellard
#define GPCMD_BLANK                            0xa1
218 5391d806 bellard
#define GPCMD_CLOSE_TRACK                    0x5b
219 5391d806 bellard
#define GPCMD_FLUSH_CACHE                    0x35
220 5391d806 bellard
#define GPCMD_FORMAT_UNIT                    0x04
221 5391d806 bellard
#define GPCMD_GET_CONFIGURATION                    0x46
222 5391d806 bellard
#define GPCMD_GET_EVENT_STATUS_NOTIFICATION 0x4a
223 5391d806 bellard
#define GPCMD_GET_PERFORMANCE                    0xac
224 5391d806 bellard
#define GPCMD_INQUIRY                            0x12
225 5391d806 bellard
#define GPCMD_LOAD_UNLOAD                    0xa6
226 5391d806 bellard
#define GPCMD_MECHANISM_STATUS                    0xbd
227 5391d806 bellard
#define GPCMD_MODE_SELECT_10                    0x55
228 5391d806 bellard
#define GPCMD_MODE_SENSE_10                    0x5a
229 5391d806 bellard
#define GPCMD_PAUSE_RESUME                    0x4b
230 5391d806 bellard
#define GPCMD_PLAY_AUDIO_10                    0x45
231 5391d806 bellard
#define GPCMD_PLAY_AUDIO_MSF                    0x47
232 5391d806 bellard
#define GPCMD_PLAY_AUDIO_TI                    0x48
233 5391d806 bellard
#define GPCMD_PLAY_CD                            0xbc
234 5391d806 bellard
#define GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL  0x1e
235 5391d806 bellard
#define GPCMD_READ_10                            0x28
236 5391d806 bellard
#define GPCMD_READ_12                            0xa8
237 5391d806 bellard
#define GPCMD_READ_CDVD_CAPACITY            0x25
238 5391d806 bellard
#define GPCMD_READ_CD                            0xbe
239 5391d806 bellard
#define GPCMD_READ_CD_MSF                    0xb9
240 5391d806 bellard
#define GPCMD_READ_DISC_INFO                    0x51
241 5391d806 bellard
#define GPCMD_READ_DVD_STRUCTURE            0xad
242 5391d806 bellard
#define GPCMD_READ_FORMAT_CAPACITIES            0x23
243 5391d806 bellard
#define GPCMD_READ_HEADER                    0x44
244 5391d806 bellard
#define GPCMD_READ_TRACK_RZONE_INFO            0x52
245 5391d806 bellard
#define GPCMD_READ_SUBCHANNEL                    0x42
246 5391d806 bellard
#define GPCMD_READ_TOC_PMA_ATIP                    0x43
247 5391d806 bellard
#define GPCMD_REPAIR_RZONE_TRACK            0x58
248 5391d806 bellard
#define GPCMD_REPORT_KEY                    0xa4
249 5391d806 bellard
#define GPCMD_REQUEST_SENSE                    0x03
250 5391d806 bellard
#define GPCMD_RESERVE_RZONE_TRACK            0x53
251 5391d806 bellard
#define GPCMD_SCAN                            0xba
252 5391d806 bellard
#define GPCMD_SEEK                            0x2b
253 5391d806 bellard
#define GPCMD_SEND_DVD_STRUCTURE            0xad
254 5391d806 bellard
#define GPCMD_SEND_EVENT                    0xa2
255 5391d806 bellard
#define GPCMD_SEND_KEY                            0xa3
256 5391d806 bellard
#define GPCMD_SEND_OPC                            0x54
257 5391d806 bellard
#define GPCMD_SET_READ_AHEAD                    0xa7
258 5391d806 bellard
#define GPCMD_SET_STREAMING                    0xb6
259 5391d806 bellard
#define GPCMD_START_STOP_UNIT                    0x1b
260 5391d806 bellard
#define GPCMD_STOP_PLAY_SCAN                    0x4e
261 5391d806 bellard
#define GPCMD_TEST_UNIT_READY                    0x00
262 5391d806 bellard
#define GPCMD_VERIFY_10                            0x2f
263 5391d806 bellard
#define GPCMD_WRITE_10                            0x2a
264 5391d806 bellard
#define GPCMD_WRITE_AND_VERIFY_10            0x2e
265 5fafdf24 ths
/* This is listed as optional in ATAPI 2.6, but is (curiously)
266 5391d806 bellard
 * missing from Mt. Fuji, Table 57.  It _is_ mentioned in Mt. Fuji
267 5391d806 bellard
 * Table 377 as an MMC command for SCSi devices though...  Most ATAPI
268 5391d806 bellard
 * drives support it. */
269 5391d806 bellard
#define GPCMD_SET_SPEED                            0xbb
270 5fafdf24 ths
/* This seems to be a SCSI specific CD-ROM opcode
271 5391d806 bellard
 * to play data at track/index */
272 5391d806 bellard
#define GPCMD_PLAYAUDIO_TI                    0x48
273 5391d806 bellard
/*
274 5391d806 bellard
 * From MS Media Status Notification Support Specification. For
275 5391d806 bellard
 * older drives only.
276 5391d806 bellard
 */
277 5391d806 bellard
#define GPCMD_GET_MEDIA_STATUS                    0xda
278 d14049ea ths
#define GPCMD_MODE_SENSE_6                    0x1a
279 5391d806 bellard
280 5391d806 bellard
/* Mode page codes for mode sense/set */
281 5391d806 bellard
#define GPMODE_R_W_ERROR_PAGE                0x01
282 5391d806 bellard
#define GPMODE_WRITE_PARMS_PAGE                0x05
283 5391d806 bellard
#define GPMODE_AUDIO_CTL_PAGE                0x0e
284 5391d806 bellard
#define GPMODE_POWER_PAGE                0x1a
285 5391d806 bellard
#define GPMODE_FAULT_FAIL_PAGE                0x1c
286 5391d806 bellard
#define GPMODE_TO_PROTECT_PAGE                0x1d
287 5391d806 bellard
#define GPMODE_CAPABILITIES_PAGE        0x2a
288 5391d806 bellard
#define GPMODE_ALL_PAGES                0x3f
289 5391d806 bellard
/* Not in Mt. Fuji, but in ATAPI 2.6 -- depricated now in favor
290 5391d806 bellard
 * of MODE_SENSE_POWER_PAGE */
291 5391d806 bellard
#define GPMODE_CDROM_PAGE                0x0d
292 5391d806 bellard
293 38cdea7c balrog
/*
294 38cdea7c balrog
 * Based on values from <linux/cdrom.h> but extending CD_MINS
295 38cdea7c balrog
 * to the maximum common size allowed by the Orange's Book ATIP
296 38cdea7c balrog
 *
297 38cdea7c balrog
 * 90 and 99 min CDs are also available but using them as the
298 38cdea7c balrog
 * upper limit reduces the effectiveness of the heuristic to
299 38cdea7c balrog
 * detect DVDs burned to less than 25% of their maximum capacity
300 38cdea7c balrog
 */
301 38cdea7c balrog
302 38cdea7c balrog
/* Some generally useful CD-ROM information */
303 38cdea7c balrog
#define CD_MINS                       80 /* max. minutes per CD */
304 38cdea7c balrog
#define CD_SECS                       60 /* seconds per minute */
305 38cdea7c balrog
#define CD_FRAMES                     75 /* frames per second */
306 38cdea7c balrog
#define CD_FRAMESIZE                2048 /* bytes per frame, "cooked" mode */
307 38cdea7c balrog
#define CD_MAX_BYTES       (CD_MINS * CD_SECS * CD_FRAMES * CD_FRAMESIZE)
308 38cdea7c balrog
#define CD_MAX_SECTORS     (CD_MAX_BYTES / 512)
309 38cdea7c balrog
310 38cdea7c balrog
/*
311 38cdea7c balrog
 * The MMC values are not IDE specific and might need to be moved
312 38cdea7c balrog
 * to a common header if they are also needed for the SCSI emulation
313 38cdea7c balrog
 */
314 38cdea7c balrog
315 38cdea7c balrog
/* Profile list from MMC-6 revision 1 table 91 */
316 38cdea7c balrog
#define MMC_PROFILE_NONE                0x0000
317 38cdea7c balrog
#define MMC_PROFILE_CD_ROM              0x0008
318 38cdea7c balrog
#define MMC_PROFILE_CD_R                0x0009
319 38cdea7c balrog
#define MMC_PROFILE_CD_RW               0x000A
320 38cdea7c balrog
#define MMC_PROFILE_DVD_ROM             0x0010
321 38cdea7c balrog
#define MMC_PROFILE_DVD_R_SR            0x0011
322 38cdea7c balrog
#define MMC_PROFILE_DVD_RAM             0x0012
323 38cdea7c balrog
#define MMC_PROFILE_DVD_RW_RO           0x0013
324 38cdea7c balrog
#define MMC_PROFILE_DVD_RW_SR           0x0014
325 38cdea7c balrog
#define MMC_PROFILE_DVD_R_DL_SR         0x0015
326 38cdea7c balrog
#define MMC_PROFILE_DVD_R_DL_JR         0x0016
327 38cdea7c balrog
#define MMC_PROFILE_DVD_RW_DL           0x0017
328 38cdea7c balrog
#define MMC_PROFILE_DVD_DDR             0x0018
329 38cdea7c balrog
#define MMC_PROFILE_DVD_PLUS_RW         0x001A
330 38cdea7c balrog
#define MMC_PROFILE_DVD_PLUS_R          0x001B
331 38cdea7c balrog
#define MMC_PROFILE_DVD_PLUS_RW_DL      0x002A
332 38cdea7c balrog
#define MMC_PROFILE_DVD_PLUS_R_DL       0x002B
333 38cdea7c balrog
#define MMC_PROFILE_BD_ROM              0x0040
334 38cdea7c balrog
#define MMC_PROFILE_BD_R_SRM            0x0041
335 38cdea7c balrog
#define MMC_PROFILE_BD_R_RRM            0x0042
336 38cdea7c balrog
#define MMC_PROFILE_BD_RE               0x0043
337 38cdea7c balrog
#define MMC_PROFILE_HDDVD_ROM           0x0050
338 38cdea7c balrog
#define MMC_PROFILE_HDDVD_R             0x0051
339 38cdea7c balrog
#define MMC_PROFILE_HDDVD_RAM           0x0052
340 38cdea7c balrog
#define MMC_PROFILE_HDDVD_RW            0x0053
341 38cdea7c balrog
#define MMC_PROFILE_HDDVD_R_DL          0x0058
342 38cdea7c balrog
#define MMC_PROFILE_HDDVD_RW_DL         0x005A
343 38cdea7c balrog
#define MMC_PROFILE_INVALID             0xFFFF
344 38cdea7c balrog
345 5391d806 bellard
#define ATAPI_INT_REASON_CD             0x01 /* 0 = data transfer */
346 5391d806 bellard
#define ATAPI_INT_REASON_IO             0x02 /* 1 = transfer to the host */
347 5391d806 bellard
#define ATAPI_INT_REASON_REL            0x04
348 5391d806 bellard
#define ATAPI_INT_REASON_TAG            0xf8
349 5391d806 bellard
350 5391d806 bellard
/* same constants as bochs */
351 7f777bf3 bellard
#define ASC_ILLEGAL_OPCODE                   0x20
352 5391d806 bellard
#define ASC_LOGICAL_BLOCK_OOR                0x21
353 5391d806 bellard
#define ASC_INV_FIELD_IN_CMD_PACKET          0x24
354 8114e9e8 ths
#define ASC_INCOMPATIBLE_FORMAT              0x30
355 5391d806 bellard
#define ASC_MEDIUM_NOT_PRESENT               0x3a
356 5391d806 bellard
#define ASC_SAVING_PARAMETERS_NOT_SUPPORTED  0x39
357 5391d806 bellard
358 201a51fc balrog
#define CFA_NO_ERROR            0x00
359 201a51fc balrog
#define CFA_MISC_ERROR          0x09
360 201a51fc balrog
#define CFA_INVALID_COMMAND     0x20
361 201a51fc balrog
#define CFA_INVALID_ADDRESS     0x21
362 201a51fc balrog
#define CFA_ADDRESS_OVERFLOW    0x2f
363 201a51fc balrog
364 5391d806 bellard
#define SENSE_NONE            0
365 5391d806 bellard
#define SENSE_NOT_READY       2
366 5391d806 bellard
#define SENSE_ILLEGAL_REQUEST 5
367 5391d806 bellard
#define SENSE_UNIT_ATTENTION  6
368 5391d806 bellard
369 5391d806 bellard
struct IDEState;
370 5391d806 bellard
371 5391d806 bellard
typedef void EndTransferFunc(struct IDEState *);
372 5391d806 bellard
373 caed8802 bellard
/* NOTE: IDEState represents in fact one drive */
374 5391d806 bellard
typedef struct IDEState {
375 5391d806 bellard
    /* ide config */
376 5391d806 bellard
    int is_cdrom;
377 201a51fc balrog
    int is_cf;
378 5391d806 bellard
    int cylinders, heads, sectors;
379 5391d806 bellard
    int64_t nb_sectors;
380 5391d806 bellard
    int mult_sectors;
381 94458802 bellard
    int identify_set;
382 94458802 bellard
    uint16_t identify_data[256];
383 d537cf6c pbrook
    qemu_irq irq;
384 34e538ae bellard
    PCIDevice *pci_dev;
385 98087450 bellard
    struct BMDMAState *bmdma;
386 aedf5382 bellard
    int drive_serial;
387 5391d806 bellard
    /* ide regs */
388 5391d806 bellard
    uint8_t feature;
389 5391d806 bellard
    uint8_t error;
390 c2ff060f bellard
    uint32_t nsector;
391 5391d806 bellard
    uint8_t sector;
392 5391d806 bellard
    uint8_t lcyl;
393 5391d806 bellard
    uint8_t hcyl;
394 c2ff060f bellard
    /* other part of tf for lba48 support */
395 c2ff060f bellard
    uint8_t hob_feature;
396 c2ff060f bellard
    uint8_t hob_nsector;
397 c2ff060f bellard
    uint8_t hob_sector;
398 c2ff060f bellard
    uint8_t hob_lcyl;
399 c2ff060f bellard
    uint8_t hob_hcyl;
400 c2ff060f bellard
401 5391d806 bellard
    uint8_t select;
402 5391d806 bellard
    uint8_t status;
403 c2ff060f bellard
404 5391d806 bellard
    /* 0x3f6 command, only meaningful for drive 0 */
405 5391d806 bellard
    uint8_t cmd;
406 c2ff060f bellard
    /* set for lba48 access */
407 c2ff060f bellard
    uint8_t lba48;
408 5391d806 bellard
    /* depends on bit 4 in select, only meaningful for drive 0 */
409 5fafdf24 ths
    struct IDEState *cur_drive;
410 5391d806 bellard
    BlockDriverState *bs;
411 5391d806 bellard
    /* ATAPI specific */
412 5391d806 bellard
    uint8_t sense_key;
413 5391d806 bellard
    uint8_t asc;
414 5391d806 bellard
    int packet_transfer_size;
415 5391d806 bellard
    int elementary_transfer_size;
416 5391d806 bellard
    int io_buffer_index;
417 5391d806 bellard
    int lba;
418 98087450 bellard
    int cd_sector_size;
419 98087450 bellard
    int atapi_dma; /* true if dma is requested for the packet cmd */
420 98087450 bellard
    /* ATA DMA state */
421 98087450 bellard
    int io_buffer_size;
422 98087450 bellard
    /* PIO transfer handling */
423 5391d806 bellard
    int req_nb_sectors; /* number of sectors per interrupt */
424 5391d806 bellard
    EndTransferFunc *end_transfer_func;
425 5391d806 bellard
    uint8_t *data_ptr;
426 5391d806 bellard
    uint8_t *data_end;
427 33f00271 balrog
    uint8_t *io_buffer;
428 31c2a146 ths
    QEMUTimer *sector_write_timer; /* only used for win2k install hack */
429 e774a278 bellard
    uint32_t irq_count; /* counts IRQs when using win2k install hack */
430 201a51fc balrog
    /* CF-ATA extended error */
431 201a51fc balrog
    uint8_t ext_error;
432 201a51fc balrog
    /* CF-ATA metadata storage */
433 201a51fc balrog
    uint32_t mdata_size;
434 201a51fc balrog
    uint8_t *mdata_storage;
435 201a51fc balrog
    int media_changed;
436 5391d806 bellard
} IDEState;
437 5391d806 bellard
438 8114e9e8 ths
/* XXX: DVDs that could fit on a CD will be reported as a CD */
439 8114e9e8 ths
static inline int media_present(IDEState *s)
440 8114e9e8 ths
{
441 8114e9e8 ths
    return (s->nb_sectors > 0);
442 8114e9e8 ths
}
443 8114e9e8 ths
444 8114e9e8 ths
static inline int media_is_dvd(IDEState *s)
445 8114e9e8 ths
{
446 8114e9e8 ths
    return (media_present(s) && s->nb_sectors > CD_MAX_SECTORS);
447 8114e9e8 ths
}
448 8114e9e8 ths
449 8114e9e8 ths
static inline int media_is_cd(IDEState *s)
450 8114e9e8 ths
{
451 8114e9e8 ths
    return (media_present(s) && s->nb_sectors <= CD_MAX_SECTORS);
452 8114e9e8 ths
}
453 8114e9e8 ths
454 98087450 bellard
#define BM_STATUS_DMAING 0x01
455 98087450 bellard
#define BM_STATUS_ERROR  0x02
456 98087450 bellard
#define BM_STATUS_INT    0x04
457 98087450 bellard
458 98087450 bellard
#define BM_CMD_START     0x01
459 98087450 bellard
#define BM_CMD_READ      0x08
460 98087450 bellard
461 5457c8ce bellard
#define IDE_TYPE_PIIX3   0
462 5457c8ce bellard
#define IDE_TYPE_CMD646  1
463 afcc3cdf ths
#define IDE_TYPE_PIIX4   2
464 5457c8ce bellard
465 5457c8ce bellard
/* CMD646 specific */
466 5457c8ce bellard
#define MRDMODE                0x71
467 5457c8ce bellard
#define   MRDMODE_INTR_CH0        0x04
468 5457c8ce bellard
#define   MRDMODE_INTR_CH1        0x08
469 5457c8ce bellard
#define   MRDMODE_BLK_CH0        0x10
470 5457c8ce bellard
#define   MRDMODE_BLK_CH1        0x20
471 5457c8ce bellard
#define UDIDETCR0        0x73
472 5457c8ce bellard
#define UDIDETCR1        0x7B
473 5457c8ce bellard
474 98087450 bellard
typedef struct BMDMAState {
475 98087450 bellard
    uint8_t cmd;
476 98087450 bellard
    uint8_t status;
477 98087450 bellard
    uint32_t addr;
478 3b46e624 ths
479 5457c8ce bellard
    struct PCIIDEState *pci_dev;
480 98087450 bellard
    /* current transfer state */
481 8ccad811 bellard
    uint32_t cur_addr;
482 8ccad811 bellard
    uint32_t cur_prd_last;
483 8ccad811 bellard
    uint32_t cur_prd_addr;
484 8ccad811 bellard
    uint32_t cur_prd_len;
485 98087450 bellard
    IDEState *ide_if;
486 8ccad811 bellard
    BlockDriverCompletionFunc *dma_cb;
487 8ccad811 bellard
    BlockDriverAIOCB *aiocb;
488 98087450 bellard
} BMDMAState;
489 98087450 bellard
490 98087450 bellard
typedef struct PCIIDEState {
491 98087450 bellard
    PCIDevice dev;
492 98087450 bellard
    IDEState ide_if[4];
493 98087450 bellard
    BMDMAState bmdma[2];
494 5457c8ce bellard
    int type; /* see IDE_TYPE_xxx */
495 98087450 bellard
} PCIIDEState;
496 98087450 bellard
497 8ccad811 bellard
static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb);
498 5f12ab4b ths
static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret);
499 98087450 bellard
500 5391d806 bellard
static void padstr(char *str, const char *src, int len)
501 5391d806 bellard
{
502 5391d806 bellard
    int i, v;
503 5391d806 bellard
    for(i = 0; i < len; i++) {
504 5391d806 bellard
        if (*src)
505 5391d806 bellard
            v = *src++;
506 5391d806 bellard
        else
507 5391d806 bellard
            v = ' ';
508 69b34976 ths
        str[i^1] = v;
509 5391d806 bellard
    }
510 5391d806 bellard
}
511 5391d806 bellard
512 bd0d90b2 bellard
static void padstr8(uint8_t *buf, int buf_size, const char *src)
513 bd0d90b2 bellard
{
514 bd0d90b2 bellard
    int i;
515 bd0d90b2 bellard
    for(i = 0; i < buf_size; i++) {
516 bd0d90b2 bellard
        if (*src)
517 bd0d90b2 bellard
            buf[i] = *src++;
518 bd0d90b2 bellard
        else
519 bd0d90b2 bellard
            buf[i] = ' ';
520 bd0d90b2 bellard
    }
521 bd0d90b2 bellard
}
522 bd0d90b2 bellard
523 67b915a5 bellard
static void put_le16(uint16_t *p, unsigned int v)
524 67b915a5 bellard
{
525 0c4ad8dc bellard
    *p = cpu_to_le16(v);
526 67b915a5 bellard
}
527 67b915a5 bellard
528 5391d806 bellard
static void ide_identify(IDEState *s)
529 5391d806 bellard
{
530 5391d806 bellard
    uint16_t *p;
531 5391d806 bellard
    unsigned int oldsize;
532 aedf5382 bellard
    char buf[20];
533 5391d806 bellard
534 94458802 bellard
    if (s->identify_set) {
535 94458802 bellard
        memcpy(s->io_buffer, s->identify_data, sizeof(s->identify_data));
536 94458802 bellard
        return;
537 94458802 bellard
    }
538 94458802 bellard
539 5391d806 bellard
    memset(s->io_buffer, 0, 512);
540 5391d806 bellard
    p = (uint16_t *)s->io_buffer;
541 67b915a5 bellard
    put_le16(p + 0, 0x0040);
542 5fafdf24 ths
    put_le16(p + 1, s->cylinders);
543 67b915a5 bellard
    put_le16(p + 3, s->heads);
544 67b915a5 bellard
    put_le16(p + 4, 512 * s->sectors); /* XXX: retired, remove ? */
545 67b915a5 bellard
    put_le16(p + 5, 512); /* XXX: retired, remove ? */
546 5fafdf24 ths
    put_le16(p + 6, s->sectors);
547 aedf5382 bellard
    snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial);
548 60fe76f3 ths
    padstr((char *)(p + 10), buf, 20); /* serial number */
549 67b915a5 bellard
    put_le16(p + 20, 3); /* XXX: retired, remove ? */
550 67b915a5 bellard
    put_le16(p + 21, 512); /* cache size in sectors */
551 67b915a5 bellard
    put_le16(p + 22, 4); /* ecc bytes */
552 60fe76f3 ths
    padstr((char *)(p + 23), QEMU_VERSION, 8); /* firmware version */
553 60fe76f3 ths
    padstr((char *)(p + 27), "QEMU HARDDISK", 40); /* model */
554 3b46e624 ths
#if MAX_MULT_SECTORS > 1
555 67b915a5 bellard
    put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
556 5391d806 bellard
#endif
557 67b915a5 bellard
    put_le16(p + 48, 1); /* dword I/O */
558 94458802 bellard
    put_le16(p + 49, (1 << 11) | (1 << 9) | (1 << 8)); /* DMA and LBA supported */
559 67b915a5 bellard
    put_le16(p + 51, 0x200); /* PIO transfer cycle */
560 67b915a5 bellard
    put_le16(p + 52, 0x200); /* DMA transfer cycle */
561 94458802 bellard
    put_le16(p + 53, 1 | (1 << 1) | (1 << 2)); /* words 54-58,64-70,88 are valid */
562 67b915a5 bellard
    put_le16(p + 54, s->cylinders);
563 67b915a5 bellard
    put_le16(p + 55, s->heads);
564 67b915a5 bellard
    put_le16(p + 56, s->sectors);
565 5391d806 bellard
    oldsize = s->cylinders * s->heads * s->sectors;
566 67b915a5 bellard
    put_le16(p + 57, oldsize);
567 67b915a5 bellard
    put_le16(p + 58, oldsize >> 16);
568 5391d806 bellard
    if (s->mult_sectors)
569 67b915a5 bellard
        put_le16(p + 59, 0x100 | s->mult_sectors);
570 67b915a5 bellard
    put_le16(p + 60, s->nb_sectors);
571 67b915a5 bellard
    put_le16(p + 61, s->nb_sectors >> 16);
572 d1b5c20d ths
    put_le16(p + 62, 0x07); /* single word dma0-2 supported */
573 94458802 bellard
    put_le16(p + 63, 0x07); /* mdma0-2 supported */
574 94458802 bellard
    put_le16(p + 65, 120);
575 94458802 bellard
    put_le16(p + 66, 120);
576 94458802 bellard
    put_le16(p + 67, 120);
577 94458802 bellard
    put_le16(p + 68, 120);
578 94458802 bellard
    put_le16(p + 80, 0xf0); /* ata3 -> ata6 supported */
579 94458802 bellard
    put_le16(p + 81, 0x16); /* conforms to ata5 */
580 67b915a5 bellard
    put_le16(p + 82, (1 << 14));
581 c2ff060f bellard
    /* 13=flush_cache_ext,12=flush_cache,10=lba48 */
582 c2ff060f bellard
    put_le16(p + 83, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10));
583 67b915a5 bellard
    put_le16(p + 84, (1 << 14));
584 67b915a5 bellard
    put_le16(p + 85, (1 << 14));
585 c2ff060f bellard
    /* 13=flush_cache_ext,12=flush_cache,10=lba48 */
586 c2ff060f bellard
    put_le16(p + 86, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10));
587 67b915a5 bellard
    put_le16(p + 87, (1 << 14));
588 94458802 bellard
    put_le16(p + 88, 0x3f | (1 << 13)); /* udma5 set and supported */
589 94458802 bellard
    put_le16(p + 93, 1 | (1 << 14) | 0x2000);
590 c2ff060f bellard
    put_le16(p + 100, s->nb_sectors);
591 c2ff060f bellard
    put_le16(p + 101, s->nb_sectors >> 16);
592 c2ff060f bellard
    put_le16(p + 102, s->nb_sectors >> 32);
593 c2ff060f bellard
    put_le16(p + 103, s->nb_sectors >> 48);
594 94458802 bellard
595 94458802 bellard
    memcpy(s->identify_data, p, sizeof(s->identify_data));
596 94458802 bellard
    s->identify_set = 1;
597 5391d806 bellard
}
598 5391d806 bellard
599 5391d806 bellard
static void ide_atapi_identify(IDEState *s)
600 5391d806 bellard
{
601 5391d806 bellard
    uint16_t *p;
602 aedf5382 bellard
    char buf[20];
603 5391d806 bellard
604 94458802 bellard
    if (s->identify_set) {
605 94458802 bellard
        memcpy(s->io_buffer, s->identify_data, sizeof(s->identify_data));
606 94458802 bellard
        return;
607 94458802 bellard
    }
608 94458802 bellard
609 5391d806 bellard
    memset(s->io_buffer, 0, 512);
610 5391d806 bellard
    p = (uint16_t *)s->io_buffer;
611 5391d806 bellard
    /* Removable CDROM, 50us response, 12 byte packets */
612 67b915a5 bellard
    put_le16(p + 0, (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0));
613 aedf5382 bellard
    snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial);
614 60fe76f3 ths
    padstr((char *)(p + 10), buf, 20); /* serial number */
615 67b915a5 bellard
    put_le16(p + 20, 3); /* buffer type */
616 67b915a5 bellard
    put_le16(p + 21, 512); /* cache size in sectors */
617 67b915a5 bellard
    put_le16(p + 22, 4); /* ecc bytes */
618 60fe76f3 ths
    padstr((char *)(p + 23), QEMU_VERSION, 8); /* firmware version */
619 38cdea7c balrog
    padstr((char *)(p + 27), "QEMU DVD-ROM", 40); /* model */
620 67b915a5 bellard
    put_le16(p + 48, 1); /* dword I/O (XXX: should not be set on CDROM) */
621 8ccad811 bellard
#ifdef USE_DMA_CDROM
622 8ccad811 bellard
    put_le16(p + 49, 1 << 9 | 1 << 8); /* DMA and LBA supported */
623 8ccad811 bellard
    put_le16(p + 53, 7); /* words 64-70, 54-58, 88 valid */
624 d1b5c20d ths
    put_le16(p + 62, 7);  /* single word dma0-2 supported */
625 8ccad811 bellard
    put_le16(p + 63, 7);  /* mdma0-2 supported */
626 8ccad811 bellard
    put_le16(p + 64, 0x3f); /* PIO modes supported */
627 8ccad811 bellard
#else
628 67b915a5 bellard
    put_le16(p + 49, 1 << 9); /* LBA supported, no DMA */
629 67b915a5 bellard
    put_le16(p + 53, 3); /* words 64-70, 54-58 valid */
630 67b915a5 bellard
    put_le16(p + 63, 0x103); /* DMA modes XXX: may be incorrect */
631 67b915a5 bellard
    put_le16(p + 64, 1); /* PIO modes */
632 8ccad811 bellard
#endif
633 67b915a5 bellard
    put_le16(p + 65, 0xb4); /* minimum DMA multiword tx cycle time */
634 67b915a5 bellard
    put_le16(p + 66, 0xb4); /* recommended DMA multiword tx cycle time */
635 67b915a5 bellard
    put_le16(p + 67, 0x12c); /* minimum PIO cycle time without flow control */
636 67b915a5 bellard
    put_le16(p + 68, 0xb4); /* minimum PIO cycle time with IORDY flow control */
637 94458802 bellard
638 67b915a5 bellard
    put_le16(p + 71, 30); /* in ns */
639 67b915a5 bellard
    put_le16(p + 72, 30); /* in ns */
640 5391d806 bellard
641 67b915a5 bellard
    put_le16(p + 80, 0x1e); /* support up to ATA/ATAPI-4 */
642 8ccad811 bellard
#ifdef USE_DMA_CDROM
643 8ccad811 bellard
    put_le16(p + 88, 0x3f | (1 << 13)); /* udma5 set and supported */
644 8ccad811 bellard
#endif
645 94458802 bellard
    memcpy(s->identify_data, p, sizeof(s->identify_data));
646 94458802 bellard
    s->identify_set = 1;
647 5391d806 bellard
}
648 5391d806 bellard
649 201a51fc balrog
static void ide_cfata_identify(IDEState *s)
650 201a51fc balrog
{
651 201a51fc balrog
    uint16_t *p;
652 201a51fc balrog
    uint32_t cur_sec;
653 201a51fc balrog
    char buf[20];
654 201a51fc balrog
655 201a51fc balrog
    p = (uint16_t *) s->identify_data;
656 201a51fc balrog
    if (s->identify_set)
657 201a51fc balrog
        goto fill_buffer;
658 201a51fc balrog
659 201a51fc balrog
    memset(p, 0, sizeof(s->identify_data));
660 201a51fc balrog
661 201a51fc balrog
    cur_sec = s->cylinders * s->heads * s->sectors;
662 201a51fc balrog
663 201a51fc balrog
    put_le16(p + 0, 0x848a);                        /* CF Storage Card signature */
664 201a51fc balrog
    put_le16(p + 1, s->cylinders);                /* Default cylinders */
665 201a51fc balrog
    put_le16(p + 3, s->heads);                        /* Default heads */
666 201a51fc balrog
    put_le16(p + 6, s->sectors);                /* Default sectors per track */
667 201a51fc balrog
    put_le16(p + 7, s->nb_sectors >> 16);        /* Sectors per card */
668 201a51fc balrog
    put_le16(p + 8, s->nb_sectors);                /* Sectors per card */
669 201a51fc balrog
    snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial);
670 60fe76f3 ths
    padstr((char *)(p + 10), buf, 20);        /* Serial number in ASCII */
671 201a51fc balrog
    put_le16(p + 22, 0x0004);                        /* ECC bytes */
672 60fe76f3 ths
    padstr((char *) (p + 23), QEMU_VERSION, 8);        /* Firmware Revision */
673 60fe76f3 ths
    padstr((char *) (p + 27), "QEMU MICRODRIVE", 40);/* Model number */
674 201a51fc balrog
#if MAX_MULT_SECTORS > 1
675 201a51fc balrog
    put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
676 201a51fc balrog
#else
677 201a51fc balrog
    put_le16(p + 47, 0x0000);
678 201a51fc balrog
#endif
679 201a51fc balrog
    put_le16(p + 49, 0x0f00);                        /* Capabilities */
680 201a51fc balrog
    put_le16(p + 51, 0x0002);                        /* PIO cycle timing mode */
681 201a51fc balrog
    put_le16(p + 52, 0x0001);                        /* DMA cycle timing mode */
682 201a51fc balrog
    put_le16(p + 53, 0x0003);                        /* Translation params valid */
683 201a51fc balrog
    put_le16(p + 54, s->cylinders);                /* Current cylinders */
684 201a51fc balrog
    put_le16(p + 55, s->heads);                        /* Current heads */
685 201a51fc balrog
    put_le16(p + 56, s->sectors);                /* Current sectors */
686 201a51fc balrog
    put_le16(p + 57, cur_sec);                        /* Current capacity */
687 201a51fc balrog
    put_le16(p + 58, cur_sec >> 16);                /* Current capacity */
688 201a51fc balrog
    if (s->mult_sectors)                        /* Multiple sector setting */
689 201a51fc balrog
        put_le16(p + 59, 0x100 | s->mult_sectors);
690 201a51fc balrog
    put_le16(p + 60, s->nb_sectors);                /* Total LBA sectors */
691 201a51fc balrog
    put_le16(p + 61, s->nb_sectors >> 16);        /* Total LBA sectors */
692 201a51fc balrog
    put_le16(p + 63, 0x0203);                        /* Multiword DMA capability */
693 201a51fc balrog
    put_le16(p + 64, 0x0001);                        /* Flow Control PIO support */
694 201a51fc balrog
    put_le16(p + 65, 0x0096);                        /* Min. Multiword DMA cycle */
695 201a51fc balrog
    put_le16(p + 66, 0x0096);                        /* Rec. Multiword DMA cycle */
696 201a51fc balrog
    put_le16(p + 68, 0x00b4);                        /* Min. PIO cycle time */
697 201a51fc balrog
    put_le16(p + 82, 0x400c);                        /* Command Set supported */
698 201a51fc balrog
    put_le16(p + 83, 0x7068);                        /* Command Set supported */
699 201a51fc balrog
    put_le16(p + 84, 0x4000);                        /* Features supported */
700 201a51fc balrog
    put_le16(p + 85, 0x000c);                        /* Command Set enabled */
701 201a51fc balrog
    put_le16(p + 86, 0x7044);                        /* Command Set enabled */
702 201a51fc balrog
    put_le16(p + 87, 0x4000);                        /* Features enabled */
703 201a51fc balrog
    put_le16(p + 91, 0x4060);                        /* Current APM level */
704 201a51fc balrog
    put_le16(p + 129, 0x0002);                        /* Current features option */
705 201a51fc balrog
    put_le16(p + 130, 0x0005);                        /* Reassigned sectors */
706 201a51fc balrog
    put_le16(p + 131, 0x0001);                        /* Initial power mode */
707 201a51fc balrog
    put_le16(p + 132, 0x0000);                        /* User signature */
708 201a51fc balrog
    put_le16(p + 160, 0x8100);                        /* Power requirement */
709 201a51fc balrog
    put_le16(p + 161, 0x8001);                        /* CF command set */
710 201a51fc balrog
711 201a51fc balrog
    s->identify_set = 1;
712 201a51fc balrog
713 201a51fc balrog
fill_buffer:
714 201a51fc balrog
    memcpy(s->io_buffer, p, sizeof(s->identify_data));
715 201a51fc balrog
}
716 201a51fc balrog
717 5391d806 bellard
static void ide_set_signature(IDEState *s)
718 5391d806 bellard
{
719 5391d806 bellard
    s->select &= 0xf0; /* clear head */
720 5391d806 bellard
    /* put signature */
721 5391d806 bellard
    s->nsector = 1;
722 5391d806 bellard
    s->sector = 1;
723 5391d806 bellard
    if (s->is_cdrom) {
724 5391d806 bellard
        s->lcyl = 0x14;
725 5391d806 bellard
        s->hcyl = 0xeb;
726 5391d806 bellard
    } else if (s->bs) {
727 5391d806 bellard
        s->lcyl = 0;
728 5391d806 bellard
        s->hcyl = 0;
729 5391d806 bellard
    } else {
730 5391d806 bellard
        s->lcyl = 0xff;
731 5391d806 bellard
        s->hcyl = 0xff;
732 5391d806 bellard
    }
733 5391d806 bellard
}
734 5391d806 bellard
735 5391d806 bellard
static inline void ide_abort_command(IDEState *s)
736 5391d806 bellard
{
737 5391d806 bellard
    s->status = READY_STAT | ERR_STAT;
738 5391d806 bellard
    s->error = ABRT_ERR;
739 5391d806 bellard
}
740 5391d806 bellard
741 5391d806 bellard
static inline void ide_set_irq(IDEState *s)
742 5391d806 bellard
{
743 98ff7d30 bellard
    BMDMAState *bm = s->bmdma;
744 5391d806 bellard
    if (!(s->cmd & IDE_CMD_DISABLE_IRQ)) {
745 5457c8ce bellard
        if (bm) {
746 98ff7d30 bellard
            bm->status |= BM_STATUS_INT;
747 5457c8ce bellard
        }
748 d537cf6c pbrook
        qemu_irq_raise(s->irq);
749 5391d806 bellard
    }
750 5391d806 bellard
}
751 5391d806 bellard
752 5391d806 bellard
/* prepare data transfer and tell what to do after */
753 5fafdf24 ths
static void ide_transfer_start(IDEState *s, uint8_t *buf, int size,
754 5391d806 bellard
                               EndTransferFunc *end_transfer_func)
755 5391d806 bellard
{
756 5391d806 bellard
    s->end_transfer_func = end_transfer_func;
757 5391d806 bellard
    s->data_ptr = buf;
758 5391d806 bellard
    s->data_end = buf + size;
759 7603d156 ths
    if (!(s->status & ERR_STAT))
760 7603d156 ths
        s->status |= DRQ_STAT;
761 5391d806 bellard
}
762 5391d806 bellard
763 5391d806 bellard
static void ide_transfer_stop(IDEState *s)
764 5391d806 bellard
{
765 5391d806 bellard
    s->end_transfer_func = ide_transfer_stop;
766 5391d806 bellard
    s->data_ptr = s->io_buffer;
767 5391d806 bellard
    s->data_end = s->io_buffer;
768 5391d806 bellard
    s->status &= ~DRQ_STAT;
769 5391d806 bellard
}
770 5391d806 bellard
771 5391d806 bellard
static int64_t ide_get_sector(IDEState *s)
772 5391d806 bellard
{
773 5391d806 bellard
    int64_t sector_num;
774 5391d806 bellard
    if (s->select & 0x40) {
775 5391d806 bellard
        /* lba */
776 c2ff060f bellard
        if (!s->lba48) {
777 c2ff060f bellard
            sector_num = ((s->select & 0x0f) << 24) | (s->hcyl << 16) |
778 c2ff060f bellard
                (s->lcyl << 8) | s->sector;
779 c2ff060f bellard
        } else {
780 c2ff060f bellard
            sector_num = ((int64_t)s->hob_hcyl << 40) |
781 c2ff060f bellard
                ((int64_t) s->hob_lcyl << 32) |
782 c2ff060f bellard
                ((int64_t) s->hob_sector << 24) |
783 c2ff060f bellard
                ((int64_t) s->hcyl << 16) |
784 c2ff060f bellard
                ((int64_t) s->lcyl << 8) | s->sector;
785 c2ff060f bellard
        }
786 5391d806 bellard
    } else {
787 5391d806 bellard
        sector_num = ((s->hcyl << 8) | s->lcyl) * s->heads * s->sectors +
788 c2ff060f bellard
            (s->select & 0x0f) * s->sectors + (s->sector - 1);
789 5391d806 bellard
    }
790 5391d806 bellard
    return sector_num;
791 5391d806 bellard
}
792 5391d806 bellard
793 5391d806 bellard
static void ide_set_sector(IDEState *s, int64_t sector_num)
794 5391d806 bellard
{
795 5391d806 bellard
    unsigned int cyl, r;
796 5391d806 bellard
    if (s->select & 0x40) {
797 c2ff060f bellard
        if (!s->lba48) {
798 c2ff060f bellard
            s->select = (s->select & 0xf0) | (sector_num >> 24);
799 c2ff060f bellard
            s->hcyl = (sector_num >> 16);
800 c2ff060f bellard
            s->lcyl = (sector_num >> 8);
801 c2ff060f bellard
            s->sector = (sector_num);
802 c2ff060f bellard
        } else {
803 c2ff060f bellard
            s->sector = sector_num;
804 c2ff060f bellard
            s->lcyl = sector_num >> 8;
805 c2ff060f bellard
            s->hcyl = sector_num >> 16;
806 c2ff060f bellard
            s->hob_sector = sector_num >> 24;
807 c2ff060f bellard
            s->hob_lcyl = sector_num >> 32;
808 c2ff060f bellard
            s->hob_hcyl = sector_num >> 40;
809 c2ff060f bellard
        }
810 5391d806 bellard
    } else {
811 5391d806 bellard
        cyl = sector_num / (s->heads * s->sectors);
812 5391d806 bellard
        r = sector_num % (s->heads * s->sectors);
813 5391d806 bellard
        s->hcyl = cyl >> 8;
814 5391d806 bellard
        s->lcyl = cyl;
815 1b8eb456 bellard
        s->select = (s->select & 0xf0) | ((r / s->sectors) & 0x0f);
816 5391d806 bellard
        s->sector = (r % s->sectors) + 1;
817 5391d806 bellard
    }
818 5391d806 bellard
}
819 5391d806 bellard
820 5391d806 bellard
static void ide_sector_read(IDEState *s)
821 5391d806 bellard
{
822 5391d806 bellard
    int64_t sector_num;
823 5391d806 bellard
    int ret, n;
824 5391d806 bellard
825 5391d806 bellard
    s->status = READY_STAT | SEEK_STAT;
826 a136e5a8 bellard
    s->error = 0; /* not needed by IDE spec, but needed by Windows */
827 5391d806 bellard
    sector_num = ide_get_sector(s);
828 5391d806 bellard
    n = s->nsector;
829 5391d806 bellard
    if (n == 0) {
830 5391d806 bellard
        /* no more sector to read from disk */
831 5391d806 bellard
        ide_transfer_stop(s);
832 5391d806 bellard
    } else {
833 5391d806 bellard
#if defined(DEBUG_IDE)
834 5391d806 bellard
        printf("read sector=%Ld\n", sector_num);
835 5391d806 bellard
#endif
836 5391d806 bellard
        if (n > s->req_nb_sectors)
837 5391d806 bellard
            n = s->req_nb_sectors;
838 5391d806 bellard
        ret = bdrv_read(s->bs, sector_num, s->io_buffer, n);
839 5391d806 bellard
        ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_read);
840 5391d806 bellard
        ide_set_irq(s);
841 5391d806 bellard
        ide_set_sector(s, sector_num + n);
842 5391d806 bellard
        s->nsector -= n;
843 5391d806 bellard
    }
844 5391d806 bellard
}
845 5391d806 bellard
846 8ccad811 bellard
/* return 0 if buffer completed */
847 8ccad811 bellard
static int dma_buf_rw(BMDMAState *bm, int is_write)
848 98087450 bellard
{
849 8ccad811 bellard
    IDEState *s = bm->ide_if;
850 8ccad811 bellard
    struct {
851 8ccad811 bellard
        uint32_t addr;
852 8ccad811 bellard
        uint32_t size;
853 8ccad811 bellard
    } prd;
854 8ccad811 bellard
    int l, len;
855 98087450 bellard
856 8ccad811 bellard
    for(;;) {
857 8ccad811 bellard
        l = s->io_buffer_size - s->io_buffer_index;
858 5fafdf24 ths
        if (l <= 0)
859 8ccad811 bellard
            break;
860 8ccad811 bellard
        if (bm->cur_prd_len == 0) {
861 8ccad811 bellard
            /* end of table (with a fail safe of one page) */
862 8ccad811 bellard
            if (bm->cur_prd_last ||
863 8ccad811 bellard
                (bm->cur_addr - bm->addr) >= 4096)
864 8ccad811 bellard
                return 0;
865 8ccad811 bellard
            cpu_physical_memory_read(bm->cur_addr, (uint8_t *)&prd, 8);
866 8ccad811 bellard
            bm->cur_addr += 8;
867 8ccad811 bellard
            prd.addr = le32_to_cpu(prd.addr);
868 8ccad811 bellard
            prd.size = le32_to_cpu(prd.size);
869 8ccad811 bellard
            len = prd.size & 0xfffe;
870 8ccad811 bellard
            if (len == 0)
871 8ccad811 bellard
                len = 0x10000;
872 8ccad811 bellard
            bm->cur_prd_len = len;
873 8ccad811 bellard
            bm->cur_prd_addr = prd.addr;
874 8ccad811 bellard
            bm->cur_prd_last = (prd.size & 0x80000000);
875 8ccad811 bellard
        }
876 8ccad811 bellard
        if (l > bm->cur_prd_len)
877 8ccad811 bellard
            l = bm->cur_prd_len;
878 8ccad811 bellard
        if (l > 0) {
879 8ccad811 bellard
            if (is_write) {
880 5fafdf24 ths
                cpu_physical_memory_write(bm->cur_prd_addr,
881 8ccad811 bellard
                                          s->io_buffer + s->io_buffer_index, l);
882 8ccad811 bellard
            } else {
883 5fafdf24 ths
                cpu_physical_memory_read(bm->cur_prd_addr,
884 8ccad811 bellard
                                          s->io_buffer + s->io_buffer_index, l);
885 8ccad811 bellard
            }
886 8ccad811 bellard
            bm->cur_prd_addr += l;
887 8ccad811 bellard
            bm->cur_prd_len -= l;
888 8ccad811 bellard
            s->io_buffer_index += l;
889 98087450 bellard
        }
890 98087450 bellard
    }
891 8ccad811 bellard
    return 1;
892 8ccad811 bellard
}
893 8ccad811 bellard
894 8ccad811 bellard
/* XXX: handle errors */
895 8ccad811 bellard
static void ide_read_dma_cb(void *opaque, int ret)
896 8ccad811 bellard
{
897 8ccad811 bellard
    BMDMAState *bm = opaque;
898 8ccad811 bellard
    IDEState *s = bm->ide_if;
899 8ccad811 bellard
    int n;
900 8ccad811 bellard
    int64_t sector_num;
901 8ccad811 bellard
902 8ccad811 bellard
    n = s->io_buffer_size >> 9;
903 8ccad811 bellard
    sector_num = ide_get_sector(s);
904 8ccad811 bellard
    if (n > 0) {
905 8ccad811 bellard
        sector_num += n;
906 8ccad811 bellard
        ide_set_sector(s, sector_num);
907 8ccad811 bellard
        s->nsector -= n;
908 8ccad811 bellard
        if (dma_buf_rw(bm, 1) == 0)
909 8ccad811 bellard
            goto eot;
910 8ccad811 bellard
    }
911 8ccad811 bellard
912 8ccad811 bellard
    /* end of transfer ? */
913 8ccad811 bellard
    if (s->nsector == 0) {
914 98087450 bellard
        s->status = READY_STAT | SEEK_STAT;
915 98087450 bellard
        ide_set_irq(s);
916 8ccad811 bellard
    eot:
917 8ccad811 bellard
        bm->status &= ~BM_STATUS_DMAING;
918 8ccad811 bellard
        bm->status |= BM_STATUS_INT;
919 8ccad811 bellard
        bm->dma_cb = NULL;
920 8ccad811 bellard
        bm->ide_if = NULL;
921 8ccad811 bellard
        bm->aiocb = NULL;
922 8ccad811 bellard
        return;
923 98087450 bellard
    }
924 8ccad811 bellard
925 8ccad811 bellard
    /* launch next transfer */
926 8ccad811 bellard
    n = s->nsector;
927 1d8cde5b aurel32
    if (n > IDE_DMA_BUF_SECTORS)
928 1d8cde5b aurel32
        n = IDE_DMA_BUF_SECTORS;
929 8ccad811 bellard
    s->io_buffer_index = 0;
930 8ccad811 bellard
    s->io_buffer_size = n * 512;
931 8ccad811 bellard
#ifdef DEBUG_AIO
932 8ccad811 bellard
    printf("aio_read: sector_num=%lld n=%d\n", sector_num, n);
933 8ccad811 bellard
#endif
934 5fafdf24 ths
    bm->aiocb = bdrv_aio_read(s->bs, sector_num, s->io_buffer, n,
935 8ccad811 bellard
                              ide_read_dma_cb, bm);
936 98087450 bellard
}
937 98087450 bellard
938 98087450 bellard
static void ide_sector_read_dma(IDEState *s)
939 98087450 bellard
{
940 8ccad811 bellard
    s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
941 98087450 bellard
    s->io_buffer_index = 0;
942 98087450 bellard
    s->io_buffer_size = 0;
943 98087450 bellard
    ide_dma_start(s, ide_read_dma_cb);
944 98087450 bellard
}
945 98087450 bellard
946 a09db21f bellard
static void ide_sector_write_timer_cb(void *opaque)
947 a09db21f bellard
{
948 a09db21f bellard
    IDEState *s = opaque;
949 a09db21f bellard
    ide_set_irq(s);
950 a09db21f bellard
}
951 a09db21f bellard
952 5391d806 bellard
static void ide_sector_write(IDEState *s)
953 5391d806 bellard
{
954 5391d806 bellard
    int64_t sector_num;
955 31c2a146 ths
    int ret, n, n1;
956 5391d806 bellard
957 5391d806 bellard
    s->status = READY_STAT | SEEK_STAT;
958 5391d806 bellard
    sector_num = ide_get_sector(s);
959 5391d806 bellard
#if defined(DEBUG_IDE)
960 5391d806 bellard
    printf("write sector=%Ld\n", sector_num);
961 5391d806 bellard
#endif
962 5391d806 bellard
    n = s->nsector;
963 5391d806 bellard
    if (n > s->req_nb_sectors)
964 5391d806 bellard
        n = s->req_nb_sectors;
965 31c2a146 ths
    ret = bdrv_write(s->bs, sector_num, s->io_buffer, n);
966 5391d806 bellard
    s->nsector -= n;
967 5391d806 bellard
    if (s->nsector == 0) {
968 292eef5a ths
        /* no more sectors to write */
969 5391d806 bellard
        ide_transfer_stop(s);
970 5391d806 bellard
    } else {
971 5391d806 bellard
        n1 = s->nsector;
972 5391d806 bellard
        if (n1 > s->req_nb_sectors)
973 5391d806 bellard
            n1 = s->req_nb_sectors;
974 5391d806 bellard
        ide_transfer_start(s, s->io_buffer, 512 * n1, ide_sector_write);
975 5391d806 bellard
    }
976 5391d806 bellard
    ide_set_sector(s, sector_num + n);
977 3b46e624 ths
978 31c2a146 ths
#ifdef TARGET_I386
979 31c2a146 ths
    if (win2k_install_hack && ((++s->irq_count % 16) == 0)) {
980 31c2a146 ths
        /* It seems there is a bug in the Windows 2000 installer HDD
981 31c2a146 ths
           IDE driver which fills the disk with empty logs when the
982 31c2a146 ths
           IDE write IRQ comes too early. This hack tries to correct
983 31c2a146 ths
           that at the expense of slower write performances. Use this
984 31c2a146 ths
           option _only_ to install Windows 2000. You must disable it
985 31c2a146 ths
           for normal use. */
986 31c2a146 ths
        qemu_mod_timer(s->sector_write_timer, 
987 31c2a146 ths
                       qemu_get_clock(vm_clock) + (ticks_per_sec / 1000));
988 31c2a146 ths
    } else 
989 31c2a146 ths
#endif
990 31c2a146 ths
    {
991 31c2a146 ths
        ide_set_irq(s);
992 31c2a146 ths
    }
993 5391d806 bellard
}
994 5391d806 bellard
995 8ccad811 bellard
/* XXX: handle errors */
996 8ccad811 bellard
static void ide_write_dma_cb(void *opaque, int ret)
997 98087450 bellard
{
998 8ccad811 bellard
    BMDMAState *bm = opaque;
999 8ccad811 bellard
    IDEState *s = bm->ide_if;
1000 8ccad811 bellard
    int n;
1001 98087450 bellard
    int64_t sector_num;
1002 98087450 bellard
1003 8ccad811 bellard
    n = s->io_buffer_size >> 9;
1004 8ccad811 bellard
    sector_num = ide_get_sector(s);
1005 8ccad811 bellard
    if (n > 0) {
1006 8ccad811 bellard
        sector_num += n;
1007 8ccad811 bellard
        ide_set_sector(s, sector_num);
1008 8ccad811 bellard
        s->nsector -= n;
1009 98087450 bellard
    }
1010 98087450 bellard
1011 8ccad811 bellard
    /* end of transfer ? */
1012 8ccad811 bellard
    if (s->nsector == 0) {
1013 8ccad811 bellard
        s->status = READY_STAT | SEEK_STAT;
1014 8ccad811 bellard
        ide_set_irq(s);
1015 8ccad811 bellard
    eot:
1016 8ccad811 bellard
        bm->status &= ~BM_STATUS_DMAING;
1017 8ccad811 bellard
        bm->status |= BM_STATUS_INT;
1018 8ccad811 bellard
        bm->dma_cb = NULL;
1019 8ccad811 bellard
        bm->ide_if = NULL;
1020 8ccad811 bellard
        bm->aiocb = NULL;
1021 8ccad811 bellard
        return;
1022 8ccad811 bellard
    }
1023 8ccad811 bellard
1024 8ccad811 bellard
    /* launch next transfer */
1025 98087450 bellard
    n = s->nsector;
1026 1d8cde5b aurel32
    if (n > IDE_DMA_BUF_SECTORS)
1027 1d8cde5b aurel32
        n = IDE_DMA_BUF_SECTORS;
1028 98087450 bellard
    s->io_buffer_index = 0;
1029 98087450 bellard
    s->io_buffer_size = n * 512;
1030 8ccad811 bellard
1031 8ccad811 bellard
    if (dma_buf_rw(bm, 0) == 0)
1032 8ccad811 bellard
        goto eot;
1033 8ccad811 bellard
#ifdef DEBUG_AIO
1034 8ccad811 bellard
    printf("aio_write: sector_num=%lld n=%d\n", sector_num, n);
1035 8ccad811 bellard
#endif
1036 5fafdf24 ths
    bm->aiocb = bdrv_aio_write(s->bs, sector_num, s->io_buffer, n,
1037 8ccad811 bellard
                               ide_write_dma_cb, bm);
1038 8ccad811 bellard
}
1039 8ccad811 bellard
1040 8ccad811 bellard
static void ide_sector_write_dma(IDEState *s)
1041 8ccad811 bellard
{
1042 8ccad811 bellard
    s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
1043 8ccad811 bellard
    s->io_buffer_index = 0;
1044 8ccad811 bellard
    s->io_buffer_size = 0;
1045 98087450 bellard
    ide_dma_start(s, ide_write_dma_cb);
1046 98087450 bellard
}
1047 98087450 bellard
1048 5391d806 bellard
static void ide_atapi_cmd_ok(IDEState *s)
1049 5391d806 bellard
{
1050 5391d806 bellard
    s->error = 0;
1051 41a2b959 aliguori
    s->status = READY_STAT | SEEK_STAT;
1052 5391d806 bellard
    s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
1053 5391d806 bellard
    ide_set_irq(s);
1054 5391d806 bellard
}
1055 5391d806 bellard
1056 5391d806 bellard
static void ide_atapi_cmd_error(IDEState *s, int sense_key, int asc)
1057 5391d806 bellard
{
1058 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
1059 5391d806 bellard
    printf("atapi_cmd_error: sense=0x%x asc=0x%x\n", sense_key, asc);
1060 5391d806 bellard
#endif
1061 5391d806 bellard
    s->error = sense_key << 4;
1062 5391d806 bellard
    s->status = READY_STAT | ERR_STAT;
1063 5391d806 bellard
    s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
1064 5391d806 bellard
    s->sense_key = sense_key;
1065 5391d806 bellard
    s->asc = asc;
1066 5391d806 bellard
    ide_set_irq(s);
1067 5391d806 bellard
}
1068 5391d806 bellard
1069 5391d806 bellard
static inline void cpu_to_ube16(uint8_t *buf, int val)
1070 5391d806 bellard
{
1071 5391d806 bellard
    buf[0] = val >> 8;
1072 5391d806 bellard
    buf[1] = val;
1073 5391d806 bellard
}
1074 5391d806 bellard
1075 5391d806 bellard
static inline void cpu_to_ube32(uint8_t *buf, unsigned int val)
1076 5391d806 bellard
{
1077 5391d806 bellard
    buf[0] = val >> 24;
1078 5391d806 bellard
    buf[1] = val >> 16;
1079 5391d806 bellard
    buf[2] = val >> 8;
1080 5391d806 bellard
    buf[3] = val;
1081 5391d806 bellard
}
1082 5391d806 bellard
1083 5391d806 bellard
static inline int ube16_to_cpu(const uint8_t *buf)
1084 5391d806 bellard
{
1085 5391d806 bellard
    return (buf[0] << 8) | buf[1];
1086 5391d806 bellard
}
1087 5391d806 bellard
1088 5391d806 bellard
static inline int ube32_to_cpu(const uint8_t *buf)
1089 5391d806 bellard
{
1090 5391d806 bellard
    return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
1091 5391d806 bellard
}
1092 5391d806 bellard
1093 98087450 bellard
static void lba_to_msf(uint8_t *buf, int lba)
1094 98087450 bellard
{
1095 98087450 bellard
    lba += 150;
1096 98087450 bellard
    buf[0] = (lba / 75) / 60;
1097 98087450 bellard
    buf[1] = (lba / 75) % 60;
1098 98087450 bellard
    buf[2] = lba % 75;
1099 98087450 bellard
}
1100 98087450 bellard
1101 8ccad811 bellard
static void cd_data_to_raw(uint8_t *buf, int lba)
1102 8ccad811 bellard
{
1103 8ccad811 bellard
    /* sync bytes */
1104 8ccad811 bellard
    buf[0] = 0x00;
1105 8ccad811 bellard
    memset(buf + 1, 0xff, 10);
1106 8ccad811 bellard
    buf[11] = 0x00;
1107 8ccad811 bellard
    buf += 12;
1108 8ccad811 bellard
    /* MSF */
1109 8ccad811 bellard
    lba_to_msf(buf, lba);
1110 8ccad811 bellard
    buf[3] = 0x01; /* mode 1 data */
1111 8ccad811 bellard
    buf += 4;
1112 8ccad811 bellard
    /* data */
1113 8ccad811 bellard
    buf += 2048;
1114 8ccad811 bellard
    /* XXX: ECC not computed */
1115 8ccad811 bellard
    memset(buf, 0, 288);
1116 8ccad811 bellard
}
1117 8ccad811 bellard
1118 5fafdf24 ths
static int cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf,
1119 98087450 bellard
                           int sector_size)
1120 98087450 bellard
{
1121 66c6ef76 bellard
    int ret;
1122 66c6ef76 bellard
1123 98087450 bellard
    switch(sector_size) {
1124 98087450 bellard
    case 2048:
1125 66c6ef76 bellard
        ret = bdrv_read(bs, (int64_t)lba << 2, buf, 4);
1126 98087450 bellard
        break;
1127 98087450 bellard
    case 2352:
1128 66c6ef76 bellard
        ret = bdrv_read(bs, (int64_t)lba << 2, buf + 16, 4);
1129 66c6ef76 bellard
        if (ret < 0)
1130 66c6ef76 bellard
            return ret;
1131 8ccad811 bellard
        cd_data_to_raw(buf, lba);
1132 98087450 bellard
        break;
1133 98087450 bellard
    default:
1134 66c6ef76 bellard
        ret = -EIO;
1135 98087450 bellard
        break;
1136 98087450 bellard
    }
1137 66c6ef76 bellard
    return ret;
1138 66c6ef76 bellard
}
1139 66c6ef76 bellard
1140 66c6ef76 bellard
static void ide_atapi_io_error(IDEState *s, int ret)
1141 66c6ef76 bellard
{
1142 66c6ef76 bellard
    /* XXX: handle more errors */
1143 66c6ef76 bellard
    if (ret == -ENOMEDIUM) {
1144 5fafdf24 ths
        ide_atapi_cmd_error(s, SENSE_NOT_READY,
1145 66c6ef76 bellard
                            ASC_MEDIUM_NOT_PRESENT);
1146 66c6ef76 bellard
    } else {
1147 5fafdf24 ths
        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1148 66c6ef76 bellard
                            ASC_LOGICAL_BLOCK_OOR);
1149 66c6ef76 bellard
    }
1150 98087450 bellard
}
1151 98087450 bellard
1152 5391d806 bellard
/* The whole ATAPI transfer logic is handled in this function */
1153 5391d806 bellard
static void ide_atapi_cmd_reply_end(IDEState *s)
1154 5391d806 bellard
{
1155 66c6ef76 bellard
    int byte_count_limit, size, ret;
1156 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
1157 5fafdf24 ths
    printf("reply: tx_size=%d elem_tx_size=%d index=%d\n",
1158 5391d806 bellard
           s->packet_transfer_size,
1159 5391d806 bellard
           s->elementary_transfer_size,
1160 5391d806 bellard
           s->io_buffer_index);
1161 5391d806 bellard
#endif
1162 5391d806 bellard
    if (s->packet_transfer_size <= 0) {
1163 5391d806 bellard
        /* end of transfer */
1164 5391d806 bellard
        ide_transfer_stop(s);
1165 41a2b959 aliguori
        s->status = READY_STAT | SEEK_STAT;
1166 5391d806 bellard
        s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
1167 5391d806 bellard
        ide_set_irq(s);
1168 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
1169 5391d806 bellard
        printf("status=0x%x\n", s->status);
1170 5391d806 bellard
#endif
1171 5391d806 bellard
    } else {
1172 5391d806 bellard
        /* see if a new sector must be read */
1173 98087450 bellard
        if (s->lba != -1 && s->io_buffer_index >= s->cd_sector_size) {
1174 66c6ef76 bellard
            ret = cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size);
1175 66c6ef76 bellard
            if (ret < 0) {
1176 66c6ef76 bellard
                ide_transfer_stop(s);
1177 66c6ef76 bellard
                ide_atapi_io_error(s, ret);
1178 66c6ef76 bellard
                return;
1179 66c6ef76 bellard
            }
1180 5391d806 bellard
            s->lba++;
1181 5391d806 bellard
            s->io_buffer_index = 0;
1182 5391d806 bellard
        }
1183 5391d806 bellard
        if (s->elementary_transfer_size > 0) {
1184 5391d806 bellard
            /* there are some data left to transmit in this elementary
1185 5391d806 bellard
               transfer */
1186 98087450 bellard
            size = s->cd_sector_size - s->io_buffer_index;
1187 5391d806 bellard
            if (size > s->elementary_transfer_size)
1188 5391d806 bellard
                size = s->elementary_transfer_size;
1189 5fafdf24 ths
            ide_transfer_start(s, s->io_buffer + s->io_buffer_index,
1190 5391d806 bellard
                               size, ide_atapi_cmd_reply_end);
1191 5391d806 bellard
            s->packet_transfer_size -= size;
1192 5391d806 bellard
            s->elementary_transfer_size -= size;
1193 5391d806 bellard
            s->io_buffer_index += size;
1194 5391d806 bellard
        } else {
1195 5391d806 bellard
            /* a new transfer is needed */
1196 5391d806 bellard
            s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO;
1197 5391d806 bellard
            byte_count_limit = s->lcyl | (s->hcyl << 8);
1198 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
1199 5391d806 bellard
            printf("byte_count_limit=%d\n", byte_count_limit);
1200 5391d806 bellard
#endif
1201 5391d806 bellard
            if (byte_count_limit == 0xffff)
1202 5391d806 bellard
                byte_count_limit--;
1203 5391d806 bellard
            size = s->packet_transfer_size;
1204 5391d806 bellard
            if (size > byte_count_limit) {
1205 5391d806 bellard
                /* byte count limit must be even if this case */
1206 5391d806 bellard
                if (byte_count_limit & 1)
1207 5391d806 bellard
                    byte_count_limit--;
1208 5391d806 bellard
                size = byte_count_limit;
1209 5391d806 bellard
            }
1210 a136e5a8 bellard
            s->lcyl = size;
1211 a136e5a8 bellard
            s->hcyl = size >> 8;
1212 5391d806 bellard
            s->elementary_transfer_size = size;
1213 5391d806 bellard
            /* we cannot transmit more than one sector at a time */
1214 5391d806 bellard
            if (s->lba != -1) {
1215 98087450 bellard
                if (size > (s->cd_sector_size - s->io_buffer_index))
1216 98087450 bellard
                    size = (s->cd_sector_size - s->io_buffer_index);
1217 5391d806 bellard
            }
1218 5fafdf24 ths
            ide_transfer_start(s, s->io_buffer + s->io_buffer_index,
1219 5391d806 bellard
                               size, ide_atapi_cmd_reply_end);
1220 5391d806 bellard
            s->packet_transfer_size -= size;
1221 5391d806 bellard
            s->elementary_transfer_size -= size;
1222 5391d806 bellard
            s->io_buffer_index += size;
1223 5391d806 bellard
            ide_set_irq(s);
1224 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
1225 5391d806 bellard
            printf("status=0x%x\n", s->status);
1226 5391d806 bellard
#endif
1227 5391d806 bellard
        }
1228 5391d806 bellard
    }
1229 5391d806 bellard
}
1230 5391d806 bellard
1231 5391d806 bellard
/* send a reply of 'size' bytes in s->io_buffer to an ATAPI command */
1232 5391d806 bellard
static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size)
1233 5391d806 bellard
{
1234 5391d806 bellard
    if (size > max_size)
1235 5391d806 bellard
        size = max_size;
1236 5391d806 bellard
    s->lba = -1; /* no sector read */
1237 5391d806 bellard
    s->packet_transfer_size = size;
1238 5f12ab4b ths
    s->io_buffer_size = size;    /* dma: send the reply data as one chunk */
1239 5391d806 bellard
    s->elementary_transfer_size = 0;
1240 5391d806 bellard
    s->io_buffer_index = 0;
1241 5391d806 bellard
1242 5f12ab4b ths
    if (s->atapi_dma) {
1243 41a2b959 aliguori
            s->status = READY_STAT | SEEK_STAT | DRQ_STAT;
1244 5f12ab4b ths
        ide_dma_start(s, ide_atapi_cmd_read_dma_cb);
1245 5f12ab4b ths
    } else {
1246 41a2b959 aliguori
            s->status = READY_STAT | SEEK_STAT;
1247 5f12ab4b ths
            ide_atapi_cmd_reply_end(s);
1248 5f12ab4b ths
    }
1249 5391d806 bellard
}
1250 5391d806 bellard
1251 5391d806 bellard
/* start a CD-CDROM read command */
1252 98087450 bellard
static void ide_atapi_cmd_read_pio(IDEState *s, int lba, int nb_sectors,
1253 98087450 bellard
                                   int sector_size)
1254 5391d806 bellard
{
1255 5391d806 bellard
    s->lba = lba;
1256 98087450 bellard
    s->packet_transfer_size = nb_sectors * sector_size;
1257 5391d806 bellard
    s->elementary_transfer_size = 0;
1258 98087450 bellard
    s->io_buffer_index = sector_size;
1259 98087450 bellard
    s->cd_sector_size = sector_size;
1260 5391d806 bellard
1261 41a2b959 aliguori
    s->status = READY_STAT | SEEK_STAT;
1262 5391d806 bellard
    ide_atapi_cmd_reply_end(s);
1263 5391d806 bellard
}
1264 5391d806 bellard
1265 98087450 bellard
/* ATAPI DMA support */
1266 8ccad811 bellard
1267 8ccad811 bellard
/* XXX: handle read errors */
1268 8ccad811 bellard
static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret)
1269 98087450 bellard
{
1270 8ccad811 bellard
    BMDMAState *bm = opaque;
1271 8ccad811 bellard
    IDEState *s = bm->ide_if;
1272 8ccad811 bellard
    int data_offset, n;
1273 8ccad811 bellard
1274 66c6ef76 bellard
    if (ret < 0) {
1275 66c6ef76 bellard
        ide_atapi_io_error(s, ret);
1276 66c6ef76 bellard
        goto eot;
1277 66c6ef76 bellard
    }
1278 66c6ef76 bellard
1279 8ccad811 bellard
    if (s->io_buffer_size > 0) {
1280 5f12ab4b ths
        /*
1281 5f12ab4b ths
         * For a cdrom read sector command (s->lba != -1),
1282 5f12ab4b ths
         * adjust the lba for the next s->io_buffer_size chunk
1283 5f12ab4b ths
         * and dma the current chunk.
1284 5f12ab4b ths
         * For a command != read (s->lba == -1), just transfer
1285 5f12ab4b ths
         * the reply data.
1286 5f12ab4b ths
         */
1287 5f12ab4b ths
        if (s->lba != -1) {
1288 5f12ab4b ths
            if (s->cd_sector_size == 2352) {
1289 5f12ab4b ths
                n = 1;
1290 5f12ab4b ths
                cd_data_to_raw(s->io_buffer, s->lba);
1291 5f12ab4b ths
            } else {
1292 5f12ab4b ths
                n = s->io_buffer_size >> 11;
1293 5f12ab4b ths
            }
1294 5f12ab4b ths
            s->lba += n;
1295 5f12ab4b ths
        }
1296 8ccad811 bellard
        s->packet_transfer_size -= s->io_buffer_size;
1297 8ccad811 bellard
        if (dma_buf_rw(bm, 1) == 0)
1298 8ccad811 bellard
            goto eot;
1299 98087450 bellard
    }
1300 8ccad811 bellard
1301 98087450 bellard
    if (s->packet_transfer_size <= 0) {
1302 41a2b959 aliguori
        s->status = READY_STAT | SEEK_STAT;
1303 98087450 bellard
        s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
1304 98087450 bellard
        ide_set_irq(s);
1305 8ccad811 bellard
    eot:
1306 8ccad811 bellard
        bm->status &= ~BM_STATUS_DMAING;
1307 8ccad811 bellard
        bm->status |= BM_STATUS_INT;
1308 8ccad811 bellard
        bm->dma_cb = NULL;
1309 8ccad811 bellard
        bm->ide_if = NULL;
1310 8ccad811 bellard
        bm->aiocb = NULL;
1311 8ccad811 bellard
        return;
1312 8ccad811 bellard
    }
1313 3b46e624 ths
1314 8ccad811 bellard
    s->io_buffer_index = 0;
1315 8ccad811 bellard
    if (s->cd_sector_size == 2352) {
1316 8ccad811 bellard
        n = 1;
1317 8ccad811 bellard
        s->io_buffer_size = s->cd_sector_size;
1318 8ccad811 bellard
        data_offset = 16;
1319 8ccad811 bellard
    } else {
1320 8ccad811 bellard
        n = s->packet_transfer_size >> 11;
1321 1d8cde5b aurel32
        if (n > (IDE_DMA_BUF_SECTORS / 4))
1322 1d8cde5b aurel32
            n = (IDE_DMA_BUF_SECTORS / 4);
1323 8ccad811 bellard
        s->io_buffer_size = n * 2048;
1324 8ccad811 bellard
        data_offset = 0;
1325 98087450 bellard
    }
1326 8ccad811 bellard
#ifdef DEBUG_AIO
1327 8ccad811 bellard
    printf("aio_read_cd: lba=%u n=%d\n", s->lba, n);
1328 8ccad811 bellard
#endif
1329 5fafdf24 ths
    bm->aiocb = bdrv_aio_read(s->bs, (int64_t)s->lba << 2,
1330 5fafdf24 ths
                              s->io_buffer + data_offset, n * 4,
1331 8ccad811 bellard
                              ide_atapi_cmd_read_dma_cb, bm);
1332 66c6ef76 bellard
    if (!bm->aiocb) {
1333 66c6ef76 bellard
        /* Note: media not present is the most likely case */
1334 5fafdf24 ths
        ide_atapi_cmd_error(s, SENSE_NOT_READY,
1335 66c6ef76 bellard
                            ASC_MEDIUM_NOT_PRESENT);
1336 66c6ef76 bellard
        goto eot;
1337 66c6ef76 bellard
    }
1338 98087450 bellard
}
1339 98087450 bellard
1340 98087450 bellard
/* start a CD-CDROM read command with DMA */
1341 98087450 bellard
/* XXX: test if DMA is available */
1342 98087450 bellard
static void ide_atapi_cmd_read_dma(IDEState *s, int lba, int nb_sectors,
1343 98087450 bellard
                                   int sector_size)
1344 98087450 bellard
{
1345 98087450 bellard
    s->lba = lba;
1346 98087450 bellard
    s->packet_transfer_size = nb_sectors * sector_size;
1347 8ccad811 bellard
    s->io_buffer_index = 0;
1348 8ccad811 bellard
    s->io_buffer_size = 0;
1349 98087450 bellard
    s->cd_sector_size = sector_size;
1350 98087450 bellard
1351 8ccad811 bellard
    /* XXX: check if BUSY_STAT should be set */
1352 41a2b959 aliguori
    s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
1353 98087450 bellard
    ide_dma_start(s, ide_atapi_cmd_read_dma_cb);
1354 98087450 bellard
}
1355 98087450 bellard
1356 5fafdf24 ths
static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors,
1357 98087450 bellard
                               int sector_size)
1358 98087450 bellard
{
1359 98087450 bellard
#ifdef DEBUG_IDE_ATAPI
1360 5f12ab4b ths
    printf("read %s: LBA=%d nb_sectors=%d\n", s->atapi_dma ? "dma" : "pio",
1361 5f12ab4b ths
        lba, nb_sectors);
1362 98087450 bellard
#endif
1363 98087450 bellard
    if (s->atapi_dma) {
1364 98087450 bellard
        ide_atapi_cmd_read_dma(s, lba, nb_sectors, sector_size);
1365 98087450 bellard
    } else {
1366 98087450 bellard
        ide_atapi_cmd_read_pio(s, lba, nb_sectors, sector_size);
1367 98087450 bellard
    }
1368 98087450 bellard
}
1369 98087450 bellard
1370 38cdea7c balrog
static inline uint8_t ide_atapi_set_profile(uint8_t *buf, uint8_t *index,
1371 38cdea7c balrog
                                            uint16_t profile)
1372 38cdea7c balrog
{
1373 38cdea7c balrog
    uint8_t *buf_profile = buf + 12; /* start of profiles */
1374 38cdea7c balrog
1375 38cdea7c balrog
    buf_profile += ((*index) * 4); /* start of indexed profile */
1376 38cdea7c balrog
    cpu_to_ube16 (buf_profile, profile);
1377 38cdea7c balrog
    buf_profile[2] = ((buf_profile[0] == buf[6]) && (buf_profile[1] == buf[7]));
1378 38cdea7c balrog
1379 38cdea7c balrog
    /* each profile adds 4 bytes to the response */
1380 38cdea7c balrog
    (*index)++;
1381 38cdea7c balrog
    buf[11] += 4; /* Additional Length */
1382 38cdea7c balrog
1383 38cdea7c balrog
    return 4;
1384 38cdea7c balrog
}
1385 38cdea7c balrog
1386 8114e9e8 ths
static int ide_dvd_read_structure(IDEState *s, int format,
1387 8114e9e8 ths
                                  const uint8_t *packet, uint8_t *buf)
1388 8114e9e8 ths
{
1389 8114e9e8 ths
    switch (format) {
1390 8114e9e8 ths
        case 0x0: /* Physical format information */
1391 8114e9e8 ths
            {
1392 8114e9e8 ths
                int layer = packet[6];
1393 8114e9e8 ths
                uint64_t total_sectors;
1394 8114e9e8 ths
1395 8114e9e8 ths
                if (layer != 0)
1396 8114e9e8 ths
                    return -ASC_INV_FIELD_IN_CMD_PACKET;
1397 8114e9e8 ths
1398 8114e9e8 ths
                bdrv_get_geometry(s->bs, &total_sectors);
1399 8114e9e8 ths
                total_sectors >>= 2;
1400 8114e9e8 ths
                if (total_sectors == 0)
1401 8114e9e8 ths
                    return -ASC_MEDIUM_NOT_PRESENT;
1402 8114e9e8 ths
1403 8114e9e8 ths
                buf[4] = 1;   /* DVD-ROM, part version 1 */
1404 8114e9e8 ths
                buf[5] = 0xf; /* 120mm disc, minimum rate unspecified */
1405 8114e9e8 ths
                buf[6] = 1;   /* one layer, read-only (per MMC-2 spec) */
1406 8114e9e8 ths
                buf[7] = 0;   /* default densities */
1407 8114e9e8 ths
1408 8114e9e8 ths
                /* FIXME: 0x30000 per spec? */
1409 8114e9e8 ths
                cpu_to_ube32(buf + 8, 0); /* start sector */
1410 8114e9e8 ths
                cpu_to_ube32(buf + 12, total_sectors - 1); /* end sector */
1411 8114e9e8 ths
                cpu_to_ube32(buf + 16, total_sectors - 1); /* l0 end sector */
1412 8114e9e8 ths
1413 8114e9e8 ths
                /* Size of buffer, not including 2 byte size field */
1414 8114e9e8 ths
                cpu_to_be16wu((uint16_t *)buf, 2048 + 2);
1415 8114e9e8 ths
1416 8114e9e8 ths
                /* 2k data + 4 byte header */
1417 8114e9e8 ths
                return (2048 + 4);
1418 8114e9e8 ths
            }
1419 8114e9e8 ths
1420 8114e9e8 ths
        case 0x01: /* DVD copyright information */
1421 8114e9e8 ths
            buf[4] = 0; /* no copyright data */
1422 8114e9e8 ths
            buf[5] = 0; /* no region restrictions */
1423 8114e9e8 ths
1424 8114e9e8 ths
            /* Size of buffer, not including 2 byte size field */
1425 8114e9e8 ths
            cpu_to_be16wu((uint16_t *)buf, 4 + 2);
1426 8114e9e8 ths
1427 8114e9e8 ths
            /* 4 byte header + 4 byte data */
1428 8114e9e8 ths
            return (4 + 4);
1429 8114e9e8 ths
1430 8114e9e8 ths
        case 0x03: /* BCA information - invalid field for no BCA info */
1431 8114e9e8 ths
            return -ASC_INV_FIELD_IN_CMD_PACKET;
1432 8114e9e8 ths
1433 8114e9e8 ths
        case 0x04: /* DVD disc manufacturing information */
1434 8114e9e8 ths
            /* Size of buffer, not including 2 byte size field */
1435 8114e9e8 ths
            cpu_to_be16wu((uint16_t *)buf, 2048 + 2);
1436 8114e9e8 ths
1437 8114e9e8 ths
            /* 2k data + 4 byte header */
1438 8114e9e8 ths
            return (2048 + 4);
1439 8114e9e8 ths
1440 8114e9e8 ths
        case 0xff:
1441 8114e9e8 ths
            /*
1442 8114e9e8 ths
             * This lists all the command capabilities above.  Add new ones
1443 8114e9e8 ths
             * in order and update the length and buffer return values.
1444 8114e9e8 ths
             */
1445 8114e9e8 ths
1446 8114e9e8 ths
            buf[4] = 0x00; /* Physical format */
1447 8114e9e8 ths
            buf[5] = 0x40; /* Not writable, is readable */
1448 8114e9e8 ths
            cpu_to_be16wu((uint16_t *)(buf + 6), 2048 + 4);
1449 8114e9e8 ths
1450 8114e9e8 ths
            buf[8] = 0x01; /* Copyright info */
1451 8114e9e8 ths
            buf[9] = 0x40; /* Not writable, is readable */
1452 8114e9e8 ths
            cpu_to_be16wu((uint16_t *)(buf + 10), 4 + 4);
1453 8114e9e8 ths
1454 8114e9e8 ths
            buf[12] = 0x03; /* BCA info */
1455 8114e9e8 ths
            buf[13] = 0x40; /* Not writable, is readable */
1456 8114e9e8 ths
            cpu_to_be16wu((uint16_t *)(buf + 14), 188 + 4);
1457 8114e9e8 ths
1458 8114e9e8 ths
            buf[16] = 0x04; /* Manufacturing info */
1459 8114e9e8 ths
            buf[17] = 0x40; /* Not writable, is readable */
1460 8114e9e8 ths
            cpu_to_be16wu((uint16_t *)(buf + 18), 2048 + 4);
1461 8114e9e8 ths
1462 8114e9e8 ths
            /* Size of buffer, not including 2 byte size field */
1463 8114e9e8 ths
            cpu_to_be16wu((uint16_t *)buf, 16 + 2);
1464 8114e9e8 ths
1465 8114e9e8 ths
            /* data written + 4 byte header */
1466 8114e9e8 ths
            return (16 + 4);
1467 8114e9e8 ths
1468 8114e9e8 ths
        default: /* TODO: formats beyond DVD-ROM requires */
1469 8114e9e8 ths
            return -ASC_INV_FIELD_IN_CMD_PACKET;
1470 8114e9e8 ths
    }
1471 8114e9e8 ths
}
1472 8114e9e8 ths
1473 5391d806 bellard
static void ide_atapi_cmd(IDEState *s)
1474 5391d806 bellard
{
1475 5391d806 bellard
    const uint8_t *packet;
1476 5391d806 bellard
    uint8_t *buf;
1477 5391d806 bellard
    int max_len;
1478 5391d806 bellard
1479 5391d806 bellard
    packet = s->io_buffer;
1480 5391d806 bellard
    buf = s->io_buffer;
1481 5391d806 bellard
#ifdef DEBUG_IDE_ATAPI
1482 5391d806 bellard
    {
1483 5391d806 bellard
        int i;
1484 5391d806 bellard
        printf("ATAPI limit=0x%x packet:", s->lcyl | (s->hcyl << 8));
1485 5391d806 bellard
        for(i = 0; i < ATAPI_PACKET_SIZE; i++) {
1486 5391d806 bellard
            printf(" %02x", packet[i]);
1487 5391d806 bellard
        }
1488 5391d806 bellard
        printf("\n");
1489 5391d806 bellard
    }
1490 5391d806 bellard
#endif
1491 5391d806 bellard
    switch(s->io_buffer[0]) {
1492 5391d806 bellard
    case GPCMD_TEST_UNIT_READY:
1493 caed8802 bellard
        if (bdrv_is_inserted(s->bs)) {
1494 5391d806 bellard
            ide_atapi_cmd_ok(s);
1495 5391d806 bellard
        } else {
1496 5fafdf24 ths
            ide_atapi_cmd_error(s, SENSE_NOT_READY,
1497 5391d806 bellard
                                ASC_MEDIUM_NOT_PRESENT);
1498 5391d806 bellard
        }
1499 5391d806 bellard
        break;
1500 d14049ea ths
    case GPCMD_MODE_SENSE_6:
1501 5391d806 bellard
    case GPCMD_MODE_SENSE_10:
1502 5391d806 bellard
        {
1503 5391d806 bellard
            int action, code;
1504 d14049ea ths
            if (packet[0] == GPCMD_MODE_SENSE_10)
1505 d14049ea ths
                max_len = ube16_to_cpu(packet + 7);
1506 d14049ea ths
            else
1507 d14049ea ths
                max_len = packet[4];
1508 5391d806 bellard
            action = packet[2] >> 6;
1509 5391d806 bellard
            code = packet[2] & 0x3f;
1510 5391d806 bellard
            switch(action) {
1511 5391d806 bellard
            case 0: /* current values */
1512 5391d806 bellard
                switch(code) {
1513 5391d806 bellard
                case 0x01: /* error recovery */
1514 5391d806 bellard
                    cpu_to_ube16(&buf[0], 16 + 6);
1515 5391d806 bellard
                    buf[2] = 0x70;
1516 5391d806 bellard
                    buf[3] = 0;
1517 5391d806 bellard
                    buf[4] = 0;
1518 5391d806 bellard
                    buf[5] = 0;
1519 5391d806 bellard
                    buf[6] = 0;
1520 5391d806 bellard
                    buf[7] = 0;
1521 5391d806 bellard
1522 5391d806 bellard
                    buf[8] = 0x01;
1523 5391d806 bellard
                    buf[9] = 0x06;
1524 5391d806 bellard
                    buf[10] = 0x00;
1525 5391d806 bellard
                    buf[11] = 0x05;
1526 5391d806 bellard
                    buf[12] = 0x00;
1527 5391d806 bellard
                    buf[13] = 0x00;
1528 5391d806 bellard
                    buf[14] = 0x00;
1529 5391d806 bellard
                    buf[15] = 0x00;
1530 5391d806 bellard
                    ide_atapi_cmd_reply(s, 16, max_len);
1531 5391d806 bellard
                    break;
1532 5391d806 bellard
                case 0x2a:
1533 5391d806 bellard
                    cpu_to_ube16(&buf[0], 28 + 6);
1534 5391d806 bellard
                    buf[2] = 0x70;
1535 5391d806 bellard
                    buf[3] = 0;
1536 5391d806 bellard
                    buf[4] = 0;
1537 5391d806 bellard
                    buf[5] = 0;
1538 5391d806 bellard
                    buf[6] = 0;
1539 5391d806 bellard
                    buf[7] = 0;
1540 5391d806 bellard
1541 5391d806 bellard
                    buf[8] = 0x2a;
1542 5391d806 bellard
                    buf[9] = 0x12;
1543 0d4a05a1 ths
                    buf[10] = 0x00;
1544 5391d806 bellard
                    buf[11] = 0x00;
1545 3b46e624 ths
1546 5391d806 bellard
                    buf[12] = 0x70;
1547 5391d806 bellard
                    buf[13] = 3 << 5;
1548 5391d806 bellard
                    buf[14] = (1 << 0) | (1 << 3) | (1 << 5);
1549 caed8802 bellard
                    if (bdrv_is_locked(s->bs))
1550 5391d806 bellard
                        buf[6] |= 1 << 1;
1551 5391d806 bellard
                    buf[15] = 0x00;
1552 5391d806 bellard
                    cpu_to_ube16(&buf[16], 706);
1553 5391d806 bellard
                    buf[18] = 0;
1554 5391d806 bellard
                    buf[19] = 2;
1555 5391d806 bellard
                    cpu_to_ube16(&buf[20], 512);
1556 5391d806 bellard
                    cpu_to_ube16(&buf[22], 706);
1557 5391d806 bellard
                    buf[24] = 0;
1558 5391d806 bellard
                    buf[25] = 0;
1559 5391d806 bellard
                    buf[26] = 0;
1560 5391d806 bellard
                    buf[27] = 0;
1561 5391d806 bellard
                    ide_atapi_cmd_reply(s, 28, max_len);
1562 5391d806 bellard
                    break;
1563 5391d806 bellard
                default:
1564 5391d806 bellard
                    goto error_cmd;
1565 5391d806 bellard
                }
1566 5391d806 bellard
                break;
1567 5391d806 bellard
            case 1: /* changeable values */
1568 5391d806 bellard
                goto error_cmd;
1569 5391d806 bellard
            case 2: /* default values */
1570 5391d806 bellard
                goto error_cmd;
1571 5391d806 bellard
            default:
1572 5391d806 bellard
            case 3: /* saved values */
1573 5fafdf24 ths
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1574 5391d806 bellard
                                    ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
1575 5391d806 bellard
                break;
1576 5391d806 bellard
            }
1577 5391d806 bellard
        }
1578 5391d806 bellard
        break;
1579 5391d806 bellard
    case GPCMD_REQUEST_SENSE:
1580 5391d806 bellard
        max_len = packet[4];
1581 5391d806 bellard
        memset(buf, 0, 18);
1582 5391d806 bellard
        buf[0] = 0x70 | (1 << 7);
1583 5391d806 bellard
        buf[2] = s->sense_key;
1584 5391d806 bellard
        buf[7] = 10;
1585 5391d806 bellard
        buf[12] = s->asc;
1586 5391d806 bellard
        ide_atapi_cmd_reply(s, 18, max_len);
1587 5391d806 bellard
        break;
1588 5391d806 bellard
    case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
1589 caed8802 bellard
        if (bdrv_is_inserted(s->bs)) {
1590 caed8802 bellard
            bdrv_set_locked(s->bs, packet[4] & 1);
1591 5391d806 bellard
            ide_atapi_cmd_ok(s);
1592 5391d806 bellard
        } else {
1593 5fafdf24 ths
            ide_atapi_cmd_error(s, SENSE_NOT_READY,
1594 5391d806 bellard
                                ASC_MEDIUM_NOT_PRESENT);
1595 5391d806 bellard
        }
1596 5391d806 bellard
        break;
1597 5391d806 bellard
    case GPCMD_READ_10:
1598 5391d806 bellard
    case GPCMD_READ_12:
1599 5391d806 bellard
        {
1600 5391d806 bellard
            int nb_sectors, lba;
1601 5391d806 bellard
1602 5391d806 bellard
            if (packet[0] == GPCMD_READ_10)
1603 5391d806 bellard
                nb_sectors = ube16_to_cpu(packet + 7);
1604 5391d806 bellard
            else
1605 5391d806 bellard
                nb_sectors = ube32_to_cpu(packet + 6);
1606 5391d806 bellard
            lba = ube32_to_cpu(packet + 2);
1607 5391d806 bellard
            if (nb_sectors == 0) {
1608 5391d806 bellard
                ide_atapi_cmd_ok(s);
1609 5391d806 bellard
                break;
1610 5391d806 bellard
            }
1611 98087450 bellard
            ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
1612 98087450 bellard
        }
1613 98087450 bellard
        break;
1614 98087450 bellard
    case GPCMD_READ_CD:
1615 98087450 bellard
        {
1616 98087450 bellard
            int nb_sectors, lba, transfer_request;
1617 98087450 bellard
1618 98087450 bellard
            nb_sectors = (packet[6] << 16) | (packet[7] << 8) | packet[8];
1619 98087450 bellard
            lba = ube32_to_cpu(packet + 2);
1620 98087450 bellard
            if (nb_sectors == 0) {
1621 98087450 bellard
                ide_atapi_cmd_ok(s);
1622 98087450 bellard
                break;
1623 98087450 bellard
            }
1624 98087450 bellard
            transfer_request = packet[9];
1625 98087450 bellard
            switch(transfer_request & 0xf8) {
1626 98087450 bellard
            case 0x00:
1627 98087450 bellard
                /* nothing */
1628 98087450 bellard
                ide_atapi_cmd_ok(s);
1629 98087450 bellard
                break;
1630 98087450 bellard
            case 0x10:
1631 98087450 bellard
                /* normal read */
1632 98087450 bellard
                ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
1633 98087450 bellard
                break;
1634 98087450 bellard
            case 0xf8:
1635 98087450 bellard
                /* read all data */
1636 98087450 bellard
                ide_atapi_cmd_read(s, lba, nb_sectors, 2352);
1637 98087450 bellard
                break;
1638 98087450 bellard
            default:
1639 5fafdf24 ths
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1640 98087450 bellard
                                    ASC_INV_FIELD_IN_CMD_PACKET);
1641 98087450 bellard
                break;
1642 98087450 bellard
            }
1643 5391d806 bellard
        }
1644 5391d806 bellard
        break;
1645 5391d806 bellard
    case GPCMD_SEEK:
1646 5391d806 bellard
        {
1647 96b8f136 ths
            unsigned int lba;
1648 96b8f136 ths
            uint64_t total_sectors;
1649 66c6ef76 bellard
1650 66c6ef76 bellard
            bdrv_get_geometry(s->bs, &total_sectors);
1651 66c6ef76 bellard
            total_sectors >>= 2;
1652 96b8f136 ths
            if (total_sectors == 0) {
1653 5fafdf24 ths
                ide_atapi_cmd_error(s, SENSE_NOT_READY,
1654 5391d806 bellard
                                    ASC_MEDIUM_NOT_PRESENT);
1655 5391d806 bellard
                break;
1656 5391d806 bellard
            }
1657 5391d806 bellard
            lba = ube32_to_cpu(packet + 2);
1658 66c6ef76 bellard
            if (lba >= total_sectors) {
1659 5fafdf24 ths
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1660 5391d806 bellard
                                    ASC_LOGICAL_BLOCK_OOR);
1661 5391d806 bellard
                break;
1662 5391d806 bellard
            }
1663 5391d806 bellard
            ide_atapi_cmd_ok(s);
1664 5391d806 bellard
        }
1665 5391d806 bellard
        break;
1666 5391d806 bellard
    case GPCMD_START_STOP_UNIT:
1667 5391d806 bellard
        {
1668 5391d806 bellard
            int start, eject;
1669 5391d806 bellard
            start = packet[4] & 1;
1670 5391d806 bellard
            eject = (packet[4] >> 1) & 1;
1671 3b46e624 ths
1672 caed8802 bellard
            if (eject && !start) {
1673 caed8802 bellard
                /* eject the disk */
1674 66c6ef76 bellard
                bdrv_eject(s->bs, 1);
1675 66c6ef76 bellard
            } else if (eject && start) {
1676 66c6ef76 bellard
                /* close the tray */
1677 66c6ef76 bellard
                bdrv_eject(s->bs, 0);
1678 caed8802 bellard
            }
1679 5391d806 bellard
            ide_atapi_cmd_ok(s);
1680 5391d806 bellard
        }
1681 5391d806 bellard
        break;
1682 5391d806 bellard
    case GPCMD_MECHANISM_STATUS:
1683 5391d806 bellard
        {
1684 5391d806 bellard
            max_len = ube16_to_cpu(packet + 8);
1685 5391d806 bellard
            cpu_to_ube16(buf, 0);
1686 5391d806 bellard
            /* no current LBA */
1687 5391d806 bellard
            buf[2] = 0;
1688 5391d806 bellard
            buf[3] = 0;
1689 5391d806 bellard
            buf[4] = 0;
1690 5391d806 bellard
            buf[5] = 1;
1691 5391d806 bellard
            cpu_to_ube16(buf + 6, 0);
1692 5391d806 bellard
            ide_atapi_cmd_reply(s, 8, max_len);
1693 5391d806 bellard
        }
1694 5391d806 bellard
        break;
1695 5391d806 bellard
    case GPCMD_READ_TOC_PMA_ATIP:
1696 5391d806 bellard
        {
1697 5391d806 bellard
            int format, msf, start_track, len;
1698 96b8f136 ths
            uint64_t total_sectors;
1699 5391d806 bellard
1700 66c6ef76 bellard
            bdrv_get_geometry(s->bs, &total_sectors);
1701 66c6ef76 bellard
            total_sectors >>= 2;
1702 96b8f136 ths
            if (total_sectors == 0) {
1703 5fafdf24 ths
                ide_atapi_cmd_error(s, SENSE_NOT_READY,
1704 5391d806 bellard
                                    ASC_MEDIUM_NOT_PRESENT);
1705 5391d806 bellard
                break;
1706 5391d806 bellard
            }
1707 5391d806 bellard
            max_len = ube16_to_cpu(packet + 7);
1708 5391d806 bellard
            format = packet[9] >> 6;
1709 5391d806 bellard
            msf = (packet[1] >> 1) & 1;
1710 5391d806 bellard
            start_track = packet[6];
1711 5391d806 bellard
            switch(format) {
1712 5391d806 bellard
            case 0:
1713 66c6ef76 bellard
                len = cdrom_read_toc(total_sectors, buf, msf, start_track);
1714 5391d806 bellard
                if (len < 0)
1715 5391d806 bellard
                    goto error_cmd;
1716 5391d806 bellard
                ide_atapi_cmd_reply(s, len, max_len);
1717 5391d806 bellard
                break;
1718 5391d806 bellard
            case 1:
1719 5391d806 bellard
                /* multi session : only a single session defined */
1720 5391d806 bellard
                memset(buf, 0, 12);
1721 5391d806 bellard
                buf[1] = 0x0a;
1722 5391d806 bellard
                buf[2] = 0x01;
1723 5391d806 bellard
                buf[3] = 0x01;
1724 5391d806 bellard
                ide_atapi_cmd_reply(s, 12, max_len);
1725 5391d806 bellard
                break;
1726 98087450 bellard
            case 2:
1727 66c6ef76 bellard
                len = cdrom_read_toc_raw(total_sectors, buf, msf, start_track);
1728 98087450 bellard
                if (len < 0)
1729 98087450 bellard
                    goto error_cmd;
1730 98087450 bellard
                ide_atapi_cmd_reply(s, len, max_len);
1731 98087450 bellard
                break;
1732 5391d806 bellard
            default:
1733 7f777bf3 bellard
            error_cmd:
1734 5fafdf24 ths
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1735 7f777bf3 bellard
                                    ASC_INV_FIELD_IN_CMD_PACKET);
1736 7f777bf3 bellard
                break;
1737 5391d806 bellard
            }
1738 5391d806 bellard
        }
1739 5391d806 bellard
        break;
1740 5391d806 bellard
    case GPCMD_READ_CDVD_CAPACITY:
1741 66c6ef76 bellard
        {
1742 96b8f136 ths
            uint64_t total_sectors;
1743 66c6ef76 bellard
1744 66c6ef76 bellard
            bdrv_get_geometry(s->bs, &total_sectors);
1745 66c6ef76 bellard
            total_sectors >>= 2;
1746 96b8f136 ths
            if (total_sectors == 0) {
1747 5fafdf24 ths
                ide_atapi_cmd_error(s, SENSE_NOT_READY,
1748 66c6ef76 bellard
                                    ASC_MEDIUM_NOT_PRESENT);
1749 66c6ef76 bellard
                break;
1750 66c6ef76 bellard
            }
1751 66c6ef76 bellard
            /* NOTE: it is really the number of sectors minus 1 */
1752 66c6ef76 bellard
            cpu_to_ube32(buf, total_sectors - 1);
1753 66c6ef76 bellard
            cpu_to_ube32(buf + 4, 2048);
1754 66c6ef76 bellard
            ide_atapi_cmd_reply(s, 8, 8);
1755 5391d806 bellard
        }
1756 5391d806 bellard
        break;
1757 d14049ea ths
    case GPCMD_READ_DVD_STRUCTURE:
1758 d14049ea ths
        {
1759 d14049ea ths
            int media = packet[1];
1760 8114e9e8 ths
            int format = packet[7];
1761 8114e9e8 ths
            int ret;
1762 d14049ea ths
1763 8114e9e8 ths
            max_len = ube16_to_cpu(packet + 8);
1764 d14049ea ths
1765 8114e9e8 ths
            if (format < 0xff) {
1766 8114e9e8 ths
                if (media_is_cd(s)) {
1767 8114e9e8 ths
                    ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1768 8114e9e8 ths
                                        ASC_INCOMPATIBLE_FORMAT);
1769 8114e9e8 ths
                    break;
1770 8114e9e8 ths
                } else if (!media_present(s)) {
1771 8114e9e8 ths
                    ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1772 8114e9e8 ths
                                        ASC_INV_FIELD_IN_CMD_PACKET);
1773 8114e9e8 ths
                    break;
1774 8114e9e8 ths
                }
1775 8114e9e8 ths
            }
1776 d14049ea ths
1777 8114e9e8 ths
            memset(buf, 0, max_len > IDE_DMA_BUF_SECTORS * 512 + 4 ?
1778 8114e9e8 ths
                   IDE_DMA_BUF_SECTORS * 512 + 4 : max_len);
1779 d14049ea ths
1780 8114e9e8 ths
            switch (format) {
1781 8114e9e8 ths
                case 0x00 ... 0x7f:
1782 8114e9e8 ths
                case 0xff:
1783 8114e9e8 ths
                    if (media == 0) {
1784 8114e9e8 ths
                        ret = ide_dvd_read_structure(s, format, packet, buf);
1785 d14049ea ths
1786 8114e9e8 ths
                        if (ret < 0)
1787 8114e9e8 ths
                            ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, -ret);
1788 8114e9e8 ths
                        else
1789 8114e9e8 ths
                            ide_atapi_cmd_reply(s, ret, max_len);
1790 d14049ea ths
1791 8114e9e8 ths
                        break;
1792 8114e9e8 ths
                    }
1793 8114e9e8 ths
                    /* TODO: BD support, fall through for now */
1794 8114e9e8 ths
1795 8114e9e8 ths
                /* Generic disk structures */
1796 8114e9e8 ths
                case 0x80: /* TODO: AACS volume identifier */
1797 8114e9e8 ths
                case 0x81: /* TODO: AACS media serial number */
1798 8114e9e8 ths
                case 0x82: /* TODO: AACS media identifier */
1799 8114e9e8 ths
                case 0x83: /* TODO: AACS media key block */
1800 8114e9e8 ths
                case 0x90: /* TODO: List of recognized format layers */
1801 8114e9e8 ths
                case 0xc0: /* TODO: Write protection status */
1802 d14049ea ths
                default:
1803 d14049ea ths
                    ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1804 d14049ea ths
                                        ASC_INV_FIELD_IN_CMD_PACKET);
1805 d14049ea ths
                    break;
1806 d14049ea ths
            }
1807 d14049ea ths
        }
1808 d14049ea ths
        break;
1809 d14049ea ths
    case GPCMD_SET_SPEED:
1810 d14049ea ths
        ide_atapi_cmd_ok(s);
1811 d14049ea ths
        break;
1812 bd0d90b2 bellard
    case GPCMD_INQUIRY:
1813 bd0d90b2 bellard
        max_len = packet[4];
1814 bd0d90b2 bellard
        buf[0] = 0x05; /* CD-ROM */
1815 bd0d90b2 bellard
        buf[1] = 0x80; /* removable */
1816 bd0d90b2 bellard
        buf[2] = 0x00; /* ISO */
1817 bd0d90b2 bellard
        buf[3] = 0x21; /* ATAPI-2 (XXX: put ATAPI-4 ?) */
1818 aa1f17c1 ths
        buf[4] = 31; /* additional length */
1819 bd0d90b2 bellard
        buf[5] = 0; /* reserved */
1820 bd0d90b2 bellard
        buf[6] = 0; /* reserved */
1821 bd0d90b2 bellard
        buf[7] = 0; /* reserved */
1822 bd0d90b2 bellard
        padstr8(buf + 8, 8, "QEMU");
1823 38cdea7c balrog
        padstr8(buf + 16, 16, "QEMU DVD-ROM");
1824 bd0d90b2 bellard
        padstr8(buf + 32, 4, QEMU_VERSION);
1825 bd0d90b2 bellard
        ide_atapi_cmd_reply(s, 36, max_len);
1826 bd0d90b2 bellard
        break;
1827 d14049ea ths
    case GPCMD_GET_CONFIGURATION:
1828 d14049ea ths
        {
1829 38cdea7c balrog
            uint32_t len;
1830 091d055b balrog
            uint8_t index = 0;
1831 d14049ea ths
1832 d14049ea ths
            /* only feature 0 is supported */
1833 d14049ea ths
            if (packet[2] != 0 || packet[3] != 0) {
1834 d14049ea ths
                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1835 d14049ea ths
                                    ASC_INV_FIELD_IN_CMD_PACKET);
1836 d14049ea ths
                break;
1837 d14049ea ths
            }
1838 38cdea7c balrog
1839 38cdea7c balrog
            /* XXX: could result in alignment problems in some architectures */
1840 38cdea7c balrog
            max_len = ube16_to_cpu(packet + 7);
1841 091d055b balrog
1842 38cdea7c balrog
            /*
1843 091d055b balrog
             * XXX: avoid overflow for io_buffer if max_len is bigger than
1844 091d055b balrog
             *      the size of that buffer (dimensioned to max number of
1845 091d055b balrog
             *      sectors to transfer at once)
1846 38cdea7c balrog
             *
1847 091d055b balrog
             *      Only a problem if the feature/profiles grow.
1848 38cdea7c balrog
             */
1849 38cdea7c balrog
            if (max_len > 512) /* XXX: assume 1 sector */
1850 38cdea7c balrog
                max_len = 512;
1851 38cdea7c balrog
1852 38cdea7c balrog
            memset(buf, 0, max_len);
1853 38cdea7c balrog
            /* 
1854 38cdea7c balrog
             * the number of sectors from the media tells us which profile
1855 38cdea7c balrog
             * to use as current.  0 means there is no media
1856 38cdea7c balrog
             */
1857 8114e9e8 ths
            if (media_is_dvd(s))
1858 8114e9e8 ths
                cpu_to_ube16(buf + 6, MMC_PROFILE_DVD_ROM);
1859 8114e9e8 ths
            else if (media_is_cd(s))
1860 8114e9e8 ths
                cpu_to_ube16(buf + 6, MMC_PROFILE_CD_ROM);
1861 38cdea7c balrog
1862 091d055b balrog
            buf[10] = 0x02 | 0x01; /* persistent and current */
1863 091d055b balrog
            len = 12; /* headers: 8 + 4 */
1864 091d055b balrog
            len += ide_atapi_set_profile(buf, &index, MMC_PROFILE_DVD_ROM);
1865 091d055b balrog
            len += ide_atapi_set_profile(buf, &index, MMC_PROFILE_CD_ROM);
1866 38cdea7c balrog
            cpu_to_ube32(buf, len - 4); /* data length */
1867 38cdea7c balrog
1868 38cdea7c balrog
            ide_atapi_cmd_reply(s, len, max_len);
1869 d14049ea ths
            break;
1870 d14049ea ths
        }
1871 5391d806 bellard
    default:
1872 5fafdf24 ths
        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1873 7f777bf3 bellard
                            ASC_ILLEGAL_OPCODE);
1874 5391d806 bellard
        break;
1875 5391d806 bellard
    }
1876 5391d806 bellard
}
1877 5391d806 bellard
1878 201a51fc balrog
static void ide_cfata_metadata_inquiry(IDEState *s)
1879 201a51fc balrog
{
1880 201a51fc balrog
    uint16_t *p;
1881 201a51fc balrog
    uint32_t spd;
1882 201a51fc balrog
1883 201a51fc balrog
    p = (uint16_t *) s->io_buffer;
1884 201a51fc balrog
    memset(p, 0, 0x200);
1885 201a51fc balrog
    spd = ((s->mdata_size - 1) >> 9) + 1;
1886 201a51fc balrog
1887 201a51fc balrog
    put_le16(p + 0, 0x0001);                        /* Data format revision */
1888 201a51fc balrog
    put_le16(p + 1, 0x0000);                        /* Media property: silicon */
1889 201a51fc balrog
    put_le16(p + 2, s->media_changed);                /* Media status */
1890 201a51fc balrog
    put_le16(p + 3, s->mdata_size & 0xffff);        /* Capacity in bytes (low) */
1891 201a51fc balrog
    put_le16(p + 4, s->mdata_size >> 16);        /* Capacity in bytes (high) */
1892 201a51fc balrog
    put_le16(p + 5, spd & 0xffff);                /* Sectors per device (low) */
1893 201a51fc balrog
    put_le16(p + 6, spd >> 16);                        /* Sectors per device (high) */
1894 201a51fc balrog
}
1895 201a51fc balrog
1896 201a51fc balrog
static void ide_cfata_metadata_read(IDEState *s)
1897 201a51fc balrog
{
1898 201a51fc balrog
    uint16_t *p;
1899 201a51fc balrog
1900 201a51fc balrog
    if (((s->hcyl << 16) | s->lcyl) << 9 > s->mdata_size + 2) {
1901 201a51fc balrog
        s->status = ERR_STAT;
1902 201a51fc balrog
        s->error = ABRT_ERR;
1903 201a51fc balrog
        return;
1904 201a51fc balrog
    }
1905 201a51fc balrog
1906 201a51fc balrog
    p = (uint16_t *) s->io_buffer;
1907 201a51fc balrog
    memset(p, 0, 0x200);
1908 201a51fc balrog
1909 201a51fc balrog
    put_le16(p + 0, s->media_changed);                /* Media status */
1910 201a51fc balrog
    memcpy(p + 1, s->mdata_storage + (((s->hcyl << 16) | s->lcyl) << 9),
1911 201a51fc balrog
                    MIN(MIN(s->mdata_size - (((s->hcyl << 16) | s->lcyl) << 9),
1912 201a51fc balrog
                                    s->nsector << 9), 0x200 - 2));
1913 201a51fc balrog
}
1914 201a51fc balrog
1915 201a51fc balrog
static void ide_cfata_metadata_write(IDEState *s)
1916 201a51fc balrog
{
1917 201a51fc balrog
    if (((s->hcyl << 16) | s->lcyl) << 9 > s->mdata_size + 2) {
1918 201a51fc balrog
        s->status = ERR_STAT;
1919 201a51fc balrog
        s->error = ABRT_ERR;
1920 201a51fc balrog
        return;
1921 201a51fc balrog
    }
1922 201a51fc balrog
1923 201a51fc balrog
    s->media_changed = 0;
1924 201a51fc balrog
1925 201a51fc balrog
    memcpy(s->mdata_storage + (((s->hcyl << 16) | s->lcyl) << 9),
1926 201a51fc balrog
                    s->io_buffer + 2,
1927 201a51fc balrog
                    MIN(MIN(s->mdata_size - (((s->hcyl << 16) | s->lcyl) << 9),
1928 201a51fc balrog
                                    s->nsector << 9), 0x200 - 2));
1929 201a51fc balrog
}
1930 201a51fc balrog
1931 bd491d6a ths
/* called when the inserted state of the media has changed */
1932 bd491d6a ths
static void cdrom_change_cb(void *opaque)
1933 bd491d6a ths
{
1934 bd491d6a ths
    IDEState *s = opaque;
1935 96b8f136 ths
    uint64_t nb_sectors;
1936 bd491d6a ths
1937 bd491d6a ths
    /* XXX: send interrupt too */
1938 bd491d6a ths
    bdrv_get_geometry(s->bs, &nb_sectors);
1939 bd491d6a ths
    s->nb_sectors = nb_sectors;
1940 bd491d6a ths
}
1941 bd491d6a ths
1942 c2ff060f bellard
static void ide_cmd_lba48_transform(IDEState *s, int lba48)
1943 c2ff060f bellard
{
1944 c2ff060f bellard
    s->lba48 = lba48;
1945 c2ff060f bellard
1946 c2ff060f bellard
    /* handle the 'magic' 0 nsector count conversion here. to avoid
1947 c2ff060f bellard
     * fiddling with the rest of the read logic, we just store the
1948 c2ff060f bellard
     * full sector count in ->nsector and ignore ->hob_nsector from now
1949 c2ff060f bellard
     */
1950 c2ff060f bellard
    if (!s->lba48) {
1951 c2ff060f bellard
        if (!s->nsector)
1952 c2ff060f bellard
            s->nsector = 256;
1953 c2ff060f bellard
    } else {
1954 c2ff060f bellard
        if (!s->nsector && !s->hob_nsector)
1955 c2ff060f bellard
            s->nsector = 65536;
1956 c2ff060f bellard
        else {
1957 c2ff060f bellard
            int lo = s->nsector;
1958 c2ff060f bellard
            int hi = s->hob_nsector;
1959 c2ff060f bellard
1960 c2ff060f bellard
            s->nsector = (hi << 8) | lo;
1961 c2ff060f bellard
        }
1962 c2ff060f bellard
    }
1963 c2ff060f bellard
}
1964 c2ff060f bellard
1965 c2ff060f bellard
static void ide_clear_hob(IDEState *ide_if)
1966 c2ff060f bellard
{
1967 c2ff060f bellard
    /* any write clears HOB high bit of device control register */
1968 c2ff060f bellard
    ide_if[0].select &= ~(1 << 7);
1969 c2ff060f bellard
    ide_if[1].select &= ~(1 << 7);
1970 c2ff060f bellard
}
1971 c2ff060f bellard
1972 caed8802 bellard
static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
1973 caed8802 bellard
{
1974 caed8802 bellard
    IDEState *ide_if = opaque;
1975 c45c3d00 bellard
    IDEState *s;
1976 5391d806 bellard
    int unit, n;
1977 c2ff060f bellard
    int lba48 = 0;
1978 5391d806 bellard
1979 5391d806 bellard
#ifdef DEBUG_IDE
1980 5391d806 bellard
    printf("IDE: write addr=0x%x val=0x%02x\n", addr, val);
1981 5391d806 bellard
#endif
1982 c2ff060f bellard
1983 5391d806 bellard
    addr &= 7;
1984 fcdd25ab aliguori
1985 fcdd25ab aliguori
    /* ignore writes to command block while busy with previous command */
1986 fcdd25ab aliguori
    if (addr != 7 && (ide_if->cur_drive->status & (BUSY_STAT|DRQ_STAT)))
1987 fcdd25ab aliguori
        return;
1988 fcdd25ab aliguori
1989 5391d806 bellard
    switch(addr) {
1990 5391d806 bellard
    case 0:
1991 5391d806 bellard
        break;
1992 5391d806 bellard
    case 1:
1993 c2ff060f bellard
        ide_clear_hob(ide_if);
1994 c45c3d00 bellard
        /* NOTE: data is written to the two drives */
1995 c2ff060f bellard
        ide_if[0].hob_feature = ide_if[0].feature;
1996 c2ff060f bellard
        ide_if[1].hob_feature = ide_if[1].feature;
1997 c45c3d00 bellard
        ide_if[0].feature = val;
1998 c45c3d00 bellard
        ide_if[1].feature = val;
1999 5391d806 bellard
        break;
2000 5391d806 bellard
    case 2:
2001 c2ff060f bellard
        ide_clear_hob(ide_if);
2002 c2ff060f bellard
        ide_if[0].hob_nsector = ide_if[0].nsector;
2003 c2ff060f bellard
        ide_if[1].hob_nsector = ide_if[1].nsector;
2004 c45c3d00 bellard
        ide_if[0].nsector = val;
2005 c45c3d00 bellard
        ide_if[1].nsector = val;
2006 5391d806 bellard
        break;
2007 5391d806 bellard
    case 3:
2008 c2ff060f bellard
        ide_clear_hob(ide_if);
2009 c2ff060f bellard
        ide_if[0].hob_sector = ide_if[0].sector;
2010 c2ff060f bellard
        ide_if[1].hob_sector = ide_if[1].sector;
2011 c45c3d00 bellard
        ide_if[0].sector = val;
2012 c45c3d00 bellard
        ide_if[1].sector = val;
2013 5391d806 bellard
        break;
2014 5391d806 bellard
    case 4:
2015 c2ff060f bellard
        ide_clear_hob(ide_if);
2016 c2ff060f bellard
        ide_if[0].hob_lcyl = ide_if[0].lcyl;
2017 c2ff060f bellard
        ide_if[1].hob_lcyl = ide_if[1].lcyl;
2018 c45c3d00 bellard
        ide_if[0].lcyl = val;
2019 c45c3d00 bellard
        ide_if[1].lcyl = val;
2020 5391d806 bellard
        break;
2021 5391d806 bellard
    case 5:
2022 c2ff060f bellard
        ide_clear_hob(ide_if);
2023 c2ff060f bellard
        ide_if[0].hob_hcyl = ide_if[0].hcyl;
2024 c2ff060f bellard
        ide_if[1].hob_hcyl = ide_if[1].hcyl;
2025 c45c3d00 bellard
        ide_if[0].hcyl = val;
2026 c45c3d00 bellard
        ide_if[1].hcyl = val;
2027 5391d806 bellard
        break;
2028 5391d806 bellard
    case 6:
2029 c2ff060f bellard
        /* FIXME: HOB readback uses bit 7 */
2030 7ae98627 bellard
        ide_if[0].select = (val & ~0x10) | 0xa0;
2031 7ae98627 bellard
        ide_if[1].select = (val | 0x10) | 0xa0;
2032 5391d806 bellard
        /* select drive */
2033 5391d806 bellard
        unit = (val >> 4) & 1;
2034 5391d806 bellard
        s = ide_if + unit;
2035 5391d806 bellard
        ide_if->cur_drive = s;
2036 5391d806 bellard
        break;
2037 5391d806 bellard
    default:
2038 5391d806 bellard
    case 7:
2039 5391d806 bellard
        /* command */
2040 5391d806 bellard
#if defined(DEBUG_IDE)
2041 5391d806 bellard
        printf("ide: CMD=%02x\n", val);
2042 5391d806 bellard
#endif
2043 c45c3d00 bellard
        s = ide_if->cur_drive;
2044 66201e2d bellard
        /* ignore commands to non existant slave */
2045 5fafdf24 ths
        if (s != ide_if && !s->bs)
2046 66201e2d bellard
            break;
2047 c2ff060f bellard
2048 fcdd25ab aliguori
        /* Only DEVICE RESET is allowed while BSY or/and DRQ are set */
2049 fcdd25ab aliguori
        if ((s->status & (BUSY_STAT|DRQ_STAT)) && val != WIN_DEVICE_RESET)
2050 fcdd25ab aliguori
            break;
2051 fcdd25ab aliguori
2052 5391d806 bellard
        switch(val) {
2053 5391d806 bellard
        case WIN_IDENTIFY:
2054 5391d806 bellard
            if (s->bs && !s->is_cdrom) {
2055 201a51fc balrog
                if (!s->is_cf)
2056 201a51fc balrog
                    ide_identify(s);
2057 201a51fc balrog
                else
2058 201a51fc balrog
                    ide_cfata_identify(s);
2059 2a282056 bellard
                s->status = READY_STAT | SEEK_STAT;
2060 5391d806 bellard
                ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
2061 5391d806 bellard
            } else {
2062 5391d806 bellard
                if (s->is_cdrom) {
2063 5391d806 bellard
                    ide_set_signature(s);
2064 5391d806 bellard
                }
2065 5391d806 bellard
                ide_abort_command(s);
2066 5391d806 bellard
            }
2067 5391d806 bellard
            ide_set_irq(s);
2068 5391d806 bellard
            break;
2069 5391d806 bellard
        case WIN_SPECIFY:
2070 5391d806 bellard
        case WIN_RECAL:
2071 a136e5a8 bellard
            s->error = 0;
2072 769bec72 bellard
            s->status = READY_STAT | SEEK_STAT;
2073 5391d806 bellard
            ide_set_irq(s);
2074 5391d806 bellard
            break;
2075 5391d806 bellard
        case WIN_SETMULT:
2076 201a51fc balrog
            if (s->is_cf && s->nsector == 0) {
2077 201a51fc balrog
                /* Disable Read and Write Multiple */
2078 201a51fc balrog
                s->mult_sectors = 0;
2079 41a2b959 aliguori
                s->status = READY_STAT | SEEK_STAT;
2080 201a51fc balrog
            } else if ((s->nsector & 0xff) != 0 &&
2081 39dfc926 ths
                ((s->nsector & 0xff) > MAX_MULT_SECTORS ||
2082 39dfc926 ths
                 (s->nsector & (s->nsector - 1)) != 0)) {
2083 5391d806 bellard
                ide_abort_command(s);
2084 5391d806 bellard
            } else {
2085 292eef5a ths
                s->mult_sectors = s->nsector & 0xff;
2086 41a2b959 aliguori
                s->status = READY_STAT | SEEK_STAT;
2087 5391d806 bellard
            }
2088 5391d806 bellard
            ide_set_irq(s);
2089 5391d806 bellard
            break;
2090 c2ff060f bellard
        case WIN_VERIFY_EXT:
2091 c2ff060f bellard
            lba48 = 1;
2092 4ce900b4 bellard
        case WIN_VERIFY:
2093 4ce900b4 bellard
        case WIN_VERIFY_ONCE:
2094 4ce900b4 bellard
            /* do sector number check ? */
2095 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
2096 41a2b959 aliguori
            s->status = READY_STAT | SEEK_STAT;
2097 4ce900b4 bellard
            ide_set_irq(s);
2098 4ce900b4 bellard
            break;
2099 c2ff060f bellard
        case WIN_READ_EXT:
2100 c2ff060f bellard
            lba48 = 1;
2101 5391d806 bellard
        case WIN_READ:
2102 5391d806 bellard
        case WIN_READ_ONCE:
2103 5fafdf24 ths
            if (!s->bs)
2104 6b136f9e bellard
                goto abort_cmd;
2105 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
2106 5391d806 bellard
            s->req_nb_sectors = 1;
2107 5391d806 bellard
            ide_sector_read(s);
2108 5391d806 bellard
            break;
2109 c2ff060f bellard
        case WIN_WRITE_EXT:
2110 c2ff060f bellard
            lba48 = 1;
2111 5391d806 bellard
        case WIN_WRITE:
2112 5391d806 bellard
        case WIN_WRITE_ONCE:
2113 201a51fc balrog
        case CFA_WRITE_SECT_WO_ERASE:
2114 201a51fc balrog
        case WIN_WRITE_VERIFY:
2115 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
2116 a136e5a8 bellard
            s->error = 0;
2117 f66723fa bellard
            s->status = SEEK_STAT | READY_STAT;
2118 5391d806 bellard
            s->req_nb_sectors = 1;
2119 5391d806 bellard
            ide_transfer_start(s, s->io_buffer, 512, ide_sector_write);
2120 201a51fc balrog
            s->media_changed = 1;
2121 5391d806 bellard
            break;
2122 c2ff060f bellard
        case WIN_MULTREAD_EXT:
2123 c2ff060f bellard
            lba48 = 1;
2124 5391d806 bellard
        case WIN_MULTREAD:
2125 5391d806 bellard
            if (!s->mult_sectors)
2126 5391d806 bellard
                goto abort_cmd;
2127 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
2128 5391d806 bellard
            s->req_nb_sectors = s->mult_sectors;
2129 5391d806 bellard
            ide_sector_read(s);
2130 5391d806 bellard
            break;
2131 c2ff060f bellard
        case WIN_MULTWRITE_EXT:
2132 c2ff060f bellard
            lba48 = 1;
2133 5391d806 bellard
        case WIN_MULTWRITE:
2134 201a51fc balrog
        case CFA_WRITE_MULTI_WO_ERASE:
2135 5391d806 bellard
            if (!s->mult_sectors)
2136 5391d806 bellard
                goto abort_cmd;
2137 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
2138 a136e5a8 bellard
            s->error = 0;
2139 f66723fa bellard
            s->status = SEEK_STAT | READY_STAT;
2140 5391d806 bellard
            s->req_nb_sectors = s->mult_sectors;
2141 5391d806 bellard
            n = s->nsector;
2142 5391d806 bellard
            if (n > s->req_nb_sectors)
2143 5391d806 bellard
                n = s->req_nb_sectors;
2144 5391d806 bellard
            ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
2145 201a51fc balrog
            s->media_changed = 1;
2146 5391d806 bellard
            break;
2147 c2ff060f bellard
        case WIN_READDMA_EXT:
2148 c2ff060f bellard
            lba48 = 1;
2149 98087450 bellard
        case WIN_READDMA:
2150 98087450 bellard
        case WIN_READDMA_ONCE:
2151 5fafdf24 ths
            if (!s->bs)
2152 98087450 bellard
                goto abort_cmd;
2153 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
2154 98087450 bellard
            ide_sector_read_dma(s);
2155 98087450 bellard
            break;
2156 c2ff060f bellard
        case WIN_WRITEDMA_EXT:
2157 c2ff060f bellard
            lba48 = 1;
2158 98087450 bellard
        case WIN_WRITEDMA:
2159 98087450 bellard
        case WIN_WRITEDMA_ONCE:
2160 5fafdf24 ths
            if (!s->bs)
2161 98087450 bellard
                goto abort_cmd;
2162 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
2163 98087450 bellard
            ide_sector_write_dma(s);
2164 201a51fc balrog
            s->media_changed = 1;
2165 98087450 bellard
            break;
2166 c2ff060f bellard
        case WIN_READ_NATIVE_MAX_EXT:
2167 c2ff060f bellard
            lba48 = 1;
2168 5391d806 bellard
        case WIN_READ_NATIVE_MAX:
2169 c2ff060f bellard
            ide_cmd_lba48_transform(s, lba48);
2170 5391d806 bellard
            ide_set_sector(s, s->nb_sectors - 1);
2171 41a2b959 aliguori
            s->status = READY_STAT | SEEK_STAT;
2172 5391d806 bellard
            ide_set_irq(s);
2173 5391d806 bellard
            break;
2174 a136e5a8 bellard
        case WIN_CHECKPOWERMODE1:
2175 201a51fc balrog
        case WIN_CHECKPOWERMODE2:
2176 a136e5a8 bellard
            s->nsector = 0xff; /* device active or idle */
2177 41a2b959 aliguori
            s->status = READY_STAT | SEEK_STAT;
2178 a136e5a8 bellard
            ide_set_irq(s);
2179 a136e5a8 bellard
            break;
2180 34e538ae bellard
        case WIN_SETFEATURES:
2181 34e538ae bellard
            if (!s->bs)
2182 34e538ae bellard
                goto abort_cmd;
2183 34e538ae bellard
            /* XXX: valid for CDROM ? */
2184 34e538ae bellard
            switch(s->feature) {
2185 e1f63470 ths
            case 0xcc: /* reverting to power-on defaults enable */
2186 e1f63470 ths
            case 0x66: /* reverting to power-on defaults disable */
2187 34e538ae bellard
            case 0x02: /* write cache enable */
2188 34e538ae bellard
            case 0x82: /* write cache disable */
2189 34e538ae bellard
            case 0xaa: /* read look-ahead enable */
2190 34e538ae bellard
            case 0x55: /* read look-ahead disable */
2191 201a51fc balrog
            case 0x05: /* set advanced power management mode */
2192 201a51fc balrog
            case 0x85: /* disable advanced power management mode */
2193 201a51fc balrog
            case 0x69: /* NOP */
2194 201a51fc balrog
            case 0x67: /* NOP */
2195 201a51fc balrog
            case 0x96: /* NOP */
2196 201a51fc balrog
            case 0x9a: /* NOP */
2197 c3e88d8c ths
            case 0x42: /* enable Automatic Acoustic Mode */
2198 c3e88d8c ths
            case 0xc2: /* disable Automatic Acoustic Mode */
2199 e0fe67aa bellard
                s->status = READY_STAT | SEEK_STAT;
2200 34e538ae bellard
                ide_set_irq(s);
2201 34e538ae bellard
                break;
2202 94458802 bellard
            case 0x03: { /* set transfer mode */
2203 94458802 bellard
                uint8_t val = s->nsector & 0x07;
2204 94458802 bellard
2205 94458802 bellard
                switch (s->nsector >> 3) {
2206 94458802 bellard
                    case 0x00: /* pio default */
2207 94458802 bellard
                    case 0x01: /* pio mode */
2208 d1b5c20d ths
                        put_le16(s->identify_data + 62,0x07);
2209 d1b5c20d ths
                        put_le16(s->identify_data + 63,0x07);
2210 d1b5c20d ths
                        put_le16(s->identify_data + 88,0x3f);
2211 d1b5c20d ths
                        break;
2212 d1b5c20d ths
                    case 0x02: /* sigle word dma mode*/
2213 d1b5c20d ths
                        put_le16(s->identify_data + 62,0x07 | (1 << (val + 8)));
2214 94458802 bellard
                        put_le16(s->identify_data + 63,0x07);
2215 94458802 bellard
                        put_le16(s->identify_data + 88,0x3f);
2216 94458802 bellard
                        break;
2217 94458802 bellard
                    case 0x04: /* mdma mode */
2218 d1b5c20d ths
                        put_le16(s->identify_data + 62,0x07);
2219 94458802 bellard
                        put_le16(s->identify_data + 63,0x07 | (1 << (val + 8)));
2220 94458802 bellard
                        put_le16(s->identify_data + 88,0x3f);
2221 94458802 bellard
                        break;
2222 94458802 bellard
                    case 0x08: /* udma mode */
2223 d1b5c20d ths
                        put_le16(s->identify_data + 62,0x07);
2224 94458802 bellard
                        put_le16(s->identify_data + 63,0x07);
2225 94458802 bellard
                        put_le16(s->identify_data + 88,0x3f | (1 << (val + 8)));
2226 94458802 bellard
                        break;
2227 94458802 bellard
                    default:
2228 94458802 bellard
                        goto abort_cmd;
2229 94458802 bellard
                }
2230 94458802 bellard
                s->status = READY_STAT | SEEK_STAT;
2231 94458802 bellard
                ide_set_irq(s);
2232 94458802 bellard
                break;
2233 94458802 bellard
            }
2234 34e538ae bellard
            default:
2235 34e538ae bellard
                goto abort_cmd;
2236 34e538ae bellard
            }
2237 34e538ae bellard
            break;
2238 c2ff060f bellard
        case WIN_FLUSH_CACHE:
2239 c2ff060f bellard
        case WIN_FLUSH_CACHE_EXT:
2240 7a6cba61 pbrook
            if (s->bs)
2241 7a6cba61 pbrook
                bdrv_flush(s->bs);
2242 41a2b959 aliguori
            s->status = READY_STAT | SEEK_STAT;
2243 7a6cba61 pbrook
            ide_set_irq(s);
2244 7a6cba61 pbrook
            break;
2245 c3e88d8c ths
        case WIN_STANDBY:
2246 c3e88d8c ths
        case WIN_STANDBY2:
2247 c3e88d8c ths
        case WIN_STANDBYNOW1:
2248 201a51fc balrog
        case WIN_STANDBYNOW2:
2249 c451ee71 bellard
        case WIN_IDLEIMMEDIATE:
2250 201a51fc balrog
        case CFA_IDLEIMMEDIATE:
2251 201a51fc balrog
        case WIN_SETIDLE1:
2252 201a51fc balrog
        case WIN_SETIDLE2:
2253 c3e88d8c ths
        case WIN_SLEEPNOW1:
2254 c3e88d8c ths
        case WIN_SLEEPNOW2:
2255 c3e88d8c ths
            s->status = READY_STAT;
2256 a7dfe172 bellard
            ide_set_irq(s);
2257 a7dfe172 bellard
            break;
2258 5391d806 bellard
            /* ATAPI commands */
2259 5391d806 bellard
        case WIN_PIDENTIFY:
2260 5391d806 bellard
            if (s->is_cdrom) {
2261 5391d806 bellard
                ide_atapi_identify(s);
2262 1298fe63 bellard
                s->status = READY_STAT | SEEK_STAT;
2263 5391d806 bellard
                ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
2264 5391d806 bellard
            } else {
2265 5391d806 bellard
                ide_abort_command(s);
2266 5391d806 bellard
            }
2267 5391d806 bellard
            ide_set_irq(s);
2268 5391d806 bellard
            break;
2269 c451ee71 bellard
        case WIN_DIAGNOSE:
2270 c451ee71 bellard
            ide_set_signature(s);
2271 41a2b959 aliguori
            s->status = READY_STAT | SEEK_STAT;
2272 c451ee71 bellard
            s->error = 0x01;
2273 f5fdd0a8 balrog
            ide_set_irq(s);
2274 c451ee71 bellard
            break;
2275 5391d806 bellard
        case WIN_SRST:
2276 5391d806 bellard
            if (!s->is_cdrom)
2277 5391d806 bellard
                goto abort_cmd;
2278 5391d806 bellard
            ide_set_signature(s);
2279 6b136f9e bellard
            s->status = 0x00; /* NOTE: READY is _not_ set */
2280 5391d806 bellard
            s->error = 0x01;
2281 5391d806 bellard
            break;
2282 5391d806 bellard
        case WIN_PACKETCMD:
2283 5391d806 bellard
            if (!s->is_cdrom)
2284 5391d806 bellard
                goto abort_cmd;
2285 98087450 bellard
            /* overlapping commands not supported */
2286 98087450 bellard
            if (s->feature & 0x02)
2287 5391d806 bellard
                goto abort_cmd;
2288 41a2b959 aliguori
            s->status = READY_STAT | SEEK_STAT;
2289 98087450 bellard
            s->atapi_dma = s->feature & 1;
2290 5391d806 bellard
            s->nsector = 1;
2291 5fafdf24 ths
            ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE,
2292 5391d806 bellard
                               ide_atapi_cmd);
2293 5391d806 bellard
            break;
2294 201a51fc balrog
        /* CF-ATA commands */
2295 201a51fc balrog
        case CFA_REQ_EXT_ERROR_CODE:
2296 201a51fc balrog
            if (!s->is_cf)
2297 201a51fc balrog
                goto abort_cmd;
2298 201a51fc balrog
            s->error = 0x09;    /* miscellaneous error */
2299 41a2b959 aliguori
            s->status = READY_STAT | SEEK_STAT;
2300 201a51fc balrog
            ide_set_irq(s);
2301 201a51fc balrog
            break;
2302 201a51fc balrog
        case CFA_ERASE_SECTORS:
2303 201a51fc balrog
        case CFA_WEAR_LEVEL:
2304 201a51fc balrog
            if (!s->is_cf)
2305 201a51fc balrog
                goto abort_cmd;
2306 201a51fc balrog
            if (val == CFA_WEAR_LEVEL)
2307 201a51fc balrog
                s->nsector = 0;
2308 201a51fc balrog
            if (val == CFA_ERASE_SECTORS)
2309 201a51fc balrog
                s->media_changed = 1;
2310 201a51fc balrog
            s->error = 0x00;
2311 41a2b959 aliguori
            s->status = READY_STAT | SEEK_STAT;
2312 201a51fc balrog
            ide_set_irq(s);
2313 201a51fc balrog
            break;
2314 201a51fc balrog
        case CFA_TRANSLATE_SECTOR:
2315 201a51fc balrog
            if (!s->is_cf)
2316 201a51fc balrog
                goto abort_cmd;
2317 201a51fc balrog
            s->error = 0x00;
2318 41a2b959 aliguori
            s->status = READY_STAT | SEEK_STAT;
2319 201a51fc balrog
            memset(s->io_buffer, 0, 0x200);
2320 201a51fc balrog
            s->io_buffer[0x00] = s->hcyl;                        /* Cyl MSB */
2321 201a51fc balrog
            s->io_buffer[0x01] = s->lcyl;                        /* Cyl LSB */
2322 201a51fc balrog
            s->io_buffer[0x02] = s->select;                        /* Head */
2323 201a51fc balrog
            s->io_buffer[0x03] = s->sector;                        /* Sector */
2324 201a51fc balrog
            s->io_buffer[0x04] = ide_get_sector(s) >> 16;        /* LBA MSB */
2325 201a51fc balrog
            s->io_buffer[0x05] = ide_get_sector(s) >> 8;        /* LBA */
2326 201a51fc balrog
            s->io_buffer[0x06] = ide_get_sector(s) >> 0;        /* LBA LSB */
2327 201a51fc balrog
            s->io_buffer[0x13] = 0x00;                                /* Erase flag */
2328 201a51fc balrog
            s->io_buffer[0x18] = 0x00;                                /* Hot count */
2329 201a51fc balrog
            s->io_buffer[0x19] = 0x00;                                /* Hot count */
2330 201a51fc balrog
            s->io_buffer[0x1a] = 0x01;                                /* Hot count */
2331 201a51fc balrog
            ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
2332 201a51fc balrog
            ide_set_irq(s);
2333 201a51fc balrog
            break;
2334 201a51fc balrog
        case CFA_ACCESS_METADATA_STORAGE:
2335 201a51fc balrog
            if (!s->is_cf)
2336 201a51fc balrog
                goto abort_cmd;
2337 201a51fc balrog
            switch (s->feature) {
2338 201a51fc balrog
            case 0x02:        /* Inquiry Metadata Storage */
2339 201a51fc balrog
                ide_cfata_metadata_inquiry(s);
2340 201a51fc balrog
                break;
2341 201a51fc balrog
            case 0x03:        /* Read Metadata Storage */
2342 201a51fc balrog
                ide_cfata_metadata_read(s);
2343 201a51fc balrog
                break;
2344 201a51fc balrog
            case 0x04:        /* Write Metadata Storage */
2345 201a51fc balrog
                ide_cfata_metadata_write(s);
2346 201a51fc balrog
                break;
2347 201a51fc balrog
            default:
2348 201a51fc balrog
                goto abort_cmd;
2349 201a51fc balrog
            }
2350 201a51fc balrog
            ide_transfer_start(s, s->io_buffer, 0x200, ide_transfer_stop);
2351 201a51fc balrog
            s->status = 0x00; /* NOTE: READY is _not_ set */
2352 201a51fc balrog
            ide_set_irq(s);
2353 201a51fc balrog
            break;
2354 201a51fc balrog
        case IBM_SENSE_CONDITION:
2355 201a51fc balrog
            if (!s->is_cf)
2356 201a51fc balrog
                goto abort_cmd;
2357 201a51fc balrog
            switch (s->feature) {
2358 201a51fc balrog
            case 0x01:  /* sense temperature in device */
2359 201a51fc balrog
                s->nsector = 0x50;      /* +20 C */
2360 201a51fc balrog
                break;
2361 201a51fc balrog
            default:
2362 201a51fc balrog
                goto abort_cmd;
2363 201a51fc balrog
            }
2364 41a2b959 aliguori
            s->status = READY_STAT | SEEK_STAT;
2365 201a51fc balrog
            ide_set_irq(s);
2366 201a51fc balrog
            break;
2367 5391d806 bellard
        default:
2368 5391d806 bellard
        abort_cmd:
2369 5391d806 bellard
            ide_abort_command(s);
2370 5391d806 bellard
            ide_set_irq(s);
2371 5391d806 bellard
            break;
2372 5391d806 bellard
        }
2373 5391d806 bellard
    }
2374 5391d806 bellard
}
2375 5391d806 bellard
2376 caed8802 bellard
static uint32_t ide_ioport_read(void *opaque, uint32_t addr1)
2377 5391d806 bellard
{
2378 7ae98627 bellard
    IDEState *ide_if = opaque;
2379 7ae98627 bellard
    IDEState *s = ide_if->cur_drive;
2380 5391d806 bellard
    uint32_t addr;
2381 c2ff060f bellard
    int ret, hob;
2382 5391d806 bellard
2383 5391d806 bellard
    addr = addr1 & 7;
2384 c2ff060f bellard
    /* FIXME: HOB readback uses bit 7, but it's always set right now */
2385 c2ff060f bellard
    //hob = s->select & (1 << 7);
2386 c2ff060f bellard
    hob = 0;
2387 5391d806 bellard
    switch(addr) {
2388 5391d806 bellard
    case 0:
2389 5391d806 bellard
        ret = 0xff;
2390 5391d806 bellard
        break;
2391 5391d806 bellard
    case 1:
2392 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
2393 c45c3d00 bellard
            ret = 0;
2394 c2ff060f bellard
        else if (!hob)
2395 c45c3d00 bellard
            ret = s->error;
2396 c2ff060f bellard
        else
2397 c2ff060f bellard
            ret = s->hob_feature;
2398 5391d806 bellard
        break;
2399 5391d806 bellard
    case 2:
2400 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
2401 c45c3d00 bellard
            ret = 0;
2402 c2ff060f bellard
        else if (!hob)
2403 c45c3d00 bellard
            ret = s->nsector & 0xff;
2404 c2ff060f bellard
        else
2405 c2ff060f bellard
            ret = s->hob_nsector;
2406 5391d806 bellard
        break;
2407 5391d806 bellard
    case 3:
2408 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
2409 c45c3d00 bellard
            ret = 0;
2410 c2ff060f bellard
        else if (!hob)
2411 c45c3d00 bellard
            ret = s->sector;
2412 c2ff060f bellard
        else
2413 c2ff060f bellard
            ret = s->hob_sector;
2414 5391d806 bellard
        break;
2415 5391d806 bellard
    case 4:
2416 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
2417 c45c3d00 bellard
            ret = 0;
2418 c2ff060f bellard
        else if (!hob)
2419 c45c3d00 bellard
            ret = s->lcyl;
2420 c2ff060f bellard
        else
2421 c2ff060f bellard
            ret = s->hob_lcyl;
2422 5391d806 bellard
        break;
2423 5391d806 bellard
    case 5:
2424 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
2425 c45c3d00 bellard
            ret = 0;
2426 c2ff060f bellard
        else if (!hob)
2427 c45c3d00 bellard
            ret = s->hcyl;
2428 c2ff060f bellard
        else
2429 c2ff060f bellard
            ret = s->hob_hcyl;
2430 5391d806 bellard
        break;
2431 5391d806 bellard
    case 6:
2432 7ae98627 bellard
        if (!ide_if[0].bs && !ide_if[1].bs)
2433 c45c3d00 bellard
            ret = 0;
2434 c45c3d00 bellard
        else
2435 7ae98627 bellard
            ret = s->select;
2436 5391d806 bellard
        break;
2437 5391d806 bellard
    default:
2438 5391d806 bellard
    case 7:
2439 66201e2d bellard
        if ((!ide_if[0].bs && !ide_if[1].bs) ||
2440 66201e2d bellard
            (s != ide_if && !s->bs))
2441 c45c3d00 bellard
            ret = 0;
2442 c45c3d00 bellard
        else
2443 c45c3d00 bellard
            ret = s->status;
2444 d537cf6c pbrook
        qemu_irq_lower(s->irq);
2445 5391d806 bellard
        break;
2446 5391d806 bellard
    }
2447 5391d806 bellard
#ifdef DEBUG_IDE
2448 5391d806 bellard
    printf("ide: read addr=0x%x val=%02x\n", addr1, ret);
2449 5391d806 bellard
#endif
2450 5391d806 bellard
    return ret;
2451 5391d806 bellard
}
2452 5391d806 bellard
2453 caed8802 bellard
static uint32_t ide_status_read(void *opaque, uint32_t addr)
2454 5391d806 bellard
{
2455 7ae98627 bellard
    IDEState *ide_if = opaque;
2456 7ae98627 bellard
    IDEState *s = ide_if->cur_drive;
2457 5391d806 bellard
    int ret;
2458 7ae98627 bellard
2459 66201e2d bellard
    if ((!ide_if[0].bs && !ide_if[1].bs) ||
2460 66201e2d bellard
        (s != ide_if && !s->bs))
2461 7ae98627 bellard
        ret = 0;
2462 7ae98627 bellard
    else
2463 7ae98627 bellard
        ret = s->status;
2464 5391d806 bellard
#ifdef DEBUG_IDE
2465 5391d806 bellard
    printf("ide: read status addr=0x%x val=%02x\n", addr, ret);
2466 5391d806 bellard
#endif
2467 5391d806 bellard
    return ret;
2468 5391d806 bellard
}
2469 5391d806 bellard
2470 caed8802 bellard
static void ide_cmd_write(void *opaque, uint32_t addr, uint32_t val)
2471 5391d806 bellard
{
2472 caed8802 bellard
    IDEState *ide_if = opaque;
2473 5391d806 bellard
    IDEState *s;
2474 5391d806 bellard
    int i;
2475 5391d806 bellard
2476 5391d806 bellard
#ifdef DEBUG_IDE
2477 5391d806 bellard
    printf("ide: write control addr=0x%x val=%02x\n", addr, val);
2478 5391d806 bellard
#endif
2479 5391d806 bellard
    /* common for both drives */
2480 5391d806 bellard
    if (!(ide_if[0].cmd & IDE_CMD_RESET) &&
2481 5391d806 bellard
        (val & IDE_CMD_RESET)) {
2482 5391d806 bellard
        /* reset low to high */
2483 5391d806 bellard
        for(i = 0;i < 2; i++) {
2484 5391d806 bellard
            s = &ide_if[i];
2485 5391d806 bellard
            s->status = BUSY_STAT | SEEK_STAT;
2486 5391d806 bellard
            s->error = 0x01;
2487 5391d806 bellard
        }
2488 5391d806 bellard
    } else if ((ide_if[0].cmd & IDE_CMD_RESET) &&
2489 5391d806 bellard
               !(val & IDE_CMD_RESET)) {
2490 5391d806 bellard
        /* high to low */
2491 5391d806 bellard
        for(i = 0;i < 2; i++) {
2492 5391d806 bellard
            s = &ide_if[i];
2493 6b136f9e bellard
            if (s->is_cdrom)
2494 6b136f9e bellard
                s->status = 0x00; /* NOTE: READY is _not_ set */
2495 6b136f9e bellard
            else
2496 56bf1d37 bellard
                s->status = READY_STAT | SEEK_STAT;
2497 5391d806 bellard
            ide_set_signature(s);
2498 5391d806 bellard
        }
2499 5391d806 bellard
    }
2500 5391d806 bellard
2501 5391d806 bellard
    ide_if[0].cmd = val;
2502 5391d806 bellard
    ide_if[1].cmd = val;
2503 5391d806 bellard
}
2504 5391d806 bellard
2505 caed8802 bellard
static void ide_data_writew(void *opaque, uint32_t addr, uint32_t val)
2506 5391d806 bellard
{
2507 caed8802 bellard
    IDEState *s = ((IDEState *)opaque)->cur_drive;
2508 5391d806 bellard
    uint8_t *p;
2509 5391d806 bellard
2510 fcdd25ab aliguori
    /* PIO data access allowed only when DRQ bit is set */
2511 fcdd25ab aliguori
    if (!(s->status & DRQ_STAT))
2512 fcdd25ab aliguori
        return;
2513 fcdd25ab aliguori
2514 5391d806 bellard
    p = s->data_ptr;
2515 0c4ad8dc bellard
    *(uint16_t *)p = le16_to_cpu(val);
2516 5391d806 bellard
    p += 2;
2517 5391d806 bellard
    s->data_ptr = p;
2518 5391d806 bellard
    if (p >= s->data_end)
2519 5391d806 bellard
        s->end_transfer_func(s);
2520 5391d806 bellard
}
2521 5391d806 bellard
2522 caed8802 bellard
static uint32_t ide_data_readw(void *opaque, uint32_t addr)
2523 5391d806 bellard
{
2524 caed8802 bellard
    IDEState *s = ((IDEState *)opaque)->cur_drive;
2525 5391d806 bellard
    uint8_t *p;
2526 5391d806 bellard
    int ret;
2527 fcdd25ab aliguori
2528 fcdd25ab aliguori
    /* PIO data access allowed only when DRQ bit is set */
2529 fcdd25ab aliguori
    if (!(s->status & DRQ_STAT))
2530 fcdd25ab aliguori
        return 0;
2531 fcdd25ab aliguori
2532 5391d806 bellard
    p = s->data_ptr;
2533 0c4ad8dc bellard
    ret = cpu_to_le16(*(uint16_t *)p);
2534 5391d806 bellard
    p += 2;
2535 5391d806 bellard
    s->data_ptr = p;
2536 5391d806 bellard
    if (p >= s->data_end)
2537 5391d806 bellard
        s->end_transfer_func(s);
2538 5391d806 bellard
    return ret;
2539 5391d806 bellard
}
2540 5391d806 bellard
2541 caed8802 bellard
static void ide_data_writel(void *opaque, uint32_t addr, uint32_t val)
2542 5391d806 bellard
{
2543 caed8802 bellard
    IDEState *s = ((IDEState *)opaque)->cur_drive;
2544 5391d806 bellard
    uint8_t *p;
2545 5391d806 bellard
2546 fcdd25ab aliguori
    /* PIO data access allowed only when DRQ bit is set */
2547 fcdd25ab aliguori
    if (!(s->status & DRQ_STAT))
2548 fcdd25ab aliguori
        return;
2549 fcdd25ab aliguori
2550 5391d806 bellard
    p = s->data_ptr;
2551 0c4ad8dc bellard
    *(uint32_t *)p = le32_to_cpu(val);
2552 5391d806 bellard
    p += 4;
2553 5391d806 bellard
    s->data_ptr = p;
2554 5391d806 bellard
    if (p >= s->data_end)
2555 5391d806 bellard
        s->end_transfer_func(s);
2556 5391d806 bellard
}
2557 5391d806 bellard
2558 caed8802 bellard
static uint32_t ide_data_readl(void *opaque, uint32_t addr)
2559 5391d806 bellard
{
2560 caed8802 bellard
    IDEState *s = ((IDEState *)opaque)->cur_drive;
2561 5391d806 bellard
    uint8_t *p;
2562 5391d806 bellard
    int ret;
2563 3b46e624 ths
2564 fcdd25ab aliguori
    /* PIO data access allowed only when DRQ bit is set */
2565 fcdd25ab aliguori
    if (!(s->status & DRQ_STAT))
2566 fcdd25ab aliguori
        return 0;
2567 fcdd25ab aliguori
2568 5391d806 bellard
    p = s->data_ptr;
2569 0c4ad8dc bellard
    ret = cpu_to_le32(*(uint32_t *)p);
2570 5391d806 bellard
    p += 4;
2571 5391d806 bellard
    s->data_ptr = p;
2572 5391d806 bellard
    if (p >= s->data_end)
2573 5391d806 bellard
        s->end_transfer_func(s);
2574 5391d806 bellard
    return ret;
2575 5391d806 bellard
}
2576 5391d806 bellard
2577 a7dfe172 bellard
static void ide_dummy_transfer_stop(IDEState *s)
2578 a7dfe172 bellard
{
2579 a7dfe172 bellard
    s->data_ptr = s->io_buffer;
2580 a7dfe172 bellard
    s->data_end = s->io_buffer;
2581 a7dfe172 bellard
    s->io_buffer[0] = 0xff;
2582 a7dfe172 bellard
    s->io_buffer[1] = 0xff;
2583 a7dfe172 bellard
    s->io_buffer[2] = 0xff;
2584 a7dfe172 bellard
    s->io_buffer[3] = 0xff;
2585 a7dfe172 bellard
}
2586 a7dfe172 bellard
2587 5391d806 bellard
static void ide_reset(IDEState *s)
2588 5391d806 bellard
{
2589 201a51fc balrog
    if (s->is_cf)
2590 201a51fc balrog
        s->mult_sectors = 0;
2591 201a51fc balrog
    else
2592 201a51fc balrog
        s->mult_sectors = MAX_MULT_SECTORS;
2593 5391d806 bellard
    s->cur_drive = s;
2594 5391d806 bellard
    s->select = 0xa0;
2595 41a2b959 aliguori
    s->status = READY_STAT | SEEK_STAT;
2596 5391d806 bellard
    ide_set_signature(s);
2597 a7dfe172 bellard
    /* init the transfer handler so that 0xffff is returned on data
2598 a7dfe172 bellard
       accesses */
2599 a7dfe172 bellard
    s->end_transfer_func = ide_dummy_transfer_stop;
2600 a7dfe172 bellard
    ide_dummy_transfer_stop(s);
2601 201a51fc balrog
    s->media_changed = 0;
2602 5391d806 bellard
}
2603 5391d806 bellard
2604 5391d806 bellard
struct partition {
2605 5391d806 bellard
        uint8_t boot_ind;                /* 0x80 - active */
2606 5391d806 bellard
        uint8_t head;                /* starting head */
2607 5391d806 bellard
        uint8_t sector;                /* starting sector */
2608 5391d806 bellard
        uint8_t cyl;                /* starting cylinder */
2609 5391d806 bellard
        uint8_t sys_ind;                /* What partition type */
2610 5391d806 bellard
        uint8_t end_head;                /* end head */
2611 5391d806 bellard
        uint8_t end_sector;        /* end sector */
2612 5391d806 bellard
        uint8_t end_cyl;                /* end cylinder */
2613 5391d806 bellard
        uint32_t start_sect;        /* starting sector counting from 0 */
2614 5391d806 bellard
        uint32_t nr_sects;                /* nr of sectors in partition */
2615 5391d806 bellard
} __attribute__((packed));
2616 5391d806 bellard
2617 bf1b938f bellard
/* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */
2618 5fafdf24 ths
static int guess_disk_lchs(IDEState *s,
2619 bf1b938f bellard
                           int *pcylinders, int *pheads, int *psectors)
2620 5391d806 bellard
{
2621 c717d8bf balrog
    uint8_t *buf = s->io_buffer;
2622 46d4767d bellard
    int ret, i, heads, sectors, cylinders;
2623 5391d806 bellard
    struct partition *p;
2624 5391d806 bellard
    uint32_t nr_sects;
2625 5391d806 bellard
2626 5391d806 bellard
    ret = bdrv_read(s->bs, 0, buf, 1);
2627 33f00271 balrog
    if (ret < 0) {
2628 bf1b938f bellard
        return -1;
2629 33f00271 balrog
    }
2630 5391d806 bellard
    /* test msdos magic */
2631 33f00271 balrog
    if (buf[510] != 0x55 || buf[511] != 0xaa) {
2632 bf1b938f bellard
        return -1;
2633 33f00271 balrog
    }
2634 5391d806 bellard
    for(i = 0; i < 4; i++) {
2635 5391d806 bellard
        p = ((struct partition *)(buf + 0x1be)) + i;
2636 0c4ad8dc bellard
        nr_sects = le32_to_cpu(p->nr_sects);
2637 5391d806 bellard
        if (nr_sects && p->end_head) {
2638 5391d806 bellard
            /* We make the assumption that the partition terminates on
2639 5391d806 bellard
               a cylinder boundary */
2640 46d4767d bellard
            heads = p->end_head + 1;
2641 46d4767d bellard
            sectors = p->end_sector & 63;
2642 46d4767d bellard
            if (sectors == 0)
2643 46d4767d bellard
                continue;
2644 46d4767d bellard
            cylinders = s->nb_sectors / (heads * sectors);
2645 46d4767d bellard
            if (cylinders < 1 || cylinders > 16383)
2646 46d4767d bellard
                continue;
2647 bf1b938f bellard
            *pheads = heads;
2648 bf1b938f bellard
            *psectors = sectors;
2649 bf1b938f bellard
            *pcylinders = cylinders;
2650 5391d806 bellard
#if 0
2651 5fafdf24 ths
            printf("guessed geometry: LCHS=%d %d %d\n",
2652 bf1b938f bellard
                   cylinders, heads, sectors);
2653 5391d806 bellard
#endif
2654 bf1b938f bellard
            return 0;
2655 5391d806 bellard
        }
2656 5391d806 bellard
    }
2657 bf1b938f bellard
    return -1;
2658 5391d806 bellard
}
2659 5391d806 bellard
2660 5457c8ce bellard
static void ide_init2(IDEState *ide_state,
2661 5457c8ce bellard
                      BlockDriverState *hd0, BlockDriverState *hd1,
2662 d537cf6c pbrook
                      qemu_irq irq)
2663 5391d806 bellard
{
2664 69b91039 bellard
    IDEState *s;
2665 aedf5382 bellard
    static int drive_serial = 1;
2666 4dbb0f50 ths
    int i, cylinders, heads, secs, translation, lba_detected = 0;
2667 96b8f136 ths
    uint64_t nb_sectors;
2668 5391d806 bellard
2669 caed8802 bellard
    for(i = 0; i < 2; i++) {
2670 caed8802 bellard
        s = ide_state + i;
2671 1d8cde5b aurel32
        s->io_buffer = qemu_memalign(512, IDE_DMA_BUF_SECTORS*512 + 4);
2672 caed8802 bellard
        if (i == 0)
2673 caed8802 bellard
            s->bs = hd0;
2674 caed8802 bellard
        else
2675 caed8802 bellard
            s->bs = hd1;
2676 5391d806 bellard
        if (s->bs) {
2677 5391d806 bellard
            bdrv_get_geometry(s->bs, &nb_sectors);
2678 5391d806 bellard
            s->nb_sectors = nb_sectors;
2679 caed8802 bellard
            /* if a geometry hint is available, use it */
2680 caed8802 bellard
            bdrv_get_geometry_hint(s->bs, &cylinders, &heads, &secs);
2681 4dbb0f50 ths
            translation = bdrv_get_translation_hint(s->bs);
2682 caed8802 bellard
            if (cylinders != 0) {
2683 5391d806 bellard
                s->cylinders = cylinders;
2684 caed8802 bellard
                s->heads = heads;
2685 caed8802 bellard
                s->sectors = secs;
2686 caed8802 bellard
            } else {
2687 bf1b938f bellard
                if (guess_disk_lchs(s, &cylinders, &heads, &secs) == 0) {
2688 bf1b938f bellard
                    if (heads > 16) {
2689 bf1b938f bellard
                        /* if heads > 16, it means that a BIOS LBA
2690 bf1b938f bellard
                           translation was active, so the default
2691 bf1b938f bellard
                           hardware geometry is OK */
2692 4dbb0f50 ths
                        lba_detected = 1;
2693 bf1b938f bellard
                        goto default_geometry;
2694 bf1b938f bellard
                    } else {
2695 bf1b938f bellard
                        s->cylinders = cylinders;
2696 bf1b938f bellard
                        s->heads = heads;
2697 bf1b938f bellard
                        s->sectors = secs;
2698 bf1b938f bellard
                        /* disable any translation to be in sync with
2699 bf1b938f bellard
                           the logical geometry */
2700 bf1b938f bellard
                        if (translation == BIOS_ATA_TRANSLATION_AUTO) {
2701 bf1b938f bellard
                            bdrv_set_translation_hint(s->bs,
2702 bf1b938f bellard
                                                      BIOS_ATA_TRANSLATION_NONE);
2703 bf1b938f bellard
                        }
2704 bf1b938f bellard
                    }
2705 bf1b938f bellard
                } else {
2706 bf1b938f bellard
                default_geometry:
2707 46d4767d bellard
                    /* if no geometry, use a standard physical disk geometry */
2708 caed8802 bellard
                    cylinders = nb_sectors / (16 * 63);
2709 caed8802 bellard
                    if (cylinders > 16383)
2710 caed8802 bellard
                        cylinders = 16383;
2711 caed8802 bellard
                    else if (cylinders < 2)
2712 caed8802 bellard
                        cylinders = 2;
2713 caed8802 bellard
                    s->cylinders = cylinders;
2714 caed8802 bellard
                    s->heads = 16;
2715 caed8802 bellard
                    s->sectors = 63;
2716 4dbb0f50 ths
                    if ((lba_detected == 1) && (translation == BIOS_ATA_TRANSLATION_AUTO)) {
2717 4dbb0f50 ths
                      if ((s->cylinders * s->heads) <= 131072) {
2718 4dbb0f50 ths
                        bdrv_set_translation_hint(s->bs,
2719 4dbb0f50 ths
                                                  BIOS_ATA_TRANSLATION_LARGE);
2720 4dbb0f50 ths
                      } else {
2721 4dbb0f50 ths
                        bdrv_set_translation_hint(s->bs,
2722 4dbb0f50 ths
                                                  BIOS_ATA_TRANSLATION_LBA);
2723 4dbb0f50 ths
                      }
2724 4dbb0f50 ths
                    }
2725 caed8802 bellard
                }
2726 769bec72 bellard
                bdrv_set_geometry_hint(s->bs, s->cylinders, s->heads, s->sectors);
2727 caed8802 bellard
            }
2728 caed8802 bellard
            if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) {
2729 caed8802 bellard
                s->is_cdrom = 1;
2730 bd491d6a ths
                bdrv_set_change_cb(s->bs, cdrom_change_cb, s);
2731 5391d806 bellard
            }
2732 5391d806 bellard
        }
2733 aedf5382 bellard
        s->drive_serial = drive_serial++;
2734 caed8802 bellard
        s->irq = irq;
2735 5fafdf24 ths
        s->sector_write_timer = qemu_new_timer(vm_clock,
2736 a09db21f bellard
                                               ide_sector_write_timer_cb, s);
2737 5391d806 bellard
        ide_reset(s);
2738 5391d806 bellard
    }
2739 69b91039 bellard
}
2740 69b91039 bellard
2741 34e538ae bellard
static void ide_init_ioport(IDEState *ide_state, int iobase, int iobase2)
2742 69b91039 bellard
{
2743 caed8802 bellard
    register_ioport_write(iobase, 8, 1, ide_ioport_write, ide_state);
2744 caed8802 bellard
    register_ioport_read(iobase, 8, 1, ide_ioport_read, ide_state);
2745 caed8802 bellard
    if (iobase2) {
2746 caed8802 bellard
        register_ioport_read(iobase2, 1, 1, ide_status_read, ide_state);
2747 caed8802 bellard
        register_ioport_write(iobase2, 1, 1, ide_cmd_write, ide_state);
2748 5391d806 bellard
    }
2749 3b46e624 ths
2750 caed8802 bellard
    /* data ports */
2751 caed8802 bellard
    register_ioport_write(iobase, 2, 2, ide_data_writew, ide_state);
2752 caed8802 bellard
    register_ioport_read(iobase, 2, 2, ide_data_readw, ide_state);
2753 caed8802 bellard
    register_ioport_write(iobase, 4, 4, ide_data_writel, ide_state);
2754 caed8802 bellard
    register_ioport_read(iobase, 4, 4, ide_data_readl, ide_state);
2755 5391d806 bellard
}
2756 69b91039 bellard
2757 aa941b94 balrog
/* save per IDE drive data */
2758 aa941b94 balrog
static void ide_save(QEMUFile* f, IDEState *s)
2759 aa941b94 balrog
{
2760 bee8d684 ths
    qemu_put_be32(f, s->mult_sectors);
2761 bee8d684 ths
    qemu_put_be32(f, s->identify_set);
2762 aa941b94 balrog
    if (s->identify_set) {
2763 aa941b94 balrog
        qemu_put_buffer(f, (const uint8_t *)s->identify_data, 512);
2764 aa941b94 balrog
    }
2765 aa941b94 balrog
    qemu_put_8s(f, &s->feature);
2766 aa941b94 balrog
    qemu_put_8s(f, &s->error);
2767 aa941b94 balrog
    qemu_put_be32s(f, &s->nsector);
2768 aa941b94 balrog
    qemu_put_8s(f, &s->sector);
2769 aa941b94 balrog
    qemu_put_8s(f, &s->lcyl);
2770 aa941b94 balrog
    qemu_put_8s(f, &s->hcyl);
2771 aa941b94 balrog
    qemu_put_8s(f, &s->hob_feature);
2772 aa941b94 balrog
    qemu_put_8s(f, &s->hob_nsector);
2773 aa941b94 balrog
    qemu_put_8s(f, &s->hob_sector);
2774 aa941b94 balrog
    qemu_put_8s(f, &s->hob_lcyl);
2775 aa941b94 balrog
    qemu_put_8s(f, &s->hob_hcyl);
2776 aa941b94 balrog
    qemu_put_8s(f, &s->select);
2777 aa941b94 balrog
    qemu_put_8s(f, &s->status);
2778 aa941b94 balrog
    qemu_put_8s(f, &s->lba48);
2779 aa941b94 balrog
2780 aa941b94 balrog
    qemu_put_8s(f, &s->sense_key);
2781 aa941b94 balrog
    qemu_put_8s(f, &s->asc);
2782 aa941b94 balrog
    /* XXX: if a transfer is pending, we do not save it yet */
2783 aa941b94 balrog
}
2784 aa941b94 balrog
2785 aa941b94 balrog
/* load per IDE drive data */
2786 aa941b94 balrog
static void ide_load(QEMUFile* f, IDEState *s)
2787 aa941b94 balrog
{
2788 bee8d684 ths
    s->mult_sectors=qemu_get_be32(f);
2789 bee8d684 ths
    s->identify_set=qemu_get_be32(f);
2790 aa941b94 balrog
    if (s->identify_set) {
2791 aa941b94 balrog
        qemu_get_buffer(f, (uint8_t *)s->identify_data, 512);
2792 aa941b94 balrog
    }
2793 aa941b94 balrog
    qemu_get_8s(f, &s->feature);
2794 aa941b94 balrog
    qemu_get_8s(f, &s->error);
2795 aa941b94 balrog
    qemu_get_be32s(f, &s->nsector);
2796 aa941b94 balrog
    qemu_get_8s(f, &s->sector);
2797 aa941b94 balrog
    qemu_get_8s(f, &s->lcyl);
2798 aa941b94 balrog
    qemu_get_8s(f, &s->hcyl);
2799 aa941b94 balrog
    qemu_get_8s(f, &s->hob_feature);
2800 aa941b94 balrog
    qemu_get_8s(f, &s->hob_nsector);
2801 aa941b94 balrog
    qemu_get_8s(f, &s->hob_sector);
2802 aa941b94 balrog
    qemu_get_8s(f, &s->hob_lcyl);
2803 aa941b94 balrog
    qemu_get_8s(f, &s->hob_hcyl);
2804 aa941b94 balrog
    qemu_get_8s(f, &s->select);
2805 aa941b94 balrog
    qemu_get_8s(f, &s->status);
2806 aa941b94 balrog
    qemu_get_8s(f, &s->lba48);
2807 aa941b94 balrog
2808 aa941b94 balrog
    qemu_get_8s(f, &s->sense_key);
2809 aa941b94 balrog
    qemu_get_8s(f, &s->asc);
2810 aa941b94 balrog
    /* XXX: if a transfer is pending, we do not save it yet */
2811 aa941b94 balrog
}
2812 aa941b94 balrog
2813 69b91039 bellard
/***********************************************************/
2814 34e538ae bellard
/* ISA IDE definitions */
2815 34e538ae bellard
2816 d537cf6c pbrook
void isa_ide_init(int iobase, int iobase2, qemu_irq irq,
2817 34e538ae bellard
                  BlockDriverState *hd0, BlockDriverState *hd1)
2818 34e538ae bellard
{
2819 34e538ae bellard
    IDEState *ide_state;
2820 34e538ae bellard
2821 34e538ae bellard
    ide_state = qemu_mallocz(sizeof(IDEState) * 2);
2822 34e538ae bellard
    if (!ide_state)
2823 34e538ae bellard
        return;
2824 3b46e624 ths
2825 d537cf6c pbrook
    ide_init2(ide_state, hd0, hd1, irq);
2826 34e538ae bellard
    ide_init_ioport(ide_state, iobase, iobase2);
2827 34e538ae bellard
}
2828 34e538ae bellard
2829 34e538ae bellard
/***********************************************************/
2830 69b91039 bellard
/* PCI IDE definitions */
2831 69b91039 bellard
2832 5457c8ce bellard
static void cmd646_update_irq(PCIIDEState *d);
2833 5457c8ce bellard
2834 5fafdf24 ths
static void ide_map(PCIDevice *pci_dev, int region_num,
2835 69b91039 bellard
                    uint32_t addr, uint32_t size, int type)
2836 69b91039 bellard
{
2837 69b91039 bellard
    PCIIDEState *d = (PCIIDEState *)pci_dev;
2838 69b91039 bellard
    IDEState *ide_state;
2839 69b91039 bellard
2840 69b91039 bellard
    if (region_num <= 3) {
2841 69b91039 bellard
        ide_state = &d->ide_if[(region_num >> 1) * 2];
2842 69b91039 bellard
        if (region_num & 1) {
2843 69b91039 bellard
            register_ioport_read(addr + 2, 1, 1, ide_status_read, ide_state);
2844 69b91039 bellard
            register_ioport_write(addr + 2, 1, 1, ide_cmd_write, ide_state);
2845 69b91039 bellard
        } else {
2846 69b91039 bellard
            register_ioport_write(addr, 8, 1, ide_ioport_write, ide_state);
2847 69b91039 bellard
            register_ioport_read(addr, 8, 1, ide_ioport_read, ide_state);
2848 69b91039 bellard
2849 69b91039 bellard
            /* data ports */
2850 69b91039 bellard
            register_ioport_write(addr, 2, 2, ide_data_writew, ide_state);
2851 69b91039 bellard
            register_ioport_read(addr, 2, 2, ide_data_readw, ide_state);
2852 69b91039 bellard
            register_ioport_write(addr, 4, 4, ide_data_writel, ide_state);
2853 69b91039 bellard
            register_ioport_read(addr, 4, 4, ide_data_readl, ide_state);
2854 69b91039 bellard
        }
2855 69b91039 bellard
    }
2856 69b91039 bellard
}
2857 69b91039 bellard
2858 8ccad811 bellard
static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb)
2859 98087450 bellard
{
2860 98087450 bellard
    BMDMAState *bm = s->bmdma;
2861 98087450 bellard
    if(!bm)
2862 98087450 bellard
        return;
2863 98087450 bellard
    bm->ide_if = s;
2864 98087450 bellard
    bm->dma_cb = dma_cb;
2865 8ccad811 bellard
    bm->cur_prd_last = 0;
2866 8ccad811 bellard
    bm->cur_prd_addr = 0;
2867 8ccad811 bellard
    bm->cur_prd_len = 0;
2868 98087450 bellard
    if (bm->status & BM_STATUS_DMAING) {
2869 8ccad811 bellard
        bm->dma_cb(bm, 0);
2870 98087450 bellard
    }
2871 98087450 bellard
}
2872 98087450 bellard
2873 72c7b06c aliguori
static void ide_dma_cancel(BMDMAState *bm)
2874 72c7b06c aliguori
{
2875 72c7b06c aliguori
    if (bm->status & BM_STATUS_DMAING) {
2876 72c7b06c aliguori
        bm->status &= ~BM_STATUS_DMAING;
2877 72c7b06c aliguori
        /* cancel DMA request */
2878 72c7b06c aliguori
        bm->ide_if = NULL;
2879 72c7b06c aliguori
        bm->dma_cb = NULL;
2880 72c7b06c aliguori
        if (bm->aiocb) {
2881 72c7b06c aliguori
#ifdef DEBUG_AIO
2882 72c7b06c aliguori
            printf("aio_cancel\n");
2883 72c7b06c aliguori
#endif
2884 72c7b06c aliguori
            bdrv_aio_cancel(bm->aiocb);
2885 72c7b06c aliguori
            bm->aiocb = NULL;
2886 72c7b06c aliguori
        }
2887 72c7b06c aliguori
    }
2888 72c7b06c aliguori
}
2889 72c7b06c aliguori
2890 98087450 bellard
static void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)
2891 98087450 bellard
{
2892 98087450 bellard
    BMDMAState *bm = opaque;
2893 98087450 bellard
#ifdef DEBUG_IDE
2894 98087450 bellard
    printf("%s: 0x%08x\n", __func__, val);
2895 98087450 bellard
#endif
2896 98087450 bellard
    if (!(val & BM_CMD_START)) {
2897 98087450 bellard
        /* XXX: do it better */
2898 72c7b06c aliguori
        ide_dma_cancel(bm);
2899 98087450 bellard
        bm->cmd = val & 0x09;
2900 98087450 bellard
    } else {
2901 8ccad811 bellard
        if (!(bm->status & BM_STATUS_DMAING)) {
2902 8ccad811 bellard
            bm->status |= BM_STATUS_DMAING;
2903 8ccad811 bellard
            /* start dma transfer if possible */
2904 8ccad811 bellard
            if (bm->dma_cb)
2905 8ccad811 bellard
                bm->dma_cb(bm, 0);
2906 8ccad811 bellard
        }
2907 98087450 bellard
        bm->cmd = val & 0x09;
2908 98087450 bellard
    }
2909 98087450 bellard
}
2910 98087450 bellard
2911 5457c8ce bellard
static uint32_t bmdma_readb(void *opaque, uint32_t addr)
2912 98087450 bellard
{
2913 98087450 bellard
    BMDMAState *bm = opaque;
2914 5457c8ce bellard
    PCIIDEState *pci_dev;
2915 98087450 bellard
    uint32_t val;
2916 3b46e624 ths
2917 5457c8ce bellard
    switch(addr & 3) {
2918 5fafdf24 ths
    case 0:
2919 5457c8ce bellard
        val = bm->cmd;
2920 5457c8ce bellard
        break;
2921 5457c8ce bellard
    case 1:
2922 5457c8ce bellard
        pci_dev = bm->pci_dev;
2923 5457c8ce bellard
        if (pci_dev->type == IDE_TYPE_CMD646) {
2924 5457c8ce bellard
            val = pci_dev->dev.config[MRDMODE];
2925 5457c8ce bellard
        } else {
2926 5457c8ce bellard
            val = 0xff;
2927 5457c8ce bellard
        }
2928 5457c8ce bellard
        break;
2929 5457c8ce bellard
    case 2:
2930 5457c8ce bellard
        val = bm->status;
2931 5457c8ce bellard
        break;
2932 5457c8ce bellard
    case 3:
2933 5457c8ce bellard
        pci_dev = bm->pci_dev;
2934 5457c8ce bellard
        if (pci_dev->type == IDE_TYPE_CMD646) {
2935 5457c8ce bellard
            if (bm == &pci_dev->bmdma[0])
2936 5457c8ce bellard
                val = pci_dev->dev.config[UDIDETCR0];
2937 5457c8ce bellard
            else
2938 5457c8ce bellard
                val = pci_dev->dev.config[UDIDETCR1];
2939 5457c8ce bellard
        } else {
2940 5457c8ce bellard
            val = 0xff;
2941 5457c8ce bellard
        }
2942 5457c8ce bellard
        break;
2943 5457c8ce bellard
    default:
2944 5457c8ce bellard
        val = 0xff;
2945 5457c8ce bellard
        break;
2946 5457c8ce bellard
    }
2947 98087450 bellard
#ifdef DEBUG_IDE
2948 5457c8ce bellard
    printf("bmdma: readb 0x%02x : 0x%02x\n", addr, val);
2949 98087450 bellard
#endif
2950 98087450 bellard
    return val;
2951 98087450 bellard
}
2952 98087450 bellard
2953 5457c8ce bellard
static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val)
2954 98087450 bellard
{
2955 98087450 bellard
    BMDMAState *bm = opaque;
2956 5457c8ce bellard
    PCIIDEState *pci_dev;
2957 98087450 bellard
#ifdef DEBUG_IDE
2958 5457c8ce bellard
    printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val);
2959 98087450 bellard
#endif
2960 5457c8ce bellard
    switch(addr & 3) {
2961 5457c8ce bellard
    case 1:
2962 5457c8ce bellard
        pci_dev = bm->pci_dev;
2963 5457c8ce bellard
        if (pci_dev->type == IDE_TYPE_CMD646) {
2964 5fafdf24 ths
            pci_dev->dev.config[MRDMODE] =
2965 5457c8ce bellard
                (pci_dev->dev.config[MRDMODE] & ~0x30) | (val & 0x30);
2966 5457c8ce bellard
            cmd646_update_irq(pci_dev);
2967 5457c8ce bellard
        }
2968 5457c8ce bellard
        break;
2969 5457c8ce bellard
    case 2:
2970 5457c8ce bellard
        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
2971 5457c8ce bellard
        break;
2972 5457c8ce bellard
    case 3:
2973 5457c8ce bellard
        pci_dev = bm->pci_dev;
2974 5457c8ce bellard
        if (pci_dev->type == IDE_TYPE_CMD646) {
2975 5457c8ce bellard
            if (bm == &pci_dev->bmdma[0])
2976 5457c8ce bellard
                pci_dev->dev.config[UDIDETCR0] = val;
2977 5457c8ce bellard
            else
2978 5457c8ce bellard
                pci_dev->dev.config[UDIDETCR1] = val;
2979 5457c8ce bellard
        }
2980 5457c8ce bellard
        break;
2981 5457c8ce bellard
    }
2982 98087450 bellard
}
2983 98087450 bellard
2984 5b9a1293 aurel32
static uint32_t bmdma_addr_readb(void *opaque, uint32_t addr)
2985 5b9a1293 aurel32
{
2986 5b9a1293 aurel32
    BMDMAState *bm = opaque;
2987 5b9a1293 aurel32
    uint32_t val;
2988 5b9a1293 aurel32
    val = (bm->addr >> ((addr & 3) * 8)) & 0xff;
2989 5b9a1293 aurel32
#ifdef DEBUG_IDE
2990 5b9a1293 aurel32
    printf("%s: 0x%08x\n", __func__, val);
2991 5b9a1293 aurel32
#endif
2992 5b9a1293 aurel32
    return val;
2993 5b9a1293 aurel32
}
2994 5b9a1293 aurel32
2995 5b9a1293 aurel32
static void bmdma_addr_writeb(void *opaque, uint32_t addr, uint32_t val)
2996 5b9a1293 aurel32
{
2997 5b9a1293 aurel32
    BMDMAState *bm = opaque;
2998 5b9a1293 aurel32
    int shift = (addr & 3) * 8;
2999 5b9a1293 aurel32
#ifdef DEBUG_IDE
3000 5b9a1293 aurel32
    printf("%s: 0x%08x\n", __func__, val);
3001 5b9a1293 aurel32
#endif
3002 5b9a1293 aurel32
    bm->addr &= ~(0xFF << shift);
3003 5b9a1293 aurel32
    bm->addr |= ((val & 0xFF) << shift) & ~3;
3004 5b9a1293 aurel32
    bm->cur_addr = bm->addr;
3005 5b9a1293 aurel32
}
3006 5b9a1293 aurel32
3007 5b9a1293 aurel32
static uint32_t bmdma_addr_readw(void *opaque, uint32_t addr)
3008 5b9a1293 aurel32
{
3009 5b9a1293 aurel32
    BMDMAState *bm = opaque;
3010 5b9a1293 aurel32
    uint32_t val;
3011 5b9a1293 aurel32
    val = (bm->addr >> ((addr & 3) * 8)) & 0xffff;
3012 5b9a1293 aurel32
#ifdef DEBUG_IDE
3013 5b9a1293 aurel32
    printf("%s: 0x%08x\n", __func__, val);
3014 5b9a1293 aurel32
#endif
3015 5b9a1293 aurel32
    return val;
3016 5b9a1293 aurel32
}
3017 5b9a1293 aurel32
3018 5b9a1293 aurel32
static void bmdma_addr_writew(void *opaque, uint32_t addr, uint32_t val)
3019 5b9a1293 aurel32
{
3020 5b9a1293 aurel32
    BMDMAState *bm = opaque;
3021 5b9a1293 aurel32
    int shift = (addr & 3) * 8;
3022 5b9a1293 aurel32
#ifdef DEBUG_IDE
3023 5b9a1293 aurel32
    printf("%s: 0x%08x\n", __func__, val);
3024 5b9a1293 aurel32
#endif
3025 5b9a1293 aurel32
    bm->addr &= ~(0xFFFF << shift);
3026 5b9a1293 aurel32
    bm->addr |= ((val & 0xFFFF) << shift) & ~3;
3027 5b9a1293 aurel32
    bm->cur_addr = bm->addr;
3028 5b9a1293 aurel32
}
3029 5b9a1293 aurel32
3030 98087450 bellard
static uint32_t bmdma_addr_readl(void *opaque, uint32_t addr)
3031 98087450 bellard
{
3032 98087450 bellard
    BMDMAState *bm = opaque;
3033 98087450 bellard
    uint32_t val;
3034 98087450 bellard
    val = bm->addr;
3035 98087450 bellard
#ifdef DEBUG_IDE
3036 98087450 bellard
    printf("%s: 0x%08x\n", __func__, val);
3037 98087450 bellard
#endif
3038 98087450 bellard
    return val;
3039 98087450 bellard
}
3040 98087450 bellard
3041 98087450 bellard
static void bmdma_addr_writel(void *opaque, uint32_t addr, uint32_t val)
3042 98087450 bellard
{
3043 98087450 bellard
    BMDMAState *bm = opaque;
3044 98087450 bellard
#ifdef DEBUG_IDE
3045 98087450 bellard
    printf("%s: 0x%08x\n", __func__, val);
3046 98087450 bellard
#endif
3047 98087450 bellard
    bm->addr = val & ~3;
3048 30c4bbac ths
    bm->cur_addr = bm->addr;
3049 98087450 bellard
}
3050 98087450 bellard
3051 5fafdf24 ths
static void bmdma_map(PCIDevice *pci_dev, int region_num,
3052 98087450 bellard
                    uint32_t addr, uint32_t size, int type)
3053 98087450 bellard
{
3054 98087450 bellard
    PCIIDEState *d = (PCIIDEState *)pci_dev;
3055 98087450 bellard
    int i;
3056 98087450 bellard
3057 98087450 bellard
    for(i = 0;i < 2; i++) {
3058 98087450 bellard
        BMDMAState *bm = &d->bmdma[i];
3059 98087450 bellard
        d->ide_if[2 * i].bmdma = bm;
3060 98087450 bellard
        d->ide_if[2 * i + 1].bmdma = bm;
3061 5457c8ce bellard
        bm->pci_dev = (PCIIDEState *)pci_dev;
3062 5457c8ce bellard
3063 98087450 bellard
        register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);
3064 98087450 bellard
3065 5457c8ce bellard
        register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm);
3066 5457c8ce bellard
        register_ioport_read(addr, 4, 1, bmdma_readb, bm);
3067 98087450 bellard
3068 5b9a1293 aurel32
        register_ioport_write(addr + 4, 4, 1, bmdma_addr_writeb, bm);
3069 5b9a1293 aurel32
        register_ioport_read(addr + 4, 4, 1, bmdma_addr_readb, bm);
3070 5b9a1293 aurel32
        register_ioport_write(addr + 4, 4, 2, bmdma_addr_writew, bm);
3071 5b9a1293 aurel32
        register_ioport_read(addr + 4, 4, 2, bmdma_addr_readw, bm);
3072 98087450 bellard
        register_ioport_write(addr + 4, 4, 4, bmdma_addr_writel, bm);
3073 98087450 bellard
        register_ioport_read(addr + 4, 4, 4, bmdma_addr_readl, bm);
3074 98087450 bellard
        addr += 8;
3075 98087450 bellard
    }
3076 98087450 bellard
}
3077 98087450 bellard
3078 5457c8ce bellard
/* XXX: call it also when the MRDMODE is changed from the PCI config
3079 5457c8ce bellard
   registers */
3080 5457c8ce bellard
static void cmd646_update_irq(PCIIDEState *d)
3081 5457c8ce bellard
{
3082 5457c8ce bellard
    int pci_level;
3083 5457c8ce bellard
    pci_level = ((d->dev.config[MRDMODE] & MRDMODE_INTR_CH0) &&
3084 5457c8ce bellard
                 !(d->dev.config[MRDMODE] & MRDMODE_BLK_CH0)) ||
3085 5457c8ce bellard
        ((d->dev.config[MRDMODE] & MRDMODE_INTR_CH1) &&
3086 5457c8ce bellard
         !(d->dev.config[MRDMODE] & MRDMODE_BLK_CH1));
3087 d537cf6c pbrook
    qemu_set_irq(d->dev.irq[0], pci_level);
3088 5457c8ce bellard
}
3089 5457c8ce bellard
3090 5457c8ce bellard
/* the PCI irq level is the logical OR of the two channels */
3091 5457c8ce bellard
static void cmd646_set_irq(void *opaque, int channel, int level)
3092 5457c8ce bellard
{
3093 5457c8ce bellard
    PCIIDEState *d = opaque;
3094 5457c8ce bellard
    int irq_mask;
3095 5457c8ce bellard
3096 5457c8ce bellard
    irq_mask = MRDMODE_INTR_CH0 << channel;
3097 5457c8ce bellard
    if (level)
3098 5457c8ce bellard
        d->dev.config[MRDMODE] |= irq_mask;
3099 5457c8ce bellard
    else
3100 5457c8ce bellard
        d->dev.config[MRDMODE] &= ~irq_mask;
3101 5457c8ce bellard
    cmd646_update_irq(d);
3102 5457c8ce bellard
}
3103 5457c8ce bellard
3104 5457c8ce bellard
/* CMD646 PCI IDE controller */
3105 5457c8ce bellard
void pci_cmd646_ide_init(PCIBus *bus, BlockDriverState **hd_table,
3106 5457c8ce bellard
                         int secondary_ide_enabled)
3107 69b91039 bellard
{
3108 69b91039 bellard
    PCIIDEState *d;
3109 69b91039 bellard
    uint8_t *pci_conf;
3110 34e538ae bellard
    int i;
3111 d537cf6c pbrook
    qemu_irq *irq;
3112 34e538ae bellard
3113 5fafdf24 ths
    d = (PCIIDEState *)pci_register_device(bus, "CMD646 IDE",
3114 5457c8ce bellard
                                           sizeof(PCIIDEState),
3115 5fafdf24 ths
                                           -1,
3116 73c11f63 bellard
                                           NULL, NULL);
3117 5457c8ce bellard
    d->type = IDE_TYPE_CMD646;
3118 69b91039 bellard
    pci_conf = d->dev.config;
3119 5457c8ce bellard
    pci_conf[0x00] = 0x95; // CMD646
3120 5457c8ce bellard
    pci_conf[0x01] = 0x10;
3121 5457c8ce bellard
    pci_conf[0x02] = 0x46;
3122 5457c8ce bellard
    pci_conf[0x03] = 0x06;
3123 5457c8ce bellard
3124 5457c8ce bellard
    pci_conf[0x08] = 0x07; // IDE controller revision
3125 5fafdf24 ths
    pci_conf[0x09] = 0x8f;
3126 5457c8ce bellard
3127 69b91039 bellard
    pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
3128 69b91039 bellard
    pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
3129 5457c8ce bellard
    pci_conf[0x0e] = 0x00; // header_type
3130 3b46e624 ths
3131 5457c8ce bellard
    if (secondary_ide_enabled) {
3132 5457c8ce bellard
        /* XXX: if not enabled, really disable the seconday IDE controller */
3133 5457c8ce bellard
        pci_conf[0x51] = 0x80; /* enable IDE1 */
3134 5457c8ce bellard
    }
3135 69b91039 bellard
3136 5fafdf24 ths
    pci_register_io_region((PCIDevice *)d, 0, 0x8,
3137 69b91039 bellard
                           PCI_ADDRESS_SPACE_IO, ide_map);
3138 5fafdf24 ths
    pci_register_io_region((PCIDevice *)d, 1, 0x4,
3139 69b91039 bellard
                           PCI_ADDRESS_SPACE_IO, ide_map);
3140 5fafdf24 ths
    pci_register_io_region((PCIDevice *)d, 2, 0x8,
3141 69b91039 bellard
                           PCI_ADDRESS_SPACE_IO, ide_map);
3142 5fafdf24 ths
    pci_register_io_region((PCIDevice *)d, 3, 0x4,
3143 69b91039 bellard
                           PCI_ADDRESS_SPACE_IO, ide_map);
3144 5fafdf24 ths
    pci_register_io_region((PCIDevice *)d, 4, 0x10,
3145 98087450 bellard
                           PCI_ADDRESS_SPACE_IO, bmdma_map);
3146 69b91039 bellard
3147 34e538ae bellard
    pci_conf[0x3d] = 0x01; // interrupt on pin 1
3148 3b46e624 ths
3149 34e538ae bellard
    for(i = 0; i < 4; i++)
3150 34e538ae bellard
        d->ide_if[i].pci_dev = (PCIDevice *)d;
3151 d537cf6c pbrook
3152 d537cf6c pbrook
    irq = qemu_allocate_irqs(cmd646_set_irq, d, 2);
3153 d537cf6c pbrook
    ide_init2(&d->ide_if[0], hd_table[0], hd_table[1], irq[0]);
3154 d537cf6c pbrook
    ide_init2(&d->ide_if[2], hd_table[2], hd_table[3], irq[1]);
3155 34e538ae bellard
}
3156 34e538ae bellard
3157 c3d78997 bellard
static void pci_ide_save(QEMUFile* f, void *opaque)
3158 c3d78997 bellard
{
3159 c3d78997 bellard
    PCIIDEState *d = opaque;
3160 c3d78997 bellard
    int i;
3161 c3d78997 bellard
3162 c3d78997 bellard
    pci_device_save(&d->dev, f);
3163 c3d78997 bellard
3164 c3d78997 bellard
    for(i = 0; i < 2; i++) {
3165 c3d78997 bellard
        BMDMAState *bm = &d->bmdma[i];
3166 c3d78997 bellard
        qemu_put_8s(f, &bm->cmd);
3167 c3d78997 bellard
        qemu_put_8s(f, &bm->status);
3168 c3d78997 bellard
        qemu_put_be32s(f, &bm->addr);
3169 c3d78997 bellard
        /* XXX: if a transfer is pending, we do not save it yet */
3170 c3d78997 bellard
    }
3171 c3d78997 bellard
3172 c3d78997 bellard
    /* per IDE interface data */
3173 c3d78997 bellard
    for(i = 0; i < 2; i++) {
3174 c3d78997 bellard
        IDEState *s = &d->ide_if[i * 2];
3175 c3d78997 bellard
        uint8_t drive1_selected;
3176 c3d78997 bellard
        qemu_put_8s(f, &s->cmd);
3177 c3d78997 bellard
        drive1_selected = (s->cur_drive != s);
3178 c3d78997 bellard
        qemu_put_8s(f, &drive1_selected);
3179 c3d78997 bellard
    }
3180 c3d78997 bellard
3181 c3d78997 bellard
    /* per IDE drive data */
3182 c3d78997 bellard
    for(i = 0; i < 4; i++) {
3183 aa941b94 balrog
        ide_save(f, &d->ide_if[i]);
3184 c3d78997 bellard
    }
3185 c3d78997 bellard
}
3186 c3d78997 bellard
3187 c3d78997 bellard
static int pci_ide_load(QEMUFile* f, void *opaque, int version_id)
3188 c3d78997 bellard
{
3189 c3d78997 bellard
    PCIIDEState *d = opaque;
3190 c3d78997 bellard
    int ret, i;
3191 c3d78997 bellard
3192 c3d78997 bellard
    if (version_id != 1)
3193 c3d78997 bellard
        return -EINVAL;
3194 c3d78997 bellard
    ret = pci_device_load(&d->dev, f);
3195 c3d78997 bellard
    if (ret < 0)
3196 c3d78997 bellard
        return ret;
3197 c3d78997 bellard
3198 c3d78997 bellard
    for(i = 0; i < 2; i++) {
3199 c3d78997 bellard
        BMDMAState *bm = &d->bmdma[i];
3200 c3d78997 bellard
        qemu_get_8s(f, &bm->cmd);
3201 c3d78997 bellard
        qemu_get_8s(f, &bm->status);
3202 c3d78997 bellard
        qemu_get_be32s(f, &bm->addr);
3203 c3d78997 bellard
        /* XXX: if a transfer is pending, we do not save it yet */
3204 c3d78997 bellard
    }
3205 c3d78997 bellard
3206 c3d78997 bellard
    /* per IDE interface data */
3207 c3d78997 bellard
    for(i = 0; i < 2; i++) {
3208 c3d78997 bellard
        IDEState *s = &d->ide_if[i * 2];
3209 c3d78997 bellard
        uint8_t drive1_selected;
3210 c3d78997 bellard
        qemu_get_8s(f, &s->cmd);
3211 c3d78997 bellard
        qemu_get_8s(f, &drive1_selected);
3212 c3d78997 bellard
        s->cur_drive = &d->ide_if[i * 2 + (drive1_selected != 0)];
3213 c3d78997 bellard
    }
3214 c3d78997 bellard
3215 c3d78997 bellard
    /* per IDE drive data */
3216 c3d78997 bellard
    for(i = 0; i < 4; i++) {
3217 aa941b94 balrog
        ide_load(f, &d->ide_if[i]);
3218 c3d78997 bellard
    }
3219 c3d78997 bellard
    return 0;
3220 c3d78997 bellard
}
3221 c3d78997 bellard
3222 72c7b06c aliguori
static void piix3_reset(void *opaque)
3223 e6a71ae3 ths
{
3224 72c7b06c aliguori
    PCIIDEState *d = opaque;
3225 e6a71ae3 ths
    uint8_t *pci_conf = d->dev.config;
3226 72c7b06c aliguori
    int i;
3227 72c7b06c aliguori
3228 72c7b06c aliguori
    for (i = 0; i < 2; i++)
3229 72c7b06c aliguori
        ide_dma_cancel(&d->bmdma[i]);
3230 e6a71ae3 ths
3231 e6a71ae3 ths
    pci_conf[0x04] = 0x00;
3232 e6a71ae3 ths
    pci_conf[0x05] = 0x00;
3233 e6a71ae3 ths
    pci_conf[0x06] = 0x80; /* FBC */
3234 e6a71ae3 ths
    pci_conf[0x07] = 0x02; // PCI_status_devsel_medium
3235 e6a71ae3 ths
    pci_conf[0x20] = 0x01; /* BMIBA: 20-23h */
3236 e6a71ae3 ths
}
3237 e6a71ae3 ths
3238 34e538ae bellard
/* hd_table must contain 4 block drivers */
3239 34e538ae bellard
/* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
3240 d537cf6c pbrook
void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn,
3241 d537cf6c pbrook
                        qemu_irq *pic)
3242 34e538ae bellard
{
3243 34e538ae bellard
    PCIIDEState *d;
3244 34e538ae bellard
    uint8_t *pci_conf;
3245 3b46e624 ths
3246 34e538ae bellard
    /* register a function 1 of PIIX3 */
3247 5fafdf24 ths
    d = (PCIIDEState *)pci_register_device(bus, "PIIX3 IDE",
3248 46e50e9d bellard
                                           sizeof(PCIIDEState),
3249 502a5395 pbrook
                                           devfn,
3250 34e538ae bellard
                                           NULL, NULL);
3251 5457c8ce bellard
    d->type = IDE_TYPE_PIIX3;
3252 5457c8ce bellard
3253 34e538ae bellard
    pci_conf = d->dev.config;
3254 34e538ae bellard
    pci_conf[0x00] = 0x86; // Intel
3255 34e538ae bellard
    pci_conf[0x01] = 0x80;
3256 34e538ae bellard
    pci_conf[0x02] = 0x10;
3257 34e538ae bellard
    pci_conf[0x03] = 0x70;
3258 92510b8c bellard
    pci_conf[0x09] = 0x80; // legacy ATA mode
3259 34e538ae bellard
    pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
3260 34e538ae bellard
    pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
3261 34e538ae bellard
    pci_conf[0x0e] = 0x00; // header_type
3262 34e538ae bellard
3263 72c7b06c aliguori
    qemu_register_reset(piix3_reset, d);
3264 e6a71ae3 ths
    piix3_reset(d);
3265 e6a71ae3 ths
3266 5fafdf24 ths
    pci_register_io_region((PCIDevice *)d, 4, 0x10,
3267 98087450 bellard
                           PCI_ADDRESS_SPACE_IO, bmdma_map);
3268 34e538ae bellard
3269 d537cf6c pbrook
    ide_init2(&d->ide_if[0], hd_table[0], hd_table[1], pic[14]);
3270 d537cf6c pbrook
    ide_init2(&d->ide_if[2], hd_table[2], hd_table[3], pic[15]);
3271 34e538ae bellard
    ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
3272 34e538ae bellard
    ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
3273 c3d78997 bellard
3274 c3d78997 bellard
    register_savevm("ide", 0, 1, pci_ide_save, pci_ide_load, d);
3275 69b91039 bellard
}
3276 1ade1de2 bellard
3277 afcc3cdf ths
/* hd_table must contain 4 block drivers */
3278 afcc3cdf ths
/* NOTE: for the PIIX4, the IRQs and IOports are hardcoded */
3279 afcc3cdf ths
void pci_piix4_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn,
3280 afcc3cdf ths
                        qemu_irq *pic)
3281 afcc3cdf ths
{
3282 afcc3cdf ths
    PCIIDEState *d;
3283 afcc3cdf ths
    uint8_t *pci_conf;
3284 afcc3cdf ths
3285 afcc3cdf ths
    /* register a function 1 of PIIX4 */
3286 afcc3cdf ths
    d = (PCIIDEState *)pci_register_device(bus, "PIIX4 IDE",
3287 afcc3cdf ths
                                           sizeof(PCIIDEState),
3288 afcc3cdf ths
                                           devfn,
3289 afcc3cdf ths
                                           NULL, NULL);
3290 afcc3cdf ths
    d->type = IDE_TYPE_PIIX4;
3291 afcc3cdf ths
3292 afcc3cdf ths
    pci_conf = d->dev.config;
3293 afcc3cdf ths
    pci_conf[0x00] = 0x86; // Intel
3294 afcc3cdf ths
    pci_conf[0x01] = 0x80;
3295 afcc3cdf ths
    pci_conf[0x02] = 0x11;
3296 afcc3cdf ths
    pci_conf[0x03] = 0x71;
3297 afcc3cdf ths
    pci_conf[0x09] = 0x80; // legacy ATA mode
3298 afcc3cdf ths
    pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
3299 afcc3cdf ths
    pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
3300 afcc3cdf ths
    pci_conf[0x0e] = 0x00; // header_type
3301 afcc3cdf ths
3302 72c7b06c aliguori
    qemu_register_reset(piix3_reset, d);
3303 afcc3cdf ths
    piix3_reset(d);
3304 afcc3cdf ths
3305 afcc3cdf ths
    pci_register_io_region((PCIDevice *)d, 4, 0x10,
3306 afcc3cdf ths
                           PCI_ADDRESS_SPACE_IO, bmdma_map);
3307 afcc3cdf ths
3308 afcc3cdf ths
    ide_init2(&d->ide_if[0], hd_table[0], hd_table[1], pic[14]);
3309 afcc3cdf ths
    ide_init2(&d->ide_if[2], hd_table[2], hd_table[3], pic[15]);
3310 afcc3cdf ths
    ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
3311 afcc3cdf ths
    ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
3312 afcc3cdf ths
3313 afcc3cdf ths
    register_savevm("ide", 0, 1, pci_ide_save, pci_ide_load, d);
3314 afcc3cdf ths
}
3315 afcc3cdf ths
3316 1ade1de2 bellard
/***********************************************************/
3317 1ade1de2 bellard
/* MacIO based PowerPC IDE */
3318 1ade1de2 bellard
3319 1ade1de2 bellard
/* PowerMac IDE memory IO */
3320 1ade1de2 bellard
static void pmac_ide_writeb (void *opaque,
3321 1ade1de2 bellard
                             target_phys_addr_t addr, uint32_t val)
3322 1ade1de2 bellard
{
3323 5fafdf24 ths
    addr = (addr & 0xFFF) >> 4;
3324 1ade1de2 bellard
    switch (addr) {
3325 1ade1de2 bellard
    case 1 ... 7:
3326 1ade1de2 bellard
        ide_ioport_write(opaque, addr, val);
3327 1ade1de2 bellard
        break;
3328 1ade1de2 bellard
    case 8:
3329 1ade1de2 bellard
    case 22:
3330 1ade1de2 bellard
        ide_cmd_write(opaque, 0, val);
3331 1ade1de2 bellard
        break;
3332 1ade1de2 bellard
    default:
3333 1ade1de2 bellard
        break;
3334 1ade1de2 bellard
    }
3335 1ade1de2 bellard
}
3336 1ade1de2 bellard
3337 1ade1de2 bellard
static uint32_t pmac_ide_readb (void *opaque,target_phys_addr_t addr)
3338 1ade1de2 bellard
{
3339 1ade1de2 bellard
    uint8_t retval;
3340 1ade1de2 bellard
3341 1ade1de2 bellard
    addr = (addr & 0xFFF) >> 4;
3342 1ade1de2 bellard
    switch (addr) {
3343 1ade1de2 bellard
    case 1 ... 7:
3344 1ade1de2 bellard
        retval = ide_ioport_read(opaque, addr);
3345 1ade1de2 bellard
        break;
3346 1ade1de2 bellard
    case 8:
3347 1ade1de2 bellard
    case 22:
3348 1ade1de2 bellard
        retval = ide_status_read(opaque, 0);
3349 1ade1de2 bellard
        break;
3350 1ade1de2 bellard
    default:
3351 1ade1de2 bellard
        retval = 0xFF;
3352 1ade1de2 bellard
        break;
3353 1ade1de2 bellard
    }
3354 1ade1de2 bellard
    return retval;
3355 1ade1de2 bellard
}
3356 1ade1de2 bellard
3357 1ade1de2 bellard
static void pmac_ide_writew (void *opaque,
3358 1ade1de2 bellard
                             target_phys_addr_t addr, uint32_t val)
3359 1ade1de2 bellard
{
3360 5fafdf24 ths
    addr = (addr & 0xFFF) >> 4;
3361 1ade1de2 bellard
#ifdef TARGET_WORDS_BIGENDIAN
3362 1ade1de2 bellard
    val = bswap16(val);
3363 1ade1de2 bellard
#endif
3364 1ade1de2 bellard
    if (addr == 0) {
3365 1ade1de2 bellard
        ide_data_writew(opaque, 0, val);
3366 1ade1de2 bellard
    }
3367 1ade1de2 bellard
}
3368 1ade1de2 bellard
3369 1ade1de2 bellard
static uint32_t pmac_ide_readw (void *opaque,target_phys_addr_t addr)
3370 1ade1de2 bellard
{
3371 1ade1de2 bellard
    uint16_t retval;
3372 1ade1de2 bellard
3373 5fafdf24 ths
    addr = (addr & 0xFFF) >> 4;
3374 1ade1de2 bellard
    if (addr == 0) {
3375 1ade1de2 bellard
        retval = ide_data_readw(opaque, 0);
3376 1ade1de2 bellard
    } else {
3377 1ade1de2 bellard
        retval = 0xFFFF;
3378 1ade1de2 bellard
    }
3379 1ade1de2 bellard
#ifdef TARGET_WORDS_BIGENDIAN
3380 1ade1de2 bellard
    retval = bswap16(retval);
3381 1ade1de2 bellard
#endif
3382 1ade1de2 bellard
    return retval;
3383 1ade1de2 bellard
}
3384 1ade1de2 bellard
3385 1ade1de2 bellard
static void pmac_ide_writel (void *opaque,
3386 1ade1de2 bellard
                             target_phys_addr_t addr, uint32_t val)
3387 1ade1de2 bellard
{
3388 5fafdf24 ths
    addr = (addr & 0xFFF) >> 4;
3389 1ade1de2 bellard
#ifdef TARGET_WORDS_BIGENDIAN
3390 1ade1de2 bellard
    val = bswap32(val);
3391 1ade1de2 bellard
#endif
3392 1ade1de2 bellard
    if (addr == 0) {
3393 1ade1de2 bellard
        ide_data_writel(opaque, 0, val);
3394 1ade1de2 bellard
    }
3395 1ade1de2 bellard
}
3396 1ade1de2 bellard
3397 1ade1de2 bellard
static uint32_t pmac_ide_readl (void *opaque,target_phys_addr_t addr)
3398 1ade1de2 bellard
{
3399 1ade1de2 bellard
    uint32_t retval;
3400 1ade1de2 bellard
3401 5fafdf24 ths
    addr = (addr & 0xFFF) >> 4;
3402 1ade1de2 bellard
    if (addr == 0) {
3403 1ade1de2 bellard
        retval = ide_data_readl(opaque, 0);
3404 1ade1de2 bellard
    } else {
3405 1ade1de2 bellard
        retval = 0xFFFFFFFF;
3406 1ade1de2 bellard
    }
3407 1ade1de2 bellard
#ifdef TARGET_WORDS_BIGENDIAN
3408 1ade1de2 bellard
    retval = bswap32(retval);
3409 1ade1de2 bellard
#endif
3410 1ade1de2 bellard
    return retval;
3411 1ade1de2 bellard
}
3412 1ade1de2 bellard
3413 1ade1de2 bellard
static CPUWriteMemoryFunc *pmac_ide_write[] = {
3414 1ade1de2 bellard
    pmac_ide_writeb,
3415 1ade1de2 bellard
    pmac_ide_writew,
3416 1ade1de2 bellard
    pmac_ide_writel,
3417 1ade1de2 bellard
};
3418 1ade1de2 bellard
3419 1ade1de2 bellard
static CPUReadMemoryFunc *pmac_ide_read[] = {
3420 1ade1de2 bellard
    pmac_ide_readb,
3421 1ade1de2 bellard
    pmac_ide_readw,
3422 1ade1de2 bellard
    pmac_ide_readl,
3423 1ade1de2 bellard
};
3424 1ade1de2 bellard
3425 1ade1de2 bellard
/* hd_table must contain 4 block drivers */
3426 1ade1de2 bellard
/* PowerMac uses memory mapped registers, not I/O. Return the memory
3427 1ade1de2 bellard
   I/O index to access the ide. */
3428 d537cf6c pbrook
int pmac_ide_init (BlockDriverState **hd_table, qemu_irq irq)
3429 1ade1de2 bellard
{
3430 1ade1de2 bellard
    IDEState *ide_if;
3431 1ade1de2 bellard
    int pmac_ide_memory;
3432 1ade1de2 bellard
3433 1ade1de2 bellard
    ide_if = qemu_mallocz(sizeof(IDEState) * 2);
3434 d537cf6c pbrook
    ide_init2(&ide_if[0], hd_table[0], hd_table[1], irq);
3435 3b46e624 ths
3436 1ade1de2 bellard
    pmac_ide_memory = cpu_register_io_memory(0, pmac_ide_read,
3437 1ade1de2 bellard
                                             pmac_ide_write, &ide_if[0]);
3438 1ade1de2 bellard
    return pmac_ide_memory;
3439 1ade1de2 bellard
}
3440 201a51fc balrog
3441 201a51fc balrog
/***********************************************************/
3442 201a51fc balrog
/* CF-ATA Microdrive */
3443 201a51fc balrog
3444 201a51fc balrog
#define METADATA_SIZE        0x20
3445 201a51fc balrog
3446 201a51fc balrog
/* DSCM-1XXXX Microdrive hard disk with CF+ II / PCMCIA interface.  */
3447 201a51fc balrog
struct md_s {
3448 201a51fc balrog
    IDEState ide[2];
3449 201a51fc balrog
    struct pcmcia_card_s card;
3450 201a51fc balrog
    uint32_t attr_base;
3451 201a51fc balrog
    uint32_t io_base;
3452 201a51fc balrog
3453 201a51fc balrog
    /* Card state */
3454 201a51fc balrog
    uint8_t opt;
3455 201a51fc balrog
    uint8_t stat;
3456 201a51fc balrog
    uint8_t pins;
3457 201a51fc balrog
3458 201a51fc balrog
    uint8_t ctrl;
3459 201a51fc balrog
    uint16_t io;
3460 201a51fc balrog
    int cycle;
3461 201a51fc balrog
};
3462 201a51fc balrog
3463 201a51fc balrog
/* Register bitfields */
3464 201a51fc balrog
enum md_opt {
3465 201a51fc balrog
    OPT_MODE_MMAP        = 0,
3466 201a51fc balrog
    OPT_MODE_IOMAP16        = 1,
3467 201a51fc balrog
    OPT_MODE_IOMAP1        = 2,
3468 201a51fc balrog
    OPT_MODE_IOMAP2        = 3,
3469 201a51fc balrog
    OPT_MODE                = 0x3f,
3470 201a51fc balrog
    OPT_LEVIREQ                = 0x40,
3471 201a51fc balrog
    OPT_SRESET                = 0x80,
3472 201a51fc balrog
};
3473 201a51fc balrog
enum md_cstat {
3474 201a51fc balrog
    STAT_INT                = 0x02,
3475 201a51fc balrog
    STAT_PWRDWN                = 0x04,
3476 201a51fc balrog
    STAT_XE                = 0x10,
3477 201a51fc balrog
    STAT_IOIS8                = 0x20,
3478 201a51fc balrog
    STAT_SIGCHG                = 0x40,
3479 201a51fc balrog
    STAT_CHANGED        = 0x80,
3480 201a51fc balrog
};
3481 201a51fc balrog
enum md_pins {
3482 201a51fc balrog
    PINS_MRDY                = 0x02,
3483 201a51fc balrog
    PINS_CRDY                = 0x20,
3484 201a51fc balrog
};
3485 201a51fc balrog
enum md_ctrl {
3486 201a51fc balrog
    CTRL_IEN                = 0x02,
3487 201a51fc balrog
    CTRL_SRST                = 0x04,
3488 201a51fc balrog
};
3489 201a51fc balrog
3490 201a51fc balrog
static inline void md_interrupt_update(struct md_s *s)
3491 201a51fc balrog
{
3492 201a51fc balrog
    if (!s->card.slot)
3493 201a51fc balrog
        return;
3494 201a51fc balrog
3495 201a51fc balrog
    qemu_set_irq(s->card.slot->irq,
3496 201a51fc balrog
                    !(s->stat & STAT_INT) &&        /* Inverted */
3497 201a51fc balrog
                    !(s->ctrl & (CTRL_IEN | CTRL_SRST)) &&
3498 201a51fc balrog
                    !(s->opt & OPT_SRESET));
3499 201a51fc balrog
}
3500 201a51fc balrog
3501 201a51fc balrog
static void md_set_irq(void *opaque, int irq, int level)
3502 201a51fc balrog
{
3503 201a51fc balrog
    struct md_s *s = (struct md_s *) opaque;
3504 201a51fc balrog
    if (level)
3505 201a51fc balrog
        s->stat |= STAT_INT;
3506 201a51fc balrog
    else
3507 201a51fc balrog
        s->stat &= ~STAT_INT;
3508 201a51fc balrog
3509 201a51fc balrog
    md_interrupt_update(s);
3510 201a51fc balrog
}
3511 201a51fc balrog
3512 201a51fc balrog
static void md_reset(struct md_s *s)
3513 201a51fc balrog
{
3514 201a51fc balrog
    s->opt = OPT_MODE_MMAP;
3515 201a51fc balrog
    s->stat = 0;
3516 201a51fc balrog
    s->pins = 0;
3517 201a51fc balrog
    s->cycle = 0;
3518 201a51fc balrog
    s->ctrl = 0;
3519 201a51fc balrog
    ide_reset(s->ide);
3520 201a51fc balrog
}
3521 201a51fc balrog
3522 9e315fa9 balrog
static uint8_t md_attr_read(void *opaque, uint32_t at)
3523 201a51fc balrog
{
3524 201a51fc balrog
    struct md_s *s = (struct md_s *) opaque;
3525 201a51fc balrog
    if (at < s->attr_base) {
3526 201a51fc balrog
        if (at < s->card.cis_len)
3527 201a51fc balrog
            return s->card.cis[at];
3528 201a51fc balrog
        else
3529 201a51fc balrog
            return 0x00;
3530 201a51fc balrog
    }
3531 201a51fc balrog
3532 201a51fc balrog
    at -= s->attr_base;
3533 201a51fc balrog
3534 201a51fc balrog
    switch (at) {
3535 201a51fc balrog
    case 0x00:        /* Configuration Option Register */
3536 201a51fc balrog
        return s->opt;
3537 201a51fc balrog
    case 0x02:        /* Card Configuration Status Register */
3538 201a51fc balrog
        if (s->ctrl & CTRL_IEN)
3539 201a51fc balrog
            return s->stat & ~STAT_INT;
3540 201a51fc balrog
        else
3541 201a51fc balrog
            return s->stat;
3542 201a51fc balrog
    case 0x04:        /* Pin Replacement Register */
3543 201a51fc balrog
        return (s->pins & PINS_CRDY) | 0x0c;
3544 201a51fc balrog
    case 0x06:        /* Socket and Copy Register */
3545 201a51fc balrog
        return 0x00;
3546 201a51fc balrog
#ifdef VERBOSE
3547 201a51fc balrog
    default:
3548 201a51fc balrog
        printf("%s: Bad attribute space register %02x\n", __FUNCTION__, at);
3549 201a51fc balrog
#endif
3550 201a51fc balrog
    }
3551 201a51fc balrog
3552 201a51fc balrog
    return 0;
3553 201a51fc balrog
}
3554 201a51fc balrog
3555 9e315fa9 balrog
static void md_attr_write(void *opaque, uint32_t at, uint8_t value)
3556 201a51fc balrog
{
3557 201a51fc balrog
    struct md_s *s = (struct md_s *) opaque;
3558 201a51fc balrog
    at -= s->attr_base;
3559 201a51fc balrog
3560 201a51fc balrog
    switch (at) {
3561 201a51fc balrog
    case 0x00:        /* Configuration Option Register */
3562 201a51fc balrog
        s->opt = value & 0xcf;
3563 201a51fc balrog
        if (value & OPT_SRESET)
3564 201a51fc balrog
            md_reset(s);
3565 201a51fc balrog
        md_interrupt_update(s);
3566 201a51fc balrog
        break;
3567 201a51fc balrog
    case 0x02:        /* Card Configuration Status Register */
3568 201a51fc balrog
        if ((s->stat ^ value) & STAT_PWRDWN)
3569 201a51fc balrog
            s->pins |= PINS_CRDY;
3570 201a51fc balrog
        s->stat &= 0x82;
3571 201a51fc balrog
        s->stat |= value & 0x74;
3572 201a51fc balrog
        md_interrupt_update(s);
3573 201a51fc balrog
        /* Word 170 in Identify Device must be equal to STAT_XE */
3574 201a51fc balrog
        break;
3575 201a51fc balrog
    case 0x04:        /* Pin Replacement Register */
3576 201a51fc balrog
        s->pins &= PINS_CRDY;
3577 201a51fc balrog
        s->pins |= value & PINS_MRDY;
3578 201a51fc balrog
        break;
3579 201a51fc balrog
    case 0x06:        /* Socket and Copy Register */
3580 201a51fc balrog
        break;
3581 201a51fc balrog
    default:
3582 201a51fc balrog
        printf("%s: Bad attribute space register %02x\n", __FUNCTION__, at);
3583 201a51fc balrog
    }
3584 201a51fc balrog
}
3585 201a51fc balrog
3586 9e315fa9 balrog
static uint16_t md_common_read(void *opaque, uint32_t at)
3587 201a51fc balrog
{
3588 201a51fc balrog
    struct md_s *s = (struct md_s *) opaque;
3589 201a51fc balrog
    uint16_t ret;
3590 201a51fc balrog
    at -= s->io_base;
3591 201a51fc balrog
3592 201a51fc balrog
    switch (s->opt & OPT_MODE) {
3593 201a51fc balrog
    case OPT_MODE_MMAP:
3594 201a51fc balrog
        if ((at & ~0x3ff) == 0x400)
3595 201a51fc balrog
            at = 0;
3596 201a51fc balrog
        break;
3597 201a51fc balrog
    case OPT_MODE_IOMAP16:
3598 201a51fc balrog
        at &= 0xf;
3599 201a51fc balrog
        break;
3600 201a51fc balrog
    case OPT_MODE_IOMAP1:
3601 201a51fc balrog
        if ((at & ~0xf) == 0x3f0)
3602 201a51fc balrog
            at -= 0x3e8;
3603 201a51fc balrog
        else if ((at & ~0xf) == 0x1f0)
3604 201a51fc balrog
            at -= 0x1f0;
3605 201a51fc balrog
        break;
3606 201a51fc balrog
    case OPT_MODE_IOMAP2:
3607 201a51fc balrog
        if ((at & ~0xf) == 0x370)
3608 201a51fc balrog
            at -= 0x368;
3609 201a51fc balrog
        else if ((at & ~0xf) == 0x170)
3610 201a51fc balrog
            at -= 0x170;
3611 201a51fc balrog
    }
3612 201a51fc balrog
3613 201a51fc balrog
    switch (at) {
3614 201a51fc balrog
    case 0x0:        /* Even RD Data */
3615 201a51fc balrog
    case 0x8:
3616 201a51fc balrog
        return ide_data_readw(s->ide, 0);
3617 201a51fc balrog
3618 201a51fc balrog
        /* TODO: 8-bit accesses */
3619 201a51fc balrog
        if (s->cycle)
3620 201a51fc balrog
            ret = s->io >> 8;
3621 201a51fc balrog
        else {
3622 201a51fc balrog
            s->io = ide_data_readw(s->ide, 0);
3623 201a51fc balrog
            ret = s->io & 0xff;
3624 201a51fc balrog
        }
3625 201a51fc balrog
        s->cycle = !s->cycle;
3626 201a51fc balrog
        return ret;
3627 201a51fc balrog
    case 0x9:        /* Odd RD Data */
3628 201a51fc balrog
        return s->io >> 8;
3629 201a51fc balrog
    case 0xd:        /* Error */
3630 201a51fc balrog
        return ide_ioport_read(s->ide, 0x1);
3631 201a51fc balrog
    case 0xe:        /* Alternate Status */
3632 201a51fc balrog
        if (s->ide->cur_drive->bs)
3633 201a51fc balrog
            return s->ide->cur_drive->status;
3634 201a51fc balrog
        else
3635 201a51fc balrog
            return 0;
3636 201a51fc balrog
    case 0xf:        /* Device Address */
3637 201a51fc balrog
        return 0xc2 | ((~s->ide->select << 2) & 0x3c);
3638 201a51fc balrog
    default:
3639 201a51fc balrog
        return ide_ioport_read(s->ide, at);
3640 201a51fc balrog
    }
3641 201a51fc balrog
3642 201a51fc balrog
    return 0;
3643 201a51fc balrog
}
3644 201a51fc balrog
3645 9e315fa9 balrog
static void md_common_write(void *opaque, uint32_t at, uint16_t value)
3646 201a51fc balrog
{
3647 201a51fc balrog
    struct md_s *s = (struct md_s *) opaque;
3648 201a51fc balrog
    at -= s->io_base;
3649 201a51fc balrog
3650 201a51fc balrog
    switch (s->opt & OPT_MODE) {
3651 201a51fc balrog
    case OPT_MODE_MMAP:
3652 201a51fc balrog
        if ((at & ~0x3ff) == 0x400)
3653 201a51fc balrog
            at = 0;
3654 201a51fc balrog
        break;
3655 201a51fc balrog
    case OPT_MODE_IOMAP16:
3656 201a51fc balrog
        at &= 0xf;
3657 201a51fc balrog
        break;
3658 201a51fc balrog
    case OPT_MODE_IOMAP1:
3659 201a51fc balrog
        if ((at & ~0xf) == 0x3f0)
3660 201a51fc balrog
            at -= 0x3e8;
3661 201a51fc balrog
        else if ((at & ~0xf) == 0x1f0)
3662 201a51fc balrog
            at -= 0x1f0;
3663 201a51fc balrog
        break;
3664 201a51fc balrog
    case OPT_MODE_IOMAP2:
3665 201a51fc balrog
        if ((at & ~0xf) == 0x370)
3666 201a51fc balrog
            at -= 0x368;
3667 201a51fc balrog
        else if ((at & ~0xf) == 0x170)
3668 201a51fc balrog
            at -= 0x170;
3669 201a51fc balrog
    }
3670 201a51fc balrog
3671 201a51fc balrog
    switch (at) {
3672 201a51fc balrog
    case 0x0:        /* Even WR Data */
3673 201a51fc balrog
    case 0x8:
3674 201a51fc balrog
        ide_data_writew(s->ide, 0, value);
3675 201a51fc balrog
        break;
3676 201a51fc balrog
3677 201a51fc balrog
        /* TODO: 8-bit accesses */
3678 201a51fc balrog
        if (s->cycle)
3679 201a51fc balrog
            ide_data_writew(s->ide, 0, s->io | (value << 8));
3680 201a51fc balrog
        else
3681 201a51fc balrog
            s->io = value & 0xff;
3682 201a51fc balrog
        s->cycle = !s->cycle;
3683 201a51fc balrog
        break;
3684 201a51fc balrog
    case 0x9:
3685 201a51fc balrog
        s->io = value & 0xff;
3686 201a51fc balrog
        s->cycle = !s->cycle;
3687 201a51fc balrog
        break;
3688 201a51fc balrog
    case 0xd:        /* Features */
3689 201a51fc balrog
        ide_ioport_write(s->ide, 0x1, value);
3690 201a51fc balrog
        break;
3691 201a51fc balrog
    case 0xe:        /* Device Control */
3692 201a51fc balrog
        s->ctrl = value;
3693 201a51fc balrog
        if (value & CTRL_SRST)
3694 201a51fc balrog
            md_reset(s);
3695 201a51fc balrog
        md_interrupt_update(s);
3696 201a51fc balrog
        break;
3697 201a51fc balrog
    default:
3698 201a51fc balrog
        if (s->stat & STAT_PWRDWN) {
3699 201a51fc balrog
            s->pins |= PINS_CRDY;
3700 201a51fc balrog
            s->stat &= ~STAT_PWRDWN;
3701 201a51fc balrog
        }
3702 201a51fc balrog
        ide_ioport_write(s->ide, at, value);
3703 201a51fc balrog
    }
3704 201a51fc balrog
}
3705 201a51fc balrog
3706 aa941b94 balrog
static void md_save(QEMUFile *f, void *opaque)
3707 aa941b94 balrog
{
3708 aa941b94 balrog
    struct md_s *s = (struct md_s *) opaque;
3709 aa941b94 balrog
    int i;
3710 aa941b94 balrog
    uint8_t drive1_selected;
3711 aa941b94 balrog
3712 aa941b94 balrog
    qemu_put_8s(f, &s->opt);
3713 aa941b94 balrog
    qemu_put_8s(f, &s->stat);
3714 aa941b94 balrog
    qemu_put_8s(f, &s->pins);
3715 aa941b94 balrog
3716 aa941b94 balrog
    qemu_put_8s(f, &s->ctrl);
3717 aa941b94 balrog
    qemu_put_be16s(f, &s->io);
3718 aa941b94 balrog
    qemu_put_byte(f, s->cycle);
3719 aa941b94 balrog
3720 aa941b94 balrog
    drive1_selected = (s->ide->cur_drive != s->ide);
3721 aa941b94 balrog
    qemu_put_8s(f, &s->ide->cmd);
3722 aa941b94 balrog
    qemu_put_8s(f, &drive1_selected);
3723 aa941b94 balrog
3724 aa941b94 balrog
    for (i = 0; i < 2; i ++)
3725 aa941b94 balrog
        ide_save(f, &s->ide[i]);
3726 aa941b94 balrog
}
3727 aa941b94 balrog
3728 aa941b94 balrog
static int md_load(QEMUFile *f, void *opaque, int version_id)
3729 aa941b94 balrog
{
3730 aa941b94 balrog
    struct md_s *s = (struct md_s *) opaque;
3731 aa941b94 balrog
    int i;
3732 aa941b94 balrog
    uint8_t drive1_selected;
3733 aa941b94 balrog
3734 aa941b94 balrog
    qemu_get_8s(f, &s->opt);
3735 aa941b94 balrog
    qemu_get_8s(f, &s->stat);
3736 aa941b94 balrog
    qemu_get_8s(f, &s->pins);
3737 aa941b94 balrog
3738 aa941b94 balrog
    qemu_get_8s(f, &s->ctrl);
3739 aa941b94 balrog
    qemu_get_be16s(f, &s->io);
3740 aa941b94 balrog
    s->cycle = qemu_get_byte(f);
3741 aa941b94 balrog
3742 aa941b94 balrog
    qemu_get_8s(f, &s->ide->cmd);
3743 aa941b94 balrog
    qemu_get_8s(f, &drive1_selected);
3744 aa941b94 balrog
    s->ide->cur_drive = &s->ide[(drive1_selected != 0)];
3745 aa941b94 balrog
3746 aa941b94 balrog
    for (i = 0; i < 2; i ++)
3747 aa941b94 balrog
        ide_load(f, &s->ide[i]);
3748 aa941b94 balrog
3749 aa941b94 balrog
    return 0;
3750 aa941b94 balrog
}
3751 aa941b94 balrog
3752 201a51fc balrog
static const uint8_t dscm1xxxx_cis[0x14a] = {
3753 201a51fc balrog
    [0x000] = CISTPL_DEVICE,        /* 5V Device Information */
3754 201a51fc balrog
    [0x002] = 0x03,                /* Tuple length = 4 bytes */
3755 201a51fc balrog
    [0x004] = 0xdb,                /* ID: DTYPE_FUNCSPEC, non WP, DSPEED_150NS */
3756 201a51fc balrog
    [0x006] = 0x01,                /* Size = 2K bytes */
3757 201a51fc balrog
    [0x008] = CISTPL_ENDMARK,
3758 201a51fc balrog
3759 201a51fc balrog
    [0x00a] = CISTPL_DEVICE_OC,        /* Additional Device Information */
3760 201a51fc balrog
    [0x00c] = 0x04,                /* Tuple length = 4 byest */
3761 201a51fc balrog
    [0x00e] = 0x03,                /* Conditions: Ext = 0, Vcc 3.3V, MWAIT = 1 */
3762 201a51fc balrog
    [0x010] = 0xdb,                /* ID: DTYPE_FUNCSPEC, non WP, DSPEED_150NS */
3763 201a51fc balrog
    [0x012] = 0x01,                /* Size = 2K bytes */
3764 201a51fc balrog
    [0x014] = CISTPL_ENDMARK,
3765 201a51fc balrog
3766 201a51fc balrog
    [0x016] = CISTPL_JEDEC_C,        /* JEDEC ID */
3767 201a51fc balrog
    [0x018] = 0x02,                /* Tuple length = 2 bytes */
3768 201a51fc balrog
    [0x01a] = 0xdf,                /* PC Card ATA with no Vpp required */
3769 201a51fc balrog
    [0x01c] = 0x01,
3770 201a51fc balrog
3771 201a51fc balrog
    [0x01e] = CISTPL_MANFID,        /* Manufacture ID */
3772 201a51fc balrog
    [0x020] = 0x04,                /* Tuple length = 4 bytes */
3773 201a51fc balrog
    [0x022] = 0xa4,                /* TPLMID_MANF = 00a4 (IBM) */
3774 201a51fc balrog
    [0x024] = 0x00,
3775 201a51fc balrog
    [0x026] = 0x00,                /* PLMID_CARD = 0000 */
3776 201a51fc balrog
    [0x028] = 0x00,
3777 201a51fc balrog
3778 201a51fc balrog
    [0x02a] = CISTPL_VERS_1,        /* Level 1 Version */
3779 201a51fc balrog
    [0x02c] = 0x12,                /* Tuple length = 23 bytes */
3780 201a51fc balrog
    [0x02e] = 0x04,                /* Major Version = JEIDA 4.2 / PCMCIA 2.1 */
3781 201a51fc balrog
    [0x030] = 0x01,                /* Minor Version = 1 */
3782 201a51fc balrog
    [0x032] = 'I',
3783 201a51fc balrog
    [0x034] = 'B',
3784 201a51fc balrog
    [0x036] = 'M',
3785 201a51fc balrog
    [0x038] = 0x00,
3786 201a51fc balrog
    [0x03a] = 'm',
3787 201a51fc balrog
    [0x03c] = 'i',
3788 201a51fc balrog
    [0x03e] = 'c',
3789 201a51fc balrog
    [0x040] = 'r',
3790 201a51fc balrog
    [0x042] = 'o',
3791 201a51fc balrog
    [0x044] = 'd',
3792 201a51fc balrog
    [0x046] = 'r',
3793 201a51fc balrog
    [0x048] = 'i',
3794 201a51fc balrog
    [0x04a] = 'v',
3795 201a51fc balrog
    [0x04c] = 'e',
3796 201a51fc balrog
    [0x04e] = 0x00,
3797 201a51fc balrog
    [0x050] = CISTPL_ENDMARK,
3798 201a51fc balrog
3799 201a51fc balrog
    [0x052] = CISTPL_FUNCID,        /* Function ID */
3800 201a51fc balrog
    [0x054] = 0x02,                /* Tuple length = 2 bytes */
3801 201a51fc balrog
    [0x056] = 0x04,                /* TPLFID_FUNCTION = Fixed Disk */
3802 201a51fc balrog
    [0x058] = 0x01,                /* TPLFID_SYSINIT: POST = 1, ROM = 0 */
3803 201a51fc balrog
3804 201a51fc balrog
    [0x05a] = CISTPL_FUNCE,        /* Function Extension */
3805 201a51fc balrog
    [0x05c] = 0x02,                /* Tuple length = 2 bytes */
3806 201a51fc balrog
    [0x05e] = 0x01,                /* TPLFE_TYPE = Disk Device Interface */
3807 201a51fc balrog
    [0x060] = 0x01,                /* TPLFE_DATA = PC Card ATA Interface */
3808 201a51fc balrog
3809 201a51fc balrog
    [0x062] = CISTPL_FUNCE,        /* Function Extension */
3810 201a51fc balrog
    [0x064] = 0x03,                /* Tuple length = 3 bytes */
3811 201a51fc balrog
    [0x066] = 0x02,                /* TPLFE_TYPE = Basic PC Card ATA Interface */
3812 201a51fc balrog
    [0x068] = 0x08,                /* TPLFE_DATA: Rotating, Unique, Single */
3813 201a51fc balrog
    [0x06a] = 0x0f,                /* TPLFE_DATA: Sleep, Standby, Idle, Auto */
3814 201a51fc balrog
3815 201a51fc balrog
    [0x06c] = CISTPL_CONFIG,        /* Configuration */
3816 201a51fc balrog
    [0x06e] = 0x05,                /* Tuple length = 5 bytes */
3817 201a51fc balrog
    [0x070] = 0x01,                /* TPCC_RASZ = 2 bytes, TPCC_RMSZ = 1 byte */
3818 201a51fc balrog
    [0x072] = 0x07,                /* TPCC_LAST = 7 */
3819 201a51fc balrog
    [0x074] = 0x00,                /* TPCC_RADR = 0200 */
3820 201a51fc balrog
    [0x076] = 0x02,
3821 201a51fc balrog
    [0x078] = 0x0f,                /* TPCC_RMSK = 200, 202, 204, 206 */
3822 201a51fc balrog
3823 201a51fc balrog
    [0x07a] = CISTPL_CFTABLE_ENTRY,        /* 16-bit PC Card Configuration */
3824 201a51fc balrog
    [0x07c] = 0x0b,                /* Tuple length = 11 bytes */
3825 201a51fc balrog
    [0x07e] = 0xc0,                /* TPCE_INDX = Memory Mode, Default, Iface */
3826 201a51fc balrog
    [0x080] = 0xc0,                /* TPCE_IF = Memory, no BVDs, no WP, READY */
3827 201a51fc balrog
    [0x082] = 0xa1,                /* TPCE_FS = Vcc only, no I/O, Memory, Misc */
3828 201a51fc balrog
    [0x084] = 0x27,                /* NomV = 1, MinV = 1, MaxV = 1, Peakl = 1 */
3829 201a51fc balrog
    [0x086] = 0x55,                /* NomV: 5.0 V */
3830 201a51fc balrog
    [0x088] = 0x4d,                /* MinV: 4.5 V */
3831 201a51fc balrog
    [0x08a] = 0x5d,                /* MaxV: 5.5 V */
3832 201a51fc balrog
    [0x08c] = 0x4e,                /* Peakl: 450 mA */
3833 201a51fc balrog
    [0x08e] = 0x08,                /* TPCE_MS = 1 window, 1 byte, Host address */
3834 201a51fc balrog
    [0x090] = 0x00,                /* Window descriptor: Window length = 0 */
3835 201a51fc balrog
    [0x092] = 0x20,                /* TPCE_MI: support power down mode, RW */
3836 201a51fc balrog
3837 201a51fc balrog
    [0x094] = CISTPL_CFTABLE_ENTRY,        /* 16-bit PC Card Configuration */
3838 201a51fc balrog
    [0x096] = 0x06,                /* Tuple length = 6 bytes */
3839 201a51fc balrog
    [0x098] = 0x00,                /* TPCE_INDX = Memory Mode, no Default */
3840 201a51fc balrog
    [0x09a] = 0x01,                /* TPCE_FS = Vcc only, no I/O, no Memory */
3841 201a51fc balrog
    [0x09c] = 0x21,                /* NomV = 1, MinV = 0, MaxV = 0, Peakl = 1 */
3842 201a51fc balrog
    [0x09e] = 0xb5,                /* NomV: 3.3 V */
3843 201a51fc balrog
    [0x0a0] = 0x1e,
3844 201a51fc balrog
    [0x0a2] = 0x3e,                /* Peakl: 350 mA */
3845 201a51fc balrog
3846 201a51fc balrog
    [0x0a4] = CISTPL_CFTABLE_ENTRY,        /* 16-bit PC Card Configuration */
3847 201a51fc balrog
    [0x0a6] = 0x0d,                /* Tuple length = 13 bytes */
3848 201a51fc balrog
    [0x0a8] = 0xc1,                /* TPCE_INDX = I/O and Memory Mode, Default */
3849 201a51fc balrog
    [0x0aa] = 0x41,                /* TPCE_IF = I/O and Memory, no BVD, no WP */
3850 201a51fc balrog
    [0x0ac] = 0x99,                /* TPCE_FS = Vcc only, I/O, Interrupt, Misc */
3851 201a51fc balrog
    [0x0ae] = 0x27,                /* NomV = 1, MinV = 1, MaxV = 1, Peakl = 1 */
3852 201a51fc balrog
    [0x0b0] = 0x55,                /* NomV: 5.0 V */
3853 201a51fc balrog
    [0x0b2] = 0x4d,                /* MinV: 4.5 V */
3854 201a51fc balrog
    [0x0b4] = 0x5d,                /* MaxV: 5.5 V */
3855 201a51fc balrog
    [0x0b6] = 0x4e,                /* Peakl: 450 mA */
3856 201a51fc balrog
    [0x0b8] = 0x64,                /* TPCE_IO = 16-byte boundary, 16/8 accesses */
3857 201a51fc balrog
    [0x0ba] = 0xf0,                /* TPCE_IR =  MASK, Level, Pulse, Share */
3858 201a51fc balrog
    [0x0bc] = 0xff,                /* IRQ0..IRQ7 supported */
3859 201a51fc balrog
    [0x0be] = 0xff,                /* IRQ8..IRQ15 supported */
3860 201a51fc balrog
    [0x0c0] = 0x20,                /* TPCE_MI = support power down mode */
3861 201a51fc balrog
3862 201a51fc balrog
    [0x0c2] = CISTPL_CFTABLE_ENTRY,        /* 16-bit PC Card Configuration */
3863 201a51fc balrog
    [0x0c4] = 0x06,                /* Tuple length = 6 bytes */
3864 201a51fc balrog
    [0x0c6] = 0x01,                /* TPCE_INDX = I/O and Memory Mode */
3865 201a51fc balrog
    [0x0c8] = 0x01,                /* TPCE_FS = Vcc only, no I/O, no Memory */
3866 201a51fc balrog
    [0x0ca] = 0x21,                /* NomV = 1, MinV = 0, MaxV = 0, Peakl = 1 */
3867 201a51fc balrog
    [0x0cc] = 0xb5,                /* NomV: 3.3 V */
3868 201a51fc balrog
    [0x0ce] = 0x1e,
3869 201a51fc balrog
    [0x0d0] = 0x3e,                /* Peakl: 350 mA */
3870 201a51fc balrog
3871 201a51fc balrog
    [0x0d2] = CISTPL_CFTABLE_ENTRY,        /* 16-bit PC Card Configuration */
3872 201a51fc balrog
    [0x0d4] = 0x12,                /* Tuple length = 18 bytes */
3873 201a51fc balrog
    [0x0d6] = 0xc2,                /* TPCE_INDX = I/O Primary Mode */
3874 201a51fc balrog
    [0x0d8] = 0x41,                /* TPCE_IF = I/O and Memory, no BVD, no WP */
3875 201a51fc balrog
    [0x0da] = 0x99,                /* TPCE_FS = Vcc only, I/O, Interrupt, Misc */
3876 201a51fc balrog
    [0x0dc] = 0x27,                /* NomV = 1, MinV = 1, MaxV = 1, Peakl = 1 */
3877 201a51fc balrog
    [0x0de] = 0x55,                /* NomV: 5.0 V */
3878 201a51fc balrog
    [0x0e0] = 0x4d,                /* MinV: 4.5 V */
3879 201a51fc balrog
    [0x0e2] = 0x5d,                /* MaxV: 5.5 V */
3880 201a51fc balrog
    [0x0e4] = 0x4e,                /* Peakl: 450 mA */
3881 201a51fc balrog
    [0x0e6] = 0xea,                /* TPCE_IO = 1K boundary, 16/8 access, Range */
3882 201a51fc balrog
    [0x0e8] = 0x61,                /* Range: 2 fields, 2 bytes addr, 1 byte len */
3883 201a51fc balrog
    [0x0ea] = 0xf0,                /* Field 1 address = 0x01f0 */
3884 201a51fc balrog
    [0x0ec] = 0x01,
3885 201a51fc balrog
    [0x0ee] = 0x07,                /* Address block length = 8 */
3886 201a51fc balrog
    [0x0f0] = 0xf6,                /* Field 2 address = 0x03f6 */
3887 201a51fc balrog
    [0x0f2] = 0x03,
3888 201a51fc balrog
    [0x0f4] = 0x01,                /* Address block length = 2 */
3889 201a51fc balrog
    [0x0f6] = 0xee,                /* TPCE_IR = IRQ E, Level, Pulse, Share */
3890 201a51fc balrog
    [0x0f8] = 0x20,                /* TPCE_MI = support power down mode */
3891 201a51fc balrog
3892 201a51fc balrog
    [0x0fa] = CISTPL_CFTABLE_ENTRY,        /* 16-bit PC Card Configuration */
3893 201a51fc balrog
    [0x0fc] = 0x06,                /* Tuple length = 6 bytes */
3894 201a51fc balrog
    [0x0fe] = 0x02,                /* TPCE_INDX = I/O Primary Mode, no Default */
3895 201a51fc balrog
    [0x100] = 0x01,                /* TPCE_FS = Vcc only, no I/O, no Memory */
3896 201a51fc balrog
    [0x102] = 0x21,                /* NomV = 1, MinV = 0, MaxV = 0, Peakl = 1 */
3897 201a51fc balrog
    [0x104] = 0xb5,                /* NomV: 3.3 V */
3898 201a51fc balrog
    [0x106] = 0x1e,
3899 201a51fc balrog
    [0x108] = 0x3e,                /* Peakl: 350 mA */
3900 201a51fc balrog
3901 201a51fc balrog
    [0x10a] = CISTPL_CFTABLE_ENTRY,        /* 16-bit PC Card Configuration */
3902 201a51fc balrog
    [0x10c] = 0x12,                /* Tuple length = 18 bytes */
3903 201a51fc balrog
    [0x10e] = 0xc3,                /* TPCE_INDX = I/O Secondary Mode, Default */
3904 201a51fc balrog
    [0x110] = 0x41,                /* TPCE_IF = I/O and Memory, no BVD, no WP */
3905 201a51fc balrog
    [0x112] = 0x99,                /* TPCE_FS = Vcc only, I/O, Interrupt, Misc */
3906 201a51fc balrog
    [0x114] = 0x27,                /* NomV = 1, MinV = 1, MaxV = 1, Peakl = 1 */
3907 201a51fc balrog
    [0x116] = 0x55,                /* NomV: 5.0 V */
3908 201a51fc balrog
    [0x118] = 0x4d,                /* MinV: 4.5 V */
3909 201a51fc balrog
    [0x11a] = 0x5d,                /* MaxV: 5.5 V */
3910 201a51fc balrog
    [0x11c] = 0x4e,                /* Peakl: 450 mA */
3911 201a51fc balrog
    [0x11e] = 0xea,                /* TPCE_IO = 1K boundary, 16/8 access, Range */
3912 201a51fc balrog
    [0x120] = 0x61,                /* Range: 2 fields, 2 byte addr, 1 byte len */
3913 201a51fc balrog
    [0x122] = 0x70,                /* Field 1 address = 0x0170 */
3914 201a51fc balrog
    [0x124] = 0x01,
3915 201a51fc balrog
    [0x126] = 0x07,                /* Address block length = 8 */
3916 201a51fc balrog
    [0x128] = 0x76,                /* Field 2 address = 0x0376 */
3917 201a51fc balrog
    [0x12a] = 0x03,
3918 201a51fc balrog
    [0x12c] = 0x01,                /* Address block length = 2 */
3919 201a51fc balrog
    [0x12e] = 0xee,                /* TPCE_IR = IRQ E, Level, Pulse, Share */
3920 201a51fc balrog
    [0x130] = 0x20,                /* TPCE_MI = support power down mode */
3921 201a51fc balrog
3922 201a51fc balrog
    [0x132] = CISTPL_CFTABLE_ENTRY,        /* 16-bit PC Card Configuration */
3923 201a51fc balrog
    [0x134] = 0x06,                /* Tuple length = 6 bytes */
3924 201a51fc balrog
    [0x136] = 0x03,                /* TPCE_INDX = I/O Secondary Mode */
3925 201a51fc balrog
    [0x138] = 0x01,                /* TPCE_FS = Vcc only, no I/O, no Memory */
3926 201a51fc balrog
    [0x13a] = 0x21,                /* NomV = 1, MinV = 0, MaxV = 0, Peakl = 1 */
3927 201a51fc balrog
    [0x13c] = 0xb5,                /* NomV: 3.3 V */
3928 201a51fc balrog
    [0x13e] = 0x1e,
3929 201a51fc balrog
    [0x140] = 0x3e,                /* Peakl: 350 mA */
3930 201a51fc balrog
3931 201a51fc balrog
    [0x142] = CISTPL_NO_LINK,        /* No Link */
3932 201a51fc balrog
    [0x144] = 0x00,                /* Tuple length = 0 bytes */
3933 201a51fc balrog
3934 201a51fc balrog
    [0x146] = CISTPL_END,        /* Tuple End */
3935 201a51fc balrog
};
3936 201a51fc balrog
3937 201a51fc balrog
static int dscm1xxxx_attach(void *opaque)
3938 201a51fc balrog
{
3939 201a51fc balrog
    struct md_s *md = (struct md_s *) opaque;
3940 201a51fc balrog
    md->card.attr_read = md_attr_read;
3941 201a51fc balrog
    md->card.attr_write = md_attr_write;
3942 201a51fc balrog
    md->card.common_read = md_common_read;
3943 201a51fc balrog
    md->card.common_write = md_common_write;
3944 201a51fc balrog
    md->card.io_read = md_common_read;
3945 201a51fc balrog
    md->card.io_write = md_common_write;
3946 201a51fc balrog
3947 201a51fc balrog
    md->attr_base = md->card.cis[0x74] | (md->card.cis[0x76] << 8);
3948 201a51fc balrog
    md->io_base = 0x0;
3949 201a51fc balrog
3950 201a51fc balrog
    md_reset(md);
3951 201a51fc balrog
    md_interrupt_update(md);
3952 201a51fc balrog
3953 201a51fc balrog
    md->card.slot->card_string = "DSCM-1xxxx Hitachi Microdrive";
3954 201a51fc balrog
    return 0;
3955 201a51fc balrog
}
3956 201a51fc balrog
3957 201a51fc balrog
static int dscm1xxxx_detach(void *opaque)
3958 201a51fc balrog
{
3959 201a51fc balrog
    struct md_s *md = (struct md_s *) opaque;
3960 201a51fc balrog
    md_reset(md);
3961 201a51fc balrog
    return 0;
3962 201a51fc balrog
}
3963 201a51fc balrog
3964 201a51fc balrog
struct pcmcia_card_s *dscm1xxxx_init(BlockDriverState *bdrv)
3965 201a51fc balrog
{
3966 201a51fc balrog
    struct md_s *md = (struct md_s *) qemu_mallocz(sizeof(struct md_s));
3967 201a51fc balrog
    md->card.state = md;
3968 201a51fc balrog
    md->card.attach = dscm1xxxx_attach;
3969 201a51fc balrog
    md->card.detach = dscm1xxxx_detach;
3970 201a51fc balrog
    md->card.cis = dscm1xxxx_cis;
3971 201a51fc balrog
    md->card.cis_len = sizeof(dscm1xxxx_cis);
3972 201a51fc balrog
3973 201a51fc balrog
    ide_init2(md->ide, bdrv, 0, qemu_allocate_irqs(md_set_irq, md, 1)[0]);
3974 201a51fc balrog
    md->ide->is_cf = 1;
3975 201a51fc balrog
    md->ide->mdata_size = METADATA_SIZE;
3976 201a51fc balrog
    md->ide->mdata_storage = (uint8_t *) qemu_mallocz(METADATA_SIZE);
3977 aa941b94 balrog
3978 18be5187 pbrook
    register_savevm("microdrive", -1, 0, md_save, md_load, md);
3979 aa941b94 balrog
3980 201a51fc balrog
    return &md->card;
3981 201a51fc balrog
}