VirtualBox

source: vbox/trunk/src/VBox/Devices/PC/BIOS-new/ata.c@ 38876

Last change on this file since 38876 was 38848, checked in by vboxsync, 13 years ago

Integrated basic AHCI support into new BIOS.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 36.6 KB
Line 
1/*
2 * Copyright (C) 2006-2011 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 uint16_t ebda_seg=read_word(0x0040,0x000E);
84 uint8_t channel, device;
85 ata_t __far *AtaData;
86
87 AtaData = ebda_seg :> &EbdaData->ata;
88
89 // Channels info init.
90 for (channel=0; channel<BX_MAX_ATA_INTERFACES; channel++) {
91 AtaData->channels[channel].iface = ATA_IFACE_NONE;
92 AtaData->channels[channel].iobase1 = 0x0;
93 AtaData->channels[channel].iobase2 = 0x0;
94 AtaData->channels[channel].irq = 0;
95 }
96
97 // Devices info init.
98 for (device=0; device<BX_MAX_ATA_DEVICES; device++) {
99 AtaData->devices[device].type = ATA_TYPE_NONE;
100 AtaData->devices[device].device = ATA_DEVICE_NONE;
101 AtaData->devices[device].removable = 0;
102 AtaData->devices[device].lock = 0;
103 AtaData->devices[device].mode = ATA_MODE_NONE;
104 AtaData->devices[device].blksize = 0x200;
105 AtaData->devices[device].translation = ATA_TRANSLATION_NONE;
106 AtaData->devices[device].lchs.heads = 0;
107 AtaData->devices[device].lchs.cylinders = 0;
108 AtaData->devices[device].lchs.spt = 0;
109 AtaData->devices[device].pchs.heads = 0;
110 AtaData->devices[device].pchs.cylinders = 0;
111 AtaData->devices[device].pchs.spt = 0;
112 AtaData->devices[device].sectors = 0;
113 }
114
115 // hdidmap and cdidmap init.
116 for (device=0; device<BX_MAX_STORAGE_DEVICES; device++) {
117 AtaData->hdidmap[device] = BX_MAX_STORAGE_DEVICES;
118 AtaData->cdidmap[device] = BX_MAX_STORAGE_DEVICES;
119 }
120
121 AtaData->hdcount = 0;
122 AtaData->cdcount = 0;
123}
124
125// ---------------------------------------------------------------------------
126// ATA/ATAPI driver : software reset
127// ---------------------------------------------------------------------------
128// ATA-3
129// 8.2.1 Software reset - Device 0
130
131void ata_reset(uint16_t device)
132{
133 uint16_t ebda_seg = read_word(0x0040,0x000E);
134 uint16_t iobase1, iobase2;
135 uint8_t channel, slave, sn, sc;
136 uint16_t max;
137 uint16_t pdelay;
138 ata_t __far *AtaData;
139
140 AtaData = ebda_seg :> &EbdaData->ata;
141 channel = device / 2;
142 slave = device % 2;
143
144 iobase1 = AtaData->channels[channel].iobase1;
145 iobase2 = AtaData->channels[channel].iobase2;
146
147 // Reset
148
149 // 8.2.1 (a) -- set SRST in DC
150 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN | ATA_CB_DC_SRST);
151
152 // 8.2.1 (b) -- wait for BSY
153 max=0xff;
154 while(--max>0) {
155 uint8_t status = inb(iobase1+ATA_CB_STAT);
156 if ((status & ATA_CB_STAT_BSY) != 0)
157 break;
158 }
159
160 // 8.2.1 (f) -- clear SRST
161 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
162
163 if (AtaData->devices[device].type != ATA_TYPE_NONE) {
164 // 8.2.1 (g) -- check for sc==sn==0x01
165 // select device
166 outb(iobase1+ATA_CB_DH, slave?ATA_CB_DH_DEV1:ATA_CB_DH_DEV0);
167 sc = inb(iobase1+ATA_CB_SC);
168 sn = inb(iobase1+ATA_CB_SN);
169
170 if ( (sc==0x01) && (sn==0x01) ) {
171 // 8.2.1 (h) -- wait for not BSY
172 max=0xffff; /* The ATA specification says that the drive may be busy for up to 30 seconds. */
173 while(--max>0) {
174 uint8_t status = inb(iobase1+ATA_CB_STAT);
175 if ((status & ATA_CB_STAT_BSY) == 0)
176 break;
177 pdelay=0xffff;
178 while (--pdelay>0) {
179 /* nothing */
180 }
181 }
182 }
183 }
184
185 // 8.2.1 (i) -- wait for DRDY
186 max = 0x10; /* Speed up for virtual drives. Disks are immediately ready, CDs never */
187 while(--max>0) {
188 uint8_t status = inb(iobase1+ATA_CB_STAT);
189 if ((status & ATA_CB_STAT_RDY) != 0)
190 break;
191 }
192
193 // Enable interrupts
194 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
195}
196
197// ---------------------------------------------------------------------------
198// ATA/ATAPI driver : execute a data-in command
199// ---------------------------------------------------------------------------
200 // returns
201 // 0 : no error
202 // 1 : BUSY bit set
203 // 2 : read error
204 // 3 : expected DRQ=1
205 // 4 : no sectors left to read/verify
206 // 5 : more sectors to read/verify
207 // 6 : no sectors left to write
208 // 7 : more sectors to write
209uint16_t ata_cmd_data_in(uint16_t device, uint16_t command, uint16_t count, uint16_t cylinder,
210 uint16_t head, uint16_t sector, uint32_t lba, char __far *buffer)
211{
212 uint16_t ebda_seg = read_word(0x0040,0x000E);
213 uint16_t iobase1, iobase2, blksize, mult_blk_cnt;
214 uint8_t channel, slave;
215 uint8_t status, current, mode;
216 ata_t __far *AtaData;
217
218 AtaData = ebda_seg :> &EbdaData->ata;
219
220 channel = device / 2;
221 slave = device % 2;
222
223 iobase1 = AtaData->channels[channel].iobase1;
224 iobase2 = AtaData->channels[channel].iobase2;
225 mode = AtaData->devices[device].mode;
226 blksize = AtaData->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 // sector will be 0 only on lba access. Convert to lba-chs
249 if (sector == 0) {
250 if (lba + count >= 268435456)
251 {
252 sector = (lba & 0xff000000L) >> 24;
253 cylinder = 0; /* The parameter lba is just a 32 bit value. */
254 outb(iobase1 + ATA_CB_SC, (count & 0xff00) >> 8);
255 outb(iobase1 + ATA_CB_SN, sector);
256 outb(iobase1 + ATA_CB_CL, cylinder & 0x00ff);
257 outb(iobase1 + ATA_CB_CH, cylinder >> 8);
258 /* Leave the bottom 24 bits as is, they are treated correctly by the
259 * LBA28 code path. */
260 lba &= 0xffffff;
261 }
262 sector = (uint16_t) (lba & 0x000000ffL);
263 lba >>= 8;
264 cylinder = (uint16_t) (lba & 0x0000ffffL);
265 lba >>= 16;
266 head = ((uint16_t) (lba & 0x0000000fL)) | 0x40;
267 }
268
269 // Reset count of transferred data
270 AtaData->trsfsectors = 0;
271 AtaData->trsfbytes = 0;
272 current = 0;
273
274 outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
275 outb(iobase1 + ATA_CB_FR, 0x00);
276 outb(iobase1 + ATA_CB_SC, count);
277 outb(iobase1 + ATA_CB_SN, sector);
278 outb(iobase1 + ATA_CB_CL, cylinder & 0x00ff);
279 outb(iobase1 + ATA_CB_CH, cylinder >> 8);
280 outb(iobase1 + ATA_CB_DH, (slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) | (uint8_t) head );
281 outb(iobase1 + ATA_CB_CMD, command);
282
283 if (command == ATA_CMD_READ_MULTIPLE || command == ATA_CMD_READ_MULTIPLE_EXT) {
284 mult_blk_cnt = count;
285 count = 1;
286 } else {
287 mult_blk_cnt = 1;
288 }
289
290 while (1) {
291 status = inb(iobase1 + ATA_CB_STAT);
292 if ( !(status & ATA_CB_STAT_BSY) )
293 break;
294 }
295
296 if (status & ATA_CB_STAT_ERR) {
297 BX_DEBUG_ATA("%s: read error\n", __func__);
298 // Enable interrupts
299 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
300 return 2;
301 } else if ( !(status & ATA_CB_STAT_DRQ) ) {
302 BX_DEBUG_ATA("%s: DRQ not set (status %02x)\n", __func__, (unsigned) status);
303 // Enable interrupts
304 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
305 return 3;
306 }
307
308 // FIXME : move seg/off translation here
309
310 int_enable(); // enable higher priority interrupts
311
312 while (1) {
313
314 // adjust if there will be an overrun. 2K max sector size
315 if (FP_OFF(buffer) >= 0xF800)
316 buffer = MK_FP(FP_SEG(buffer) + 0x80, FP_OFF(buffer) - 0x800);
317
318 if (mode == ATA_MODE_PIO32) {
319 buffer = rep_insd(buffer, blksize, iobase1);
320 } else {
321 buffer = rep_insw(buffer, blksize, iobase1);
322 }
323 current += mult_blk_cnt;
324 AtaData->trsfsectors = current;
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 ata_t __far *AtaData;
367
368 AtaData = ebda_seg :> &EbdaData->ata;
369
370#if BX_MAX_ATA_INTERFACES > 0
371 AtaData->channels[0].iface = ATA_IFACE_ISA;
372 AtaData->channels[0].iobase1 = 0x1f0;
373 AtaData->channels[0].iobase2 = 0x3f0;
374 AtaData->channels[0].irq = 14;
375#endif
376#if BX_MAX_ATA_INTERFACES > 1
377 AtaData->channels[1].iface = ATA_IFACE_ISA;
378 AtaData->channels[1].iobase1 = 0x170;
379 AtaData->channels[1].iobase2 = 0x370;
380 AtaData->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 AtaData->channels[2].iface = ATA_IFACE_ISA;
385 AtaData->channels[2].iobase1 = 0x1e8;
386 AtaData->channels[2].iobase2 = 0x3e0;
387 AtaData->channels[2].irq = 12;
388#endif
389#if BX_MAX_ATA_INTERFACES > 3
390 AtaData->channels[3].iface = ATA_IFACE_ISA;
391 AtaData->channels[3].iobase1 = 0x168;
392 AtaData->channels[3].iobase2 = 0x360;
393 AtaData->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 = AtaData->channels[channel].iobase1;
412 iobase2 = AtaData->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 AtaData->devices[device].type = ATA_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 AtaData->devices[device].type = ATA_TYPE_ATAPI;
447 } else if ((cl==0x00) && (ch==0x00) && (st!=0x00)) {
448 AtaData->devices[device].type = ATA_TYPE_ATA;
449 } else if ((cl==0xff) && (ch==0xff)) {
450 AtaData->devices[device].type = ATA_TYPE_NONE;
451 }
452 }
453 }
454
455 // Enable interrupts
456 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
457
458 type = AtaData->devices[device].type;
459
460 // Now we send a IDENTIFY command to ATA device
461 if (type == ATA_TYPE_ATA) {
462 uint32_t sectors;
463 uint16_t cylinders, heads, spt, blksize;
464 uint16_t lcylinders, lheads, lspt;
465 uint8_t chsgeo_base;
466 uint8_t removable, mode;
467
468 //Temporary values to do the transfer
469 AtaData->devices[device].device = ATA_DEVICE_HD;
470 AtaData->devices[device].mode = ATA_MODE_PIO16;
471
472 if (ata_cmd_data_in(device, ATA_CMD_IDENTIFY_DEVICE, 1, 0, 0, 0, 0L, buffer) !=0 )
473 BX_PANIC("ata-detect: Failed to detect ATA device\n");
474
475 removable = (*(buffer+0) & 0x80) ? 1 : 0;
476 mode = *(buffer+96) ? ATA_MODE_PIO32 : ATA_MODE_PIO16;
477 blksize = 512; /* There is no sector size field any more. */
478
479 cylinders = *(uint16_t *)(buffer+(1*2)); // word 1
480 heads = *(uint16_t *)(buffer+(3*2)); // word 3
481 spt = *(uint16_t *)(buffer+(6*2)); // word 6
482
483 sectors = *(uint32_t *)(buffer+(60*2)); // word 60 and word 61
484 /** @todo update sectors to be a 64 bit number (also lba...). */
485 if (sectors == 268435455)
486 sectors = *(uint32_t *)(buffer+(100*2)); // words 100 to 103 (someday)
487 switch (device)
488 {
489 case 0:
490 chsgeo_base = 0x1e;
491 break;
492 case 1:
493 chsgeo_base = 0x26;
494 break;
495 case 2:
496 chsgeo_base = 0x67;
497 break;
498 case 3:
499 chsgeo_base = 0x70;
500 break;
501 case 4:
502 chsgeo_base = 0x40;
503 break;
504 case 5:
505 chsgeo_base = 0x48;
506 break;
507 case 6:
508 chsgeo_base = 0x50;
509 break;
510 case 7:
511 chsgeo_base = 0x58;
512 break;
513 default:
514 chsgeo_base = 0;
515 }
516 if (chsgeo_base != 0)
517 {
518 lcylinders = inb_cmos(chsgeo_base) + (inb_cmos(chsgeo_base+1) << 8);
519 lheads = inb_cmos(chsgeo_base+2);
520 lspt = inb_cmos(chsgeo_base+7);
521 }
522 else
523 {
524 lcylinders = 0;
525 lheads = 0;
526 lspt = 0;
527 }
528 BX_INFO("ata%d-%d: PCHS=%u/%d/%d LCHS=%u/%u/%u\n", channel, slave,
529 cylinders,heads, spt, lcylinders, lheads, lspt);
530
531 AtaData->devices[device].device = ATA_DEVICE_HD;
532 AtaData->devices[device].removable = removable;
533 AtaData->devices[device].mode = mode;
534 AtaData->devices[device].blksize = blksize;
535 AtaData->devices[device].pchs.heads = heads;
536 AtaData->devices[device].pchs.cylinders = cylinders;
537 AtaData->devices[device].pchs.spt = spt;
538 AtaData->devices[device].sectors = sectors;
539 AtaData->devices[device].lchs.heads = lheads;
540 AtaData->devices[device].lchs.cylinders = lcylinders;
541 AtaData->devices[device].lchs.spt = lspt;
542 if (device < 2)
543 {
544 uint8_t sum, i;
545 fdpt_t __far *fdpt;
546
547 if (device == 0)
548 fdpt = ebda_seg :> &EbdaData->fdpt0;
549 else
550 fdpt = ebda_seg :> &EbdaData->fdpt1;
551
552 /* Update the DPT for drive 0/1 pointed to by Int41/46. This used
553 * to be done at POST time with lots of ugly assembler code, which
554 * isn't worth the effort of converting from AMI to Award CMOS
555 * format. Just do it here. */
556 fdpt->lcyl = lcylinders;
557 fdpt->lhead = lheads;
558 fdpt->sig = 0xa0;
559 fdpt->spt = spt;
560 fdpt->cyl = cylinders;
561 fdpt->head = heads;
562 fdpt->lspt = spt;
563 sum = 0;
564 for (i = 0; i < 0xf; i++)
565 sum += *((uint8_t __far *)fdpt + i);
566 sum = -sum;
567 fdpt->csum = sum;
568 }
569
570 // fill hdidmap
571 AtaData->hdidmap[hdcount] = device;
572 hdcount++;
573 }
574
575 // Now we send an IDENTIFY command to ATAPI device
576 if (type == ATA_TYPE_ATAPI) {
577 uint8_t type, removable, mode;
578 uint16_t blksize;
579
580 // Temporary values to do the transfer
581 AtaData->devices[device].device = ATA_DEVICE_CDROM;
582 AtaData->devices[device].mode = ATA_MODE_PIO16;
583
584 if (ata_cmd_data_in(device, ATA_CMD_IDENTIFY_DEVICE_PACKET, 1, 0, 0, 0, 0L, buffer) != 0)
585 BX_PANIC("ata-detect: Failed to detect ATAPI device\n");
586
587 type = *(buffer+1) & 0x1f;
588 removable = (*(buffer+0) & 0x80) ? 1 : 0;
589 mode = *(buffer+96) ? ATA_MODE_PIO32 : ATA_MODE_PIO16;
590 blksize = 2048;
591
592 AtaData->devices[device].device = type;
593 AtaData->devices[device].removable = removable;
594 AtaData->devices[device].mode = mode;
595 AtaData->devices[device].blksize = blksize;
596
597 // fill cdidmap
598 AtaData->cdidmap[cdcount] = device;
599 cdcount++;
600 }
601
602 {
603 uint32_t sizeinmb;
604 uint16_t ataversion;
605 uint8_t version, model[41];
606 int i;
607
608 switch (type) {
609 case ATA_TYPE_ATA:
610 sizeinmb = AtaData->devices[device].sectors;
611 sizeinmb >>= 11;
612 case ATA_TYPE_ATAPI:
613 // Read ATA/ATAPI version
614 ataversion = ((uint16_t)(*(buffer+161))<<8) | *(buffer+160);
615 for (version = 15; version > 0; version--) {
616 if ((ataversion & (1 << version)) !=0 )
617 break;
618 }
619
620 // Read model name
621 for (i = 0; i < 20; i++ ) {
622 *(model+(i*2)) = *(buffer+(i*2)+54+1);
623 *(model+(i*2)+1) = *(buffer+(i*2)+54);
624 }
625
626 // Reformat
627 *(model+40) = 0x00;
628 for ( i = 39; i > 0; i-- ){
629 if (*(model+i) == 0x20)
630 *(model+i) = 0x00;
631 else
632 break;
633 }
634 break;
635 }
636
637#ifdef VBOXz
638 // we don't want any noisy output for now
639#else /* !VBOX */
640 switch (type) {
641 int c;
642 case ATA_TYPE_ATA:
643 printf("ata%d %s: ", channel, slave ? " slave" : "master");
644 i=0;
645 while(c=*(model+i++))
646 printf("%c", c);
647 printf(" ATA-%d Hard-Disk (%lu MBytes)\n", version, sizeinmb);
648 break;
649 case ATA_TYPE_ATAPI:
650 printf("ata%d %s: ", channel, slave ? " slave" : "master");
651 i=0;
652 while(c=*(model+i++))
653 printf("%c", c);
654 if (AtaData->devices[device].device == ATA_DEVICE_CDROM)
655 printf(" ATAPI-%d CD-ROM/DVD-ROM\n", version);
656 else
657 printf(" ATAPI-%d Device\n", version);
658 break;
659 case ATA_TYPE_UNKNOWN:
660 printf("ata%d %s: Unknown device\n", channel , slave ? " slave" : "master");
661 break;
662 }
663#endif /* !VBOX */
664 }
665 }
666
667 // Store the devices counts
668 AtaData->hdcount = hdcount;
669 AtaData->cdcount = cdcount;
670 write_byte(0x40,0x75, hdcount);
671
672#ifdef VBOX
673 // we don't want any noisy output for now
674#else /* !VBOX */
675 printf("\n");
676#endif /* !VBOX */
677
678 // FIXME : should use bios=cmos|auto|disable bits
679 // FIXME : should know about translation bits
680 // FIXME : move hard_drive_post here
681
682}
683
684// ---------------------------------------------------------------------------
685// ATA/ATAPI driver : execute a data-out command
686// ---------------------------------------------------------------------------
687 // returns
688 // 0 : no error
689 // 1 : BUSY bit set
690 // 2 : read error
691 // 3 : expected DRQ=1
692 // 4 : no sectors left to read/verify
693 // 5 : more sectors to read/verify
694 // 6 : no sectors left to write
695 // 7 : more sectors to write
696uint16_t ata_cmd_data_out(uint16_t device, uint16_t command, uint16_t count, uint16_t cylinder,
697 uint16_t head, uint16_t sector, uint32_t lba, char __far *buffer)
698{
699 uint16_t ebda_seg = read_word(0x0040,0x000E);
700 uint16_t iobase1, iobase2, blksize;
701 uint8_t channel, slave;
702 uint8_t status, current, mode;
703 ata_t __far *AtaData;
704
705 AtaData = ebda_seg :> &EbdaData->ata;
706
707 channel = device / 2;
708 slave = device % 2;
709
710 iobase1 = AtaData->channels[channel].iobase1;
711 iobase2 = AtaData->channels[channel].iobase2;
712 mode = AtaData->devices[device].mode;
713 blksize = 0x200; // was = AtaData->devices[device].blksize;
714 if (mode == ATA_MODE_PIO32)
715 blksize >>= 2;
716 else
717 blksize >>= 1;
718
719 status = inb(iobase1 + ATA_CB_STAT);
720 if (status & ATA_CB_STAT_BSY)
721 {
722 // Enable interrupts
723 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
724 return 1;
725 }
726
727 // sector will be 0 only on lba access. Convert to lba-chs
728 if (sector == 0) {
729 if (lba + count >= 268435456)
730 {
731 sector = (lba & 0xff000000L) >> 24;
732 cylinder = 0; /* The parameter lba is just a 32 bit value. */
733 outb(iobase1 + ATA_CB_SC, (count & 0xff00) >> 8);
734 outb(iobase1 + ATA_CB_SN, sector);
735 outb(iobase1 + ATA_CB_CL, cylinder & 0x00ff);
736 outb(iobase1 + ATA_CB_CH, cylinder >> 8);
737 /* Leave the bottom 24 bits as is, they are treated correctly by the
738 * LBA28 code path. */
739 lba &= 0xffffff;
740 }
741 sector = (uint16_t) (lba & 0x000000ffL);
742 lba >>= 8;
743 cylinder = (uint16_t) (lba & 0x0000ffffL);
744 lba >>= 16;
745 head = ((uint16_t) (lba & 0x0000000fL)) | 0x40;
746 }
747
748 // Reset count of transferred data
749 AtaData->trsfsectors = 0;
750 AtaData->trsfbytes = 0;
751 current = 0;
752
753 outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
754 outb(iobase1 + ATA_CB_FR, 0x00);
755 outb(iobase1 + ATA_CB_SC, count);
756 outb(iobase1 + ATA_CB_SN, sector);
757 outb(iobase1 + ATA_CB_CL, cylinder & 0x00ff);
758 outb(iobase1 + ATA_CB_CH, cylinder >> 8);
759 outb(iobase1 + ATA_CB_DH, (slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) | (uint8_t) head );
760 outb(iobase1 + ATA_CB_CMD, command);
761
762 while (1) {
763 status = inb(iobase1 + ATA_CB_STAT);
764 if ( !(status & ATA_CB_STAT_BSY) )
765 break;
766 }
767
768 if (status & ATA_CB_STAT_ERR) {
769 BX_DEBUG_ATA("%s: read error\n", __func__);
770 // Enable interrupts
771 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
772 return 2;
773 } else if ( !(status & ATA_CB_STAT_DRQ) ) {
774 BX_DEBUG_ATA("%s: DRQ not set (status %02x)\n", __func__, (unsigned) status);
775 // Enable interrupts
776 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
777 return 3;
778 }
779
780 // FIXME : move seg/off translation here
781
782 int_enable(); // enable higher priority interrupts
783
784 while (1) {
785
786 // adjust if there will be an overrun. 2K max sector size
787 if (FP_OFF(buffer) >= 0xF800)
788 buffer = MK_FP(FP_SEG(buffer) + 0x80, FP_OFF(buffer) - 0x800);
789
790 if (mode == ATA_MODE_PIO32) {
791 buffer = rep_outsd(buffer, blksize, iobase1);
792 } else {
793 buffer = rep_outsw(buffer, blksize, iobase1);
794 }
795
796 current++;
797 AtaData->trsfsectors = current;
798 count--;
799 while (1) {
800 status = inb(iobase1 + ATA_CB_STAT);
801 if ( !(status & ATA_CB_STAT_BSY) )
802 break;
803 }
804 if (count == 0) {
805 if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DF | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) )
806 != ATA_CB_STAT_RDY ) {
807 BX_DEBUG_ATA("%s: no sectors left (status %02x)\n", __func__, (unsigned) status);
808 // Enable interrupts
809 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
810 return 6;
811 }
812 break;
813 }
814 else {
815 if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) )
816 != (ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ) ) {
817 BX_DEBUG_ATA("%s: more sectors left (status %02x)\n", __func__, (unsigned) status);
818 // Enable interrupts
819 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
820 return 7;
821 }
822 continue;
823 }
824 }
825 // Enable interrupts
826 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
827 return 0;
828}
829
830// ---------------------------------------------------------------------------
831// ATA/ATAPI driver : execute a packet command
832// ---------------------------------------------------------------------------
833 // returns
834 // 0 : no error
835 // 1 : error in parameters
836 // 2 : BUSY bit set
837 // 3 : error
838 // 4 : not ready
839uint16_t ata_cmd_packet(uint16_t device, uint8_t cmdlen, char __far *cmdbuf,
840 uint16_t header, uint32_t length, uint8_t inout, char __far *buffer)
841{
842 uint16_t ebda_seg = read_word(0x0040,0x000E);
843 uint16_t iobase1, iobase2;
844 uint16_t lcount, lbefore, lafter, count;
845 uint8_t channel, slave;
846 uint8_t status, mode, lmode;
847 uint32_t transfer;
848 ata_t __far *AtaData;
849
850 AtaData = ebda_seg :> &EbdaData->ata;
851
852 channel = device / 2;
853 slave = device % 2;
854
855 // Data out is not supported yet
856 if (inout == ATA_DATA_OUT) {
857 BX_INFO("%s: DATA_OUT not supported yet\n", __func__);
858 return 1;
859 }
860
861 // The header length must be even
862 if (header & 1) {
863 BX_DEBUG_ATA("%s: header must be even (%04x)\n", __func__, header);
864 return 1;
865 }
866
867 iobase1 = AtaData->channels[channel].iobase1;
868 iobase2 = AtaData->channels[channel].iobase2;
869 mode = AtaData->devices[device].mode;
870 transfer = 0L;
871
872 if (cmdlen < 12)
873 cmdlen = 12;
874 if (cmdlen > 12)
875 cmdlen = 16;
876 cmdlen >>= 1;
877
878 // Reset count of transferred data
879 AtaData->trsfsectors = 0;
880 AtaData->trsfbytes = 0;
881
882 status = inb(iobase1 + ATA_CB_STAT);
883 if (status & ATA_CB_STAT_BSY)
884 return 2;
885
886 outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
887 // outb(iobase1 + ATA_CB_FR, 0x00);
888 // outb(iobase1 + ATA_CB_SC, 0x00);
889 // outb(iobase1 + ATA_CB_SN, 0x00);
890 outb(iobase1 + ATA_CB_CL, 0xfff0 & 0x00ff);
891 outb(iobase1 + ATA_CB_CH, 0xfff0 >> 8);
892 outb(iobase1 + ATA_CB_DH, slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0);
893 outb(iobase1 + ATA_CB_CMD, ATA_CMD_PACKET);
894
895 // Device should ok to receive command
896 while (1) {
897 status = inb(iobase1 + ATA_CB_STAT);
898 if ( !(status & ATA_CB_STAT_BSY) ) break;
899 }
900
901 if (status & ATA_CB_STAT_ERR) {
902 BX_DEBUG_ATA("%s: error, status is %02x\n", __func__, status);
903 // Enable interrupts
904 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
905 return 3;
906 } else if ( !(status & ATA_CB_STAT_DRQ) ) {
907 BX_DEBUG_ATA("%s: DRQ not set (status %02x)\n", __func__, (unsigned) status);
908 // Enable interrupts
909 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
910 return 4;
911 }
912
913 int_enable(); // enable higher priority interrupts
914
915 // Normalize address
916 BX_DEBUG_ATA("acp1 buffer ptr: %04x:%04x wlen %04x\n", FP_SEG(cmdbuf), FP_OFF(cmdbuf), cmdlen);
917 cmdbuf = MK_FP(FP_SEG(cmdbuf) + FP_OFF(cmdbuf) / 16 , FP_OFF(cmdbuf) % 16);
918 // cmdseg += (cmdoff / 16);
919 // cmdoff %= 16;
920
921 // Send command to device
922 rep_outsw(cmdbuf, cmdlen, iobase1);
923
924 if (inout == ATA_DATA_NO) {
925 status = inb(iobase1 + ATA_CB_STAT);
926 }
927 else {
928 while (1) {
929
930 while (1) {
931 status = inb(iobase1 + ATA_CB_STAT);
932 if ( !(status & ATA_CB_STAT_BSY) )
933 break;
934 }
935
936 // Check if command completed
937 if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_DRQ) ) ==0 )
938 break;
939
940 if (status & ATA_CB_STAT_ERR) {
941 BX_DEBUG_ATA("%s: error (status %02x)\n", __func__, status);
942 // Enable interrupts
943 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
944 return 3;
945 }
946
947 // Device must be ready to send data
948 if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) )
949 != (ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ) ) {
950 BX_DEBUG_ATA("%s: not ready (status %02x)\n", __func__, status);
951 // Enable interrupts
952 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
953 return 4;
954 }
955
956 // Normalize address
957 BX_DEBUG_ATA("acp2 buffer ptr: %04x:%04x\n", FP_SEG(buffer), FP_OFF(buffer));
958 buffer = MK_FP(FP_SEG(buffer) + FP_OFF(buffer) / 16 , FP_OFF(buffer) % 16);
959 // bufseg += (bufoff / 16);
960 // bufoff %= 16;
961
962 // Get the byte count
963 lcount = ((uint16_t)(inb(iobase1 + ATA_CB_CH))<<8)+inb(iobase1 + ATA_CB_CL);
964
965 // adjust to read what we want
966 if (header>lcount) {
967 lbefore = lcount;
968 header -= lcount;
969 lcount = 0;
970 }
971 else {
972 lbefore = header;
973 header = 0;
974 lcount -= lbefore;
975 }
976
977 if (lcount>length) {
978 lafter = lcount - length;
979 lcount = length;
980 length = 0;
981 }
982 else {
983 lafter = 0;
984 length -= lcount;
985 }
986
987 // Save byte count
988 count = lcount;
989
990 BX_DEBUG_ATA("Trying to read %04x bytes (%04x %04x %04x) ",lbefore+lcount+lafter,lbefore,lcount,lafter);
991 BX_DEBUG_ATA("to 0x%04x:0x%04x\n",FP_SEG(buffer),FP_OFF(buffer));
992
993 // If counts not dividable by 4, use 16bits mode
994 lmode = mode;
995 if (lbefore & 0x03)
996 lmode = ATA_MODE_PIO16;
997 if (lcount & 0x03)
998 lmode = ATA_MODE_PIO16;
999 if (lafter & 0x03)
1000 lmode = ATA_MODE_PIO16;
1001
1002 // adds an extra byte if count are odd. before is always even
1003 if (lcount & 0x01) {
1004 lcount += 1;
1005 if ((lafter > 0) && (lafter & 0x01)) {
1006 lafter -= 1;
1007 }
1008 }
1009
1010 if (lmode == ATA_MODE_PIO32) {
1011 lcount >>= 2;
1012 lbefore >>= 2;
1013 lafter >>= 2;
1014 }
1015 else {
1016 lcount >>= 1;
1017 lbefore >>= 1;
1018 lafter >>= 1;
1019 }
1020
1021 if (lmode == ATA_MODE_PIO32) {
1022 if (lbefore)
1023 insd_discard(lbefore, iobase1);
1024 rep_insd(buffer, lcount, iobase1);
1025 if (lafter)
1026 insd_discard(lafter, iobase1);
1027 } else {
1028 if (lbefore)
1029 insw_discard(lbefore, iobase1);
1030 rep_insw(buffer, lcount, iobase1);
1031 if (lafter)
1032 insw_discard(lafter, iobase1);
1033 }
1034
1035
1036 // Compute new buffer address
1037 buffer += count;
1038
1039 // Save transferred bytes count
1040 transfer += count;
1041 AtaData->trsfbytes = transfer;
1042 }
1043 }
1044
1045 // Final check, device must be ready
1046 if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DF | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) )
1047 != ATA_CB_STAT_RDY ) {
1048 BX_DEBUG_ATA("%s: not ready (status %02x)\n", __func__, (unsigned) status);
1049 // Enable interrupts
1050 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
1051 return 4;
1052 }
1053
1054 // Enable interrupts
1055 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
1056 return 0;
1057}
1058
1059
1060// ---------------------------------------------------------------------------
1061// End of ATA/ATAPI Driver
1062// ---------------------------------------------------------------------------
1063
1064uint16_t atapi_is_cdrom(uint8_t device)
1065{
1066 uint16_t ebda_seg = read_word(0x0040,0x000E);
1067 ata_t __far *AtaData;
1068
1069 AtaData = ebda_seg :> &EbdaData->ata;
1070
1071 if (device >= BX_MAX_ATA_DEVICES)
1072 return 0;
1073
1074 if (AtaData->devices[device].type != ATA_TYPE_ATAPI)
1075 return 0;
1076
1077 if (AtaData->devices[device].device != ATA_DEVICE_CDROM)
1078 return 0;
1079
1080 return 1;
1081}
1082
1083// ---------------------------------------------------------------------------
1084// End of ATA/ATAPI generic functions
1085// ---------------------------------------------------------------------------
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