VirtualBox

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

Last change on this file was 104194, checked in by vboxsync, 4 weeks ago

BIOS: Run INITIALIZE DRIVE PARAMETERS after resetting drives in the unusual case where logical geometry does not match physical.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use