96749795df1f84d235c6fd0c7d96f8ed4cc04d61
[seabios.git] / src / ata.c
1 // Low level ATA disk access
2 //
3 // Copyright (C) 2008  Kevin O'Connor <kevin@koconnor.net>
4 // Copyright (C) 2002  MandrakeSoft S.A.
5 //
6 // This file may be distributed under the terms of the GNU GPLv3 license.
7
8 #include "ata.h" // ATA_*
9 #include "types.h" // u8
10 #include "ioport.h" // inb
11 #include "util.h" // BX_INFO
12 #include "cmos.h" // inb_cmos
13
14 #define TIMEOUT 0
15 #define BSY 1
16 #define NOT_BSY 2
17 #define NOT_BSY_DRQ 3
18 #define NOT_BSY_NOT_DRQ 4
19 #define NOT_BSY_RDY 5
20
21 #define IDE_TIMEOUT 32000u //32 seconds max for IDE ops
22
23 #define DEBUGF1(fmt, args...) bprintf(0, fmt , ##args)
24 #define DEBUGF(fmt, args...)
25
26 // XXX - lots of redundancy in this file.
27
28 static int
29 await_ide(u8 when_done, u16 base, u16 timeout)
30 {
31     u32 time=0,last=0;
32     // for the times you're supposed to throw one away
33     u16 status = inb(base + ATA_CB_STAT);
34     for (;;) {
35         status = inb(base+ATA_CB_STAT);
36         time++;
37         u8 result;
38         if (when_done == BSY)
39             result = status & ATA_CB_STAT_BSY;
40         else if (when_done == NOT_BSY)
41             result = !(status & ATA_CB_STAT_BSY);
42         else if (when_done == NOT_BSY_DRQ)
43             result = !(status & ATA_CB_STAT_BSY) && (status & ATA_CB_STAT_DRQ);
44         else if (when_done == NOT_BSY_NOT_DRQ)
45             result = !(status & ATA_CB_STAT_BSY) && !(status & ATA_CB_STAT_DRQ);
46         else if (when_done == NOT_BSY_RDY)
47             result = !(status & ATA_CB_STAT_BSY) && (status & ATA_CB_STAT_RDY);
48         else if (when_done == TIMEOUT)
49             result = 0;
50
51         if (result)
52             return 0;
53         // mod 2048 each 16 ms
54         if (time>>16 != last) {
55             last = time >>16;
56             DEBUGF("await_ide: (TIMEOUT,BSY,!BSY,!BSY_DRQ,!BSY_!DRQ,!BSY_RDY)"
57                    " %d time= %d timeout= %d\n"
58                    , when_done, time>>11, timeout);
59         }
60         if (status & ATA_CB_STAT_ERR) {
61             DEBUGF("await_ide: ERROR (TIMEOUT,BSY,!BSY,!BSY_DRQ"
62                    ",!BSY_!DRQ,!BSY_RDY) %d time= %d timeout= %d\n"
63                    , when_done, time>>11, timeout);
64             return -1;
65         }
66         if ((timeout == 0) || ((time>>11) > timeout))
67             break;
68     }
69     BX_INFO("IDE time out\n");
70     return -1;
71 }
72
73
74 // ---------------------------------------------------------------------------
75 // ATA/ATAPI driver : software reset
76 // ---------------------------------------------------------------------------
77 // ATA-3
78 // 8.2.1 Software reset - Device 0
79
80 void
81 ata_reset(u16 device)
82 {
83     u16 iobase1, iobase2;
84     u8  channel, slave, sn, sc;
85     u8  type;
86
87     channel = device / 2;
88     slave = device % 2;
89
90     iobase1 = GET_EBDA(ata.channels[channel].iobase1);
91     iobase2 = GET_EBDA(ata.channels[channel].iobase2);
92
93     // Reset
94
95     // 8.2.1 (a) -- set SRST in DC
96     outb(ATA_CB_DC_HD15 | ATA_CB_DC_NIEN | ATA_CB_DC_SRST, iobase2+ATA_CB_DC);
97
98     // 8.2.1 (b) -- wait for BSY
99     await_ide(BSY, iobase1, 20);
100
101     // 8.2.1 (f) -- clear SRST
102     outb(ATA_CB_DC_HD15 | ATA_CB_DC_NIEN, iobase2+ATA_CB_DC);
103
104     type=GET_EBDA(ata.devices[device].type);
105     if (type != ATA_TYPE_NONE) {
106
107         // 8.2.1 (g) -- check for sc==sn==0x01
108         // select device
109         outb(slave?ATA_CB_DH_DEV1:ATA_CB_DH_DEV0, iobase1+ATA_CB_DH);
110         sc = inb(iobase1+ATA_CB_SC);
111         sn = inb(iobase1+ATA_CB_SN);
112
113         if ( (sc==0x01) && (sn==0x01) ) {
114             if (type == ATA_TYPE_ATA) //ATA
115                 await_ide(NOT_BSY_RDY, iobase1, IDE_TIMEOUT);
116             else //ATAPI
117                 await_ide(NOT_BSY, iobase1, IDE_TIMEOUT);
118         }
119
120         // 8.2.1 (h) -- wait for not BSY
121         await_ide(NOT_BSY, iobase1, IDE_TIMEOUT);
122     }
123
124     // Enable interrupts
125     outb(ATA_CB_DC_HD15, iobase2+ATA_CB_DC);
126 }
127
128 static void
129 insw(u16 port, u16 segment, u16 offset, u16 count)
130 {
131     u16 i;
132     for (i=0; i<count; i++) {
133         u16 d = inw(port);
134         SET_FARVAR(segment, *(u16*)(offset + 2*i), d);
135     }
136 }
137
138 static void
139 insl(u16 port, u16 segment, u16 offset, u16 count)
140 {
141     u16 i;
142     for (i=0; i<count; i++) {
143         u32 d = inl(port);
144         SET_FARVAR(segment, *(u32*)(offset + 4*i), d);
145     }
146 }
147
148 static void
149 outsw(u16 port, u16 segment, u16 offset, u16 count)
150 {
151     u16 i;
152     for (i=0; i<count; i++) {
153         u16 d = GET_FARVAR(segment, *(u16*)(offset + 2*i));
154         outw(d, port);
155     }
156 }
157
158 static void
159 outsl(u16 port, u16 segment, u16 offset, u16 count)
160 {
161     u16 i;
162     for (i=0; i<count; i++) {
163         u32 d = GET_FARVAR(segment, *(u32*)(offset + 4*i));
164         outl(d, port);
165     }
166 }
167
168
169 // ---------------------------------------------------------------------------
170 // ATA/ATAPI driver : execute a data-in command
171 // ---------------------------------------------------------------------------
172       // returns
173       // 0 : no error
174       // 1 : BUSY bit set
175       // 2 : read error
176       // 3 : expected DRQ=1
177       // 4 : no sectors left to read/verify
178       // 5 : more sectors to read/verify
179       // 6 : no sectors left to write
180       // 7 : more sectors to write
181 u16
182 ata_cmd_data_in(u16 device, u16 command, u16 count, u16 cylinder
183                 , u16 head, u16 sector, u32 lba, u16 segment, u16 offset)
184 {
185     u16 iobase1, iobase2, blksize;
186     u8  channel, slave;
187     u8  status, current, mode;
188
189     channel = device / 2;
190     slave   = device % 2;
191
192     iobase1 = GET_EBDA(ata.channels[channel].iobase1);
193     iobase2 = GET_EBDA(ata.channels[channel].iobase2);
194     mode    = GET_EBDA(ata.devices[device].mode);
195     blksize = 0x200;
196     if (mode == ATA_MODE_PIO32)
197         blksize>>=2;
198     else
199         blksize>>=1;
200
201     // Reset count of transferred data
202     SET_EBDA(ata.trsfsectors,0);
203     SET_EBDA(ata.trsfbytes,0L);
204     current = 0;
205
206     status = inb(iobase1 + ATA_CB_STAT);
207     if (status & ATA_CB_STAT_BSY)
208         return 1;
209
210     outb(ATA_CB_DC_HD15 | ATA_CB_DC_NIEN, iobase2 + ATA_CB_DC);
211
212     // sector will be 0 only on lba access. Convert to lba-chs
213     if (sector == 0) {
214         if ((count >= 1 << 8) || (lba + count >= 1UL << 28)) {
215             outb(0x00, iobase1 + ATA_CB_FR);
216             outb((count >> 8) & 0xff, iobase1 + ATA_CB_SC);
217             outb(lba >> 24, iobase1 + ATA_CB_SN);
218             outb(0, iobase1 + ATA_CB_CL);
219             outb(0, iobase1 + ATA_CB_CH);
220             command |= 0x04;
221             count &= (1UL << 8) - 1;
222             lba &= (1UL << 24) - 1;
223         }
224         sector = (u16) (lba & 0x000000ffL);
225         cylinder = (u16) ((lba>>8) & 0x0000ffffL);
226         head = ((u16) ((lba>>24) & 0x0000000fL)) | ATA_CB_DH_LBA;
227     }
228
229     outb(0x00, iobase1 + ATA_CB_FR);
230     outb(count, iobase1 + ATA_CB_SC);
231     outb(sector, iobase1 + ATA_CB_SN);
232     outb(cylinder & 0x00ff, iobase1 + ATA_CB_CL);
233     outb(cylinder >> 8, iobase1 + ATA_CB_CH);
234     outb((slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) | (u8) head
235          , iobase1 + ATA_CB_DH);
236     outb(command, iobase1 + ATA_CB_CMD);
237
238     await_ide(NOT_BSY_DRQ, iobase1, IDE_TIMEOUT);
239     status = inb(iobase1 + ATA_CB_STAT);
240
241     if (status & ATA_CB_STAT_ERR) {
242         DEBUGF("ata_cmd_data_in : read error\n");
243         return 2;
244     } else if ( !(status & ATA_CB_STAT_DRQ) ) {
245         DEBUGF("ata_cmd_data_in : DRQ not set (status %02x)\n"
246                , (unsigned) status);
247         return 3;
248     }
249
250     // FIXME : move seg/off translation here
251
252     irq_enable();
253
254     while (1) {
255
256         if (offset > 0xf800) {
257             offset -= 0x800;
258             segment += 0x80;
259         }
260
261         if (mode == ATA_MODE_PIO32)
262             insl(iobase1, segment, offset, blksize);
263         else
264             insw(iobase1, segment, offset, blksize);
265
266         current++;
267         SET_EBDA(ata.trsfsectors,current);
268         count--;
269         await_ide(NOT_BSY, iobase1, IDE_TIMEOUT);
270         status = inb(iobase1 + ATA_CB_STAT);
271         if (count == 0) {
272             if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ
273                             | ATA_CB_STAT_ERR) )
274                  != ATA_CB_STAT_RDY ) {
275                 DEBUGF("ata_cmd_data_in : no sectors left (status %02x)\n"
276                        , (unsigned) status);
277                 return 4;
278             }
279             break;
280         }
281         else {
282             if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ
283                             | ATA_CB_STAT_ERR) )
284                  != (ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ) ) {
285                 DEBUGF("ata_cmd_data_in : more sectors left (status %02x)\n"
286                        , (unsigned) status);
287                 return 5;
288             }
289             continue;
290         }
291     }
292     // Enable interrupts
293     outb(ATA_CB_DC_HD15, iobase2+ATA_CB_DC);
294     return 0;
295 }
296
297 // ---------------------------------------------------------------------------
298 // ATA/ATAPI driver : execute a data-out command
299 // ---------------------------------------------------------------------------
300       // returns
301       // 0 : no error
302       // 1 : BUSY bit set
303       // 2 : read error
304       // 3 : expected DRQ=1
305       // 4 : no sectors left to read/verify
306       // 5 : more sectors to read/verify
307       // 6 : no sectors left to write
308       // 7 : more sectors to write
309 u16
310 ata_cmd_data_out(u16 device, u16 command, u16 count, u16 cylinder
311                  , u16 head, u16 sector, u32 lba, u16 segment, u16 offset)
312 {
313     u16 iobase1, iobase2, blksize;
314     u8  channel, slave;
315     u8  status, current, mode;
316
317     channel = device / 2;
318     slave   = device % 2;
319
320     iobase1 = GET_EBDA(ata.channels[channel].iobase1);
321     iobase2 = GET_EBDA(ata.channels[channel].iobase2);
322     mode    = GET_EBDA(ata.devices[device].mode);
323     blksize = 0x200;
324     if (mode == ATA_MODE_PIO32)
325         blksize>>=2;
326     else
327         blksize>>=1;
328
329     // Reset count of transferred data
330     SET_EBDA(ata.trsfsectors,0);
331     SET_EBDA(ata.trsfbytes,0L);
332     current = 0;
333
334     status = inb(iobase1 + ATA_CB_STAT);
335     if (status & ATA_CB_STAT_BSY)
336         return 1;
337
338     outb(ATA_CB_DC_HD15 | ATA_CB_DC_NIEN, iobase2 + ATA_CB_DC);
339
340     // sector will be 0 only on lba access. Convert to lba-chs
341     if (sector == 0) {
342         if ((count >= 1 << 8) || (lba + count >= 1UL << 28)) {
343             outb(0x00, iobase1 + ATA_CB_FR);
344             outb((count >> 8) & 0xff, iobase1 + ATA_CB_SC);
345             outb(lba >> 24, iobase1 + ATA_CB_SN);
346             outb(0, iobase1 + ATA_CB_CL);
347             outb(0, iobase1 + ATA_CB_CH);
348             command |= 0x04;
349             count &= (1UL << 8) - 1;
350             lba &= (1UL << 24) - 1;
351         }
352         sector = (u16) (lba & 0x000000ffL);
353         cylinder = (u16) ((lba>>8) & 0x0000ffffL);
354         head = ((u16) ((lba>>24) & 0x0000000fL)) | ATA_CB_DH_LBA;
355     }
356
357     outb(0x00, iobase1 + ATA_CB_FR);
358     outb(count, iobase1 + ATA_CB_SC);
359     outb(sector, iobase1 + ATA_CB_SN);
360     outb(cylinder & 0x00ff, iobase1 + ATA_CB_CL);
361     outb(cylinder >> 8, iobase1 + ATA_CB_CH);
362     outb((slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) | (u8) head
363          , iobase1 + ATA_CB_DH);
364     outb(command, iobase1 + ATA_CB_CMD);
365
366     await_ide(NOT_BSY_DRQ, iobase1, IDE_TIMEOUT);
367     status = inb(iobase1 + ATA_CB_STAT);
368
369     if (status & ATA_CB_STAT_ERR) {
370         DEBUGF("ata_cmd_data_out : read error\n");
371         return 2;
372     } else if ( !(status & ATA_CB_STAT_DRQ) ) {
373         DEBUGF("ata_cmd_data_out : DRQ not set (status %02x)\n"
374                , (unsigned) status);
375         return 3;
376     }
377
378     // FIXME : move seg/off translation here
379
380     irq_enable();
381
382     while (1) {
383
384         if (offset > 0xf800) {
385             offset -= 0x800;
386             segment += 0x80;
387         }
388
389         if (mode == ATA_MODE_PIO32)
390             outsl(iobase1, segment, offset, blksize);
391         else
392             outsw(iobase1, segment, offset, blksize);
393
394         current++;
395         SET_EBDA(ata.trsfsectors,current);
396         count--;
397         status = inb(iobase1 + ATA_CB_STAT);
398         if (count == 0) {
399             if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DF
400                             | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) )
401                  != ATA_CB_STAT_RDY ) {
402                 DEBUGF("ata_cmd_data_out : no sectors left (status %02x)\n"
403                        , (unsigned) status);
404                 return 6;
405             }
406             break;
407         } else {
408             if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ
409                             | ATA_CB_STAT_ERR) )
410                  != (ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ) ) {
411                 DEBUGF("ata_cmd_data_out : more sectors left (status %02x)\n"
412                        , (unsigned) status);
413                 return 7;
414             }
415             continue;
416         }
417     }
418     // Enable interrupts
419     outb(ATA_CB_DC_HD15, iobase2+ATA_CB_DC);
420     return 0;
421 }
422
423 // ---------------------------------------------------------------------------
424 // ATA/ATAPI driver : execute a packet command
425 // ---------------------------------------------------------------------------
426       // returns
427       // 0 : no error
428       // 1 : error in parameters
429       // 2 : BUSY bit set
430       // 3 : error
431       // 4 : not ready
432 u16
433 ata_cmd_packet(u16 device, u8 *cmdbuf, u8 cmdlen, u16 header
434                , u32 length, u8 inout, u16 bufseg, u16 bufoff)
435 {
436     u16 iobase1, iobase2;
437     u16 lcount, lbefore, lafter, count;
438     u8  channel, slave;
439     u8  status, mode, lmode;
440     u32 transfer;
441
442     channel = device / 2;
443     slave = device % 2;
444
445     // Data out is not supported yet
446     if (inout == ATA_DATA_OUT) {
447         BX_INFO("ata_cmd_packet: DATA_OUT not supported yet\n");
448         return 1;
449     }
450
451     // The header length must be even
452     if (header & 1) {
453         DEBUGF("ata_cmd_packet : header must be even (%04x)\n", header);
454         return 1;
455     }
456
457     iobase1 = GET_EBDA(ata.channels[channel].iobase1);
458     iobase2 = GET_EBDA(ata.channels[channel].iobase2);
459     mode    = GET_EBDA(ata.devices[device].mode);
460     transfer= 0L;
461
462     if (cmdlen < 12)
463         cmdlen=12;
464     if (cmdlen > 12)
465         cmdlen=16;
466     cmdlen>>=1;
467
468     // Reset count of transferred data
469     SET_EBDA(ata.trsfsectors,0);
470     SET_EBDA(ata.trsfbytes,0L);
471
472     status = inb(iobase1 + ATA_CB_STAT);
473     if (status & ATA_CB_STAT_BSY)
474         return 2;
475
476     outb(ATA_CB_DC_HD15 | ATA_CB_DC_NIEN, iobase2 + ATA_CB_DC);
477     outb(0x00, iobase1 + ATA_CB_FR);
478     outb(0x00, iobase1 + ATA_CB_SC);
479     outb(0x00, iobase1 + ATA_CB_SN);
480     outb(0xfff0 & 0x00ff, iobase1 + ATA_CB_CL);
481     outb(0xfff0 >> 8, iobase1 + ATA_CB_CH);
482     outb(slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0, iobase1 + ATA_CB_DH);
483     outb(ATA_CMD_PACKET, iobase1 + ATA_CB_CMD);
484
485     // Device should ok to receive command
486     await_ide(NOT_BSY_DRQ, iobase1, IDE_TIMEOUT);
487     status = inb(iobase1 + ATA_CB_STAT);
488
489     if (status & ATA_CB_STAT_ERR) {
490         DEBUGF("ata_cmd_packet : error, status is %02x\n", status);
491         return 3;
492     } else if ( !(status & ATA_CB_STAT_DRQ) ) {
493         DEBUGF("ata_cmd_packet : DRQ not set (status %02x)\n"
494                , (unsigned) status);
495         return 4;
496     }
497
498     // Send command to device
499     irq_enable();
500
501     outsw(iobase1, GET_SEG(SS), (u32)cmdbuf, cmdlen);
502
503     if (inout == ATA_DATA_NO) {
504         await_ide(NOT_BSY, iobase1, IDE_TIMEOUT);
505         status = inb(iobase1 + ATA_CB_STAT);
506     } else {
507         u16 loops = 0;
508         u8 sc;
509         while (1) {
510
511             if (loops == 0) {//first time through
512                 status = inb(iobase2 + ATA_CB_ASTAT);
513                 await_ide(NOT_BSY_DRQ, iobase1, IDE_TIMEOUT);
514             } else
515                 await_ide(NOT_BSY, iobase1, IDE_TIMEOUT);
516             loops++;
517
518             status = inb(iobase1 + ATA_CB_STAT);
519             sc = inb(iobase1 + ATA_CB_SC);
520
521             // Check if command completed
522             if(((inb(iobase1 + ATA_CB_SC)&0x7)==0x3) &&
523                ((status & (ATA_CB_STAT_RDY | ATA_CB_STAT_ERR)) == ATA_CB_STAT_RDY))
524                 break;
525
526             if (status & ATA_CB_STAT_ERR) {
527                 DEBUGF("ata_cmd_packet : error (status %02x)\n", status);
528                 return 3;
529             }
530
531             // Normalize address
532             bufseg += (bufoff / 16);
533             bufoff %= 16;
534
535             // Get the byte count
536             lcount =  ((u16)(inb(iobase1 + ATA_CB_CH))<<8)+inb(iobase1 + ATA_CB_CL);
537
538             // adjust to read what we want
539             if (header > lcount) {
540                 lbefore=lcount;
541                 header-=lcount;
542                 lcount=0;
543             } else {
544                 lbefore=header;
545                 header=0;
546                 lcount-=lbefore;
547             }
548
549             if (lcount > length) {
550                 lafter=lcount-length;
551                 lcount=length;
552                 length=0;
553             } else {
554                 lafter=0;
555                 length-=lcount;
556             }
557
558             // Save byte count
559             count = lcount;
560
561             DEBUGF("Trying to read %04x bytes (%04x %04x %04x) "
562                    , lbefore+lcount+lafter, lbefore, lcount, lafter);
563             DEBUGF("to 0x%04x:0x%04x\n", bufseg, bufoff);
564
565             // If counts not dividable by 4, use 16bits mode
566             lmode = mode;
567             if (lbefore & 0x03) lmode=ATA_MODE_PIO16;
568             if (lcount  & 0x03) lmode=ATA_MODE_PIO16;
569             if (lafter  & 0x03) lmode=ATA_MODE_PIO16;
570
571             // adds an extra byte if count are odd. before is always even
572             if (lcount & 0x01) {
573                 lcount+=1;
574                 if ((lafter > 0) && (lafter & 0x01)) {
575                     lafter-=1;
576                 }
577             }
578
579             if (lmode == ATA_MODE_PIO32) {
580                 lcount>>=2; lbefore>>=2; lafter>>=2;
581             } else {
582                 lcount>>=1; lbefore>>=1; lafter>>=1;
583             }
584
585             int i;
586             for (i=0; i<lbefore; i++)
587                 if (lmode == ATA_MODE_PIO32)
588                     inl(iobase1);
589                 else
590                     inw(iobase1);
591
592             if (lmode == ATA_MODE_PIO32)
593                 insl(iobase1, bufseg, bufoff, lcount);
594             else
595                 insw(iobase1, bufseg, bufoff, lcount);
596
597             for (i=0; i<lafter; i++)
598                 if (lmode == ATA_MODE_PIO32)
599                     inl(iobase1);
600                 else
601                     inw(iobase1);
602
603             // Compute new buffer address
604             bufoff += count;
605
606             // Save transferred bytes count
607             transfer += count;
608             SET_EBDA(ata.trsfbytes,transfer);
609         }
610     }
611
612     // Final check, device must be ready
613     if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DF
614                     | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) )
615          != ATA_CB_STAT_RDY ) {
616         DEBUGF("ata_cmd_packet : not ready (status %02x)\n"
617                , (unsigned) status);
618         return 4;
619     }
620
621     // Enable interrupts
622     outb(ATA_CB_DC_HD15, iobase2+ATA_CB_DC);
623     return 0;
624 }
625
626 u16
627 cdrom_read(u16 device, u32 lba, u32 count, u16 segment, u16 offset, u16 skip)
628 {
629     u16 sectors = (count + 2048 - 1) / 2048;
630
631     u8 atacmd[12];
632     memset(atacmd, 0, sizeof(atacmd));
633     atacmd[0]=0x28;                      // READ command
634     atacmd[7]=(sectors & 0xff00) >> 8;   // Sectors
635     atacmd[8]=(sectors & 0x00ff);        // Sectors
636     atacmd[2]=(lba & 0xff000000) >> 24;  // LBA
637     atacmd[3]=(lba & 0x00ff0000) >> 16;
638     atacmd[4]=(lba & 0x0000ff00) >> 8;
639     atacmd[5]=(lba & 0x000000ff);
640
641     return ata_cmd_packet(device, atacmd, sizeof(atacmd)
642                           , skip, count, ATA_DATA_IN
643                           , segment, offset);
644 }
645
646 // ---------------------------------------------------------------------------
647 // ATA/ATAPI driver : device detection
648 // ---------------------------------------------------------------------------
649
650 void
651 ata_detect()
652 {
653     u8  hdcount, cdcount, device, type;
654     u8  buffer[0x0200];
655     memset(buffer, 0, sizeof(buffer));
656
657 #if CONFIG_MAX_ATA_INTERFACES > 0
658     SET_EBDA(ata.channels[0].iface,ATA_IFACE_ISA);
659     SET_EBDA(ata.channels[0].iobase1,0x1f0);
660     SET_EBDA(ata.channels[0].iobase2,0x3f0);
661     SET_EBDA(ata.channels[0].irq,14);
662 #endif
663 #if CONFIG_MAX_ATA_INTERFACES > 1
664     SET_EBDA(ata.channels[1].iface,ATA_IFACE_ISA);
665     SET_EBDA(ata.channels[1].iobase1,0x170);
666     SET_EBDA(ata.channels[1].iobase2,0x370);
667     SET_EBDA(ata.channels[1].irq,15);
668 #endif
669 #if CONFIG_MAX_ATA_INTERFACES > 2
670     SET_EBDA(ata.channels[2].iface,ATA_IFACE_ISA);
671     SET_EBDA(ata.channels[2].iobase1,0x1e8);
672     SET_EBDA(ata.channels[2].iobase2,0x3e0);
673     SET_EBDA(ata.channels[2].irq,12);
674 #endif
675 #if CONFIG_MAX_ATA_INTERFACES > 3
676     SET_EBDA(ata.channels[3].iface,ATA_IFACE_ISA);
677     SET_EBDA(ata.channels[3].iobase1,0x168);
678     SET_EBDA(ata.channels[3].iobase2,0x360);
679     SET_EBDA(ata.channels[3].irq,11);
680 #endif
681 #if CONFIG_MAX_ATA_INTERFACES > 4
682 #error Please fill the ATA interface informations
683 #endif
684
685     // Device detection
686     hdcount=cdcount=0;
687
688     for(device=0; device<CONFIG_MAX_ATA_DEVICES; device++) {
689         u16 iobase1, iobase2;
690         u8  channel, slave, shift;
691         u8  sc, sn, cl, ch, st;
692
693         channel = device / 2;
694         slave = device % 2;
695
696         iobase1 =GET_EBDA(ata.channels[channel].iobase1);
697         iobase2 =GET_EBDA(ata.channels[channel].iobase2);
698
699         // Disable interrupts
700         outb(ATA_CB_DC_HD15 | ATA_CB_DC_NIEN, iobase2+ATA_CB_DC);
701
702         // Look for device
703         outb(slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0, iobase1+ATA_CB_DH);
704         outb(0x55, iobase1+ATA_CB_SC);
705         outb(0xaa, iobase1+ATA_CB_SN);
706         outb(0xaa, iobase1+ATA_CB_SC);
707         outb(0x55, iobase1+ATA_CB_SN);
708         outb(0x55, iobase1+ATA_CB_SC);
709         outb(0xaa, iobase1+ATA_CB_SN);
710
711         // If we found something
712         sc = inb(iobase1+ATA_CB_SC);
713         sn = inb(iobase1+ATA_CB_SN);
714
715         if ( (sc == 0x55) && (sn == 0xaa) ) {
716             SET_EBDA(ata.devices[device].type,ATA_TYPE_UNKNOWN);
717
718             // reset the channel
719             ata_reset(device);
720
721             // check for ATA or ATAPI
722             outb(slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0, iobase1+ATA_CB_DH);
723             sc = inb(iobase1+ATA_CB_SC);
724             sn = inb(iobase1+ATA_CB_SN);
725             if ((sc==0x01) && (sn==0x01)) {
726                 cl = inb(iobase1+ATA_CB_CL);
727                 ch = inb(iobase1+ATA_CB_CH);
728                 st = inb(iobase1+ATA_CB_STAT);
729
730                 if ((cl==0x14) && (ch==0xeb)) {
731                     SET_EBDA(ata.devices[device].type,ATA_TYPE_ATAPI);
732                 } else if ((cl==0x00) && (ch==0x00) && (st!=0x00)) {
733                     SET_EBDA(ata.devices[device].type,ATA_TYPE_ATA);
734                 } else if ((cl==0xff) && (ch==0xff)) {
735                     SET_EBDA(ata.devices[device].type,ATA_TYPE_NONE);
736                 }
737             }
738         }
739
740         type=GET_EBDA(ata.devices[device].type);
741
742         // Now we send a IDENTIFY command to ATA device
743         if(type == ATA_TYPE_ATA) {
744             u32 sectors;
745             u16 cylinders, heads, spt, blksize;
746             u8  translation, removable, mode;
747
748             //Temporary values to do the transfer
749             SET_EBDA(ata.devices[device].device,ATA_DEVICE_HD);
750             SET_EBDA(ata.devices[device].mode, ATA_MODE_PIO16);
751
752             u16 ret = ata_cmd_data_in(device,ATA_CMD_IDENTIFY_DEVICE
753                                       , 1, 0, 0, 0, 0L
754                                       , GET_SEG(SS), (u32)buffer);
755             if (ret)
756                 BX_PANIC("ata-detect: Failed to detect ATA device\n");
757
758             removable = (buffer[0] & 0x80) ? 1 : 0;
759             mode      = buffer[96] ? ATA_MODE_PIO32 : ATA_MODE_PIO16;
760             blksize   = *(u16*)&buffer[10];
761
762             cylinders = *(u16*)&buffer[1*2]; // word 1
763             heads     = *(u16*)&buffer[3*2]; // word 3
764             spt       = *(u16*)&buffer[6*2]; // word 6
765
766             sectors   = *(u32*)&buffer[60*2]; // word 60 and word 61
767
768             SET_EBDA(ata.devices[device].device,ATA_DEVICE_HD);
769             SET_EBDA(ata.devices[device].removable, removable);
770             SET_EBDA(ata.devices[device].mode, mode);
771             SET_EBDA(ata.devices[device].blksize, blksize);
772             SET_EBDA(ata.devices[device].pchs.heads, heads);
773             SET_EBDA(ata.devices[device].pchs.cylinders, cylinders);
774             SET_EBDA(ata.devices[device].pchs.spt, spt);
775             SET_EBDA(ata.devices[device].sectors, sectors);
776             BX_INFO("ata%d-%d: PCHS=%u/%d/%d translation=", channel, slave,cylinders, heads, spt);
777
778             translation = inb_cmos(CMOS_BIOS_DISKTRANSFLAG + channel/2);
779             for (shift=device%4; shift>0; shift--)
780                 translation >>= 2;
781             translation &= 0x03;
782
783             SET_EBDA(ata.devices[device].translation, translation);
784
785             switch (translation) {
786             case ATA_TRANSLATION_NONE:
787                 BX_INFO("none");
788                 break;
789             case ATA_TRANSLATION_LBA:
790                 BX_INFO("lba");
791                 break;
792             case ATA_TRANSLATION_LARGE:
793                 BX_INFO("large");
794                 break;
795             case ATA_TRANSLATION_RECHS:
796                 BX_INFO("r-echs");
797                 break;
798             }
799             switch (translation) {
800             case ATA_TRANSLATION_NONE:
801                 break;
802             case ATA_TRANSLATION_LBA:
803                 spt = 63;
804                 sectors /= 63;
805                 heads = sectors / 1024;
806                 if (heads>128) heads = 255;
807                 else if (heads>64) heads = 128;
808                 else if (heads>32) heads = 64;
809                 else if (heads>16) heads = 32;
810                 else heads=16;
811                 cylinders = sectors / heads;
812                 break;
813             case ATA_TRANSLATION_RECHS:
814                 // Take care not to overflow
815                 if (heads==16) {
816                     if(cylinders>61439) cylinders=61439;
817                     heads=15;
818                     cylinders = (u16)((u32)(cylinders)*16/15);
819                 }
820                 // then go through the large bitshift process
821             case ATA_TRANSLATION_LARGE:
822                 while(cylinders > 1024) {
823                     cylinders >>= 1;
824                     heads <<= 1;
825
826                     // If we max out the head count
827                     if (heads > 127) break;
828                 }
829                 break;
830             }
831             // clip to 1024 cylinders in lchs
832             if (cylinders > 1024)
833                 cylinders=1024;
834             BX_INFO(" LCHS=%d/%d/%d\n", cylinders, heads, spt);
835
836             SET_EBDA(ata.devices[device].lchs.heads, heads);
837             SET_EBDA(ata.devices[device].lchs.cylinders, cylinders);
838             SET_EBDA(ata.devices[device].lchs.spt, spt);
839
840             // fill hdidmap
841             SET_EBDA(ata.idmap[0][hdcount], device);
842             hdcount++;
843         }
844
845         // Now we send a IDENTIFY command to ATAPI device
846         if(type == ATA_TYPE_ATAPI) {
847
848             u8  type, removable, mode;
849             u16 blksize;
850
851             //Temporary values to do the transfer
852             SET_EBDA(ata.devices[device].device,ATA_DEVICE_CDROM);
853             SET_EBDA(ata.devices[device].mode, ATA_MODE_PIO16);
854
855             u16 ret = ata_cmd_data_in(device,ATA_CMD_IDENTIFY_DEVICE_PACKET
856                                       , 1, 0, 0, 0, 0L
857                                       , GET_SEG(SS), (u32)buffer);
858             if (ret != 0)
859                 BX_PANIC("ata-detect: Failed to detect ATAPI device\n");
860
861             type      = buffer[1] & 0x1f;
862             removable = (buffer[0] & 0x80) ? 1 : 0;
863             mode      = buffer[96] ? ATA_MODE_PIO32 : ATA_MODE_PIO16;
864             blksize   = 2048;
865
866             SET_EBDA(ata.devices[device].device, type);
867             SET_EBDA(ata.devices[device].removable, removable);
868             SET_EBDA(ata.devices[device].mode, mode);
869             SET_EBDA(ata.devices[device].blksize, blksize);
870
871             // fill cdidmap
872             SET_EBDA(ata.idmap[1][cdcount], device);
873             cdcount++;
874         }
875
876         u32 sizeinmb = 0;
877         u16 ataversion;
878         u8  c, i, version=0, model[41];
879
880         switch (type) {
881         case ATA_TYPE_ATA:
882             sizeinmb = GET_EBDA(ata.devices[device].sectors);
883             sizeinmb >>= 11;
884         case ATA_TYPE_ATAPI:
885             // Read ATA/ATAPI version
886             ataversion=((u16)(buffer[161])<<8) | buffer[160];
887             for(version=15;version>0;version--) {
888                 if ((ataversion&(1<<version))!=0)
889                     break;
890             }
891
892             // Read model name
893             for (i=0;i<20;i++) {
894                 model[i*2] = buffer[(i*2)+54+1];
895                 model[(i*2)+1] = buffer[(i*2)+54];
896             }
897
898             // Reformat
899             model[40] = 0x00;
900             for (i=39;i>0;i--) {
901                 if (model[i]==0x20)
902                     model[i] = 0x00;
903                 else
904                     break;
905             }
906             break;
907         }
908
909         switch (type) {
910         case ATA_TYPE_ATA:
911             printf("ata%d %s: ",channel,slave?" slave":"master");
912             i=0;
913             while ((c=model[i++]))
914                 printf("%c",c);
915             if (sizeinmb < (1UL<<16))
916                 printf(" ATA-%d Hard-Disk (%u MBytes)\n", version, (u16)sizeinmb);
917             else
918                 printf(" ATA-%d Hard-Disk (%u GBytes)\n", version, (u16)(sizeinmb>>10));
919             break;
920         case ATA_TYPE_ATAPI:
921             printf("ata%d %s: ",channel,slave?" slave":"master");
922             i=0;
923             while ((c=model[i++]))
924                 printf("%c",c);
925             if (GET_EBDA(ata.devices[device].device)==ATA_DEVICE_CDROM)
926                 printf(" ATAPI-%d CD-Rom/DVD-Rom\n",version);
927             else
928                 printf(" ATAPI-%d Device\n",version);
929             break;
930         case ATA_TYPE_UNKNOWN:
931             printf("ata%d %s: Unknown device\n",channel,slave?" slave":"master");
932             break;
933         }
934     }
935
936     // Store the devices counts
937     SET_EBDA(ata.hdcount, hdcount);
938     SET_EBDA(ata.cdcount, cdcount);
939     SET_BDA(disk_count, hdcount);
940
941     printf("\n");
942
943     // FIXME : should use bios=cmos|auto|disable bits
944     // FIXME : should know about translation bits
945     // FIXME : move hard_drive_post here
946 }