Fix bug reported by Mike Brown <mbrown@vmware.com>, in which a
[pintos-anon] / src / devices / disk.c
1 #include "devices/disk.h"
2 #include <ctype.h>
3 #include <debug.h>
4 #include <stdbool.h>
5 #include <stdio.h>
6 #include "devices/timer.h"
7 #include "threads/io.h"
8 #include "threads/interrupt.h"
9 #include "threads/synch.h"
10
11 /* The code in this file is an interface to an ATA (IDE)
12    controller.  It attempts to comply to [ATA-3]. */
13
14 /* ATA command block port addresses. */
15 #define reg_data(CHANNEL) ((CHANNEL)->reg_base + 0)     /* Data. */
16 #define reg_error(CHANNEL) ((CHANNEL)->reg_base + 1)    /* Error. */
17 #define reg_nsect(CHANNEL) ((CHANNEL)->reg_base + 2)    /* Sector Count. */
18 #define reg_lbal(CHANNEL) ((CHANNEL)->reg_base + 3)     /* LBA 0:7. */
19 #define reg_lbam(CHANNEL) ((CHANNEL)->reg_base + 4)     /* LBA 15:8. */
20 #define reg_lbah(CHANNEL) ((CHANNEL)->reg_base + 5)     /* LBA 23:16. */
21 #define reg_device(CHANNEL) ((CHANNEL)->reg_base + 6)   /* Device/LBA 27:24. */
22 #define reg_status(CHANNEL) ((CHANNEL)->reg_base + 7)   /* Status (r/o). */
23 #define reg_command(CHANNEL) reg_status (CHANNEL)       /* Command (w/o). */
24
25 /* ATA control block port addresses.
26    (If we supported non-legacy ATA controllers this would not be
27    flexible enough, but it's fine for what we do.) */
28 #define reg_ctl(CHANNEL) ((CHANNEL)->reg_base + 0x206)  /* Control (w/o). */
29 #define reg_alt_status(CHANNEL) reg_ctl (CHANNEL)       /* Alt Status (r/o). */
30
31 /* Alternate Status Register bits. */
32 #define STA_BSY 0x80            /* Busy. */
33 #define STA_DRDY 0x40           /* Device Ready. */
34 #define STA_DRQ 0x08            /* Data Request. */
35
36 /* Control Register bits. */
37 #define CTL_SRST 0x04           /* Software Reset. */
38
39 /* Device Register bits. */
40 #define DEV_MBS 0xa0            /* Must be set. */
41 #define DEV_LBA 0x40            /* Linear based addressing. */
42 #define DEV_DEV 0x10            /* Select device: 0=master, 1=slave. */
43
44 /* Commands.
45    Many more are defined but this is the small subset that we
46    use. */
47 #define CMD_IDENTIFY_DEVICE 0xec        /* IDENTIFY DEVICE. */
48 #define CMD_READ_SECTOR_RETRY 0x20      /* READ SECTOR with retries. */
49 #define CMD_WRITE_SECTOR_RETRY 0x30     /* WRITE SECTOR with retries. */
50
51 /* An ATA device. */
52 struct disk 
53   {
54     char name[8];               /* Name, e.g. "hd0:1". */
55     struct channel *channel;    /* Channel disk is on. */
56     int dev_no;                 /* Device 0 or 1 for master or slave. */
57
58     bool is_ata;                /* 1=This device is an ATA disk. */
59     disk_sector_t capacity;     /* Capacity in sectors (if is_ata). */
60
61     long long read_cnt;         /* Number of sectors read. */
62     long long write_cnt;        /* Number of sectors written. */
63   };
64
65 /* An ATA channel (aka controller).
66    Each channel can control up to two disks. */
67 struct channel 
68   {
69     char name[8];               /* Name, e.g. "hd0". */
70     uint16_t reg_base;          /* Base I/O port. */
71     uint8_t irq;                /* Interrupt in use. */
72
73     struct lock lock;           /* Must acquire to access the controller. */
74     bool expecting_interrupt;   /* True if an interrupt is expected, false if
75                                    any interrupt would be spurious. */
76     struct semaphore completion_wait;   /* Up'd by interrupt handler. */
77
78     struct disk devices[2];     /* The devices on this channel. */
79   };
80
81 /* We support the two "legacy" ATA channels found in a standard PC. */
82 #define CHANNEL_CNT 2
83 static struct channel channels[CHANNEL_CNT];
84
85 static void reset_channel (struct channel *);
86 static bool check_device_type (struct disk *);
87 static void identify_ata_device (struct disk *);
88
89 static void select_sector (struct disk *, disk_sector_t);
90 static void issue_pio_command (struct channel *, uint8_t command);
91 static void input_sector (struct channel *, void *);
92 static void output_sector (struct channel *, const void *);
93
94 static void wait_until_idle (const struct disk *);
95 static bool wait_while_busy (const struct disk *);
96 static void select_device (const struct disk *);
97 static void select_device_wait (const struct disk *);
98
99 static void interrupt_handler (struct intr_frame *);
100
101 /* Initialize the disk subsystem and detect disks. */
102 void
103 disk_init (void) 
104 {
105   size_t chan_no;
106
107   for (chan_no = 0; chan_no < CHANNEL_CNT; chan_no++)
108     {
109       struct channel *c = &channels[chan_no];
110       int dev_no;
111
112       /* Initialize channel. */
113       snprintf (c->name, sizeof c->name, "hd%zu", chan_no);
114       switch (chan_no) 
115         {
116         case 0:
117           c->reg_base = 0x1f0;
118           c->irq = 14 + 0x20;
119           break;
120         case 1:
121           c->reg_base = 0x170;
122           c->irq = 15 + 0x20;
123           break;
124         default:
125           NOT_REACHED ();
126         }
127       lock_init (&c->lock);
128       c->expecting_interrupt = false;
129       sema_init (&c->completion_wait, 0);
130  
131       /* Initialize devices. */
132       for (dev_no = 0; dev_no < 2; dev_no++)
133         {
134           struct disk *d = &c->devices[dev_no];
135           snprintf (d->name, sizeof d->name, "%s:%d", c->name, dev_no);
136           d->channel = c;
137           d->dev_no = dev_no;
138
139           d->is_ata = false;
140           d->capacity = 0;
141
142           d->read_cnt = d->write_cnt = 0;
143         }
144
145       /* Register interrupt handler. */
146       intr_register_ext (c->irq, interrupt_handler, c->name);
147
148       /* Reset hardware. */
149       reset_channel (c);
150
151       /* Distinguish ATA hard disks from other devices. */
152       if (check_device_type (&c->devices[0]))
153         check_device_type (&c->devices[1]);
154
155       /* Read hard disk identity information. */
156       for (dev_no = 0; dev_no < 2; dev_no++)
157         if (c->devices[dev_no].is_ata)
158           identify_ata_device (&c->devices[dev_no]);
159     }
160 }
161
162 /* Prints disk statistics. */
163 void
164 disk_print_stats (void) 
165 {
166   int chan_no;
167
168   for (chan_no = 0; chan_no < CHANNEL_CNT; chan_no++) 
169     {
170       int dev_no;
171
172       for (dev_no = 0; dev_no < 2; dev_no++) 
173         {
174           struct disk *d = disk_get (chan_no, dev_no);
175           if (d != NULL && d->is_ata) 
176             printf ("%s: %lld reads, %lld writes\n",
177                     d->name, d->read_cnt, d->write_cnt);
178         }
179     }
180 }
181
182 /* Returns the disk numbered DEV_NO--either 0 or 1 for master or
183    slave, respectively--within the channel numbered CHAN_NO.
184
185    Pintos uses disks this way:
186         0:0 - operating system kernel
187         0:1 - file system
188         1:0 - scratch
189         1:1 - swap
190 */
191 struct disk *
192 disk_get (int chan_no, int dev_no) 
193 {
194   ASSERT (dev_no == 0 || dev_no == 1);
195
196   if (chan_no < (int) CHANNEL_CNT) 
197     {
198       struct disk *d = &channels[chan_no].devices[dev_no];
199       if (d->is_ata)
200         return d; 
201     }
202   return NULL;
203 }
204
205 /* Returns the size of disk D, measured in DISK_SECTOR_SIZE-byte
206    sectors. */
207 disk_sector_t
208 disk_size (struct disk *d) 
209 {
210   ASSERT (d != NULL);
211   
212   return d->capacity;
213 }
214
215 /* Reads sector SEC_NO from disk D into BUFFER, which must have
216    room for DISK_SECTOR_SIZE bytes. */
217 void
218 disk_read (struct disk *d, disk_sector_t sec_no, void *buffer) 
219 {
220   struct channel *c;
221   
222   ASSERT (d != NULL);
223   ASSERT (buffer != NULL);
224
225   c = d->channel;
226   lock_acquire (&c->lock);
227   select_sector (d, sec_no);
228   issue_pio_command (c, CMD_READ_SECTOR_RETRY);
229   sema_down (&c->completion_wait);
230   if (!wait_while_busy (d))
231     PANIC ("%s: disk read failed, sector=%"PRDSNu, d->name, sec_no);
232   input_sector (c, buffer);
233   d->read_cnt++;
234   lock_release (&c->lock);
235 }
236
237 /* Write sector SEC_NO to disk D from BUFFER, which must contain
238    DISK_SECTOR_SIZE bytes.  Returns after the disk has
239    acknowledged receiving the data. */
240 void
241 disk_write (struct disk *d, disk_sector_t sec_no, const void *buffer)
242 {
243   struct channel *c;
244   
245   ASSERT (d != NULL);
246   ASSERT (buffer != NULL);
247
248   c = d->channel;
249   lock_acquire (&c->lock);
250   select_sector (d, sec_no);
251   issue_pio_command (c, CMD_WRITE_SECTOR_RETRY);
252   if (!wait_while_busy (d))
253     PANIC ("%s: disk write failed, sector=%"PRDSNu, d->name, sec_no);
254   output_sector (c, buffer);
255   sema_down (&c->completion_wait);
256   d->write_cnt++;
257   lock_release (&c->lock);
258 }
259 \f
260 /* Disk detection and identification. */
261
262 static void print_ata_string (char *string, size_t size);
263
264 /* Resets an ATA channel and waits for any devices present on it
265    to finish the reset. */
266 static void
267 reset_channel (struct channel *c) 
268 {
269   bool present[2];
270   int dev_no;
271
272   /* The ATA reset sequence depends on which devices are present,
273      so we start by detecting device presence. */
274   for (dev_no = 0; dev_no < 2; dev_no++)
275     {
276       struct disk *d = &c->devices[dev_no];
277
278       select_device (d);
279
280       outb (reg_nsect (c), 0x55);
281       outb (reg_lbal (c), 0xaa);
282
283       outb (reg_nsect (c), 0xaa);
284       outb (reg_lbal (c), 0x55);
285
286       outb (reg_nsect (c), 0x55);
287       outb (reg_lbal (c), 0xaa);
288
289       present[dev_no] = (inb (reg_nsect (c)) == 0x55
290                          && inb (reg_lbal (c)) == 0xaa);
291     }
292
293   /* Issue soft reset sequence, which selects device 0 as a side effect.
294      Also enable interrupts. */
295   outb (reg_ctl (c), 0);
296   timer_usleep (10);
297   outb (reg_ctl (c), CTL_SRST);
298   timer_usleep (10);
299   outb (reg_ctl (c), 0);
300
301   timer_msleep (150);
302
303   /* Wait for device 0 to clear BSY. */
304   if (present[0]) 
305     {
306       select_device (&c->devices[0]);
307       wait_while_busy (&c->devices[0]); 
308     }
309
310   /* Wait for device 1 to clear BSY. */
311   if (present[1])
312     {
313       int i;
314
315       select_device (&c->devices[1]);
316       for (i = 0; i < 3000; i++) 
317         {
318           if (inb (reg_nsect (c)) == 1 && inb (reg_lbal (c)) == 1)
319             break;
320           timer_msleep (10);
321         }
322       wait_while_busy (&c->devices[1]);
323     }
324 }
325
326 /* Checks whether device D is an ATA disk and sets D's is_ata
327    member appropriately.  If D is device 0 (master), returns true
328    if it's possible that a slave (device 1) exists on this
329    channel.  If D is device 1 (slave), the return value is not
330    meaningful. */
331 static bool
332 check_device_type (struct disk *d) 
333 {
334   struct channel *c = d->channel;
335   uint8_t error, lbam, lbah, status;
336
337   select_device (d);
338
339   error = inb (reg_error (c));
340   lbam = inb (reg_lbam (c));
341   lbah = inb (reg_lbah (c));
342   status = inb (reg_status (c));
343
344   if ((error != 1 && (error != 0x81 || d->dev_no == 1))
345       || (status & STA_DRDY) == 0
346       || (status & STA_BSY) != 0)
347     {
348       d->is_ata = false;
349       return error != 0x81;      
350     }
351   else 
352     {
353       d->is_ata = (lbam == 0 && lbah == 0) || (lbam == 0x3c && lbah == 0xc3);
354       return true; 
355     }
356 }
357
358 /* Sends an IDENTIFY DEVICE command to disk D and reads the
359    response.  Initializes D's capacity member based on the result
360    and prints a message describing the disk to the console. */
361 static void
362 identify_ata_device (struct disk *d) 
363 {
364   struct channel *c = d->channel;
365   uint16_t id[DISK_SECTOR_SIZE / 2];
366
367   ASSERT (d->is_ata);
368
369   /* Send the IDENTIFY DEVICE command, wait for an interrupt
370      indicating the device's response is ready, and read the data
371      into our buffer. */
372   select_device_wait (d);
373   issue_pio_command (c, CMD_IDENTIFY_DEVICE);
374   sema_down (&c->completion_wait);
375   if (!wait_while_busy (d))
376     {
377       d->is_ata = false;
378       return;
379     }
380   input_sector (c, id);
381
382   /* Calculate capacity. */
383   d->capacity = id[60] | ((uint32_t) id[61] << 16);
384
385   /* Print identification message. */
386   printf ("%s: detected %'"PRDSNu" sector (", d->name, d->capacity);
387   if (d->capacity > 1024 / DISK_SECTOR_SIZE * 1024 * 1024)
388     printf ("%"PRDSNu" GB",
389             d->capacity / (1024 / DISK_SECTOR_SIZE * 1024 * 1024));
390   else if (d->capacity > 1024 / DISK_SECTOR_SIZE * 1024)
391     printf ("%"PRDSNu" MB", d->capacity / (1024 / DISK_SECTOR_SIZE * 1024));
392   else if (d->capacity > 1024 / DISK_SECTOR_SIZE)
393     printf ("%"PRDSNu" kB", d->capacity / (1024 / DISK_SECTOR_SIZE));
394   else
395     printf ("%"PRDSNu" byte", d->capacity * DISK_SECTOR_SIZE);
396   printf (") disk, model \"");
397   print_ata_string ((char *) &id[27], 40);
398   printf ("\", serial \"");
399   print_ata_string ((char *) &id[10], 20);
400   printf ("\"\n");
401 }
402
403 /* Prints STRING, which consists of SIZE bytes in a funky format:
404    each pair of bytes is in reverse order.  Does not print
405    trailing whitespace and/or nulls. */
406 static void
407 print_ata_string (char *string, size_t size) 
408 {
409   size_t i;
410
411   /* Find the last non-white, non-null character. */
412   for (; size > 0; size--)
413     {
414       int c = string[(size - 1) ^ 1];
415       if (c != '\0' && !isspace (c))
416         break; 
417     }
418
419   /* Print. */
420   for (i = 0; i < size; i++)
421     printf ("%c", string[i ^ 1]);
422 }
423 \f
424 /* Selects device D, waiting for it to become ready, and then
425    writes SEC_NO to the disk's sector selection registers.  (We
426    use LBA mode.) */
427 static void
428 select_sector (struct disk *d, disk_sector_t sec_no) 
429 {
430   struct channel *c = d->channel;
431
432   ASSERT (sec_no < d->capacity);
433   ASSERT (sec_no < (1UL << 28));
434   
435   select_device_wait (d);
436   outb (reg_nsect (c), 1);
437   outb (reg_lbal (c), sec_no);
438   outb (reg_lbam (c), sec_no >> 8);
439   outb (reg_lbah (c), (sec_no >> 16));
440   outb (reg_device (c),
441         DEV_MBS | DEV_LBA | (d->dev_no == 1 ? DEV_DEV : 0) | (sec_no >> 24));
442 }
443
444 /* Writes COMMAND to channel C and prepares for receiving a
445    completion interrupt. */
446 static void
447 issue_pio_command (struct channel *c, uint8_t command) 
448 {
449   /* Interrupts must be enabled or our semaphore will never be
450      up'd by the completion handler. */
451   ASSERT (intr_get_level () == INTR_ON);
452
453   c->expecting_interrupt = true;
454   outb (reg_command (c), command);
455 }
456
457 /* Reads a sector from channel C's data register in PIO mode into
458    SECTOR, which must have room for DISK_SECTOR_SIZE bytes. */
459 static void
460 input_sector (struct channel *c, void *sector) 
461 {
462   insw (reg_data (c), sector, DISK_SECTOR_SIZE / 2);
463 }
464
465 /* Writes SECTOR to channel C's data register in PIO mode.
466    SECTOR must contain DISK_SECTOR_SIZE bytes. */
467 static void
468 output_sector (struct channel *c, const void *sector) 
469 {
470   outsw (reg_data (c), sector, DISK_SECTOR_SIZE / 2);
471 }
472 \f
473 /* Low-level ATA primitives. */
474
475 /* Wait up to 10 seconds for the controller to become idle, that
476    is, for the BSY and DRQ bits to clear in the status register.
477
478    As a side effect, reading the status register clears any
479    pending interrupt. */
480 static void
481 wait_until_idle (const struct disk *d) 
482 {
483   int i;
484
485   for (i = 0; i < 1000; i++) 
486     {
487       if ((inb (reg_status (d->channel)) & (STA_BSY | STA_DRQ)) == 0)
488         return;
489       timer_usleep (10);
490     }
491
492   printf ("%s: idle timeout\n", d->name);
493 }
494
495 /* Wait up to 30 seconds for disk D to clear BSY,
496    and then return the status of the DRQ bit.
497    The ATA standards say that a disk may take as long as that to
498    complete its reset. */
499 static bool
500 wait_while_busy (const struct disk *d) 
501 {
502   struct channel *c = d->channel;
503   int i;
504   
505   for (i = 0; i < 3000; i++)
506     {
507       if (i == 700)
508         printf ("%s: busy, waiting...", d->name);
509       if (!(inb (reg_alt_status (c)) & STA_BSY)) 
510         {
511           if (i >= 700)
512             printf ("ok\n");
513           return (inb (reg_alt_status (c)) & STA_DRQ) != 0;
514         }
515       timer_msleep (10);
516     }
517
518   printf ("failed\n");
519   return false;
520 }
521
522 /* Program D's channel so that D is now the selected disk. */
523 static void
524 select_device (const struct disk *d)
525 {
526   struct channel *c = d->channel;
527   uint8_t dev = DEV_MBS;
528   if (d->dev_no == 1)
529     dev |= DEV_DEV;
530   outb (reg_device (c), dev);
531   inb (reg_alt_status (c));
532   timer_nsleep (400);
533 }
534
535 /* Select disk D in its channel, as select_device(), but wait for
536    the channel to become idle before and after. */
537 static void
538 select_device_wait (const struct disk *d) 
539 {
540   wait_until_idle (d);
541   select_device (d);
542   wait_until_idle (d);
543 }
544 \f
545 /* ATA interrupt handler. */
546 static void
547 interrupt_handler (struct intr_frame *f) 
548 {
549   struct channel *c;
550
551   for (c = channels; c < channels + CHANNEL_CNT; c++)
552     if (f->vec_no == c->irq)
553       {
554         if (c->expecting_interrupt) 
555           {
556             inb (reg_status (c));               /* Acknowledge interrupt. */
557             sema_up (&c->completion_wait);      /* Wake up waiter. */
558           }
559         else
560           printf ("%s: unexpected interrupt\n", c->name);
561         return;
562       }
563
564   NOT_REACHED ();
565 }
566
567