eba9972a5057c2efc641ee8de837cf8a171884a4
[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
129 // ---------------------------------------------------------------------------
130 // ATA/ATAPI driver : execute a data command
131 // ---------------------------------------------------------------------------
132       // returns
133       // 0 : no error
134       // 1 : BUSY bit set
135       // 2 : read error
136       // 3 : expected DRQ=1
137       // 4 : no sectors left to read/verify
138       // 5 : more sectors to read/verify
139       // 6 : no sectors left to write
140       // 7 : more sectors to write
141
142 struct ata_pio_command {
143     void *far_buffer;
144     u8 biosid;
145
146     u8 feature;
147     u8 sector_count;
148     u8 lba_low;
149     u8 lba_mid;
150     u8 lba_high;
151     u8 device;
152     u8 command;
153
154     u8 sector_count2;
155     u8 lba_low2;
156     u8 lba_mid2;
157     u8 lba_high2;
158 };
159
160 static int
161 send_cmd(struct ata_pio_command *cmd)
162 {
163     u16 biosid = cmd->biosid;
164     u8 channel = biosid / 2;
165     u16 iobase1 = GET_EBDA(ata.channels[channel].iobase1);
166     u16 iobase2 = GET_EBDA(ata.channels[channel].iobase2);
167
168     u8 status = inb(iobase1 + ATA_CB_STAT);
169     if (status & ATA_CB_STAT_BSY)
170         return 1;
171
172     outb(ATA_CB_DC_HD15 | ATA_CB_DC_NIEN, iobase2 + ATA_CB_DC);
173     if (cmd->command & 0x04) {
174         outb(0x00, iobase1 + ATA_CB_FR);
175         outb(cmd->sector_count2, iobase1 + ATA_CB_SC);
176         outb(cmd->lba_low2, iobase1 + ATA_CB_SN);
177         outb(cmd->lba_mid2, iobase1 + ATA_CB_CL);
178         outb(cmd->lba_high2, iobase1 + ATA_CB_CH);
179     }
180     outb(cmd->feature, iobase1 + ATA_CB_FR);
181     outb(cmd->sector_count, iobase1 + ATA_CB_SC);
182     outb(cmd->lba_low, iobase1 + ATA_CB_SN);
183     outb(cmd->lba_mid, iobase1 + ATA_CB_CL);
184     outb(cmd->lba_high, iobase1 + ATA_CB_CH);
185     outb(cmd->device, iobase1 + ATA_CB_DH);
186     outb(cmd->command, iobase1 + ATA_CB_CMD);
187
188     await_ide(NOT_BSY_DRQ, iobase1, IDE_TIMEOUT);
189
190     status = inb(iobase1 + ATA_CB_STAT);
191     if (status & ATA_CB_STAT_ERR) {
192         DEBUGF("send_cmd : read error\n");
193         return 2;
194     }
195     if (!(status & ATA_CB_STAT_DRQ)) {
196         DEBUGF("send_cmd : DRQ not set (status %02x)\n"
197                , (unsigned) status);
198         return 3;
199     }
200
201     return 0;
202 }
203
204 static int
205 ata_transfer(struct ata_pio_command *cmd)
206 {
207     DEBUGF("ata_transfer id=%d cmd=%d lba=%d count=%d buf=%p\n"
208            , cmd->biosid, cmd->command
209            , (cmd->lba_high << 16) | (cmd->lba_mid << 8) | cmd->lba_low
210            , cmd->sector_count, cmd->far_buffer);
211
212     // Reset count of transferred data
213     SET_EBDA(ata.trsfsectors,0);
214     SET_EBDA(ata.trsfbytes,0L);
215
216     int ret = send_cmd(cmd);
217     if (ret)
218         return ret;
219
220     u16 biosid = cmd->biosid;
221     u8 channel  = biosid / 2;
222     u16 iobase1 = GET_EBDA(ata.channels[channel].iobase1);
223     u16 iobase2 = GET_EBDA(ata.channels[channel].iobase2);
224     u8 mode     = GET_EBDA(ata.devices[biosid].mode);
225     int iswrite = (cmd->command & ~0x40) == ATA_CMD_WRITE_SECTORS;
226     u8 current = 0;
227     u16 count = cmd->sector_count;
228     u8 status;
229     void *far_buffer = cmd->far_buffer;
230     for (;;) {
231         if (iswrite) {
232             // Write data to controller
233             DEBUGF("Write sector id=%d dest=%p\n", biosid, far_buffer);
234             if (mode == ATA_MODE_PIO32)
235                 outsl_far(iobase1, far_buffer, 512 / 4);
236             else
237                 outsw_far(iobase1, far_buffer, 512 / 2);
238         } else {
239             // Read data from controller
240             DEBUGF("Read sector id=%d dest=%p\n", biosid, far_buffer);
241             if (mode == ATA_MODE_PIO32)
242                 insl_far(iobase1, far_buffer, 512 / 4);
243             else
244                 insw_far(iobase1, far_buffer, 512 / 2);
245             await_ide(NOT_BSY, iobase1, IDE_TIMEOUT);
246         }
247         far_buffer += 512;
248
249         current++;
250         SET_EBDA(ata.trsfsectors,current);
251         count--;
252         status = inb(iobase1 + ATA_CB_STAT);
253         if (count == 0)
254             break;
255         status &= (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ
256                    | ATA_CB_STAT_ERR);
257         if (status != (ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ)) {
258             DEBUGF("ata_transfer : more sectors left (status %02x)\n"
259                    , (unsigned) status);
260             return 5;
261         }
262     }
263
264     status &= (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DF
265                | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR);
266     if (!iswrite)
267         status &= ~ATA_CB_STAT_DF;
268     if (status != ATA_CB_STAT_RDY ) {
269         DEBUGF("ata_transfer : no sectors left (status %02x)\n"
270                , (unsigned) status);
271         return 4;
272     }
273
274     // Enable interrupts
275     outb(ATA_CB_DC_HD15, iobase2+ATA_CB_DC);
276     return 0;
277 }
278
279 inline int
280 ata_cmd_data(u16 biosid, u16 command, u32 lba, u16 count, void *far_buffer)
281 {
282     u8 slave   = biosid % 2;
283
284     struct ata_pio_command cmd;
285     cmd.far_buffer = far_buffer;
286     cmd.biosid = biosid;
287
288     if (count >= (1<<8) || lba + count >= (1<<28)) {
289         cmd.sector_count2 = count >> 8;
290         cmd.lba_low2 = lba >> 24;
291         cmd.lba_mid2 = 0;
292         cmd.lba_high2 = 0;
293
294         command |= 0x04;
295         lba &= 0xffffff;
296     }
297
298     cmd.feature = 0;
299     cmd.sector_count = count;
300     cmd.lba_low = lba;
301     cmd.lba_mid = lba >> 8;
302     cmd.lba_high = lba >> 16;
303     cmd.device = ((slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0)
304                   | ((lba >> 24) & 0xf) | ATA_CB_DH_LBA);
305     cmd.command = command;
306     return ata_transfer(&cmd);
307 }
308
309 // ---------------------------------------------------------------------------
310 // ATA/ATAPI driver : execute a packet command
311 // ---------------------------------------------------------------------------
312       // returns
313       // 0 : no error
314       // 1 : error in parameters
315       // 2 : BUSY bit set
316       // 3 : error
317       // 4 : not ready
318 static inline int
319 __ata_cmd_packet(u16 biosid, u8 *cmdbuf, u8 cmdlen
320                  , u16 header, u32 length, void *far_buffer)
321 {
322     DEBUGF("ata_cmd_packet d=%d cmdlen=%d h=%d l=%d buf=%p\n"
323            , biosid, cmdlen, header, length, far_buffer);
324
325     u8 channel = biosid / 2;
326     u8 slave = biosid % 2;
327
328     // The header length must be even
329     if (header & 1) {
330         DEBUGF("ata_cmd_packet : header must be even (%04x)\n", header);
331         return 1;
332     }
333
334     u16 iobase1 = GET_EBDA(ata.channels[channel].iobase1);
335     u16 iobase2 = GET_EBDA(ata.channels[channel].iobase2);
336     u8 mode     = GET_EBDA(ata.devices[biosid].mode);
337
338     struct ata_pio_command cmd;
339     cmd.sector_count = 0;
340     cmd.feature = 0;
341     cmd.lba_low = 0;
342     cmd.lba_mid = 0xf0;
343     cmd.lba_high = 0xff;
344     cmd.device = slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0;
345     cmd.command = ATA_CMD_PACKET;
346
347     cmd.biosid = biosid;
348     int ret = send_cmd(&cmd);
349     if (ret)
350         return ret;
351
352     // Reset count of transferred data
353     SET_EBDA(ata.trsfsectors,0);
354     SET_EBDA(ata.trsfbytes,0L);
355
356     // Send command to device
357     outsw_far(iobase1, MAKE_FARPTR(GET_SEG(SS), (u32)cmdbuf), cmdlen / 2);
358
359     u8 status;
360     u16 loops = 0;
361     for (;;) {
362         if (loops == 0) {//first time through
363             status = inb(iobase2 + ATA_CB_ASTAT);
364             await_ide(NOT_BSY_DRQ, iobase1, IDE_TIMEOUT);
365         } else
366             await_ide(NOT_BSY, iobase1, IDE_TIMEOUT);
367         loops++;
368
369         status = inb(iobase1 + ATA_CB_STAT);
370         inb(iobase1 + ATA_CB_SC);
371
372         // Check if command completed
373         if(((inb(iobase1 + ATA_CB_SC)&0x7)==0x3) &&
374            ((status & (ATA_CB_STAT_RDY | ATA_CB_STAT_ERR)) == ATA_CB_STAT_RDY))
375             break;
376
377         if (status & ATA_CB_STAT_ERR) {
378             DEBUGF("ata_cmd_packet : error (status %02x)\n", status);
379             return 3;
380         }
381
382         // Get the byte count
383         u16 lcount =  (((u16)(inb(iobase1 + ATA_CB_CH))<<8)
384                        + inb(iobase1 + ATA_CB_CL));
385
386         // adjust to read what we want
387         u16 lbefore, lafter;
388         if (header > lcount) {
389             lbefore=lcount;
390             header-=lcount;
391             lcount=0;
392         } else {
393             lbefore=header;
394             header=0;
395             lcount-=lbefore;
396         }
397
398         if (lcount > length) {
399             lafter=lcount-length;
400             lcount=length;
401             length=0;
402         } else {
403             lafter=0;
404             length-=lcount;
405         }
406
407         // Save byte count
408         u16 count = lcount;
409
410         DEBUGF("Trying to read %04x bytes (%04x %04x %04x) to %p\n"
411                , lbefore+lcount+lafter, lbefore, lcount, lafter, far_buffer);
412
413         // If counts not dividable by 4, use 16bits mode
414         u8 lmode = mode;
415         if (lbefore & 0x03) lmode=ATA_MODE_PIO16;
416         if (lcount  & 0x03) lmode=ATA_MODE_PIO16;
417         if (lafter  & 0x03) lmode=ATA_MODE_PIO16;
418
419         // adds an extra byte if count are odd. before is always even
420         if (lcount & 0x01) {
421             lcount+=1;
422             if ((lafter > 0) && (lafter & 0x01)) {
423                 lafter-=1;
424             }
425         }
426
427         if (lmode == ATA_MODE_PIO32) {
428             lcount>>=2; lbefore>>=2; lafter>>=2;
429         } else {
430             lcount>>=1; lbefore>>=1; lafter>>=1;
431         }
432
433         int i;
434         for (i=0; i<lbefore; i++)
435             if (lmode == ATA_MODE_PIO32)
436                 inl(iobase1);
437             else
438                 inw(iobase1);
439
440         if (lmode == ATA_MODE_PIO32)
441             insl_far(iobase1, far_buffer, lcount);
442         else
443             insw_far(iobase1, far_buffer, lcount);
444
445         for (i=0; i<lafter; i++)
446             if (lmode == ATA_MODE_PIO32)
447                 inl(iobase1);
448             else
449                 inw(iobase1);
450
451         // Compute new buffer address
452         far_buffer += count;
453
454         // Save transferred bytes count
455         SET_EBDA(ata.trsfsectors, loops);
456     }
457
458     // Final check, device must be ready
459     if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DF
460                     | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) )
461          != ATA_CB_STAT_RDY ) {
462         DEBUGF("ata_cmd_packet : not ready (status %02x)\n"
463                , (unsigned) status);
464         return 4;
465     }
466
467     // Enable interrupts
468     outb(ATA_CB_DC_HD15, iobase2+ATA_CB_DC);
469     return 0;
470 }
471
472 int
473 ata_cmd_packet(u16 biosid, u8 *cmdbuf, u8 cmdlen
474                , u32 length, void *far_buffer)
475 {
476     return __ata_cmd_packet(biosid, cmdbuf, cmdlen, 0, length, far_buffer);
477 }
478
479 static void
480 build_cdrom_cmd(u8 *atacmd, u32 lba, u16 count)
481 {
482     memset(atacmd, 0, 12);
483     atacmd[0]=0x28;                     // READ command
484     atacmd[7]=(count & 0xff00) >> 8;    // Sectors
485     atacmd[8]=(count & 0x00ff);         // Sectors
486     atacmd[2]=(lba & 0xff000000) >> 24; // LBA
487     atacmd[3]=(lba & 0x00ff0000) >> 16;
488     atacmd[4]=(lba & 0x0000ff00) >> 8;
489     atacmd[5]=(lba & 0x000000ff);
490 }
491
492 // Read sectors from the cdrom.
493 int
494 cdrom_read(u16 biosid, u32 lba, u32 count, void *far_buffer)
495 {
496     u8 atacmd[12];
497     build_cdrom_cmd(atacmd, lba, count);
498     return ata_cmd_packet(biosid, atacmd, sizeof(atacmd)
499                           , count*2048, far_buffer);
500 }
501
502 // Pretend the cdrom has 512 byte sectors (instead of 2048) and read
503 // sectors.
504 int
505 cdrom_read_512(u16 biosid, u32 vlba, u32 count, void *far_buffer)
506 {
507     u32 slba = vlba / 4;
508     u16 before = vlba % 4;
509     u32 elba = (vlba + count - 1) / 4;
510
511     u8 atacmd[12];
512     build_cdrom_cmd(atacmd, slba, elba - slba + 1);
513
514     int status = __ata_cmd_packet(biosid, atacmd, sizeof(atacmd)
515                                   , before*512, count*512, far_buffer);
516     if (status) {
517         SET_EBDA(ata.trsfsectors, 0);
518         return status;
519     }
520     SET_EBDA(ata.trsfsectors, count);
521     return 0;
522 }
523
524
525 // ---------------------------------------------------------------------------
526 // ATA/ATAPI driver : device detection
527 // ---------------------------------------------------------------------------
528
529 static void
530 report_model(u8 devid, u8 *buffer)
531 {
532     u8 model[41];
533
534     // Read model name
535     int i;
536     for (i=0; i<40; i+=2) {
537         model[i] = buffer[i+54+1];
538         model[i+1] = buffer[i+54];
539     }
540
541     // Reformat
542     model[40] = 0x00;
543     for (i=39; i>0; i--) {
544         if (model[i] != 0x20)
545             break;
546         model[i] = 0x00;
547     }
548
549     u8 channel = devid / 2;
550     u8 slave = devid % 2;
551     // XXX - model on stack not %cs
552     printf("ata%d %s: %s", channel, slave ? " slave" : "master", model);
553 }
554
555 static u8
556 get_ata_version(u8 *buffer)
557 {
558     u16 ataversion = *(u16*)&buffer[160];
559     u8 version;
560     for (version=15; version>0; version--)
561         if (ataversion & (1<<version))
562             break;
563     return version;
564 }
565
566 static void
567 init_drive_atapi(u8 devid)
568 {
569     SET_EBDA(ata.devices[devid].type,ATA_TYPE_ATAPI);
570
571     // Temporary values to do the transfer
572     SET_EBDA(ata.devices[devid].device,ATA_DEVICE_CDROM);
573     SET_EBDA(ata.devices[devid].mode, ATA_MODE_PIO16);
574
575     // Now we send a IDENTIFY command to ATAPI device
576     u8 buffer[0x0200];
577     memset(buffer, 0, sizeof(buffer));
578     u16 ret = ata_cmd_data(devid, ATA_CMD_IDENTIFY_DEVICE_PACKET
579                            , 1, 1
580                            , MAKE_FARPTR(GET_SEG(SS), (u32)buffer));
581     if (ret != 0)
582         BX_PANIC("ata-detect: Failed to detect ATAPI device\n");
583
584     u8 type      = buffer[1] & 0x1f;
585     u8 removable = (buffer[0] & 0x80) ? 1 : 0;
586     u8 mode      = buffer[96] ? ATA_MODE_PIO32 : ATA_MODE_PIO16;
587     u16 blksize  = 2048;
588
589     SET_EBDA(ata.devices[devid].device, type);
590     SET_EBDA(ata.devices[devid].removable, removable);
591     SET_EBDA(ata.devices[devid].mode, mode);
592     SET_EBDA(ata.devices[devid].blksize, blksize);
593
594     // fill cdidmap
595     u8 cdcount = GET_EBDA(ata.cdcount);
596     SET_EBDA(ata.idmap[1][cdcount], devid);
597     SET_EBDA(ata.cdcount, ++cdcount);
598
599     report_model(devid, buffer);
600     u8 version = get_ata_version(buffer);
601     if (GET_EBDA(ata.devices[devid].device)==ATA_DEVICE_CDROM)
602         printf(" ATAPI-%d CD-Rom/DVD-Rom\n", version);
603     else
604         printf(" ATAPI-%d Device\n", version);
605 }
606
607 static void
608 init_drive_ata(u8 devid)
609 {
610     SET_EBDA(ata.devices[devid].type,ATA_TYPE_ATA);
611
612     // Temporary values to do the transfer
613     SET_EBDA(ata.devices[devid].device, ATA_DEVICE_HD);
614     SET_EBDA(ata.devices[devid].mode, ATA_MODE_PIO16);
615
616     // Now we send a IDENTIFY command to ATA device
617     u8 buffer[0x0200];
618     memset(buffer, 0, sizeof(buffer));
619     u16 ret = ata_cmd_data(devid, ATA_CMD_IDENTIFY_DEVICE
620                            , 1, 1
621                            , MAKE_FARPTR(GET_SEG(SS), (u32)buffer));
622     if (ret)
623         BX_PANIC("ata-detect: Failed to detect ATA device\n");
624
625     u8 removable  = (buffer[0] & 0x80) ? 1 : 0;
626     u8 mode       = buffer[96] ? ATA_MODE_PIO32 : ATA_MODE_PIO16;
627     u16 blksize   = *(u16*)&buffer[10];
628
629     u16 cylinders = *(u16*)&buffer[1*2]; // word 1
630     u16 heads     = *(u16*)&buffer[3*2]; // word 3
631     u16 spt       = *(u16*)&buffer[6*2]; // word 6
632
633     u32 sectors   = *(u32*)&buffer[60*2]; // word 60 and word 61
634
635     SET_EBDA(ata.devices[devid].device,ATA_DEVICE_HD);
636     SET_EBDA(ata.devices[devid].removable, removable);
637     SET_EBDA(ata.devices[devid].mode, mode);
638     SET_EBDA(ata.devices[devid].blksize, blksize);
639     SET_EBDA(ata.devices[devid].pchs.heads, heads);
640     SET_EBDA(ata.devices[devid].pchs.cylinders, cylinders);
641     SET_EBDA(ata.devices[devid].pchs.spt, spt);
642     SET_EBDA(ata.devices[devid].sectors, sectors);
643
644     u8 channel = devid / 2;
645     u8 slave = devid % 2;
646     u8 translation = inb_cmos(CMOS_BIOS_DISKTRANSFLAG + channel/2);
647     u8 shift;
648     for (shift=devid%4; shift>0; shift--)
649         translation >>= 2;
650     translation &= 0x03;
651
652     SET_EBDA(ata.devices[devid].translation, translation);
653
654     BX_INFO("ata%d-%d: PCHS=%u/%d/%d translation="
655             , channel, slave, cylinders, heads, spt);
656     switch (translation) {
657     case ATA_TRANSLATION_NONE:
658         BX_INFO("none");
659         break;
660     case ATA_TRANSLATION_LBA:
661         BX_INFO("lba");
662         spt = 63;
663         sectors /= 63;
664         heads = sectors / 1024;
665         if (heads>128)
666             heads = 255;
667         else if (heads>64)
668             heads = 128;
669         else if (heads>32)
670             heads = 64;
671         else if (heads>16)
672             heads = 32;
673         else
674             heads = 16;
675         cylinders = sectors / heads;
676         break;
677     case ATA_TRANSLATION_RECHS:
678         BX_INFO("r-echs");
679         // Take care not to overflow
680         if (heads==16) {
681             if (cylinders>61439)
682                 cylinders=61439;
683             heads=15;
684             cylinders = (u16)((u32)(cylinders)*16/15);
685         }
686         // then go through the large bitshift process
687     case ATA_TRANSLATION_LARGE:
688         if (translation == ATA_TRANSLATION_LARGE)
689             BX_INFO("large");
690         while(cylinders > 1024) {
691             cylinders >>= 1;
692             heads <<= 1;
693
694             // If we max out the head count
695             if (heads > 127)
696                 break;
697         }
698         break;
699     }
700     // clip to 1024 cylinders in lchs
701     if (cylinders > 1024)
702         cylinders = 1024;
703     BX_INFO(" LCHS=%d/%d/%d\n", cylinders, heads, spt);
704
705     SET_EBDA(ata.devices[devid].lchs.heads, heads);
706     SET_EBDA(ata.devices[devid].lchs.cylinders, cylinders);
707     SET_EBDA(ata.devices[devid].lchs.spt, spt);
708
709     // fill hdidmap
710     u8 hdcount = GET_EBDA(ata.hdcount);
711     SET_EBDA(ata.idmap[0][hdcount], devid);
712     SET_EBDA(ata.hdcount, ++hdcount);
713
714     u32 sizeinmb = GET_EBDA(ata.devices[devid].sectors);
715     sizeinmb >>= 11;
716
717     report_model(devid, buffer);
718     u8 version = get_ata_version(buffer);
719     if (sizeinmb < (1 << 16))
720         printf(" ATA-%d Hard-Disk (%u MBytes)\n", version, sizeinmb);
721     else
722         printf(" ATA-%d Hard-Disk (%u GBytes)\n", version, sizeinmb >> 10);
723 }
724
725 static void
726 init_drive_unknown(u8 devid)
727 {
728     SET_EBDA(ata.devices[devid].type,ATA_TYPE_UNKNOWN);
729
730     u8 channel = devid / 2;
731     u8 slave = devid % 2;
732     printf("ata%d %s: Unknown device\n", channel, slave ? " slave" : "master");
733 }
734
735 void
736 ata_detect()
737 {
738 #if CONFIG_MAX_ATA_INTERFACES > 0
739     SET_EBDA(ata.channels[0].iface,ATA_IFACE_ISA);
740     SET_EBDA(ata.channels[0].iobase1,0x1f0);
741     SET_EBDA(ata.channels[0].iobase2,0x3f0);
742     SET_EBDA(ata.channels[0].irq,14);
743 #endif
744 #if CONFIG_MAX_ATA_INTERFACES > 1
745     SET_EBDA(ata.channels[1].iface,ATA_IFACE_ISA);
746     SET_EBDA(ata.channels[1].iobase1,0x170);
747     SET_EBDA(ata.channels[1].iobase2,0x370);
748     SET_EBDA(ata.channels[1].irq,15);
749 #endif
750 #if CONFIG_MAX_ATA_INTERFACES > 2
751     SET_EBDA(ata.channels[2].iface,ATA_IFACE_ISA);
752     SET_EBDA(ata.channels[2].iobase1,0x1e8);
753     SET_EBDA(ata.channels[2].iobase2,0x3e0);
754     SET_EBDA(ata.channels[2].irq,12);
755 #endif
756 #if CONFIG_MAX_ATA_INTERFACES > 3
757     SET_EBDA(ata.channels[3].iface,ATA_IFACE_ISA);
758     SET_EBDA(ata.channels[3].iobase1,0x168);
759     SET_EBDA(ata.channels[3].iobase2,0x360);
760     SET_EBDA(ata.channels[3].irq,11);
761 #endif
762 #if CONFIG_MAX_ATA_INTERFACES > 4
763 #error Please fill the ATA interface informations
764 #endif
765
766     // Device detection
767     u8 devid;
768     for(devid=0; devid<CONFIG_MAX_ATA_DEVICES; devid++) {
769         u8 channel = devid / 2;
770         u8 slave = devid % 2;
771
772         u16 iobase1 = GET_EBDA(ata.channels[channel].iobase1);
773         u16 iobase2 = GET_EBDA(ata.channels[channel].iobase2);
774
775         // Disable interrupts
776         outb(ATA_CB_DC_HD15 | ATA_CB_DC_NIEN, iobase2+ATA_CB_DC);
777
778         // Look for device
779         outb(slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0, iobase1+ATA_CB_DH);
780         outb(0x55, iobase1+ATA_CB_SC);
781         outb(0xaa, iobase1+ATA_CB_SN);
782         outb(0xaa, iobase1+ATA_CB_SC);
783         outb(0x55, iobase1+ATA_CB_SN);
784         outb(0x55, iobase1+ATA_CB_SC);
785         outb(0xaa, iobase1+ATA_CB_SN);
786
787         // If we found something
788         u8 sc = inb(iobase1+ATA_CB_SC);
789         u8 sn = inb(iobase1+ATA_CB_SN);
790
791         if (sc != 0x55 || sn != 0xaa)
792             continue;
793
794         // reset the channel
795         ata_reset(devid);
796
797         // check for ATA or ATAPI
798         outb(slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0, iobase1+ATA_CB_DH);
799         sc = inb(iobase1+ATA_CB_SC);
800         sn = inb(iobase1+ATA_CB_SN);
801         if (sc!=0x01 || sn!=0x01) {
802             init_drive_unknown(devid);
803             continue;
804         }
805         u8 cl = inb(iobase1+ATA_CB_CL);
806         u8 ch = inb(iobase1+ATA_CB_CH);
807         u8 st = inb(iobase1+ATA_CB_STAT);
808
809         if (cl==0x14 && ch==0xeb)
810             init_drive_atapi(devid);
811         else if (cl==0x00 && ch==0x00 && st!=0x00)
812             init_drive_ata(devid);
813         else if (cl==0xff && ch==0xff)
814             // None
815             continue;
816         else
817             init_drive_unknown(devid);
818     }
819
820     // Store the device count
821     SET_BDA(disk_count, GET_EBDA(ata.hdcount));
822
823     printf("\n");
824
825     // FIXME : should use bios=cmos|auto|disable bits
826     // FIXME : should know about translation bits
827     // FIXME : move hard_drive_post here
828 }