VirtualBox

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

Last change on this file since 100443 was 100443, checked in by vboxsync, 11 months ago

BIOS: Recognize common hard disk types and set the corresponding CMOS drive type. In the BIOS, point such drive types at the FDPT in ROM.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use