Make backtraces slightly more reliable.
[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 - boot loader, command line args, and 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    Internally synchronizes accesses to disks, so external
218    per-disk locking is unneeded. */
219 void
220 disk_read (struct disk *d, disk_sector_t sec_no, void *buffer) 
221 {
222   struct channel *c;
223   
224   ASSERT (d != NULL);
225   ASSERT (buffer != NULL);
226
227   c = d->channel;
228   lock_acquire (&c->lock);
229   select_sector (d, sec_no);
230   issue_pio_command (c, CMD_READ_SECTOR_RETRY);
231   sema_down (&c->completion_wait);
232   if (!wait_while_busy (d))
233     PANIC ("%s: disk read failed, sector=%"PRDSNu, d->name, sec_no);
234   input_sector (c, buffer);
235   d->read_cnt++;
236   lock_release (&c->lock);
237 }
238
239 /* Write sector SEC_NO to disk D from BUFFER, which must contain
240    DISK_SECTOR_SIZE bytes.  Returns after the disk has
241    acknowledged receiving the data.
242    Internally synchronizes accesses to disks, so external
243    per-disk locking is unneeded. */
244 void
245 disk_write (struct disk *d, disk_sector_t sec_no, const void *buffer)
246 {
247   struct channel *c;
248   
249   ASSERT (d != NULL);
250   ASSERT (buffer != NULL);
251
252   c = d->channel;
253   lock_acquire (&c->lock);
254   select_sector (d, sec_no);
255   issue_pio_command (c, CMD_WRITE_SECTOR_RETRY);
256   if (!wait_while_busy (d))
257     PANIC ("%s: disk write failed, sector=%"PRDSNu, d->name, sec_no);
258   output_sector (c, buffer);
259   sema_down (&c->completion_wait);
260   d->write_cnt++;
261   lock_release (&c->lock);
262 }
263 \f
264 /* Disk detection and identification. */
265
266 static void print_ata_string (char *string, size_t size);
267
268 /* Resets an ATA channel and waits for any devices present on it
269    to finish the reset. */
270 static void
271 reset_channel (struct channel *c) 
272 {
273   bool present[2];
274   int dev_no;
275
276   /* The ATA reset sequence depends on which devices are present,
277      so we start by detecting device presence. */
278   for (dev_no = 0; dev_no < 2; dev_no++)
279     {
280       struct disk *d = &c->devices[dev_no];
281
282       select_device (d);
283
284       outb (reg_nsect (c), 0x55);
285       outb (reg_lbal (c), 0xaa);
286
287       outb (reg_nsect (c), 0xaa);
288       outb (reg_lbal (c), 0x55);
289
290       outb (reg_nsect (c), 0x55);
291       outb (reg_lbal (c), 0xaa);
292
293       present[dev_no] = (inb (reg_nsect (c)) == 0x55
294                          && inb (reg_lbal (c)) == 0xaa);
295     }
296
297   /* Issue soft reset sequence, which selects device 0 as a side effect.
298      Also enable interrupts. */
299   outb (reg_ctl (c), 0);
300   timer_usleep (10);
301   outb (reg_ctl (c), CTL_SRST);
302   timer_usleep (10);
303   outb (reg_ctl (c), 0);
304
305   timer_msleep (150);
306
307   /* Wait for device 0 to clear BSY. */
308   if (present[0]) 
309     {
310       select_device (&c->devices[0]);
311       wait_while_busy (&c->devices[0]); 
312     }
313
314   /* Wait for device 1 to clear BSY. */
315   if (present[1])
316     {
317       int i;
318
319       select_device (&c->devices[1]);
320       for (i = 0; i < 3000; i++) 
321         {
322           if (inb (reg_nsect (c)) == 1 && inb (reg_lbal (c)) == 1)
323             break;
324           timer_msleep (10);
325         }
326       wait_while_busy (&c->devices[1]);
327     }
328 }
329
330 /* Checks whether device D is an ATA disk and sets D's is_ata
331    member appropriately.  If D is device 0 (master), returns true
332    if it's possible that a slave (device 1) exists on this
333    channel.  If D is device 1 (slave), the return value is not
334    meaningful. */
335 static bool
336 check_device_type (struct disk *d) 
337 {
338   struct channel *c = d->channel;
339   uint8_t error, lbam, lbah, status;
340
341   select_device (d);
342
343   error = inb (reg_error (c));
344   lbam = inb (reg_lbam (c));
345   lbah = inb (reg_lbah (c));
346   status = inb (reg_status (c));
347
348   if ((error != 1 && (error != 0x81 || d->dev_no == 1))
349       || (status & STA_DRDY) == 0
350       || (status & STA_BSY) != 0)
351     {
352       d->is_ata = false;
353       return error != 0x81;      
354     }
355   else 
356     {
357       d->is_ata = (lbam == 0 && lbah == 0) || (lbam == 0x3c && lbah == 0xc3);
358       return true; 
359     }
360 }
361
362 /* Sends an IDENTIFY DEVICE command to disk D and reads the
363    response.  Initializes D's capacity member based on the result
364    and prints a message describing the disk to the console. */
365 static void
366 identify_ata_device (struct disk *d) 
367 {
368   struct channel *c = d->channel;
369   uint16_t id[DISK_SECTOR_SIZE / 2];
370
371   ASSERT (d->is_ata);
372
373   /* Send the IDENTIFY DEVICE command, wait for an interrupt
374      indicating the device's response is ready, and read the data
375      into our buffer. */
376   select_device_wait (d);
377   issue_pio_command (c, CMD_IDENTIFY_DEVICE);
378   sema_down (&c->completion_wait);
379   if (!wait_while_busy (d))
380     {
381       d->is_ata = false;
382       return;
383     }
384   input_sector (c, id);
385
386   /* Calculate capacity. */
387   d->capacity = id[60] | ((uint32_t) id[61] << 16);
388
389   /* Print identification message. */
390   printf ("%s: detected %'"PRDSNu" sector (", d->name, d->capacity);
391   if (d->capacity > 1024 / DISK_SECTOR_SIZE * 1024 * 1024)
392     printf ("%"PRDSNu" GB",
393             d->capacity / (1024 / DISK_SECTOR_SIZE * 1024 * 1024));
394   else if (d->capacity > 1024 / DISK_SECTOR_SIZE * 1024)
395     printf ("%"PRDSNu" MB", d->capacity / (1024 / DISK_SECTOR_SIZE * 1024));
396   else if (d->capacity > 1024 / DISK_SECTOR_SIZE)
397     printf ("%"PRDSNu" kB", d->capacity / (1024 / DISK_SECTOR_SIZE));
398   else
399     printf ("%"PRDSNu" byte", d->capacity * DISK_SECTOR_SIZE);
400   printf (") disk, model \"");
401   print_ata_string ((char *) &id[27], 40);
402   printf ("\", serial \"");
403   print_ata_string ((char *) &id[10], 20);
404   printf ("\"\n");
405 }
406
407 /* Prints STRING, which consists of SIZE bytes in a funky format:
408    each pair of bytes is in reverse order.  Does not print
409    trailing whitespace and/or nulls. */
410 static void
411 print_ata_string (char *string, size_t size) 
412 {
413   size_t i;
414
415   /* Find the last non-white, non-null character. */
416   for (; size > 0; size--)
417     {
418       int c = string[(size - 1) ^ 1];
419       if (c != '\0' && !isspace (c))
420         break; 
421     }
422
423   /* Print. */
424   for (i = 0; i < size; i++)
425     printf ("%c", string[i ^ 1]);
426 }
427 \f
428 /* Selects device D, waiting for it to become ready, and then
429    writes SEC_NO to the disk's sector selection registers.  (We
430    use LBA mode.) */
431 static void
432 select_sector (struct disk *d, disk_sector_t sec_no) 
433 {
434   struct channel *c = d->channel;
435
436   ASSERT (sec_no < d->capacity);
437   ASSERT (sec_no < (1UL << 28));
438   
439   select_device_wait (d);
440   outb (reg_nsect (c), 1);
441   outb (reg_lbal (c), sec_no);
442   outb (reg_lbam (c), sec_no >> 8);
443   outb (reg_lbah (c), (sec_no >> 16));
444   outb (reg_device (c),
445         DEV_MBS | DEV_LBA | (d->dev_no == 1 ? DEV_DEV : 0) | (sec_no >> 24));
446 }
447
448 /* Writes COMMAND to channel C and prepares for receiving a
449    completion interrupt. */
450 static void
451 issue_pio_command (struct channel *c, uint8_t command) 
452 {
453   /* Interrupts must be enabled or our semaphore will never be
454      up'd by the completion handler. */
455   ASSERT (intr_get_level () == INTR_ON);
456
457   c->expecting_interrupt = true;
458   outb (reg_command (c), command);
459 }
460
461 /* Reads a sector from channel C's data register in PIO mode into
462    SECTOR, which must have room for DISK_SECTOR_SIZE bytes. */
463 static void
464 input_sector (struct channel *c, void *sector) 
465 {
466   insw (reg_data (c), sector, DISK_SECTOR_SIZE / 2);
467 }
468
469 /* Writes SECTOR to channel C's data register in PIO mode.
470    SECTOR must contain DISK_SECTOR_SIZE bytes. */
471 static void
472 output_sector (struct channel *c, const void *sector) 
473 {
474   outsw (reg_data (c), sector, DISK_SECTOR_SIZE / 2);
475 }
476 \f
477 /* Low-level ATA primitives. */
478
479 /* Wait up to 10 seconds for the controller to become idle, that
480    is, for the BSY and DRQ bits to clear in the status register.
481
482    As a side effect, reading the status register clears any
483    pending interrupt. */
484 static void
485 wait_until_idle (const struct disk *d) 
486 {
487   int i;
488
489   for (i = 0; i < 1000; i++) 
490     {
491       if ((inb (reg_status (d->channel)) & (STA_BSY | STA_DRQ)) == 0)
492         return;
493       timer_usleep (10);
494     }
495
496   printf ("%s: idle timeout\n", d->name);
497 }
498
499 /* Wait up to 30 seconds for disk D to clear BSY,
500    and then return the status of the DRQ bit.
501    The ATA standards say that a disk may take as long as that to
502    complete its reset. */
503 static bool
504 wait_while_busy (const struct disk *d) 
505 {
506   struct channel *c = d->channel;
507   int i;
508   
509   for (i = 0; i < 3000; i++)
510     {
511       if (i == 700)
512         printf ("%s: busy, waiting...", d->name);
513       if (!(inb (reg_alt_status (c)) & STA_BSY)) 
514         {
515           if (i >= 700)
516             printf ("ok\n");
517           return (inb (reg_alt_status (c)) & STA_DRQ) != 0;
518         }
519       timer_msleep (10);
520     }
521
522   printf ("failed\n");
523   return false;
524 }
525
526 /* Program D's channel so that D is now the selected disk. */
527 static void
528 select_device (const struct disk *d)
529 {
530   struct channel *c = d->channel;
531   uint8_t dev = DEV_MBS;
532   if (d->dev_no == 1)
533     dev |= DEV_DEV;
534   outb (reg_device (c), dev);
535   inb (reg_alt_status (c));
536   timer_nsleep (400);
537 }
538
539 /* Select disk D in its channel, as select_device(), but wait for
540    the channel to become idle before and after. */
541 static void
542 select_device_wait (const struct disk *d) 
543 {
544   wait_until_idle (d);
545   select_device (d);
546   wait_until_idle (d);
547 }
548 \f
549 /* ATA interrupt handler. */
550 static void
551 interrupt_handler (struct intr_frame *f) 
552 {
553   struct channel *c;
554
555   for (c = channels; c < channels + CHANNEL_CNT; c++)
556     if (f->vec_no == c->irq)
557       {
558         if (c->expecting_interrupt) 
559           {
560             inb (reg_status (c));               /* Acknowledge interrupt. */
561             sema_up (&c->completion_wait);      /* Wake up waiter. */
562           }
563         else
564           printf ("%s: unexpected interrupt\n", c->name);
565         return;
566       }
567
568   NOT_REACHED ();
569 }
570
571