1 #include "devices/disk.h"
6 #include "devices/timer.h"
7 #include "threads/io.h"
8 #include "threads/interrupt.h"
9 #include "threads/synch.h"
11 /* ATA command block port addresses. */
12 #define reg_data(CHANNEL) ((CHANNEL)->reg_base + 0) /* Data. */
13 #define reg_error(CHANNEL) ((CHANNEL)->reg_base + 1) /* Error. */
14 #define reg_nsect(CHANNEL) ((CHANNEL)->reg_base + 2) /* Sector Count. */
15 #define reg_lbal(CHANNEL) ((CHANNEL)->reg_base + 3) /* LBA 0:7. */
16 #define reg_lbam(CHANNEL) ((CHANNEL)->reg_base + 4) /* LBA 15:8. */
17 #define reg_lbah(CHANNEL) ((CHANNEL)->reg_base + 5) /* LBA 23:16. */
18 #define reg_device(CHANNEL) ((CHANNEL)->reg_base + 6) /* Device/LBA 27:24. */
19 #define reg_status(CHANNEL) ((CHANNEL)->reg_base + 7) /* Status (r/o). */
20 #define reg_command(CHANNEL) reg_status (CHANNEL) /* Command (w/o). */
22 /* ATA control block port addresses.
23 (If we supported non-legacy ATA controllers this would not be
24 flexible enough, but it's fine for what we do.) */
25 #define reg_ctl(CHANNEL) ((CHANNEL)->reg_base + 0x206) /* Control (w/o). */
26 #define reg_alt_status(CHANNEL) reg_ctl (CHANNEL) /* Alt Status (r/o). */
28 /* Alternate Status Register bits. */
29 #define STA_BSY 0x80 /* Busy. */
30 #define STA_DRQ 0x08 /* Data Request. */
32 /* Control Register bits. */
33 #define CTL_SRST 0x04 /* Software Reset. */
35 /* Device Register bits. */
36 #define DEV_MBS 0xa0 /* Must be set. */
37 #define DEV_LBA 0x40 /* Linear based addressing. */
38 #define DEV_DEV 0x10 /* Select device: 0=master, 1=slave. */
41 Many more are defined but this is the small subset that we
43 #define CMD_IDENTIFY_DEVICE 0xec /* IDENTIFY DEVICE. */
44 #define CMD_READ_SECTOR_RETRY 0x20 /* READ SECTOR with retries. */
45 #define CMD_WRITE_SECTOR_RETRY 0x30 /* WRITE SECTOR with retries. */
50 char name[8]; /* Name, e.g. "hd0:1". */
51 struct channel *channel; /* Channel disk is on. */
52 int dev_no; /* Device 0 or 1 for master or slave. */
54 bool is_ata; /* 1=This device is an ATA disk. */
55 disk_sector_t capacity; /* Capacity in sectors (if is_ata). */
57 long long read_cnt; /* Number of sectors read. */
58 long long write_cnt; /* Number of sectors written. */
61 /* An ATA channel (aka controller).
62 Each channel can control up to two disks. */
65 char name[8]; /* Name, e.g. "hd0". */
66 uint16_t reg_base; /* Base I/O port. */
67 uint8_t irq; /* Interrupt in use. */
69 struct lock lock; /* Must acquire to access the controller. */
70 bool expecting_interrupt; /* True if an interrupt is expected, false if
71 any interrupt would be spurious. */
72 struct semaphore completion_wait; /* Up'd by interrupt handler. */
74 struct disk devices[2]; /* The devices on this channel. */
77 /* We support the two "legacy" ATA channels found in a standard PC. */
79 static struct channel channels[CHANNEL_CNT];
81 static void reset_channel (struct channel *);
82 static bool check_device_type (struct disk *);
83 static void identify_ata_device (struct disk *);
85 static void select_sector (struct disk *, disk_sector_t);
86 static void issue_pio_command (struct channel *, uint8_t command);
87 static void input_sector (struct channel *, void *);
88 static void output_sector (struct channel *, const void *);
90 static void wait_until_idle (const struct disk *);
91 static bool wait_while_busy (const struct disk *);
92 static void select_device (const struct disk *);
93 static void select_device_wait (const struct disk *);
95 static void interrupt_handler (struct intr_frame *);
97 /* Initialize the disk subsystem and detect disks. */
103 for (chan_no = 0; chan_no < CHANNEL_CNT; chan_no++)
105 struct channel *c = &channels[chan_no];
108 /* Initialize channel. */
109 snprintf (c->name, sizeof c->name, "hd%zd", chan_no);
123 lock_init (&c->lock, c->name);
124 c->expecting_interrupt = false;
125 sema_init (&c->completion_wait, 0, c->name);
127 /* Initialize devices. */
128 for (dev_no = 0; dev_no < 2; dev_no++)
130 struct disk *d = &c->devices[dev_no];
131 snprintf (d->name, sizeof d->name, "%s:%d", c->name, dev_no);
138 d->read_cnt = d->write_cnt = 0;
141 /* Register interrupt handler. */
142 intr_register (c->irq, 0, INTR_OFF, interrupt_handler, c->name);
144 /* Reset hardware. */
147 /* Distinguish ATA hard disks from other devices. */
148 if (check_device_type (&c->devices[0]))
149 check_device_type (&c->devices[1]);
151 /* Read hard disk identity information. */
152 for (dev_no = 0; dev_no < 2; dev_no++)
153 if (c->devices[dev_no].is_ata)
154 identify_ata_device (&c->devices[dev_no]);
158 /* Prints disk statistics. */
160 disk_print_stats (void)
164 for (chan_no = 0; chan_no < CHANNEL_CNT; chan_no++)
168 for (dev_no = 0; dev_no < 2; dev_no++)
170 struct disk *d = disk_get (chan_no, dev_no);
171 if (d != NULL && d->is_ata)
172 printf ("%s: %lld reads, %lld writes\n",
173 d->name, d->read_cnt, d->write_cnt);
178 /* Returns the disk numbered DEV_NO--either 0 or 1 for master or
179 slave, respectively--within the channel numbered CHAN_NO. */
181 disk_get (int chan_no, int dev_no)
183 ASSERT (dev_no == 0 || dev_no == 1);
185 if (chan_no < (int) CHANNEL_CNT)
187 struct disk *d = &channels[chan_no].devices[dev_no];
194 /* Returns the size of disk D, measured in DISK_SECTOR_SIZE-byte
197 disk_size (struct disk *d)
204 /* Reads sector SEC_NO from disk D into BUFFER, which must have
205 room for DISK_SECTOR_SIZE bytes. */
207 disk_read (struct disk *d, disk_sector_t sec_no, void *buffer)
212 ASSERT (buffer != NULL);
215 lock_acquire (&c->lock);
216 select_sector (d, sec_no);
217 issue_pio_command (c, CMD_READ_SECTOR_RETRY);
218 sema_down (&c->completion_wait);
219 if (!wait_while_busy (d))
220 PANIC ("%s: disk read failed, sector=%"PRDSNu, d->name, sec_no);
221 input_sector (c, buffer);
223 lock_release (&c->lock);
226 /* Write sector SEC_NO to disk D from BUFFER, which must contain
227 DISK_SECTOR_SIZE bytes. Returns after the disk has
228 acknowledged receiving the data. */
230 disk_write (struct disk *d, disk_sector_t sec_no, const void *buffer)
235 ASSERT (buffer != NULL);
238 lock_acquire (&c->lock);
239 select_sector (d, sec_no);
240 issue_pio_command (c, CMD_WRITE_SECTOR_RETRY);
241 if (!wait_while_busy (d))
242 PANIC ("%s: disk write failed, sector=%"PRDSNu, d->name, sec_no);
243 output_sector (c, buffer);
244 sema_down (&c->completion_wait);
246 lock_release (&c->lock);
249 /* Disk detection and identification. */
251 static void print_ata_string (char *string, size_t size);
253 /* Resets an ATA channel and waits for any devices present on it
254 to finish the reset. */
256 reset_channel (struct channel *c)
261 /* The ATA reset sequence depends on which devices are present,
262 so we start by detecting device presence. */
263 for (dev_no = 0; dev_no < 2; dev_no++)
265 struct disk *d = &c->devices[dev_no];
269 outb (reg_nsect (c), 0x55);
270 outb (reg_lbal (c), 0xaa);
272 outb (reg_nsect (c), 0xaa);
273 outb (reg_lbal (c), 0x55);
275 outb (reg_nsect (c), 0x55);
276 outb (reg_lbal (c), 0xaa);
278 present[dev_no] = (inb (reg_nsect (c)) == 0x55
279 && inb (reg_lbal (c)) == 0xaa);
282 /* Issue soft reset sequence, which selects device 0 as a side effect.
283 Also enable interrupts. */
284 outb (reg_ctl (c), 0);
285 timer_sleep (timer_us2ticks (10));
286 outb (reg_ctl (c), CTL_SRST);
287 timer_sleep (timer_us2ticks (10));
288 outb (reg_ctl (c), 0);
290 timer_sleep (timer_ms2ticks (150));
292 /* Wait for device 0 to clear BSY. */
295 select_device (&c->devices[0]);
296 wait_while_busy (&c->devices[0]);
299 /* Wait for device 1 to clear BSY. */
304 select_device (&c->devices[1]);
305 for (i = 0; i < 3000; i++)
307 if (inb (reg_nsect (c)) == 1 && inb (reg_lbal (c)) == 1)
309 timer_sleep (timer_ms2ticks (10));
311 wait_while_busy (&c->devices[1]);
315 /* Checks whether device D is an ATA disk and sets D's is_ata
316 member appropriately. If D is device 0 (master), returns true
317 if it's possible that a slave (device 1) exists on this
318 channel. If D is device 1 (slave), the return value is not
321 check_device_type (struct disk *d)
323 struct channel *c = d->channel;
324 uint8_t error, lbam, lbah;
328 error = inb (reg_error (c));
329 lbam = inb (reg_lbam (c));
330 lbah = inb (reg_lbah (c));
332 if (error != 1 && (error != 0x81 || d->dev_no == 1))
335 return error != 0x81;
339 d->is_ata = (lbam == 0 && lbah == 0) || (lbam == 0x3c && lbah == 0xc3);
344 /* Sends an IDENTIFY DEVICE command to disk D and reads the
345 response. Initializes D's capacity member based on the result
346 and prints a message describing the disk to the console. */
348 identify_ata_device (struct disk *d)
350 struct channel *c = d->channel;
351 uint16_t id[DISK_SECTOR_SIZE / 2];
355 /* Send the IDENTIFY DEVICE command, wait for an interrupt
356 indicating the device's response is ready, and read the data
358 select_device_wait (d);
359 issue_pio_command (c, CMD_IDENTIFY_DEVICE);
360 sema_down (&c->completion_wait);
361 if (!wait_while_busy (d))
366 input_sector (c, id);
368 /* Calculate capacity. */
369 d->capacity = id[60] | ((uint32_t) id[61] << 16);
371 /* Print identification message. */
372 printf ("%s: detected %'"PRDSNu" sector (", d->name, d->capacity);
373 if (d->capacity > 1024 / DISK_SECTOR_SIZE * 1024 * 1024)
374 printf ("%"PRDSNu" GB",
375 d->capacity / (1024 / DISK_SECTOR_SIZE * 1024 * 1024));
376 else if (d->capacity > 1024 / DISK_SECTOR_SIZE * 1024)
377 printf ("%"PRDSNu" MB", d->capacity / (1024 / DISK_SECTOR_SIZE * 1024));
378 else if (d->capacity > 1024 / DISK_SECTOR_SIZE)
379 printf ("%"PRDSNu" kB", d->capacity / (1024 / DISK_SECTOR_SIZE));
381 printf ("%"PRDSNu" byte", d->capacity * DISK_SECTOR_SIZE);
382 printf (") disk, model \"");
383 print_ata_string ((char *) &id[27], 40);
384 printf ("\", serial \"");
385 print_ata_string ((char *) &id[10], 20);
389 /* Prints STRING, which consists of SIZE bytes in a funky format:
390 each pair of bytes is in reverse order. Does not print
391 trailing whitespace and/or nulls. */
393 print_ata_string (char *string, size_t size)
397 /* Find the last non-white, non-null character. */
398 for (; size > 0; size--)
400 int c = string[(size - 1) ^ 1];
401 if (c != '\0' && !isspace (c))
406 for (i = 0; i < size; i++)
407 printf ("%c", string[i ^ 1]);
410 /* Selects device D, waiting for it to become ready, and then
411 writes SEC_NO to the disk's sector selection registers. (We
414 select_sector (struct disk *d, disk_sector_t sec_no)
416 struct channel *c = d->channel;
418 ASSERT (sec_no < d->capacity);
419 ASSERT (sec_no < (1UL << 28));
421 select_device_wait (d);
422 outb (reg_nsect (c), 1);
423 outb (reg_lbal (c), sec_no);
424 outb (reg_lbam (c), sec_no >> 8);
425 outb (reg_lbah (c), (sec_no >> 16));
426 outb (reg_device (c),
427 DEV_MBS | DEV_LBA | (d->dev_no == 1 ? DEV_DEV : 0) | (sec_no >> 24));
430 /* Writes COMMAND to channel C and prepares for receiving a
431 completion interrupt. */
433 issue_pio_command (struct channel *c, uint8_t command)
435 /* Interrupts must be enabled or our semaphore will never be
436 up'd by the completion handler. */
437 ASSERT (intr_get_level () == INTR_ON);
439 c->expecting_interrupt = true;
440 outb (reg_command (c), command);
443 /* Reads a sector from channel C's data register in PIO mode into
444 SECTOR, which must have room for DISK_SECTOR_SIZE bytes. */
446 input_sector (struct channel *c, void *sector)
448 insw (reg_data (c), sector, DISK_SECTOR_SIZE / 2);
451 /* Writes SECTOR to channel C's data register in PIO mode.
452 SECTOR must contain DISK_SECTOR_SIZE bytes. */
454 output_sector (struct channel *c, const void *sector)
456 outsw (reg_data (c), sector, DISK_SECTOR_SIZE / 2);
459 /* Low-level ATA primitives. */
461 /* Wait up to 10 seconds for the controller to become idle, that
462 is, for the BSY and DRQ bits to clear in the status register.
464 As a side effect, reading the status register clears any
465 pending interrupt. */
467 wait_until_idle (const struct disk *d)
471 for (i = 0; i < 1000; i++)
473 if ((inb (reg_status (d->channel)) & (STA_BSY | STA_DRQ)) == 0)
475 timer_sleep (timer_us2ticks (10));
478 printf ("%s: idle timeout\n", d->name);
481 /* Wait up to 30 seconds for disk D to clear BSY,
482 and then return the status of the DRQ bit.
483 The ATA standards say that a disk may take as long as that to
484 complete its reset. */
486 wait_while_busy (const struct disk *d)
488 struct channel *c = d->channel;
491 for (i = 0; i < 3000; i++)
494 printf ("%s: busy, waiting...", d->name);
495 if (!(inb (reg_alt_status (c)) & STA_BSY))
499 return (inb (reg_alt_status (c)) & STA_DRQ) != 0;
501 timer_sleep (timer_ms2ticks (10));
508 /* Program D's channel so that D is now the selected disk. */
510 select_device (const struct disk *d)
512 struct channel *c = d->channel;
513 uint8_t dev = DEV_MBS;
516 outb (reg_device (c), dev);
517 inb (reg_alt_status (c));
518 timer_sleep (timer_ns2ticks (400));
521 /* Select disk D in its channel, as select_device(), but wait for
522 the channel to become idle before and after. */
524 select_device_wait (const struct disk *d)
531 /* ATA interrupt handler. */
533 interrupt_handler (struct intr_frame *f)
537 for (c = channels; c < channels + CHANNEL_CNT; c++)
538 if (f->vec_no == c->irq)
540 if (c->expecting_interrupt)
542 inb (reg_status (c)); /* Acknowledge interrupt. */
543 sema_up (&c->completion_wait); /* Wake up waiter. */
546 printf ("%s: unexpected interrupt\n", c->name);