1 #include "devices/disk.h"
6 #include "devices/timer.h"
7 #include "threads/io.h"
8 #include "threads/interrupt.h"
9 #include "threads/synch.h"
11 /* The code in this file is an interface to an ATA (IDE)
12 controller. It attempts to comply to [ATA-3]. */
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). */
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). */
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. */
36 /* Control Register bits. */
37 #define CTL_SRST 0x04 /* Software Reset. */
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. */
45 Many more are defined but this is the small subset that we
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. */
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. */
58 bool is_ata
; /* 1=This device is an ATA disk. */
59 disk_sector_t capacity
; /* Capacity in sectors (if is_ata). */
61 long long read_cnt
; /* Number of sectors read. */
62 long long write_cnt
; /* Number of sectors written. */
65 /* An ATA channel (aka controller).
66 Each channel can control up to two disks. */
69 char name
[8]; /* Name, e.g. "hd0". */
70 uint16_t reg_base
; /* Base I/O port. */
71 uint8_t irq
; /* Interrupt in use. */
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. */
78 struct disk devices
[2]; /* The devices on this channel. */
81 /* We support the two "legacy" ATA channels found in a standard PC. */
83 static struct channel channels
[CHANNEL_CNT
];
85 static void reset_channel (struct channel
*);
86 static bool check_device_type (struct disk
*);
87 static void identify_ata_device (struct disk
*);
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 *);
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
*);
99 static void interrupt_handler (struct intr_frame
*);
101 /* Initialize the disk subsystem and detect disks. */
107 for (chan_no
= 0; chan_no
< CHANNEL_CNT
; chan_no
++)
109 struct channel
*c
= &channels
[chan_no
];
112 /* Initialize channel. */
113 snprintf (c
->name
, sizeof c
->name
, "hd%zu", chan_no
);
127 lock_init (&c
->lock
);
128 c
->expecting_interrupt
= false;
129 sema_init (&c
->completion_wait
, 0);
131 /* Initialize devices. */
132 for (dev_no
= 0; dev_no
< 2; dev_no
++)
134 struct disk
*d
= &c
->devices
[dev_no
];
135 snprintf (d
->name
, sizeof d
->name
, "%s:%d", c
->name
, dev_no
);
142 d
->read_cnt
= d
->write_cnt
= 0;
145 /* Register interrupt handler. */
146 intr_register_ext (c
->irq
, interrupt_handler
, c
->name
);
148 /* Reset hardware. */
151 /* Distinguish ATA hard disks from other devices. */
152 if (check_device_type (&c
->devices
[0]))
153 check_device_type (&c
->devices
[1]);
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
]);
162 /* Prints disk statistics. */
164 disk_print_stats (void)
168 for (chan_no
= 0; chan_no
< CHANNEL_CNT
; chan_no
++)
172 for (dev_no
= 0; dev_no
< 2; dev_no
++)
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
);
182 /* Returns the disk numbered DEV_NO--either 0 or 1 for master or
183 slave, respectively--within the channel numbered CHAN_NO.
185 Pintos uses disks this way:
186 0:0 - boot loader, command line args, and operating system kernel
192 disk_get (int chan_no
, int dev_no
)
194 ASSERT (dev_no
== 0 || dev_no
== 1);
196 if (chan_no
< (int) CHANNEL_CNT
)
198 struct disk
*d
= &channels
[chan_no
].devices
[dev_no
];
205 /* Returns the size of disk D, measured in DISK_SECTOR_SIZE-byte
208 disk_size (struct disk
*d
)
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. */
220 disk_read (struct disk
*d
, disk_sector_t sec_no
, void *buffer
)
225 ASSERT (buffer
!= NULL
);
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
);
236 lock_release (&c
->lock
);
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. */
245 disk_write (struct disk
*d
, disk_sector_t sec_no
, const void *buffer
)
250 ASSERT (buffer
!= NULL
);
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
);
261 lock_release (&c
->lock
);
264 /* Disk detection and identification. */
266 static void print_ata_string (char *string
, size_t size
);
268 /* Resets an ATA channel and waits for any devices present on it
269 to finish the reset. */
271 reset_channel (struct channel
*c
)
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
++)
280 struct disk
*d
= &c
->devices
[dev_no
];
284 outb (reg_nsect (c
), 0x55);
285 outb (reg_lbal (c
), 0xaa);
287 outb (reg_nsect (c
), 0xaa);
288 outb (reg_lbal (c
), 0x55);
290 outb (reg_nsect (c
), 0x55);
291 outb (reg_lbal (c
), 0xaa);
293 present
[dev_no
] = (inb (reg_nsect (c
)) == 0x55
294 && inb (reg_lbal (c
)) == 0xaa);
297 /* Issue soft reset sequence, which selects device 0 as a side effect.
298 Also enable interrupts. */
299 outb (reg_ctl (c
), 0);
301 outb (reg_ctl (c
), CTL_SRST
);
303 outb (reg_ctl (c
), 0);
307 /* Wait for device 0 to clear BSY. */
310 select_device (&c
->devices
[0]);
311 wait_while_busy (&c
->devices
[0]);
314 /* Wait for device 1 to clear BSY. */
319 select_device (&c
->devices
[1]);
320 for (i
= 0; i
< 3000; i
++)
322 if (inb (reg_nsect (c
)) == 1 && inb (reg_lbal (c
)) == 1)
326 wait_while_busy (&c
->devices
[1]);
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
336 check_device_type (struct disk
*d
)
338 struct channel
*c
= d
->channel
;
339 uint8_t error
, lbam
, lbah
, status
;
343 error
= inb (reg_error (c
));
344 lbam
= inb (reg_lbam (c
));
345 lbah
= inb (reg_lbah (c
));
346 status
= inb (reg_status (c
));
348 if ((error
!= 1 && (error
!= 0x81 || d
->dev_no
== 1))
349 || (status
& STA_DRDY
) == 0
350 || (status
& STA_BSY
) != 0)
353 return error
!= 0x81;
357 d
->is_ata
= (lbam
== 0 && lbah
== 0) || (lbam
== 0x3c && lbah
== 0xc3);
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. */
366 identify_ata_device (struct disk
*d
)
368 struct channel
*c
= d
->channel
;
369 uint16_t id
[DISK_SECTOR_SIZE
/ 2];
373 /* Send the IDENTIFY DEVICE command, wait for an interrupt
374 indicating the device's response is ready, and read the data
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
))
384 input_sector (c
, id
);
386 /* Calculate capacity. */
387 d
->capacity
= id
[60] | ((uint32_t) id
[61] << 16);
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
));
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);
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. */
411 print_ata_string (char *string
, size_t size
)
415 /* Find the last non-white, non-null character. */
416 for (; size
> 0; size
--)
418 int c
= string
[(size
- 1) ^ 1];
419 if (c
!= '\0' && !isspace (c
))
424 for (i
= 0; i
< size
; i
++)
425 printf ("%c", string
[i
^ 1]);
428 /* Selects device D, waiting for it to become ready, and then
429 writes SEC_NO to the disk's sector selection registers. (We
432 select_sector (struct disk
*d
, disk_sector_t sec_no
)
434 struct channel
*c
= d
->channel
;
436 ASSERT (sec_no
< d
->capacity
);
437 ASSERT (sec_no
< (1UL << 28));
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));
448 /* Writes COMMAND to channel C and prepares for receiving a
449 completion interrupt. */
451 issue_pio_command (struct channel
*c
, uint8_t command
)
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
);
457 c
->expecting_interrupt
= true;
458 outb (reg_command (c
), command
);
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. */
464 input_sector (struct channel
*c
, void *sector
)
466 insw (reg_data (c
), sector
, DISK_SECTOR_SIZE
/ 2);
469 /* Writes SECTOR to channel C's data register in PIO mode.
470 SECTOR must contain DISK_SECTOR_SIZE bytes. */
472 output_sector (struct channel
*c
, const void *sector
)
474 outsw (reg_data (c
), sector
, DISK_SECTOR_SIZE
/ 2);
477 /* Low-level ATA primitives. */
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.
482 As a side effect, reading the status register clears any
483 pending interrupt. */
485 wait_until_idle (const struct disk
*d
)
489 for (i
= 0; i
< 1000; i
++)
491 if ((inb (reg_status (d
->channel
)) & (STA_BSY
| STA_DRQ
)) == 0)
496 printf ("%s: idle timeout\n", d
->name
);
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. */
504 wait_while_busy (const struct disk
*d
)
506 struct channel
*c
= d
->channel
;
509 for (i
= 0; i
< 3000; i
++)
512 printf ("%s: busy, waiting...", d
->name
);
513 if (!(inb (reg_alt_status (c
)) & STA_BSY
))
517 return (inb (reg_alt_status (c
)) & STA_DRQ
) != 0;
526 /* Program D's channel so that D is now the selected disk. */
528 select_device (const struct disk
*d
)
530 struct channel
*c
= d
->channel
;
531 uint8_t dev
= DEV_MBS
;
534 outb (reg_device (c
), dev
);
535 inb (reg_alt_status (c
));
539 /* Select disk D in its channel, as select_device(), but wait for
540 the channel to become idle before and after. */
542 select_device_wait (const struct disk
*d
)
549 /* ATA interrupt handler. */
551 interrupt_handler (struct intr_frame
*f
)
555 for (c
= channels
; c
< channels
+ CHANNEL_CNT
; c
++)
556 if (f
->vec_no
== c
->irq
)
558 if (c
->expecting_interrupt
)
560 inb (reg_status (c
)); /* Acknowledge interrupt. */
561 sema_up (&c
->completion_wait
); /* Wake up waiter. */
564 printf ("%s: unexpected interrupt\n", c
->name
);