VirtualBox

source: vbox/trunk/src/VBox/Devices/PC/BIOS/ata.c@ 48123

Last change on this file since 48123 was 48123, checked in by vboxsync, 11 years ago

BIOS: Trailing spaces, begone!

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 38.7 KB
Line 
1/*
2 * Copyright (C) 2006-2012 Oracle Corporation
3 *
4 * This file is part of VirtualBox Open Source Edition (OSE), as
5 * available from http://www.virtualbox.org. This file is free software;
6 * you can redistribute it and/or modify it under the terms of the GNU
7 * General Public License (GPL) as published by the Free Software
8 * Foundation, in version 2 as it comes in the "COPYING" file of the
9 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
10 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
11 * --------------------------------------------------------------------
12 *
13 * This code is based on:
14 *
15 * ROM BIOS for use with Bochs/Plex86/QEMU emulation environment
16 *
17 * Copyright (C) 2002 MandrakeSoft S.A.
18 *
19 * MandrakeSoft S.A.
20 * 43, rue d'Aboukir
21 * 75002 Paris - France
22 * http://www.linux-mandrake.com/
23 * http://www.mandrakesoft.com/
24 *
25 * This library is free software; you can redistribute it and/or
26 * modify it under the terms of the GNU Lesser General Public
27 * License as published by the Free Software Foundation; either
28 * version 2 of the License, or (at your option) any later version.
29 *
30 * This library is distributed in the hope that it will be useful,
31 * but WITHOUT ANY WARRANTY; without even the implied warranty of
32 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
33 * Lesser General Public License for more details.
34 *
35 * You should have received a copy of the GNU Lesser General Public
36 * License along with this library; if not, write to the Free Software
37 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
38 *
39 */
40
41
42#include <stdint.h>
43#include <stdarg.h>
44#include "inlines.h"
45#include "biosint.h"
46#include "ebda.h"
47#include "ata.h"
48
49#if DEBUG_ATA
50# define BX_DEBUG_ATA(...) BX_DEBUG(__VA_ARGS__)
51#else
52# define BX_DEBUG_ATA(...)
53#endif
54
55
56// ---------------------------------------------------------------------------
57// Start of ATA/ATAPI Driver
58// ---------------------------------------------------------------------------
59
60void insw_discard(unsigned nwords, unsigned port);
61#pragma aux insw_discard = \
62 ".286" \
63 "again:" \
64 "in ax,dx" \
65 "loop again" \
66 parm [cx] [dx] modify exact [cx ax] nomemory;
67
68void insd_discard(unsigned ndwords, unsigned port);
69#pragma aux insd_discard = \
70 ".386" \
71 "push eax" \
72 "again:" \
73 "in eax,dx" \
74 "loop again" \
75 "pop eax" \
76 parm [cx] [dx] modify exact [cx] nomemory;
77
78// ---------------------------------------------------------------------------
79// ATA/ATAPI driver : initialization
80// ---------------------------------------------------------------------------
81void BIOSCALL ata_init(void)
82{
83 uint8_t channel, device;
84 bio_dsk_t __far *bios_dsk;
85
86 bios_dsk = read_word(0x0040, 0x000E) :> &EbdaData->bdisk;
87
88 // Channels info init.
89 for (channel=0; channel<BX_MAX_ATA_INTERFACES; channel++) {
90 bios_dsk->channels[channel].iface = ATA_IFACE_NONE;
91 bios_dsk->channels[channel].iobase1 = 0x0;
92 bios_dsk->channels[channel].iobase2 = 0x0;
93 bios_dsk->channels[channel].irq = 0;
94 }
95
96 // Devices info init.
97 for (device=0; device<BX_MAX_ATA_DEVICES; device++) {
98 bios_dsk->devices[device].type = DSK_TYPE_NONE;
99 bios_dsk->devices[device].device = DSK_DEVICE_NONE;
100 bios_dsk->devices[device].removable = 0;
101 bios_dsk->devices[device].lock = 0;
102 bios_dsk->devices[device].mode = ATA_MODE_NONE;
103 bios_dsk->devices[device].blksize = 0x200;
104 bios_dsk->devices[device].translation = GEO_TRANSLATION_NONE;
105 bios_dsk->devices[device].lchs.heads = 0;
106 bios_dsk->devices[device].lchs.cylinders = 0;
107 bios_dsk->devices[device].lchs.spt = 0;
108 bios_dsk->devices[device].pchs.heads = 0;
109 bios_dsk->devices[device].pchs.cylinders = 0;
110 bios_dsk->devices[device].pchs.spt = 0;
111 bios_dsk->devices[device].sectors = 0;
112 }
113
114 // hdidmap and cdidmap init.
115 for (device=0; device<BX_MAX_STORAGE_DEVICES; device++) {
116 bios_dsk->hdidmap[device] = BX_MAX_STORAGE_DEVICES;
117 bios_dsk->cdidmap[device] = BX_MAX_STORAGE_DEVICES;
118 }
119
120 bios_dsk->hdcount = 0;
121 bios_dsk->cdcount = 0;
122}
123
124// ---------------------------------------------------------------------------
125// ATA/ATAPI driver : software reset
126// ---------------------------------------------------------------------------
127// ATA-3
128// 8.2.1 Software reset - Device 0
129
130void ata_reset(uint16_t device)
131{
132 uint16_t iobase1, iobase2;
133 uint8_t channel, slave, sn, sc;
134 uint16_t max;
135 uint16_t pdelay;
136 bio_dsk_t __far *bios_dsk;
137
138 bios_dsk = read_word(0x0040, 0x000E) :> &EbdaData->bdisk;
139 channel = device / 2;
140 slave = device % 2;
141
142 iobase1 = bios_dsk->channels[channel].iobase1;
143 iobase2 = bios_dsk->channels[channel].iobase2;
144
145 // Reset
146
147 // 8.2.1 (a) -- set SRST in DC
148 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN | ATA_CB_DC_SRST);
149
150 // 8.2.1 (b) -- wait for BSY
151 max=0xff;
152 while(--max>0) {
153 uint8_t status = inb(iobase1+ATA_CB_STAT);
154 if ((status & ATA_CB_STAT_BSY) != 0)
155 break;
156 }
157
158 // 8.2.1 (f) -- clear SRST
159 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
160
161 if (bios_dsk->devices[device].type != DSK_TYPE_NONE) {
162 // 8.2.1 (g) -- check for sc==sn==0x01
163 // select device
164 outb(iobase1+ATA_CB_DH, slave?ATA_CB_DH_DEV1:ATA_CB_DH_DEV0);
165 sc = inb(iobase1+ATA_CB_SC);
166 sn = inb(iobase1+ATA_CB_SN);
167
168 if ( (sc==0x01) && (sn==0x01) ) {
169 // 8.2.1 (h) -- wait for not BSY
170 max=0xffff; /* The ATA specification says that the drive may be busy for up to 30 seconds. */
171 while(--max>0) {
172 uint8_t status = inb(iobase1+ATA_CB_STAT);
173 if ((status & ATA_CB_STAT_BSY) == 0)
174 break;
175 pdelay=0xffff;
176 while (--pdelay>0) {
177 /* nothing */
178 }
179 }
180 }
181 }
182
183 // 8.2.1 (i) -- wait for DRDY
184 max = 0x10; /* Speed up for virtual drives. Disks are immediately ready, CDs never */
185 while(--max>0) {
186 uint8_t status = inb(iobase1+ATA_CB_STAT);
187 if ((status & ATA_CB_STAT_RDY) != 0)
188 break;
189 }
190
191 // Enable interrupts
192 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
193}
194
195// ---------------------------------------------------------------------------
196// ATA/ATAPI driver : execute a data-in command
197// ---------------------------------------------------------------------------
198 // returns
199 // 0 : no error
200 // 1 : BUSY bit set
201 // 2 : read error
202 // 3 : expected DRQ=1
203 // 4 : no sectors left to read/verify
204 // 5 : more sectors to read/verify
205 // 6 : no sectors left to write
206 // 7 : more sectors to write
207uint16_t ata_cmd_data_in(bio_dsk_t __far *bios_dsk, uint16_t command, uint16_t count)
208{
209 uint32_t lba;
210 uint16_t iobase1, iobase2, blksize, mult_blk_cnt;
211 uint16_t cylinder;
212 uint16_t head;
213 uint16_t sector;
214 uint16_t device;
215 uint8_t channel, slave;
216 uint8_t status, mode;
217 char __far *buffer;
218
219 device = bios_dsk->drqp.dev_id;
220 channel = device / 2;
221 slave = device % 2;
222
223 iobase1 = bios_dsk->channels[channel].iobase1;
224 iobase2 = bios_dsk->channels[channel].iobase2;
225 mode = bios_dsk->devices[device].mode;
226 blksize = bios_dsk->devices[device].blksize;
227 if (blksize == 0) { /* If transfer size is exactly 64K */
228 if (mode == ATA_MODE_PIO32)
229 blksize = 0x4000;
230 else
231 blksize = 0x8000;
232 } else {
233 if (mode == ATA_MODE_PIO32)
234 blksize >>= 2;
235 else
236 blksize >>= 1;
237 }
238
239 status = inb(iobase1 + ATA_CB_STAT);
240 if (status & ATA_CB_STAT_BSY)
241 {
242 BX_DEBUG_ATA("%s: disk busy\n", __func__);
243 // Enable interrupts
244 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
245 return 1;
246 }
247
248 lba = bios_dsk->drqp.lba;
249 buffer = bios_dsk->drqp.buffer;
250 sector = bios_dsk->drqp.sector;
251 cylinder = bios_dsk->drqp.cylinder;
252 head = bios_dsk->drqp.head;
253
254 // sector will be 0 only on lba access. Convert to lba-chs
255 if (sector == 0) {
256 if (lba + count >= 268435456)
257 {
258 sector = (lba & 0xff000000L) >> 24;
259 cylinder = 0; /* The parameter lba is just a 32 bit value. */
260 outb(iobase1 + ATA_CB_SC, (count & 0xff00) >> 8);
261 outb(iobase1 + ATA_CB_SN, sector);
262 outb(iobase1 + ATA_CB_CL, cylinder & 0x00ff);
263 outb(iobase1 + ATA_CB_CH, cylinder >> 8);
264 /* Leave the bottom 24 bits as is, they are treated correctly by the
265 * LBA28 code path. */
266 lba &= 0xffffff;
267 }
268 sector = (uint16_t) (lba & 0x000000ffL);
269 lba >>= 8;
270 cylinder = (uint16_t) (lba & 0x0000ffffL);
271 lba >>= 16;
272 head = ((uint16_t) (lba & 0x0000000fL)) | 0x40;
273 }
274
275 outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
276 outb(iobase1 + ATA_CB_FR, 0x00);
277 outb(iobase1 + ATA_CB_SC, count);
278 outb(iobase1 + ATA_CB_SN, sector);
279 outb(iobase1 + ATA_CB_CL, cylinder & 0x00ff);
280 outb(iobase1 + ATA_CB_CH, cylinder >> 8);
281 outb(iobase1 + ATA_CB_DH, (slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) | (uint8_t) head );
282 outb(iobase1 + ATA_CB_CMD, command);
283
284 if (command == ATA_CMD_READ_MULTIPLE || command == ATA_CMD_READ_MULTIPLE_EXT) {
285 mult_blk_cnt = count;
286 count = 1;
287 } else {
288 mult_blk_cnt = 1;
289 }
290
291 while (1) {
292 status = inb(iobase1 + ATA_CB_STAT);
293 if ( !(status & ATA_CB_STAT_BSY) )
294 break;
295 }
296
297 if (status & ATA_CB_STAT_ERR) {
298 BX_DEBUG_ATA("%s: read error\n", __func__);
299 // Enable interrupts
300 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
301 return 2;
302 } else if ( !(status & ATA_CB_STAT_DRQ) ) {
303 BX_DEBUG_ATA("%s: DRQ not set (status %02x)\n", __func__, (unsigned) status);
304 // Enable interrupts
305 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
306 return 3;
307 }
308
309 // FIXME : move seg/off translation here
310
311 int_enable(); // enable higher priority interrupts
312
313 while (1) {
314
315 // adjust if there will be an overrun. 2K max sector size
316 if (FP_OFF(buffer) >= 0xF800)
317 buffer = MK_FP(FP_SEG(buffer) + 0x80, FP_OFF(buffer) - 0x800);
318
319 if (mode == ATA_MODE_PIO32) {
320 buffer = rep_insd(buffer, blksize, iobase1);
321 } else {
322 buffer = rep_insw(buffer, blksize, iobase1);
323 }
324 bios_dsk->drqp.trsfsectors += mult_blk_cnt;
325 count--;
326 while (1) {
327 status = inb(iobase1 + ATA_CB_STAT);
328 if ( !(status & ATA_CB_STAT_BSY) )
329 break;
330 }
331 if (count == 0) {
332 if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) )
333 != ATA_CB_STAT_RDY ) {
334 BX_DEBUG_ATA("%s: no sectors left (status %02x)\n", __func__, (unsigned) status);
335 // Enable interrupts
336 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
337 return 4;
338 }
339 break;
340 }
341 else {
342 if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) )
343 != (ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ) ) {
344 BX_DEBUG_ATA("%s: more sectors left (status %02x)\n", __func__, (unsigned) status);
345 // Enable interrupts
346 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
347 return 5;
348 }
349 continue;
350 }
351 }
352 // Enable interrupts
353 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
354 return 0;
355}
356
357// ---------------------------------------------------------------------------
358// ATA/ATAPI driver : device detection
359// ---------------------------------------------------------------------------
360
361void BIOSCALL ata_detect(void)
362{
363 uint16_t ebda_seg = read_word(0x0040,0x000E);
364 uint8_t hdcount, cdcount, device, type;
365 uint8_t buffer[0x0200];
366 bio_dsk_t __far *bios_dsk;
367
368 bios_dsk = ebda_seg :> &EbdaData->bdisk;
369
370#if BX_MAX_ATA_INTERFACES > 0
371 bios_dsk->channels[0].iface = ATA_IFACE_ISA;
372 bios_dsk->channels[0].iobase1 = 0x1f0;
373 bios_dsk->channels[0].iobase2 = 0x3f0;
374 bios_dsk->channels[0].irq = 14;
375#endif
376#if BX_MAX_ATA_INTERFACES > 1
377 bios_dsk->channels[1].iface = ATA_IFACE_ISA;
378 bios_dsk->channels[1].iobase1 = 0x170;
379 bios_dsk->channels[1].iobase2 = 0x370;
380 bios_dsk->channels[1].irq = 15;
381#endif
382#if 0 //@todo - temporarily removed to avoid conflict with AHCI
383#if BX_MAX_ATA_INTERFACES > 2
384 bios_dsk->channels[2].iface = ATA_IFACE_ISA;
385 bios_dsk->channels[2].iobase1 = 0x1e8;
386 bios_dsk->channels[2].iobase2 = 0x3e0;
387 bios_dsk->channels[2].irq = 12;
388#endif
389#if BX_MAX_ATA_INTERFACES > 3
390 bios_dsk->channels[3].iface = ATA_IFACE_ISA;
391 bios_dsk->channels[3].iobase1 = 0x168;
392 bios_dsk->channels[3].iobase2 = 0x360;
393 bios_dsk->channels[3].irq = 11;
394#endif
395#endif
396#if BX_MAX_ATA_INTERFACES > 4
397#error Please fill the ATA interface informations
398#endif
399
400 // Device detection
401 hdcount = cdcount = 0;
402
403 for (device = 0; device < BX_MAX_ATA_DEVICES; device++) {
404 uint16_t iobase1, iobase2;
405 uint8_t channel, slave;
406 uint8_t sc, sn, cl, ch, st;
407
408 channel = device / 2;
409 slave = device % 2;
410
411 iobase1 = bios_dsk->channels[channel].iobase1;
412 iobase2 = bios_dsk->channels[channel].iobase2;
413
414 // Disable interrupts
415 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
416
417 // Look for device
418 outb(iobase1+ATA_CB_DH, slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0);
419 outb(iobase1+ATA_CB_SC, 0x55);
420 outb(iobase1+ATA_CB_SN, 0xaa);
421 outb(iobase1+ATA_CB_SC, 0xaa);
422 outb(iobase1+ATA_CB_SN, 0x55);
423 outb(iobase1+ATA_CB_SC, 0x55);
424 outb(iobase1+ATA_CB_SN, 0xaa);
425
426 // If we found something
427 sc = inb(iobase1+ATA_CB_SC);
428 sn = inb(iobase1+ATA_CB_SN);
429
430 if ( (sc == 0x55) && (sn == 0xaa) ) {
431 bios_dsk->devices[device].type = DSK_TYPE_UNKNOWN;
432
433 // reset the channel
434 ata_reset(device);
435
436 // check for ATA or ATAPI
437 outb(iobase1+ATA_CB_DH, slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0);
438 sc = inb(iobase1+ATA_CB_SC);
439 sn = inb(iobase1+ATA_CB_SN);
440 if ((sc==0x01) && (sn==0x01)) {
441 cl = inb(iobase1+ATA_CB_CL);
442 ch = inb(iobase1+ATA_CB_CH);
443 st = inb(iobase1+ATA_CB_STAT);
444
445 if ((cl==0x14) && (ch==0xeb)) {
446 bios_dsk->devices[device].type = DSK_TYPE_ATAPI;
447 } else if ((cl==0x00) && (ch==0x00) && (st!=0x00)) {
448 bios_dsk->devices[device].type = DSK_TYPE_ATA;
449 } else if ((cl==0xff) && (ch==0xff)) {
450 bios_dsk->devices[device].type = DSK_TYPE_NONE;
451 }
452 }
453 }
454
455 // Enable interrupts
456 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
457
458 type = bios_dsk->devices[device].type;
459
460 // Now we send a IDENTIFY command to ATA device
461 if (type == DSK_TYPE_ATA) {
462 uint32_t sectors;
463 uint16_t cylinders, heads, spt, blksize;
464 chs_t lgeo;
465 uint8_t chsgeo_base;
466 uint8_t removable, mode;
467
468 //Temporary values to do the transfer
469 bios_dsk->devices[device].device = DSK_DEVICE_HD;
470 bios_dsk->devices[device].mode = ATA_MODE_PIO16;
471 bios_dsk->drqp.buffer = buffer;
472 bios_dsk->drqp.dev_id = device;
473
474 if (ata_cmd_data_in(bios_dsk, ATA_CMD_IDENTIFY_DEVICE, 1) !=0 )
475 BX_PANIC("ata-detect: Failed to detect ATA device\n");
476
477 removable = (*(buffer+0) & 0x80) ? 1 : 0;
478 mode = *(buffer+96) ? ATA_MODE_PIO32 : ATA_MODE_PIO16;
479 blksize = 512; /* There is no sector size field any more. */
480
481 cylinders = *(uint16_t *)(buffer+(1*2)); // word 1
482 heads = *(uint16_t *)(buffer+(3*2)); // word 3
483 spt = *(uint16_t *)(buffer+(6*2)); // word 6
484
485 sectors = *(uint32_t *)(buffer+(60*2)); // word 60 and word 61
486 /** @todo update sectors to be a 64 bit number (also lba...). */
487 if (sectors == 0x0FFFFFFF) /* For disks bigger than ~128GB */
488 sectors = *(uint32_t *)(buffer+(100*2)); // words 100 to 103 (someday)
489 switch (device)
490 {
491 case 0:
492 chsgeo_base = 0x1e;
493 break;
494 case 1:
495 chsgeo_base = 0x26;
496 break;
497 case 2:
498 chsgeo_base = 0x67;
499 break;
500 case 3:
501 chsgeo_base = 0x70;
502 break;
503 default:
504 chsgeo_base = 0;
505 }
506 if (chsgeo_base)
507 {
508 lgeo.cylinders = inb_cmos(chsgeo_base) + (inb_cmos(chsgeo_base + 1) << 8);
509 lgeo.heads = inb_cmos(chsgeo_base + 2);
510 lgeo.spt = inb_cmos(chsgeo_base + 7);
511 }
512 else
513 set_geom_lba(&lgeo, sectors); /* Default EDD-style translated LBA geometry. */
514
515 BX_INFO("ata%d-%d: PCHS=%u/%d/%d LCHS=%u/%u/%u\n", channel, slave,
516 cylinders,heads, spt, lgeo.cylinders, lgeo.heads, lgeo.spt);
517
518 bios_dsk->devices[device].device = DSK_DEVICE_HD;
519 bios_dsk->devices[device].removable = removable;
520 bios_dsk->devices[device].mode = mode;
521 bios_dsk->devices[device].blksize = blksize;
522 bios_dsk->devices[device].pchs.heads = heads;
523 bios_dsk->devices[device].pchs.cylinders = cylinders;
524 bios_dsk->devices[device].pchs.spt = spt;
525 bios_dsk->devices[device].sectors = sectors;
526 bios_dsk->devices[device].lchs = lgeo;
527 if (device < 2)
528 {
529 uint8_t sum, i;
530 fdpt_t __far *fdpt;
531
532 if (device == 0)
533 fdpt = ebda_seg :> &EbdaData->fdpt0;
534 else
535 fdpt = ebda_seg :> &EbdaData->fdpt1;
536
537 /* Update the DPT for drive 0/1 pointed to by Int41/46. This used
538 * to be done at POST time with lots of ugly assembler code, which
539 * isn't worth the effort of converting from AMI to Award CMOS
540 * format. Just do it here. */
541 fdpt->lcyl = lgeo.cylinders;
542 fdpt->lhead = lgeo.heads;
543 fdpt->sig = 0xa0;
544 fdpt->spt = spt;
545 fdpt->cyl = cylinders;
546 fdpt->head = heads;
547 fdpt->lspt = spt;
548 sum = 0;
549 for (i = 0; i < 0xf; i++)
550 sum += *((uint8_t __far *)fdpt + i);
551 sum = -sum;
552 fdpt->csum = sum;
553 }
554
555 // fill hdidmap
556 bios_dsk->hdidmap[hdcount] = device;
557 hdcount++;
558 }
559
560 // Now we send an IDENTIFY command to ATAPI device
561 if (type == DSK_TYPE_ATAPI) {
562 uint8_t type, removable, mode;
563 uint16_t blksize;
564
565 // Temporary values to do the transfer
566 bios_dsk->devices[device].device = DSK_DEVICE_CDROM;
567 bios_dsk->devices[device].mode = ATA_MODE_PIO16;
568 bios_dsk->drqp.buffer = buffer;
569 bios_dsk->drqp.dev_id = device;
570
571 if (ata_cmd_data_in(bios_dsk, ATA_CMD_IDENTIFY_PACKET, 1) != 0)
572 BX_PANIC("ata-detect: Failed to detect ATAPI device\n");
573
574 type = *(buffer+1) & 0x1f;
575 removable = (*(buffer+0) & 0x80) ? 1 : 0;
576 mode = *(buffer+96) ? ATA_MODE_PIO32 : ATA_MODE_PIO16;
577 blksize = 2048;
578
579 bios_dsk->devices[device].device = type;
580 bios_dsk->devices[device].removable = removable;
581 bios_dsk->devices[device].mode = mode;
582 bios_dsk->devices[device].blksize = blksize;
583
584 // fill cdidmap
585 bios_dsk->cdidmap[cdcount] = device;
586 cdcount++;
587 }
588
589 {
590 uint32_t sizeinmb;
591 uint16_t ataversion;
592 uint8_t version, model[41];
593 int i;
594
595 switch (type) {
596 case DSK_TYPE_ATA:
597 sizeinmb = bios_dsk->devices[device].sectors;
598 sizeinmb >>= 11;
599 case DSK_TYPE_ATAPI:
600 // Read ATA/ATAPI version
601 ataversion = ((uint16_t)(*(buffer+161))<<8) | *(buffer+160);
602 for (version = 15; version > 0; version--) {
603 if ((ataversion & (1 << version)) !=0 )
604 break;
605 }
606
607 // Read model name
608 for (i = 0; i < 20; i++ ) {
609 *(model+(i*2)) = *(buffer+(i*2)+54+1);
610 *(model+(i*2)+1) = *(buffer+(i*2)+54);
611 }
612
613 // Reformat
614 *(model+40) = 0x00;
615 for ( i = 39; i > 0; i-- ){
616 if (*(model+i) == 0x20)
617 *(model+i) = 0x00;
618 else
619 break;
620 }
621 break;
622 }
623
624#ifdef VBOXz
625 // we don't want any noisy output for now
626#else /* !VBOX */
627 switch (type) {
628 int c;
629 case DSK_TYPE_ATA:
630 printf("ata%d %s: ", channel, slave ? " slave" : "master");
631 i=0;
632 while(c=*(model+i++))
633 printf("%c", c);
634 printf(" ATA-%d Hard-Disk (%lu MBytes)\n", version, sizeinmb);
635 break;
636 case DSK_TYPE_ATAPI:
637 printf("ata%d %s: ", channel, slave ? " slave" : "master");
638 i=0;
639 while(c=*(model+i++))
640 printf("%c", c);
641 if (bios_dsk->devices[device].device == DSK_DEVICE_CDROM)
642 printf(" ATAPI-%d CD-ROM/DVD-ROM\n", version);
643 else
644 printf(" ATAPI-%d Device\n", version);
645 break;
646 case DSK_TYPE_UNKNOWN:
647 printf("ata%d %s: Unknown device\n", channel , slave ? " slave" : "master");
648 break;
649 }
650#endif /* !VBOX */
651 }
652 }
653
654 // Store the devices counts
655 bios_dsk->hdcount = hdcount;
656 bios_dsk->cdcount = cdcount;
657 write_byte(0x40,0x75, hdcount);
658
659#ifdef VBOX
660 // we don't want any noisy output for now
661#else /* !VBOX */
662 printf("\n");
663#endif /* !VBOX */
664
665 // FIXME : should use bios=cmos|auto|disable bits
666 // FIXME : should know about translation bits
667 // FIXME : move hard_drive_post here
668
669}
670
671// ---------------------------------------------------------------------------
672// ATA/ATAPI driver : execute a data-out command
673// ---------------------------------------------------------------------------
674 // returns
675 // 0 : no error
676 // 1 : BUSY bit set
677 // 2 : read error
678 // 3 : expected DRQ=1
679 // 4 : no sectors left to read/verify
680 // 5 : more sectors to read/verify
681 // 6 : no sectors left to write
682 // 7 : more sectors to write
683uint16_t ata_cmd_data_out(bio_dsk_t __far *bios_dsk, uint16_t command, uint16_t count)
684{
685 uint32_t lba;
686 char __far *buffer;
687 uint16_t iobase1, iobase2, blksize;
688 uint16_t cylinder;
689 uint16_t head;
690 uint16_t sector;
691 uint16_t device;
692 uint8_t channel, slave;
693 uint8_t status, mode;
694
695 device = bios_dsk->drqp.dev_id;
696 channel = device / 2;
697 slave = device % 2;
698
699 iobase1 = bios_dsk->channels[channel].iobase1;
700 iobase2 = bios_dsk->channels[channel].iobase2;
701 mode = bios_dsk->devices[device].mode;
702 blksize = 0x200; // was = bios_dsk->devices[device].blksize;
703 if (mode == ATA_MODE_PIO32)
704 blksize >>= 2;
705 else
706 blksize >>= 1;
707
708 status = inb(iobase1 + ATA_CB_STAT);
709 if (status & ATA_CB_STAT_BSY)
710 {
711 // Enable interrupts
712 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
713 return 1;
714 }
715
716 lba = bios_dsk->drqp.lba;
717 buffer = bios_dsk->drqp.buffer;
718 sector = bios_dsk->drqp.sector;
719 cylinder = bios_dsk->drqp.cylinder;
720 head = bios_dsk->drqp.head;
721
722 // sector will be 0 only on lba access. Convert to lba-chs
723 if (sector == 0) {
724 if (lba + count >= 268435456)
725 {
726 sector = (lba & 0xff000000L) >> 24;
727 cylinder = 0; /* The parameter lba is just a 32 bit value. */
728 outb(iobase1 + ATA_CB_SC, (count & 0xff00) >> 8);
729 outb(iobase1 + ATA_CB_SN, sector);
730 outb(iobase1 + ATA_CB_CL, cylinder & 0x00ff);
731 outb(iobase1 + ATA_CB_CH, cylinder >> 8);
732 /* Leave the bottom 24 bits as is, they are treated correctly by the
733 * LBA28 code path. */
734 lba &= 0xffffff;
735 }
736 sector = (uint16_t) (lba & 0x000000ffL);
737 lba >>= 8;
738 cylinder = (uint16_t) (lba & 0x0000ffffL);
739 lba >>= 16;
740 head = ((uint16_t) (lba & 0x0000000fL)) | 0x40;
741 }
742
743 outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
744 outb(iobase1 + ATA_CB_FR, 0x00);
745 outb(iobase1 + ATA_CB_SC, count);
746 outb(iobase1 + ATA_CB_SN, sector);
747 outb(iobase1 + ATA_CB_CL, cylinder & 0x00ff);
748 outb(iobase1 + ATA_CB_CH, cylinder >> 8);
749 outb(iobase1 + ATA_CB_DH, (slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) | (uint8_t) head );
750 outb(iobase1 + ATA_CB_CMD, command);
751
752 while (1) {
753 status = inb(iobase1 + ATA_CB_STAT);
754 if ( !(status & ATA_CB_STAT_BSY) )
755 break;
756 }
757
758 if (status & ATA_CB_STAT_ERR) {
759 BX_DEBUG_ATA("%s: write error\n", __func__);
760 // Enable interrupts
761 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
762 return 2;
763 } else if ( !(status & ATA_CB_STAT_DRQ) ) {
764 BX_DEBUG_ATA("%s: DRQ not set (status %02x)\n", __func__, (unsigned) status);
765 // Enable interrupts
766 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
767 return 3;
768 }
769
770 // FIXME : move seg/off translation here
771
772 int_enable(); // enable higher priority interrupts
773
774 while (1) {
775
776 // adjust if there will be an overrun. 2K max sector size
777 if (FP_OFF(buffer) >= 0xF800)
778 buffer = MK_FP(FP_SEG(buffer) + 0x80, FP_OFF(buffer) - 0x800);
779
780 if (mode == ATA_MODE_PIO32) {
781 buffer = rep_outsd(buffer, blksize, iobase1);
782 } else {
783 buffer = rep_outsw(buffer, blksize, iobase1);
784 }
785
786 bios_dsk->drqp.trsfsectors++;
787 count--;
788 while (1) {
789 status = inb(iobase1 + ATA_CB_STAT);
790 if ( !(status & ATA_CB_STAT_BSY) )
791 break;
792 }
793 if (count == 0) {
794 if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DF | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) )
795 != ATA_CB_STAT_RDY ) {
796 BX_DEBUG_ATA("%s: no sectors left (status %02x)\n", __func__, (unsigned) status);
797 // Enable interrupts
798 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
799 return 6;
800 }
801 break;
802 }
803 else {
804 if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) )
805 != (ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ) ) {
806 BX_DEBUG_ATA("%s: more sectors left (status %02x)\n", __func__, (unsigned) status);
807 // Enable interrupts
808 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
809 return 7;
810 }
811 continue;
812 }
813 }
814 // Enable interrupts
815 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
816 return 0;
817}
818
819
820/**
821 * Read sectors from an attached ATA device.
822 *
823 * @returns status code.
824 * @param bios_dsk Pointer to disk request packet (in the
825 * EBDA).
826 */
827int ata_read_sectors(bio_dsk_t __far *bios_dsk)
828{
829 uint16_t n_sect;
830 int status;
831 uint8_t device_id;
832
833 device_id = bios_dsk->drqp.dev_id;
834 n_sect = bios_dsk->drqp.nsect;
835
836 if (bios_dsk->drqp.sector) {
837 /* CHS addressing. */
838 bios_dsk->devices[device_id].blksize = n_sect * 0x200;
839 status = ata_cmd_data_in(bios_dsk, ATA_CMD_READ_MULTIPLE, n_sect);
840 bios_dsk->devices[device_id].blksize = 0x200;
841 } else {
842 /* LBA addressing. */
843 if (bios_dsk->drqp.lba + n_sect >= 268435456)
844 status = ata_cmd_data_in(bios_dsk, ATA_CMD_READ_SECTORS_EXT, n_sect);
845 else {
846 bios_dsk->devices[device_id].blksize = n_sect * 0x200;
847 status = ata_cmd_data_in(bios_dsk, ATA_CMD_READ_MULTIPLE, n_sect);
848 bios_dsk->devices[device_id].blksize = 0x200;
849 }
850 }
851 return status;
852}
853
854/**
855 * Write sectors to an attached ATA device.
856 *
857 * @returns status code.
858 * @param bios_dsk Pointer to disk request packet (in the
859 * EBDA).
860 */
861int ata_write_sectors(bio_dsk_t __far *bios_dsk)
862{
863 uint16_t n_sect;
864
865 n_sect = bios_dsk->drqp.nsect;
866
867 if (bios_dsk->drqp.sector) {
868 /* CHS addressing. */
869 return ata_cmd_data_out(bios_dsk, ATA_CMD_WRITE_SECTORS, n_sect);
870 } else {
871 /* LBA addressing. */
872 if (bios_dsk->drqp.lba + n_sect >= 268435456)
873 return ata_cmd_data_out(bios_dsk, ATA_CMD_WRITE_SECTORS_EXT, n_sect);
874 else
875 return ata_cmd_data_out(bios_dsk, ATA_CMD_WRITE_SECTORS, n_sect);
876 }
877}
878
879
880// ---------------------------------------------------------------------------
881// ATA/ATAPI driver : execute a packet command
882// ---------------------------------------------------------------------------
883 // returns
884 // 0 : no error
885 // 1 : error in parameters
886 // 2 : BUSY bit set
887 // 3 : error
888 // 4 : not ready
889uint16_t ata_cmd_packet(uint16_t device, uint8_t cmdlen, char __far *cmdbuf,
890 uint16_t header, uint32_t length, uint8_t inout, char __far *buffer)
891{
892 uint16_t iobase1, iobase2;
893 uint16_t lcount, lbefore, lafter, count;
894 uint8_t channel, slave;
895 uint8_t status, mode, lmode;
896 uint32_t transfer;
897 bio_dsk_t __far *bios_dsk;
898
899 bios_dsk = read_word(0x0040, 0x000E) :> &EbdaData->bdisk;
900
901 channel = device / 2;
902 slave = device % 2;
903
904 // Data out is not supported yet
905 if (inout == ATA_DATA_OUT) {
906 BX_INFO("%s: DATA_OUT not supported yet\n", __func__);
907 return 1;
908 }
909
910 // The header length must be even
911 if (header & 1) {
912 BX_DEBUG_ATA("%s: header must be even (%04x)\n", __func__, header);
913 return 1;
914 }
915
916 iobase1 = bios_dsk->channels[channel].iobase1;
917 iobase2 = bios_dsk->channels[channel].iobase2;
918 mode = bios_dsk->devices[device].mode;
919 transfer = 0L;
920
921 if (cmdlen < 12)
922 cmdlen = 12;
923 if (cmdlen > 12)
924 cmdlen = 16;
925 cmdlen >>= 1;
926
927 // Reset count of transferred data
928 // @todo: clear in calling code?
929 bios_dsk->drqp.trsfsectors = 0;
930 bios_dsk->drqp.trsfbytes = 0;
931
932 status = inb(iobase1 + ATA_CB_STAT);
933 if (status & ATA_CB_STAT_BSY)
934 return 2;
935
936 outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
937 // outb(iobase1 + ATA_CB_FR, 0x00);
938 // outb(iobase1 + ATA_CB_SC, 0x00);
939 // outb(iobase1 + ATA_CB_SN, 0x00);
940 outb(iobase1 + ATA_CB_CL, 0xfff0 & 0x00ff);
941 outb(iobase1 + ATA_CB_CH, 0xfff0 >> 8);
942 outb(iobase1 + ATA_CB_DH, slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0);
943 outb(iobase1 + ATA_CB_CMD, ATA_CMD_PACKET);
944
945 // Device should ok to receive command
946 while (1) {
947 status = inb(iobase1 + ATA_CB_STAT);
948 if ( !(status & ATA_CB_STAT_BSY) ) break;
949 }
950
951 if (status & ATA_CB_STAT_CHK) {
952 BX_DEBUG_ATA("%s: error, status is %02x\n", __func__, status);
953 // Enable interrupts
954 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
955 return 3;
956 } else if ( !(status & ATA_CB_STAT_DRQ) ) {
957 BX_DEBUG_ATA("%s: DRQ not set (status %02x)\n", __func__, (unsigned) status);
958 // Enable interrupts
959 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
960 return 4;
961 }
962
963 int_enable(); // enable higher priority interrupts
964
965 // Normalize address
966 BX_DEBUG_ATA("acp1 buffer ptr: %04x:%04x wlen %04x\n", FP_SEG(cmdbuf), FP_OFF(cmdbuf), cmdlen);
967 cmdbuf = MK_FP(FP_SEG(cmdbuf) + FP_OFF(cmdbuf) / 16 , FP_OFF(cmdbuf) % 16);
968 // cmdseg += (cmdoff / 16);
969 // cmdoff %= 16;
970
971 // Send command to device
972 rep_outsw(cmdbuf, cmdlen, iobase1);
973
974 if (inout == ATA_DATA_NO) {
975 status = inb(iobase1 + ATA_CB_STAT);
976 }
977 else {
978 while (1) {
979
980 while (1) {
981 status = inb(iobase1 + ATA_CB_STAT);
982 if ( !(status & ATA_CB_STAT_BSY) )
983 break;
984 }
985
986 // Check if command completed
987 if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_DRQ) ) ==0 )
988 break;
989
990 if (status & ATA_CB_STAT_CHK) {
991 BX_DEBUG_ATA("%s: error (status %02x)\n", __func__, status);
992 // Enable interrupts
993 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
994 return 3;
995 }
996
997 // Device must be ready to send data
998 if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_CHK) )
999 != (ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ) ) {
1000 BX_DEBUG_ATA("%s: not ready (status %02x)\n", __func__, status);
1001 // Enable interrupts
1002 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
1003 return 4;
1004 }
1005
1006 // Normalize address
1007 BX_DEBUG_ATA("acp2 buffer ptr: %04x:%04x\n", FP_SEG(buffer), FP_OFF(buffer));
1008 buffer = MK_FP(FP_SEG(buffer) + FP_OFF(buffer) / 16 , FP_OFF(buffer) % 16);
1009 // bufseg += (bufoff / 16);
1010 // bufoff %= 16;
1011
1012 // Get the byte count
1013 lcount = ((uint16_t)(inb(iobase1 + ATA_CB_CH))<<8)+inb(iobase1 + ATA_CB_CL);
1014
1015 // adjust to read what we want
1016 if (header>lcount) {
1017 lbefore = lcount;
1018 header -= lcount;
1019 lcount = 0;
1020 }
1021 else {
1022 lbefore = header;
1023 header = 0;
1024 lcount -= lbefore;
1025 }
1026
1027 if (lcount>length) {
1028 lafter = lcount - length;
1029 lcount = length;
1030 length = 0;
1031 }
1032 else {
1033 lafter = 0;
1034 length -= lcount;
1035 }
1036
1037 // Save byte count
1038 count = lcount;
1039
1040 BX_DEBUG_ATA("Trying to read %04x bytes (%04x %04x %04x) ",lbefore+lcount+lafter,lbefore,lcount,lafter);
1041 BX_DEBUG_ATA("to 0x%04x:0x%04x\n",FP_SEG(buffer),FP_OFF(buffer));
1042
1043 // If counts not dividable by 4, use 16bits mode
1044 lmode = mode;
1045 if (lbefore & 0x03)
1046 lmode = ATA_MODE_PIO16;
1047 if (lcount & 0x03)
1048 lmode = ATA_MODE_PIO16;
1049 if (lafter & 0x03)
1050 lmode = ATA_MODE_PIO16;
1051
1052 // adds an extra byte if count are odd. before is always even
1053 if (lcount & 0x01) {
1054 lcount += 1;
1055 if ((lafter > 0) && (lafter & 0x01)) {
1056 lafter -= 1;
1057 }
1058 }
1059
1060 if (lmode == ATA_MODE_PIO32) {
1061 lcount >>= 2;
1062 lbefore >>= 2;
1063 lafter >>= 2;
1064 }
1065 else {
1066 lcount >>= 1;
1067 lbefore >>= 1;
1068 lafter >>= 1;
1069 }
1070
1071 if (lmode == ATA_MODE_PIO32) {
1072 if (lbefore)
1073 insd_discard(lbefore, iobase1);
1074 rep_insd(buffer, lcount, iobase1);
1075 if (lafter)
1076 insd_discard(lafter, iobase1);
1077 } else {
1078 if (lbefore)
1079 insw_discard(lbefore, iobase1);
1080 rep_insw(buffer, lcount, iobase1);
1081 if (lafter)
1082 insw_discard(lafter, iobase1);
1083 }
1084
1085
1086 // Compute new buffer address
1087 buffer += count;
1088
1089 // Save transferred bytes count
1090 transfer += count;
1091 bios_dsk->drqp.trsfbytes = transfer;
1092 }
1093 }
1094
1095 // Final check, device must be ready
1096 if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DF | ATA_CB_STAT_DRQ | ATA_CB_STAT_CHK) )
1097 != ATA_CB_STAT_RDY ) {
1098 BX_DEBUG_ATA("%s: not ready (status %02x)\n", __func__, (unsigned) status);
1099 // Enable interrupts
1100 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
1101 return 4;
1102 }
1103
1104 // Enable interrupts
1105 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
1106 return 0;
1107}
1108
1109// ---------------------------------------------------------------------------
1110// ATA/ATAPI driver : reset device; intended for ATAPI devices
1111// ---------------------------------------------------------------------------
1112 // returns
1113 // 0 : no error
1114 // 1 : error
1115uint16_t ata_soft_reset(uint16_t device)
1116{
1117 uint16_t iobase1, iobase2;
1118 uint8_t channel, slave;
1119 uint8_t status;
1120 bio_dsk_t __far *bios_dsk;
1121
1122 bios_dsk = read_word(0x0040, 0x000E) :> &EbdaData->bdisk;
1123
1124 channel = device / 2;
1125 slave = device % 2;
1126
1127 iobase1 = bios_dsk->channels[channel].iobase1;
1128 iobase2 = bios_dsk->channels[channel].iobase2;
1129
1130 /* Send a reset command to the device. */
1131 outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
1132 outb(iobase1 + ATA_CB_DH, slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0);
1133 outb(iobase1 + ATA_CB_CMD, ATA_CMD_DEVICE_RESET);
1134
1135 /* Wait for the device to clear BSY. */
1136 while (1) {
1137 status = inb(iobase1 + ATA_CB_STAT);
1138 if ( !(status & ATA_CB_STAT_BSY) ) break;
1139 }
1140
1141 /* Final check, device must be ready */
1142 if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DF | ATA_CB_STAT_DRQ | ATA_CB_STAT_CHK) )
1143 != ATA_CB_STAT_RDY ) {
1144 BX_DEBUG_ATA("%s: not ready (status %02x)\n", __func__, (unsigned) status);
1145 /* Enable interrupts */
1146 outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15);
1147 return 1;
1148 }
1149
1150 /* Enable interrupts */
1151 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
1152 return 0;
1153}
1154
1155
1156// ---------------------------------------------------------------------------
1157// End of ATA/ATAPI Driver
1158// ---------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette