/[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

Annotation of /src/io/ide/ide.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide annotations)
Wed Sep 5 17:11:21 2007 UTC (16 years, 7 months ago) by dpavlin
File size: 72670 byte(s)
import upstream CVS
1 dpavlin 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", bmide_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, gCPU.pc, gCPU.lr);
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, gCPU.pc, gCPU.lr);
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, gCPU.pc);
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