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
/* XXX: For now this only works on i386. */
25
#include <grub/cpu/io.h>
26
#include <grub/machine/time.h>
27
#include <grub/machine/biosdisk.h>
34
} grub_ata_addressing_t;
36
/* At the moment, only two IDE ports are supported. */
37
static const int grub_ata_ioaddress[] = { 0x1f0, 0x170 };
38
static const int grub_ata_ioaddress2[] = { 0x3f6, 0x376 };
40
#define GRUB_CDROM_SECTOR_SIZE 2048
42
#define GRUB_ATA_REG_DATA 0
43
#define GRUB_ATA_REG_ERROR 1
44
#define GRUB_ATA_REG_FEATURES 1
45
#define GRUB_ATA_REG_SECTORS 2
46
#define GRUB_ATA_REG_SECTNUM 3
47
#define GRUB_ATA_REG_CYLLSB 4
48
#define GRUB_ATA_REG_CYLMSB 5
49
#define GRUB_ATA_REG_LBALOW 3
50
#define GRUB_ATA_REG_LBAMID 4
51
#define GRUB_ATA_REG_LBAHIGH 5
52
#define GRUB_ATA_REG_DISK 6
53
#define GRUB_ATA_REG_CMD 7
54
#define GRUB_ATA_REG_STATUS 7
56
#define GRUB_ATA_REG2_CONTROL 0
58
enum grub_ata_commands
60
GRUB_ATA_CMD_READ_SECTORS = 0x20,
61
GRUB_ATA_CMD_READ_SECTORS_EXT = 0x24,
62
GRUB_ATA_CMD_WRITE_SECTORS = 0x30,
63
GRUB_ATA_CMD_WRITE_SECTORS_EXT = 0x34,
64
GRUB_ATA_CMD_IDENTIFY_DEVICE = 0xEC,
65
GRUB_ATA_CMD_IDENTIFY_PACKET_DEVICE = 0xA1,
66
GRUB_ATA_CMD_PACKET = 0xA0
69
struct grub_ata_device
71
/* IDE port to use. */
74
/* IO addresses on which the registers for this device can be
79
/* Two devices can be connected to a single cable. Use this field
80
to select device 0 (commonly known as "master") or device 1
81
(commonly known as "slave"). */
84
/* Addressing methods available for accessing this device. If CHS
85
is only available, use that. Otherwise use LBA, except for the
86
high sectors. In that case use LBA48. */
87
grub_ata_addressing_t addr;
93
grub_uint16_t cylinders;
95
grub_uint16_t sectors_per_track;
97
/* Set to 0 for ATA, set to 1 for ATAPI. */
100
struct grub_ata_device *next;
103
static struct grub_ata_device *grub_ata_devices;
106
grub_ata_regset (struct grub_ata_device *dev, int reg, int val)
108
grub_outb (val, dev->ioaddress + reg);
112
grub_ata_regget (struct grub_ata_device *dev, int reg)
114
return grub_inb (dev->ioaddress + reg);
118
grub_ata_regset2 (struct grub_ata_device *dev, int reg, int val)
120
grub_outb (val, dev->ioaddress2 + reg);
124
grub_ata_regget2 (struct grub_ata_device *dev, int reg)
126
return grub_inb (dev->ioaddress2 + reg);
129
/* Wait until the device DEV has the status set to ready. */
131
grub_ata_wait_busy (struct grub_ata_device *dev)
133
while ((grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & 0x80));
137
grub_ata_wait_drq (struct grub_ata_device *dev)
139
while (! (grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & 0x08));
146
time = grub_get_rtc ();
148
while (time + 1 > grub_get_rtc ());
151
/* Byteorder has to be changed before strings can be read. */
153
grub_ata_strncpy (char *dst, char *src, grub_size_t len)
155
grub_uint16_t *src16 = (grub_uint16_t *) src;
156
grub_uint16_t *dst16 = (grub_uint16_t *) dst;
159
for (i = 0; i < len / 2; i++)
160
*(dst16++) = grub_be_to_cpu16(*(src16++));
165
grub_ata_pio_read (struct grub_ata_device *dev, char *buf,
168
grub_uint16_t *buf16 = (grub_uint16_t *) buf;
171
/* Make sure the read command is processed. */
174
if (grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & 1)
175
return grub_ata_regget (dev, GRUB_ATA_REG_ERROR);
177
/* Wait until the data is available. */
178
grub_ata_wait_drq (dev);
180
/* Read in the data, word by word. */
181
for (i = 0; i < size / 2; i++)
182
buf16[i] = grub_le_to_cpu16 (grub_inw(dev->ioaddress + GRUB_ATA_REG_DATA));
184
/* XXX: Do some error checks. */
190
grub_ata_pio_write (struct grub_ata_device *dev, char *buf,
193
grub_uint16_t *buf16 = (grub_uint16_t *) buf;
196
/* Make sure the write command is processed. */
199
/* Wait until the device is ready to write. */
200
grub_ata_wait_drq (dev);
202
/* Write the data, word by word. */
203
for (i = 0; i < size / 2; i++)
204
grub_outw(grub_cpu_to_le16 (buf16[i]), dev->ioaddress + GRUB_ATA_REG_DATA);
206
/* XXX: Do some error checks. */
212
grub_ata_dumpinfo (struct grub_ata_device *dev, char *info)
216
/* The device information was read, dump it for debugging. */
217
grub_ata_strncpy (text, info + 20, 20);
218
grub_printf ("Serial: %s\n", text);
219
grub_ata_strncpy (text, info + 46, 8);
220
grub_printf ("Firmware: %s\n", text);
221
grub_ata_strncpy (text, info + 54, 40);
222
grub_printf ("Model: %s\n", text);
224
grub_printf ("Addressing: %d\n", dev->addr);
225
grub_printf ("#sectors: %d\n", dev->size);
230
grub_atapi_identify (struct grub_ata_device *dev)
234
info = grub_malloc (256);
238
grub_ata_wait_busy (dev);
240
grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4);
241
grub_ata_regset (dev, GRUB_ATA_REG_CMD,
242
GRUB_ATA_CMD_IDENTIFY_PACKET_DEVICE);
244
grub_ata_pio_read (dev, info, 256);
248
grub_ata_dumpinfo (dev, info);
256
grub_atapi_packet (struct grub_ata_device *dev, char *packet)
258
grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4);
259
grub_ata_regset (dev, GRUB_ATA_REG_FEATURES, 0);
260
grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, 0);
261
grub_ata_regset (dev, GRUB_ATA_REG_LBAHIGH, 0xFF);
262
grub_ata_regset (dev, GRUB_ATA_REG_LBAMID, 0xFF);
263
grub_ata_regset (dev, GRUB_ATA_REG_CMD, GRUB_ATA_CMD_PACKET);
265
grub_ata_pio_write (dev, packet, 12);
271
grub_ata_identify (struct grub_ata_device *dev)
274
grub_uint16_t *info16;
277
info = grub_malloc (GRUB_DISK_SECTOR_SIZE);
281
info16 = (grub_uint16_t *) info;
283
grub_ata_wait_busy (dev);
285
grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4);
286
grub_ata_regset (dev, GRUB_ATA_REG_CMD, GRUB_ATA_CMD_IDENTIFY_DEVICE);
288
ataerr = grub_ata_pio_read (dev, info, GRUB_DISK_SECTOR_SIZE);
291
/* ATAPI device detected. */
293
return grub_atapi_identify (dev);
299
return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
300
"device can not be identified");
303
/* Now it is certain that this is not an ATAPI device. */
306
/* CHS is always supported. */
307
dev->addr = GRUB_ATA_CHS;
309
/* Check if LBA is supported. */
310
if (info16[49] & (1 << 9))
312
/* Check if LBA48 is supported. */
313
if (info16[83] & (1 << 10))
314
dev->addr = GRUB_ATA_LBA48;
316
dev->addr = GRUB_ATA_LBA;
319
/* Determine the amount of sectors. */
320
if (dev->addr != GRUB_ATA_LBA48)
321
dev->size = grub_le_to_cpu32(*((grub_uint32_t *) &info16[60]));
323
dev->size = grub_le_to_cpu64(*((grub_uint32_t *) &info16[100]));
325
/* Read CHS information. */
326
dev->cylinders = info16[1];
327
dev->heads = info16[3];
328
dev->sectors_per_track = info16[6];
330
grub_ata_dumpinfo (dev, info);
338
grub_ata_initialize (void)
340
struct grub_ata_device *dev;
341
struct grub_ata_device **devp;
345
for (port = 0; port <= 1; port++)
347
for (device = 0; device <= 1; device++)
349
dev = grub_malloc (sizeof(*dev));
353
/* Setup the device information. */
355
dev->device = device;
356
dev->ioaddress = grub_ata_ioaddress[dev->port];
357
dev->ioaddress2 = grub_ata_ioaddress2[dev->port];
360
/* Try to detect if the port is in use by writing to it,
361
waiting for a while and reading it again. If the value
362
was preserved, there is a device connected. */
363
grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4);
365
grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, 0x5A);
367
if (grub_ata_regget (dev, GRUB_ATA_REG_SECTORS) != 0x5A)
373
/* Detect if the device is present by issuing a reset. */
374
grub_ata_regset2 (dev, GRUB_ATA_REG2_CONTROL, 6);
376
grub_ata_regset2 (dev, GRUB_ATA_REG2_CONTROL, 2);
378
grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4);
381
/* XXX: Check some registers to see if the reset worked as
382
expected for this device. */
384
/* Enable for ATAPI . */
385
if (grub_ata_regget (dev, GRUB_ATA_REG_CYLLSB) != 0x14
386
|| grub_ata_regget (dev, GRUB_ATA_REG_CYLMSB) != 0xeb)
388
if (grub_ata_regget (dev, GRUB_ATA_REG_STATUS) == 0
389
|| (grub_ata_regget (dev, GRUB_ATA_REG_CYLLSB) != 0
390
&& grub_ata_regget (dev, GRUB_ATA_REG_CYLMSB) != 0
391
&& grub_ata_regget (dev, GRUB_ATA_REG_CYLLSB) != 0x3c
392
&& grub_ata_regget (dev, GRUB_ATA_REG_CYLLSB) != 0xc3))
398
/* Use the IDENTIFY DEVICE command to query the device. */
399
if (grub_ata_identify (dev))
405
/* Register the device. */
406
for (devp = &grub_ata_devices; *devp; devp = &(*devp)->next);
415
grub_ata_setlba (struct grub_ata_device *dev, grub_disk_addr_t sector,
418
grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, size);
419
grub_ata_regset (dev, GRUB_ATA_REG_LBALOW, sector & 0xFF);
420
grub_ata_regset (dev, GRUB_ATA_REG_LBAMID, (sector >> 8) & 0xFF);
421
grub_ata_regset (dev, GRUB_ATA_REG_LBAHIGH, (sector >> 16) & 0xFF);
425
grub_ata_setaddress (struct grub_ata_device *dev,
426
grub_ata_addressing_t addressing,
427
grub_disk_addr_t sector,
430
grub_ata_wait_busy (dev);
436
unsigned int cylinder;
440
/* Calculate the sector, cylinder and head to use. */
441
sect = ((grub_uint32_t) sector % dev->sectors_per_track) + 1;
442
cylinder = (((grub_uint32_t) sector / dev->sectors_per_track)
444
head = ((grub_uint32_t) sector / dev->sectors_per_track) % dev->heads;
446
if (sect > dev->sectors_per_track
447
|| cylinder > dev->cylinders
448
|| head > dev->heads)
449
return grub_error (GRUB_ERR_OUT_OF_RANGE,
450
"sector %d can not be addressed "
451
"using CHS addressing", sector);
453
grub_ata_regset (dev, GRUB_ATA_REG_SECTNUM, sect);
454
grub_ata_regset (dev, GRUB_ATA_REG_CYLLSB, cylinder & 0xFF);
455
grub_ata_regset (dev, GRUB_ATA_REG_CYLMSB, cylinder >> 8);
456
grub_ata_regset (dev, GRUB_ATA_REG_DISK, (dev->device << 4) | head);
464
grub_ata_setlba (dev, sector, size);
465
grub_ata_regset (dev, GRUB_ATA_REG_DISK,
466
0xE0 | (dev->device << 4) | ((sector >> 24) & 0x0F));
473
/* Set "Previous". */
474
grub_ata_setlba (dev, sector >> 24, size >> 8);
476
grub_ata_setlba (dev, sector, size);
477
grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | (dev->device << 4));
482
return GRUB_ERR_NONE;
486
grub_ata_readwrite (grub_disk_t disk, grub_disk_addr_t sector,
487
grub_size_t size, char *buf, int rw)
489
struct grub_ata_device *dev = (struct grub_ata_device *) disk->data;
492
grub_ata_addressing_t addressing;
496
addressing = dev->addr;
498
if (addressing == GRUB_ATA_LBA48 && ((sector + size) >> 28) != 0)
501
cmd = GRUB_ATA_CMD_READ_SECTORS_EXT;
502
cmd_write = GRUB_ATA_CMD_WRITE_SECTORS_EXT;
506
if (addressing == GRUB_ATA_LBA48)
507
addressing = GRUB_ATA_LBA;
509
cmd = GRUB_ATA_CMD_READ_SECTORS;
510
cmd_write = GRUB_ATA_CMD_WRITE_SECTORS;
515
/* Read/write batches of 256/65536 sectors, when more than 256/65536
516
sectors should be read/written. */
519
if (grub_ata_setaddress (dev, addressing, sector, batch))
524
/* Read 256/65536 sectors. */
525
grub_ata_regset (dev, GRUB_ATA_REG_CMD, cmd);
526
if (grub_ata_pio_read (dev, buf,
527
batch * GRUB_DISK_SECTOR_SIZE))
532
/* Write 256/65536 sectors. */
533
grub_ata_regset (dev, GRUB_ATA_REG_CMD, cmd_write);
534
if (grub_ata_pio_write (dev, buf,
535
batch * GRUB_DISK_SECTOR_SIZE))
539
buf += batch * GRUB_DISK_SECTOR_SIZE;
540
sector += batch * GRUB_DISK_SECTOR_SIZE;
543
/* Read/write just a "few" sectors. */
544
if (grub_ata_setaddress (dev, addressing, sector, size % batch))
550
grub_ata_regset (dev, GRUB_ATA_REG_CMD, cmd);
551
if (grub_ata_pio_read (dev, buf,
552
(size % batch) * GRUB_DISK_SECTOR_SIZE))
556
grub_ata_regset (dev, GRUB_ATA_REG_CMD, cmd_write);
557
if (grub_ata_pio_write (dev, buf,
558
(size % batch) * GRUB_DISK_SECTOR_SIZE))
562
return GRUB_ERR_NONE;
568
grub_ata_iterate (int (*hook) (const char *name))
570
struct grub_ata_device *dev;
572
for (dev = grub_ata_devices; dev; dev = dev->next)
575
grub_sprintf (devname, "ata%d", dev->port * 2 + dev->device);
585
grub_ata_open (const char *name, grub_disk_t disk)
587
struct grub_ata_device *dev;
589
for (dev = grub_ata_devices; dev; dev = dev->next)
592
grub_sprintf (devname, "ata%d", dev->port * 2 + dev->device);
593
if (grub_strcmp (name, devname) == 0)
598
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't open device");
601
disk->total_sectors = 9000000; /* XXX */
603
disk->total_sectors = dev->size;
605
disk->id = (int) dev;
607
disk->has_partitions = !dev->atapi;
614
grub_ata_close (grub_disk_t disk __attribute__((unused)))
619
struct grub_atapi_read
622
grub_uint8_t reserved1;
624
grub_uint32_t length;
625
grub_uint8_t reserved2[2];
626
} __attribute__((packed));
629
grub_atapi_readsector (struct grub_ata_device *dev,
630
char *buf, grub_disk_addr_t sector)
632
struct grub_atapi_read readcmd;
635
readcmd.lba = grub_cpu_to_be32 (sector);
636
readcmd.length = grub_cpu_to_be32 (1);
638
grub_atapi_packet (dev, (char *) &readcmd);
639
grub_ata_pio_read (dev, buf, GRUB_CDROM_SECTOR_SIZE);
645
grub_ata_read (grub_disk_t disk, grub_disk_addr_t sector,
646
grub_size_t size, char *buf)
648
struct grub_ata_device *dev = (struct grub_ata_device *) disk->data;
653
return grub_ata_readwrite (disk, sector, size, buf, 0);
655
/* ATAPI is being used, so try to read from CDROM using ATAPI. */
657
sbuf = grub_malloc (GRUB_CDROM_SECTOR_SIZE);
661
/* CDROMs have sectors of 2048 bytes, so chop them into pieces of
669
cdsector = sector >> 2;
670
rsize = ((size * GRUB_DISK_SECTOR_SIZE > GRUB_CDROM_SECTOR_SIZE)
671
? GRUB_CDROM_SECTOR_SIZE : size * GRUB_DISK_SECTOR_SIZE);
672
offset = (sector & 3) * GRUB_DISK_SECTOR_SIZE;
673
max = GRUB_CDROM_SECTOR_SIZE - offset;
674
rsize = (rsize > max) ? max : rsize;
676
grub_atapi_readsector (dev, sbuf, cdsector);
677
grub_memcpy (buf + offset, sbuf, rsize);
680
size -= rsize / GRUB_DISK_SECTOR_SIZE;
681
sector += rsize / GRUB_DISK_SECTOR_SIZE;
690
grub_ata_write (grub_disk_t disk,
691
grub_disk_addr_t sector,
696
return GRUB_ERR_NOT_IMPLEMENTED_YET;
698
return grub_ata_readwrite (disk, sector, size, (char *) buf, 1);
702
static struct grub_disk_dev grub_atadisk_dev =
705
.id = GRUB_DISK_DEVICE_ATA_ID,
706
.iterate = grub_ata_iterate,
707
.open = grub_ata_open,
708
.close = grub_ata_close,
709
.read = grub_ata_read,
710
.write = grub_ata_write,
718
(void) mod; /* To stop warning. */
720
/* XXX: To prevent two drivers operating on the same disks. */
721
grub_biosdisk_fini ();
723
/* ATA initialization. */
724
grub_ata_initialize ();
726
grub_disk_dev_register (&grub_atadisk_dev);
731
grub_disk_dev_unregister (&grub_atadisk_dev);