10 #define reg_data(CHANNEL) ((CHANNEL)->reg_base + 0)
11 #define reg_error(CHANNEL) ((CHANNEL)->reg_base + 1)
12 #define reg_nsect(CHANNEL) ((CHANNEL)->reg_base + 2)
13 #define reg_lbal(CHANNEL) ((CHANNEL)->reg_base + 3)
14 #define reg_lbam(CHANNEL) ((CHANNEL)->reg_base + 4)
15 #define reg_lbah(CHANNEL) ((CHANNEL)->reg_base + 5)
16 #define reg_device(CHANNEL) ((CHANNEL)->reg_base + 6)
17 #define reg_status(CHANNEL) ((CHANNEL)->reg_base + 7)
18 #define reg_command(CHANNEL) reg_status (CHANNEL)
19 #define reg_ctl(CHANNEL) ((CHANNEL)->reg_base + 0x206)
20 #define reg_alt_status(CHANNEL) reg_ctl (CHANNEL)
22 /* Alternate Status Register bits. */
32 /* Control Register bits. */
36 /* Device Register bits. */
37 #define DEV_MBS 0xa0 /* Must be set. */
38 #define DEV_LBA 0x40 /* Linear based addressing. */
39 #define DEV_DEV 0x10 /* Select device: 0=master, 1=slave. */
42 #define CMD_IDENTIFY 0xec /* IDENTIFY DEVICE. */
43 #define CMD_READ_SECTOR_RETRY 0x20 /* READ SECTOR with retries. */
44 #define CMD_READ_SECTOR_NORETRY 0x21 /* READ SECTOR without retries. */
45 #define CMD_WRITE_SECTOR_RETRY 0x30 /* WRITE SECTOR with retries. */
46 #define CMD_WRITE_SECTOR_NORETRY 0x31 /* WRITE SECTOR without retries. */
51 struct channel *channel;
55 disk_sector_no capacity;
64 bool expecting_interrupt;
65 struct semaphore completion_wait;
70 #define CHANNEL_CNT (sizeof channels / sizeof *channels)
71 static struct channel channels[2];
74 wait_until_idle (const struct disk *d)
78 for(i = 0; i < 1000; i++)
80 if ((inb (reg_status (d->channel)) & (STA_BSY | STA_DRQ)) == 0)
85 printk ("%s: idle timeout\n", d->name);
88 /* Wait up to 30 seconds for disk D to clear BSY. */
90 wait_while_busy (const struct disk *d)
92 struct channel *c = d->channel;
95 for (i = 0; i < 3000; i++)
98 printk ("%s: busy, waiting...", d->name);
99 if (!(inb (reg_alt_status (c)) & STA_BSY))
113 select_device (const struct disk *d)
115 struct channel *c = d->channel;
116 uint8_t dev = DEV_MBS;
119 outb (reg_device (c), dev);
120 inb (reg_alt_status (c));
125 select_device_wait (const struct disk *d)
133 reset_channel (struct channel *c)
138 /* The ATA reset sequence depends on which devices are present,
139 so we start by detecting device presence. */
140 for (device = 0; device < 2; device++)
142 struct disk *d = &c->dev[device];
146 outb (reg_nsect (c), 0x55);
147 outb (reg_lbal (c), 0xaa);
149 outb (reg_nsect (c), 0xaa);
150 outb (reg_lbal (c), 0x55);
152 outb (reg_nsect (c), 0x55);
153 outb (reg_lbal (c), 0xaa);
155 present[device] = (inb (reg_nsect (c)) == 0x55
156 && inb (reg_lbal (c)) == 0xaa);
159 /* Issue soft reset sequence, which selects device 0 as a side effect.
160 Also enable interrupts. */
161 outb (reg_ctl (c), 0);
163 outb (reg_ctl (c), CTL_SRST);
165 outb (reg_ctl (c), 0);
169 /* Wait for device 0 to clear BSY. */
172 select_device (&c->dev[0]);
173 wait_while_busy (&c->dev[0]);
176 /* Wait for device 1 to clear BSY. */
181 select_device (&c->dev[1]);
182 for (i = 0; i < 3000; i++)
184 if (inb (reg_nsect (c)) == 1 && inb (reg_lbal (c)) == 1)
188 wait_while_busy (&c->dev[1]);
193 check_device_type (struct disk *d)
195 struct channel *c = d->channel;
196 uint8_t error, lbam, lbah;
200 error = inb (reg_error (c));
201 lbam = inb (reg_lbam (c));
202 lbah = inb (reg_lbah (c));
204 if (error != 1 && (error != 0x81 || d->device == 1))
207 return error != 0x81;
211 d->is_ata = (lbam == 0 && lbah == 0) || (lbam == 0x3c && lbah == 0xc3);
217 execute_command (struct disk *d, uint8_t command)
219 struct channel *c = d->channel;
221 /* Interrupts must be enabled or our semaphore will never be
222 up'd by the completion handler. */
223 ASSERT (intr_get_level () == IF_ON);
225 /* Atomically note that we expect an interrupt and send the
226 command to the device. */
228 c->expecting_interrupt = true;
229 outb (reg_command (c), command);
232 /* Wait for the command to complete. */
233 sema_down (&c->completion_wait);
237 input_sector (struct channel *c, void *sector)
241 ASSERT (sector != NULL);
243 status = inb (reg_status (c));
244 if (status & STA_DRQ)
246 /* Command was successful. Read data into SECTOR. */
247 insw (reg_data (c), sector, DISK_SECTOR_SIZE / 2);
252 /* Command failed. */
258 output_sector (struct channel *c, const void *sector)
262 ASSERT (sector != NULL);
264 status = inb (reg_status (c));
265 if (status & STA_DRQ)
267 /* Command was successful. Write data into SECTOR. */
268 outsw (reg_data (c), sector, DISK_SECTOR_SIZE / 2);
273 /* Command failed. */
279 printk_ata_string (char *string, size_t word_cnt)
284 for (last = word_cnt * 2 - 1; last >= 0; last--)
285 if (string[last ^ 1] != ' ')
288 for (i = 0; i <= last; i++)
289 printk ("%c", string[i ^ 1]);
293 identify_ata_device (struct disk *d)
295 uint16_t id[DISK_SECTOR_SIZE / 2];
299 select_device_wait (d);
300 execute_command (d, CMD_IDENTIFY);
303 if (!input_sector (d->channel, id))
309 d->capacity = id[60] | ((uint32_t) id[61] << 16);
310 printk ("%s: detected %'"PRDSNu" sector (%d MB) disk: ",
311 d->name, d->capacity, d->capacity * DISK_SECTOR_SIZE / 1024 / 1024);
312 printk_ata_string ((char *) &id[27], 20);
314 printk_ata_string ((char *) &id[10], 10);
319 interrupt_handler (struct intr_frame *f)
323 for (c = channels; c < channels + CHANNEL_CNT; c++)
324 if (f->vec_no == c->irq)
326 if (c->expecting_interrupt)
328 /* Acknowledge interrupt. */
329 inb (reg_status (c));
331 /* Wake up waiter. */
332 sema_up (&c->completion_wait);
335 printk ("%s: unexpected interrupt\n", c->name);
347 for (channel = 0; channel < CHANNEL_CNT; channel++)
349 struct channel *c = &channels[channel];
352 /* Initialize channel. */
353 snprintf (c->name, sizeof c->name, "ide%d", channel);
367 c->expecting_interrupt = false;
368 sema_init (&c->completion_wait, 0, c->name);
370 /* Initialize devices. */
371 for (device = 0; device < 2; device++)
373 struct disk *d = &c->dev[device];
374 snprintf (d->name, sizeof d->name, "%s:%d", c->name, device);
382 /* Register interrupt handler. */
383 intr_register (c->irq, 0, IF_OFF, interrupt_handler, c->name);
385 /* Reset hardware. */
388 /* Distinguish ATA hard disks from other devices. */
389 if (check_device_type (&c->dev[0]))
390 check_device_type (&c->dev[1]);
392 /* Read hard disk identity information. */
393 for (device = 0; device < 2; device++)
394 if (c->dev[device].is_ata)
395 identify_ata_device (&c->dev[device]);
404 ASSERT (idx >= 0 && idx < 4);
405 d = &channels[idx / 2].dev[idx % 2];
406 return d->is_ata ? d : NULL;
410 disk_size (struct disk *d)
418 select_sector (struct disk *d, disk_sector_no sec_no)
420 struct channel *c = d->channel;
422 ASSERT (sec_no < d->capacity);
423 ASSERT (sec_no < (1UL << 28));
425 select_device_wait (d);
426 outb (reg_nsect (c), 1);
427 outb (reg_lbal (c), sec_no);
428 outb (reg_lbam (c), sec_no >> 8);
429 outb (reg_lbah (c), (sec_no >> 16));
430 outb (reg_device (c),
431 DEV_MBS | DEV_LBA | (d->device == 1 ? DEV_DEV : 0) | (sec_no >> 24));
435 disk_read (struct disk *d, disk_sector_no sec_no, void *buffer)
438 ASSERT (buffer != NULL);
440 select_sector (d, sec_no);
441 execute_command (d, CMD_READ_SECTOR_RETRY);
443 if (!input_sector (d->channel, buffer))
444 panic ("%s: disk read failed, sector=%"PRDSNu, d->name, sec_no);
448 disk_write (struct disk *d, disk_sector_no sec_no, const void *buffer)
451 ASSERT (buffer != NULL);
453 select_sector (d, sec_no);
454 execute_command (d, CMD_WRITE_SECTOR_RETRY);
456 if (!output_sector (d->channel, buffer))
457 panic ("%s: disk write failed, sector=%"PRDSNu, d->name, sec_no);