VirtualBox

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

Last change on this file since 78374 was 78052, checked in by vboxsync, 6 years ago

BIOS: Only probe IDE devices if a PCI IDE controller is present (see bugref:6549).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 40.7 KB
Line 
1/* $Id: ata.c 78052 2019-04-09 10:13:30Z vboxsync $ */
2/** @file
3 * PC BIOS - ???
4 */
5
6/*
7 * Copyright (C) 2006-2019 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 if (bios_dsk->devices[device].type != DSK_TYPE_NONE) {
180 // 8.2.1 (g) -- check for sc==sn==0x01
181 // select device
182 outb(iobase1+ATA_CB_DH, slave?ATA_CB_DH_DEV1:ATA_CB_DH_DEV0);
183 sc = inb(iobase1+ATA_CB_SC);
184 sn = inb(iobase1+ATA_CB_SN);
185
186 if ( (sc==0x01) && (sn==0x01) ) {
187 // 8.2.1 (h) -- wait for not BSY
188 max=0xffff; /* The ATA specification says that the drive may be busy for up to 30 seconds. */
189 while(--max>0) {
190 uint8_t status = inb(iobase1+ATA_CB_STAT);
191 if ((status & ATA_CB_STAT_BSY) == 0)
192 break;
193 pdelay=0xffff;
194 while (--pdelay>0) {
195 /* nothing */
196 }
197 }
198 }
199 }
200
201 // 8.2.1 (i) -- wait for DRDY
202 max = 0x10; /* Speed up for virtual drives. Disks are immediately ready, CDs never */
203 while(--max>0) {
204 uint8_t status = inb(iobase1+ATA_CB_STAT);
205 if ((status & ATA_CB_STAT_RDY) != 0)
206 break;
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
376void BIOSCALL ata_detect(void)
377{
378 uint16_t ebda_seg = read_word(0x0040,0x000E);
379 uint8_t hdcount, cdcount, device, type;
380 uint8_t buffer[0x0200];
381 bio_dsk_t __far *bios_dsk;
382
383 /* If we have PCI support, look for an IDE controller (it has to be a PCI device)
384 * so that we can skip silly probing. If there's no PCI, assume IDE is present.
385 *
386 * Needs an internal PCI function because the Programming Interface byte can be
387 * almost anything, and we conly care about the base-class and sub-class code.
388 */
389#if VBOX_BIOS_CPU >= 80386
390 uint16_t busdevfn;
391
392 busdevfn = pci_find_class_noif(0x0101);
393 if (busdevfn == 0xffff) {
394 BX_INFO("No PCI IDE controller, not probing IDE\n");
395 return;
396 }
397#endif
398
399 bios_dsk = ebda_seg :> &EbdaData->bdisk;
400
401#if BX_MAX_ATA_INTERFACES > 0
402 bios_dsk->channels[0].iface = ATA_IFACE_ISA;
403 bios_dsk->channels[0].iobase1 = 0x1f0;
404 bios_dsk->channels[0].iobase2 = 0x3f0;
405 bios_dsk->channels[0].irq = 14;
406#endif
407#if BX_MAX_ATA_INTERFACES > 1
408 bios_dsk->channels[1].iface = ATA_IFACE_ISA;
409 bios_dsk->channels[1].iobase1 = 0x170;
410 bios_dsk->channels[1].iobase2 = 0x370;
411 bios_dsk->channels[1].irq = 15;
412#endif
413#if 0 /// @todo - temporarily removed to avoid conflict with AHCI
414#if BX_MAX_ATA_INTERFACES > 2
415 bios_dsk->channels[2].iface = ATA_IFACE_ISA;
416 bios_dsk->channels[2].iobase1 = 0x1e8;
417 bios_dsk->channels[2].iobase2 = 0x3e0;
418 bios_dsk->channels[2].irq = 12;
419#endif
420#if BX_MAX_ATA_INTERFACES > 3
421 bios_dsk->channels[3].iface = ATA_IFACE_ISA;
422 bios_dsk->channels[3].iobase1 = 0x168;
423 bios_dsk->channels[3].iobase2 = 0x360;
424 bios_dsk->channels[3].irq = 11;
425#endif
426#endif
427#if BX_MAX_ATA_INTERFACES > 4
428#error Please fill the ATA interface informations
429#endif
430
431 // Device detection
432 hdcount = cdcount = 0;
433
434 for (device = 0; device < BX_MAX_ATA_DEVICES; device++) {
435 uint16_t iobase1, iobase2;
436 uint8_t channel, slave;
437 uint8_t sc, sn, cl, ch, st;
438
439 channel = device / 2;
440 slave = device % 2;
441
442 iobase1 = bios_dsk->channels[channel].iobase1;
443 iobase2 = bios_dsk->channels[channel].iobase2;
444
445 // Disable interrupts
446 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
447
448 // Look for device
449 outb(iobase1+ATA_CB_DH, slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0);
450 outb(iobase1+ATA_CB_SC, 0x55);
451 outb(iobase1+ATA_CB_SN, 0xaa);
452 outb(iobase1+ATA_CB_SC, 0xaa);
453 outb(iobase1+ATA_CB_SN, 0x55);
454 outb(iobase1+ATA_CB_SC, 0x55);
455 outb(iobase1+ATA_CB_SN, 0xaa);
456
457 // If we found something
458 sc = inb(iobase1+ATA_CB_SC);
459 sn = inb(iobase1+ATA_CB_SN);
460
461 if ( (sc == 0x55) && (sn == 0xaa) ) {
462 bios_dsk->devices[device].type = DSK_TYPE_UNKNOWN;
463
464 // reset the channel
465 ata_reset(device);
466
467 // check for ATA or ATAPI
468 outb(iobase1+ATA_CB_DH, slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0);
469 sc = inb(iobase1+ATA_CB_SC);
470 sn = inb(iobase1+ATA_CB_SN);
471 if ((sc==0x01) && (sn==0x01)) {
472 cl = inb(iobase1+ATA_CB_CL);
473 ch = inb(iobase1+ATA_CB_CH);
474 st = inb(iobase1+ATA_CB_STAT);
475
476 if ((cl==0x14) && (ch==0xeb)) {
477 bios_dsk->devices[device].type = DSK_TYPE_ATAPI;
478 } else if ((cl==0x00) && (ch==0x00) && (st!=0x00)) {
479 bios_dsk->devices[device].type = DSK_TYPE_ATA;
480 } else if ((cl==0xff) && (ch==0xff)) {
481 bios_dsk->devices[device].type = DSK_TYPE_NONE;
482 }
483 }
484 }
485
486 // Enable interrupts
487 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
488
489 type = bios_dsk->devices[device].type;
490
491 // Now we send a IDENTIFY command to ATA device
492 if (type == DSK_TYPE_ATA) {
493 uint64_t sectors;
494 uint16_t cylinders, heads, spt, blksize;
495 chs_t lgeo;
496 uint8_t chsgeo_base;
497 uint8_t removable, mode;
498
499 //Temporary values to do the transfer
500 bios_dsk->devices[device].device = DSK_DEVICE_HD;
501 bios_dsk->devices[device].mode = ATA_MODE_PIO16;
502 bios_dsk->drqp.buffer = buffer;
503 bios_dsk->drqp.dev_id = device;
504
505 if (ata_cmd_data_in(bios_dsk, ATA_CMD_IDENTIFY_DEVICE, 1) !=0 )
506 BX_PANIC("ata-detect: Failed to detect ATA device\n");
507
508 removable = (*(buffer+0) & 0x80) ? 1 : 0;
509#if VBOX_BIOS_CPU >= 80386
510 mode = *(buffer+96) ? ATA_MODE_PIO32 : ATA_MODE_PIO16;
511#else
512 mode = ATA_MODE_PIO16;
513#endif
514 blksize = 512; /* There is no sector size field any more. */
515
516 cylinders = *(uint16_t *)(buffer+(1*2)); // word 1
517 heads = *(uint16_t *)(buffer+(3*2)); // word 3
518 spt = *(uint16_t *)(buffer+(6*2)); // word 6
519
520 sectors = *(uint32_t *)(buffer+(60*2)); // word 60 and word 61
521 if (sectors == 0x0FFFFFFF) /* For disks bigger than ~128GB */
522 sectors = *(uint64_t *)(buffer+(100*2)); // words 100 to 103
523 switch (device)
524 {
525 case 0:
526 chsgeo_base = 0x1e;
527 break;
528 case 1:
529 chsgeo_base = 0x26;
530 break;
531 case 2:
532 chsgeo_base = 0x67;
533 break;
534 case 3:
535 chsgeo_base = 0x70;
536 break;
537 default:
538 chsgeo_base = 0;
539 }
540 if (chsgeo_base)
541 {
542 lgeo.cylinders = inb_cmos(chsgeo_base) + (inb_cmos(chsgeo_base + 1) << 8);
543 lgeo.heads = inb_cmos(chsgeo_base + 2);
544 lgeo.spt = inb_cmos(chsgeo_base + 7);
545 }
546 else
547 set_geom_lba(&lgeo, sectors); /* Default EDD-style translated LBA geometry. */
548
549 BX_INFO("ata%d-%d: PCHS=%u/%u/%u LCHS=%u/%u/%u\n", channel, slave,
550 cylinders, heads, spt, lgeo.cylinders, lgeo.heads, lgeo.spt);
551
552 bios_dsk->devices[device].device = DSK_DEVICE_HD;
553 bios_dsk->devices[device].removable = removable;
554 bios_dsk->devices[device].mode = mode;
555 bios_dsk->devices[device].blksize = blksize;
556 bios_dsk->devices[device].pchs.heads = heads;
557 bios_dsk->devices[device].pchs.cylinders = cylinders;
558 bios_dsk->devices[device].pchs.spt = spt;
559 bios_dsk->devices[device].sectors = sectors;
560 bios_dsk->devices[device].lchs = lgeo;
561 if (device < 2)
562 {
563 uint8_t sum, i;
564 fdpt_t __far *fdpt;
565 void __far * __far *int_vec;
566
567 if (device == 0)
568 fdpt = ebda_seg :> &EbdaData->fdpt0;
569 else
570 fdpt = ebda_seg :> &EbdaData->fdpt1;
571
572#if 0
573 /* Place the FDPT outside of conventional memory. Needed for
574 * 286 XENIX 2.1.3/2.2.1 because it completely wipes out
575 * the EBDA and low memory. Hack!
576 */
577 fdpt = MK_FP(0xE200, 0xf00);
578 fdpt += device;
579#endif
580
581 /* Set the INT 41h or 46h pointer. */
582 int_vec = MK_FP(0, (0x41 + device * 5) * sizeof(void __far *));
583 *int_vec = fdpt;
584
585 /* Update the DPT for drive 0/1 pointed to by Int41/46. This used
586 * to be done at POST time with lots of ugly assembler code, which
587 * isn't worth the effort of converting from AMI to Award CMOS
588 * format. Just do it here. */
589 fdpt->resvd1 = fdpt->resvd2 = 0;
590
591 fdpt->lcyl = lgeo.cylinders;
592 fdpt->lhead = lgeo.heads;
593 fdpt->sig = 0xa0;
594 fdpt->spt = spt;
595 fdpt->cyl = cylinders;
596 fdpt->head = heads;
597 fdpt->lspt = lgeo.spt;
598 sum = 0;
599 for (i = 0; i < 0xf; i++)
600 sum += *((uint8_t __far *)fdpt + i);
601 sum = -sum;
602 fdpt->csum = sum;
603 }
604
605 // fill hdidmap
606 bios_dsk->hdidmap[hdcount] = device;
607 hdcount++;
608 }
609
610 // Now we send an IDENTIFY command to ATAPI device
611 if (type == DSK_TYPE_ATAPI) {
612 uint8_t type, removable, mode;
613 uint16_t blksize;
614
615 // Temporary values to do the transfer
616 bios_dsk->devices[device].device = DSK_DEVICE_CDROM;
617 bios_dsk->devices[device].mode = ATA_MODE_PIO16;
618 bios_dsk->drqp.buffer = buffer;
619 bios_dsk->drqp.dev_id = device;
620
621 if (ata_cmd_data_in(bios_dsk, ATA_CMD_IDENTIFY_PACKET, 1) != 0)
622 BX_PANIC("ata-detect: Failed to detect ATAPI device\n");
623
624 type = *(buffer+1) & 0x1f;
625 removable = (*(buffer+0) & 0x80) ? 1 : 0;
626#if VBOX_BIOS_CPU >= 80386
627 mode = *(buffer+96) ? ATA_MODE_PIO32 : ATA_MODE_PIO16;
628#else
629 mode = ATA_MODE_PIO16;
630#endif
631 blksize = 2048;
632
633 bios_dsk->devices[device].device = type;
634 bios_dsk->devices[device].removable = removable;
635 bios_dsk->devices[device].mode = mode;
636 bios_dsk->devices[device].blksize = blksize;
637
638 // fill cdidmap
639 bios_dsk->cdidmap[cdcount] = device;
640 cdcount++;
641 }
642
643 {
644 uint32_t sizeinmb;
645 uint16_t ataversion;
646 uint8_t version, model[41];
647 int i;
648
649 switch (type) {
650 case DSK_TYPE_ATA:
651 sizeinmb = (bios_dsk->devices[device].sectors >> 11);
652 case DSK_TYPE_ATAPI:
653 // Read ATA/ATAPI version
654 ataversion = ((uint16_t)(*(buffer+161))<<8) | *(buffer+160);
655 for (version = 15; version > 0; version--) {
656 if ((ataversion & (1 << version)) !=0 )
657 break;
658 }
659
660 // Read model name
661 for (i = 0; i < 20; i++ ) {
662 *(model+(i*2)) = *(buffer+(i*2)+54+1);
663 *(model+(i*2)+1) = *(buffer+(i*2)+54);
664 }
665
666 // Reformat
667 *(model+40) = 0x00;
668 for ( i = 39; i > 0; i-- ){
669 if (*(model+i) == 0x20)
670 *(model+i) = 0x00;
671 else
672 break;
673 }
674 break;
675 }
676
677#ifdef VBOXz
678 // we don't want any noisy output for now
679#else /* !VBOX */
680 switch (type) {
681 int c;
682 case DSK_TYPE_ATA:
683 printf("ata%d %s: ", channel, slave ? " slave" : "master");
684 i=0;
685 while(c=*(model+i++))
686 printf("%c", c);
687 printf(" ATA-%d Hard-Disk (%lu MBytes)\n", version, sizeinmb);
688 break;
689 case DSK_TYPE_ATAPI:
690 printf("ata%d %s: ", channel, slave ? " slave" : "master");
691 i=0;
692 while(c=*(model+i++))
693 printf("%c", c);
694 if (bios_dsk->devices[device].device == DSK_DEVICE_CDROM)
695 printf(" ATAPI-%d CD-ROM/DVD-ROM\n", version);
696 else
697 printf(" ATAPI-%d Device\n", version);
698 break;
699 case DSK_TYPE_UNKNOWN:
700 printf("ata%d %s: Unknown device\n", channel , slave ? " slave" : "master");
701 break;
702 }
703#endif /* !VBOX */
704 }
705 }
706
707 // Store the devices counts
708 bios_dsk->hdcount = hdcount;
709 bios_dsk->cdcount = cdcount;
710 write_byte(0x40,0x75, hdcount);
711
712#ifdef VBOX
713 // we don't want any noisy output for now
714#else /* !VBOX */
715 printf("\n");
716#endif /* !VBOX */
717
718 // FIXME : should use bios=cmos|auto|disable bits
719 // FIXME : should know about translation bits
720 // FIXME : move hard_drive_post here
721
722}
723
724// ---------------------------------------------------------------------------
725// ATA/ATAPI driver : execute a data-out command
726// ---------------------------------------------------------------------------
727 // returns
728 // 0 : no error
729 // 1 : BUSY bit set
730 // 2 : read error
731 // 3 : expected DRQ=1
732 // 4 : no sectors left to read/verify
733 // 5 : more sectors to read/verify
734 // 6 : no sectors left to write
735 // 7 : more sectors to write
736uint16_t ata_cmd_data_out(bio_dsk_t __far *bios_dsk, uint16_t command, uint16_t count)
737{
738 uint64_t lba;
739 char __far *buffer;
740 uint16_t iobase1, iobase2, blksize;
741 uint16_t cylinder;
742 uint16_t head;
743 uint16_t sector;
744 uint16_t device;
745 uint8_t channel, slave;
746 uint8_t status, mode;
747
748 device = bios_dsk->drqp.dev_id;
749 channel = device / 2;
750 slave = device % 2;
751
752 iobase1 = bios_dsk->channels[channel].iobase1;
753 iobase2 = bios_dsk->channels[channel].iobase2;
754 mode = bios_dsk->devices[device].mode;
755 blksize = 0x200; // was = bios_dsk->devices[device].blksize;
756#if VBOX_BIOS_CPU >= 80386
757 if (mode == ATA_MODE_PIO32)
758 blksize >>= 2;
759 else
760#endif
761 blksize >>= 1;
762
763 status = inb(iobase1 + ATA_CB_STAT);
764 if (status & ATA_CB_STAT_BSY)
765 {
766 // Enable interrupts
767 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
768 return 1;
769 }
770
771 lba = bios_dsk->drqp.lba;
772 buffer = bios_dsk->drqp.buffer;
773 sector = bios_dsk->drqp.sector;
774 cylinder = bios_dsk->drqp.cylinder;
775 head = bios_dsk->drqp.head;
776
777 // sector will be 0 only on lba access. Convert to lba-chs
778 if (sector == 0) {
779 if (lba + count >= 268435456)
780 {
781 sector = (lba >> 24) & 0x00ff;
782 cylinder = (lba >> 32) & 0xffff;
783 outb(iobase1 + ATA_CB_SC, (count & 0xff00) >> 8);
784 outb(iobase1 + ATA_CB_SN, sector);
785 outb(iobase1 + ATA_CB_CL, cylinder & 0x00ff);
786 outb(iobase1 + ATA_CB_CH, cylinder >> 8);
787 /* Leave the bottom 24 bits as is, they are treated correctly by the
788 * LBA28 code path. */
789 lba &= 0xffffff;
790 }
791 sector = (uint16_t) (lba & 0x000000ffL);
792 lba >>= 8;
793 cylinder = (uint16_t) (lba & 0x0000ffffL);
794 lba >>= 16;
795 head = ((uint16_t) (lba & 0x0000000fL)) | 0x40;
796 }
797
798 outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
799 outb(iobase1 + ATA_CB_FR, 0x00);
800 outb(iobase1 + ATA_CB_SC, count);
801 outb(iobase1 + ATA_CB_SN, sector);
802 outb(iobase1 + ATA_CB_CL, cylinder & 0x00ff);
803 outb(iobase1 + ATA_CB_CH, cylinder >> 8);
804 outb(iobase1 + ATA_CB_DH, (slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) | (uint8_t) head );
805 outb(iobase1 + ATA_CB_CMD, command);
806
807 while (1) {
808 status = inb(iobase1 + ATA_CB_STAT);
809 if ( !(status & ATA_CB_STAT_BSY) )
810 break;
811 }
812
813 if (status & ATA_CB_STAT_ERR) {
814 BX_DEBUG_ATA("%s: write error\n", __func__);
815 // Enable interrupts
816 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
817 return 2;
818 } else if ( !(status & ATA_CB_STAT_DRQ) ) {
819 BX_DEBUG_ATA("%s: DRQ not set (status %02x)\n", __func__, (unsigned) status);
820 // Enable interrupts
821 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
822 return 3;
823 }
824
825 // FIXME : move seg/off translation here
826
827 int_enable(); // enable higher priority interrupts
828
829 while (1) {
830
831 // adjust if there will be an overrun. 2K max sector size
832 if (FP_OFF(buffer) >= 0xF800)
833 buffer = MK_FP(FP_SEG(buffer) + 0x80, FP_OFF(buffer) - 0x800);
834
835#if VBOX_BIOS_CPU >= 80386
836 if (mode == ATA_MODE_PIO32)
837 buffer = rep_outsd(buffer, blksize, iobase1);
838 else
839#endif
840 buffer = rep_outsw(buffer, blksize, iobase1);
841
842 bios_dsk->drqp.trsfsectors++;
843 count--;
844 while (1) {
845 status = inb(iobase1 + ATA_CB_STAT);
846 if ( !(status & ATA_CB_STAT_BSY) )
847 break;
848 }
849 if (count == 0) {
850 if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DF | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) )
851 != ATA_CB_STAT_RDY ) {
852 BX_DEBUG_ATA("%s: no sectors left (status %02x)\n", __func__, (unsigned) status);
853 // Enable interrupts
854 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
855 return 6;
856 }
857 break;
858 }
859 else {
860 if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) )
861 != (ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ) ) {
862 BX_DEBUG_ATA("%s: more sectors left (status %02x)\n", __func__, (unsigned) status);
863 // Enable interrupts
864 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
865 return 7;
866 }
867 continue;
868 }
869 }
870 // Enable interrupts
871 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
872 return 0;
873}
874
875
876/**
877 * Read sectors from an attached ATA device.
878 *
879 * @returns status code.
880 * @param bios_dsk Pointer to disk request packet (in the
881 * EBDA).
882 */
883int ata_read_sectors(bio_dsk_t __far *bios_dsk)
884{
885 uint16_t n_sect;
886 int status;
887 uint8_t device_id;
888
889 device_id = bios_dsk->drqp.dev_id;
890 n_sect = bios_dsk->drqp.nsect;
891
892 if (bios_dsk->drqp.sector) {
893 /* CHS addressing. */
894 bios_dsk->devices[device_id].blksize = n_sect * 0x200;
895 BX_DEBUG_ATA("%s: reading %u sectors (CHS)\n", __func__, n_sect);
896 status = ata_cmd_data_in(bios_dsk, ATA_CMD_READ_MULTIPLE, n_sect);
897 bios_dsk->devices[device_id].blksize = 0x200;
898 } else {
899 /* LBA addressing. */
900 if (bios_dsk->drqp.lba + n_sect >= 268435456) {
901 BX_DEBUG_ATA("%s: reading %u sector (LBA,EXT)\n", __func__, n_sect);
902 status = ata_cmd_data_in(bios_dsk, ATA_CMD_READ_SECTORS_EXT, n_sect);
903 } else {
904 bios_dsk->devices[device_id].blksize = n_sect * 0x200;
905 BX_DEBUG_ATA("%s: reading %u sector (LBA,MULT)\n", __func__, n_sect);
906 status = ata_cmd_data_in(bios_dsk, ATA_CMD_READ_MULTIPLE, n_sect);
907 bios_dsk->devices[device_id].blksize = 0x200;
908 }
909 }
910 return status;
911}
912
913/**
914 * Write sectors to an attached ATA device.
915 *
916 * @returns status code.
917 * @param bios_dsk Pointer to disk request packet (in the
918 * EBDA).
919 */
920int ata_write_sectors(bio_dsk_t __far *bios_dsk)
921{
922 uint16_t n_sect;
923
924 n_sect = bios_dsk->drqp.nsect;
925
926 if (bios_dsk->drqp.sector) {
927 /* CHS addressing. */
928 return ata_cmd_data_out(bios_dsk, ATA_CMD_WRITE_SECTORS, n_sect);
929 } else {
930 /* LBA addressing. */
931 if (bios_dsk->drqp.lba + n_sect >= 268435456)
932 return ata_cmd_data_out(bios_dsk, ATA_CMD_WRITE_SECTORS_EXT, n_sect);
933 else
934 return ata_cmd_data_out(bios_dsk, ATA_CMD_WRITE_SECTORS, n_sect);
935 }
936}
937
938
939// ---------------------------------------------------------------------------
940// ATA/ATAPI driver : execute a packet command
941// ---------------------------------------------------------------------------
942 // returns
943 // 0 : no error
944 // 1 : error in parameters
945 // 2 : BUSY bit set
946 // 3 : error
947 // 4 : not ready
948uint16_t ata_cmd_packet(uint16_t device, uint8_t cmdlen, char __far *cmdbuf,
949 uint16_t header, uint32_t length, uint8_t inout, char __far *buffer)
950{
951 uint16_t iobase1, iobase2;
952 uint16_t lcount, lbefore, lafter, count;
953 uint8_t channel, slave;
954 uint8_t status, mode, lmode;
955 uint32_t transfer;
956 bio_dsk_t __far *bios_dsk;
957
958 bios_dsk = read_word(0x0040, 0x000E) :> &EbdaData->bdisk;
959
960 channel = device / 2;
961 slave = device % 2;
962
963 // Data out is not supported yet
964 if (inout == ATA_DATA_OUT) {
965 BX_INFO("%s: DATA_OUT not supported yet\n", __func__);
966 return 1;
967 }
968
969 // The header length must be even
970 if (header & 1) {
971 BX_DEBUG_ATA("%s: header must be even (%04x)\n", __func__, header);
972 return 1;
973 }
974
975 iobase1 = bios_dsk->channels[channel].iobase1;
976 iobase2 = bios_dsk->channels[channel].iobase2;
977 mode = bios_dsk->devices[device].mode;
978 transfer = 0L;
979
980 if (cmdlen < 12)
981 cmdlen = 12;
982 if (cmdlen > 12)
983 cmdlen = 16;
984 cmdlen >>= 1;
985
986 // Reset count of transferred data
987 /// @todo clear in calling code?
988 bios_dsk->drqp.trsfsectors = 0;
989 bios_dsk->drqp.trsfbytes = 0;
990
991 status = inb(iobase1 + ATA_CB_STAT);
992 if (status & ATA_CB_STAT_BSY)
993 return 2;
994
995 outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
996 // outb(iobase1 + ATA_CB_FR, 0x00);
997 // outb(iobase1 + ATA_CB_SC, 0x00);
998 // outb(iobase1 + ATA_CB_SN, 0x00);
999 outb(iobase1 + ATA_CB_CL, 0xfff0 & 0x00ff);
1000 outb(iobase1 + ATA_CB_CH, 0xfff0 >> 8);
1001 outb(iobase1 + ATA_CB_DH, slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0);
1002 outb(iobase1 + ATA_CB_CMD, ATA_CMD_PACKET);
1003
1004 // Device should ok to receive command
1005 while (1) {
1006 status = inb(iobase1 + ATA_CB_STAT);
1007 if ( !(status & ATA_CB_STAT_BSY) ) break;
1008 }
1009
1010 if (status & ATA_CB_STAT_CHK) {
1011 BX_DEBUG_ATA("%s: error, status is %02x\n", __func__, status);
1012 // Enable interrupts
1013 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
1014 return 3;
1015 } else if ( !(status & ATA_CB_STAT_DRQ) ) {
1016 BX_DEBUG_ATA("%s: DRQ not set (status %02x)\n", __func__, (unsigned) status);
1017 // Enable interrupts
1018 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
1019 return 4;
1020 }
1021
1022 int_enable(); // enable higher priority interrupts
1023
1024 // Normalize address
1025 BX_DEBUG_ATA("acp1 buffer ptr: %04x:%04x wlen %04x\n", FP_SEG(cmdbuf), FP_OFF(cmdbuf), cmdlen);
1026 cmdbuf = MK_FP(FP_SEG(cmdbuf) + FP_OFF(cmdbuf) / 16 , FP_OFF(cmdbuf) % 16);
1027 // cmdseg += (cmdoff / 16);
1028 // cmdoff %= 16;
1029
1030 // Send command to device
1031 rep_outsw(cmdbuf, cmdlen, iobase1);
1032
1033 if (inout == ATA_DATA_NO) {
1034 status = inb(iobase1 + ATA_CB_STAT);
1035 }
1036 else {
1037 while (1) {
1038
1039 while (1) {
1040 status = inb(iobase1 + ATA_CB_STAT);
1041 if ( !(status & ATA_CB_STAT_BSY) )
1042 break;
1043 }
1044
1045 // Check if command completed
1046 if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_DRQ) ) ==0 )
1047 break;
1048
1049 if (status & ATA_CB_STAT_CHK) {
1050 BX_DEBUG_ATA("%s: error (status %02x)\n", __func__, status);
1051 // Enable interrupts
1052 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
1053 return 3;
1054 }
1055
1056 // Device must be ready to send data
1057 if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_CHK) )
1058 != (ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ) ) {
1059 BX_DEBUG_ATA("%s: not ready (status %02x)\n", __func__, status);
1060 // Enable interrupts
1061 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
1062 return 4;
1063 }
1064
1065 // Normalize address
1066 BX_DEBUG_ATA("acp2 buffer ptr: %04x:%04x\n", FP_SEG(buffer), FP_OFF(buffer));
1067 buffer = MK_FP(FP_SEG(buffer) + FP_OFF(buffer) / 16 , FP_OFF(buffer) % 16);
1068 // bufseg += (bufoff / 16);
1069 // bufoff %= 16;
1070
1071 // Get the byte count
1072 lcount = ((uint16_t)(inb(iobase1 + ATA_CB_CH))<<8)+inb(iobase1 + ATA_CB_CL);
1073
1074 // adjust to read what we want
1075 if (header>lcount) {
1076 lbefore = lcount;
1077 header -= lcount;
1078 lcount = 0;
1079 }
1080 else {
1081 lbefore = header;
1082 header = 0;
1083 lcount -= lbefore;
1084 }
1085
1086 if (lcount>length) {
1087 lafter = lcount - length;
1088 lcount = length;
1089 length = 0;
1090 }
1091 else {
1092 lafter = 0;
1093 length -= lcount;
1094 }
1095
1096 // Save byte count
1097 count = lcount;
1098
1099 BX_DEBUG_ATA("Trying to read %04x bytes (%04x %04x %04x) ",lbefore+lcount+lafter,lbefore,lcount,lafter);
1100 BX_DEBUG_ATA("to 0x%04x:0x%04x\n",FP_SEG(buffer),FP_OFF(buffer));
1101
1102 // If counts not dividable by 4, use 16bits mode
1103 lmode = mode;
1104 if (lbefore & 0x03)
1105 lmode = ATA_MODE_PIO16;
1106 if (lcount & 0x03)
1107 lmode = ATA_MODE_PIO16;
1108 if (lafter & 0x03)
1109 lmode = ATA_MODE_PIO16;
1110
1111 // adds an extra byte if count are odd. before is always even
1112 if (lcount & 0x01) {
1113 lcount += 1;
1114 if ((lafter > 0) && (lafter & 0x01)) {
1115 lafter -= 1;
1116 }
1117 }
1118
1119#if VBOX_BIOS_CPU >= 80386
1120 if (lmode == ATA_MODE_PIO32) {
1121 lcount >>= 2;
1122 lbefore >>= 2;
1123 lafter >>= 2;
1124 } else
1125#endif
1126 {
1127 lcount >>= 1;
1128 lbefore >>= 1;
1129 lafter >>= 1;
1130 }
1131
1132#if VBOX_BIOS_CPU >= 80386
1133 if (lmode == ATA_MODE_PIO32) {
1134 if (lbefore)
1135 insd_discard(lbefore, iobase1);
1136 rep_insd(buffer, lcount, iobase1);
1137 if (lafter)
1138 insd_discard(lafter, iobase1);
1139 } else
1140#endif
1141 {
1142 if (lbefore)
1143 insw_discard(lbefore, iobase1);
1144 rep_insw(buffer, lcount, iobase1);
1145 if (lafter)
1146 insw_discard(lafter, iobase1);
1147 }
1148
1149
1150 // Compute new buffer address
1151 buffer += count;
1152
1153 // Save transferred bytes count
1154 transfer += count;
1155 bios_dsk->drqp.trsfbytes = transfer;
1156 }
1157 }
1158
1159 // Final check, device must be ready
1160 if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DF | ATA_CB_STAT_DRQ | ATA_CB_STAT_CHK) )
1161 != ATA_CB_STAT_RDY ) {
1162 BX_DEBUG_ATA("%s: not ready (status %02x)\n", __func__, (unsigned) status);
1163 // Enable interrupts
1164 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
1165 return 4;
1166 }
1167
1168 // Enable interrupts
1169 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
1170 return 0;
1171}
1172
1173// ---------------------------------------------------------------------------
1174// ATA/ATAPI driver : reset device; intended for ATAPI devices
1175// ---------------------------------------------------------------------------
1176 // returns
1177 // 0 : no error
1178 // 1 : error
1179uint16_t ata_soft_reset(uint16_t device)
1180{
1181 uint16_t iobase1, iobase2;
1182 uint8_t channel, slave;
1183 uint8_t status;
1184 bio_dsk_t __far *bios_dsk;
1185
1186 bios_dsk = read_word(0x0040, 0x000E) :> &EbdaData->bdisk;
1187
1188 channel = device / 2;
1189 slave = device % 2;
1190
1191 iobase1 = bios_dsk->channels[channel].iobase1;
1192 iobase2 = bios_dsk->channels[channel].iobase2;
1193
1194 /* Send a reset command to the device. */
1195 outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
1196 outb(iobase1 + ATA_CB_DH, slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0);
1197 outb(iobase1 + ATA_CB_CMD, ATA_CMD_DEVICE_RESET);
1198
1199 /* Wait for the device to clear BSY. */
1200 while (1) {
1201 status = inb(iobase1 + ATA_CB_STAT);
1202 if ( !(status & ATA_CB_STAT_BSY) ) break;
1203 }
1204
1205 /* Final check, device must be ready */
1206 if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DF | ATA_CB_STAT_DRQ | ATA_CB_STAT_CHK) )
1207 != ATA_CB_STAT_RDY ) {
1208 BX_DEBUG_ATA("%s: not ready (status %02x)\n", __func__, (unsigned) status);
1209 /* Enable interrupts */
1210 outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15);
1211 return 1;
1212 }
1213
1214 /* Enable interrupts */
1215 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
1216 return 0;
1217}
1218
1219
1220// ---------------------------------------------------------------------------
1221// End of ATA/ATAPI Driver
1222// ---------------------------------------------------------------------------
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