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