VirtualBox

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

Last change on this file since 87766 was 82968, checked in by vboxsync, 5 years ago

Copyright year updates by scm.

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

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