Change license from GPLv3 to LGPLv3.
[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 LGPLv3 license.
7
8 #include "types.h" // u8
9 #include "ioport.h" // inb
10 #include "util.h" // dprintf
11 #include "cmos.h" // inb_cmos
12 #include "pic.h" // enable_hwirq
13 #include "biosvar.h" // GET_EBDA
14 #include "pci.h" // pci_find_class
15 #include "pci_ids.h" // PCI_CLASS_STORAGE_OTHER
16 #include "pci_regs.h" // PCI_INTERRUPT_LINE
17 #include "disk.h" // struct ata_s
18 #include "atabits.h" // ATA_CB_STAT
19
20 #define TIMEOUT 0
21 #define BSY 1
22 #define NOT_BSY 2
23 #define NOT_BSY_DRQ 3
24 #define NOT_BSY_NOT_DRQ 4
25 #define NOT_BSY_RDY 5
26
27 #define IDE_SECTOR_SIZE 512
28 #define CDROM_SECTOR_SIZE 2048
29
30 #define IDE_TIMEOUT 32000u //32 seconds max for IDE ops
31
32 struct ata_s ATA VAR16_32;
33
34
35 /****************************************************************
36  * Helper functions
37  ****************************************************************/
38
39 // Wait for the specified ide state
40 static int
41 await_ide(u8 when_done, u16 base, u16 timeout)
42 {
43     u64 end = calc_future_tsc(timeout);
44     for (;;) {
45         u8 status = inb(base+ATA_CB_STAT);
46         u8 result = 0;
47         if (when_done == BSY)
48             result = status & ATA_CB_STAT_BSY;
49         else if (when_done == NOT_BSY)
50             result = !(status & ATA_CB_STAT_BSY);
51         else if (when_done == NOT_BSY_DRQ)
52             result = !(status & ATA_CB_STAT_BSY) && (status & ATA_CB_STAT_DRQ);
53         else if (when_done == NOT_BSY_NOT_DRQ)
54             result = !(status & ATA_CB_STAT_BSY) && !(status & ATA_CB_STAT_DRQ);
55         else if (when_done == NOT_BSY_RDY)
56             result = !(status & ATA_CB_STAT_BSY) && (status & ATA_CB_STAT_RDY);
57
58         if (result)
59             return status;
60         if (status & ATA_CB_STAT_ERR) {
61             dprintf(1, "await_ide: ERROR (TIMEOUT,BSY,!BSY,!BSY_DRQ"
62                     ",!BSY_!DRQ,!BSY_RDY) %d status=%x timeout=%d\n"
63                     , when_done, status, timeout);
64             return -1;
65         }
66         if (rdtscll() >= end)
67             break;
68     }
69     dprintf(1, "IDE time out\n");
70     return -2;
71 }
72
73 // Wait for ide state - pauses for one ata cycle first.
74 static __always_inline int
75 pause_await_ide(u8 when_done, u16 iobase1, u16 iobase2, u16 timeout)
76 {
77     // Wait one PIO transfer cycle.
78     inb(iobase2 + ATA_CB_ASTAT);
79
80     return await_ide(when_done, iobase1, timeout);
81 }
82
83 // Wait for ide state - pause for 400ns first.
84 static __always_inline int
85 ndelay_await_ide(u8 when_done, u16 iobase1, u16 timeout)
86 {
87     ndelay(400);
88     return await_ide(when_done, iobase1, timeout);
89 }
90
91 // Reset a drive
92 void
93 ata_reset(int driveid)
94 {
95     u8 channel = driveid / 2;
96     u8 slave = driveid % 2;
97     u16 iobase1 = GET_GLOBAL(ATA.channels[channel].iobase1);
98     u16 iobase2 = GET_GLOBAL(ATA.channels[channel].iobase2);
99
100     // Reset
101
102     // 8.2.1 (a) -- set SRST in DC
103     outb(ATA_CB_DC_HD15 | ATA_CB_DC_NIEN | ATA_CB_DC_SRST, iobase2+ATA_CB_DC);
104
105     // 8.2.1 (b) -- wait for BSY
106     int status = await_ide(BSY, iobase1, 20);
107     dprintf(6, "ata_reset(1) status=%x\n", status);
108
109     // 8.2.1 (f) -- clear SRST
110     outb(ATA_CB_DC_HD15 | ATA_CB_DC_NIEN, iobase2+ATA_CB_DC);
111
112     // 8.2.1 (g) -- check for sc==sn==0x01
113     // select device
114     outb(slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0, iobase1+ATA_CB_DH);
115     mdelay(50);
116     u8 sc = inb(iobase1+ATA_CB_SC);
117     u8 sn = inb(iobase1+ATA_CB_SN);
118
119     // For predetermined ATA drives - wait for ready.
120     if (sc==0x01 && sn==0x01) {
121         u8 type=GET_GLOBAL(ATA.devices[driveid].type);
122         if (type == ATA_TYPE_ATA)
123             await_ide(NOT_BSY_RDY, iobase1, IDE_TIMEOUT);
124     }
125
126     // 8.2.1 (h) -- wait for not BSY
127     status = await_ide(NOT_BSY, iobase1, IDE_TIMEOUT);
128     dprintf(6, "ata_reset(2) status=%x\n", status);
129
130     // Enable interrupts
131     outb(ATA_CB_DC_HD15, iobase2+ATA_CB_DC);
132 }
133
134
135 /****************************************************************
136  * ATA send command
137  ****************************************************************/
138
139 struct ata_pio_command {
140     u8 feature;
141     u8 sector_count;
142     u8 lba_low;
143     u8 lba_mid;
144     u8 lba_high;
145     u8 device;
146     u8 command;
147
148     u8 sector_count2;
149     u8 lba_low2;
150     u8 lba_mid2;
151     u8 lba_high2;
152 };
153
154 // Send an ata command to the drive.
155 static int
156 send_cmd(int driveid, struct ata_pio_command *cmd)
157 {
158     u8 channel = driveid / 2;
159     u16 iobase1 = GET_GLOBAL(ATA.channels[channel].iobase1);
160     u16 iobase2 = GET_GLOBAL(ATA.channels[channel].iobase2);
161
162     int status = inb(iobase1 + ATA_CB_STAT);
163     if (status & ATA_CB_STAT_BSY)
164         return -3;
165
166     // Disable interrupts
167     outb(ATA_CB_DC_HD15 | ATA_CB_DC_NIEN, iobase2 + ATA_CB_DC);
168
169     // Select device
170     u8 device = inb(iobase1 + ATA_CB_DH);
171     outb(cmd->device, iobase1 + ATA_CB_DH);
172     if ((device ^ cmd->device) & (1 << 4))
173         // Wait for device to become active.
174         mdelay(50);
175
176     if (cmd->command & 0x04) {
177         outb(0x00, iobase1 + ATA_CB_FR);
178         outb(cmd->sector_count2, iobase1 + ATA_CB_SC);
179         outb(cmd->lba_low2, iobase1 + ATA_CB_SN);
180         outb(cmd->lba_mid2, iobase1 + ATA_CB_CL);
181         outb(cmd->lba_high2, iobase1 + ATA_CB_CH);
182     }
183     outb(cmd->feature, iobase1 + ATA_CB_FR);
184     outb(cmd->sector_count, iobase1 + ATA_CB_SC);
185     outb(cmd->lba_low, iobase1 + ATA_CB_SN);
186     outb(cmd->lba_mid, iobase1 + ATA_CB_CL);
187     outb(cmd->lba_high, iobase1 + ATA_CB_CH);
188     outb(cmd->command, iobase1 + ATA_CB_CMD);
189
190     status = ndelay_await_ide(NOT_BSY_DRQ, iobase1, IDE_TIMEOUT);
191     if (status < 0)
192         return status;
193
194     if (status & ATA_CB_STAT_ERR) {
195         dprintf(6, "send_cmd : read error\n");
196         return -4;
197     }
198     if (!(status & ATA_CB_STAT_DRQ)) {
199         dprintf(6, "send_cmd : DRQ not set (status %02x)\n"
200                 , (unsigned) status);
201         return -5;
202     }
203
204     return 0;
205 }
206
207
208 /****************************************************************
209  * ATA transfers
210  ****************************************************************/
211
212 // Read and discard x number of bytes from an io channel.
213 static void
214 insx_discard(int mode, int iobase1, int bytes)
215 {
216     int count, i;
217     if (mode == ATA_MODE_PIO32) {
218         count = bytes / 4;
219         for (i=0; i<count; i++)
220             inl(iobase1);
221     } else {
222         count = bytes / 2;
223         for (i=0; i<count; i++)
224             inw(iobase1);
225     }
226 }
227
228 // Transfer 'count' blocks (of 'blocksize' bytes) to/from drive
229 // 'driveid'.  If 'skipfirst' or 'skiplast' is set then the first
230 // and/or last block may be partially transferred.  This function is
231 // inlined because all the callers use different forms and because the
232 // large number of parameters would consume a lot of stack space.
233 static __always_inline int
234 ata_transfer(int driveid, int iswrite, int count, int blocksize
235              , int skipfirst, int skiplast, void *far_buffer)
236 {
237     dprintf(16, "ata_transfer id=%d write=%d count=%d bs=%d"
238             " skipf=%d skipl=%d buf=%p\n"
239             , driveid, iswrite, count, blocksize
240             , skipfirst, skiplast, far_buffer);
241
242     // Reset count of transferred data
243     SET_EBDA(sector_count, 0);
244
245     u8 channel  = driveid / 2;
246     u16 iobase1 = GET_GLOBAL(ATA.channels[channel].iobase1);
247     u16 iobase2 = GET_GLOBAL(ATA.channels[channel].iobase2);
248     u8 mode     = GET_GLOBAL(ATA.devices[driveid].mode);
249     int current = 0;
250     int status;
251     for (;;) {
252         int bsize = blocksize;
253         if (skipfirst && current == 0) {
254             insx_discard(mode, iobase1, skipfirst);
255             bsize -= skipfirst;
256         }
257         if (skiplast && current == count-1)
258             bsize -= skiplast;
259
260         if (iswrite) {
261             // Write data to controller
262             dprintf(16, "Write sector id=%d dest=%p\n", driveid, far_buffer);
263             if (mode == ATA_MODE_PIO32)
264                 outsl_far(iobase1, far_buffer, bsize / 4);
265             else
266                 outsw_far(iobase1, far_buffer, bsize / 2);
267         } else {
268             // Read data from controller
269             dprintf(16, "Read sector id=%d dest=%p\n", driveid, far_buffer);
270             if (mode == ATA_MODE_PIO32)
271                 insl_far(iobase1, far_buffer, bsize / 4);
272             else
273                 insw_far(iobase1, far_buffer, bsize / 2);
274         }
275         far_buffer += bsize;
276
277         if (skiplast && current == count-1)
278             insx_discard(mode, iobase1, skiplast);
279
280         status = pause_await_ide(NOT_BSY, iobase1, iobase2, IDE_TIMEOUT);
281         if (status < 0)
282             // Error
283             return status;
284
285         current++;
286         SET_EBDA(sector_count, current);
287         if (current == count)
288             break;
289         status &= (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ
290                    | ATA_CB_STAT_ERR);
291         if (status != (ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ)) {
292             dprintf(6, "ata_transfer : more sectors left (status %02x)\n"
293                     , (unsigned) status);
294             return -6;
295         }
296     }
297
298     status &= (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DF
299                | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR);
300     if (!iswrite)
301         status &= ~ATA_CB_STAT_DF;
302     if (status != ATA_CB_STAT_RDY ) {
303         dprintf(6, "ata_transfer : no sectors left (status %02x)\n"
304                 , (unsigned) status);
305         return -7;
306     }
307
308     // Enable interrupts
309     outb(ATA_CB_DC_HD15, iobase2+ATA_CB_DC);
310     return 0;
311 }
312
313 static noinline int
314 ata_transfer_disk(const struct disk_op_s *op)
315 {
316     return ata_transfer(op->driveid, op->command == ATA_CMD_WRITE_SECTORS
317                         , op->count, IDE_SECTOR_SIZE, 0, 0, op->far_buffer);
318 }
319
320 static noinline int
321 ata_transfer_cdrom(const struct disk_op_s *op)
322 {
323     return ata_transfer(op->driveid, 0, op->count, CDROM_SECTOR_SIZE
324                         , 0, 0, op->far_buffer);
325 }
326
327 static noinline int
328 ata_transfer_cdemu(const struct disk_op_s *op, int before, int after)
329 {
330     int vcount = op->count * 4 - before - after;
331     int ret = ata_transfer(op->driveid, 0, op->count, CDROM_SECTOR_SIZE
332                            , before*512, after*512, op->far_buffer);
333     if (ret) {
334         SET_EBDA(sector_count, 0);
335         return ret;
336     }
337     SET_EBDA(sector_count, vcount);
338     return 0;
339 }
340
341
342 /****************************************************************
343  * ATA hard drive functions
344  ****************************************************************/
345
346 static noinline int
347 send_cmd_disk(const struct disk_op_s *op)
348 {
349     u8 slave = op->driveid % 2;
350     u64 lba = op->lba;
351
352     struct ata_pio_command cmd;
353     memset(&cmd, 0, sizeof(cmd));
354
355     cmd.command = op->command;
356     if (op->count >= (1<<8) || lba + op->count >= (1<<28)) {
357         cmd.sector_count2 = op->count >> 8;
358         cmd.lba_low2 = lba >> 24;
359         cmd.lba_mid2 = lba >> 32;
360         cmd.lba_high2 = lba >> 40;
361
362         cmd.command |= 0x04;
363         lba &= 0xffffff;
364     }
365
366     cmd.feature = 0;
367     cmd.sector_count = op->count;
368     cmd.lba_low = lba;
369     cmd.lba_mid = lba >> 8;
370     cmd.lba_high = lba >> 16;
371     cmd.device = ((slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0)
372                   | ((lba >> 24) & 0xf) | ATA_CB_DH_LBA);
373
374     return send_cmd(op->driveid, &cmd);
375 }
376
377 // Read/write count blocks from a harddrive.
378 __always_inline int
379 ata_cmd_data(struct disk_op_s *op)
380 {
381     int ret = send_cmd_disk(op);
382     if (ret)
383         return ret;
384     return ata_transfer_disk(op);
385 }
386
387
388 /****************************************************************
389  * ATAPI functions
390  ****************************************************************/
391
392 // Low-level atapi command transmit function.
393 static __always_inline int
394 send_atapi_cmd(int driveid, u8 *cmdbuf, u8 cmdlen, u16 blocksize)
395 {
396     u8 channel = driveid / 2;
397     u8 slave = driveid % 2;
398     u16 iobase1 = GET_GLOBAL(ATA.channels[channel].iobase1);
399     u16 iobase2 = GET_GLOBAL(ATA.channels[channel].iobase2);
400
401     struct ata_pio_command cmd;
402     cmd.sector_count = 0;
403     cmd.feature = 0;
404     cmd.lba_low = 0;
405     cmd.lba_mid = blocksize;
406     cmd.lba_high = blocksize >> 8;
407     cmd.device = slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0;
408     cmd.command = ATA_CMD_PACKET;
409
410     int ret = send_cmd(driveid, &cmd);
411     if (ret)
412         return ret;
413
414     // Send command to device
415     outsw_far(iobase1, MAKE_FARPTR(GET_SEG(SS), (u32)cmdbuf), cmdlen / 2);
416
417     int status = pause_await_ide(NOT_BSY_DRQ, iobase1, iobase2, IDE_TIMEOUT);
418     if (status < 0)
419         return status;
420
421     return 0;
422 }
423
424 // Low-level cdrom read atapi command transmit function.
425 static int
426 send_cmd_cdrom(const struct disk_op_s *op)
427 {
428     u8 atacmd[12];
429     memset(atacmd, 0, sizeof(atacmd));
430
431     atacmd[0]=0x28;                         // READ command
432     atacmd[7]=(op->count & 0xff00) >> 8;    // Sectors
433     atacmd[8]=(op->count & 0x00ff);
434     atacmd[2]=(op->lba & 0xff000000) >> 24; // LBA
435     atacmd[3]=(op->lba & 0x00ff0000) >> 16;
436     atacmd[4]=(op->lba & 0x0000ff00) >> 8;
437     atacmd[5]=(op->lba & 0x000000ff);
438
439     return send_atapi_cmd(op->driveid, atacmd, sizeof(atacmd)
440                           , CDROM_SECTOR_SIZE);
441 }
442
443 // Read sectors from the cdrom.
444 __always_inline int
445 cdrom_read(struct disk_op_s *op)
446 {
447     int ret = send_cmd_cdrom(op);
448     if (ret)
449         return ret;
450
451     return ata_transfer_cdrom(op);
452 }
453
454 // Pretend the cdrom has 512 byte sectors (instead of 2048) and read
455 // sectors.
456 __always_inline int
457 cdrom_read_512(struct disk_op_s *op)
458 {
459     u32 vlba = op->lba;
460     u32 vcount = op->count;
461     u32 lba = op->lba = vlba / 4;
462     u32 velba = vlba + vcount - 1;
463     u32 elba = velba / 4;
464     op->count = elba - lba + 1;
465     int before = vlba % 4;
466     int after = 3 - (velba % 4);
467
468     dprintf(16, "cdrom_read_512: id=%d vlba=%d vcount=%d buf=%p lba=%d elba=%d"
469             " count=%d before=%d after=%d\n"
470             , op->driveid, vlba, vcount, op->far_buffer, lba, elba
471             , op->count, before, after);
472
473     int ret = send_cmd_cdrom(op);
474     if (ret)
475         return ret;
476
477     return ata_transfer_cdemu(op, before, after);
478 }
479
480 // Send a simple atapi command to a drive.
481 int
482 ata_cmd_packet(int driveid, u8 *cmdbuf, u8 cmdlen
483                , u32 length, void *far_buffer)
484 {
485     int ret = send_atapi_cmd(driveid, cmdbuf, cmdlen, length);
486     if (ret)
487         return ret;
488
489     return ata_transfer(driveid, 0, 1, length, 0, 0, far_buffer);
490 }
491
492
493 /****************************************************************
494  * ATA detect and init
495  ****************************************************************/
496
497 static void
498 report_model(int driveid, u8 *buffer)
499 {
500     u8 model[41];
501
502     // Read model name
503     int i;
504     for (i=0; i<40; i+=2) {
505         model[i] = buffer[i+54+1];
506         model[i+1] = buffer[i+54];
507     }
508
509     // Reformat
510     model[40] = 0x00;
511     for (i=39; i>0; i--) {
512         if (model[i] != 0x20)
513             break;
514         model[i] = 0x00;
515     }
516
517     u8 channel = driveid / 2;
518     u8 slave = driveid % 2;
519     // XXX - model on stack not %cs
520     printf("ata%d %s: %s", channel, slave ? " slave" : "master", model);
521 }
522
523 static u8
524 get_ata_version(u8 *buffer)
525 {
526     u16 ataversion = *(u16*)&buffer[160];
527     u8 version;
528     for (version=15; version>0; version--)
529         if (ataversion & (1<<version))
530             break;
531     return version;
532 }
533
534 static void
535 init_drive_atapi(int driveid)
536 {
537     SET_GLOBAL(ATA.devices[driveid].type, ATA_TYPE_ATAPI);
538
539     // Temporary values to do the transfer
540     SET_GLOBAL(ATA.devices[driveid].device,ATA_DEVICE_CDROM);
541     SET_GLOBAL(ATA.devices[driveid].mode, ATA_MODE_PIO16);
542
543     // Now we send a IDENTIFY command to ATAPI device
544     u8 buffer[0x0200];
545     memset(buffer, 0, sizeof(buffer));
546     struct disk_op_s dop;
547     dop.driveid = driveid;
548     dop.command = ATA_CMD_IDENTIFY_DEVICE_PACKET;
549     dop.count = 1;
550     dop.lba = 1;
551     dop.far_buffer = MAKE_FARPTR(GET_SEG(SS), (u32)buffer);
552     u16 ret = ata_cmd_data(&dop);
553     if (ret != 0)
554         BX_PANIC("ata-detect: Failed to detect ATAPI device\n");
555
556     u8 type      = buffer[1] & 0x1f;
557     u8 removable = (buffer[0] & 0x80) ? 1 : 0;
558     u8 mode      = buffer[96] ? ATA_MODE_PIO32 : ATA_MODE_PIO16;
559     u16 blksize  = CDROM_SECTOR_SIZE;
560
561     SET_GLOBAL(ATA.devices[driveid].device, type);
562     SET_GLOBAL(ATA.devices[driveid].removable, removable);
563     SET_GLOBAL(ATA.devices[driveid].mode, mode);
564     SET_GLOBAL(ATA.devices[driveid].blksize, blksize);
565
566     // fill cdidmap
567     u8 cdcount = GET_GLOBAL(ATA.cdcount);
568     SET_GLOBAL(ATA.idmap[1][cdcount], driveid);
569     SET_GLOBAL(ATA.cdcount, ++cdcount);
570
571     report_model(driveid, buffer);
572     u8 version = get_ata_version(buffer);
573     if (GET_GLOBAL(ATA.devices[driveid].device)==ATA_DEVICE_CDROM)
574         printf(" ATAPI-%d CD-Rom/DVD-Rom\n", version);
575     else
576         printf(" ATAPI-%d Device\n", version);
577 }
578
579 static void
580 fill_fdpt(int driveid)
581 {
582     if (driveid > 1)
583         return;
584
585     u16 nlc   = GET_GLOBAL(ATA.devices[driveid].lchs.cylinders);
586     u16 nlh   = GET_GLOBAL(ATA.devices[driveid].lchs.heads);
587     u16 nlspt = GET_GLOBAL(ATA.devices[driveid].lchs.spt);
588
589     u16 npc   = GET_GLOBAL(ATA.devices[driveid].pchs.cylinders);
590     u16 nph   = GET_GLOBAL(ATA.devices[driveid].pchs.heads);
591     u16 npspt = GET_GLOBAL(ATA.devices[driveid].pchs.spt);
592
593     struct extended_bios_data_area_s *ebda = get_ebda_ptr();
594     ebda->fdpt[driveid].precompensation = 0xffff;
595     ebda->fdpt[driveid].drive_control_byte = 0xc0 | ((nph > 8) << 3);
596     ebda->fdpt[driveid].landing_zone = npc;
597     ebda->fdpt[driveid].cylinders = nlc;
598     ebda->fdpt[driveid].heads = nlh;
599     ebda->fdpt[driveid].sectors = nlspt;
600
601     if (nlc == npc && nlh == nph && nlspt == npspt)
602         // no logical CHS mapping used, just physical CHS
603         // use Standard Fixed Disk Parameter Table (FDPT)
604         return;
605
606     // complies with Phoenix style Translated Fixed Disk Parameter
607     // Table (FDPT)
608     ebda->fdpt[driveid].phys_cylinders = npc;
609     ebda->fdpt[driveid].phys_heads = nph;
610     ebda->fdpt[driveid].phys_sectors = npspt;
611     ebda->fdpt[driveid].a0h_signature = 0xa0;
612
613     // Checksum structure.
614     u8 sum = checksum((u8*)&ebda->fdpt[driveid], sizeof(ebda->fdpt[driveid])-1);
615     ebda->fdpt[driveid].checksum = -sum;
616 }
617
618 static u8
619 get_translation(int driveid)
620 {
621     if (! CONFIG_COREBOOT) {
622         // Emulators pass in the translation info via nvram.
623         u8 channel = driveid / 2;
624         u8 translation = inb_cmos(CMOS_BIOS_DISKTRANSFLAG + channel/2);
625         translation >>= 2 * (driveid % 4);
626         translation &= 0x03;
627         return translation;
628     }
629
630     // On COREBOOT, use a heuristic to determine translation type.
631     u16 heads = GET_GLOBAL(ATA.devices[driveid].pchs.heads);
632     u16 cylinders = GET_GLOBAL(ATA.devices[driveid].pchs.cylinders);
633     u16 spt = GET_GLOBAL(ATA.devices[driveid].pchs.spt);
634
635     if (cylinders <= 1024 && heads <= 16 && spt <= 63)
636         return ATA_TRANSLATION_NONE;
637     if (cylinders * heads <= 131072)
638         return ATA_TRANSLATION_LARGE;
639     return ATA_TRANSLATION_LBA;
640 }
641
642 static void
643 setup_translation(int driveid)
644 {
645     u8 translation = get_translation(driveid);
646     SET_GLOBAL(ATA.devices[driveid].translation, translation);
647
648     u8 channel = driveid / 2;
649     u8 slave = driveid % 2;
650     u16 heads = GET_GLOBAL(ATA.devices[driveid].pchs.heads);
651     u16 cylinders = GET_GLOBAL(ATA.devices[driveid].pchs.cylinders);
652     u16 spt = GET_GLOBAL(ATA.devices[driveid].pchs.spt);
653     u64 sectors = GET_GLOBAL(ATA.devices[driveid].sectors);
654
655     dprintf(1, "ata%d-%d: PCHS=%u/%d/%d translation="
656             , channel, slave, cylinders, heads, spt);
657     switch (translation) {
658     case ATA_TRANSLATION_NONE:
659         dprintf(1, "none");
660         break;
661     case ATA_TRANSLATION_LBA:
662         dprintf(1, "lba");
663         spt = 63;
664         if (sectors > 63*255*1024) {
665             heads = 255;
666             cylinders = 1024;
667             break;
668         }
669         u32 sect = (u32)sectors / 63;
670         heads = sect / 1024;
671         if (heads>128)
672             heads = 255;
673         else if (heads>64)
674             heads = 128;
675         else if (heads>32)
676             heads = 64;
677         else if (heads>16)
678             heads = 32;
679         else
680             heads = 16;
681         cylinders = sect / heads;
682         break;
683     case ATA_TRANSLATION_RECHS:
684         dprintf(1, "r-echs");
685         // Take care not to overflow
686         if (heads==16) {
687             if (cylinders>61439)
688                 cylinders=61439;
689             heads=15;
690             cylinders = (u16)((u32)(cylinders)*16/15);
691         }
692         // then go through the large bitshift process
693     case ATA_TRANSLATION_LARGE:
694         if (translation == ATA_TRANSLATION_LARGE)
695             dprintf(1, "large");
696         while (cylinders > 1024) {
697             cylinders >>= 1;
698             heads <<= 1;
699
700             // If we max out the head count
701             if (heads > 127)
702                 break;
703         }
704         break;
705     }
706     // clip to 1024 cylinders in lchs
707     if (cylinders > 1024)
708         cylinders = 1024;
709     dprintf(1, " LCHS=%d/%d/%d\n", cylinders, heads, spt);
710
711     SET_GLOBAL(ATA.devices[driveid].lchs.heads, heads);
712     SET_GLOBAL(ATA.devices[driveid].lchs.cylinders, cylinders);
713     SET_GLOBAL(ATA.devices[driveid].lchs.spt, spt);
714 }
715
716 static void
717 init_drive_ata(int driveid)
718 {
719     SET_GLOBAL(ATA.devices[driveid].type, ATA_TYPE_ATA);
720
721     // Temporary values to do the transfer
722     SET_GLOBAL(ATA.devices[driveid].device, ATA_DEVICE_HD);
723     SET_GLOBAL(ATA.devices[driveid].mode, ATA_MODE_PIO16);
724
725     // Now we send a IDENTIFY command to ATA device
726     u8 buffer[0x0200];
727     memset(buffer, 0, sizeof(buffer));
728     struct disk_op_s dop;
729     dop.driveid = driveid;
730     dop.command = ATA_CMD_IDENTIFY_DEVICE;
731     dop.count = 1;
732     dop.lba = 1;
733     dop.far_buffer = MAKE_FARPTR(GET_SEG(SS), (u32)buffer);
734     u16 ret = ata_cmd_data(&dop);
735     if (ret)
736         BX_PANIC("ata-detect: Failed to detect ATA device\n");
737
738     u8 removable  = (buffer[0] & 0x80) ? 1 : 0;
739     u8 mode       = buffer[48*2] ? ATA_MODE_PIO32 : ATA_MODE_PIO16;
740     u16 blksize   = IDE_SECTOR_SIZE;
741
742     u16 cylinders = *(u16*)&buffer[1*2]; // word 1
743     u16 heads     = *(u16*)&buffer[3*2]; // word 3
744     u16 spt       = *(u16*)&buffer[6*2]; // word 6
745
746     u64 sectors;
747     if (*(u16*)&buffer[83*2] & (1 << 10)) // word 83 - lba48 support
748         sectors = *(u64*)&buffer[100*2]; // word 100-103
749     else
750         sectors = *(u32*)&buffer[60*2]; // word 60 and word 61
751
752     SET_GLOBAL(ATA.devices[driveid].device, ATA_DEVICE_HD);
753     SET_GLOBAL(ATA.devices[driveid].removable, removable);
754     SET_GLOBAL(ATA.devices[driveid].mode, mode);
755     SET_GLOBAL(ATA.devices[driveid].blksize, blksize);
756     SET_GLOBAL(ATA.devices[driveid].pchs.heads, heads);
757     SET_GLOBAL(ATA.devices[driveid].pchs.cylinders, cylinders);
758     SET_GLOBAL(ATA.devices[driveid].pchs.spt, spt);
759     SET_GLOBAL(ATA.devices[driveid].sectors, sectors);
760
761     // Setup disk geometry translation.
762     setup_translation(driveid);
763
764     // fill hdidmap
765     u8 hdcount = GET_BDA(hdcount);
766     SET_GLOBAL(ATA.idmap[0][hdcount], driveid);
767     SET_BDA(hdcount, ++hdcount);
768
769     // Fill "fdpt" structure.
770     fill_fdpt(driveid);
771
772     // Report drive info to user.
773     u64 sizeinmb = GET_GLOBAL(ATA.devices[driveid].sectors) >> 11;
774     report_model(driveid, buffer);
775     u8 version = get_ata_version(buffer);
776     if (sizeinmb < (1 << 16))
777         printf(" ATA-%d Hard-Disk (%u MiBytes)\n", version, (u32)sizeinmb);
778     else
779         printf(" ATA-%d Hard-Disk (%u GiBytes)\n", version
780                , (u32)(sizeinmb >> 10));
781 }
782
783 static void
784 init_drive_unknown(int driveid)
785 {
786     SET_GLOBAL(ATA.devices[driveid].type, ATA_TYPE_UNKNOWN);
787
788     u8 channel = driveid / 2;
789     u8 slave = driveid % 2;
790     printf("ata%d %s: Unknown device\n", channel, slave ? " slave" : "master");
791 }
792
793 static void
794 ata_detect()
795 {
796     // Device detection
797     int driveid;
798     for(driveid=0; driveid<CONFIG_MAX_ATA_DEVICES; driveid++) {
799         u8 channel = driveid / 2;
800         u8 slave = driveid % 2;
801
802         u16 iobase1 = GET_GLOBAL(ATA.channels[channel].iobase1);
803         u16 iobase2 = GET_GLOBAL(ATA.channels[channel].iobase2);
804         if (!iobase1)
805             break;
806
807         // Disable interrupts
808         outb(ATA_CB_DC_HD15 | ATA_CB_DC_NIEN, iobase2+ATA_CB_DC);
809
810         // Look for device
811         outb(slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0, iobase1+ATA_CB_DH);
812         mdelay(50);
813         outb(0x55, iobase1+ATA_CB_SC);
814         outb(0xaa, iobase1+ATA_CB_SN);
815         outb(0xaa, iobase1+ATA_CB_SC);
816         outb(0x55, iobase1+ATA_CB_SN);
817         outb(0x55, iobase1+ATA_CB_SC);
818         outb(0xaa, iobase1+ATA_CB_SN);
819
820         // If we found something
821         u8 sc = inb(iobase1+ATA_CB_SC);
822         u8 sn = inb(iobase1+ATA_CB_SN);
823         dprintf(6, "ata_detect(1) drive=%d sc=%x sn=%x\n", driveid, sc, sn);
824
825         if (sc != 0x55 || sn != 0xaa)
826             continue;
827
828         // reset the channel
829         ata_reset(driveid);
830
831         // check for ATA or ATAPI
832         outb(slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0, iobase1+ATA_CB_DH);
833         mdelay(50);
834         sc = inb(iobase1+ATA_CB_SC);
835         sn = inb(iobase1+ATA_CB_SN);
836         dprintf(6, "ata_detect(2) drive=%d sc=%x sn=%x\n", driveid, sc, sn);
837         if (sc!=0x01 || sn!=0x01) {
838             init_drive_unknown(driveid);
839             continue;
840         }
841         u8 cl = inb(iobase1+ATA_CB_CL);
842         u8 ch = inb(iobase1+ATA_CB_CH);
843         u8 st = inb(iobase1+ATA_CB_STAT);
844         dprintf(6, "ata_detect(3) drive=%d sc=%x sn=%x cl=%x ch=%x st=%x\n"
845                 , driveid, sc, sn, cl, ch, st);
846
847         if (cl==0x14 && ch==0xeb)
848             init_drive_atapi(driveid);
849         else if (cl==0x00 && ch==0x00 && st!=0x00)
850             init_drive_ata(driveid);
851         else if (cl==0xff && ch==0xff)
852             // None
853             continue;
854         else
855             init_drive_unknown(driveid);
856     }
857
858     printf("\n");
859 }
860
861 static void
862 ata_init()
863 {
864     // hdidmap and cdidmap init.
865     u8 device;
866     for (device=0; device < CONFIG_MAX_ATA_DEVICES; device++) {
867         SET_GLOBAL(ATA.idmap[0][device], CONFIG_MAX_ATA_DEVICES);
868         SET_GLOBAL(ATA.idmap[1][device], CONFIG_MAX_ATA_DEVICES);
869     }
870
871     // Scan PCI bus for ATA adapters
872     int count=0;
873     int bdf, max;
874     foreachpci(bdf, max) {
875         if (pci_config_readw(bdf, PCI_CLASS_DEVICE) != PCI_CLASS_STORAGE_IDE)
876             continue;
877
878         u8 irq = pci_config_readb(bdf, PCI_INTERRUPT_LINE);
879         SET_GLOBAL(ATA.channels[count].irq, irq);
880         SET_GLOBAL(ATA.channels[count].pci_bdf, bdf);
881
882         u8 prog_if = pci_config_readb(bdf, PCI_CLASS_PROG);
883         u32 port1, port2;
884
885         if (prog_if & 1) {
886             port1 = pci_config_readl(bdf, PCI_BASE_ADDRESS_0) & ~3;
887             port2 = pci_config_readl(bdf, PCI_BASE_ADDRESS_1) & ~3;
888         } else {
889             port1 = 0x1f0;
890             port2 = 0x3f0;
891         }
892         SET_GLOBAL(ATA.channels[count].iobase1, port1);
893         SET_GLOBAL(ATA.channels[count].iobase2, port2);
894         dprintf(1, "ATA controller %d at %x/%x (dev %x prog_if %x)\n"
895                 , count, port1, port2, bdf, prog_if);
896         count++;
897
898         if (prog_if & 4) {
899             port1 = pci_config_readl(bdf, PCI_BASE_ADDRESS_2) & ~3;
900             port2 = pci_config_readl(bdf, PCI_BASE_ADDRESS_3) & ~3;
901         } else {
902             port1 = 0x170;
903             port2 = 0x370;
904         }
905         dprintf(1, "ATA controller %d at %x/%x (dev %x prog_if %x)\n"
906                 , count, port1, port2, bdf, prog_if);
907         SET_GLOBAL(ATA.channels[count].iobase1, port1);
908         SET_GLOBAL(ATA.channels[count].iobase2, port2);
909         count++;
910     }
911 }
912
913 void
914 hard_drive_setup()
915 {
916     if (!CONFIG_ATA)
917         return;
918
919     dprintf(3, "init hard drives\n");
920     ata_init();
921     ata_detect();
922
923     SET_BDA(disk_control_byte, 0xc0);
924
925     enable_hwirq(14, entry_76);
926 }