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