VirtualBox

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

Last change on this file since 69496 was 69496, checked in by vboxsync, 7 years ago

*: scm --update-copyright-year

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

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