/[pearpc]/src/io/ide/ide.cc
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /src/io/ide/ide.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 7 - (show annotations)
Wed Sep 5 18:23:57 2007 UTC (16 years, 7 months ago) by dpavlin
File size: 72714 byte(s)
various tweaks to make all tracers work again
1 /*
2 * PearPC
3 * ide.cc
4 *
5 * Copyright (C) 2003, 2004 Sebastian Biallas (sb@biallas.net)
6 * Some ideas from harddrv.cc from Bochs (http://bochs.sf.net)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include <cerrno>
23 #include <cstdlib>
24 #include <cstring>
25
26 #include "tools/data.h"
27 #include "tools/snprintf.h"
28 #include "system/arch/sysendian.h"
29 #include "cpu/cpu.h"
30 #include "cpu/debug.h"
31 #include "cpu/mem.h"
32 #include "io/pic/pic.h"
33 #include "io/pci/pci.h"
34 #include "debug/tracers.h"
35 #include "ide.h"
36 #include "ata.h"
37 #include "cd.h"
38 #include "system/syscdrom.h"
39
40 #define IDE_ADDRESS_ISA_BASE 0x1f0
41 #define IDE_ADDRESS_ISA_BASE2 0x354
42
43 #define IDE_ADDRESS_DATA 0x0 // R/W
44 #define IDE_ADDRESS_ERROR 0x1 // R
45 #define IDE_ADDRESS_FEATURE 0x1 // W
46 #define IDE_ADDRESS_SEC_CNT 0x2 // R/W ATA
47 #define IDE_ADDRESS_INTR_REASON 0x2 // R/W ATAPI
48 #define IDE_ADDRESS_SEC_NO 0x3 // R/W
49 #define IDE_ADDRESS_CYL_LSB 0x4 // R/W
50 #define IDE_ADDRESS_CYL_MSB 0x5 // R/W
51 #define IDE_ADDRESS_DRV_HEAD 0x6 // R/W
52 #define IDE_ADDRESS_STATUS 0x7 // R
53 #define IDE_ADDRESS_COMMAND 0x7 // W
54
55 #define IDE_ADDRESS_STATUS2 0x12 // R
56 #define IDE_ADDRESS_OUTPUT 0x12 // W
57 #define IDE_ADDRESS_DEV_ADR 0x13 // R
58
59 #define IDE_DRIVE_HEAD_LBA (1<<6)
60 #define IDE_DRIVE_HEAD_SLAVE (1<<4)
61 #define IDE_DRIVE_HEAD(v) ((v) & 0xf)
62
63 #define IDE_OUTPUT_RESET 4
64 #define IDE_OUTPUT_INT 2
65
66 #define IDE_STATUS_BSY (1<<7)
67 #define IDE_STATUS_RDY (1<<6)
68 #define IDE_STATUS_WFT (1<<5)
69 #define IDE_STATUS_SKC (1<<4)
70 #define IDE_STATUS_DRQ (1<<3)
71 #define IDE_STATUS_CORR (1<<2)
72 #define IDE_STATUS_IDX (1<<1)
73 #define IDE_STATUS_ERR (1<<0)
74
75 #define IDE_CONFIG_ATAPI (1<<15)
76 #define IDE_CONFIG_HD (1<<6)
77
78 #define IDE_COMMAND_RESET_ATAPI 0x08
79 #define IDE_COMMAND_RECALIBRATE 0x10
80 #define IDE_COMMAND_READ_SECTOR 0x20
81 #define IDE_COMMAND_WRITE_SECTOR 0x30
82 #define IDE_COMMAND_FIX_PARAM 0x91
83 #define IDE_COMMAND_IDENT_ATAPI 0xa1
84 #define IDE_COMMAND_PACKET 0xa0
85 #define IDE_COMMAND_SET_MULTIPLE 0xc6
86 #define IDE_COMMAND_READ_SECTOR_DMA 0xc8
87 #define IDE_COMMAND_WRITE_SECTOR_DMA 0xca
88 #define IDE_COMMAND_STANDBY_IMMEDIATE 0xe0
89 #define IDE_COMMAND_SLEEP 0xe6
90 #define IDE_COMMAND_FLUSH_CACHE 0xe7
91 #define IDE_COMMAND_IDENT 0xec
92 #define IDE_COMMAND_SET_FEATURE 0xef
93 #define IDE_COMMAND_READ_NATIVE_MAX 0xf8
94
95 #define IDE_COMMAND_FEATURE_ENABLE_WRITE_CACHE 0x02
96 #define IDE_COMMAND_FEATURE_SET_TRANSFER_MODE 0x03
97 #define IDE_COMMAND_FEATURE_ENABLE_APM 0x05
98 #define IDE_COMMAND_FEATURE_SET_PIO_MODE 0x08
99 #define IDE_COMMAND_FEATURE_DISABLE_WRITE_CACHE 0x82
100 #define IDE_COMMAND_FEATURE_ENABLE_LOOKAHEAD 0xaa
101 #define IDE_COMMAND_FEATURE_DISABLE_LOOKAHEAD 0x55
102 #define IDE_COMMAND_FEATURE_ENABLE_PW_DEFAULT 0xcc
103 #define IDE_COMMAND_FEATURE_DISABLE_PW_DEFAULT 0x66
104
105 // .259
106 // 6 Byte CDB
107 #define IDE_ATAPI_COMMAND_TEST_READY 0x00 // .499
108 #define IDE_ATAPI_COMMAND_REQ_SENSE 0x03 // .450
109 #define IDE_ATAPI_COMMAND_FORMAT_UNIT 0x04 // .271
110 #define IDE_ATAPI_COMMAND_INQUIRY 0x12 // .310
111 #define IDE_ATAPI_COMMAND_MODE_SELECT6 0x15
112 #define IDE_ATAPI_COMMAND_MODE_SENSE6 0x1a
113 #define IDE_ATAPI_COMMAND_START_STOP 0x1b // .493
114 #define IDE_ATAPI_COMMAND_TOGGLE_LOCK 0x1e // .335
115
116 // 10 Byte CDB
117 #define IDE_ATAPI_COMMAND_READ_FMT_CAP 0x23 // .400
118 #define IDE_ATAPI_COMMAND_READ_CAPACITY 0x25 // .349
119 #define IDE_ATAPI_COMMAND_READ10 0x28 // .337
120 #define IDE_ATAPI_COMMAND_SEEK10 0x2b // .460
121 #define IDE_ATAPI_COMMAND_ERASE10 0x2c // .269
122 #define IDE_ATAPI_COMMAND_WRITE10 0x2a // .502
123 #define IDE_ATAPI_COMMAND_VER_WRITE10 0x2e // .510
124 #define IDE_ATAPI_COMMAND_VERIFY10 0x2f // .500
125 #define IDE_ATAPI_COMMAND_SYNC_CACHE 0x35 // .497
126 #define IDE_ATAPI_COMMAND_WRITE_BUF 0x3b // .512
127 #define IDE_ATAPI_COMMAND_READ_BUF 0x3c // .342
128 #define IDE_ATAPI_COMMAND_READ_SUBCH 0x42 // .406
129 #define IDE_ATAPI_COMMAND_READ_TOC 0x43 // .413
130 #define IDE_ATAPI_COMMAND_READ_HEADER 0x44
131 #define IDE_ATAPI_COMMAND_PLAY_AUDIO10 0x45 // .329
132 #define IDE_ATAPI_COMMAND_GET_CONFIG 0x46 // .284
133 #define IDE_ATAPI_COMMAND_PLAY_AUDIOMSF 0x47 // .333
134 #define IDE_ATAPI_COMMAND_EVENT_INFO 0x4a // .287
135 #define IDE_ATAPI_COMMAND_TOGGLE_PAUSE 0x4b // .327
136 #define IDE_ATAPI_COMMAND_STOP 0x4e // .495
137 #define IDE_ATAPI_COMMAND_READ_INFO 0x51 // .362
138 #define IDE_ATAPI_COMMAND_READ_TRK_INFO 0x52 // .423
139 #define IDE_ATAPI_COMMAND_RES_TRACK 0x53 // .455
140 #define IDE_ATAPI_COMMAND_SEND_OPC 0x54 // .482
141 #define IDE_ATAPI_COMMAND_MODE_SELECT10 0x55 // .322
142 #define IDE_ATAPI_COMMAND_REPAIR_TRACK 0x58 // .441
143 #define IDE_ATAPI_COMMAND_MODE_SENSE10 0x5a // .324
144 #define IDE_ATAPI_COMMAND_CLOSE_TRACK 0x5b // .264
145 #define IDE_ATAPI_COMMAND_READ_BUF_CAP 0x5c // .348
146
147 // 12 Byte CDB
148 #define IDE_ATAPI_COMMAND_BLANK 0xa1 // .260
149 #define IDE_ATAPI_COMMAND_SEND_KEY 0xa3 // .478
150 #define IDE_ATAPI_COMMAND_REPORT_KEY 0xa4 // .443
151 #define IDE_ATAPI_COMMAND_PLAY_AUDIO12 0xa5 // .331
152 #define IDE_ATAPI_COMMAND_LOAD_CD 0xa6 // .315
153 #define IDE_ATAPI_COMMAND_SET_RD_AHEAD 0xa7 // .486
154 #define IDE_ATAPI_COMMAND_READ12 0xa8 // .339
155 #define IDE_ATAPI_COMMAND_WRITE12 0xaa // .507
156 #define IDE_ATAPI_COMMAND_GET_PERF 0xac // .299
157 #define IDE_ATAPI_COMMAND_READ_DVD_S 0xad // .368
158 #define IDE_ATAPI_COMMAND_SET_STREAM 0xb6 // .488
159 #define IDE_ATAPI_COMMAND_READ_CD_MSF 0xb9 // .360
160 #define IDE_ATAPI_COMMAND_SCAN 0xba // .458
161 #define IDE_ATAPI_COMMAND_SET_CD_SPEED 0xbb // .484
162 #define IDE_ATAPI_COMMAND_PLAY_CD 0xbc
163 #define IDE_ATAPI_COMMAND_MECH_STATUS 0xbd // .317
164 #define IDE_ATAPI_COMMAND_READ_CD 0xbe // .352
165 #define IDE_ATAPI_COMMAND_SEND_DVD_S 0xbf // .470
166
167 enum {
168 IDE_TRANSFER_MODE_NONE,
169 IDE_TRANSFER_MODE_READ,
170 IDE_TRANSFER_MODE_WRITE,
171 IDE_TRANSFER_MODE_DMA,
172 };
173
174 #define IDE_ATAPI_PACKET_SIZE 12
175
176 #define IDE_ATAPI_SENSE_NONE 0
177 #define IDE_ATAPI_SENSE_NOT_READY 2
178 #define IDE_ATAPI_SENSE_ILLEGAL_REQUEST 5
179 #define IDE_ATAPI_SENSE_UNIT_ATTENTION 6
180
181 #define IDE_ATAPI_ASC_INV_FIELD_IN_CMD_PACKET 0x24
182 #define IDE_ATAPI_ASC_CANNOT_READ_MEDIUM 0x30
183 #define IDE_ATAPI_ASC_MEDIUM_NOT_PRESENT 0x3a
184 #define IDE_ATAPI_ASC_SAVING_PARAMETERS_NOT_SUPPORTED 0x39
185 #define IDE_ATAPI_ASC_LOGICAL_BLOCK_OOR 0x21
186
187 #define IDE_ATAPI_INTR_REASON_C_D (1<<0)
188 #define IDE_ATAPI_INTR_REASON_I_O (1<<1)
189 #define IDE_ATAPI_INTR_REASON_REL (1<<2)
190 #define IDE_ATAPI_INTR_REASON_TAG(v) ((v)>>3)
191 #define IDE_ATAPI_INTR_REASON_SET_TAG(v, a) (((v)&7) | ((a)<<3))
192
193 #define IDE_ATAPI_TRANSFER_HDR_SYNC 0x80
194 #define IDE_ATAPI_TRANSFER_HDR_SECTOR_SUB 0x40
195 #define IDE_ATAPI_TRANSFER_HDR_SECTOR 0x20
196 #define IDE_ATAPI_TRANSFER_DATA 0x10
197 #define IDE_ATAPI_TRANSFER_ECC 0x08
198
199 struct IDEDriveState {
200 uint8 status;
201 uint8 head;
202 uint8 outreg;
203 uint8 error;
204 uint8 feature;
205 union {
206 uint8 sector_count;
207 uint8 intr_reason;
208 };
209 uint8 sector_no;
210 union {
211 uint16 cyl;
212 uint16 byte_count;
213 };
214
215 int sectorpos;
216 int drqpos;
217 uint8 sector[IDE_MAX_BLOCK_SIZE];
218 int current_sector_size;
219 int current_command;
220 uint32 dma_lba_start;
221 uint32 dma_lba_count;
222
223 int mode;
224 int atapi_transfer_request;
225 };
226
227 struct IDEState {
228 int drive;
229 uint8 drive_head;
230 IDEConfig config[2];
231 IDEDriveState state[2];
232
233 bool one_time_shit;
234 };
235
236 IDEState gIDEState;
237
238 /*******************************************************************************
239 * IDE - Controller PCI
240 */
241
242 #define IDE_PCI_REG_0_CMD 0
243 #define IDE_PCI_REG_0_CTRL 1
244 #define IDE_PCI_REG_1_CMD 2
245 #define IDE_PCI_REG_1_CTRL 3
246 #define IDE_PCI_REG_BMDMA 4
247
248 /*
249 * CMD64x specific registers definition.
250 */
251 #define CFR 0x50
252 #define CFR_INTR_CH0 0x02
253 #define CNTRL 0x51
254 #define CNTRL_DIS_RA0 0x40
255 #define CNTRL_DIS_RA1 0x80
256 #define CNTRL_ENA_2ND 0x08
257
258 #define CMDTIM 0x52
259 #define ARTTIM0 0x53
260 #define DRWTIM0 0x54
261 #define ARTTIM1 0x55
262 #define DRWTIM1 0x56
263 #define ARTTIM23 0x57
264 #define ARTTIM23_DIS_RA2 0x04
265 #define ARTTIM23_DIS_RA3 0x08
266 #define ARTTIM23_INTR_CH1 0x10
267 #define ARTTIM2 0x57
268 #define ARTTIM3 0x57
269 #define DRWTIM23 0x58
270 #define DRWTIM2 0x58
271 #define BRST 0x59
272 #define DRWTIM3 0x5b
273
274 #define BMIDECR0 0x70
275 #define MRDMODE 0x71
276 #define MRDMODE_INTR_CH0 0x04
277 #define MRDMODE_INTR_CH1 0x08
278 #define MRDMODE_BLK_CH0 0x10
279 #define MRDMODE_BLK_CH1 0x20
280 #define BMIDESR0 0x72
281 #define UDIDETCR0 0x73
282 #define DTPR0 0x74
283 #define BMIDECR1 0x78
284 #define BMIDECSR 0x79
285 #define BMIDESR1 0x7A
286 #define UDIDETCR1 0x7B
287 #define DTPR1 0x7C
288
289 /*
290 * Bus master IDE consts
291 */
292
293 // bus master IDE command register (CR)
294 #define BM_IDE_CR_WRITE (1<<3) // read otherwise
295 #define BM_IDE_CR_START (1<<0) // stop otherwise
296 #define BM_IDE_CR_MASK (BM_IDE_CR_WRITE | BM_IDE_CR_START)
297
298 // bus master IDE status register (SR)
299 #define BM_IDE_SR_SIMPLEX_ONLY (1<<7) // duplex otherwise
300 #define BM_IDE_SR_DMA1_CAPABLE (1<<6)
301 #define BM_IDE_SR_DMA0_CAPABLE (1<<5)
302 #define BM_IDE_SR_INTERRUPT (1<<2)
303 #define BM_IDE_SR_ERROR (1<<1)
304 #define BM_IDE_SR_ACTIVE (1<<0)
305 #define BM_IDE_SR_MASK (BM_IDE_SR_ERROR | BM_IDE_SR_INTERRUPT \
306 | BM_IDE_SR_DMA0_CAPABLE | BM_IDE_SR_DMA1_CAPABLE | BM_IDE_SR_SIMPLEX_ONLY \
307 | BM_IDE_SR_ACTIVE)
308
309 class IDE_Controller: public PCI_Device {
310 public:
311
312 IDE_Controller()
313 :PCI_Device("IDE-Controller", 0x01, 0x01)
314 {
315 mIORegSize[IDE_PCI_REG_0_CMD] = 0x10;
316 mIORegSize[IDE_PCI_REG_0_CTRL] = 0x10;
317 mIORegSize[IDE_PCI_REG_1_CMD] = 0; // no secondary controller for now
318 mIORegSize[IDE_PCI_REG_1_CTRL] = 0;
319 mIORegSize[IDE_PCI_REG_BMDMA] = 0x10;
320
321 mIORegType[IDE_PCI_REG_0_CMD] = PCI_ADDRESS_SPACE_IO;
322 mIORegType[IDE_PCI_REG_0_CTRL] = PCI_ADDRESS_SPACE_IO;
323 mIORegType[IDE_PCI_REG_BMDMA] = PCI_ADDRESS_SPACE_IO;
324
325 mConfig[0x00] = 0x95; // vendor ID
326 mConfig[0x01] = 0x10;
327 mConfig[0x02] = 0x46; // unit ID
328 mConfig[0x03] = 0x06;
329
330 mConfig[0x04] = 0x01; // command
331 mConfig[0x05] = 0x00;
332 mConfig[0x06] = 0x00; // status
333 mConfig[0x07] = 0x00;
334
335 mConfig[0x08] = 0x07; // ide-controller revision
336 mConfig[0x09] = 0x8f; // bit7: bm-ide
337 mConfig[0x0a] = 0x01; // ide-controller
338 mConfig[0x0b] = 0x01; // controller for mass-storage
339
340 mConfig[0x0e] = 0x00; // header-type
341
342 assignIOPort(IDE_PCI_REG_0_CMD, 0x0001c40);
343 assignIOPort(IDE_PCI_REG_0_CTRL, 0x0001c30);
344 assignIOPort(IDE_PCI_REG_BMDMA, 0x0001c00);
345
346 mConfig[0x3c] = 0x1a; // irq
347 mConfig[0x3d] = 1;
348 mConfig[0x3e] = 0x02; // min grand
349 mConfig[0x3f] = 0x04; // max latency
350 }
351
352 /*******************************************************************************
353 * IDE - Controller Core
354 */
355
356 /*
357 * makeLogical return a maximum of 0x10000000, so it's safe
358 * to use uint32 here.
359 */
360 uint32 makeLogical(int head, int cyl, int sec_no)
361 {
362 if (gIDEState.config[gIDEState.drive].lba) {
363 return (head << 24) | (cyl << 8) | sec_no;
364 } else {
365 return cyl * gIDEState.config[gIDEState.drive].hd.heads * gIDEState.config[gIDEState.drive].hd.spt
366 + head * gIDEState.config[gIDEState.drive].hd.spt
367 + sec_no - 1;
368 }
369 }
370
371 void incAddress()
372 {
373 gIDEState.state[gIDEState.drive].sector_count--;
374
375 if (gIDEState.config[gIDEState.drive].lba) {
376 uint32 cur = makeLogical(gIDEState.state[gIDEState.drive].head,
377 gIDEState.state[gIDEState.drive].cyl,
378 gIDEState.state[gIDEState.drive].sector_no);
379 cur++;
380 gIDEState.state[gIDEState.drive].head = (cur>>24) & 0xf;
381 gIDEState.state[gIDEState.drive].cyl = cur>>8;
382 gIDEState.state[gIDEState.drive].sector_no = cur & 0xff;
383 } else {
384 gIDEState.state[gIDEState.drive].sector_no++;
385 if (gIDEState.state[gIDEState.drive].sector_no > gIDEState.config[gIDEState.drive].hd.spt) {
386 gIDEState.state[gIDEState.drive].sector_no = 1;
387 gIDEState.state[gIDEState.drive].head++;
388 if (gIDEState.state[gIDEState.drive].head >= gIDEState.config[gIDEState.drive].hd.heads) {
389 gIDEState.state[gIDEState.drive].head = 0;
390 gIDEState.state[gIDEState.drive].cyl++;
391 }
392 }
393 }
394 }
395
396 void raiseInterrupt(int bus)
397 {
398 IO_IDE_TRACE("MRDMODE: %02x\n", mConfig[MRDMODE]);
399 if (!(gIDEState.state[gIDEState.drive].outreg & IDE_OUTPUT_INT) && !(mConfig[MRDMODE] & MRDMODE_BLK_CH0)) {
400 pic_raise_interrupt(mConfig[0x3c]);
401 }
402 mConfig[MRDMODE] |= MRDMODE_INTR_CH0 << bus;
403 }
404
405 void cancelInterrupt(int bus)
406 {
407 pic_cancel_interrupt(IO_PIC_IRQ_IDE0);
408 mConfig[MRDMODE] &= ~(MRDMODE_INTR_CH0 << bus);
409 }
410
411 void drive_ident()
412 {
413 #define AW(a, b) (((a)<<8)|(b))
414 uint16 id[256];
415 if (gIDEState.config[gIDEState.drive].installed) {
416 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY | IDE_STATUS_DRQ | IDE_STATUS_SKC;
417 } else {
418 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY | IDE_STATUS_ERR;
419 gIDEState.state[gIDEState.drive].error = 0x4; // abort command
420 return;
421 }
422 memset(&id, 0, sizeof id);
423 if (gIDEState.config[gIDEState.drive].protocol == IDE_ATA) {
424 // id[0] = IDE_CONFIG_HD;
425 id[0] = 0x0c5a;
426 id[1] = gIDEState.config[gIDEState.drive].hd.cyl;
427 id[3] = gIDEState.config[gIDEState.drive].hd.heads;
428 id[4] = gIDEState.config[gIDEState.drive].hd.spt*gIDEState.config[gIDEState.drive].bps;
429 id[5] = gIDEState.config[gIDEState.drive].bps;
430 id[6] = gIDEState.config[gIDEState.drive].hd.spt;
431 } else {
432 // id[0] = IDE_CONFIG_ATAPI | (5 << 8) | (1 << 7) | (1 << 6) | (0 << 0);
433 id[0] = 0x85c0;
434 }
435
436 id[10] = AW(' ',' ');
437 id[11] = AW(' ',' ');
438 id[12] = AW(' ',' ');
439 id[13] = AW(' ',' ');
440 id[14] = AW(' ',' ');
441 id[15] = AW('F','o');
442 id[16] = AW('u','n');
443 id[17] = AW('d','a');
444 id[18] = AW('t','i');
445 id[19] = AW('o','n');
446
447 if (gIDEState.config[gIDEState.drive].protocol == IDE_ATA) {
448 id[20] = 3; //buffer type
449 id[21] = 512; //buffer size / 512
450 id[22] = 4; // ECC-Bytes
451 } else {
452 id[20] = 3; //buffer type
453 id[21] = 0x100; //buffer size / 512
454 id[22] = 0; // ECC-Bytes
455 }
456 id[23] = AW('F','I');
457 id[24] = AW('R','M');
458 id[25] = AW('W','A');
459 id[26] = AW('R','E');
460 if (gIDEState.drive==0) {
461 id[27] = AW('E','I');
462 id[28] = AW('N',' ');
463 id[29] = AW('G','E');
464 id[30] = AW('B','U');
465 id[31] = AW('E','S');
466 id[32] = AW('C','H');
467 id[33] = AW('!',' ');
468 id[34] = AW(' ',' ');
469 } else {
470 id[27] = AW('Z','W');
471 id[28] = AW('E','I');
472 id[29] = AW(' ','G');
473 id[30] = AW('E','B');
474 id[31] = AW('U','E');
475 id[32] = AW('S','C');
476 id[33] = AW('H','!');
477 id[34] = AW(' ',' ');
478 }
479 id[35] = AW(' ',' ');
480 id[36] = AW(' ',' ');
481 id[37] = AW(' ',' ');
482 id[38] = AW(' ',' ');
483 id[39] = AW(' ',' ');
484 id[40] = AW(' ',' ');
485 id[41] = AW(' ',' ');
486 id[42] = AW(' ',' ');
487 id[43] = AW(' ',' ');
488 id[44] = AW(' ',' ');
489 id[45] = AW(' ',' ');
490 id[46] = AW(' ',' ');
491
492 if (gIDEState.config[gIDEState.drive].protocol == IDE_ATA) {
493 id[47] = 1; // sectors per interrupt
494 id[48] = 0; // 32 bit i/o
495 id[49] = (1<<9)|(1<<8); // LBA & DMA
496 id[51] = 0x200; // pio time
497 id[52] = 0x200; // dma time
498 // from Linux kernel's hdreg.h:
499 // unsigned short field_valid;
500
501 /* (word 53)
502 * 2: ultra_ok word 88
503 * 1: eide_ok words 64-70
504 * 0: cur_ok words 54-58
505 */
506
507 // see also: static int config_drive_for_dma (ide_drive_t *drive) in ide-dma.c
508
509 id[53] = 4; // fieldValidity: Multi DMA fields valid
510
511 id[54] = gIDEState.config[gIDEState.drive].hd.cyl;
512 id[55] = gIDEState.config[gIDEState.drive].hd.heads;
513 id[56] = gIDEState.config[gIDEState.drive].hd.spt;
514
515 uint32 sectors = gIDEState.config[gIDEState.drive].hd.cyl
516 * gIDEState.config[gIDEState.drive].hd.heads
517 * gIDEState.config[gIDEState.drive].hd.spt;
518 id[57] = sectors;
519 id[58] = sectors >> 16;
520 id[59] = 0; // multisector bla
521 id[60] = sectors; // lba capacity
522 id[61] = sectors >> 16; // lba capacity cont.
523 id[62] = 0; // obsolete single word dma (linux dma_1word)
524 id[63] = 7|0x404; // multiple word dma info (linux dma_mword)
525 id[64] = 1; // eide pio modes
526 id[65] = 480; // eide min dma cycle time
527 id[66] = 480; // eide recommended dma cycle time
528 id[67] = 0;
529 id[68] = 0;
530 id[69] = 0; // res
531 id[70] = 0; // res
532
533 id[80] = (1<<2) | (1<<1);
534 id[82] = (1<<14) | (1<<9) | (1<<5) | (1<<3); // command set 1
535 id[83] = (1<<14); // command set 2
536 id[84] = (1<<14); // set feature extensions
537 id[85] = (1<<5); // set feature enabled
538 id[86] = (1<<14); // set feature enabled 2
539 id[87] = (1<<14); // set feature default
540 id[88] = 7; // dma ultra
541 // bit 15 set indicates UDMA(mode 7) capable
542 // bit 14 set indicates UDMA(133) capable
543 // bit 13 set indicates UDMA(100) capable
544 // bit 12 set indicates UDMA(66) capable
545 // bit 11 set indicates UDMA(44) capable
546 // bits 0-2 ???
547
548 id[93] = (1<<14) | 1; // hw config
549 } else {
550 id[47] = 0; // sectors per interrupt
551 id[48] = 1; // 32 bit i/o
552 id[49] = (1<<9); // lba
553 id[53] = 3;
554 id[63] = 0x103;
555 id[64] = 0x1;
556 id[65] = 0xb4;
557 id[66] = 0xb4;
558 id[67] = 0x12c;
559 id[68] = 0xb4;
560 id[71] = 30;
561 id[72] = 30;
562 id[80] = 0x1e; // supports up to ATA/ATAPI-4
563 }
564
565 gIDEState.state[gIDEState.drive].sectorpos = 0;
566 gIDEState.state[gIDEState.drive].sector_count = 0;
567
568 for (int i=0; i<256; i++) {
569 gIDEState.state[gIDEState.drive].sector[i*2] = id[i];
570 gIDEState.state[gIDEState.drive].sector[i*2+1] = id[i]>>8;
571 }
572 }
573
574 void atapi_command_nop()
575 {
576 gIDEState.state[gIDEState.drive].intr_reason |= IDE_ATAPI_INTR_REASON_C_D|IDE_ATAPI_INTR_REASON_I_O;
577 gIDEState.state[gIDEState.drive].intr_reason &= ~IDE_ATAPI_INTR_REASON_REL;
578 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY | IDE_STATUS_SKC;
579 }
580
581 void atapi_command_error(uint8 sense_key, uint8 asc)
582 {
583 memset(&gIDEState.config[gIDEState.drive].cdrom.sense, 0, sizeof gIDEState.config[gIDEState.drive].cdrom.sense);
584 gIDEState.state[gIDEState.drive].error = sense_key << 4;
585 gIDEState.state[gIDEState.drive].intr_reason |= IDE_ATAPI_INTR_REASON_C_D|IDE_ATAPI_INTR_REASON_I_O;
586 gIDEState.state[gIDEState.drive].intr_reason &= ~IDE_ATAPI_INTR_REASON_REL;
587 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY | IDE_STATUS_ERR;
588
589 gIDEState.config[gIDEState.drive].cdrom.sense.sense_key = sense_key;
590 gIDEState.config[gIDEState.drive].cdrom.sense.asc = asc;
591 gIDEState.config[gIDEState.drive].cdrom.sense.ascq = 0;
592 }
593
594 void atapi_start_send_command(uint8 command, int reqlen, int alloclen, int sectorpos=0, int sectorsize=2048)
595 {
596 if (gIDEState.state[gIDEState.drive].byte_count == 0xffff) gIDEState.state[gIDEState.drive].byte_count = 0xfffe;
597 if ((gIDEState.state[gIDEState.drive].byte_count & 1) && !(alloclen <= gIDEState.state[gIDEState.drive].byte_count)) {
598 gIDEState.state[gIDEState.drive].byte_count--;
599 }
600 if (!gIDEState.state[gIDEState.drive].byte_count) {
601 IO_IDE_ERR("byte_count==0\n");
602 }
603 if (!alloclen) alloclen = gIDEState.state[gIDEState.drive].byte_count;
604 gIDEState.state[gIDEState.drive].intr_reason |= IDE_ATAPI_INTR_REASON_I_O;
605 gIDEState.state[gIDEState.drive].intr_reason &= ~IDE_ATAPI_INTR_REASON_C_D;
606 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY | IDE_STATUS_DRQ | IDE_STATUS_SKC;
607 gIDEState.state[gIDEState.drive].sectorpos = sectorpos;
608 gIDEState.state[gIDEState.drive].current_sector_size = sectorsize;
609 gIDEState.state[gIDEState.drive].drqpos = 0;
610 if (gIDEState.state[gIDEState.drive].byte_count > reqlen) gIDEState.state[gIDEState.drive].byte_count = reqlen;
611 if (gIDEState.state[gIDEState.drive].byte_count > alloclen) gIDEState.state[gIDEState.drive].byte_count = alloclen;
612
613 gIDEState.config[gIDEState.drive].cdrom.atapi.command = command;
614 gIDEState.config[gIDEState.drive].cdrom.atapi.drq_bytes = gIDEState.state[gIDEState.drive].byte_count;
615 gIDEState.config[gIDEState.drive].cdrom.atapi.total_remain = MIN(reqlen, alloclen);
616 }
617
618 void atapi_start_mode_sense(const byte *src, int size)
619 {
620 gIDEState.state[gIDEState.drive].sector[0] = (size-2) >> 8;
621 gIDEState.state[gIDEState.drive].sector[1] = size-2;
622 gIDEState.state[gIDEState.drive].sector[2] = 0;
623 gIDEState.state[gIDEState.drive].sector[3] = 0;
624 gIDEState.state[gIDEState.drive].sector[4] = 0;
625 gIDEState.state[gIDEState.drive].sector[5] = 0;
626 gIDEState.state[gIDEState.drive].sector[6] = 0;
627 gIDEState.state[gIDEState.drive].sector[7] = 0;
628 }
629
630 static uint8 bcd_encode(uint8 value)
631 {
632 return (value / 10)*16+(value % 10);
633 }
634
635 /*
636 * gIDEState.config[gIDEState.drive] must be acquired
637 */
638 bool atapi_check_dma()
639 {
640 if (gIDEState.config[gIDEState.drive].cdrom.dma) {
641 gIDEState.state[gIDEState.drive].dma_lba_count = gIDEState.config[gIDEState.drive].cdrom.remain;
642 gIDEState.state[gIDEState.drive].dma_lba_start = gIDEState.config[gIDEState.drive].cdrom.next_lba;
643 gIDEState.config[gIDEState.drive].device->setMode(
644 gIDEState.state[gIDEState.drive].atapi_transfer_request,
645 gIDEState.state[gIDEState.drive].current_sector_size);
646 gIDEState.config[gIDEState.drive].device->seek(gIDEState.state[gIDEState.drive].dma_lba_start);
647 gIDEState.state[gIDEState.drive].status &= ~IDE_STATUS_DRQ;
648 gIDEState.state[gIDEState.drive].intr_reason |= IDE_ATAPI_INTR_REASON_C_D;
649 bmide_start_dma(false);
650 return true;
651 }
652 return false;
653 }
654
655 void receive_atapi_packet()
656 {
657 uint8 command = gIDEState.state[gIDEState.drive].sector[0];
658 IO_IDE_TRACE("ATAPI command(%02x)\n", command);
659 CDROMDevice *dev = (CDROMDevice *)gIDEState.config[gIDEState.drive].device;
660 uint8 *sector = gIDEState.state[gIDEState.drive].sector;
661 switch (command) {
662 case IDE_ATAPI_COMMAND_TEST_READY:
663 if (dev->isReady()) {
664 atapi_command_nop();
665 } else {
666 atapi_command_error(IDE_ATAPI_SENSE_NOT_READY, IDE_ATAPI_ASC_MEDIUM_NOT_PRESENT);
667 }
668 raiseInterrupt(0);
669 break;
670 case IDE_ATAPI_COMMAND_REQ_SENSE: {
671 // .450
672 int len = sector[4];
673 atapi_start_send_command(command, 18, len);
674 sector[0] = 0xf0; // valid + current error info
675 sector[1] = 0x00;
676 sector[2] = gIDEState.config[gIDEState.drive].cdrom.sense.sense_key;
677 sector[3] = gIDEState.config[gIDEState.drive].cdrom.sense.info[0];
678 sector[4] = gIDEState.config[gIDEState.drive].cdrom.sense.info[1];
679 sector[5] = gIDEState.config[gIDEState.drive].cdrom.sense.info[2];
680 sector[6] = gIDEState.config[gIDEState.drive].cdrom.sense.info[3];
681 sector[7] = 10;
682 sector[8] = gIDEState.config[gIDEState.drive].cdrom.sense.spec_info[0];
683 sector[9] = gIDEState.config[gIDEState.drive].cdrom.sense.spec_info[1];
684 sector[10] = gIDEState.config[gIDEState.drive].cdrom.sense.spec_info[2];
685 sector[11] = gIDEState.config[gIDEState.drive].cdrom.sense.spec_info[3];
686 sector[12] = gIDEState.config[gIDEState.drive].cdrom.sense.asc;
687 sector[13] = gIDEState.config[gIDEState.drive].cdrom.sense.ascq;
688 sector[14] = gIDEState.config[gIDEState.drive].cdrom.sense.fruc;
689 sector[15] = gIDEState.config[gIDEState.drive].cdrom.sense.key_spec[0];
690 sector[16] = gIDEState.config[gIDEState.drive].cdrom.sense.key_spec[1];
691 sector[17] = gIDEState.config[gIDEState.drive].cdrom.sense.key_spec[2];
692 raiseInterrupt(0);
693 break;
694 }
695 case IDE_ATAPI_COMMAND_INQUIRY: {
696 // .310
697 int len = sector[4];
698 atapi_start_send_command(command, 36, len);
699 memset(sector, 0, sizeof gIDEState.state[gIDEState.drive].sector);
700 sector[0] = 0x05;
701 sector[1] = 0x80; // Removable Medium
702 sector[2] = 0x00; // ATAPI
703 sector[3] = 0x32; // ATAPI / format = 2
704 sector[4] = 62-4;
705 sector[5] = 0x00;
706 sector[6] = 0x00;
707 sector[7] = 0x00;
708
709 memcpy(sector+8, "SPIRO ", 8);
710 memcpy(sector+16, "MULTIMAX 4000 ", 16);
711 memcpy(sector+32, "0.1 ", 4);
712
713 sector[58] = 0x03;
714 sector[59] = 0xa0; // MMC-4
715 sector[60] = 0x15;
716 sector[61] = 0xe0; // ATA/ATAPI-6
717
718 raiseInterrupt(0);
719 break;
720 }
721 case IDE_ATAPI_COMMAND_START_STOP: {
722 bool eject = sector[4] & 2;
723 bool start = sector[4] & 1;
724 if (!eject && !start) {
725 atapi_command_nop();
726 } else if (!eject && start) {
727 atapi_command_nop();
728 } else if (eject && !start) {
729 dev->eject();
730 atapi_command_nop();
731 } else {
732 dev->eject();
733 atapi_command_nop();
734 }
735 raiseInterrupt(0);
736 break;
737 }
738 case IDE_ATAPI_COMMAND_TOGGLE_LOCK:
739 if (dev->isReady()) {
740 dev->setLock(sector[4] & 1);
741 atapi_command_nop();
742 } else {
743 atapi_command_error(IDE_ATAPI_SENSE_NOT_READY, IDE_ATAPI_ASC_MEDIUM_NOT_PRESENT);
744 }
745 raiseInterrupt(0);
746 break;
747 case IDE_ATAPI_COMMAND_READ_CAPACITY:
748 if (dev->isReady()) {
749 atapi_start_send_command(command, 8, 8);
750 uint32 capacity = dev->getCapacity();
751 sector[0] = capacity >> 24;
752 sector[1] = capacity >> 16;
753 sector[2] = capacity >> 8;
754 sector[3] = capacity;
755 sector[4] = 2048 >> 24;
756 sector[5] = 2048 >> 16;
757 sector[6] = 2048 >> 8;
758 sector[7] = 2048;
759 } else {
760 atapi_command_error(IDE_ATAPI_SENSE_NOT_READY, IDE_ATAPI_ASC_MEDIUM_NOT_PRESENT);
761 }
762 raiseInterrupt(0);
763 break;
764 case IDE_ATAPI_COMMAND_READ10:
765 if (dev->isReady()) {
766 uint16 len = ((uint16)sector[7]<<8)|(sector[8]);
767 if (!len) {
768 atapi_command_nop();
769 } else {
770 uint32 lba = ((uint32)sector[2]<<24)|((uint32)sector[3]<<16)|((uint32)sector[4]<<8)|sector[5];
771 if (lba + len > dev->getCapacity()) {
772 atapi_command_error(IDE_ATAPI_SENSE_ILLEGAL_REQUEST, IDE_ATAPI_ASC_LOGICAL_BLOCK_OOR);
773 } else {
774 IO_IDE_TRACE("read cd: lba: 0x%08x len: %d\n", lba, len);
775 gIDEState.state[gIDEState.drive].current_sector_size = 2048;
776 gIDEState.state[gIDEState.drive].atapi_transfer_request = 0x10; // only data
777 uint secsize = gIDEState.state[gIDEState.drive].current_sector_size;
778 atapi_start_send_command(command, len*secsize, len*secsize, secsize, secsize);
779 gIDEState.config[gIDEState.drive].cdrom.remain = len;
780 gIDEState.config[gIDEState.drive].cdrom.next_lba = lba;
781 if (atapi_check_dma()) return;
782 }
783 }
784 } else {
785 atapi_command_error(IDE_ATAPI_SENSE_NOT_READY, IDE_ATAPI_ASC_MEDIUM_NOT_PRESENT);
786 }
787 raiseInterrupt(0);
788 break;
789 case IDE_ATAPI_COMMAND_SEEK10:
790 if (dev->isReady()) {
791 uint32 lba = ((uint32)sector[2]<<24)|((uint32)sector[3]<<16)|((uint32)sector[4]<<8)|sector[5];
792 if (lba > dev->getCapacity()) {
793 atapi_command_error(IDE_ATAPI_SENSE_ILLEGAL_REQUEST, IDE_ATAPI_ASC_LOGICAL_BLOCK_OOR);
794 } else {
795 atapi_command_nop();
796 }
797 } else {
798 atapi_command_error(IDE_ATAPI_SENSE_NOT_READY, IDE_ATAPI_ASC_MEDIUM_NOT_PRESENT);
799 }
800 raiseInterrupt(0);
801 break;
802 case IDE_ATAPI_COMMAND_READ_SUBCH:
803 SINGLESTEP("IDE_ATAPI_COMMAND_READ_SUBCH\n");
804 atapi_command_error(IDE_ATAPI_SENSE_ILLEGAL_REQUEST, IDE_ATAPI_ASC_INV_FIELD_IN_CMD_PACKET);
805 raiseInterrupt(0);
806 break;
807 case IDE_ATAPI_COMMAND_READ_TOC:
808 // .413
809 if (dev->isReady()) {
810 bool msf = sector[1] & 2;
811 uint8 start_track = sector[6];
812 int len = ((uint16)sector[7]<<8)|(sector[8]);
813 // first check for ATAPI-SFF 8020 style
814 uint8 format = sector[2] & 0xf;
815 if (!format) {
816 // then for MMC-2 style
817 format = sector[9] >> 6;
818 }
819 len = MIN(len, IDE_MAX_BLOCK_SIZE);
820 int result = dev->readTOC(sector, msf, start_track, len, format);
821 atapi_start_send_command(command, result, len);
822 } else {
823 atapi_command_error(IDE_ATAPI_SENSE_NOT_READY, IDE_ATAPI_ASC_MEDIUM_NOT_PRESENT);
824 }
825 raiseInterrupt(0);
826 break;
827 case IDE_ATAPI_COMMAND_READ_HEADER:
828 case IDE_ATAPI_COMMAND_PLAY_AUDIO10:
829 case IDE_ATAPI_COMMAND_PLAY_AUDIOMSF:
830 case IDE_ATAPI_COMMAND_TOGGLE_PAUSE:
831 case IDE_ATAPI_COMMAND_STOP:
832 case IDE_ATAPI_COMMAND_MODE_SELECT10:
833 case IDE_ATAPI_COMMAND_READ_INFO:
834 IO_IDE_WARN("ATAPI command 0x%08x not impl.\n", command);
835 atapi_command_error(IDE_ATAPI_SENSE_ILLEGAL_REQUEST, IDE_ATAPI_ASC_INV_FIELD_IN_CMD_PACKET);
836 raiseInterrupt(0);
837 break;
838 case IDE_ATAPI_COMMAND_MODE_SENSE6:
839 case IDE_ATAPI_COMMAND_MODE_SENSE10: {
840 // .324
841 uint8 pc = sector[2] >> 6;
842 uint8 pagecode = sector[2] & 0x3f;
843 int len;
844 if (command == IDE_ATAPI_COMMAND_MODE_SENSE6) {
845 len = ((uint16)sector[4]<<8)|(sector[5]);
846 } else {
847 len = ((uint16)sector[7]<<8)|(sector[8]);
848 }
849 memset(sector, 0, sizeof gIDEState.state[gIDEState.drive].sector);
850 // pagecode: .517
851 switch (pc) {
852 case 0x00:
853 switch (pagecode) {
854 case 0x01:
855 IO_IDE_ERR("MODE SENSE error recovery\n");
856 break;
857 case 0x1a:
858 // Power Condition Page
859 // .537
860 atapi_start_send_command(command, 20, len);
861 atapi_start_mode_sense(sector+8, 20);
862 sector[8] = 0x1a;
863 sector[9] = 10;
864 sector[10] = 0x00;
865 sector[11] = 0x00; // idle=0, standby=0
866 sector[12] = 0x00;
867 sector[13] = 0x00;
868 sector[14] = 0x00;
869 sector[15] = 0x00;
870 sector[16] = 0x00;
871 sector[17] = 0x00;
872 sector[18] = 0x00;
873 sector[19] = 0x00;
874 raiseInterrupt(0);
875 break;
876 case 0x2a:
877 // Capabilities and Mechanical Status Page
878 // .573
879 atapi_start_send_command(command, 36, len);
880 atapi_start_mode_sense(sector+8, 36);
881 sector[8] = 0x2a;
882 sector[9] = 28;
883 sector[10] = 0x3b; // DVD-RAM + DVD-R + DVD-ROM + CD-RW + CD-R read
884 sector[11] = 0;
885 sector[12] = 0;
886 sector[13] = 3<<5;
887 sector[14] = (dev->isLocked() ? (1<<1):0)
888 | 1 | (1<<3) | (1<<5);
889 sector[15] = 0;
890 sector[16] = 706 >> 8;
891 sector[17] = 706;
892 sector[18] = 0;
893 sector[19] = 2;
894 sector[20] = 512 >> 8;
895 sector[21] = 512;
896 sector[22] = 706 >> 8;
897 sector[23] = 706;
898 sector[24] = 0;
899 sector[25] = 0;
900 sector[26] = 0;
901 sector[27] = 0;
902 sector[28] = 0;
903 sector[29] = 0;
904 sector[30] = 0;
905 sector[31] = 0;
906 sector[32] = 0;
907 sector[33] = 0;
908 sector[34] = 0;
909 sector[35] = 0;
910 raiseInterrupt(0);
911 break;
912 case 0x31:
913 // Apple Features
914 atapi_start_send_command(command, 16, len);
915 atapi_start_mode_sense(sector+8, 16);
916 sector[8] = 0x31;
917 sector[9] = 6;
918 sector[10] = '.';
919 sector[11] = 'A';
920 sector[12] = 'p';
921 sector[13] = 'p';
922 sector[14] = 0;
923 sector[15] = 0;
924 raiseInterrupt(0);
925 break;
926 case 0x0d:
927 case 0x0e:
928 case 0x3f:
929 atapi_command_error(IDE_ATAPI_SENSE_ILLEGAL_REQUEST, IDE_ATAPI_ASC_INV_FIELD_IN_CMD_PACKET);
930 raiseInterrupt(0);
931 break;
932 default:;
933 IO_IDE_ERR("query MODE SENSE not impl. for 0x%08x\n", pagecode);
934 }
935 raiseInterrupt(0);
936 break;
937 case 0x01:
938 switch (pagecode) {
939 case 0x01:
940 case 0x2a:
941 case 0x0d:
942 case 0x0e:
943 case 0x3f:
944 IO_IDE_ERR("change MODE SENSE not impl. for 0x%08x\n", pagecode);
945 default:
946 atapi_command_error(IDE_ATAPI_SENSE_ILLEGAL_REQUEST, IDE_ATAPI_ASC_INV_FIELD_IN_CMD_PACKET);
947 raiseInterrupt(0);
948 break;
949 }
950 break;
951 case 0x02:
952 switch (pagecode) {
953 case 0x01:
954 case 0x2a:
955 case 0x0d:
956 case 0x0e:
957 case 0x3f:
958 IO_IDE_ERR("default MODE SENSE not impl. for 0x%08x\n", pagecode);
959 default:
960 atapi_command_error(IDE_ATAPI_SENSE_ILLEGAL_REQUEST, IDE_ATAPI_ASC_INV_FIELD_IN_CMD_PACKET);
961 raiseInterrupt(0);
962 break;
963 }
964 break;
965 case 0x03:
966 atapi_command_error(IDE_ATAPI_SENSE_ILLEGAL_REQUEST, IDE_ATAPI_ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
967 raiseInterrupt(0);
968 break;
969 }
970 break;
971 }
972 case IDE_ATAPI_COMMAND_GET_CONFIG: {
973 // .173 .242 .284
974 uint8 RT = sector[1] & 3;
975 int len = ((uint16)sector[7]<<8)|(sector[8]);
976 int feature = ((uint16)sector[2]<<8)|(sector[3]);
977 IO_IDE_TRACE("get_config: RT=%x len=%d f=%x\n", RT, len, feature);
978 memset(sector, 0, sizeof gIDEState.state[gIDEState.drive].sector);
979 len = MIN(len, IDE_MAX_BLOCK_SIZE);
980 int size = dev->getConfig(sector, len, RT, feature);
981 atapi_start_send_command(command, size, len);
982 raiseInterrupt(0);
983 break;
984 }
985 case IDE_ATAPI_COMMAND_EVENT_INFO: {
986 bool polled = sector[1] & 1;
987 uint8 request = sector[4];
988 int len = ((uint16)sector[7]<<8)|(sector[8]);
989 uint8 control = sector[9];
990 // int size = dev->eventInfo(sector, len, polled, request, control);
991 // atapi_start_send_command(command, size, len);
992 atapi_command_error(IDE_ATAPI_SENSE_ILLEGAL_REQUEST, IDE_ATAPI_ASC_INV_FIELD_IN_CMD_PACKET);
993 raiseInterrupt(0);
994 break;
995 }
996 case IDE_ATAPI_COMMAND_SET_CD_SPEED: {
997 // .484
998 atapi_command_nop();
999 raiseInterrupt(0);
1000 break;
1001 }
1002 case IDE_ATAPI_COMMAND_READ_CD: {
1003 // .352
1004 if (dev->isReady()) {
1005 uint32 len = ((uint32)sector[6]<<16)|((uint32)sector[7]<<8)|(sector[8]);
1006 if (!len) {
1007 atapi_command_nop();
1008 } else {
1009 int sec_type = (sector[1] >> 2) & 7; // .353
1010 bool dap = (sector[1] >> 1) & 1;
1011 bool rel = sector[1] & 1;
1012 uint32 lba = ((uint32)sector[2]<<24)|((uint32)sector[3]<<16)|((uint32)sector[4]<<8)|sector[5];
1013 int sub_ch = sector[10] & 3;
1014 if (sec_type) IO_IDE_ERR("sec_type not supported\n");
1015 if (rel) IO_IDE_ERR("rel not supported\n");
1016 if (sub_ch) IO_IDE_ERR("sub-channel not supported\n");
1017 // .95 .96
1018 gIDEState.state[gIDEState.drive].atapi_transfer_request = sector[9];
1019 if (gIDEState.state[gIDEState.drive].atapi_transfer_request & 7) IO_IDE_ERR("c2 not supported\n");
1020 if (lba + len > dev->getCapacity()) {
1021 atapi_command_error(IDE_ATAPI_SENSE_ILLEGAL_REQUEST, IDE_ATAPI_ASC_LOGICAL_BLOCK_OOR);
1022 } else {
1023 IO_IDE_TRACE("read cd: lba: %08x len: %08x\n", lba, len);
1024 switch (gIDEState.state[gIDEState.drive].atapi_transfer_request & 0xf8) { // .355
1025 case 0x00: // nothing
1026 gIDEState.state[gIDEState.drive].current_sector_size = 0;
1027 atapi_command_nop();
1028 raiseInterrupt(0);
1029 return;
1030 case 0x10: // user data
1031 gIDEState.state[gIDEState.drive].current_sector_size = 2048;
1032 break;
1033 case 0xf8: // everything
1034 // SYNC+HEADER+UserDATA+EDC+(Mode1 Pad)+ECC
1035 gIDEState.state[gIDEState.drive].current_sector_size = 12+4+2048+288;
1036 gIDEState.state[gIDEState.drive].atapi_transfer_request = 0xb8; // mode1 -> skip sub-header
1037 break;
1038 default:
1039 IO_IDE_ERR("unknown main channel selection in READ_CD\n");
1040 }
1041 uint cursize = gIDEState.state[gIDEState.drive].current_sector_size;
1042 atapi_start_send_command(command, len*cursize, len*cursize, cursize, cursize);
1043 gIDEState.config[gIDEState.drive].cdrom.remain = len;
1044 gIDEState.config[gIDEState.drive].cdrom.next_lba = lba;
1045 if (atapi_check_dma()) return;
1046 }
1047 }
1048 } else {
1049 atapi_command_error(IDE_ATAPI_SENSE_NOT_READY, IDE_ATAPI_ASC_MEDIUM_NOT_PRESENT);
1050 }
1051 raiseInterrupt(0);
1052 break;
1053 }
1054 case IDE_ATAPI_COMMAND_READ_DVD_S: {
1055 uint8 subcommand = sector[1] & 0xf;
1056 uint32 address = ((uint32)sector[2]<<24)|((uint32)sector[3]<<16)|((uint32)sector[4]<<8)|sector[5];
1057 uint8 layer = sector[6];
1058 uint8 format = sector[7];
1059 int len = ((uint16)sector[8]<<8)|(sector[9]);
1060 uint8 AGID = sector[10] >> 6;
1061 uint8 control = sector[11];
1062 len = MIN(len, IDE_MAX_BLOCK_SIZE);
1063
1064 int size = 0;
1065
1066 if (dev->isDVD()) {
1067 size = dev->readDVDStructure(sector, len, subcommand, address, layer, format, AGID, control);
1068 atapi_start_send_command(command, size, len);
1069 } else {
1070 atapi_command_error(IDE_ATAPI_SENSE_NOT_READY, IDE_ATAPI_ASC_CANNOT_READ_MEDIUM);
1071 }
1072 raiseInterrupt(0);
1073 break;
1074 }
1075 case IDE_ATAPI_COMMAND_LOAD_CD:
1076 case IDE_ATAPI_COMMAND_READ12:
1077 case IDE_ATAPI_COMMAND_MECH_STATUS:
1078 case IDE_ATAPI_COMMAND_PLAY_CD:
1079 case IDE_ATAPI_COMMAND_READ_CD_MSF:
1080 case IDE_ATAPI_COMMAND_SCAN:
1081 IO_IDE_WARN("unknown ATAPI command 0x%08x\n", command);
1082 atapi_command_error(IDE_ATAPI_SENSE_ILLEGAL_REQUEST, IDE_ATAPI_ASC_INV_FIELD_IN_CMD_PACKET);
1083 raiseInterrupt(0);
1084 break;
1085 default:
1086 IO_IDE_WARN("unknown ATAPI command 0x%08x\n", command);
1087 atapi_command_error(IDE_ATAPI_SENSE_ILLEGAL_REQUEST, IDE_ATAPI_ASC_INV_FIELD_IN_CMD_PACKET);
1088 raiseInterrupt(0);
1089 break;
1090 }
1091 // sanity check:
1092 if (gIDEState.config[gIDEState.drive].cdrom.dma) {
1093 IO_IDE_WARN("can't use dma with atapi command %x\n", command);
1094 }
1095 }
1096
1097 bool bm_ide_dotransfer(bool &prd_exhausted, uint32 prd_addr, byte bmide_command, byte bmide_status, uint32 lba, uint32 count)
1098 {
1099 IO_IDE_TRACE("BM IDE transfer: prd_addr = %08x, lba = %08x, size = %08x\n", prd_addr, lba, count ? count : gIDEState.state[gIDEState.drive].sector_count);
1100
1101 struct prd_entry {
1102 uint32 addr PACKED;
1103 uint32 size PACKED;
1104 };
1105
1106 prd_entry prd;
1107 if (!ppc_dma_read(&prd, prd_addr, 8)) return false;
1108 prd.addr = ppc_word_from_LE(prd.addr);
1109 prd.size = ppc_word_from_LE(prd.size);
1110 prd_exhausted = false;
1111 int pr_left = prd.size & 0xffff;
1112 if (!pr_left) pr_left = 64*1024;
1113
1114 bool write_to_mem = bmide_command & BM_IDE_CR_WRITE;
1115 bool write_to_device = !write_to_mem;
1116 while (true) {
1117 int to_transfer = gIDEState.state[gIDEState.drive].current_sector_size;
1118 int transfer_at_once = to_transfer;
1119 if (transfer_at_once > pr_left) transfer_at_once = pr_left;
1120 do {
1121 uint8 buffer[transfer_at_once];
1122 if (write_to_device) {
1123 ppc_dma_read(buffer, prd.addr, transfer_at_once);
1124 if (gIDEState.config[gIDEState.drive].device->write(buffer, transfer_at_once) != transfer_at_once) {
1125 gIDEState.config[gIDEState.drive].device->release();
1126 IO_IDE_WARN("write failed!\n");
1127 return false;
1128 }
1129 } else {
1130 if (gIDEState.config[gIDEState.drive].device->read(buffer, transfer_at_once) != transfer_at_once) {
1131 gIDEState.config[gIDEState.drive].device->release();
1132 IO_IDE_WARN("read failed!\n");
1133 return false;
1134 }
1135 ppc_dma_write(prd.addr, buffer, transfer_at_once);
1136 }
1137 pr_left -= transfer_at_once;
1138 prd.addr += transfer_at_once;
1139 to_transfer -= transfer_at_once;
1140 if (pr_left < 0) {
1141 gIDEState.config[gIDEState.drive].device->release();
1142 IO_IDE_WARN("pr_left became negative!\n");
1143 return false;
1144 }
1145 if (!pr_left) {
1146 if (prd.size & 0x80000000) {
1147 // no more prd's, but still something to transfer -> error
1148 bool ready;
1149 if (count) {
1150 ready = false;
1151 } else {
1152 ready = gIDEState.state[gIDEState.drive].sector_count > 1;
1153 }
1154 if (to_transfer || ready) {
1155 gIDEState.config[gIDEState.drive].device->release();
1156 IO_IDE_WARN("no more prd's, but still something to transfer\n");
1157 return false;
1158 }
1159 prd_exhausted = true;
1160 } else {
1161 // get next prd
1162 prd_addr += 8;
1163 if (!ppc_dma_read(&prd, prd_addr, 8)) {
1164 gIDEState.config[gIDEState.drive].device->release();
1165 return false;
1166 }
1167 prd.addr = ppc_word_from_LE(prd.addr);
1168 prd.size = ppc_word_from_LE(prd.size);
1169 pr_left = prd.size & 0xffff;
1170 if (!pr_left) pr_left = 64*1024;
1171 transfer_at_once = to_transfer;
1172 if (transfer_at_once > pr_left) transfer_at_once = pr_left;
1173 }
1174 }
1175 } while (to_transfer);
1176 if (count) {
1177 count--;
1178 if (!count) break;
1179 } else {
1180 incAddress();
1181 if (!gIDEState.state[gIDEState.drive].sector_count) break;
1182 }
1183 }
1184 gIDEState.config[gIDEState.drive].device->release();
1185 return true;
1186 }
1187
1188 bool read_bmdma_reg(uint32 port, uint32 &data, uint size)
1189 {
1190 IO_IDE_TRACE("bm-dma: read port: %08x, size: %d from (%08x, lr: %08x)\n", port, size, ppc_cpu_get_pc(0), ppc_cpu_get_lr(0));
1191 switch (port) {
1192 case 0:
1193 if (size==1) {
1194 IO_IDE_TRACE("bmide command = %02x\n", mConfig[BMIDECR0]);
1195 data = mConfig[BMIDECR0] & BM_IDE_CR_MASK;
1196 return true;
1197 }
1198 break;
1199 case 1:
1200 if (size==1) {
1201 IO_IDE_TRACE("bmide MRDMODE = %02x\n", mConfig[MRDMODE]);
1202 data = mConfig[MRDMODE];
1203 return true;
1204 }
1205 break;
1206 case 2:
1207 if (size==1) {
1208 IO_IDE_TRACE("bmide status = %02x\n", mConfig[BMIDESR0]);
1209 data = mConfig[BMIDESR0] & BM_IDE_SR_MASK;
1210 return true;
1211 }
1212 break;
1213 case 3:
1214 if (size == 1) {
1215 data = mConfig[UDIDETCR0];
1216 return true;
1217 }
1218 break;
1219 case 4:
1220 if (size==4) {
1221 memcpy(&data, &mConfig[DTPR0], 4);
1222 data = ppc_word_from_LE(data);
1223 IO_IDE_TRACE("bmide prd address: %08x\n", data);
1224 return true;
1225 }
1226 break;
1227 }
1228 return false;
1229 }
1230
1231 bool bmide_start_dma(bool startbit)
1232 {
1233 IO_IDE_TRACE("start dma %d\n", gIDEState.state[gIDEState.drive].mode);
1234 switch (gIDEState.state[gIDEState.drive].mode) {
1235 case IDE_TRANSFER_MODE_NONE:
1236 /*
1237 * wait for both:
1238 * bmide start and appropriate device command
1239 */
1240 gIDEState.state[gIDEState.drive].mode = IDE_TRANSFER_MODE_DMA;
1241 if (startbit) mConfig[BMIDESR0] |= BM_IDE_SR_ACTIVE;
1242 mConfig[BMIDESR0] &= ~BM_IDE_SR_ERROR;
1243 return true;
1244 case IDE_TRANSFER_MODE_DMA:
1245 break;
1246 default:
1247 IO_IDE_ERR("invalid gIDEState.mode in write_bmdma_reg\n");
1248 }
1249 gIDEState.state[gIDEState.drive].mode = IDE_TRANSFER_MODE_NONE;
1250 bool prd_exhausted;
1251 uint32 bmide_prd_addr;
1252 memcpy(&bmide_prd_addr, &mConfig[DTPR0], 4);
1253 bmide_prd_addr = ppc_word_from_LE(bmide_prd_addr);
1254 if (bm_ide_dotransfer(prd_exhausted, bmide_prd_addr,
1255 mConfig[BMIDECR0], mConfig[BMIDESR0],
1256 gIDEState.state[gIDEState.drive].dma_lba_start,
1257 gIDEState.state[gIDEState.drive].dma_lba_count)) {
1258 if (prd_exhausted) {
1259 mConfig[BMIDESR0] &= ~BM_IDE_SR_ACTIVE;
1260 } else {
1261 mConfig[BMIDESR0] |= BM_IDE_SR_ACTIVE;
1262 }
1263 mConfig[BMIDESR0] &= ~BM_IDE_SR_ERROR;
1264 mConfig[BMIDESR0] |= BM_IDE_SR_INTERRUPT;
1265 raiseInterrupt(0);
1266 return true;
1267 }
1268 return false;
1269 }
1270
1271 bool write_bmdma_reg(uint32 port, uint32 data, uint size)
1272 {
1273 IO_IDE_TRACE("bm-dma: write port: %08x, data: %08x, size: %d from (%08x, lr: %08x)\n", port, data, size, ppc_cpu_get_pc(0), ppc_cpu_get_lr(0));
1274 switch (port) {
1275 case 0:
1276 if (size==1) {
1277 byte prev_command = mConfig[BMIDECR0];
1278 mConfig[BMIDECR0] = data & BM_IDE_CR_MASK;
1279
1280 byte set_command = mConfig[BMIDECR0] & (prev_command ^ mConfig[BMIDECR0]);
1281 byte reset_command = (~mConfig[BMIDECR0]) & (prev_command ^ mConfig[BMIDECR0]);
1282
1283 if (set_command & BM_IDE_CR_START) {
1284 bmide_start_dma(true);
1285 }
1286 if (reset_command & BM_IDE_CR_START) {
1287 cancelInterrupt(0);
1288 }
1289 IO_IDE_TRACE("bmide command: want set %02x, now %02x\n", data, mConfig[BMIDECR0]);
1290 return true;
1291 }
1292 break;
1293 case 1: {
1294 IO_IDE_TRACE("bmide MRDMODE <- %02x\n", data);
1295 mConfig[MRDMODE] &= ~(MRDMODE_BLK_CH0 | MRDMODE_BLK_CH1);
1296 mConfig[MRDMODE] |= data & (MRDMODE_BLK_CH0 | MRDMODE_BLK_CH1);
1297 if (data & MRDMODE_INTR_CH0) {
1298 // mConfig[MRDMODE] &= ~MRDMODE_INTR_CH0;
1299 // cancelInterrupt(0);
1300 }
1301 if (data & MRDMODE_INTR_CH1) {
1302 // mConfig[MRDMODE] &= ~MRDMODE_INTR_CH1;
1303 // cancelInterrupt(1);
1304 }
1305 /*
1306 * if interrupts become unblocked and are pending -> signal them
1307 */
1308 if (!(mConfig[MRDMODE] & MRDMODE_BLK_CH0) && (mConfig[MRDMODE] & MRDMODE_INTR_CH0)) {
1309 raiseInterrupt(0);
1310 }
1311 if (!(mConfig[MRDMODE] & MRDMODE_BLK_CH1) && (mConfig[MRDMODE] & MRDMODE_INTR_CH1)) {
1312 raiseInterrupt(1);
1313 }
1314 return true;
1315 }
1316 case 2:
1317 if (size==1) {
1318 /* byte set_status = data & ((data & BM_IDE_SR_MASK) ^ mConfig[BMIDESR0]);
1319 byte reset_status = (~data) & ((data & BM_IDE_SR_MASK) ^ mConfig[BMIDESR0]);*/
1320 if (data & BM_IDE_SR_ERROR) mConfig[BMIDESR0] &= ~BM_IDE_SR_ERROR;
1321 if (data & BM_IDE_SR_INTERRUPT) {
1322 mConfig[BMIDESR0] &= ~BM_IDE_SR_INTERRUPT;
1323 cancelInterrupt(0);
1324 }
1325 if (data & BM_IDE_SR_DMA0_CAPABLE) mConfig[BMIDESR0] |= BM_IDE_SR_DMA0_CAPABLE;
1326 if (data & BM_IDE_SR_DMA1_CAPABLE) mConfig[BMIDESR0] |= BM_IDE_SR_DMA1_CAPABLE;
1327 if ((~data) & BM_IDE_SR_DMA0_CAPABLE) mConfig[BMIDESR0] &= ~BM_IDE_SR_DMA0_CAPABLE;
1328 if ((~data) & BM_IDE_SR_DMA1_CAPABLE) mConfig[BMIDESR0] &= ~BM_IDE_SR_DMA1_CAPABLE;
1329 IO_IDE_TRACE("bmide status: want set %02x, now %02x\n", data, mConfig[BMIDESR0]);
1330 return true;
1331 }
1332 break;
1333 case 3:
1334 if (size == 1) {
1335 mConfig[UDIDETCR0] = data;
1336 return true;
1337 }
1338 break;
1339 case 4:
1340 if (size==4) {
1341 IO_IDE_TRACE("bmide prd address: %08x\n", data);
1342 data = ppc_word_to_LE(data);
1343 memcpy(&mConfig[DTPR0], &data, 4);
1344 return true;
1345 }
1346 }
1347 return false;
1348 }
1349
1350 void ide_write_reg(uint32 addr, uint32 data, int size)
1351 {
1352 if (size != 1) {
1353 if (size != 2) {
1354 IO_IDE_ERR("ide size bla\n");
1355 }
1356 if (addr != IDE_ADDRESS_DATA) {
1357 IO_IDE_ERR("ide size bla\n");
1358 }
1359 // IO_IDE_TRACE("data <- %04x\n", data);
1360 switch (gIDEState.state[gIDEState.drive].current_command) {
1361 case IDE_COMMAND_WRITE_SECTOR:
1362 *((uint16 *)&gIDEState.state[gIDEState.drive].sector[gIDEState.state[gIDEState.drive].sectorpos]) = ppc_half_to_LE(data);
1363 gIDEState.state[gIDEState.drive].sectorpos += 2;
1364 if (gIDEState.state[gIDEState.drive].sectorpos == 512) {
1365 if (gIDEState.state[gIDEState.drive].mode == IDE_TRANSFER_MODE_WRITE) {
1366 uint32 pos = makeLogical(gIDEState.state[gIDEState.drive].head,
1367 gIDEState.state[gIDEState.drive].cyl,
1368 gIDEState.state[gIDEState.drive].sector_no);
1369 incAddress();
1370 IO_IDE_TRACE(" write sector cont. (%08x, %d)\n", pos, gIDEState.state[gIDEState.drive].sector_count);
1371 IDEDevice *dev = gIDEState.config[gIDEState.drive].device;
1372 dev->acquire();
1373 dev->setMode(ATA_DEVICE_MODE_PLAIN, 512);
1374 dev->seek(pos);
1375 dev->writeBlock(gIDEState.state[gIDEState.drive].sector);
1376 dev->release();
1377 if (gIDEState.state[gIDEState.drive].sector_count) {
1378 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY | IDE_STATUS_DRQ | IDE_STATUS_SKC;
1379 } else {
1380 gIDEState.state[gIDEState.drive].mode = IDE_TRANSFER_MODE_NONE;
1381 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY | IDE_STATUS_SKC;
1382 }
1383 raiseInterrupt(0);
1384 } else {
1385 IO_IDE_ERR("invalid state in %s:%d\n", __FILE__, __LINE__);
1386 gIDEState.state[gIDEState.drive].mode = IDE_TRANSFER_MODE_NONE;
1387 }
1388 gIDEState.state[gIDEState.drive].sectorpos = 0;
1389 }
1390 break;
1391 case IDE_COMMAND_PACKET:
1392 if (gIDEState.state[gIDEState.drive].sectorpos >= IDE_ATAPI_PACKET_SIZE) {
1393 IO_IDE_ERR("sectorpos >= PACKET_SIZE\n");
1394 }
1395 *((uint16 *)&gIDEState.state[gIDEState.drive].sector[gIDEState.state[gIDEState.drive].sectorpos]) = ppc_half_to_LE(data);
1396 gIDEState.state[gIDEState.drive].sectorpos += 2;
1397 if (gIDEState.state[gIDEState.drive].sectorpos >= IDE_ATAPI_PACKET_SIZE) {
1398 // ATAPI packet received
1399 IDEDevice *dev = gIDEState.config[gIDEState.drive].device;
1400 dev->acquire();
1401 receive_atapi_packet();
1402 dev->release();
1403 }
1404 break;
1405 }
1406 return;
1407 }
1408 switch (addr) {
1409 case IDE_ADDRESS_FEATURE: {
1410 IO_IDE_TRACE("feature <- %x\n", data);
1411 gIDEState.state[gIDEState.drive].feature = data;
1412 return;
1413 }
1414 case IDE_ADDRESS_COMMAND: {
1415 IO_IDE_TRACE("command register (%02x)\n", data);
1416 gIDEState.state[gIDEState.drive].current_command = data;
1417 gIDEState.one_time_shit = true;
1418 switch (data) {
1419 case IDE_COMMAND_RESET_ATAPI: {
1420 if (gIDEState.config[gIDEState.drive].protocol != IDE_ATAPI) {
1421 IO_IDE_WARN("reset non ATAPI-Drive\n");
1422 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY | IDE_STATUS_ERR;
1423 gIDEState.state[gIDEState.drive].error = 0x4;
1424 break;
1425 }
1426 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY | IDE_STATUS_SKC;
1427 gIDEState.state[gIDEState.drive].error = 0;
1428 gIDEState.state[gIDEState.drive].sector_count = 1;
1429 gIDEState.state[gIDEState.drive].sector_no = 1;
1430 gIDEState.state[gIDEState.drive].cyl = 0xeb14;
1431 gIDEState.state[gIDEState.drive].head = 0;
1432 // no interrupt:
1433 return;
1434 }
1435 case IDE_COMMAND_RECALIBRATE: {
1436 if (gIDEState.config[gIDEState.drive].protocol != IDE_ATA) {
1437 IO_IDE_WARN("recalibrate non ATA-Drive\n");
1438 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY | IDE_STATUS_ERR;
1439 gIDEState.state[gIDEState.drive].error = 0x4;
1440 break;
1441 }
1442 if (gIDEState.config[gIDEState.drive].installed) {
1443 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY | IDE_STATUS_SKC;
1444 gIDEState.state[gIDEState.drive].error = 0;
1445 } else {
1446 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY | IDE_STATUS_ERR;
1447 gIDEState.state[gIDEState.drive].error = 0x2; // Track 0 not found
1448 }
1449 break;
1450 }
1451 case IDE_COMMAND_READ_SECTOR: {
1452 if (gIDEState.config[gIDEState.drive].protocol != IDE_ATA) {
1453 IO_IDE_WARN("read sector from non ATA-Disk\n");
1454 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY | IDE_STATUS_ERR;
1455 gIDEState.state[gIDEState.drive].error = 0x4;
1456 break;
1457 }
1458 uint32 pos = makeLogical(gIDEState.state[gIDEState.drive].head,
1459 gIDEState.state[gIDEState.drive].cyl,
1460 gIDEState.state[gIDEState.drive].sector_no);
1461 IO_IDE_TRACE("read sector(%08x, %d)\n", pos, gIDEState.state[gIDEState.drive].sector_count);
1462 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY | IDE_STATUS_DRQ | IDE_STATUS_SKC;
1463
1464 gIDEState.state[gIDEState.drive].mode = IDE_TRANSFER_MODE_READ;
1465 IDEDevice *dev = gIDEState.config[gIDEState.drive].device;
1466 dev->acquire();
1467 dev->setMode(ATA_DEVICE_MODE_PLAIN, 512);
1468 dev->seek(pos);
1469 dev->readBlock(gIDEState.state[gIDEState.drive].sector);
1470 dev->release();
1471 gIDEState.state[gIDEState.drive].sectorpos = 0;
1472 gIDEState.state[gIDEState.drive].error = 0;
1473 break;
1474 }
1475 case IDE_COMMAND_WRITE_SECTOR: {
1476 if (gIDEState.config[gIDEState.drive].protocol != IDE_ATA) {
1477 IO_IDE_WARN("write sector to non ATA-Disk\n");
1478 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY | IDE_STATUS_ERR;
1479 gIDEState.state[gIDEState.drive].error = 0x4;
1480 break;
1481 }
1482 IO_IDE_TRACE("write sector(%08x, %d)\n",
1483 makeLogical(gIDEState.state[gIDEState.drive].head,
1484 gIDEState.state[gIDEState.drive].cyl,
1485 gIDEState.state[gIDEState.drive].sector_no),
1486 gIDEState.state[gIDEState.drive].sector_count);
1487 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY | IDE_STATUS_DRQ | IDE_STATUS_SKC;
1488 gIDEState.state[gIDEState.drive].mode = IDE_TRANSFER_MODE_WRITE;
1489 gIDEState.state[gIDEState.drive].sectorpos = 0;
1490 gIDEState.state[gIDEState.drive].error = 0;
1491 return;
1492 }
1493 case IDE_COMMAND_FIX_PARAM: {
1494 if (gIDEState.config[gIDEState.drive].protocol != IDE_ATA) {
1495 IO_IDE_WARN("recalibrate non ATA-Drive\n");
1496 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY | IDE_STATUS_ERR;
1497 gIDEState.state[gIDEState.drive].error = 0x4;
1498 break;
1499 }
1500 if (gIDEState.config[gIDEState.drive].installed) {
1501 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY | IDE_STATUS_SKC;
1502 gIDEState.state[gIDEState.drive].error = 0;
1503 } else {
1504 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY | IDE_STATUS_ERR;
1505 gIDEState.state[gIDEState.drive].error = 0x2; // Track 0 not found
1506 }
1507 break;
1508 }
1509 case IDE_COMMAND_READ_SECTOR_DMA: {
1510 if (gIDEState.config[gIDEState.drive].protocol != IDE_ATA) {
1511 IO_IDE_WARN("read sector from non ATA-Disk\n");
1512 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY | IDE_STATUS_ERR;
1513 gIDEState.state[gIDEState.drive].error = 0x4;
1514 break;
1515 }
1516 gIDEState.state[gIDEState.drive].dma_lba_start = makeLogical(
1517 gIDEState.state[gIDEState.drive].head,
1518 gIDEState.state[gIDEState.drive].cyl,
1519 gIDEState.state[gIDEState.drive].sector_no);
1520 gIDEState.state[gIDEState.drive].dma_lba_count = 0;
1521 gIDEState.state[gIDEState.drive].current_sector_size = 512;
1522 IO_IDE_TRACE("read sector dma(%08x, %d)\n",
1523 gIDEState.state[gIDEState.drive].dma_lba_start,
1524 gIDEState.state[gIDEState.drive].sector_count);
1525 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY | IDE_STATUS_SKC;
1526 gIDEState.config[gIDEState.drive].device->acquire();
1527 gIDEState.config[gIDEState.drive].device->setMode(ATA_DEVICE_MODE_PLAIN, 512);
1528 gIDEState.config[gIDEState.drive].device->seek(gIDEState.state[gIDEState.drive].dma_lba_start);
1529 bmide_start_dma(false);
1530 // no interrupt here:
1531 return;
1532 }
1533 case IDE_COMMAND_WRITE_SECTOR_DMA: {
1534 if (gIDEState.config[gIDEState.drive].protocol != IDE_ATA) {
1535 IO_IDE_WARN("write sector to non ATA-Disk\n");
1536 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY | IDE_STATUS_ERR;
1537 gIDEState.state[gIDEState.drive].error = 0x4;
1538 break;
1539 }
1540 gIDEState.state[gIDEState.drive].dma_lba_start = makeLogical(
1541 gIDEState.state[gIDEState.drive].head,
1542 gIDEState.state[gIDEState.drive].cyl,
1543 gIDEState.state[gIDEState.drive].sector_no);
1544 gIDEState.state[gIDEState.drive].dma_lba_count = 0;
1545 gIDEState.state[gIDEState.drive].current_sector_size = 512;
1546 IO_IDE_TRACE("write sector dma(%08x, %d)\n",
1547 gIDEState.state[gIDEState.drive].dma_lba_start,
1548 gIDEState.state[gIDEState.drive].sector_count);
1549 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY | IDE_STATUS_SKC;
1550 gIDEState.config[gIDEState.drive].device->acquire();
1551 gIDEState.config[gIDEState.drive].device->setMode(ATA_DEVICE_MODE_PLAIN, 512);
1552 gIDEState.config[gIDEState.drive].device->seek(gIDEState.state[gIDEState.drive].dma_lba_start);
1553 bmide_start_dma(false);
1554 // no interrupt here:
1555 return;
1556 }
1557 case IDE_COMMAND_IDENT: {
1558 if (gIDEState.config[gIDEState.drive].protocol == IDE_ATAPI) {
1559 gIDEState.drive_head &= ~0xf;
1560 gIDEState.state[gIDEState.drive].sector_no = 1;
1561 gIDEState.state[gIDEState.drive].sector_count = 1;
1562 gIDEState.state[gIDEState.drive].cyl = 0xeb14;
1563 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY | IDE_STATUS_ERR;
1564 gIDEState.state[gIDEState.drive].error = 0x4;
1565 break;
1566 }
1567 drive_ident();
1568 break;
1569 }
1570 case IDE_COMMAND_IDENT_ATAPI: {
1571 if (gIDEState.config[gIDEState.drive].protocol == IDE_ATA) {
1572 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY | IDE_STATUS_ERR;
1573 gIDEState.state[gIDEState.drive].error = 0x4;
1574 break;
1575 }
1576 drive_ident();
1577 break;
1578 }
1579 case IDE_COMMAND_PACKET: {
1580 if (gIDEState.config[gIDEState.drive].protocol != IDE_ATAPI) {
1581 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY | IDE_STATUS_ERR;
1582 gIDEState.state[gIDEState.drive].error = 0x4;
1583 break;
1584 }
1585 if (gIDEState.state[gIDEState.drive].feature & 1) {
1586 // IO_IDE_WARN("ATAPI feature dma\n");
1587 gIDEState.config[gIDEState.drive].cdrom.dma = true;
1588 } else {
1589 gIDEState.config[gIDEState.drive].cdrom.dma = false;
1590 }
1591 if (gIDEState.state[gIDEState.drive].feature & 2) {
1592 IO_IDE_ERR("ATAPI feature overlapped not supported\n");
1593 }
1594 gIDEState.state[gIDEState.drive].sector_count = 1;
1595 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY | IDE_STATUS_SKC | IDE_STATUS_DRQ;
1596 gIDEState.state[gIDEState.drive].sectorpos = 0;
1597 // don't raise interrupt:
1598 return;
1599 }
1600 case IDE_COMMAND_SET_FEATURE: {
1601 switch (gIDEState.state[gIDEState.drive].feature) {
1602 case IDE_COMMAND_FEATURE_ENABLE_WRITE_CACHE:
1603 case IDE_COMMAND_FEATURE_SET_TRANSFER_MODE:
1604 case IDE_COMMAND_FEATURE_ENABLE_APM:
1605 case IDE_COMMAND_FEATURE_SET_PIO_MODE:
1606 case IDE_COMMAND_FEATURE_DISABLE_WRITE_CACHE:
1607 case IDE_COMMAND_FEATURE_ENABLE_LOOKAHEAD:
1608 case IDE_COMMAND_FEATURE_DISABLE_LOOKAHEAD:
1609 case IDE_COMMAND_FEATURE_ENABLE_PW_DEFAULT:
1610 case IDE_COMMAND_FEATURE_DISABLE_PW_DEFAULT:
1611 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY;
1612 gIDEState.state[gIDEState.drive].error = 0;
1613 break;
1614 default:
1615 IO_IDE_WARN("set feature: unkown sub-command (0x%02x)\n", gIDEState.state[gIDEState.drive].feature);
1616 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY | IDE_STATUS_ERR;
1617 gIDEState.state[gIDEState.drive].error = 0x4;
1618 break;
1619 }
1620 // FIXME: dont raise interrupt?
1621 break;
1622 }
1623 case IDE_COMMAND_STANDBY_IMMEDIATE:
1624 IO_IDE_WARN("command STANDBY_IMMEDIATE stub\n");
1625 // FIXME: dont raise interrupt?
1626 break;
1627 case IDE_COMMAND_FLUSH_CACHE:
1628 gIDEState.config[gIDEState.drive].device->acquire();
1629 gIDEState.config[gIDEState.drive].device->flush();
1630 gIDEState.config[gIDEState.drive].device->release();
1631 break;
1632 case IDE_COMMAND_SLEEP:
1633 IO_IDE_WARN("command SLEEP stub\n");
1634 // FIXME: dont raise interrupt?
1635 break;
1636 case IDE_COMMAND_SET_MULTIPLE:
1637 IO_IDE_WARN("command SET MULTIPLE not implemented\n");
1638 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY | IDE_STATUS_ERR;
1639 gIDEState.state[gIDEState.drive].error = 0x4;
1640 break;
1641 case IDE_COMMAND_READ_NATIVE_MAX:
1642 IO_IDE_WARN("command READ NATIVE MAX ADDRESS not implemented\n");
1643 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY | IDE_STATUS_ERR;
1644 gIDEState.state[gIDEState.drive].error = 0x4;
1645 break;
1646 default:
1647 IO_IDE_ERR("command '%x' not impl\n", data);
1648 }
1649 raiseInterrupt(0);
1650 return;
1651 }
1652 case IDE_ADDRESS_DRV_HEAD: {
1653 IO_IDE_TRACE("drive head <- %x\n", data);
1654 gIDEState.drive_head = data | 0xa0;
1655 if (!(gIDEState.drive_head & IDE_DRIVE_HEAD_SLAVE)) {
1656 if (gIDEState.config[0].installed) {
1657 gIDEState.state[0].status &= ~IDE_STATUS_ERR;
1658 gIDEState.state[0].status |= IDE_STATUS_RDY;
1659 if (!gIDEState.one_time_shit) {
1660 gIDEState.state[0].status |= IDE_STATUS_SKC;
1661 if (gIDEState.config[0].protocol == IDE_ATA) {
1662 gIDEState.state[0].cyl = 0;
1663 gIDEState.state[0].sector_count = 1;
1664 gIDEState.state[0].sector_no = 1;
1665 } else {
1666 gIDEState.state[0].cyl = 0xeb14;
1667 }
1668 }
1669 gIDEState.state[0].error = 1;
1670 } else {
1671 gIDEState.state[0].status |= IDE_STATUS_ERR;
1672 gIDEState.state[0].error = 4; // abort
1673 // FIXME: is this correct?
1674 // should we allow setting gIDEState.drive
1675 // to drives not present or return here?
1676 }
1677 gIDEState.drive = 0;
1678 } else {
1679 if (gIDEState.config[1].installed) {
1680 gIDEState.state[1].status &= ~IDE_STATUS_ERR;
1681 gIDEState.state[1].status |= IDE_STATUS_RDY;
1682 if (!gIDEState.one_time_shit) {
1683 gIDEState.state[1].status |= IDE_STATUS_SKC;
1684 if (gIDEState.config[1].protocol == IDE_ATA) {
1685 gIDEState.state[1].cyl = 0;
1686 gIDEState.state[1].sector_count = 1;
1687 gIDEState.state[1].sector_no = 1;
1688 } else {
1689 gIDEState.state[1].cyl = 0xeb14;
1690 }
1691 }
1692 gIDEState.state[1].error = 1;
1693 } else {
1694 gIDEState.state[1].status |= IDE_STATUS_ERR;
1695 gIDEState.state[1].error = 4; // abort
1696 }
1697 gIDEState.drive = 1;
1698 // FIXME: see above
1699 }
1700 gIDEState.config[gIDEState.drive].lba = gIDEState.drive_head & IDE_DRIVE_HEAD_LBA;
1701 gIDEState.state[gIDEState.drive].head = gIDEState.drive_head & 0x0f;
1702 return;
1703 }
1704 case IDE_ADDRESS_OUTPUT: {
1705 if (data & 4) {
1706 // reset
1707 }
1708 IO_IDE_TRACE("output register <- %x\n", data);
1709 gIDEState.state[gIDEState.drive].outreg = data;
1710 return;
1711 }
1712 case IDE_ADDRESS_SEC_CNT: {
1713 IO_IDE_TRACE("sec_cnt <- %x\n", data);
1714 gIDEState.state[gIDEState.drive].sector_count = data;
1715 return;
1716 }
1717 case IDE_ADDRESS_SEC_NO: {
1718 IO_IDE_TRACE("sec_no <- %x\n", data);
1719 gIDEState.state[gIDEState.drive].sector_no = data;
1720 return;
1721 }
1722 case IDE_ADDRESS_CYL_LSB: {
1723 IO_IDE_TRACE("cyl_lsb <- %x\n", data);
1724 gIDEState.state[gIDEState.drive].cyl = (data&0xff) + (gIDEState.state[gIDEState.drive].cyl & 0xff00);
1725 return;
1726 }
1727 case IDE_ADDRESS_CYL_MSB:
1728 IO_IDE_TRACE("cyl_msb <- %x\n", data);
1729 gIDEState.state[gIDEState.drive].cyl = ((data<<8)&0xff00) + (gIDEState.state[gIDEState.drive].cyl & 0xff);
1730 return;
1731 }
1732 IO_IDE_ERR("write(%d) %08x to unknown IDE register %d\n", size, data, addr);
1733 }
1734
1735 void ide_read_reg(uint32 addr, uint32 &data, int size)
1736 {
1737 if (size != 1) {
1738 if (size != 2) {
1739 IO_IDE_ERR("ide size bla\n");
1740 }
1741 if (addr != IDE_ADDRESS_DATA) {
1742 IO_IDE_ERR("ide size bla\n");
1743 }
1744 if (!(gIDEState.state[gIDEState.drive].status & IDE_STATUS_DRQ)) {
1745 IO_IDE_WARN("read data w/o DRQ, last command: 0x%08x\n", gIDEState.state[gIDEState.drive].current_command);
1746 return;
1747 }
1748 switch (gIDEState.state[gIDEState.drive].current_command) {
1749 case IDE_COMMAND_READ_SECTOR:
1750 case IDE_COMMAND_IDENT:
1751 case IDE_COMMAND_IDENT_ATAPI:
1752 data = ppc_half_from_LE(*((uint16 *)&gIDEState.state[gIDEState.drive].sector[gIDEState.state[gIDEState.drive].sectorpos]));
1753 gIDEState.state[gIDEState.drive].sectorpos += 2;
1754 // IO_IDE_TRACE("data: %04x\n", data);
1755 if (gIDEState.state[gIDEState.drive].sectorpos == 512) {
1756 if (gIDEState.state[gIDEState.drive].mode == IDE_TRANSFER_MODE_READ) {
1757 incAddress();
1758 if (gIDEState.state[gIDEState.drive].sector_count) {
1759 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY | IDE_STATUS_SKC | IDE_STATUS_DRQ;
1760 gIDEState.state[gIDEState.drive].mode = IDE_TRANSFER_MODE_READ;
1761 uint32 pos = makeLogical(gIDEState.drive_head & 0xf, gIDEState.state[gIDEState.drive].cyl, gIDEState.state[gIDEState.drive].sector_no);
1762 IO_IDE_TRACE(" read sector cont. (%08x, %d)\n", pos, gIDEState.state[gIDEState.drive].sector_count);
1763 IDEDevice *dev = gIDEState.config[gIDEState.drive].device;
1764 dev->acquire();
1765 dev->setMode(ATA_DEVICE_MODE_PLAIN, 512);
1766 dev->seek(pos);
1767 dev->readBlock(gIDEState.state[gIDEState.drive].sector);
1768 dev->release();
1769 raiseInterrupt(0);
1770 } else {
1771 gIDEState.state[gIDEState.drive].mode = IDE_TRANSFER_MODE_NONE;
1772 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY;
1773 }
1774 } else {
1775 gIDEState.state[gIDEState.drive].mode = IDE_TRANSFER_MODE_NONE;
1776 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY;
1777 }
1778 gIDEState.state[gIDEState.drive].sectorpos = 0;
1779 }
1780 break;
1781 case IDE_COMMAND_PACKET:
1782 if (gIDEState.state[gIDEState.drive].sectorpos == gIDEState.state[gIDEState.drive].current_sector_size) {
1783 switch (gIDEState.config[gIDEState.drive].cdrom.atapi.command) {
1784 case IDE_ATAPI_COMMAND_READ10:
1785 case IDE_ATAPI_COMMAND_READ12: {
1786 CDROMDevice *dev = (CDROMDevice *)gIDEState.config[gIDEState.drive].device;
1787 if (!dev->isReady()) {
1788 IO_IDE_ERR("read with cdrom not ready\n");
1789 }
1790 dev->acquire();
1791 dev->setMode(IDE_ATAPI_TRANSFER_DATA,
1792 gIDEState.state[gIDEState.drive].current_sector_size);
1793 dev->seek(gIDEState.config[gIDEState.drive].cdrom.next_lba);
1794 dev->readBlock(gIDEState.state[gIDEState.drive].sector);
1795 dev->release();
1796 gIDEState.config[gIDEState.drive].cdrom.next_lba++;
1797 gIDEState.config[gIDEState.drive].cdrom.remain--;
1798 gIDEState.state[gIDEState.drive].sectorpos = 0;
1799 break;
1800 }
1801 case IDE_ATAPI_COMMAND_READ_CD: {
1802 CDROMDevice *dev = (CDROMDevice *)gIDEState.config[gIDEState.drive].device;
1803 if (!dev->isReady()) {
1804 IO_IDE_ERR("read with cdrom not ready\n");
1805 }
1806 dev->acquire();
1807 dev->setMode(gIDEState.state[gIDEState.drive].atapi_transfer_request,
1808 gIDEState.state[gIDEState.drive].current_sector_size);
1809 dev->seek(gIDEState.config[gIDEState.drive].cdrom.next_lba);
1810 dev->readBlock(gIDEState.state[gIDEState.drive].sector);
1811 dev->release();
1812 gIDEState.config[gIDEState.drive].cdrom.next_lba++;
1813 gIDEState.config[gIDEState.drive].cdrom.remain--;
1814 gIDEState.state[gIDEState.drive].sectorpos = 0;
1815 break;
1816 }
1817 default:
1818 IO_IDE_ERR("unknown atapi state\n");
1819 }
1820 }
1821 data = ppc_half_from_LE(*((uint16 *)&gIDEState.state[gIDEState.drive].sector[gIDEState.state[gIDEState.drive].sectorpos]));
1822 gIDEState.state[gIDEState.drive].sectorpos += 2;
1823 // IO_IDE_TRACE("data: %04x\n", data);
1824 gIDEState.state[gIDEState.drive].drqpos += 2;
1825 if (gIDEState.state[gIDEState.drive].drqpos >= gIDEState.config[gIDEState.drive].cdrom.atapi.drq_bytes) {
1826 gIDEState.state[gIDEState.drive].drqpos = 0;
1827 gIDEState.config[gIDEState.drive].cdrom.atapi.total_remain -= gIDEState.config[gIDEState.drive].cdrom.atapi.drq_bytes;
1828 if (gIDEState.config[gIDEState.drive].cdrom.atapi.total_remain > 0) {
1829 gIDEState.state[gIDEState.drive].status &= ~IDE_STATUS_BSY;
1830 gIDEState.state[gIDEState.drive].status |= IDE_STATUS_DRQ;
1831 gIDEState.state[gIDEState.drive].intr_reason |= IDE_ATAPI_INTR_REASON_I_O;
1832 gIDEState.state[gIDEState.drive].intr_reason &= ~IDE_ATAPI_INTR_REASON_C_D;
1833 if (gIDEState.state[gIDEState.drive].byte_count > gIDEState.config[gIDEState.drive].cdrom.atapi.total_remain) {
1834 gIDEState.state[gIDEState.drive].byte_count = gIDEState.config[gIDEState.drive].cdrom.atapi.total_remain;
1835 }
1836 gIDEState.config[gIDEState.drive].cdrom.atapi.drq_bytes = gIDEState.state[gIDEState.drive].byte_count;
1837 } else {
1838 gIDEState.state[gIDEState.drive].status = IDE_STATUS_RDY | IDE_STATUS_SKC;
1839 gIDEState.state[gIDEState.drive].intr_reason |= IDE_ATAPI_INTR_REASON_I_O | IDE_ATAPI_INTR_REASON_C_D;
1840 gIDEState.state[gIDEState.drive].intr_reason &= ~IDE_ATAPI_INTR_REASON_REL;
1841 }
1842 raiseInterrupt(0);
1843 }
1844 break;
1845 default:
1846 IO_IDE_ERR("data read + DRQ after 0x08%x\n", gIDEState.state[gIDEState.drive].current_command);
1847 }
1848 return;
1849 }
1850 switch (addr) {
1851 case IDE_ADDRESS_ERROR: {
1852 IO_IDE_TRACE("error: %02x\n", gIDEState.state[gIDEState.drive].error);
1853 data = gIDEState.state[gIDEState.drive].error;
1854 gIDEState.state[gIDEState.drive].status &= ~IDE_STATUS_ERR;
1855 return ;
1856 }
1857 case IDE_ADDRESS_DRV_HEAD: {
1858 IO_IDE_TRACE("drive_head: %02x\n", gIDEState.drive_head);
1859 data = (gIDEState.state[gIDEState.drive].head & 0x0f)
1860 | (gIDEState.drive_head & 0x10)
1861 | 0xa0
1862 | (gIDEState.config[gIDEState.drive].lba ? (1<<6): 0);
1863 return ;
1864 }
1865 case IDE_ADDRESS_STATUS: {
1866 IO_IDE_TRACE("status: %02x\n", gIDEState.state[gIDEState.drive].status);
1867 data = gIDEState.state[gIDEState.drive].status;
1868 cancelInterrupt(0);
1869 return ;
1870 }
1871 case IDE_ADDRESS_STATUS2: {
1872 IO_IDE_TRACE("alt-status register: %02x\n", gIDEState.state[gIDEState.drive].status);
1873 data = gIDEState.state[gIDEState.drive].status;
1874 return;
1875 }
1876 case IDE_ADDRESS_SEC_CNT: {
1877 data = gIDEState.state[gIDEState.drive].sector_count;
1878 IO_IDE_TRACE("sec_cnt: %x (from: @%08x)\n", data, ppc_cpu_get_pc(0));
1879 return;
1880 }
1881 case IDE_ADDRESS_SEC_NO: {
1882 data = gIDEState.state[gIDEState.drive].sector_no;
1883 IO_IDE_TRACE("sec_no: %x\n", data);
1884 return;
1885 }
1886 case IDE_ADDRESS_CYL_LSB: {
1887 data = gIDEState.state[gIDEState.drive].cyl & 0xff;
1888 IO_IDE_TRACE("cyl_lsb: %x\n", data);
1889 return;
1890 }
1891 case IDE_ADDRESS_CYL_MSB: {
1892 data = (gIDEState.state[gIDEState.drive].cyl & 0xff00) >> 8;
1893 IO_IDE_TRACE("cyl_msb: %x\n", data);
1894 return;
1895 }
1896 }
1897 IO_IDE_ERR("write(%d) %08x to unknown IDE register %d\n", size, data, addr);
1898 }
1899
1900 /********************************************************************************
1901 * PCI Interface
1902 */
1903 virtual bool readDeviceIO(uint r, uint32 port, uint32 &data, uint size)
1904 {
1905 switch (r) {
1906 case IDE_PCI_REG_0_CMD:
1907 ide_read_reg(port, data, size);
1908 return true;
1909 case IDE_PCI_REG_0_CTRL:
1910 ide_read_reg(port+0x10, data, size);
1911 return true;
1912 case IDE_PCI_REG_BMDMA:
1913 return read_bmdma_reg(port, data, size);
1914 }
1915 return false;
1916 }
1917
1918 virtual bool writeDeviceIO(uint r, uint32 port, uint32 data, uint size)
1919 {
1920 switch (r) {
1921 case IDE_PCI_REG_0_CMD:
1922 ide_write_reg(port, data, size);
1923 return true;
1924 case IDE_PCI_REG_0_CTRL:
1925 ide_write_reg(port+0x10, data, size);
1926 return true;
1927 case IDE_PCI_REG_BMDMA:
1928 return write_bmdma_reg(port, data, size);
1929 }
1930 return false;
1931 }
1932
1933 virtual void readConfig(uint reg)
1934 {
1935 if (reg >= BMIDECR0 && reg <= DTPR0) {
1936 // they are already set...
1937 // hook here, if you need notify on read
1938 }
1939 PCI_Device::readConfig(reg);
1940 }
1941
1942 virtual void writeConfig(uint reg, int offset, int size)
1943 {
1944 if (reg == 0x30) {
1945 // ROM-Address
1946 // FIXME: Who needs this?
1947 gPCI_Data &= ~3;
1948 }
1949 if (reg >= BMIDECR0 && reg <= DTPR0) {
1950 // FIXME: please fix this. I won't.
1951 if (size != 1) IO_IDE_ERR("size != 1 bla in writeConfig()\n");
1952 uint32 data = (gPCI_Data >> (offset*8)) & 0xff;
1953 write_bmdma_reg(reg-BMIDECR0+offset, data, size);
1954 return ;
1955 }
1956 PCI_Device::writeConfig(reg, offset, size);
1957 }
1958
1959 };
1960
1961 /*
1962 *
1963 */
1964
1965 IDEConfig *ide_get_config(int disk)
1966 {
1967 switch (disk) {
1968 case 0:
1969 case 1:
1970 return &gIDEState.config[disk];
1971 break;
1972 }
1973 return NULL;
1974 }
1975
1976 #define IDE_KEY_IDE0_MASTER_INSTALLED "pci_ide0_master_installed"
1977 #define IDE_KEY_IDE0_MASTER_TYPE "pci_ide0_master_type"
1978 #define IDE_KEY_IDE0_MASTER_IMG "pci_ide0_master_image"
1979 #define IDE_KEY_IDE0_SLAVE_INSTALLED "pci_ide0_slave_installed"
1980 #define IDE_KEY_IDE0_SLAVE_TYPE "pci_ide0_slave_type"
1981 #define IDE_KEY_IDE0_SLAVE_IMG "pci_ide0_slave_image"
1982
1983 #include "configparser.h"
1984 #include "tools/except.h"
1985 void ide_init()
1986 {
1987 memset(&gIDEState, 0, sizeof gIDEState);
1988 for (int DISK=0; DISK<2; DISK++) {
1989 const char *instkeys[] = {IDE_KEY_IDE0_MASTER_INSTALLED, IDE_KEY_IDE0_SLAVE_INSTALLED};
1990 const char *instkey = instkeys[DISK];
1991 const char *typekeys[] = {IDE_KEY_IDE0_MASTER_TYPE, IDE_KEY_IDE0_SLAVE_TYPE};
1992 const char *typekey = typekeys[DISK];
1993 const char *imgkeys[] = {IDE_KEY_IDE0_MASTER_IMG, IDE_KEY_IDE0_SLAVE_IMG};
1994 const char *imgkey = imgkeys[DISK];
1995 if (gConfig->getConfigInt(instkey)) {
1996 const char *masterslave[] = {"master", "slave"};
1997 if (!gConfig->haveKey(imgkey)) throw MsgfException("no disk image specified for ide%d %s.", 0, masterslave[DISK]);
1998 String img, tmp, ext;
1999 gConfig->getConfigString(imgkey, img);
2000 if (gConfig->haveKey(typekey)) {
2001 String type;
2002 gConfig->getConfigString(typekey, type);
2003 if (type == (String)"hd") {
2004 ext = "img";
2005 } else if (type == (String)"cdrom") {
2006 ext = "iso";
2007 } else if (type == (String)"dvdrom") {
2008 ext = "dvd";
2009 } else if (type == (String)"nativecdrom") {
2010 ext = "nativecdrom";
2011 } else {
2012 IO_IDE_ERR("key '%s' must be set to 'hd', 'cdrom' or 'nativecdrom'\n", typekey);
2013 }
2014 } else {
2015 // type isn't specified, so we must rely on the file extension
2016 if (!img.rightSplit('.', tmp, ext)) {
2017 IO_IDE_ERR("unknown disk image (file extension is neither 'img' nor 'iso').\n");
2018 }
2019 }
2020 String name;
2021 name.assignFormat("ide%d", DISK);
2022 if (ext == "img") {
2023 gIDEState.config[DISK].protocol = IDE_ATA;
2024 gIDEState.config[DISK].device = new ATADeviceFile(name.contentChar(), img.contentChar());
2025 const char *error;
2026 if ((error = gIDEState.config[DISK].device->getError())) IO_IDE_ERR("%s\n", error);
2027 gIDEState.config[DISK].hd.cyl = ((ATADevice*)gIDEState.config[DISK].device)->mCyl;
2028 gIDEState.config[DISK].hd.heads = ((ATADevice*)gIDEState.config[DISK].device)->mHeads;
2029 gIDEState.config[DISK].hd.spt = ((ATADevice*)gIDEState.config[DISK].device)->mSpt;
2030 gIDEState.config[DISK].bps = 512;
2031 gIDEState.config[DISK].lba = true;
2032 } else if (ext == "iso") {
2033 gIDEState.config[DISK].protocol = IDE_ATAPI;
2034 gIDEState.config[DISK].device = new CDROMDeviceFile(name.contentChar());
2035 ((CDROMDeviceFile *)gIDEState.config[DISK].device)->activateDVD(false);
2036 ((CDROMDeviceFile *)gIDEState.config[DISK].device)->changeDataSource(img.contentChar());
2037 const char *error;
2038 if ((error = gIDEState.config[DISK].device->getError())) IO_IDE_ERR("%s\n", error);
2039 ((CDROMDeviceFile *)gIDEState.config[DISK].device)->setReady(true);
2040 gIDEState.config[DISK].bps = 2048;
2041 gIDEState.config[DISK].lba = false;
2042 } else if (ext == "dvd") {
2043 gIDEState.config[DISK].protocol = IDE_ATAPI;
2044 gIDEState.config[DISK].device = new CDROMDeviceFile(name.contentChar());
2045 ((CDROMDeviceFile *)gIDEState.config[DISK].device)->activateDVD(true);
2046
2047 ((CDROMDeviceFile *)gIDEState.config[DISK].device)->changeDataSource(img.contentChar());
2048 const char *error;
2049 if ((error = gIDEState.config[DISK].device->getError())) IO_IDE_ERR("%s\n", error);
2050 ((CDROMDeviceFile *)gIDEState.config[DISK].device)->setReady(true);
2051 gIDEState.config[DISK].bps = 2048;
2052 gIDEState.config[DISK].lba = true;
2053 } else if (ext == "nativecdrom") {
2054 gIDEState.config[DISK].protocol = IDE_ATAPI;
2055 CDROMDevice* cdrom = createNativeCDROMDevice(name.contentChar(), img.contentChar());
2056 if (!cdrom)
2057 IO_IDE_ERR("Error creating native CDROM device\n");
2058 gIDEState.config[DISK].device = cdrom;
2059 const char *error;
2060 if ((error = gIDEState.config[DISK].device->getError()))
2061 IO_IDE_ERR("%s\n", error);
2062 gIDEState.config[DISK].bps = 2048;
2063 gIDEState.config[DISK].lba = false;
2064 } else {
2065 IO_IDE_ERR("unknown disk image (file extension is neither 'img' nor 'iso' nor native CD infor).\n");
2066 }
2067 gIDEState.config[DISK].installed = true;
2068 } else {
2069 gIDEState.config[DISK].installed = false;
2070 }
2071 }
2072
2073 gIDEState.state[0].status = IDE_STATUS_RDY;
2074 gIDEState.state[1].status = IDE_STATUS_RDY;
2075 gIDEState.one_time_shit = false;
2076 if (gIDEState.config[0].installed || gIDEState.config[1].installed) {
2077 gPCI_Devices->insert(new IDE_Controller());
2078 }
2079 }
2080
2081 void ide_done()
2082 {
2083 delete gIDEState.config[0].device;
2084 delete gIDEState.config[1].device;
2085 }
2086
2087 void ide_init_config()
2088 {
2089 gConfig->acceptConfigEntryIntDef(IDE_KEY_IDE0_MASTER_INSTALLED, 0);
2090 gConfig->acceptConfigEntryString(IDE_KEY_IDE0_MASTER_TYPE, false);
2091 gConfig->acceptConfigEntryString(IDE_KEY_IDE0_MASTER_IMG, false);
2092 gConfig->acceptConfigEntryIntDef(IDE_KEY_IDE0_SLAVE_INSTALLED, 0);
2093 gConfig->acceptConfigEntryString(IDE_KEY_IDE0_SLAVE_TYPE, false);
2094 gConfig->acceptConfigEntryString(IDE_KEY_IDE0_SLAVE_IMG, false);
2095 }
2096

  ViewVC Help
Powered by ViewVC 1.1.26