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