1 /* ata.c - ATA disk access. */
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2007 Free Software Foundation, Inc.
6 * GRUB is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GRUB is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
21 #include <grub/misc.h>
22 #include <grub/disk.h>
24 #include <grub/time.h>
25 /* XXX: For now this only works on i386. */
26 #include <grub/cpu/io.h>
33 } grub_ata_addressing_t
;
35 /* At the moment, only two IDE ports are supported. */
36 static const int grub_ata_ioaddress
[] = { 0x1f0, 0x170 };
37 static const int grub_ata_ioaddress2
[] = { 0x3f6, 0x376 };
39 #define GRUB_CDROM_SECTOR_SIZE 2048
41 #define GRUB_ATA_REG_DATA 0
42 #define GRUB_ATA_REG_ERROR 1
43 #define GRUB_ATA_REG_FEATURES 1
44 #define GRUB_ATA_REG_SECTORS 2
45 #define GRUB_ATA_REG_SECTNUM 3
46 #define GRUB_ATA_REG_CYLLSB 4
47 #define GRUB_ATA_REG_CYLMSB 5
48 #define GRUB_ATA_REG_LBALOW 3
49 #define GRUB_ATA_REG_LBAMID 4
50 #define GRUB_ATA_REG_LBAHIGH 5
51 #define GRUB_ATA_REG_DISK 6
52 #define GRUB_ATA_REG_CMD 7
53 #define GRUB_ATA_REG_STATUS 7
55 #define GRUB_ATA_REG2_CONTROL 0
57 enum grub_ata_commands
59 GRUB_ATA_CMD_READ_SECTORS
= 0x20,
60 GRUB_ATA_CMD_READ_SECTORS_EXT
= 0x24,
61 GRUB_ATA_CMD_WRITE_SECTORS
= 0x30,
62 GRUB_ATA_CMD_WRITE_SECTORS_EXT
= 0x34,
63 GRUB_ATA_CMD_IDENTIFY_DEVICE
= 0xEC,
64 GRUB_ATA_CMD_IDENTIFY_PACKET_DEVICE
= 0xA1,
65 GRUB_ATA_CMD_PACKET
= 0xA0
68 struct grub_ata_device
70 /* IDE port to use. */
73 /* IO addresses on which the registers for this device can be
78 /* Two devices can be connected to a single cable. Use this field
79 to select device 0 (commonly known as "master") or device 1
80 (commonly known as "slave"). */
83 /* Addressing methods available for accessing this device. If CHS
84 is only available, use that. Otherwise use LBA, except for the
85 high sectors. In that case use LBA48. */
86 grub_ata_addressing_t addr
;
92 grub_uint16_t cylinders
;
94 grub_uint16_t sectors_per_track
;
96 /* Set to 0 for ATA, set to 1 for ATAPI. */
99 struct grub_ata_device
*next
;
102 static struct grub_ata_device
*grub_ata_devices
;
105 grub_ata_regset (struct grub_ata_device
*dev
, int reg
, int val
)
107 grub_outb (val
, dev
->ioaddress
+ reg
);
111 grub_ata_regget (struct grub_ata_device
*dev
, int reg
)
113 return grub_inb (dev
->ioaddress
+ reg
);
117 grub_ata_regset2 (struct grub_ata_device
*dev
, int reg
, int val
)
119 grub_outb (val
, dev
->ioaddress2
+ reg
);
123 grub_ata_regget2 (struct grub_ata_device
*dev
, int reg
)
125 return grub_inb (dev
->ioaddress2
+ reg
);
128 /* Wait until the device DEV has the status set to ready. */
130 grub_ata_wait_busy (struct grub_ata_device
*dev
)
132 while ((grub_ata_regget (dev
, GRUB_ATA_REG_STATUS
) & 0x80));
136 grub_ata_wait_drq (struct grub_ata_device
*dev
)
138 while (! (grub_ata_regget (dev
, GRUB_ATA_REG_STATUS
) & 0x08));
144 grub_millisleep (50);
147 /* Byteorder has to be changed before strings can be read. */
149 grub_ata_strncpy (char *dst
, char *src
, grub_size_t len
)
151 grub_uint16_t
*src16
= (grub_uint16_t
*) src
;
152 grub_uint16_t
*dst16
= (grub_uint16_t
*) dst
;
155 for (i
= 0; i
< len
/ 2; i
++)
156 *(dst16
++) = grub_be_to_cpu16(*(src16
++));
161 grub_ata_pio_read (struct grub_ata_device
*dev
, char *buf
,
164 grub_uint16_t
*buf16
= (grub_uint16_t
*) buf
;
167 if (grub_ata_regget (dev
, GRUB_ATA_REG_STATUS
) & 1)
168 return grub_ata_regget (dev
, GRUB_ATA_REG_ERROR
);
170 /* Wait until the data is available. */
171 grub_ata_wait_drq (dev
);
173 /* Read in the data, word by word. */
174 for (i
= 0; i
< size
/ 2; i
++)
175 buf16
[i
] = grub_le_to_cpu16 (grub_inw(dev
->ioaddress
+ GRUB_ATA_REG_DATA
));
177 if (grub_ata_regget (dev
, GRUB_ATA_REG_STATUS
) & 1)
178 return grub_ata_regget (dev
, GRUB_ATA_REG_ERROR
);
184 grub_ata_pio_write (struct grub_ata_device
*dev
, char *buf
,
187 grub_uint16_t
*buf16
= (grub_uint16_t
*) buf
;
190 /* Wait until the device is ready to write. */
191 grub_ata_wait_drq (dev
);
193 /* Write the data, word by word. */
194 for (i
= 0; i
< size
/ 2; i
++)
195 grub_outw(grub_cpu_to_le16 (buf16
[i
]), dev
->ioaddress
+ GRUB_ATA_REG_DATA
);
197 if (grub_ata_regget (dev
, GRUB_ATA_REG_STATUS
) & 1)
198 return grub_ata_regget (dev
, GRUB_ATA_REG_ERROR
);
204 grub_ata_dumpinfo (struct grub_ata_device
*dev
, char *info
)
208 /* The device information was read, dump it for debugging. */
209 grub_ata_strncpy (text
, info
+ 20, 20);
210 grub_printf ("Serial: %s\n", text
);
211 grub_ata_strncpy (text
, info
+ 46, 8);
212 grub_printf ("Firmware: %s\n", text
);
213 grub_ata_strncpy (text
, info
+ 54, 40);
214 grub_printf ("Model: %s\n", text
);
216 grub_printf ("Addressing: %d\n", dev
->addr
);
217 grub_printf ("#sectors: %d\n", dev
->size
);
222 grub_atapi_identify (struct grub_ata_device
*dev
)
226 info
= grub_malloc (256);
230 grub_ata_wait_busy (dev
);
232 grub_ata_regset (dev
, GRUB_ATA_REG_DISK
, 0xE0 | dev
->device
<< 4);
233 grub_ata_regset (dev
, GRUB_ATA_REG_CMD
,
234 GRUB_ATA_CMD_IDENTIFY_PACKET_DEVICE
);
237 grub_ata_pio_read (dev
, info
, 256);
241 grub_ata_dumpinfo (dev
, info
);
249 grub_atapi_packet (struct grub_ata_device
*dev
, char *packet
)
251 grub_ata_regset (dev
, GRUB_ATA_REG_DISK
, dev
->device
<< 4);
252 grub_ata_regset (dev
, GRUB_ATA_REG_FEATURES
, 0);
253 grub_ata_regset (dev
, GRUB_ATA_REG_SECTORS
, 0);
254 grub_ata_regset (dev
, GRUB_ATA_REG_LBAHIGH
, 0xFF);
255 grub_ata_regset (dev
, GRUB_ATA_REG_LBAMID
, 0xFF);
256 grub_ata_regset (dev
, GRUB_ATA_REG_CMD
, GRUB_ATA_CMD_PACKET
);
259 grub_ata_pio_write (dev
, packet
, 12);
265 grub_ata_identify (struct grub_ata_device
*dev
)
268 grub_uint16_t
*info16
;
271 info
= grub_malloc (GRUB_DISK_SECTOR_SIZE
);
275 info16
= (grub_uint16_t
*) info
;
277 grub_ata_wait_busy (dev
);
279 grub_ata_regset (dev
, GRUB_ATA_REG_DISK
, 0xE0 | dev
->device
<< 4);
280 grub_ata_regset (dev
, GRUB_ATA_REG_CMD
, GRUB_ATA_CMD_IDENTIFY_DEVICE
);
283 ataerr
= grub_ata_pio_read (dev
, info
, GRUB_DISK_SECTOR_SIZE
);
286 /* ATAPI device detected. */
288 return grub_atapi_identify (dev
);
294 return grub_error (GRUB_ERR_UNKNOWN_DEVICE
,
295 "device can not be identified");
298 /* Now it is certain that this is not an ATAPI device. */
301 /* CHS is always supported. */
302 dev
->addr
= GRUB_ATA_CHS
;
304 /* Check if LBA is supported. */
305 if (info16
[49] & (1 << 9))
307 /* Check if LBA48 is supported. */
308 if (info16
[83] & (1 << 10))
309 dev
->addr
= GRUB_ATA_LBA48
;
311 dev
->addr
= GRUB_ATA_LBA
;
314 /* Determine the amount of sectors. */
315 if (dev
->addr
!= GRUB_ATA_LBA48
)
316 dev
->size
= grub_le_to_cpu32(*((grub_uint32_t
*) &info16
[60]));
318 dev
->size
= grub_le_to_cpu64(*((grub_uint32_t
*) &info16
[100]));
320 /* Read CHS information. */
321 dev
->cylinders
= info16
[1];
322 dev
->heads
= info16
[3];
323 dev
->sectors_per_track
= info16
[6];
325 grub_ata_dumpinfo (dev
, info
);
333 grub_ata_initialize (void)
335 struct grub_ata_device
*dev
;
336 struct grub_ata_device
**devp
;
340 for (port
= 0; port
<= 1; port
++)
342 for (device
= 0; device
<= 1; device
++)
344 dev
= grub_malloc (sizeof(*dev
));
348 /* Setup the device information. */
350 dev
->device
= device
;
351 dev
->ioaddress
= grub_ata_ioaddress
[dev
->port
];
352 dev
->ioaddress2
= grub_ata_ioaddress2
[dev
->port
];
355 /* Try to detect if the port is in use by writing to it,
356 waiting for a while and reading it again. If the value
357 was preserved, there is a device connected. */
358 grub_ata_regset (dev
, GRUB_ATA_REG_DISK
, dev
->device
<< 4);
360 grub_ata_regset (dev
, GRUB_ATA_REG_SECTORS
, 0x5A);
362 if (grub_ata_regget (dev
, GRUB_ATA_REG_SECTORS
) != 0x5A)
368 /* Detect if the device is present by issuing a reset. */
369 grub_ata_regset2 (dev
, GRUB_ATA_REG2_CONTROL
, 6);
371 grub_ata_regset2 (dev
, GRUB_ATA_REG2_CONTROL
, 2);
373 grub_ata_regset (dev
, GRUB_ATA_REG_DISK
, dev
->device
<< 4);
376 /* XXX: Check some registers to see if the reset worked as
377 expected for this device. */
379 /* Enable for ATAPI . */
380 if (grub_ata_regget (dev
, GRUB_ATA_REG_CYLLSB
) != 0x14
381 || grub_ata_regget (dev
, GRUB_ATA_REG_CYLMSB
) != 0xeb)
383 if (grub_ata_regget (dev
, GRUB_ATA_REG_STATUS
) == 0
384 || (grub_ata_regget (dev
, GRUB_ATA_REG_CYLLSB
) != 0
385 && grub_ata_regget (dev
, GRUB_ATA_REG_CYLMSB
) != 0
386 && grub_ata_regget (dev
, GRUB_ATA_REG_CYLLSB
) != 0x3c
387 && grub_ata_regget (dev
, GRUB_ATA_REG_CYLLSB
) != 0xc3))
393 /* Use the IDENTIFY DEVICE command to query the device. */
394 if (grub_ata_identify (dev
))
400 /* Register the device. */
401 for (devp
= &grub_ata_devices
; *devp
; devp
= &(*devp
)->next
);
410 grub_ata_setlba (struct grub_ata_device
*dev
, grub_disk_addr_t sector
,
413 grub_ata_regset (dev
, GRUB_ATA_REG_SECTORS
, size
);
414 grub_ata_regset (dev
, GRUB_ATA_REG_LBALOW
, sector
& 0xFF);
415 grub_ata_regset (dev
, GRUB_ATA_REG_LBAMID
, (sector
>> 8) & 0xFF);
416 grub_ata_regset (dev
, GRUB_ATA_REG_LBAHIGH
, (sector
>> 16) & 0xFF);
420 grub_ata_setaddress (struct grub_ata_device
*dev
,
421 grub_ata_addressing_t addressing
,
422 grub_disk_addr_t sector
,
425 grub_ata_wait_busy (dev
);
431 unsigned int cylinder
;
435 /* Calculate the sector, cylinder and head to use. */
436 sect
= ((grub_uint32_t
) sector
% dev
->sectors_per_track
) + 1;
437 cylinder
= (((grub_uint32_t
) sector
/ dev
->sectors_per_track
)
439 head
= ((grub_uint32_t
) sector
/ dev
->sectors_per_track
) % dev
->heads
;
441 if (sect
> dev
->sectors_per_track
442 || cylinder
> dev
->cylinders
443 || head
> dev
->heads
)
444 return grub_error (GRUB_ERR_OUT_OF_RANGE
,
445 "sector %d can not be addressed "
446 "using CHS addressing", sector
);
448 grub_ata_regset (dev
, GRUB_ATA_REG_SECTNUM
, sect
);
449 grub_ata_regset (dev
, GRUB_ATA_REG_CYLLSB
, cylinder
& 0xFF);
450 grub_ata_regset (dev
, GRUB_ATA_REG_CYLMSB
, cylinder
>> 8);
451 grub_ata_regset (dev
, GRUB_ATA_REG_DISK
, (dev
->device
<< 4) | head
);
459 grub_ata_setlba (dev
, sector
, size
);
460 grub_ata_regset (dev
, GRUB_ATA_REG_DISK
,
461 0xE0 | (dev
->device
<< 4) | ((sector
>> 24) & 0x0F));
468 /* Set "Previous". */
469 grub_ata_setlba (dev
, sector
>> 24, size
>> 8);
471 grub_ata_setlba (dev
, sector
, size
);
472 grub_ata_regset (dev
, GRUB_ATA_REG_DISK
, 0xE0 | (dev
->device
<< 4));
477 return GRUB_ERR_NONE
;
481 grub_ata_readwrite (grub_disk_t disk
, grub_disk_addr_t sector
,
482 grub_size_t size
, char *buf
, int rw
)
484 struct grub_ata_device
*dev
= (struct grub_ata_device
*) disk
->data
;
487 grub_ata_addressing_t addressing
;
492 addressing
= dev
->addr
;
494 if (addressing
== GRUB_ATA_LBA48
&& ((sector
+ size
) >> 28) != 0)
497 cmd
= GRUB_ATA_CMD_READ_SECTORS_EXT
;
498 cmd_write
= GRUB_ATA_CMD_WRITE_SECTORS_EXT
;
502 if (addressing
== GRUB_ATA_LBA48
)
503 addressing
= GRUB_ATA_LBA
;
505 cmd
= GRUB_ATA_CMD_READ_SECTORS
;
506 cmd_write
= GRUB_ATA_CMD_WRITE_SECTORS
;
511 /* Read/write batches of 256/65536 sectors, when more than 256/65536
512 sectors should be read/written. */
515 if (grub_ata_setaddress (dev
, addressing
, sector
, batch
))
520 /* Read 256/65536 sectors. */
521 grub_ata_regset (dev
, GRUB_ATA_REG_CMD
, cmd
);
523 for (sect
= 0; sect
< batch
; sect
++)
525 if (grub_ata_pio_read (dev
, buf
,
526 GRUB_DISK_SECTOR_SIZE
))
527 return grub_error (GRUB_ERR_READ_ERROR
, "ATA read error");
528 buf
+= GRUB_DISK_SECTOR_SIZE
;
534 /* Write 256/65536 sectors. */
535 grub_ata_regset (dev
, GRUB_ATA_REG_CMD
, cmd_write
);
537 for (sect
= 0; sect
< batch
; sect
++)
539 if (grub_ata_pio_write (dev
, buf
,
540 GRUB_DISK_SECTOR_SIZE
))
541 return grub_error (GRUB_ERR_WRITE_ERROR
, "ATA write error");
542 buf
+= GRUB_DISK_SECTOR_SIZE
;
548 /* Read/write just a "few" sectors. */
549 if (grub_ata_setaddress (dev
, addressing
, sector
, size
% batch
))
555 grub_ata_regset (dev
, GRUB_ATA_REG_CMD
, cmd
);
557 for (sect
= 0; sect
< (size
% batch
); sect
++)
559 if (grub_ata_pio_read (dev
, buf
, GRUB_DISK_SECTOR_SIZE
))
560 return grub_error (GRUB_ERR_READ_ERROR
, "ATA read error");
561 buf
+= GRUB_DISK_SECTOR_SIZE
;
565 grub_ata_regset (dev
, GRUB_ATA_REG_CMD
, cmd_write
);
567 for (sect
= 0; sect
< batch
; sect
++)
569 if (grub_ata_pio_write (dev
, buf
,
570 (size
% batch
) * GRUB_DISK_SECTOR_SIZE
))
571 return grub_error (GRUB_ERR_WRITE_ERROR
, "ATA write error");
572 buf
+= GRUB_DISK_SECTOR_SIZE
;
576 return GRUB_ERR_NONE
;
582 grub_ata_iterate (int (*hook
) (const char *name
))
584 struct grub_ata_device
*dev
;
586 for (dev
= grub_ata_devices
; dev
; dev
= dev
->next
)
589 grub_sprintf (devname
, "ata%d", dev
->port
* 2 + dev
->device
);
599 grub_ata_open (const char *name
, grub_disk_t disk
)
601 struct grub_ata_device
*dev
;
603 for (dev
= grub_ata_devices
; dev
; dev
= dev
->next
)
606 grub_sprintf (devname
, "ata%d", dev
->port
* 2 + dev
->device
);
607 if (grub_strcmp (name
, devname
) == 0)
612 return grub_error (GRUB_ERR_UNKNOWN_DEVICE
, "Can't open device");
615 disk
->total_sectors
= 9000000; /* XXX */
617 disk
->total_sectors
= dev
->size
;
619 disk
->id
= (int) dev
;
621 disk
->has_partitions
= !dev
->atapi
;
628 grub_ata_close (grub_disk_t disk
__attribute__((unused
)))
633 struct grub_atapi_read
636 grub_uint8_t reserved1
;
638 grub_uint32_t length
;
639 grub_uint8_t reserved2
[2];
640 } __attribute__((packed
));
643 grub_atapi_readsector (struct grub_ata_device
*dev
,
644 char *buf
, grub_disk_addr_t sector
)
646 struct grub_atapi_read readcmd
;
649 readcmd
.lba
= grub_cpu_to_be32 (sector
);
650 readcmd
.length
= grub_cpu_to_be32 (1);
652 grub_atapi_packet (dev
, (char *) &readcmd
);
654 grub_ata_pio_read (dev
, buf
, GRUB_CDROM_SECTOR_SIZE
);
660 grub_ata_read (grub_disk_t disk
, grub_disk_addr_t sector
,
661 grub_size_t size
, char *buf
)
663 struct grub_ata_device
*dev
= (struct grub_ata_device
*) disk
->data
;
668 return grub_ata_readwrite (disk
, sector
, size
, buf
, 0);
670 /* ATAPI is being used, so try to read from CDROM using ATAPI. */
672 sbuf
= grub_malloc (GRUB_CDROM_SECTOR_SIZE
);
676 /* CDROMs have sectors of 2048 bytes, so chop them into pieces of
684 cdsector
= sector
>> 2;
685 rsize
= ((size
* GRUB_DISK_SECTOR_SIZE
> GRUB_CDROM_SECTOR_SIZE
)
686 ? GRUB_CDROM_SECTOR_SIZE
: size
* GRUB_DISK_SECTOR_SIZE
);
687 offset
= (sector
& 3) * GRUB_DISK_SECTOR_SIZE
;
688 max
= GRUB_CDROM_SECTOR_SIZE
- offset
;
689 rsize
= (rsize
> max
) ? max
: rsize
;
691 grub_atapi_readsector (dev
, sbuf
, cdsector
);
692 grub_memcpy (buf
+ offset
, sbuf
, rsize
);
695 size
-= rsize
/ GRUB_DISK_SECTOR_SIZE
;
696 sector
+= rsize
/ GRUB_DISK_SECTOR_SIZE
;
705 grub_ata_write (grub_disk_t disk
,
706 grub_disk_addr_t sector
,
711 return GRUB_ERR_NOT_IMPLEMENTED_YET
;
713 return grub_ata_readwrite (disk
, sector
, size
, (char *) buf
, 1);
717 static struct grub_disk_dev grub_atadisk_dev
=
720 .id
= GRUB_DISK_DEVICE_ATA_ID
,
721 .iterate
= grub_ata_iterate
,
722 .open
= grub_ata_open
,
723 .close
= grub_ata_close
,
724 .read
= grub_ata_read
,
725 .write
= grub_ata_write
,
733 (void) mod
; /* To stop warning. */
735 /* To prevent two drivers operating on the same disks. */
736 grub_disk_firmware_is_tainted
= 1;
737 if (grub_disk_firmware_fini
)
739 grub_disk_firmware_fini ();
740 grub_disk_firmware_fini
= NULL
;
743 /* ATA initialization. */
744 grub_ata_initialize ();
746 grub_disk_dev_register (&grub_atadisk_dev
);
751 grub_disk_dev_unregister (&grub_atadisk_dev
);