VirtualBox

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

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

BIOS: Put logical SPT into the FDPT properly; simplified conditional.

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