00001 #include "devices/ide.h"
00002
00003 #include <ctype.h>
00004 #include <debug.h>
00005 #include <stdbool.h>
00006 #include <stdio.h>
00007 #include "devices/block.h"
00008 #include "devices/partition.h"
00009 #include "devices/timer.h"
00010 #include "threads/io.h"
00011 #include "threads/interrupt.h"
00012 #include "threads/synch.h"
00013
00014
00015
00016
00017
00018 #define reg_data(CHANNEL) ((CHANNEL)->reg_base + 0)
00019 #define reg_error(CHANNEL) ((CHANNEL)->reg_base + 1)
00020 #define reg_nsect(CHANNEL) ((CHANNEL)->reg_base + 2)
00021 #define reg_lbal(CHANNEL) ((CHANNEL)->reg_base + 3)
00022 #define reg_lbam(CHANNEL) ((CHANNEL)->reg_base + 4)
00023 #define reg_lbah(CHANNEL) ((CHANNEL)->reg_base + 5)
00024 #define reg_device(CHANNEL) ((CHANNEL)->reg_base + 6)
00025 #define reg_status(CHANNEL) ((CHANNEL)->reg_base + 7)
00026 #define reg_command(CHANNEL) reg_status (CHANNEL)
00027
00028
00029
00030
00031 #define reg_ctl(CHANNEL) ((CHANNEL)->reg_base + 0x206)
00032 #define reg_alt_status(CHANNEL) reg_ctl (CHANNEL)
00033
00034
00035 #define STA_BSY 0x80
00036 #define STA_DRDY 0x40
00037 #define STA_DRQ 0x08
00038
00039
00040 #define CTL_SRST 0x04
00041
00042
00043 #define DEV_MBS 0xa0
00044 #define DEV_LBA 0x40
00045 #define DEV_DEV 0x10
00046
00047
00048
00049
00050 #define CMD_IDENTIFY_DEVICE 0xec
00051 #define CMD_READ_SECTOR_RETRY 0x20
00052 #define CMD_WRITE_SECTOR_RETRY 0x30
00053
00054
00055 struct ata_disk
00056 {
00057 char name[8];
00058 struct channel *channel;
00059 int dev_no;
00060 bool is_ata;
00061 };
00062
00063
00064
00065 struct channel
00066 {
00067 char name[8];
00068 uint16_t reg_base;
00069 uint8_t irq;
00070
00071 struct lock lock;
00072 bool expecting_interrupt;
00073
00074 struct semaphore completion_wait;
00075
00076 struct ata_disk devices[2];
00077 };
00078
00079
00080 #define CHANNEL_CNT 2
00081 static struct channel channels[CHANNEL_CNT];
00082
00083 static struct block_operations ide_operations;
00084
00085 static void reset_channel (struct channel *);
00086 static bool check_device_type (struct ata_disk *);
00087 static void identify_ata_device (struct ata_disk *);
00088
00089 static void select_sector (struct ata_disk *, block_sector_t);
00090 static void issue_pio_command (struct channel *, uint8_t command);
00091 static void input_sector (struct channel *, void *);
00092 static void output_sector (struct channel *, const void *);
00093
00094 static void wait_until_idle (const struct ata_disk *);
00095 static bool wait_while_busy (const struct ata_disk *);
00096 static void select_device (const struct ata_disk *);
00097 static void select_device_wait (const struct ata_disk *);
00098
00099 static void interrupt_handler (struct intr_frame *);
00100
00101
00102 void
00103 ide_init (void)
00104 {
00105 size_t chan_no;
00106
00107 for (chan_no = 0; chan_no < CHANNEL_CNT; chan_no++)
00108 {
00109 struct channel *c = &channels[chan_no];
00110 int dev_no;
00111
00112
00113 snprintf (c->name, sizeof c->name, "ide%zu", chan_no);
00114 switch (chan_no)
00115 {
00116 case 0:
00117 c->reg_base = 0x1f0;
00118 c->irq = 14 + 0x20;
00119 break;
00120 case 1:
00121 c->reg_base = 0x170;
00122 c->irq = 15 + 0x20;
00123 break;
00124 default:
00125 NOT_REACHED ();
00126 }
00127 lock_init (&c->lock);
00128 c->expecting_interrupt = false;
00129 sema_init (&c->completion_wait, 0);
00130
00131
00132 for (dev_no = 0; dev_no < 2; dev_no++)
00133 {
00134 struct ata_disk *d = &c->devices[dev_no];
00135 snprintf (d->name, sizeof d->name,
00136 "hd%c", 'a' + chan_no * 2 + dev_no);
00137 d->channel = c;
00138 d->dev_no = dev_no;
00139 d->is_ata = false;
00140 }
00141
00142
00143 intr_register_ext (c->irq, interrupt_handler, c->name);
00144
00145
00146 reset_channel (c);
00147
00148
00149 if (check_device_type (&c->devices[0]))
00150 check_device_type (&c->devices[1]);
00151
00152
00153 for (dev_no = 0; dev_no < 2; dev_no++)
00154 if (c->devices[dev_no].is_ata)
00155 identify_ata_device (&c->devices[dev_no]);
00156 }
00157 }
00158
00159
00160
00161 static char *descramble_ata_string (char *, int size);
00162
00163
00164
00165 static void
00166 reset_channel (struct channel *c)
00167 {
00168 bool present[2];
00169 int dev_no;
00170
00171
00172
00173 for (dev_no = 0; dev_no < 2; dev_no++)
00174 {
00175 struct ata_disk *d = &c->devices[dev_no];
00176
00177 select_device (d);
00178
00179 outb (reg_nsect (c), 0x55);
00180 outb (reg_lbal (c), 0xaa);
00181
00182 outb (reg_nsect (c), 0xaa);
00183 outb (reg_lbal (c), 0x55);
00184
00185 outb (reg_nsect (c), 0x55);
00186 outb (reg_lbal (c), 0xaa);
00187
00188 present[dev_no] = (inb (reg_nsect (c)) == 0x55
00189 && inb (reg_lbal (c)) == 0xaa);
00190 }
00191
00192
00193
00194 outb (reg_ctl (c), 0);
00195 timer_usleep (10);
00196 outb (reg_ctl (c), CTL_SRST);
00197 timer_usleep (10);
00198 outb (reg_ctl (c), 0);
00199
00200 timer_msleep (150);
00201
00202
00203 if (present[0])
00204 {
00205 select_device (&c->devices[0]);
00206 wait_while_busy (&c->devices[0]);
00207 }
00208
00209
00210 if (present[1])
00211 {
00212 int i;
00213
00214 select_device (&c->devices[1]);
00215 for (i = 0; i < 3000; i++)
00216 {
00217 if (inb (reg_nsect (c)) == 1 && inb (reg_lbal (c)) == 1)
00218 break;
00219 timer_msleep (10);
00220 }
00221 wait_while_busy (&c->devices[1]);
00222 }
00223 }
00224
00225
00226
00227
00228
00229
00230 static bool
00231 check_device_type (struct ata_disk *d)
00232 {
00233 struct channel *c = d->channel;
00234 uint8_t error, lbam, lbah, status;
00235
00236 select_device (d);
00237
00238 error = inb (reg_error (c));
00239 lbam = inb (reg_lbam (c));
00240 lbah = inb (reg_lbah (c));
00241 status = inb (reg_status (c));
00242
00243 if ((error != 1 && (error != 0x81 || d->dev_no == 1))
00244 || (status & STA_DRDY) == 0
00245 || (status & STA_BSY) != 0)
00246 {
00247 d->is_ata = false;
00248 return error != 0x81;
00249 }
00250 else
00251 {
00252 d->is_ata = (lbam == 0 && lbah == 0) || (lbam == 0x3c && lbah == 0xc3);
00253 return true;
00254 }
00255 }
00256
00257
00258
00259
00260 static void
00261 identify_ata_device (struct ata_disk *d)
00262 {
00263 struct channel *c = d->channel;
00264 char id[BLOCK_SECTOR_SIZE];
00265 block_sector_t capacity;
00266 char *model, *serial;
00267 char extra_info[128];
00268 struct block *block;
00269
00270 ASSERT (d->is_ata);
00271
00272
00273
00274
00275 select_device_wait (d);
00276 issue_pio_command (c, CMD_IDENTIFY_DEVICE);
00277 sema_down (&c->completion_wait);
00278 if (!wait_while_busy (d))
00279 {
00280 d->is_ata = false;
00281 return;
00282 }
00283 input_sector (c, id);
00284
00285
00286
00287 capacity = *(uint32_t *) &id[60 * 2];
00288 model = descramble_ata_string (&id[10 * 2], 20);
00289 serial = descramble_ata_string (&id[27 * 2], 40);
00290 snprintf (extra_info, sizeof extra_info,
00291 "model \"%s\", serial \"%s\"", model, serial);
00292
00293
00294
00295
00296
00297
00298 if (capacity >= 1024 * 1024 * 1024 / BLOCK_SECTOR_SIZE)
00299 {
00300 printf ("%s: ignoring ", d->name);
00301 print_human_readable_size (capacity * 512);
00302 printf ("disk for safety\n");
00303 d->is_ata = false;
00304 return;
00305 }
00306
00307
00308 block = block_register (d->name, BLOCK_RAW, extra_info, capacity,
00309 &ide_operations, d);
00310 partition_scan (block);
00311 }
00312
00313
00314
00315
00316 static char *
00317 descramble_ata_string (char *string, int size)
00318 {
00319 int i;
00320
00321
00322 for (i = 0; i + 1 < size; i += 2)
00323 {
00324 char tmp = string[i];
00325 string[i] = string[i + 1];
00326 string[i + 1] = tmp;
00327 }
00328
00329
00330 for (size--; size > 0; size--)
00331 {
00332 int c = string[size - 1];
00333 if (c != '\0' && !isspace (c))
00334 break;
00335 }
00336 string[size] = '\0';
00337
00338 return string;
00339 }
00340
00341
00342
00343
00344
00345 static void
00346 ide_read (void *d_, block_sector_t sec_no, void *buffer)
00347 {
00348 struct ata_disk *d = d_;
00349 struct channel *c = d->channel;
00350 lock_acquire (&c->lock);
00351 select_sector (d, sec_no);
00352 issue_pio_command (c, CMD_READ_SECTOR_RETRY);
00353 sema_down (&c->completion_wait);
00354 if (!wait_while_busy (d))
00355 PANIC ("%s: disk read failed, sector=%"PRDSNu, d->name, sec_no);
00356 input_sector (c, buffer);
00357 lock_release (&c->lock);
00358 }
00359
00360
00361
00362
00363
00364
00365 static void
00366 ide_write (void *d_, block_sector_t sec_no, const void *buffer)
00367 {
00368 struct ata_disk *d = d_;
00369 struct channel *c = d->channel;
00370 lock_acquire (&c->lock);
00371 select_sector (d, sec_no);
00372 issue_pio_command (c, CMD_WRITE_SECTOR_RETRY);
00373 if (!wait_while_busy (d))
00374 PANIC ("%s: disk write failed, sector=%"PRDSNu, d->name, sec_no);
00375 output_sector (c, buffer);
00376 sema_down (&c->completion_wait);
00377 lock_release (&c->lock);
00378 }
00379
00380 static struct block_operations ide_operations =
00381 {
00382 ide_read,
00383 ide_write
00384 };
00385
00386
00387
00388
00389 static void
00390 select_sector (struct ata_disk *d, block_sector_t sec_no)
00391 {
00392 struct channel *c = d->channel;
00393
00394 ASSERT (sec_no < (1UL << 28));
00395
00396 select_device_wait (d);
00397 outb (reg_nsect (c), 1);
00398 outb (reg_lbal (c), sec_no);
00399 outb (reg_lbam (c), sec_no >> 8);
00400 outb (reg_lbah (c), (sec_no >> 16));
00401 outb (reg_device (c),
00402 DEV_MBS | DEV_LBA | (d->dev_no == 1 ? DEV_DEV : 0) | (sec_no >> 24));
00403 }
00404
00405
00406
00407 static void
00408 issue_pio_command (struct channel *c, uint8_t command)
00409 {
00410
00411
00412 ASSERT (intr_get_level () == INTR_ON);
00413
00414 c->expecting_interrupt = true;
00415 outb (reg_command (c), command);
00416 }
00417
00418
00419
00420 static void
00421 input_sector (struct channel *c, void *sector)
00422 {
00423 insw (reg_data (c), sector, BLOCK_SECTOR_SIZE / 2);
00424 }
00425
00426
00427
00428 static void
00429 output_sector (struct channel *c, const void *sector)
00430 {
00431 outsw (reg_data (c), sector, BLOCK_SECTOR_SIZE / 2);
00432 }
00433
00434
00435
00436
00437
00438
00439
00440
00441 static void
00442 wait_until_idle (const struct ata_disk *d)
00443 {
00444 int i;
00445
00446 for (i = 0; i < 1000; i++)
00447 {
00448 if ((inb (reg_status (d->channel)) & (STA_BSY | STA_DRQ)) == 0)
00449 return;
00450 timer_usleep (10);
00451 }
00452
00453 printf ("%s: idle timeout\n", d->name);
00454 }
00455
00456
00457
00458
00459
00460 static bool
00461 wait_while_busy (const struct ata_disk *d)
00462 {
00463 struct channel *c = d->channel;
00464 int i;
00465
00466 for (i = 0; i < 3000; i++)
00467 {
00468 if (i == 700)
00469 printf ("%s: busy, waiting...", d->name);
00470 if (!(inb (reg_alt_status (c)) & STA_BSY))
00471 {
00472 if (i >= 700)
00473 printf ("ok\n");
00474 return (inb (reg_alt_status (c)) & STA_DRQ) != 0;
00475 }
00476 timer_msleep (10);
00477 }
00478
00479 printf ("failed\n");
00480 return false;
00481 }
00482
00483
00484 static void
00485 select_device (const struct ata_disk *d)
00486 {
00487 struct channel *c = d->channel;
00488 uint8_t dev = DEV_MBS;
00489 if (d->dev_no == 1)
00490 dev |= DEV_DEV;
00491 outb (reg_device (c), dev);
00492 inb (reg_alt_status (c));
00493 timer_nsleep (400);
00494 }
00495
00496
00497
00498 static void
00499 select_device_wait (const struct ata_disk *d)
00500 {
00501 wait_until_idle (d);
00502 select_device (d);
00503 wait_until_idle (d);
00504 }
00505
00506
00507 static void
00508 interrupt_handler (struct intr_frame *f)
00509 {
00510 struct channel *c;
00511
00512 for (c = channels; c < channels + CHANNEL_CNT; c++)
00513 if (f->vec_no == c->irq)
00514 {
00515 if (c->expecting_interrupt)
00516 {
00517 inb (reg_status (c));
00518 sema_up (&c->completion_wait);
00519 }
00520 else
00521 printf ("%s: unexpected interrupt\n", c->name);
00522 return;
00523 }
00524
00525 NOT_REACHED ();
00526 }
00527
00528