1 ///////////////////////////////////////////////////////////////////////// 2 // $Id$ 3 ///////////////////////////////////////////////////////////////////////// 4 // 5 // Copyright (C) 2002 MandrakeSoft S.A. 6 // 7 // MandrakeSoft S.A. 8 // 43, rue d'Aboukir 9 // 75002 Paris - France 10 // http://www.linux-mandrake.com/ 11 // http://www.mandrakesoft.com/ 12 // 13 // This library is free software; you can redistribute it and/or 14 // modify it under the terms of the GNU Lesser General Public 15 // License as published by the Free Software Foundation; either 16 // version 2 of the License, or (at your option) any later version. 17 // 18 // This library is distributed in the hope that it will be useful, 19 // but WITHOUT ANY WARRANTY; without even the implied warranty of 20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 // Lesser General Public License for more details. 22 // 23 // You should have received a copy of the GNU Lesser General Public 24 // License along with this library; if not, write to the Free Software 25 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 26 27 // ROM BIOS for use with Bochs/Plex86/QEMU emulation environment 28 29 30 // ROM BIOS compatability entry points: 31 // =================================== 32 // $e05b ; POST Entry Point 33 // $e2c3 ; NMI Handler Entry Point 34 // $e3fe ; INT 13h Fixed Disk Services Entry Point 35 // $e401 ; Fixed Disk Parameter Table 36 // $e6f2 ; INT 19h Boot Load Service Entry Point 37 // $e6f5 ; Configuration Data Table 38 // $e729 ; Baud Rate Generator Table 39 // $e739 ; INT 14h Serial Communications Service Entry Point 40 // $e82e ; INT 16h Keyboard Service Entry Point 41 // $e987 ; INT 09h Keyboard Service Entry Point 42 // $ec59 ; INT 13h Diskette Service Entry Point 43 // $ef57 ; INT 0Eh Diskette Hardware ISR Entry Point 44 // $efc7 ; Diskette Controller Parameter Table 45 // $efd2 ; INT 17h Printer Service Entry Point 46 // $f045 ; INT 10 Functions 0-Fh Entry Point 47 // $f065 ; INT 10h Video Support Service Entry Point 48 // $f0a4 ; MDA/CGA Video Parameter Table (INT 1Dh) 49 // $f841 ; INT 12h Memory Size Service Entry Point 50 // $f84d ; INT 11h Equipment List Service Entry Point 51 // $f859 ; INT 15h System Services Entry Point 52 // $fa6e ; Character Font for 320x200 & 640x200 Graphics (lower 128 characters) 53 // $fe6e ; INT 1Ah Time-of-day Service Entry Point 54 // $fea5 ; INT 08h System Timer ISR Entry Point 55 // $fef3 ; Initial Interrupt Vector Offsets Loaded by POST 56 // $ff53 ; IRET Instruction for Dummy Interrupt Handler 57 // $ff54 ; INT 05h Print Screen Service Entry Point 58 // $fff0 ; Power-up Entry Point 59 // $fff5 ; ASCII Date ROM was built - 8 characters in MM/DD/YY 60 // $fffe ; System Model ID 61 62 // NOTES for ATA/ATAPI driver (cbbochs (at) free.fr) 63 // Features 64 // - supports up to 4 ATA interfaces 65 // - device/geometry detection 66 // - 16bits/32bits device access 67 // - pchs/lba access 68 // - datain/dataout/packet command support 69 // 70 // NOTES for El-Torito Boot (cbbochs (at) free.fr) 71 // - CD-ROM booting is only available if ATA/ATAPI Driver is available 72 // - Current code is only able to boot mono-session cds 73 // - Current code can not boot and emulate a hard-disk 74 // the bios will panic otherwise 75 // - Current code also use memory in EBDA segement. 76 // - I used cmos byte 0x3D to store extended information on boot-device 77 // - Code has to be modified modified to handle multiple cdrom drives 78 // - Here are the cdrom boot failure codes: 79 // 1 : no atapi device found 80 // 2 : no atapi cdrom found 81 // 3 : can not read cd - BRVD 82 // 4 : cd is not eltorito (BRVD) 83 // 5 : cd is not eltorito (ISO TAG) 84 // 6 : cd is not eltorito (ELTORITO TAG) 85 // 7 : can not read cd - boot catalog 86 // 8 : boot catalog : bad header 87 // 9 : boot catalog : bad platform 88 // 10 : boot catalog : bad signature 89 // 11 : boot catalog : bootable flag not set 90 // 12 : can not read cd - boot image 91 // 92 // ATA driver 93 // - EBDA segment. 94 // I used memory starting at 0x121 in the segment 95 // - the translation policy is defined in cmos regs 0x39 & 0x3a 96 // 97 // TODO : 98 // 99 // int74 100 // - needs to be reworked. Uses direct [bp] offsets. (?) 101 // 102 // int13: 103 // - f04 (verify sectors) isn't complete (?) 104 // - f02/03/04 should set current cyl,etc in BDA (?) 105 // - rewrite int13_relocated & clean up int13 entry code 106 // 107 // NOTES: 108 // - NMI access (bit7 of addr written to 70h) 109 // 110 // ATA driver 111 // - should handle the "don't detect" bit (cmos regs 0x3b & 0x3c) 112 // - could send the multiple-sector read/write commands 113 // 114 // El-Torito 115 // - Emulate a Hard-disk (currently only diskette can be emulated) see "FIXME ElTorito Harddisk" 116 // - Implement remaining int13_cdemu functions (as defined by El-Torito specs) 117 // - cdrom drive is hardcoded to ide 0 device 1 in several places. see "FIXME ElTorito Hardcoded" 118 // - int13 Fix DL when emulating a cd. In that case DL is decremented before calling real int13. 119 // This is ok. But DL should be reincremented afterwards. 120 // - Fix all "FIXME ElTorito Various" 121 // - should be able to boot any cdrom instead of the first one 122 // 123 // BCC Bug: find a generic way to handle the bug of #asm after an "if" (fixed in 0.16.7) 124 125 #include "rombios.h" 126 127 #define DEBUG_ATA 0 128 #define DEBUG_INT13_HD 0 129 #define DEBUG_INT13_CD 0 130 #define DEBUG_INT13_ET 0 131 #define DEBUG_INT13_FL 0 132 #define DEBUG_INT15 0 133 #define DEBUG_INT16 0 134 #define DEBUG_INT1A 0 135 #define DEBUG_INT74 0 136 #define DEBUG_APM 0 137 138 #define BX_CPU 3 139 #define BX_USE_PS2_MOUSE 1 140 #define BX_CALL_INT15_4F 1 141 #define BX_USE_EBDA 1 142 #define BX_SUPPORT_FLOPPY 1 143 #define BX_FLOPPY_ON_CNT 37 /* 2 seconds */ 144 #define BX_PCIBIOS 1 145 #define BX_APM 1 146 147 #define BX_USE_ATADRV 1 148 #define BX_ELTORITO_BOOT 1 149 150 #define BX_MAX_ATA_INTERFACES 4 151 #define BX_MAX_ATA_DEVICES (BX_MAX_ATA_INTERFACES*2) 152 153 #define BX_VIRTUAL_PORTS 1 /* normal output to Bochs ports */ 154 #define BX_DEBUG_SERIAL 0 /* output to COM1 */ 155 156 /* model byte 0xFC = AT */ 157 #define SYS_MODEL_ID 0xFC 158 #define SYS_SUBMODEL_ID 0x00 159 #define BIOS_REVISION 1 160 #define BIOS_CONFIG_TABLE 0xe6f5 161 162 #ifndef BIOS_BUILD_DATE 163 # define BIOS_BUILD_DATE "06/23/99" 164 #endif 165 166 // 1K of base memory used for Extended Bios Data Area (EBDA) 167 // EBDA is used for PS/2 mouse support, and IDE BIOS, etc. 168 #define EBDA_SEG 0x9FC0 169 #define EBDA_SIZE 1 // In KiB 170 #define BASE_MEM_IN_K (640 - EBDA_SIZE) 171 172 /* 256 bytes at 0x9ff00 -- 0x9ffff is used for the IPL boot table. */ 173 #define IPL_SEG 0x9ff0 174 #define IPL_TABLE_OFFSET 0x0000 175 #define IPL_TABLE_ENTRIES 8 176 #define IPL_COUNT_OFFSET 0x0080 /* u16: number of valid table entries */ 177 #define IPL_SEQUENCE_OFFSET 0x0082 /* u16: next boot device */ 178 #define IPL_BOOTFIRST_OFFSET 0x0084 /* u16: user selected device */ 179 #define IPL_SIZE 0xff 180 #define IPL_TYPE_FLOPPY 0x01 181 #define IPL_TYPE_HARDDISK 0x02 182 #define IPL_TYPE_CDROM 0x03 183 #define IPL_TYPE_BEV 0x80 184 185 // Sanity Checks 186 #if BX_USE_ATADRV && BX_CPU<3 187 # error The ATA/ATAPI Driver can only to be used with a 386+ cpu 188 #endif 189 #if BX_USE_ATADRV && !BX_USE_EBDA 190 # error ATA/ATAPI Driver can only be used if EBDA is available 191 #endif 192 #if BX_ELTORITO_BOOT && !BX_USE_ATADRV 193 # error El-Torito Boot can only be use if ATA/ATAPI Driver is available 194 #endif 195 #if BX_PCIBIOS && BX_CPU<3 196 # error PCI BIOS can only be used with 386+ cpu 197 #endif 198 #if BX_APM && BX_CPU<3 199 # error APM BIOS can only be used with 386+ cpu 200 #endif 201 202 // define this if you want to make PCIBIOS working on a specific bridge only 203 // undef enables PCIBIOS when at least one PCI device is found 204 // i440FX is emulated by Bochs and QEMU 205 #define PCI_FIXED_HOST_BRIDGE 0x12378086 ;; i440FX PCI bridge 206 207 // #20 is dec 20 208 // #$20 is hex 20 = 32 209 // #0x20 is hex 20 = 32 210 // LDA #$20 211 // JSR $E820 212 // LDD .i,S 213 // JSR $C682 214 // mov al, #$20 215 216 // all hex literals should be prefixed with '0x' 217 // grep "#[0-9a-fA-F][0-9a-fA-F]" rombios.c 218 // no mov SEG-REG, #value, must mov register into seg-reg 219 // grep -i "mov[ ]*.s" rombios.c 220 221 // This is for compiling with gcc2 and gcc3 222 #define ASM_START #asm 223 #define ASM_END #endasm 224 225 ASM_START 226 .rom 227 228 .org 0x0000 229 230 #if BX_CPU >= 3 231 use16 386 232 #else 233 use16 286 234 #endif 235 236 MACRO HALT 237 ;; the HALT macro is called with the line number of the HALT call. 238 ;; The line number is then sent to the PANIC_PORT, causing Bochs/Plex 239 ;; to print a BX_PANIC message. This will normally halt the simulation 240 ;; with a message such as "BIOS panic at rombios.c, line 4091". 241 ;; However, users can choose to make panics non-fatal and continue. 242 #if BX_VIRTUAL_PORTS 243 mov dx,#PANIC_PORT 244 mov ax,#?1 245 out dx,ax 246 #else 247 mov dx,#0x80 248 mov ax,#?1 249 out dx,al 250 #endif 251 MEND 252 253 MACRO JMP_AP 254 db 0xea 255 dw ?2 256 dw ?1 257 MEND 258 259 MACRO SET_INT_VECTOR 260 mov ax, ?3 261 mov ?1*4, ax 262 mov ax, ?2 263 mov ?1*4+2, ax 264 MEND 265 266 ASM_END 267 268 typedef unsigned char Bit8u; 269 typedef unsigned short Bit16u; 270 typedef unsigned short bx_bool; 271 typedef unsigned long Bit32u; 272 273 274 void memsetb(seg,offset,value,count); 275 void memcpyb(dseg,doffset,sseg,soffset,count); 276 void memcpyd(dseg,doffset,sseg,soffset,count); 277 278 // memset of count bytes 279 void 280 memsetb(seg,offset,value,count) 281 Bit16u seg; 282 Bit16u offset; 283 Bit16u value; 284 Bit16u count; 285 { 286 ASM_START 287 push bp 288 mov bp, sp 289 290 push ax 291 push cx 292 push es 293 push di 294 295 mov cx, 10[bp] ; count 296 test cx, cx 297 je memsetb_end 298 mov ax, 4[bp] ; segment 299 mov es, ax 300 mov ax, 6[bp] ; offset 301 mov di, ax 302 mov al, 8[bp] ; value 303 cld 304 rep 305 stosb 306 307 memsetb_end: 308 pop di 309 pop es 310 pop cx 311 pop ax 312 313 pop bp 314 ASM_END 315 } 316 317 // memcpy of count bytes 318 void 319 memcpyb(dseg,doffset,sseg,soffset,count) 320 Bit16u dseg; 321 Bit16u doffset; 322 Bit16u sseg; 323 Bit16u soffset; 324 Bit16u count; 325 { 326 ASM_START 327 push bp 328 mov bp, sp 329 330 push ax 331 push cx 332 push es 333 push di 334 push ds 335 push si 336 337 mov cx, 12[bp] ; count 338 test cx, cx 339 je memcpyb_end 340 mov ax, 4[bp] ; dsegment 341 mov es, ax 342 mov ax, 6[bp] ; doffset 343 mov di, ax 344 mov ax, 8[bp] ; ssegment 345 mov ds, ax 346 mov ax, 10[bp] ; soffset 347 mov si, ax 348 cld 349 rep 350 movsb 351 352 memcpyb_end: 353 pop si 354 pop ds 355 pop di 356 pop es 357 pop cx 358 pop ax 359 360 pop bp 361 ASM_END 362 } 363 364 // memcpy of count dword 365 void 366 memcpyd(dseg,doffset,sseg,soffset,count) 367 Bit16u dseg; 368 Bit16u doffset; 369 Bit16u sseg; 370 Bit16u soffset; 371 Bit16u count; 372 { 373 ASM_START 374 push bp 375 mov bp, sp 376 377 push ax 378 push cx 379 push es 380 push di 381 push ds 382 push si 383 384 mov cx, 12[bp] ; count 385 test cx, cx 386 je memcpyd_end 387 mov ax, 4[bp] ; dsegment 388 mov es, ax 389 mov ax, 6[bp] ; doffset 390 mov di, ax 391 mov ax, 8[bp] ; ssegment 392 mov ds, ax 393 mov ax, 10[bp] ; soffset 394 mov si, ax 395 cld 396 rep 397 movsd 398 399 memcpyd_end: 400 pop si 401 pop ds 402 pop di 403 pop es 404 pop cx 405 pop ax 406 407 pop bp 408 ASM_END 409 } 410 411 // read_dword and write_dword functions 412 static Bit32u read_dword(); 413 static void write_dword(); 414 415 Bit32u 416 read_dword(seg, offset) 417 Bit16u seg; 418 Bit16u offset; 419 { 420 ASM_START 421 push bp 422 mov bp, sp 423 424 push bx 425 push ds 426 mov ax, 4[bp] ; segment 427 mov ds, ax 428 mov bx, 6[bp] ; offset 429 mov ax, [bx] 430 add bx, #2 431 mov dx, [bx] 432 ;; ax = return value (word) 433 ;; dx = return value (word) 434 pop ds 435 pop bx 436 437 pop bp 438 ASM_END 439 } 440 441 void 442 write_dword(seg, offset, data) 443 Bit16u seg; 444 Bit16u offset; 445 Bit32u data; 446 { 447 ASM_START 448 push bp 449 mov bp, sp 450 451 push ax 452 push bx 453 push ds 454 mov ax, 4[bp] ; segment 455 mov ds, ax 456 mov bx, 6[bp] ; offset 457 mov ax, 8[bp] ; data word 458 mov [bx], ax ; write data word 459 add bx, #2 460 mov ax, 10[bp] ; data word 461 mov [bx], ax ; write data word 462 pop ds 463 pop bx 464 pop ax 465 466 pop bp 467 ASM_END 468 } 469 470 // Bit32u (unsigned long) and long helper functions 471 ASM_START 472 473 ;; and function 474 landl: 475 landul: 476 SEG SS 477 and ax,[di] 478 SEG SS 479 and bx,2[di] 480 ret 481 482 ;; add function 483 laddl: 484 laddul: 485 SEG SS 486 add ax,[di] 487 SEG SS 488 adc bx,2[di] 489 ret 490 491 ;; cmp function 492 lcmpl: 493 lcmpul: 494 and eax, #0x0000FFFF 495 shl ebx, #16 496 or eax, ebx 497 shr ebx, #16 498 SEG SS 499 cmp eax, dword ptr [di] 500 ret 501 502 ;; sub function 503 lsubl: 504 lsubul: 505 SEG SS 506 sub ax,[di] 507 SEG SS 508 sbb bx,2[di] 509 ret 510 511 ;; mul function 512 lmull: 513 lmulul: 514 and eax, #0x0000FFFF 515 shl ebx, #16 516 or eax, ebx 517 SEG SS 518 mul eax, dword ptr [di] 519 mov ebx, eax 520 shr ebx, #16 521 ret 522 523 ;; dec function 524 ldecl: 525 ldecul: 526 SEG SS 527 dec dword ptr [bx] 528 ret 529 530 ;; or function 531 lorl: 532 lorul: 533 SEG SS 534 or ax,[di] 535 SEG SS 536 or bx,2[di] 537 ret 538 539 ;; inc function 540 lincl: 541 lincul: 542 SEG SS 543 inc dword ptr [bx] 544 ret 545 546 ;; tst function 547 ltstl: 548 ltstul: 549 and eax, #0x0000FFFF 550 shl ebx, #16 551 or eax, ebx 552 shr ebx, #16 553 test eax, eax 554 ret 555 556 ;; sr function 557 lsrul: 558 mov cx,di 559 jcxz lsr_exit 560 and eax, #0x0000FFFF 561 shl ebx, #16 562 or eax, ebx 563 lsr_loop: 564 shr eax, #1 565 loop lsr_loop 566 mov ebx, eax 567 shr ebx, #16 568 lsr_exit: 569 ret 570 571 ;; sl function 572 lsll: 573 lslul: 574 mov cx,di 575 jcxz lsl_exit 576 and eax, #0x0000FFFF 577 shl ebx, #16 578 or eax, ebx 579 lsl_loop: 580 shl eax, #1 581 loop lsl_loop 582 mov ebx, eax 583 shr ebx, #16 584 lsl_exit: 585 ret 586 587 idiv_: 588 cwd 589 idiv bx 590 ret 591 592 idiv_u: 593 xor dx,dx 594 div bx 595 ret 596 597 ldivul: 598 and eax, #0x0000FFFF 599 shl ebx, #16 600 or eax, ebx 601 xor edx, edx 602 SEG SS 603 mov bx, 2[di] 604 shl ebx, #16 605 SEG SS 606 mov bx, [di] 607 div ebx 608 mov ebx, eax 609 shr ebx, #16 610 ret 611 612 ASM_END 613 614 // for access to RAM area which is used by interrupt vectors 615 // and BIOS Data Area 616 617 typedef struct { 618 unsigned char filler1[0x400]; 619 unsigned char filler2[0x6c]; 620 Bit16u ticks_low; 621 Bit16u ticks_high; 622 Bit8u midnight_flag; 623 } bios_data_t; 624 625 #define BiosData ((bios_data_t *) 0) 626 627 #if BX_USE_ATADRV 628 typedef struct { 629 Bit16u heads; // # heads 630 Bit16u cylinders; // # cylinders 631 Bit16u spt; // # sectors / track 632 } chs_t; 633 634 // DPTE definition 635 typedef struct { 636 Bit16u iobase1; 637 Bit16u iobase2; 638 Bit8u prefix; 639 Bit8u unused; 640 Bit8u irq; 641 Bit8u blkcount; 642 Bit8u dma; 643 Bit8u pio; 644 Bit16u options; 645 Bit16u reserved; 646 Bit8u revision; 647 Bit8u checksum; 648 } dpte_t; 649 650 typedef struct { 651 Bit8u iface; // ISA or PCI 652 Bit16u iobase1; // IO Base 1 653 Bit16u iobase2; // IO Base 2 654 Bit8u irq; // IRQ 655 } ata_channel_t; 656 657 typedef struct { 658 Bit8u type; // Detected type of ata (ata/atapi/none/unknown) 659 Bit8u device; // Detected type of attached devices (hd/cd/none) 660 Bit8u removable; // Removable device flag 661 Bit8u lock; // Locks for removable devices 662 Bit8u mode; // transfer mode : PIO 16/32 bits - IRQ - ISADMA - PCIDMA 663 Bit16u blksize; // block size 664 665 Bit8u translation; // type of translation 666 chs_t lchs; // Logical CHS 667 chs_t pchs; // Physical CHS 668 669 Bit32u sectors_low; // Total sectors count 670 Bit32u sectors_high; 671 } ata_device_t; 672 673 typedef struct { 674 // ATA channels info 675 ata_channel_t channels[BX_MAX_ATA_INTERFACES]; 676 677 // ATA devices info 678 ata_device_t devices[BX_MAX_ATA_DEVICES]; 679 // 680 // map between (bios hd id - 0x80) and ata channels 681 Bit8u hdcount, hdidmap[BX_MAX_ATA_DEVICES]; 682 683 // map between (bios cd id - 0xE0) and ata channels 684 Bit8u cdcount, cdidmap[BX_MAX_ATA_DEVICES]; 685 686 // Buffer for DPTE table 687 dpte_t dpte; 688 689 // Count of transferred sectors and bytes 690 Bit16u trsfsectors; 691 Bit32u trsfbytes; 692 693 } ata_t; 694 695 #if BX_ELTORITO_BOOT 696 // ElTorito Device Emulation data 697 typedef struct { 698 Bit8u active; 699 Bit8u media; 700 Bit8u emulated_drive; 701 Bit8u controller_index; 702 Bit16u device_spec; 703 Bit32u ilba; 704 Bit16u buffer_segment; 705 Bit16u load_segment; 706 Bit16u sector_count; 707 708 // Virtual device 709 chs_t vdevice; 710 } cdemu_t; 711 #endif // BX_ELTORITO_BOOT 712 713 // for access to EBDA area 714 // The EBDA structure should conform to 715 // http://www.frontiernet.net/~fys/rombios.htm document 716 // I made the ata and cdemu structs begin at 0x121 in the EBDA seg 717 // EBDA must be at most 768 bytes; it lives at EBDA_SEG, and the boot 718 // device tables are at IPL_SEG 719 typedef struct { 720 unsigned char filler1[0x3D]; 721 722 // FDPT - Can be splitted in data members if needed 723 unsigned char fdpt0[0x10]; 724 unsigned char fdpt1[0x10]; 725 726 unsigned char filler2[0xC4]; 727 728 // ATA Driver data 729 ata_t ata; 730 731 #if BX_ELTORITO_BOOT 732 // El Torito Emulation data 733 cdemu_t cdemu; 734 #endif // BX_ELTORITO_BOOT 735 736 } ebda_data_t; 737 738 #define EbdaData ((ebda_data_t *) 0) 739 740 // for access to the int13ext structure 741 typedef struct { 742 Bit8u size; 743 Bit8u reserved; 744 Bit16u count; 745 Bit16u offset; 746 Bit16u segment; 747 Bit32u lba1; 748 Bit32u lba2; 749 } int13ext_t; 750 751 #define Int13Ext ((int13ext_t *) 0) 752 753 // Disk Physical Table definition 754 typedef struct { 755 Bit16u size; 756 Bit16u infos; 757 Bit32u cylinders; 758 Bit32u heads; 759 Bit32u spt; 760 Bit32u sector_count1; 761 Bit32u sector_count2; 762 Bit16u blksize; 763 Bit16u dpte_offset; 764 Bit16u dpte_segment; 765 Bit16u key; 766 Bit8u dpi_length; 767 Bit8u reserved1; 768 Bit16u reserved2; 769 Bit8u host_bus[4]; 770 Bit8u iface_type[8]; 771 Bit8u iface_path[8]; 772 Bit8u device_path[8]; 773 Bit8u reserved3; 774 Bit8u checksum; 775 } dpt_t; 776 777 #define Int13DPT ((dpt_t *) 0) 778 779 #endif // BX_USE_ATADRV 780 781 typedef struct { 782 union { 783 struct { 784 Bit16u di, si, bp, sp; 785 Bit16u bx, dx, cx, ax; 786 } r16; 787 struct { 788 Bit16u filler[4]; 789 Bit8u bl, bh, dl, dh, cl, ch, al, ah; 790 } r8; 791 } u; 792 } pusha_regs_t; 793 794 typedef struct { 795 union { 796 struct { 797 Bit32u edi, esi, ebp, esp; 798 Bit32u ebx, edx, ecx, eax; 799 } r32; 800 struct { 801 Bit16u di, filler1, si, filler2, bp, filler3, sp, filler4; 802 Bit16u bx, filler5, dx, filler6, cx, filler7, ax, filler8; 803 } r16; 804 struct { 805 Bit32u filler[4]; 806 Bit8u bl, bh; 807 Bit16u filler1; 808 Bit8u dl, dh; 809 Bit16u filler2; 810 Bit8u cl, ch; 811 Bit16u filler3; 812 Bit8u al, ah; 813 Bit16u filler4; 814 } r8; 815 } u; 816 } pushad_regs_t; 817 818 typedef struct { 819 union { 820 struct { 821 Bit16u flags; 822 } r16; 823 struct { 824 Bit8u flagsl; 825 Bit8u flagsh; 826 } r8; 827 } u; 828 } flags_t; 829 830 #define SetCF(x) x.u.r8.flagsl |= 0x01 831 #define SetZF(x) x.u.r8.flagsl |= 0x40 832 #define ClearCF(x) x.u.r8.flagsl &= 0xfe 833 #define ClearZF(x) x.u.r8.flagsl &= 0xbf 834 #define GetCF(x) (x.u.r8.flagsl & 0x01) 835 836 typedef struct { 837 Bit16u ip; 838 Bit16u cs; 839 flags_t flags; 840 } iret_addr_t; 841 842 typedef struct { 843 Bit16u type; 844 Bit16u flags; 845 Bit32u vector; 846 Bit32u description; 847 Bit32u reserved; 848 } ipl_entry_t; 849 850 851 852 static Bit8u inb(); 853 static Bit8u inb_cmos(); 854 static void outb(); 855 static void outb_cmos(); 856 static Bit16u inw(); 857 static void outw(); 858 static void init_rtc(); 859 static bx_bool rtc_updating(); 860 861 static Bit8u read_byte(); 862 static Bit16u read_word(); 863 static void write_byte(); 864 static void write_word(); 865 static void bios_printf(); 866 867 static Bit8u inhibit_mouse_int_and_events(); 868 static void enable_mouse_int_and_events(); 869 static Bit8u send_to_mouse_ctrl(); 870 static Bit8u get_mouse_data(); 871 static void set_kbd_command_byte(); 872 873 static void int09_function(); 874 static void int13_harddisk(); 875 static void int13_cdrom(); 876 static void int13_cdemu(); 877 static void int13_eltorito(); 878 static void int13_diskette_function(); 879 static void int14_function(); 880 static void int15_function(); 881 static void int16_function(); 882 static void int17_function(); 883 static void int19_function(); 884 static void int1a_function(); 885 static void int70_function(); 886 static void int74_function(); 887 static Bit16u get_CS(); 888 static Bit16u get_SS(); 889 static unsigned int enqueue_key(); 890 static unsigned int dequeue_key(); 891 static void get_hd_geometry(); 892 static void set_diskette_ret_status(); 893 static void set_diskette_current_cyl(); 894 static void determine_floppy_media(); 895 static bx_bool floppy_drive_exists(); 896 static bx_bool floppy_drive_recal(); 897 static bx_bool floppy_media_known(); 898 static bx_bool floppy_media_sense(); 899 static bx_bool set_enable_a20(); 900 static void debugger_on(); 901 static void debugger_off(); 902 static void keyboard_init(); 903 static void keyboard_panic(); 904 static void shutdown_status_panic(); 905 static void nmi_handler_msg(); 906 static void delay_ticks(); 907 static void delay_ticks_and_check_for_keystroke(); 908 909 static void interactive_bootkey(); 910 static void print_bios_banner(); 911 static void print_boot_device(); 912 static void print_boot_failure(); 913 static void print_cdromboot_failure(); 914 915 # if BX_USE_ATADRV 916 917 // ATA / ATAPI driver 918 void ata_init(); 919 void ata_detect(); 920 void ata_reset(); 921 922 Bit16u ata_cmd_non_data(); 923 Bit16u ata_cmd_data_in(); 924 Bit16u ata_cmd_data_out(); 925 Bit16u ata_cmd_packet(); 926 927 Bit16u atapi_get_sense(); 928 Bit16u atapi_is_ready(); 929 Bit16u atapi_is_cdrom(); 930 931 #endif // BX_USE_ATADRV 932 933 #if BX_ELTORITO_BOOT 934 935 void cdemu_init(); 936 Bit8u cdemu_isactive(); 937 Bit8u cdemu_emulated_drive(); 938 939 Bit16u cdrom_boot(); 940 941 #endif // BX_ELTORITO_BOOT 942 943 static char bios_cvs_version_string[] = "$Revision$ $Date$"; 944 945 #define BIOS_COPYRIGHT_STRING "(c) 2002 MandrakeSoft S.A. Written by Kevin Lawton & the Bochs team." 946 947 #if DEBUG_ATA 948 # define BX_DEBUG_ATA(a...) BX_DEBUG(a) 949 #else 950 # define BX_DEBUG_ATA(a...) 951 #endif 952 #if DEBUG_INT13_HD 953 # define BX_DEBUG_INT13_HD(a...) BX_DEBUG(a) 954 #else 955 # define BX_DEBUG_INT13_HD(a...) 956 #endif 957 #if DEBUG_INT13_CD 958 # define BX_DEBUG_INT13_CD(a...) BX_DEBUG(a) 959 #else 960 # define BX_DEBUG_INT13_CD(a...) 961 #endif 962 #if DEBUG_INT13_ET 963 # define BX_DEBUG_INT13_ET(a...) BX_DEBUG(a) 964 #else 965 # define BX_DEBUG_INT13_ET(a...) 966 #endif 967 #if DEBUG_INT13_FL 968 # define BX_DEBUG_INT13_FL(a...) BX_DEBUG(a) 969 #else 970 # define BX_DEBUG_INT13_FL(a...) 971 #endif 972 #if DEBUG_INT15 973 # define BX_DEBUG_INT15(a...) BX_DEBUG(a) 974 #else 975 # define BX_DEBUG_INT15(a...) 976 #endif 977 #if DEBUG_INT16 978 # define BX_DEBUG_INT16(a...) BX_DEBUG(a) 979 #else 980 # define BX_DEBUG_INT16(a...) 981 #endif 982 #if DEBUG_INT1A 983 # define BX_DEBUG_INT1A(a...) BX_DEBUG(a) 984 #else 985 # define BX_DEBUG_INT1A(a...) 986 #endif 987 #if DEBUG_INT74 988 # define BX_DEBUG_INT74(a...) BX_DEBUG(a) 989 #else 990 # define BX_DEBUG_INT74(a...) 991 #endif 992 993 #define SET_AL(val8) AX = ((AX & 0xff00) | (val8)) 994 #define SET_BL(val8) BX = ((BX & 0xff00) | (val8)) 995 #define SET_CL(val8) CX = ((CX & 0xff00) | (val8)) 996 #define SET_DL(val8) DX = ((DX & 0xff00) | (val8)) 997 #define SET_AH(val8) AX = ((AX & 0x00ff) | ((val8) << 8)) 998 #define SET_BH(val8) BX = ((BX & 0x00ff) | ((val8) << 8)) 999 #define SET_CH(val8) CX = ((CX & 0x00ff) | ((val8) << 8)) 1000 #define SET_DH(val8) DX = ((DX & 0x00ff) | ((val8) << 8)) 1001 1002 #define GET_AL() ( AX & 0x00ff ) 1003 #define GET_BL() ( BX & 0x00ff ) 1004 #define GET_CL() ( CX & 0x00ff ) 1005 #define GET_DL() ( DX & 0x00ff ) 1006 #define GET_AH() ( AX >> 8 ) 1007 #define GET_BH() ( BX >> 8 ) 1008 #define GET_CH() ( CX >> 8 ) 1009 #define GET_DH() ( DX >> 8 ) 1010 1011 #define GET_ELDL() ( ELDX & 0x00ff ) 1012 #define GET_ELDH() ( ELDX >> 8 ) 1013 1014 #define SET_CF() FLAGS |= 0x0001 1015 #define CLEAR_CF() FLAGS &= 0xfffe 1016 #define GET_CF() (FLAGS & 0x0001) 1017 1018 #define SET_ZF() FLAGS |= 0x0040 1019 #define CLEAR_ZF() FLAGS &= 0xffbf 1020 #define GET_ZF() (FLAGS & 0x0040) 1021 1022 #define UNSUPPORTED_FUNCTION 0x86 1023 1024 #define none 0 1025 #define MAX_SCAN_CODE 0x58 1026 1027 static struct { 1028 Bit16u normal; 1029 Bit16u shift; 1030 Bit16u control; 1031 Bit16u alt; 1032 Bit8u lock_flags; 1033 } scan_to_scanascii[MAX_SCAN_CODE + 1] = { 1034 { none, none, none, none, none }, 1035 { 0x011b, 0x011b, 0x011b, 0x0100, none }, /* escape */ 1036 { 0x0231, 0x0221, none, 0x7800, none }, /* 1! */ 1037 { 0x0332, 0x0340, 0x0300, 0x7900, none }, /* 2@ */ 1038 { 0x0433, 0x0423, none, 0x7a00, none }, /* 3# */ 1039 { 0x0534, 0x0524, none, 0x7b00, none }, /* 4$ */ 1040 { 0x0635, 0x0625, none, 0x7c00, none }, /* 5% */ 1041 { 0x0736, 0x075e, 0x071e, 0x7d00, none }, /* 6^ */ 1042 { 0x0837, 0x0826, none, 0x7e00, none }, /* 7& */ 1043 { 0x0938, 0x092a, none, 0x7f00, none }, /* 8* */ 1044 { 0x0a39, 0x0a28, none, 0x8000, none }, /* 9( */ 1045 { 0x0b30, 0x0b29, none, 0x8100, none }, /* 0) */ 1046 { 0x0c2d, 0x0c5f, 0x0c1f, 0x8200, none }, /* -_ */ 1047 { 0x0d3d, 0x0d2b, none, 0x8300, none }, /* =+ */ 1048 { 0x0e08, 0x0e08, 0x0e7f, none, none }, /* backspace */ 1049 { 0x0f09, 0x0f00, none, none, none }, /* tab */ 1050 { 0x1071, 0x1051, 0x1011, 0x1000, 0x40 }, /* Q */ 1051 { 0x1177, 0x1157, 0x1117, 0x1100, 0x40 }, /* W */ 1052 { 0x1265, 0x1245, 0x1205, 0x1200, 0x40 }, /* E */ 1053 { 0x1372, 0x1352, 0x1312, 0x1300, 0x40 }, /* R */ 1054 { 0x1474, 0x1454, 0x1414, 0x1400, 0x40 }, /* T */ 1055 { 0x1579, 0x1559, 0x1519, 0x1500, 0x40 }, /* Y */ 1056 { 0x1675, 0x1655, 0x1615, 0x1600, 0x40 }, /* U */ 1057 { 0x1769, 0x1749, 0x1709, 0x1700, 0x40 }, /* I */ 1058 { 0x186f, 0x184f, 0x180f, 0x1800, 0x40 }, /* O */ 1059 { 0x1970, 0x1950, 0x1910, 0x1900, 0x40 }, /* P */ 1060 { 0x1a5b, 0x1a7b, 0x1a1b, none, none }, /* [{ */ 1061 { 0x1b5d, 0x1b7d, 0x1b1d, none, none }, /* ]} */ 1062 { 0x1c0d, 0x1c0d, 0x1c0a, none, none }, /* Enter */ 1063 { none, none, none, none, none }, /* L Ctrl */ 1064 { 0x1e61, 0x1e41, 0x1e01, 0x1e00, 0x40 }, /* A */ 1065 { 0x1f73, 0x1f53, 0x1f13, 0x1f00, 0x40 }, /* S */ 1066 { 0x2064, 0x2044, 0x2004, 0x2000, 0x40 }, /* D */ 1067 { 0x2166, 0x2146, 0x2106, 0x2100, 0x40 }, /* F */ 1068 { 0x2267, 0x2247, 0x2207, 0x2200, 0x40 }, /* G */ 1069 { 0x2368, 0x2348, 0x2308, 0x2300, 0x40 }, /* H */ 1070 { 0x246a, 0x244a, 0x240a, 0x2400, 0x40 }, /* J */ 1071 { 0x256b, 0x254b, 0x250b, 0x2500, 0x40 }, /* K */ 1072 { 0x266c, 0x264c, 0x260c, 0x2600, 0x40 }, /* L */ 1073 { 0x273b, 0x273a, none, none, none }, /* ;: */ 1074 { 0x2827, 0x2822, none, none, none }, /* '" */ 1075 { 0x2960, 0x297e, none, none, none }, /* `~ */ 1076 { none, none, none, none, none }, /* L shift */ 1077 { 0x2b5c, 0x2b7c, 0x2b1c, none, none }, /* |\ */ 1078 { 0x2c7a, 0x2c5a, 0x2c1a, 0x2c00, 0x40 }, /* Z */ 1079 { 0x2d78, 0x2d58, 0x2d18, 0x2d00, 0x40 }, /* X */ 1080 { 0x2e63, 0x2e43, 0x2e03, 0x2e00, 0x40 }, /* C */ 1081 { 0x2f76, 0x2f56, 0x2f16, 0x2f00, 0x40 }, /* V */ 1082 { 0x3062, 0x3042, 0x3002, 0x3000, 0x40 }, /* B */ 1083 { 0x316e, 0x314e, 0x310e, 0x3100, 0x40 }, /* N */ 1084 { 0x326d, 0x324d, 0x320d, 0x3200, 0x40 }, /* M */ 1085 { 0x332c, 0x333c, none, none, none }, /* ,< */ 1086 { 0x342e, 0x343e, none, none, none }, /* .> */ 1087 { 0x352f, 0x353f, none, none, none }, /* /? */ 1088 { none, none, none, none, none }, /* R Shift */ 1089 { 0x372a, 0x372a, none, none, none }, /* * */ 1090 { none, none, none, none, none }, /* L Alt */ 1091 { 0x3920, 0x3920, 0x3920, 0x3920, none }, /* space */ 1092 { none, none, none, none, none }, /* caps lock */ 1093 { 0x3b00, 0x5400, 0x5e00, 0x6800, none }, /* F1 */ 1094 { 0x3c00, 0x5500, 0x5f00, 0x6900, none }, /* F2 */ 1095 { 0x3d00, 0x5600, 0x6000, 0x6a00, none }, /* F3 */ 1096 { 0x3e00, 0x5700, 0x6100, 0x6b00, none }, /* F4 */ 1097 { 0x3f00, 0x5800, 0x6200, 0x6c00, none }, /* F5 */ 1098 { 0x4000, 0x5900, 0x6300, 0x6d00, none }, /* F6 */ 1099 { 0x4100, 0x5a00, 0x6400, 0x6e00, none }, /* F7 */ 1100 { 0x4200, 0x5b00, 0x6500, 0x6f00, none }, /* F8 */ 1101 { 0x4300, 0x5c00, 0x6600, 0x7000, none }, /* F9 */ 1102 { 0x4400, 0x5d00, 0x6700, 0x7100, none }, /* F10 */ 1103 { none, none, none, none, none }, /* Num Lock */ 1104 { none, none, none, none, none }, /* Scroll Lock */ 1105 { 0x4700, 0x4737, 0x7700, none, 0x20 }, /* 7 Home */ 1106 { 0x4800, 0x4838, none, none, 0x20 }, /* 8 UP */ 1107 { 0x4900, 0x4939, 0x8400, none, 0x20 }, /* 9 PgUp */ 1108 { 0x4a2d, 0x4a2d, none, none, none }, /* - */ 1109 { 0x4b00, 0x4b34, 0x7300, none, 0x20 }, /* 4 Left */ 1110 { 0x4c00, 0x4c35, none, none, 0x20 }, /* 5 */ 1111 { 0x4d00, 0x4d36, 0x7400, none, 0x20 }, /* 6 Right */ 1112 { 0x4e2b, 0x4e2b, none, none, none }, /* + */ 1113 { 0x4f00, 0x4f31, 0x7500, none, 0x20 }, /* 1 End */ 1114 { 0x5000, 0x5032, none, none, 0x20 }, /* 2 Down */ 1115 { 0x5100, 0x5133, 0x7600, none, 0x20 }, /* 3 PgDn */ 1116 { 0x5200, 0x5230, none, none, 0x20 }, /* 0 Ins */ 1117 { 0x5300, 0x532e, none, none, 0x20 }, /* Del */ 1118 { none, none, none, none, none }, 1119 { none, none, none, none, none }, 1120 { 0x565c, 0x567c, none, none, none }, /* \| */ 1121 { 0x8500, 0x8700, 0x8900, 0x8b00, none }, /* F11 */ 1122 { 0x8600, 0x8800, 0x8a00, 0x8c00, none }, /* F12 */ 1123 }; 1124 1125 Bit8u 1126 inb(port) 1127 Bit16u port; 1128 { 1129 ASM_START 1130 push bp 1131 mov bp, sp 1132 1133 push dx 1134 mov dx, 4[bp] 1135 in al, dx 1136 pop dx 1137 1138 pop bp 1139 ASM_END 1140 } 1141 1142 #if BX_USE_ATADRV 1143 Bit16u 1144 inw(port) 1145 Bit16u port; 1146 { 1147 ASM_START 1148 push bp 1149 mov bp, sp 1150 1151 push dx 1152 mov dx, 4[bp] 1153 in ax, dx 1154 pop dx 1155 1156 pop bp 1157 ASM_END 1158 } 1159 #endif 1160 1161 void 1162 outb(port, val) 1163 Bit16u port; 1164 Bit8u val; 1165 { 1166 ASM_START 1167 push bp 1168 mov bp, sp 1169 1170 push ax 1171 push dx 1172 mov dx, 4[bp] 1173 mov al, 6[bp] 1174 out dx, al 1175 pop dx 1176 pop ax 1177 1178 pop bp 1179 ASM_END 1180 } 1181 1182 #if BX_USE_ATADRV 1183 void 1184 outw(port, val) 1185 Bit16u port; 1186 Bit16u val; 1187 { 1188 ASM_START 1189 push bp 1190 mov bp, sp 1191 1192 push ax 1193 push dx 1194 mov dx, 4[bp] 1195 mov ax, 6[bp] 1196 out dx, ax 1197 pop dx 1198 pop ax 1199 1200 pop bp 1201 ASM_END 1202 } 1203 #endif 1204 1205 void 1206 outb_cmos(cmos_reg, val) 1207 Bit8u cmos_reg; 1208 Bit8u val; 1209 { 1210 ASM_START 1211 push bp 1212 mov bp, sp 1213 1214 mov al, 4[bp] ;; cmos_reg 1215 out 0x70, al 1216 mov al, 6[bp] ;; val 1217 out 0x71, al 1218 1219 pop bp 1220 ASM_END 1221 } 1222 1223 Bit8u 1224 inb_cmos(cmos_reg) 1225 Bit8u cmos_reg; 1226 { 1227 ASM_START 1228 push bp 1229 mov bp, sp 1230 1231 mov al, 4[bp] ;; cmos_reg 1232 out 0x70, al 1233 in al, 0x71 1234 1235 pop bp 1236 ASM_END 1237 } 1238 1239 void 1240 init_rtc() 1241 { 1242 outb_cmos(0x0a, 0x26); 1243 outb_cmos(0x0b, 0x02); 1244 inb_cmos(0x0c); 1245 inb_cmos(0x0d); 1246 } 1247 1248 bx_bool 1249 rtc_updating() 1250 { 1251 // This function checks to see if the update-in-progress bit 1252 // is set in CMOS Status Register A. If not, it returns 0. 1253 // If it is set, it tries to wait until there is a transition 1254 // to 0, and will return 0 if such a transition occurs. A 1 1255 // is returned only after timing out. The maximum period 1256 // that this bit should be set is constrained to 244useconds. 1257 // The count I use below guarantees coverage or more than 1258 // this time, with any reasonable IPS setting. 1259 1260 Bit16u count; 1261 1262 count = 25000; 1263 while (--count != 0) { 1264 if ( (inb_cmos(0x0a) & 0x80) == 0 ) 1265 return(0); 1266 } 1267 return(1); // update-in-progress never transitioned to 0 1268 } 1269 1270 1271 Bit8u 1272 read_byte(seg, offset) 1273 Bit16u seg; 1274 Bit16u offset; 1275 { 1276 ASM_START 1277 push bp 1278 mov bp, sp 1279 1280 push bx 1281 push ds 1282 mov ax, 4[bp] ; segment 1283 mov ds, ax 1284 mov bx, 6[bp] ; offset 1285 mov al, [bx] 1286 ;; al = return value (byte) 1287 pop ds 1288 pop bx 1289 1290 pop bp 1291 ASM_END 1292 } 1293 1294 Bit16u 1295 read_word(seg, offset) 1296 Bit16u seg; 1297 Bit16u offset; 1298 { 1299 ASM_START 1300 push bp 1301 mov bp, sp 1302 1303 push bx 1304 push ds 1305 mov ax, 4[bp] ; segment 1306 mov ds, ax 1307 mov bx, 6[bp] ; offset 1308 mov ax, [bx] 1309 ;; ax = return value (word) 1310 pop ds 1311 pop bx 1312 1313 pop bp 1314 ASM_END 1315 } 1316 1317 void 1318 write_byte(seg, offset, data) 1319 Bit16u seg; 1320 Bit16u offset; 1321 Bit8u data; 1322 { 1323 ASM_START 1324 push bp 1325 mov bp, sp 1326 1327 push ax 1328 push bx 1329 push ds 1330 mov ax, 4[bp] ; segment 1331 mov ds, ax 1332 mov bx, 6[bp] ; offset 1333 mov al, 8[bp] ; data byte 1334 mov [bx], al ; write data byte 1335 pop ds 1336 pop bx 1337 pop ax 1338 1339 pop bp 1340 ASM_END 1341 } 1342 1343 void 1344 write_word(seg, offset, data) 1345 Bit16u seg; 1346 Bit16u offset; 1347 Bit16u data; 1348 { 1349 ASM_START 1350 push bp 1351 mov bp, sp 1352 1353 push ax 1354 push bx 1355 push ds 1356 mov ax, 4[bp] ; segment 1357 mov ds, ax 1358 mov bx, 6[bp] ; offset 1359 mov ax, 8[bp] ; data word 1360 mov [bx], ax ; write data word 1361 pop ds 1362 pop bx 1363 pop ax 1364 1365 pop bp 1366 ASM_END 1367 } 1368 1369 Bit16u 1370 get_CS() 1371 { 1372 ASM_START 1373 mov ax, cs 1374 ASM_END 1375 } 1376 1377 Bit16u 1378 get_SS() 1379 { 1380 ASM_START 1381 mov ax, ss 1382 ASM_END 1383 } 1384 1385 #if BX_DEBUG_SERIAL 1386 /* serial debug port*/ 1387 #define BX_DEBUG_PORT 0x03f8 1388 1389 /* data */ 1390 #define UART_RBR 0x00 1391 #define UART_THR 0x00 1392 1393 /* control */ 1394 #define UART_IER 0x01 1395 #define UART_IIR 0x02 1396 #define UART_FCR 0x02 1397 #define UART_LCR 0x03 1398 #define UART_MCR 0x04 1399 #define UART_DLL 0x00 1400 #define UART_DLM 0x01 1401 1402 /* status */ 1403 #define UART_LSR 0x05 1404 #define UART_MSR 0x06 1405 #define UART_SCR 0x07 1406 1407 int uart_can_tx_byte(base_port) 1408 Bit16u base_port; 1409 { 1410 return inb(base_port + UART_LSR) & 0x20; 1411 } 1412 1413 void uart_wait_to_tx_byte(base_port) 1414 Bit16u base_port; 1415 { 1416 while (!uart_can_tx_byte(base_port)); 1417 } 1418 1419 void uart_wait_until_sent(base_port) 1420 Bit16u base_port; 1421 { 1422 while (!(inb(base_port + UART_LSR) & 0x40)); 1423 } 1424 1425 void uart_tx_byte(base_port, data) 1426 Bit16u base_port; 1427 Bit8u data; 1428 { 1429 uart_wait_to_tx_byte(base_port); 1430 outb(base_port + UART_THR, data); 1431 uart_wait_until_sent(base_port); 1432 } 1433 #endif 1434 1435 void 1436 wrch(c) 1437 Bit8u c; 1438 { 1439 ASM_START 1440 push bp 1441 mov bp, sp 1442 1443 push bx 1444 mov ah, #0x0e 1445 mov al, 4[bp] 1446 xor bx,bx 1447 int #0x10 1448 pop bx 1449 1450 pop bp 1451 ASM_END 1452 } 1453 1454 void 1455 send(action, c) 1456 Bit16u action; 1457 Bit8u c; 1458 { 1459 #if BX_DEBUG_SERIAL 1460 if (c == '\n') uart_tx_byte(BX_DEBUG_PORT, '\r'); 1461 uart_tx_byte(BX_DEBUG_PORT, c); 1462 #endif 1463 #if BX_VIRTUAL_PORTS 1464 if (action & BIOS_PRINTF_DEBUG) outb(DEBUG_PORT, c); 1465 if (action & BIOS_PRINTF_INFO) outb(INFO_PORT, c); 1466 #endif 1467 if (action & BIOS_PRINTF_SCREEN) { 1468 if (c == '\n') wrch('\r'); 1469 wrch(c); 1470 } 1471 } 1472 1473 void 1474 put_int(action, val, width, neg) 1475 Bit16u action; 1476 short val, width; 1477 bx_bool neg; 1478 { 1479 short nval = val / 10; 1480 if (nval) 1481 put_int(action, nval, width - 1, neg); 1482 else { 1483 while (--width > 0) send(action, ' '); 1484 if (neg) send(action, '-'); 1485 } 1486 send(action, val - (nval * 10) + '0'); 1487 } 1488 1489 void 1490 put_uint(action, val, width, neg) 1491 Bit16u action; 1492 unsigned short val; 1493 short width; 1494 bx_bool neg; 1495 { 1496 unsigned short nval = val / 10; 1497 if (nval) 1498 put_uint(action, nval, width - 1, neg); 1499 else { 1500 while (--width > 0) send(action, ' '); 1501 if (neg) send(action, '-'); 1502 } 1503 send(action, val - (nval * 10) + '0'); 1504 } 1505 1506 void 1507 put_luint(action, val, width, neg) 1508 Bit16u action; 1509 unsigned long val; 1510 short width; 1511 bx_bool neg; 1512 { 1513 unsigned long nval = val / 10; 1514 if (nval) 1515 put_luint(action, nval, width - 1, neg); 1516 else { 1517 while (--width > 0) send(action, ' '); 1518 if (neg) send(action, '-'); 1519 } 1520 send(action, val - (nval * 10) + '0'); 1521 } 1522 1523 void put_str(action, segment, offset) 1524 Bit16u action; 1525 Bit16u segment; 1526 Bit16u offset; 1527 { 1528 Bit8u c; 1529 1530 while (c = read_byte(segment, offset)) { 1531 send(action, c); 1532 offset++; 1533 } 1534 } 1535 1536 void 1537 delay_ticks(ticks) 1538 Bit16u ticks; 1539 { 1540 long ticks_to_wait, delta; 1541 Bit32u prev_ticks, t; 1542 1543 /* 1544 * The 0:046c wraps around at 'midnight' according to a 18.2Hz clock. 1545 * We also have to be careful about interrupt storms. 1546 */ 1547 ASM_START 1548 pushf 1549 sti 1550 ASM_END 1551 ticks_to_wait = ticks; 1552 prev_ticks = read_dword(0x0, 0x46c); 1553 do 1554 { 1555 ASM_START 1556 hlt 1557 ASM_END 1558 t = read_dword(0x0, 0x46c); 1559 if (t > prev_ticks) 1560 { 1561 delta = t - prev_ticks; /* The temp var is required or bcc screws up. */ 1562 ticks_to_wait -= delta; 1563 } 1564 else if (t < prev_ticks) 1565 { 1566 ticks_to_wait -= t; /* wrapped */ 1567 } 1568 1569 prev_ticks = t; 1570 } while (ticks_to_wait > 0); 1571 ASM_START 1572 cli 1573 popf 1574 ASM_END 1575 } 1576 1577 Bit8u 1578 check_for_keystroke() 1579 { 1580 ASM_START 1581 mov ax, #0x100 1582 int #0x16 1583 jz no_key 1584 mov al, #1 1585 jmp done 1586 no_key: 1587 xor al, al 1588 done: 1589 ASM_END 1590 } 1591 1592 Bit8u 1593 get_keystroke() 1594 { 1595 ASM_START 1596 mov ax, #0x0 1597 int #0x16 1598 xchg ah, al 1599 ASM_END 1600 } 1601 1602 void 1603 delay_ticks_and_check_for_keystroke(ticks, count) 1604 Bit16u ticks, count; 1605 { 1606 Bit16u i; 1607 for (i = 1; i <= count; i++) { 1608 delay_ticks(ticks); 1609 if (check_for_keystroke()) 1610 break; 1611 } 1612 } 1613 1614 //-------------------------------------------------------------------------- 1615 // bios_printf() 1616 // A compact variable argument printf function. 1617 // 1618 // Supports %[format_width][length]format 1619 // where format can be x,X,u,d,s,S,c 1620 // and the optional length modifier is l (ell) 1621 //-------------------------------------------------------------------------- 1622 void 1623 bios_printf(action, s) 1624 Bit16u action; 1625 Bit8u *s; 1626 { 1627 Bit8u c, format_char; 1628 bx_bool in_format; 1629 short i; 1630 Bit16u *arg_ptr; 1631 Bit16u arg_seg, arg, nibble, hibyte, shift_count, format_width, hexadd; 1632 1633 arg_ptr = &s; 1634 arg_seg = get_SS(); 1635 1636 in_format = 0; 1637 format_width = 0; 1638 1639 if ((action & BIOS_PRINTF_DEBHALT) == BIOS_PRINTF_DEBHALT) { 1640 #if BX_VIRTUAL_PORTS 1641 outb(PANIC_PORT2, 0x00); 1642 #endif 1643 bios_printf (BIOS_PRINTF_SCREEN, "FATAL: "); 1644 } 1645 1646 while (c = read_byte(get_CS(), s)) { 1647 if ( c == '%' ) { 1648 in_format = 1; 1649 format_width = 0; 1650 } 1651 else if (in_format) { 1652 if ( (c>='0') && (c<='9') ) { 1653 format_width = (format_width * 10) + (c - '0'); 1654 } 1655 else { 1656 arg_ptr++; // increment to next arg 1657 arg = read_word(arg_seg, arg_ptr); 1658 if (c == 'x' || c == 'X') { 1659 if (format_width == 0) 1660 format_width = 4; 1661 if (c == 'x') 1662 hexadd = 'a'; 1663 else 1664 hexadd = 'A'; 1665 for (i=format_width-1; i>=0; i--) { 1666 nibble = (arg >> (4 * i)) & 0x000f; 1667 send (action, (nibble<=9)? (nibble+'0') : (nibble-10+hexadd)); 1668 } 1669 } 1670 else if (c == 'u') { 1671 put_uint(action, arg, format_width, 0); 1672 } 1673 else if (c == 'l') { 1674 s++; 1675 c = read_byte(get_CS(), s); /* is it ld,lx,lu? */ 1676 arg_ptr++; /* increment to next arg */ 1677 hibyte = read_word(arg_seg, arg_ptr); 1678 if (c == 'd') { 1679 if (hibyte & 0x8000) 1680 put_luint(action, 0L-(((Bit32u) hibyte << 16) | arg), format_width-1, 1); 1681 else 1682 put_luint(action, ((Bit32u) hibyte << 16) | arg, format_width, 0); 1683 } 1684 else if (c == 'u') { 1685 put_luint(action, ((Bit32u) hibyte << 16) | arg, format_width, 0); 1686 } 1687 else if (c == 'x' || c == 'X') 1688 { 1689 if (format_width == 0) 1690 format_width = 8; 1691 if (c == 'x') 1692 hexadd = 'a'; 1693 else 1694 hexadd = 'A'; 1695 for (i=format_width-1; i>=0; i--) { 1696 nibble = ((((Bit32u) hibyte <<16) | arg) >> (4 * i)) & 0x000f; 1697 send (action, (nibble<=9)? (nibble+'0') : (nibble-10+hexadd)); 1698 } 1699 } 1700 } 1701 else if (c == 'd') { 1702 if (arg & 0x8000) 1703 put_int(action, -arg, format_width - 1, 1); 1704 else 1705 put_int(action, arg, format_width, 0); 1706 } 1707 else if (c == 's') { 1708 put_str(action, get_CS(), arg); 1709 } 1710 else if (c == 'S') { 1711 hibyte = arg; 1712 arg_ptr++; 1713 arg = read_word(arg_seg, arg_ptr); 1714 put_str(action, hibyte, arg); 1715 } 1716 else if (c == 'c') { 1717 send(action, arg); 1718 } 1719 else 1720 BX_PANIC("bios_printf: unknown format\n"); 1721 in_format = 0; 1722 } 1723 } 1724 else { 1725 send(action, c); 1726 } 1727 s ++; 1728 } 1729 1730 if (action & BIOS_PRINTF_HALT) { 1731 // freeze in a busy loop. 1732 ASM_START 1733 cli 1734 halt2_loop: 1735 hlt 1736 jmp halt2_loop 1737 ASM_END 1738 } 1739 } 1740 1741 //-------------------------------------------------------------------------- 1742 // keyboard_init 1743 //-------------------------------------------------------------------------- 1744 // this file is based on LinuxBIOS implementation of keyboard.c 1745 // could convert to #asm to gain space 1746 void 1747 keyboard_init() 1748 { 1749 Bit16u max; 1750 1751 /* ------------------- Flush buffers ------------------------*/ 1752 /* Wait until buffer is empty */ 1753 max=0xffff; 1754 while ( (inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x00); 1755 1756 /* flush incoming keys */ 1757 max=0x2000; 1758 while (--max > 0) { 1759 outb(0x80, 0x00); 1760 if (inb(0x64) & 0x01) { 1761 inb(0x60); 1762 max = 0x2000; 1763 } 1764 } 1765 1766 // Due to timer issues, and if the IPS setting is > 15000000, 1767 // the incoming keys might not be flushed here. That will 1768 // cause a panic a few lines below. See sourceforge bug report : 1769 // [ 642031 ] FATAL: Keyboard RESET error:993 1770 1771 /* ------------------- controller side ----------------------*/ 1772 /* send cmd = 0xAA, self test 8042 */ 1773 outb(0x64, 0xaa); 1774 1775 /* Wait until buffer is empty */ 1776 max=0xffff; 1777 while ( (inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x00); 1778 if (max==0x0) keyboard_panic(00); 1779 1780 /* Wait for data */ 1781 max=0xffff; 1782 while ( ((inb(0x64) & 0x01) == 0) && (--max>0) ) outb(0x80, 0x01); 1783 if (max==0x0) keyboard_panic(01); 1784 1785 /* read self-test result, 0x55 should be returned from 0x60 */ 1786 if ((inb(0x60) != 0x55)){ 1787 keyboard_panic(991); 1788 } 1789 1790 /* send cmd = 0xAB, keyboard interface test */ 1791 outb(0x64,0xab); 1792 1793 /* Wait until buffer is empty */ 1794 max=0xffff; 1795 while ((inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x10); 1796 if (max==0x0) keyboard_panic(10); 1797 1798 /* Wait for data */ 1799 max=0xffff; 1800 while ( ((inb(0x64) & 0x01) == 0) && (--max>0) ) outb(0x80, 0x11); 1801 if (max==0x0) keyboard_panic(11); 1802 1803 /* read keyboard interface test result, */ 1804 /* 0x00 should be returned form 0x60 */ 1805 if ((inb(0x60) != 0x00)) { 1806 keyboard_panic(992); 1807 } 1808 1809 /* Enable Keyboard clock */ 1810 outb(0x64,0xae); 1811 outb(0x64,0xa8); 1812 1813 /* ------------------- keyboard side ------------------------*/ 1814 /* reset kerboard and self test (keyboard side) */ 1815 outb(0x60, 0xff); 1816 1817 /* Wait until buffer is empty */ 1818 max=0xffff; 1819 while ((inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x20); 1820 if (max==0x0) keyboard_panic(20); 1821 1822 /* Wait for data */ 1823 max=0xffff; 1824 while ( ((inb(0x64) & 0x01) == 0) && (--max>0) ) outb(0x80, 0x21); 1825 if (max==0x0) keyboard_panic(21); 1826 1827 /* keyboard should return ACK */ 1828 if ((inb(0x60) != 0xfa)) { 1829 keyboard_panic(993); 1830 } 1831 1832 /* Wait for data */ 1833 max=0xffff; 1834 while ( ((inb(0x64) & 0x01) == 0) && (--max>0) ) outb(0x80, 0x31); 1835 if (max==0x0) keyboard_panic(31); 1836 1837 if ((inb(0x60) != 0xaa)) { 1838 keyboard_panic(994); 1839 } 1840 1841 /* Disable keyboard */ 1842 outb(0x60, 0xf5); 1843 1844 /* Wait until buffer is empty */ 1845 max=0xffff; 1846 while ((inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x40); 1847 if (max==0x0) keyboard_panic(40); 1848 1849 /* Wait for data */ 1850 max=0xffff; 1851 while ( ((inb(0x64) & 0x01) == 0) && (--max>0) ) outb(0x80, 0x41); 1852 if (max==0x0) keyboard_panic(41); 1853 1854 /* keyboard should return ACK */ 1855 if ((inb(0x60) != 0xfa)) { 1856 keyboard_panic(995); 1857 } 1858 1859 /* Write Keyboard Mode */ 1860 outb(0x64, 0x60); 1861 1862 /* Wait until buffer is empty */ 1863 max=0xffff; 1864 while ((inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x50); 1865 if (max==0x0) keyboard_panic(50); 1866 1867 /* send cmd: scan code convert, disable mouse, enable IRQ 1 */ 1868 outb(0x60, 0x61); 1869 1870 /* Wait until buffer is empty */ 1871 max=0xffff; 1872 while ((inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x60); 1873 if (max==0x0) keyboard_panic(60); 1874 1875 /* Enable keyboard */ 1876 outb(0x60, 0xf4); 1877 1878 /* Wait until buffer is empty */ 1879 max=0xffff; 1880 while ((inb(0x64) & 0x02) && (--max>0)) outb(0x80, 0x70); 1881 if (max==0x0) keyboard_panic(70); 1882 1883 /* Wait for data */ 1884 max=0xffff; 1885 while ( ((inb(0x64) & 0x01) == 0) && (--max>0) ) outb(0x80, 0x71); 1886 if (max==0x0) keyboard_panic(70); 1887 1888 /* keyboard should return ACK */ 1889 if ((inb(0x60) != 0xfa)) { 1890 keyboard_panic(996); 1891 } 1892 1893 outb(0x80, 0x77); 1894 } 1895 1896 //-------------------------------------------------------------------------- 1897 // keyboard_panic 1898 //-------------------------------------------------------------------------- 1899 void 1900 keyboard_panic(status) 1901 Bit16u status; 1902 { 1903 // If you're getting a 993 keyboard panic here, 1904 // please see the comment in keyboard_init 1905 1906 BX_PANIC("Keyboard error:%u\n",status); 1907 } 1908 1909 //-------------------------------------------------------------------------- 1910 // shutdown_status_panic 1911 // called when the shutdown statsu is not implemented, displays the status 1912 //-------------------------------------------------------------------------- 1913 void 1914 shutdown_status_panic(status) 1915 Bit16u status; 1916 { 1917 BX_PANIC("Unimplemented shutdown status: %02x\n",(Bit8u)status); 1918 } 1919 1920 void s3_resume_panic() 1921 { 1922 BX_PANIC("Returned from s3_resume.\n"); 1923 } 1924 1925 //-------------------------------------------------------------------------- 1926 // print_bios_banner 1927 // displays a the bios version 1928 //-------------------------------------------------------------------------- 1929 void 1930 print_bios_banner() 1931 { 1932 printf(BX_APPNAME" BIOS - build: %s\n%s\nOptions: ", 1933 BIOS_BUILD_DATE, bios_cvs_version_string); 1934 printf( 1935 #if BX_APM 1936 "apmbios " 1937 #endif 1938 #if BX_PCIBIOS 1939 "pcibios " 1940 #endif 1941 #if BX_ELTORITO_BOOT 1942 "eltorito " 1943 #endif 1944 #if BX_ROMBIOS32 1945 "rombios32 " 1946 #endif 1947 "\n\n"); 1948 } 1949 1950 //-------------------------------------------------------------------------- 1951 // BIOS Boot Specification 1.0.1 compatibility 1952 // 1953 // Very basic support for the BIOS Boot Specification, which allows expansion 1954 // ROMs to register themselves as boot devices, instead of just stealing the 1955 // INT 19h boot vector. 1956 // 1957 // This is a hack: to do it properly requires a proper PnP BIOS and we aren't 1958 // one; we just lie to the option ROMs to make them behave correctly. 1959 // We also don't support letting option ROMs register as bootable disk 1960 // drives (BCVs), only as bootable devices (BEVs). 1961 // 1962 // http://www.phoenix.com/en/Customer+Services/White+Papers-Specs/pc+industry+specifications.htm 1963 //-------------------------------------------------------------------------- 1964 1965 static char drivetypes[][10]={"", "Floppy","Hard Disk","CD-Rom", "Network"}; 1966 1967 static void 1968 init_boot_vectors() 1969 { 1970 ipl_entry_t e; 1971 Bit16u count = 0; 1972 Bit16u ss = get_SS(); 1973 1974 /* Clear out the IPL table. */ 1975 memsetb(IPL_SEG, IPL_TABLE_OFFSET, 0, IPL_SIZE); 1976 1977 /* User selected device not set */ 1978 write_word(IPL_SEG, IPL_BOOTFIRST_OFFSET, 0xFFFF); 1979 1980 /* Floppy drive */ 1981 e.type = IPL_TYPE_FLOPPY; e.flags = 0; e.vector = 0; e.description = 0; e.reserved = 0; 1982 memcpyb(IPL_SEG, IPL_TABLE_OFFSET + count * sizeof (e), ss, &e, sizeof (e)); 1983 count++; 1984 1985 /* First HDD */ 1986 e.type = IPL_TYPE_HARDDISK; e.flags = 0; e.vector = 0; e.description = 0; e.reserved = 0; 1987 memcpyb(IPL_SEG, IPL_TABLE_OFFSET + count * sizeof (e), ss, &e, sizeof (e)); 1988 count++; 1989 1990 #if BX_ELTORITO_BOOT 1991 /* CDROM */ 1992 e.type = IPL_TYPE_CDROM; e.flags = 0; e.vector = 0; e.description = 0; e.reserved = 0; 1993 memcpyb(IPL_SEG, IPL_TABLE_OFFSET + count * sizeof (e), ss, &e, sizeof (e)); 1994 count++; 1995 #endif 1996 1997 /* Remember how many devices we have */ 1998 write_word(IPL_SEG, IPL_COUNT_OFFSET, count); 1999 /* Not tried booting anything yet */ 2000 write_word(IPL_SEG, IPL_SEQUENCE_OFFSET, 0xffff); 2001 } 2002 2003 static Bit8u 2004 get_boot_vector(i, e) 2005 Bit16u i; ipl_entry_t *e; 2006 { 2007 Bit16u count; 2008 Bit16u ss = get_SS(); 2009 /* Get the count of boot devices, and refuse to overrun the array */ 2010 count = read_word(IPL_SEG, IPL_COUNT_OFFSET); 2011 if (i >= count) return 0; 2012 /* OK to read this device */ 2013 memcpyb(ss, e, IPL_SEG, IPL_TABLE_OFFSET + i * sizeof (*e), sizeof (*e)); 2014 return 1; 2015 } 2016 2017 #if BX_ELTORITO_BOOT 2018 void 2019 interactive_bootkey() 2020 { 2021 ipl_entry_t e; 2022 Bit16u count; 2023 char description[33]; 2024 Bit8u scan_code; 2025 Bit8u i; 2026 Bit16u ss = get_SS(); 2027 Bit16u valid_choice = 0; 2028 2029 while (check_for_keystroke()) 2030 get_keystroke(); 2031 2032 printf("Press F12 for boot menu.\n\n"); 2033 2034 delay_ticks_and_check_for_keystroke(11, 5); /* ~3 seconds */ 2035 if (check_for_keystroke()) 2036 { 2037 scan_code = get_keystroke(); 2038 if (scan_code == 0x86) /* F12 */ 2039 { 2040 while (check_for_keystroke()) 2041 get_keystroke(); 2042 2043 printf("Select boot device:\n\n"); 2044 2045 count = read_word(IPL_SEG, IPL_COUNT_OFFSET); 2046 for (i = 0; i < count; i++) 2047 { 2048 memcpyb(ss, &e, IPL_SEG, IPL_TABLE_OFFSET + i * sizeof (e), sizeof (e)); 2049 printf("%d. ", i+1); 2050 switch(e.type) 2051 { 2052 case IPL_TYPE_FLOPPY: 2053 case IPL_TYPE_HARDDISK: 2054 case IPL_TYPE_CDROM: 2055 printf("%s\n", drivetypes[e.type]); 2056 break; 2057 case IPL_TYPE_BEV: 2058 printf("%s", drivetypes[4]); 2059 if (e.description != 0) 2060 { 2061 memcpyb(ss, &description, (Bit16u)(e.description >> 16), (Bit16u)(e.description & 0xffff), 32); 2062 description[32] = 0; 2063 printf(" [%S]", ss, description); 2064 } 2065 printf("\n"); 2066 break; 2067 } 2068 } 2069 2070 count++; 2071 while (!valid_choice) { 2072 scan_code = get_keystroke(); 2073 if (scan_code == 0x01 || scan_code == 0x58) /* ESC or F12 */ 2074 { 2075 valid_choice = 1; 2076 } 2077 else if (scan_code <= count) 2078 { 2079 valid_choice = 1; 2080 scan_code -= 1; 2081 /* Set user selected device */ 2082 write_word(IPL_SEG, IPL_BOOTFIRST_OFFSET, scan_code); 2083 } 2084 } 2085 printf("\n"); 2086 } 2087 } 2088 } 2089 #endif // BX_ELTORITO_BOOT 2090 2091 //-------------------------------------------------------------------------- 2092 // print_boot_device 2093 // displays the boot device 2094 //-------------------------------------------------------------------------- 2095 2096 void 2097 print_boot_device(e) 2098 ipl_entry_t *e; 2099 { 2100 Bit16u type; 2101 char description[33]; 2102 Bit16u ss = get_SS(); 2103 type = e->type; 2104 /* NIC appears as type 0x80 */ 2105 if (type == IPL_TYPE_BEV) type = 0x4; 2106 if (type == 0 || type > 0x4) BX_PANIC("Bad drive type\n"); 2107 printf("Booting from %s", drivetypes[type]); 2108 /* print product string if BEV */ 2109 if (type == 4 && e->description != 0) { 2110 /* first 32 bytes are significant */ 2111 memcpyb(ss, &description, (Bit16u)(e->description >> 16), (Bit16u)(e->description & 0xffff), 32); 2112 /* terminate string */ 2113 description[32] = 0; 2114 printf(" [%S]", ss, description); 2115 } 2116 printf("...\n"); 2117 } 2118 2119 //-------------------------------------------------------------------------- 2120 // print_boot_failure 2121 // displays the reason why boot failed 2122 //-------------------------------------------------------------------------- 2123 void 2124 print_boot_failure(type, reason) 2125 Bit16u type; Bit8u reason; 2126 { 2127 if (type == 0 || type > 0x3) BX_PANIC("Bad drive type\n"); 2128 2129 printf("Boot failed"); 2130 if (type < 4) { 2131 /* Report the reason too */ 2132 if (reason==0) 2133 printf(": not a bootable disk"); 2134 else 2135 printf(": could not read the boot disk"); 2136 } 2137 printf("\n\n"); 2138 } 2139 2140 //-------------------------------------------------------------------------- 2141 // print_cdromboot_failure 2142 // displays the reason why boot failed 2143 //-------------------------------------------------------------------------- 2144 void 2145 print_cdromboot_failure( code ) 2146 Bit16u code; 2147 { 2148 bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, "CDROM boot failure code : %04x\n",code); 2149 2150 return; 2151 } 2152 2153 void 2154 nmi_handler_msg() 2155 { 2156 BX_PANIC("NMI Handler called\n"); 2157 } 2158 2159 void 2160 int18_panic_msg() 2161 { 2162 BX_PANIC("INT18: BOOT FAILURE\n"); 2163 } 2164 2165 void 2166 log_bios_start() 2167 { 2168 #if BX_DEBUG_SERIAL 2169 outb(BX_DEBUG_PORT+UART_LCR, 0x03); /* setup for serial logging: 8N1 */ 2170 #endif 2171 BX_INFO("%s\n", bios_cvs_version_string); 2172 } 2173 2174 bx_bool 2175 set_enable_a20(val) 2176 bx_bool val; 2177 { 2178 Bit8u oldval; 2179 2180 // Use PS2 System Control port A to set A20 enable 2181 2182 // get current setting first 2183 oldval = inb(0x92); 2184 2185 // change A20 status 2186 if (val) 2187 outb(0x92, oldval | 0x02); 2188 else 2189 outb(0x92, oldval & 0xfd); 2190 2191 return((oldval & 0x02) != 0); 2192 } 2193 2194 void 2195 debugger_on() 2196 { 2197 outb(0xfedc, 0x01); 2198 } 2199 2200 void 2201 debugger_off() 2202 { 2203 outb(0xfedc, 0x00); 2204 } 2205 2206 int 2207 s3_resume() 2208 { 2209 Bit32u s3_wakeup_vector; 2210 Bit8u s3_resume_flag; 2211 2212 s3_resume_flag = read_byte(0x40, 0xb0); 2213 s3_wakeup_vector = read_dword(0x40, 0xb2); 2214 2215 BX_INFO("S3 resume called %x 0x%lx\n", s3_resume_flag, s3_wakeup_vector); 2216 if (s3_resume_flag != 0xFE || !s3_wakeup_vector) 2217 return 0; 2218 2219 write_byte(0x40, 0xb0, 0); 2220 2221 /* setup wakeup vector */ 2222 write_word(0x40, 0xb6, (s3_wakeup_vector & 0xF)); /* IP */ 2223 write_word(0x40, 0xb8, (s3_wakeup_vector >> 4)); /* CS */ 2224 2225 BX_INFO("S3 resume jump to %x:%x\n", (s3_wakeup_vector >> 4), 2226 (s3_wakeup_vector & 0xF)); 2227 ASM_START 2228 jmpf [0x04b6] 2229 ASM_END 2230 return 1; 2231 } 2232 2233 #if BX_USE_ATADRV 2234 2235 // --------------------------------------------------------------------------- 2236 // Start of ATA/ATAPI Driver 2237 // --------------------------------------------------------------------------- 2238 2239 // Global defines -- ATA register and register bits. 2240 // command block & control block regs 2241 #define ATA_CB_DATA 0 // data reg in/out pio_base_addr1+0 2242 #define ATA_CB_ERR 1 // error in pio_base_addr1+1 2243 #define ATA_CB_FR 1 // feature reg out pio_base_addr1+1 2244 #define ATA_CB_SC 2 // sector count in/out pio_base_addr1+2 2245 #define ATA_CB_SN 3 // sector number in/out pio_base_addr1+3 2246 #define ATA_CB_CL 4 // cylinder low in/out pio_base_addr1+4 2247 #define ATA_CB_CH 5 // cylinder high in/out pio_base_addr1+5 2248 #define ATA_CB_DH 6 // device head in/out pio_base_addr1+6 2249 #define ATA_CB_STAT 7 // primary status in pio_base_addr1+7 2250 #define ATA_CB_CMD 7 // command out pio_base_addr1+7 2251 #define ATA_CB_ASTAT 6 // alternate status in pio_base_addr2+6 2252 #define ATA_CB_DC 6 // device control out pio_base_addr2+6 2253 #define ATA_CB_DA 7 // device address in pio_base_addr2+7 2254 2255 #define ATA_CB_ER_ICRC 0x80 // ATA Ultra DMA bad CRC 2256 #define ATA_CB_ER_BBK 0x80 // ATA bad block 2257 #define ATA_CB_ER_UNC 0x40 // ATA uncorrected error 2258 #define ATA_CB_ER_MC 0x20 // ATA media change 2259 #define ATA_CB_ER_IDNF 0x10 // ATA id not found 2260 #define ATA_CB_ER_MCR 0x08 // ATA media change request 2261 #define ATA_CB_ER_ABRT 0x04 // ATA command aborted 2262 #define ATA_CB_ER_NTK0 0x02 // ATA track 0 not found 2263 #define ATA_CB_ER_NDAM 0x01 // ATA address mark not found 2264 2265 #define ATA_CB_ER_P_SNSKEY 0xf0 // ATAPI sense key (mask) 2266 #define ATA_CB_ER_P_MCR 0x08 // ATAPI Media Change Request 2267 #define ATA_CB_ER_P_ABRT 0x04 // ATAPI command abort 2268 #define ATA_CB_ER_P_EOM 0x02 // ATAPI End of Media 2269 #define ATA_CB_ER_P_ILI 0x01 // ATAPI Illegal Length Indication 2270 2271 // ATAPI Interrupt Reason bits in the Sector Count reg (CB_SC) 2272 #define ATA_CB_SC_P_TAG 0xf8 // ATAPI tag (mask) 2273 #define ATA_CB_SC_P_REL 0x04 // ATAPI release 2274 #define ATA_CB_SC_P_IO 0x02 // ATAPI I/O 2275 #define ATA_CB_SC_P_CD 0x01 // ATAPI C/D 2276 2277 // bits 7-4 of the device/head (CB_DH) reg 2278 #define ATA_CB_DH_DEV0 0xa0 // select device 0 2279 #define ATA_CB_DH_DEV1 0xb0 // select device 1 2280 #define ATA_CB_DH_LBA 0x40 // use LBA 2281 2282 // status reg (CB_STAT and CB_ASTAT) bits 2283 #define ATA_CB_STAT_BSY 0x80 // busy 2284 #define ATA_CB_STAT_RDY 0x40 // ready 2285 #define ATA_CB_STAT_DF 0x20 // device fault 2286 #define ATA_CB_STAT_WFT 0x20 // write fault (old name) 2287 #define ATA_CB_STAT_SKC 0x10 // seek complete 2288 #define ATA_CB_STAT_SERV 0x10 // service 2289 #define ATA_CB_STAT_DRQ 0x08 // data request 2290 #define ATA_CB_STAT_CORR 0x04 // corrected 2291 #define ATA_CB_STAT_IDX 0x02 // index 2292 #define ATA_CB_STAT_ERR 0x01 // error (ATA) 2293 #define ATA_CB_STAT_CHK 0x01 // check (ATAPI) 2294 2295 // device control reg (CB_DC) bits 2296 #define ATA_CB_DC_HD15 0x08 // bit should always be set to one 2297 #define ATA_CB_DC_SRST 0x04 // soft reset 2298 #define ATA_CB_DC_NIEN 0x02 // disable interrupts 2299 2300 // Most mandtory and optional ATA commands (from ATA-3), 2301 #define ATA_CMD_CFA_ERASE_SECTORS 0xC0 2302 #define ATA_CMD_CFA_REQUEST_EXT_ERR_CODE 0x03 2303 #define ATA_CMD_CFA_TRANSLATE_SECTOR 0x87 2304 #define ATA_CMD_CFA_WRITE_MULTIPLE_WO_ERASE 0xCD 2305 #define ATA_CMD_CFA_WRITE_SECTORS_WO_ERASE 0x38 2306 #define ATA_CMD_CHECK_POWER_MODE1 0xE5 2307 #define ATA_CMD_CHECK_POWER_MODE2 0x98 2308 #define ATA_CMD_DEVICE_RESET 0x08 2309 #define ATA_CMD_EXECUTE_DEVICE_DIAGNOSTIC 0x90 2310 #define ATA_CMD_FLUSH_CACHE 0xE7 2311 #define ATA_CMD_FORMAT_TRACK 0x50 2312 #define ATA_CMD_IDENTIFY_DEVICE 0xEC 2313 #define ATA_CMD_IDENTIFY_DEVICE_PACKET 0xA1 2314 #define ATA_CMD_IDENTIFY_PACKET_DEVICE 0xA1 2315 #define ATA_CMD_IDLE1 0xE3 2316 #define ATA_CMD_IDLE2 0x97 2317 #define ATA_CMD_IDLE_IMMEDIATE1 0xE1 2318 #define ATA_CMD_IDLE_IMMEDIATE2 0x95 2319 #define ATA_CMD_INITIALIZE_DRIVE_PARAMETERS 0x91 2320 #define ATA_CMD_INITIALIZE_DEVICE_PARAMETERS 0x91 2321 #define ATA_CMD_NOP 0x00 2322 #define ATA_CMD_PACKET 0xA0 2323 #define ATA_CMD_READ_BUFFER 0xE4 2324 #define ATA_CMD_READ_DMA 0xC8 2325 #define ATA_CMD_READ_DMA_QUEUED 0xC7 2326 #define ATA_CMD_READ_MULTIPLE 0xC4 2327 #define ATA_CMD_READ_SECTORS 0x20 2328 #define ATA_CMD_READ_VERIFY_SECTORS 0x40 2329 #define ATA_CMD_RECALIBRATE 0x10 2330 #define ATA_CMD_REQUEST_SENSE 0x03 2331 #define ATA_CMD_SEEK 0x70 2332 #define ATA_CMD_SET_FEATURES 0xEF 2333 #define ATA_CMD_SET_MULTIPLE_MODE 0xC6 2334 #define ATA_CMD_SLEEP1 0xE6 2335 #define ATA_CMD_SLEEP2 0x99 2336 #define ATA_CMD_STANDBY1 0xE2 2337 #define ATA_CMD_STANDBY2 0x96 2338 #define ATA_CMD_STANDBY_IMMEDIATE1 0xE0 2339 #define ATA_CMD_STANDBY_IMMEDIATE2 0x94 2340 #define ATA_CMD_WRITE_BUFFER 0xE8 2341 #define ATA_CMD_WRITE_DMA 0xCA 2342 #define ATA_CMD_WRITE_DMA_QUEUED 0xCC 2343 #define ATA_CMD_WRITE_MULTIPLE 0xC5 2344 #define ATA_CMD_WRITE_SECTORS 0x30 2345 #define ATA_CMD_WRITE_VERIFY 0x3C 2346 2347 #define ATA_IFACE_NONE 0x00 2348 #define ATA_IFACE_ISA 0x00 2349 #define ATA_IFACE_PCI 0x01 2350 2351 #define ATA_TYPE_NONE 0x00 2352 #define ATA_TYPE_UNKNOWN 0x01 2353 #define ATA_TYPE_ATA 0x02 2354 #define ATA_TYPE_ATAPI 0x03 2355 2356 #define ATA_DEVICE_NONE 0x00 2357 #define ATA_DEVICE_HD 0xFF 2358 #define ATA_DEVICE_CDROM 0x05 2359 2360 #define ATA_MODE_NONE 0x00 2361 #define ATA_MODE_PIO16 0x00 2362 #define ATA_MODE_PIO32 0x01 2363 #define ATA_MODE_ISADMA 0x02 2364 #define ATA_MODE_PCIDMA 0x03 2365 #define ATA_MODE_USEIRQ 0x10 2366 2367 #define ATA_TRANSLATION_NONE 0 2368 #define ATA_TRANSLATION_LBA 1 2369 #define ATA_TRANSLATION_LARGE 2 2370 #define ATA_TRANSLATION_RECHS 3 2371 2372 #define ATA_DATA_NO 0x00 2373 #define ATA_DATA_IN 0x01 2374 #define ATA_DATA_OUT 0x02 2375 2376 // --------------------------------------------------------------------------- 2377 // ATA/ATAPI driver : initialization 2378 // --------------------------------------------------------------------------- 2379 void ata_init( ) 2380 { 2381 Bit16u ebda_seg=read_word(0x0040,0x000E); 2382 Bit8u channel, device; 2383 2384 // Channels info init. 2385 for (channel=0; channel<BX_MAX_ATA_INTERFACES; channel++) { 2386 write_byte(ebda_seg,&EbdaData->ata.channels[channel].iface,ATA_IFACE_NONE); 2387 write_word(ebda_seg,&EbdaData->ata.channels[channel].iobase1,0x0); 2388 write_word(ebda_seg,&EbdaData->ata.channels[channel].iobase2,0x0); 2389 write_byte(ebda_seg,&EbdaData->ata.channels[channel].irq,0); 2390 } 2391 2392 // Devices info init. 2393 for (device=0; device<BX_MAX_ATA_DEVICES; device++) { 2394 write_byte(ebda_seg,&EbdaData->ata.devices[device].type,ATA_TYPE_NONE); 2395 write_byte(ebda_seg,&EbdaData->ata.devices[device].device,ATA_DEVICE_NONE); 2396 write_byte(ebda_seg,&EbdaData->ata.devices[device].removable,0); 2397 write_byte(ebda_seg,&EbdaData->ata.devices[device].lock,0); 2398 write_byte(ebda_seg,&EbdaData->ata.devices[device].mode,ATA_MODE_NONE); 2399 write_word(ebda_seg,&EbdaData->ata.devices[device].blksize,0); 2400 write_byte(ebda_seg,&EbdaData->ata.devices[device].translation,ATA_TRANSLATION_NONE); 2401 write_word(ebda_seg,&EbdaData->ata.devices[device].lchs.heads,0); 2402 write_word(ebda_seg,&EbdaData->ata.devices[device].lchs.cylinders,0); 2403 write_word(ebda_seg,&EbdaData->ata.devices[device].lchs.spt,0); 2404 write_word(ebda_seg,&EbdaData->ata.devices[device].pchs.heads,0); 2405 write_word(ebda_seg,&EbdaData->ata.devices[device].pchs.cylinders,0); 2406 write_word(ebda_seg,&EbdaData->ata.devices[device].pchs.spt,0); 2407 2408 write_dword(ebda_seg,&EbdaData->ata.devices[device].sectors_low,0L); 2409 write_dword(ebda_seg,&EbdaData->ata.devices[device].sectors_high,0L); 2410 } 2411 2412 // hdidmap and cdidmap init. 2413 for (device=0; device<BX_MAX_ATA_DEVICES; device++) { 2414 write_byte(ebda_seg,&EbdaData->ata.hdidmap[device],BX_MAX_ATA_DEVICES); 2415 write_byte(ebda_seg,&EbdaData->ata.cdidmap[device],BX_MAX_ATA_DEVICES); 2416 } 2417 2418 write_byte(ebda_seg,&EbdaData->ata.hdcount,0); 2419 write_byte(ebda_seg,&EbdaData->ata.cdcount,0); 2420 } 2421 2422 #define TIMEOUT 0 2423 #define BSY 1 2424 #define NOT_BSY 2 2425 #define NOT_BSY_DRQ 3 2426 #define NOT_BSY_NOT_DRQ 4 2427 #define NOT_BSY_RDY 5 2428 2429 #define IDE_TIMEOUT 32000u //32 seconds max for IDE ops 2430 2431 int await_ide(); 2432 static int await_ide(when_done,base,timeout) 2433 Bit8u when_done; 2434 Bit16u base; 2435 Bit16u timeout; 2436 { 2437 Bit32u time=0,last=0; 2438 Bit16u status; 2439 Bit8u result; 2440 status = inb(base + ATA_CB_STAT); // for the times you're supposed to throw one away 2441 for(;;) { 2442 status = inb(base+ATA_CB_STAT); 2443 time++; 2444 if (when_done == BSY) 2445 result = status & ATA_CB_STAT_BSY; 2446 else if (when_done == NOT_BSY) 2447 result = !(status & ATA_CB_STAT_BSY); 2448 else if (when_done == NOT_BSY_DRQ) 2449 result = !(status & ATA_CB_STAT_BSY) && (status & ATA_CB_STAT_DRQ); 2450 else if (when_done == NOT_BSY_NOT_DRQ) 2451 result = !(status & ATA_CB_STAT_BSY) && !(status & ATA_CB_STAT_DRQ); 2452 else if (when_done == NOT_BSY_RDY) 2453 result = !(status & ATA_CB_STAT_BSY) && (status & ATA_CB_STAT_RDY); 2454 else if (when_done == TIMEOUT) 2455 result = 0; 2456 2457 if (result) return 0; 2458 if (time>>16 != last) // mod 2048 each 16 ms 2459 { 2460 last = time >>16; 2461 BX_DEBUG_ATA("await_ide: (TIMEOUT,BSY,!BSY,!BSY_DRQ,!BSY_!DRQ,!BSY_RDY) %d time= %ld timeout= %d\n",when_done,time>>11, timeout); 2462 } 2463 if (status & ATA_CB_STAT_ERR) 2464 { 2465 BX_DEBUG_ATA("await_ide: ERROR (TIMEOUT,BSY,!BSY,!BSY_DRQ,!BSY_!DRQ,!BSY_RDY) %d time= %ld timeout= %d\n",when_done,time>>11, timeout); 2466 return -1; 2467 } 2468 if ((timeout == 0) || ((time>>11) > timeout)) break; 2469 } 2470 BX_INFO("IDE time out\n"); 2471 return -1; 2472 } 2473 2474 // --------------------------------------------------------------------------- 2475 // ATA/ATAPI driver : device detection 2476 // --------------------------------------------------------------------------- 2477 2478 void ata_detect( ) 2479 { 2480 Bit16u ebda_seg=read_word(0x0040,0x000E); 2481 Bit8u hdcount, cdcount, device, type; 2482 Bit8u buffer[0x0200]; 2483 2484 #if BX_MAX_ATA_INTERFACES > 0 2485 write_byte(ebda_seg,&EbdaData->ata.channels[0].iface,ATA_IFACE_ISA); 2486 write_word(ebda_seg,&EbdaData->ata.channels[0].iobase1,0x1f0); 2487 write_word(ebda_seg,&EbdaData->ata.channels[0].iobase2,0x3f0); 2488 write_byte(ebda_seg,&EbdaData->ata.channels[0].irq,14); 2489 #endif 2490 #if BX_MAX_ATA_INTERFACES > 1 2491 write_byte(ebda_seg,&EbdaData->ata.channels[1].iface,ATA_IFACE_ISA); 2492 write_word(ebda_seg,&EbdaData->ata.channels[1].iobase1,0x170); 2493 write_word(ebda_seg,&EbdaData->ata.channels[1].iobase2,0x370); 2494 write_byte(ebda_seg,&EbdaData->ata.channels[1].irq,15); 2495 #endif 2496 #if BX_MAX_ATA_INTERFACES > 2 2497 write_byte(ebda_seg,&EbdaData->ata.channels[2].iface,ATA_IFACE_ISA); 2498 write_word(ebda_seg,&EbdaData->ata.channels[2].iobase1,0x1e8); 2499 write_word(ebda_seg,&EbdaData->ata.channels[2].iobase2,0x3e0); 2500 write_byte(ebda_seg,&EbdaData->ata.channels[2].irq,12); 2501 #endif 2502 #if BX_MAX_ATA_INTERFACES > 3 2503 write_byte(ebda_seg,&EbdaData->ata.channels[3].iface,ATA_IFACE_ISA); 2504 write_word(ebda_seg,&EbdaData->ata.channels[3].iobase1,0x168); 2505 write_word(ebda_seg,&EbdaData->ata.channels[3].iobase2,0x360); 2506 write_byte(ebda_seg,&EbdaData->ata.channels[3].irq,11); 2507 #endif 2508 #if BX_MAX_ATA_INTERFACES > 4 2509 #error Please fill the ATA interface informations 2510 #endif 2511 2512 // Device detection 2513 hdcount=cdcount=0; 2514 2515 for(device=0; device<BX_MAX_ATA_DEVICES; device++) { 2516 Bit16u iobase1, iobase2; 2517 Bit8u channel, slave, shift; 2518 Bit8u sc, sn, cl, ch, st; 2519 2520 channel = device / 2; 2521 slave = device % 2; 2522 2523 iobase1 =read_word(ebda_seg,&EbdaData->ata.channels[channel].iobase1); 2524 iobase2 =read_word(ebda_seg,&EbdaData->ata.channels[channel].iobase2); 2525 2526 // Disable interrupts 2527 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN); 2528 2529 // Look for device 2530 outb(iobase1+ATA_CB_DH, slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0); 2531 outb(iobase1+ATA_CB_SC, 0x55); 2532 outb(iobase1+ATA_CB_SN, 0xaa); 2533 outb(iobase1+ATA_CB_SC, 0xaa); 2534 outb(iobase1+ATA_CB_SN, 0x55); 2535 outb(iobase1+ATA_CB_SC, 0x55); 2536 outb(iobase1+ATA_CB_SN, 0xaa); 2537 2538 // If we found something 2539 sc = inb(iobase1+ATA_CB_SC); 2540 sn = inb(iobase1+ATA_CB_SN); 2541 2542 if ( (sc == 0x55) && (sn == 0xaa) ) { 2543 write_byte(ebda_seg,&EbdaData->ata.devices[device].type,ATA_TYPE_UNKNOWN); 2544 2545 // reset the channel 2546 ata_reset(device); 2547 2548 // check for ATA or ATAPI 2549 outb(iobase1+ATA_CB_DH, slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0); 2550 sc = inb(iobase1+ATA_CB_SC); 2551 sn = inb(iobase1+ATA_CB_SN); 2552 if ((sc==0x01) && (sn==0x01)) { 2553 cl = inb(iobase1+ATA_CB_CL); 2554 ch = inb(iobase1+ATA_CB_CH); 2555 st = inb(iobase1+ATA_CB_STAT); 2556 2557 if ((cl==0x14) && (ch==0xeb)) { 2558 write_byte(ebda_seg,&EbdaData->ata.devices[device].type,ATA_TYPE_ATAPI); 2559 } else if ((cl==0x00) && (ch==0x00) && (st!=0x00)) { 2560 write_byte(ebda_seg,&EbdaData->ata.devices[device].type,ATA_TYPE_ATA); 2561 } else if ((cl==0xff) && (ch==0xff)) { 2562 write_byte(ebda_seg,&EbdaData->ata.devices[device].type,ATA_TYPE_NONE); 2563 } 2564 } 2565 } 2566 2567 type=read_byte(ebda_seg,&EbdaData->ata.devices[device].type); 2568 2569 // Now we send a IDENTIFY command to ATA device 2570 if(type == ATA_TYPE_ATA) { 2571 Bit32u sectors_low, sectors_high; 2572 Bit16u cylinders, heads, spt, blksize; 2573 Bit8u translation, removable, mode; 2574 2575 //Temporary values to do the transfer 2576 write_byte(ebda_seg,&EbdaData->ata.devices[device].device,ATA_DEVICE_HD); 2577 write_byte(ebda_seg,&EbdaData->ata.devices[device].mode, ATA_MODE_PIO16); 2578 2579 if (ata_cmd_data_in(device,ATA_CMD_IDENTIFY_DEVICE, 1, 0, 0, 0, 0L, 0L, get_SS(),buffer) !=0 ) 2580 BX_PANIC("ata-detect: Failed to detect ATA device\n"); 2581 2582 removable = (read_byte(get_SS(),buffer+0) & 0x80) ? 1 : 0; 2583 mode = read_byte(get_SS(),buffer+96) ? ATA_MODE_PIO32 : ATA_MODE_PIO16; 2584 blksize = read_word(get_SS(),buffer+10); 2585 2586 cylinders = read_word(get_SS(),buffer+(1*2)); // word 1 2587 heads = read_word(get_SS(),buffer+(3*2)); // word 3 2588 spt = read_word(get_SS(),buffer+(6*2)); // word 6 2589 2590 if (read_word(get_SS(),buffer+(83*2)) & (1 << 10)) { // word 83 - lba48 support 2591 sectors_low = read_dword(get_SS(),buffer+(100*2)); // word 100 and word 101 2592 sectors_high = read_dword(get_SS(),buffer+(102*2)); // word 102 and word 103 2593 } else { 2594 sectors_low = read_dword(get_SS(),buffer+(60*2)); // word 60 and word 61 2595 sectors_high = 0; 2596 } 2597 2598 write_byte(ebda_seg,&EbdaData->ata.devices[device].device,ATA_DEVICE_HD); 2599 write_byte(ebda_seg,&EbdaData->ata.devices[device].removable, removable); 2600 write_byte(ebda_seg,&EbdaData->ata.devices[device].mode, mode); 2601 write_word(ebda_seg,&EbdaData->ata.devices[device].blksize, blksize); 2602 write_word(ebda_seg,&EbdaData->ata.devices[device].pchs.heads, heads); 2603 write_word(ebda_seg,&EbdaData->ata.devices[device].pchs.cylinders, cylinders); 2604 write_word(ebda_seg,&EbdaData->ata.devices[device].pchs.spt, spt); 2605 write_dword(ebda_seg,&EbdaData->ata.devices[device].sectors_low, sectors_low); 2606 write_dword(ebda_seg,&EbdaData->ata.devices[device].sectors_high, sectors_high); 2607 BX_INFO("ata%d-%d: PCHS=%u/%d/%d translation=", channel, slave,cylinders, heads, spt); 2608 2609 translation = inb_cmos(0x39 + channel/2); 2610 for (shift=device%4; shift>0; shift--) translation >>= 2; 2611 translation &= 0x03; 2612 2613 write_byte(ebda_seg,&EbdaData->ata.devices[device].translation, translation); 2614 2615 switch (translation) { 2616 case ATA_TRANSLATION_NONE: 2617 BX_INFO("none"); 2618 break; 2619 case ATA_TRANSLATION_LBA: 2620 BX_INFO("lba"); 2621 break; 2622 case ATA_TRANSLATION_LARGE: 2623 BX_INFO("large"); 2624 break; 2625 case ATA_TRANSLATION_RECHS: 2626 BX_INFO("r-echs"); 2627 break; 2628 } 2629 switch (translation) { 2630 case ATA_TRANSLATION_NONE: 2631 break; 2632 case ATA_TRANSLATION_LBA: 2633 spt = 63; 2634 sectors_low /= 63; 2635 heads = sectors_low / 1024; 2636 if (heads>128) heads = 255; 2637 else if (heads>64) heads = 128; 2638 else if (heads>32) heads = 64; 2639 else if (heads>16) heads = 32; 2640 else heads=16; 2641 cylinders = sectors_low / heads; 2642 break; 2643 case ATA_TRANSLATION_RECHS: 2644 // Take care not to overflow 2645 if (heads==16) { 2646 if(cylinders>61439) cylinders=61439; 2647 heads=15; 2648 cylinders = (Bit16u)((Bit32u)(cylinders)*16/15); 2649 } 2650 // then go through the large bitshift process 2651 case ATA_TRANSLATION_LARGE: 2652 while(cylinders > 1024) { 2653 cylinders >>= 1; 2654 heads <<= 1; 2655 2656 // If we max out the head count 2657 if (heads > 127) break; 2658 } 2659 break; 2660 } 2661 // clip to 1024 cylinders in lchs 2662 if (cylinders > 1024) cylinders=1024; 2663 BX_INFO(" LCHS=%d/%d/%d\n", cylinders, heads, spt); 2664 2665 write_word(ebda_seg,&EbdaData->ata.devices[device].lchs.heads, heads); 2666 write_word(ebda_seg,&EbdaData->ata.devices[device].lchs.cylinders, cylinders); 2667 write_word(ebda_seg,&EbdaData->ata.devices[device].lchs.spt, spt); 2668 2669 // fill hdidmap 2670 write_byte(ebda_seg,&EbdaData->ata.hdidmap[hdcount], device); 2671 hdcount++; 2672 } 2673 2674 // Now we send a IDENTIFY command to ATAPI device 2675 if(type == ATA_TYPE_ATAPI) { 2676 2677 Bit8u type, removable, mode; 2678 Bit16u blksize; 2679 2680 //Temporary values to do the transfer 2681 write_byte(ebda_seg,&EbdaData->ata.devices[device].device,ATA_DEVICE_CDROM); 2682 write_byte(ebda_seg,&EbdaData->ata.devices[device].mode, ATA_MODE_PIO16); 2683 2684 if (ata_cmd_data_in(device,ATA_CMD_IDENTIFY_DEVICE_PACKET, 1, 0, 0, 0, 0L, 0L, get_SS(),buffer) != 0) 2685 BX_PANIC("ata-detect: Failed to detect ATAPI device\n"); 2686 2687 type = read_byte(get_SS(),buffer+1) & 0x1f; 2688 removable = (read_byte(get_SS(),buffer+0) & 0x80) ? 1 : 0; 2689 mode = read_byte(get_SS(),buffer+96) ? ATA_MODE_PIO32 : ATA_MODE_PIO16; 2690 blksize = 2048; 2691 2692 write_byte(ebda_seg,&EbdaData->ata.devices[device].device, type); 2693 write_byte(ebda_seg,&EbdaData->ata.devices[device].removable, removable); 2694 write_byte(ebda_seg,&EbdaData->ata.devices[device].mode, mode); 2695 write_word(ebda_seg,&EbdaData->ata.devices[device].blksize, blksize); 2696 2697 // fill cdidmap 2698 write_byte(ebda_seg,&EbdaData->ata.cdidmap[cdcount], device); 2699 cdcount++; 2700 } 2701 2702 { 2703 Bit32u sizeinmb; 2704 Bit16u ataversion; 2705 Bit8u c, i, version, model[41]; 2706 2707 switch (type) { 2708 case ATA_TYPE_ATA: 2709 sizeinmb = (read_dword(ebda_seg,&EbdaData->ata.devices[device].sectors_high) << 21) 2710 | (read_dword(ebda_seg,&EbdaData->ata.devices[device].sectors_low) >> 11); 2711 case ATA_TYPE_ATAPI: 2712 // Read ATA/ATAPI version 2713 ataversion=((Bit16u)(read_byte(get_SS(),buffer+161))<<8)|read_byte(get_SS(),buffer+160); 2714 for(version=15;version>0;version--) { 2715 if((ataversion&(1<<version))!=0) 2716 break; 2717 } 2718 2719 // Read model name 2720 for(i=0;i<20;i++){ 2721 write_byte(get_SS(),model+(i*2),read_byte(get_SS(),buffer+(i*2)+54+1)); 2722 write_byte(get_SS(),model+(i*2)+1,read_byte(get_SS(),buffer+(i*2)+54)); 2723 } 2724 2725 // Reformat 2726 write_byte(get_SS(),model+40,0x00); 2727 for(i=39;i>0;i--){ 2728 if(read_byte(get_SS(),model+i)==0x20) 2729 write_byte(get_SS(),model+i,0x00); 2730 else break; 2731 } 2732 if (i>36) { 2733 write_byte(get_SS(),model+36,0x00); 2734 for(i=35;i>32;i--){ 2735 write_byte(get_SS(),model+i,0x2E); 2736 } 2737 } 2738 break; 2739 } 2740 2741 switch (type) { 2742 case ATA_TYPE_ATA: 2743 printf("ata%d %s: ",channel,slave?" slave":"master"); 2744 i=0; while(c=read_byte(get_SS(),model+i++)) printf("%c",c); 2745 if (sizeinmb < (1UL<<16)) 2746 printf(" ATA-%d Hard-Disk (%4u MBytes)\n", version, (Bit16u)sizeinmb); 2747 else 2748 printf(" ATA-%d Hard-Disk (%4u GBytes)\n", version, (Bit16u)(sizeinmb>>10)); 2749 break; 2750 case ATA_TYPE_ATAPI: 2751 printf("ata%d %s: ",channel,slave?" slave":"master"); 2752 i=0; while(c=read_byte(get_SS(),model+i++)) printf("%c",c); 2753 if(read_byte(ebda_seg,&EbdaData->ata.devices[device].device)==ATA_DEVICE_CDROM) 2754 printf(" ATAPI-%d CD-Rom/DVD-Rom\n",version); 2755 else 2756 printf(" ATAPI-%d Device\n",version); 2757 break; 2758 case ATA_TYPE_UNKNOWN: 2759 printf("ata%d %s: Unknown device\n",channel,slave?" slave":"master"); 2760 break; 2761 } 2762 } 2763 } 2764 2765 // Store the devices counts 2766 write_byte(ebda_seg,&EbdaData->ata.hdcount, hdcount); 2767 write_byte(ebda_seg,&EbdaData->ata.cdcount, cdcount); 2768 write_byte(0x40,0x75, hdcount); 2769 2770 printf("\n"); 2771 2772 // FIXME : should use bios=cmos|auto|disable bits 2773 // FIXME : should know about translation bits 2774 // FIXME : move hard_drive_post here 2775 2776 } 2777 2778 // --------------------------------------------------------------------------- 2779 // ATA/ATAPI driver : software reset 2780 // --------------------------------------------------------------------------- 2781 // ATA-3 2782 // 8.2.1 Software reset - Device 0 2783 2784 void ata_reset(device) 2785 Bit16u device; 2786 { 2787 Bit16u ebda_seg=read_word(0x0040,0x000E); 2788 Bit16u iobase1, iobase2; 2789 Bit8u channel, slave, sn, sc; 2790 Bit8u type; 2791 Bit16u max; 2792 2793 channel = device / 2; 2794 slave = device % 2; 2795 2796 iobase1 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase1); 2797 iobase2 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase2); 2798 2799 // Reset 2800 2801 // 8.2.1 (a) -- set SRST in DC 2802 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN | ATA_CB_DC_SRST); 2803 2804 // 8.2.1 (b) -- wait for BSY 2805 await_ide(BSY, iobase1, 20); 2806 2807 // 8.2.1 (f) -- clear SRST 2808 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN); 2809 2810 type=read_byte(ebda_seg,&EbdaData->ata.devices[device].type); 2811 if (type != ATA_TYPE_NONE) { 2812 2813 // 8.2.1 (g) -- check for sc==sn==0x01 2814 // select device 2815 outb(iobase1+ATA_CB_DH, slave?ATA_CB_DH_DEV1:ATA_CB_DH_DEV0); 2816 sc = inb(iobase1+ATA_CB_SC); 2817 sn = inb(iobase1+ATA_CB_SN); 2818 2819 if ( (sc==0x01) && (sn==0x01) ) { 2820 if (type == ATA_TYPE_ATA) //ATA 2821 await_ide(NOT_BSY_RDY, iobase1, IDE_TIMEOUT); 2822 else //ATAPI 2823 await_ide(NOT_BSY, iobase1, IDE_TIMEOUT); 2824 } 2825 2826 // 8.2.1 (h) -- wait for not BSY 2827 await_ide(NOT_BSY, iobase1, IDE_TIMEOUT); 2828 } 2829 2830 // Enable interrupts 2831 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15); 2832 } 2833 2834 // --------------------------------------------------------------------------- 2835 // ATA/ATAPI driver : execute a non data command 2836 // --------------------------------------------------------------------------- 2837 2838 Bit16u ata_cmd_non_data() 2839 {return 0;} 2840 2841 // --------------------------------------------------------------------------- 2842 // ATA/ATAPI driver : execute a data-in command 2843 // --------------------------------------------------------------------------- 2844 // returns 2845 // 0 : no error 2846 // 1 : BUSY bit set 2847 // 2 : read error 2848 // 3 : expected DRQ=1 2849 // 4 : no sectors left to read/verify 2850 // 5 : more sectors to read/verify 2851 // 6 : no sectors left to write 2852 // 7 : more sectors to write 2853 Bit16u ata_cmd_data_in(device, command, count, cylinder, head, sector, lba_low, lba_high, segment, offset) 2854 Bit16u device, command, count, cylinder, head, sector, segment, offset; 2855 Bit32u lba_low, lba_high; 2856 { 2857 Bit16u ebda_seg=read_word(0x0040,0x000E); 2858 Bit16u iobase1, iobase2, blksize; 2859 Bit8u channel, slave; 2860 Bit8u status, current, mode; 2861 2862 channel = device / 2; 2863 slave = device % 2; 2864 2865 iobase1 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase1); 2866 iobase2 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase2); 2867 mode = read_byte(ebda_seg, &EbdaData->ata.devices[device].mode); 2868 blksize = 0x200; // was = read_word(ebda_seg, &EbdaData->ata.devices[device].blksize); 2869 if (mode == ATA_MODE_PIO32) blksize>>=2; 2870 else blksize>>=1; 2871 2872 // Reset count of transferred data 2873 write_word(ebda_seg, &EbdaData->ata.trsfsectors,0); 2874 write_dword(ebda_seg, &EbdaData->ata.trsfbytes,0L); 2875 current = 0; 2876 2877 status = inb(iobase1 + ATA_CB_STAT); 2878 if (status & ATA_CB_STAT_BSY) return 1; 2879 2880 outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN); 2881 2882 // sector will be 0 only on lba access. Convert to lba-chs 2883 if (sector == 0) { 2884 if ((count >= 1 << 8) || lba_high || (lba_low + count >= 1UL << 28)) { 2885 outb(iobase1 + ATA_CB_FR, 0x00); 2886 outb(iobase1 + ATA_CB_SC, (count >> 8) & 0xff); 2887 outb(iobase1 + ATA_CB_SN, lba_low >> 24); 2888 outb(iobase1 + ATA_CB_CL, lba_high & 0xff); 2889 outb(iobase1 + ATA_CB_CH, lba_high >> 8); 2890 command |= 0x04; 2891 count &= (1UL << 8) - 1; 2892 lba_low &= (1UL << 24) - 1; 2893 } 2894 sector = (Bit16u) (lba_low & 0x000000ffL); 2895 cylinder = (Bit16u) ((lba_low>>8) & 0x0000ffffL); 2896 head = ((Bit16u) ((lba_low>>24) & 0x0000000fL)) | ATA_CB_DH_LBA; 2897 } 2898 2899 outb(iobase1 + ATA_CB_FR, 0x00); 2900 outb(iobase1 + ATA_CB_SC, count); 2901 outb(iobase1 + ATA_CB_SN, sector); 2902 outb(iobase1 + ATA_CB_CL, cylinder & 0x00ff); 2903 outb(iobase1 + ATA_CB_CH, cylinder >> 8); 2904 outb(iobase1 + ATA_CB_DH, (slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) | (Bit8u) head ); 2905 outb(iobase1 + ATA_CB_CMD, command); 2906 2907 await_ide(NOT_BSY_DRQ, iobase1, IDE_TIMEOUT); 2908 status = inb(iobase1 + ATA_CB_STAT); 2909 2910 if (status & ATA_CB_STAT_ERR) { 2911 BX_DEBUG_ATA("ata_cmd_data_in : read error\n"); 2912 return 2; 2913 } else if ( !(status & ATA_CB_STAT_DRQ) ) { 2914 BX_DEBUG_ATA("ata_cmd_data_in : DRQ not set (status %02x)\n", (unsigned) status); 2915 return 3; 2916 } 2917 2918 // FIXME : move seg/off translation here 2919 2920 ASM_START 2921 sti ;; enable higher priority interrupts 2922 ASM_END 2923 2924 while (1) { 2925 2926 ASM_START 2927 push bp 2928 mov bp, sp 2929 mov di, _ata_cmd_data_in.offset + 2[bp] 2930 mov ax, _ata_cmd_data_in.segment + 2[bp] 2931 mov cx, _ata_cmd_data_in.blksize + 2[bp] 2932 2933 ;; adjust if there will be an overrun. 2K max sector size 2934 cmp di, #0xf800 ;; 2935 jbe ata_in_no_adjust 2936 2937 ata_in_adjust: 2938 sub di, #0x0800 ;; sub 2 kbytes from offset 2939 add ax, #0x0080 ;; add 2 Kbytes to segment 2940 2941 ata_in_no_adjust: 2942 mov es, ax ;; segment in es 2943 2944 mov dx, _ata_cmd_data_in.iobase1 + 2[bp] ;; ATA data read port 2945 2946 mov ah, _ata_cmd_data_in.mode + 2[bp] 2947 cmp ah, #ATA_MODE_PIO32 2948 je ata_in_32 2949 2950 ata_in_16: 2951 rep 2952 insw ;; CX words transfered from port(DX) to ES:[DI] 2953 jmp ata_in_done 2954 2955 ata_in_32: 2956 rep 2957 insd ;; CX dwords transfered from port(DX) to ES:[DI] 2958 2959 ata_in_done: 2960 mov _ata_cmd_data_in.offset + 2[bp], di 2961 mov _ata_cmd_data_in.segment + 2[bp], es 2962 pop bp 2963 ASM_END 2964 2965 current++; 2966 write_word(ebda_seg, &EbdaData->ata.trsfsectors,current); 2967 count--; 2968 await_ide(NOT_BSY, iobase1, IDE_TIMEOUT); 2969 status = inb(iobase1 + ATA_CB_STAT); 2970 if (count == 0) { 2971 if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) ) 2972 != ATA_CB_STAT_RDY ) { 2973 BX_DEBUG_ATA("ata_cmd_data_in : no sectors left (status %02x)\n", (unsigned) status); 2974 return 4; 2975 } 2976 break; 2977 } 2978 else { 2979 if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) ) 2980 != (ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ) ) { 2981 BX_DEBUG_ATA("ata_cmd_data_in : more sectors left (status %02x)\n", (unsigned) status); 2982 return 5; 2983 } 2984 continue; 2985 } 2986 } 2987 // Enable interrupts 2988 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15); 2989 return 0; 2990 } 2991 2992 // --------------------------------------------------------------------------- 2993 // ATA/ATAPI driver : execute a data-out command 2994 // --------------------------------------------------------------------------- 2995 // returns 2996 // 0 : no error 2997 // 1 : BUSY bit set 2998 // 2 : read error 2999 // 3 : expected DRQ=1 3000 // 4 : no sectors left to read/verify 3001 // 5 : more sectors to read/verify 3002 // 6 : no sectors left to write 3003 // 7 : more sectors to write 3004 Bit16u ata_cmd_data_out(device, command, count, cylinder, head, sector, lba_low, lba_high, segment, offset) 3005 Bit16u device, command, count, cylinder, head, sector, segment, offset; 3006 Bit32u lba_low, lba_high; 3007 { 3008 Bit16u ebda_seg=read_word(0x0040,0x000E); 3009 Bit16u iobase1, iobase2, blksize; 3010 Bit8u channel, slave; 3011 Bit8u status, current, mode; 3012 3013 channel = device / 2; 3014 slave = device % 2; 3015 3016 iobase1 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase1); 3017 iobase2 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase2); 3018 mode = read_byte(ebda_seg, &EbdaData->ata.devices[device].mode); 3019 blksize = 0x200; // was = read_word(ebda_seg, &EbdaData->ata.devices[device].blksize); 3020 if (mode == ATA_MODE_PIO32) blksize>>=2; 3021 else blksize>>=1; 3022 3023 // Reset count of transferred data 3024 write_word(ebda_seg, &EbdaData->ata.trsfsectors,0); 3025 write_dword(ebda_seg, &EbdaData->ata.trsfbytes,0L); 3026 current = 0; 3027 3028 status = inb(iobase1 + ATA_CB_STAT); 3029 if (status & ATA_CB_STAT_BSY) return 1; 3030 3031 outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN); 3032 3033 // sector will be 0 only on lba access. Convert to lba-chs 3034 if (sector == 0) { 3035 if ((count >= 1 << 8) || lba_high || (lba_low + count >= 1UL << 28)) { 3036 outb(iobase1 + ATA_CB_FR, 0x00); 3037 outb(iobase1 + ATA_CB_SC, (count >> 8) & 0xff); 3038 outb(iobase1 + ATA_CB_SN, lba_low >> 24); 3039 outb(iobase1 + ATA_CB_CL, lba_high & 0xff); 3040 outb(iobase1 + ATA_CB_CH, lba_high >> 8); 3041 command |= 0x04; 3042 count &= (1UL << 8) - 1; 3043 lba_low &= (1UL << 24) - 1; 3044 } 3045 sector = (Bit16u) (lba_low & 0x000000ffL); 3046 cylinder = (Bit16u) ((lba_low>>8) & 0x0000ffffL); 3047 head = ((Bit16u) ((lba_low>>24) & 0x0000000fL)) | ATA_CB_DH_LBA; 3048 } 3049 3050 outb(iobase1 + ATA_CB_FR, 0x00); 3051 outb(iobase1 + ATA_CB_SC, count); 3052 outb(iobase1 + ATA_CB_SN, sector); 3053 outb(iobase1 + ATA_CB_CL, cylinder & 0x00ff); 3054 outb(iobase1 + ATA_CB_CH, cylinder >> 8); 3055 outb(iobase1 + ATA_CB_DH, (slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) | (Bit8u) head ); 3056 outb(iobase1 + ATA_CB_CMD, command); 3057 3058 await_ide(NOT_BSY_DRQ, iobase1, IDE_TIMEOUT); 3059 status = inb(iobase1 + ATA_CB_STAT); 3060 3061 if (status & ATA_CB_STAT_ERR) { 3062 BX_DEBUG_ATA("ata_cmd_data_out : read error\n"); 3063 return 2; 3064 } else if ( !(status & ATA_CB_STAT_DRQ) ) { 3065 BX_DEBUG_ATA("ata_cmd_data_out : DRQ not set (status %02x)\n", (unsigned) status); 3066 return 3; 3067 } 3068 3069 // FIXME : move seg/off translation here 3070 3071 ASM_START 3072 sti ;; enable higher priority interrupts 3073 ASM_END 3074 3075 while (1) { 3076 3077 ASM_START 3078 push bp 3079 mov bp, sp 3080 mov si, _ata_cmd_data_out.offset + 2[bp] 3081 mov ax, _ata_cmd_data_out.segment + 2[bp] 3082 mov cx, _ata_cmd_data_out.blksize + 2[bp] 3083 3084 ;; adjust if there will be an overrun. 2K max sector size 3085 cmp si, #0xf800 ;; 3086 jbe ata_out_no_adjust 3087 3088 ata_out_adjust: 3089 sub si, #0x0800 ;; sub 2 kbytes from offset 3090 add ax, #0x0080 ;; add 2 Kbytes to segment 3091 3092 ata_out_no_adjust: 3093 mov es, ax ;; segment in es 3094 3095 mov dx, _ata_cmd_data_out.iobase1 + 2[bp] ;; ATA data write port 3096 3097 mov ah, _ata_cmd_data_out.mode + 2[bp] 3098 cmp ah, #ATA_MODE_PIO32 3099 je ata_out_32 3100 3101 ata_out_16: 3102 seg ES 3103 rep 3104 outsw ;; CX words transfered from port(DX) to ES:[SI] 3105 jmp ata_out_done 3106 3107 ata_out_32: 3108 seg ES 3109 rep 3110 outsd ;; CX dwords transfered from port(DX) to ES:[SI] 3111 3112 ata_out_done: 3113 mov _ata_cmd_data_out.offset + 2[bp], si 3114 mov _ata_cmd_data_out.segment + 2[bp], es 3115 pop bp 3116 ASM_END 3117 3118 current++; 3119 write_word(ebda_seg, &EbdaData->ata.trsfsectors,current); 3120 count--; 3121 status = inb(iobase1 + ATA_CB_STAT); 3122 if (count == 0) { 3123 if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DF | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) ) 3124 != ATA_CB_STAT_RDY ) { 3125 BX_DEBUG_ATA("ata_cmd_data_out : no sectors left (status %02x)\n", (unsigned) status); 3126 return 6; 3127 } 3128 break; 3129 } 3130 else { 3131 if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) ) 3132 != (ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ) ) { 3133 BX_DEBUG_ATA("ata_cmd_data_out : more sectors left (status %02x)\n", (unsigned) status); 3134 return 7; 3135 } 3136 continue; 3137 } 3138 } 3139 // Enable interrupts 3140 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15); 3141 return 0; 3142 } 3143 3144 // --------------------------------------------------------------------------- 3145 // ATA/ATAPI driver : execute a packet command 3146 // --------------------------------------------------------------------------- 3147 // returns 3148 // 0 : no error 3149 // 1 : error in parameters 3150 // 2 : BUSY bit set 3151 // 3 : error 3152 // 4 : not ready 3153 Bit16u ata_cmd_packet(device, cmdlen, cmdseg, cmdoff, header, length, inout, bufseg, bufoff) 3154 Bit8u cmdlen,inout; 3155 Bit16u device,cmdseg, cmdoff, bufseg, bufoff; 3156 Bit16u header; 3157 Bit32u length; 3158 { 3159 Bit16u ebda_seg=read_word(0x0040,0x000E); 3160 Bit16u iobase1, iobase2; 3161 Bit16u lcount, lbefore, lafter, count; 3162 Bit8u channel, slave; 3163 Bit8u status, mode, lmode; 3164 Bit32u total, transfer; 3165 3166 channel = device / 2; 3167 slave = device % 2; 3168 3169 // Data out is not supported yet 3170 if (inout == ATA_DATA_OUT) { 3171 BX_INFO("ata_cmd_packet: DATA_OUT not supported yet\n"); 3172 return 1; 3173 } 3174 3175 // The header length must be even 3176 if (header & 1) { 3177 BX_DEBUG_ATA("ata_cmd_packet : header must be even (%04x)\n",header); 3178 return 1; 3179 } 3180 3181 iobase1 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase1); 3182 iobase2 = read_word(ebda_seg, &EbdaData->ata.channels[channel].iobase2); 3183 mode = read_byte(ebda_seg, &EbdaData->ata.devices[device].mode); 3184 transfer= 0L; 3185 3186 if (cmdlen < 12) cmdlen=12; 3187 if (cmdlen > 12) cmdlen=16; 3188 cmdlen>>=1; 3189 3190 // Reset count of transferred data 3191 write_word(ebda_seg, &EbdaData->ata.trsfsectors,0); 3192 write_dword(ebda_seg, &EbdaData->ata.trsfbytes,0L); 3193 3194 status = inb(iobase1 + ATA_CB_STAT); 3195 if (status & ATA_CB_STAT_BSY) return 2; 3196 3197 outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN); 3198 outb(iobase1 + ATA_CB_FR, 0x00); 3199 outb(iobase1 + ATA_CB_SC, 0x00); 3200 outb(iobase1 + ATA_CB_SN, 0x00); 3201 outb(iobase1 + ATA_CB_CL, 0xfff0 & 0x00ff); 3202 outb(iobase1 + ATA_CB_CH, 0xfff0 >> 8); 3203 outb(iobase1 + ATA_CB_DH, slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0); 3204 outb(iobase1 + ATA_CB_CMD, ATA_CMD_PACKET); 3205 3206 // Device should ok to receive command 3207 await_ide(NOT_BSY_DRQ, iobase1, IDE_TIMEOUT); 3208 status = inb(iobase1 + ATA_CB_STAT); 3209 3210 if (status & ATA_CB_STAT_ERR) { 3211 BX_DEBUG_ATA("ata_cmd_packet : error, status is %02x\n",status); 3212 return 3; 3213 } else if ( !(status & ATA_CB_STAT_DRQ) ) { 3214 BX_DEBUG_ATA("ata_cmd_packet : DRQ not set (status %02x)\n", (unsigned) status); 3215 return 4; 3216 } 3217 3218 // Normalize address 3219 cmdseg += (cmdoff / 16); 3220 cmdoff %= 16; 3221 3222 // Send command to device 3223 ASM_START 3224 sti ;; enable higher priority interrupts 3225 3226 push bp 3227 mov bp, sp 3228 3229 mov si, _ata_cmd_packet.cmdoff + 2[bp] 3230 mov ax, _ata_cmd_packet.cmdseg + 2[bp] 3231 mov cx, _ata_cmd_packet.cmdlen + 2[bp] 3232 mov es, ax ;; segment in es 3233 3234 mov dx, _ata_cmd_packet.iobase1 + 2[bp] ;; ATA data write port 3235 3236 seg ES 3237 rep 3238 outsw ;; CX words transfered from port(DX) to ES:[SI] 3239 3240 pop bp 3241 ASM_END 3242 3243 if (inout == ATA_DATA_NO) { 3244 await_ide(NOT_BSY, iobase1, IDE_TIMEOUT); 3245 status = inb(iobase1 + ATA_CB_STAT); 3246 } 3247 else { 3248 Bit16u loops = 0; 3249 Bit8u sc; 3250 while (1) { 3251 3252 if (loops == 0) {//first time through 3253 status = inb(iobase2 + ATA_CB_ASTAT); 3254 await_ide(NOT_BSY_DRQ, iobase1, IDE_TIMEOUT); 3255 } 3256 else 3257 await_ide(NOT_BSY, iobase1, IDE_TIMEOUT); 3258 loops++; 3259 3260 status = inb(iobase1 + ATA_CB_STAT); 3261 sc = inb(iobase1 + ATA_CB_SC); 3262 3263 // Check if command completed 3264 if(((inb(iobase1 + ATA_CB_SC)&0x7)==0x3) && 3265 ((status & (ATA_CB_STAT_RDY | ATA_CB_STAT_ERR)) == ATA_CB_STAT_RDY)) break; 3266 3267 if (status & ATA_CB_STAT_ERR) { 3268 BX_DEBUG_ATA("ata_cmd_packet : error (status %02x)\n",status); 3269 return 3; 3270 } 3271 3272 // Normalize address 3273 bufseg += (bufoff / 16); 3274 bufoff %= 16; 3275 3276 // Get the byte count 3277 lcount = ((Bit16u)(inb(iobase1 + ATA_CB_CH))<<8)+inb(iobase1 + ATA_CB_CL); 3278 3279 // adjust to read what we want 3280 if(header>lcount) { 3281 lbefore=lcount; 3282 header-=lcount; 3283 lcount=0; 3284 } 3285 else { 3286 lbefore=header; 3287 header=0; 3288 lcount-=lbefore; 3289 } 3290 3291 if(lcount>length) { 3292 lafter=lcount-length; 3293 lcount=length; 3294 length=0; 3295 } 3296 else { 3297 lafter=0; 3298 length-=lcount; 3299 } 3300 3301 // Save byte count 3302 count = lcount; 3303 3304 BX_DEBUG_ATA("Trying to read %04x bytes (%04x %04x %04x) ",lbefore+lcount+lafter,lbefore,lcount,lafter); 3305 BX_DEBUG_ATA("to 0x%04x:0x%04x\n",bufseg,bufoff); 3306 3307 // If counts not dividable by 4, use 16bits mode 3308 lmode = mode; 3309 if (lbefore & 0x03) lmode=ATA_MODE_PIO16; 3310 if (lcount & 0x03) lmode=ATA_MODE_PIO16; 3311 if (lafter & 0x03) lmode=ATA_MODE_PIO16; 3312 3313 // adds an extra byte if count are odd. before is always even 3314 if (lcount & 0x01) { 3315 lcount+=1; 3316 if ((lafter > 0) && (lafter & 0x01)) { 3317 lafter-=1; 3318 } 3319 } 3320 3321 if (lmode == ATA_MODE_PIO32) { 3322 lcount>>=2; lbefore>>=2; lafter>>=2; 3323 } 3324 else { 3325 lcount>>=1; lbefore>>=1; lafter>>=1; 3326 } 3327 3328 ; // FIXME bcc bug 3329 3330 ASM_START 3331 push bp 3332 mov bp, sp 3333 3334 mov dx, _ata_cmd_packet.iobase1 + 2[bp] ;; ATA data read port 3335 3336 mov cx, _ata_cmd_packet.lbefore + 2[bp] 3337 jcxz ata_packet_no_before 3338 3339 mov ah, _ata_cmd_packet.lmode + 2[bp] 3340 cmp ah, #ATA_MODE_PIO32 3341 je ata_packet_in_before_32 3342 3343 ata_packet_in_before_16: 3344 in ax, dx 3345 loop ata_packet_in_before_16 3346 jmp ata_packet_no_before 3347 3348 ata_packet_in_before_32: 3349 push eax 3350 ata_packet_in_before_32_loop: 3351 in eax, dx 3352 loop ata_packet_in_before_32_loop 3353 pop eax 3354 3355 ata_packet_no_before: 3356 mov cx, _ata_cmd_packet.lcount + 2[bp] 3357 jcxz ata_packet_after 3358 3359 mov di, _ata_cmd_packet.bufoff + 2[bp] 3360 mov ax, _ata_cmd_packet.bufseg + 2[bp] 3361 mov es, ax 3362 3363 mov ah, _ata_cmd_packet.lmode + 2[bp] 3364 cmp ah, #ATA_MODE_PIO32 3365 je ata_packet_in_32 3366 3367 ata_packet_in_16: 3368 rep 3369 insw ;; CX words transfered tp port(DX) to ES:[DI] 3370 jmp ata_packet_after 3371 3372 ata_packet_in_32: 3373 rep 3374 insd ;; CX dwords transfered to port(DX) to ES:[DI] 3375 3376 ata_packet_after: 3377 mov cx, _ata_cmd_packet.lafter + 2[bp] 3378 jcxz ata_packet_done 3379 3380 mov ah, _ata_cmd_packet.lmode + 2[bp] 3381 cmp ah, #ATA_MODE_PIO32 3382 je ata_packet_in_after_32 3383 3384 ata_packet_in_after_16: 3385 in ax, dx 3386 loop ata_packet_in_after_16 3387 jmp ata_packet_done 3388 3389 ata_packet_in_after_32: 3390 push eax 3391 ata_packet_in_after_32_loop: 3392 in eax, dx 3393 loop ata_packet_in_after_32_loop 3394 pop eax 3395 3396 ata_packet_done: 3397 pop bp 3398 ASM_END 3399 3400 // Compute new buffer address 3401 bufoff += count; 3402 3403 // Save transferred bytes count 3404 transfer += count; 3405 write_dword(ebda_seg, &EbdaData->ata.trsfbytes,transfer); 3406 } 3407 } 3408 3409 // Final check, device must be ready 3410 if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DF | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) ) 3411 != ATA_CB_STAT_RDY ) { 3412 BX_DEBUG_ATA("ata_cmd_packet : not ready (status %02x)\n", (unsigned) status); 3413 return 4; 3414 } 3415 3416 // Enable interrupts 3417 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15); 3418 return 0; 3419 } 3420 3421 // --------------------------------------------------------------------------- 3422 // End of ATA/ATAPI Driver 3423 // --------------------------------------------------------------------------- 3424 3425 // --------------------------------------------------------------------------- 3426 // Start of ATA/ATAPI generic functions 3427 // --------------------------------------------------------------------------- 3428 3429 Bit16u 3430 atapi_get_sense(device, seg, asc, ascq) 3431 Bit16u device; 3432 { 3433 Bit8u atacmd[12]; 3434 Bit8u buffer[18]; 3435 Bit8u i; 3436 3437 memsetb(get_SS(),atacmd,0,12); 3438 3439 // Request SENSE 3440 atacmd[0]=ATA_CMD_REQUEST_SENSE; 3441 atacmd[4]=sizeof(buffer); 3442 if (ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 18L, ATA_DATA_IN, get_SS(), buffer) != 0) 3443 return 0x0002; 3444 3445 write_byte(seg,asc,buffer[12]); 3446 write_byte(seg,ascq,buffer[13]); 3447 3448 return 0; 3449 } 3450 3451 Bit16u 3452 atapi_is_ready(device) 3453 Bit16u device; 3454 { 3455 Bit8u packet[12]; 3456 Bit8u buf[8]; 3457 Bit32u block_len; 3458 Bit32u sectors; 3459 Bit32u timeout; //measured in ms 3460 Bit32u time; 3461 Bit8u asc, ascq; 3462 Bit8u in_progress; 3463 Bit16u ebda_seg = read_word(0x0040,0x000E); 3464 if (read_byte(ebda_seg,&EbdaData->ata.devices[device].type) != ATA_TYPE_ATAPI) { 3465 printf("not implemented for non-ATAPI device\n"); 3466 return -1; 3467 } 3468 3469 BX_DEBUG_ATA("ata_detect_medium: begin\n"); 3470 memsetb(get_SS(),packet, 0, sizeof packet); 3471 packet[0] = 0x25; /* READ CAPACITY */ 3472 3473 /* Retry READ CAPACITY 50 times unless MEDIUM NOT PRESENT 3474 * is reported by the device. If the device reports "IN PROGRESS", 3475 * 30 seconds is added. */ 3476 timeout = 5000; 3477 time = 0; 3478 in_progress = 0; 3479 while (time < timeout) { 3480 if (ata_cmd_packet(device, sizeof(packet), get_SS(), packet, 0, 8L, ATA_DATA_IN, get_SS(), buf) == 0) 3481 goto ok; 3482 3483 if (atapi_get_sense(device, get_SS(), &asc, &ascq) == 0) { 3484 if (asc == 0x3a) { /* MEDIUM NOT PRESENT */ 3485 BX_DEBUG_ATA("Device reports MEDIUM NOT PRESENT\n"); 3486 return -1; 3487 } 3488 3489 if (asc == 0x04 && ascq == 0x01 && !in_progress) { 3490 /* IN PROGRESS OF BECOMING READY */ 3491 printf("Waiting for device to detect medium... "); 3492 /* Allow 30 seconds more */ 3493 timeout = 30000; 3494 in_progress = 1; 3495 } 3496 } 3497 time += 100; 3498 } 3499 BX_DEBUG_ATA("read capacity failed\n"); 3500 return -1; 3501 ok: 3502 3503 block_len = (Bit32u) buf[4] << 24 3504 | (Bit32u) buf[5] << 16 3505 | (Bit32u) buf[6] << 8 3506 | (Bit32u) buf[7] << 0; 3507 BX_DEBUG_ATA("block_len=%u\n", block_len); 3508 3509 if (block_len!= 2048 && block_len!= 512) 3510 { 3511 printf("Unsupported sector size %u\n", block_len); 3512 return -1; 3513 } 3514 write_dword(ebda_seg,&EbdaData->ata.devices[device].blksize, block_len); 3515 3516 sectors = (Bit32u) buf[0] << 24 3517 | (Bit32u) buf[1] << 16 3518 | (Bit32u) buf[2] << 8 3519 | (Bit32u) buf[3] << 0; 3520 3521 BX_DEBUG_ATA("sectors=%u\n", sectors); 3522 if (block_len == 2048) 3523 sectors <<= 2; /* # of sectors in 512-byte "soft" sector */ 3524 if (sectors != read_dword(ebda_seg,&EbdaData->ata.devices[device].sectors_low)) 3525 printf("%dMB medium detected\n", sectors>>(20-9)); 3526 write_dword(ebda_seg,&EbdaData->ata.devices[device].sectors_low, sectors); 3527 return 0; 3528 } 3529 3530 Bit16u 3531 atapi_is_cdrom(device) 3532 Bit8u device; 3533 { 3534 Bit16u ebda_seg=read_word(0x0040,0x000E); 3535 3536 if (device >= BX_MAX_ATA_DEVICES) 3537 return 0; 3538 3539 if (read_byte(ebda_seg,&EbdaData->ata.devices[device].type) != ATA_TYPE_ATAPI) 3540 return 0; 3541 3542 if (read_byte(ebda_seg,&EbdaData->ata.devices[device].device) != ATA_DEVICE_CDROM) 3543 return 0; 3544 3545 return 1; 3546 } 3547 3548 // --------------------------------------------------------------------------- 3549 // End of ATA/ATAPI generic functions 3550 // --------------------------------------------------------------------------- 3551 3552 #endif // BX_USE_ATADRV 3553 3554 #if BX_ELTORITO_BOOT 3555 3556 // --------------------------------------------------------------------------- 3557 // Start of El-Torito boot functions 3558 // --------------------------------------------------------------------------- 3559 3560 void 3561 cdemu_init() 3562 { 3563 Bit16u ebda_seg=read_word(0x0040,0x000E); 3564 3565 // the only important data is this one for now 3566 write_byte(ebda_seg,&EbdaData->cdemu.active,0x00); 3567 } 3568 3569 Bit8u 3570 cdemu_isactive() 3571 { 3572 Bit16u ebda_seg=read_word(0x0040,0x000E); 3573 3574 return(read_byte(ebda_seg,&EbdaData->cdemu.active)); 3575 } 3576 3577 Bit8u 3578 cdemu_emulated_drive() 3579 { 3580 Bit16u ebda_seg=read_word(0x0040,0x000E); 3581 3582 return(read_byte(ebda_seg,&EbdaData->cdemu.emulated_drive)); 3583 } 3584 3585 static char isotag[6]="CD001"; 3586 static char eltorito[24]="EL TORITO SPECIFICATION"; 3587 // 3588 // Returns ah: emulated drive, al: error code 3589 // 3590 Bit16u 3591 cdrom_boot() 3592 { 3593 Bit16u ebda_seg=read_word(0x0040,0x000E); 3594 Bit8u atacmd[12], buffer[2048]; 3595 Bit32u lba; 3596 Bit16u boot_segment, nbsectors, i, error; 3597 Bit8u device; 3598 3599 // Find out the first cdrom 3600 for (device=0; device<BX_MAX_ATA_DEVICES;device++) { 3601 if (atapi_is_cdrom(device)) break; 3602 } 3603 3604 // if not found 3605 if(device >= BX_MAX_ATA_DEVICES) return 2; 3606 3607 if(error = atapi_is_ready(device) != 0) 3608 BX_INFO("ata_is_ready returned %d\n",error); 3609 3610 // Read the Boot Record Volume Descriptor 3611 memsetb(get_SS(),atacmd,0,12); 3612 atacmd[0]=0x28; // READ command 3613 atacmd[7]=(0x01 & 0xff00) >> 8; // Sectors 3614 atacmd[8]=(0x01 & 0x00ff); // Sectors 3615 atacmd[2]=(0x11 & 0xff000000) >> 24; // LBA 3616 atacmd[3]=(0x11 & 0x00ff0000) >> 16; 3617 atacmd[4]=(0x11 & 0x0000ff00) >> 8; 3618 atacmd[5]=(0x11 & 0x000000ff); 3619 if((error = ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 2048L, ATA_DATA_IN, get_SS(), buffer)) != 0) 3620 return 3; 3621 3622 // Validity checks 3623 if(buffer[0]!=0)return 4; 3624 for(i=0;i<5;i++){ 3625 if(buffer[1+i]!=read_byte(0xf000,&isotag[i]))return 5; 3626 } 3627 for(i=0;i<23;i++) 3628 if(buffer[7+i]!=read_byte(0xf000,&eltorito[i]))return 6; 3629 3630 // ok, now we calculate the Boot catalog address 3631 lba=buffer[0x4A]*0x1000000+buffer[0x49]*0x10000+buffer[0x48]*0x100+buffer[0x47]; 3632 3633 // And we read the Boot Catalog 3634 memsetb(get_SS(),atacmd,0,12); 3635 atacmd[0]=0x28; // READ command 3636 atacmd[7]=(0x01 & 0xff00) >> 8; // Sectors 3637 atacmd[8]=(0x01 & 0x00ff); // Sectors 3638 atacmd[2]=(lba & 0xff000000) >> 24; // LBA 3639 atacmd[3]=(lba & 0x00ff0000) >> 16; 3640 atacmd[4]=(lba & 0x0000ff00) >> 8; 3641 atacmd[5]=(lba & 0x000000ff); 3642 if((error = ata_cmd_packet(device, 12, get_SS(), atacmd, 0, 2048L, ATA_DATA_IN, get_SS(), buffer)) != 0) 3643 return 7; 3644 3645 // Validation entry 3646 if(buffer[0x00]!=0x01)return 8; // Header 3647 if(buffer[0x01]!=0x00)return 9; // Platform 3648 if(buffer[0x1E]!=0x55)return 10; // key 1 3649 if(buffer[0x1F]!=0xAA)return 10; // key 2 3650 3651 // Initial/Default Entry 3652 if(buffer[0x20]!=0x88)return 11; // Bootable 3653 3654 write_byte(ebda_seg,&EbdaData->cdemu.media,buffer[0x21]); 3655 if(buffer[0x21]==0){ 3656 // FIXME ElTorito Hardcoded. cdrom is hardcoded as device 0xE0. 3657 // Win2000 cd boot needs to know it booted from cd 3658 write_byte(ebda_seg,&EbdaData->cdemu.emulated_drive,0xE0); 3659 } 3660 else if(buffer[0x21]<4) 3661 write_byte(ebda_seg,&EbdaData->cdemu.emulated_drive,0x00); 3662 else 3663 write_byte(ebda_seg,&EbdaData->cdemu.emulated_drive,0x80); 3664 3665 write_byte(ebda_seg,&EbdaData->cdemu.controller_index,device/2); 3666 write_byte(ebda_seg,&EbdaData->cdemu.device_spec,device%2); 3667 3668 boot_segment=buffer[0x23]*0x100+buffer[0x22]; 3669 if(boot_segment==0x0000)boot_segment=0x07C0; 3670 3671 write_word(ebda_seg,&EbdaData->cdemu.load_segment,boot_segment); 3672 write_word(ebda_seg,&EbdaData->cdemu.buffer_segment,0x0000); 3673 3674 nbsectors=buffer[0x27]*0x100+buffer[0x26]; 3675 write_word(ebda_seg,&EbdaData->cdemu.sector_count,nbsectors); 3676 3677 lba=buffer[0x2B]*0x1000000+buffer[0x2A]*0x10000+buffer[0x29]*0x100+buffer[0x28]; 3678 write_dword(ebda_seg,&EbdaData->cdemu.ilba,lba); 3679 3680 // And we read the image in memory 3681 memsetb(get_SS(),atacmd,0,12); 3682 atacmd[0]=0x28; // READ command 3683 atacmd[7]=((1+(nbsectors-1)/4) & 0xff00) >> 8; // Sectors 3684 atacmd[8]=((1+(nbsectors-1)/4) & 0x00ff); // Sectors 3685 atacmd[2]=(lba & 0xff000000) >> 24; // LBA 3686 atacmd[3]=(lba & 0x00ff0000) >> 16; 3687 atacmd[4]=(lba & 0x0000ff00) >> 8; 3688 atacmd[5]=(lba & 0x000000ff); 3689 if((error = ata_cmd_packet(device, 12, get_SS(), atacmd, 0, nbsectors*512L, ATA_DATA_IN, boot_segment,0)) != 0) 3690 return 12; 3691 3692 // Remember the media type 3693 switch(read_byte(ebda_seg,&EbdaData->cdemu.media)) { 3694 case 0x01: // 1.2M floppy 3695 write_word(ebda_seg,&EbdaData->cdemu.vdevice.spt,15); 3696 write_word(ebda_seg,&EbdaData->cdemu.vdevice.cylinders,80); 3697 write_word(ebda_seg,&EbdaData->cdemu.vdevice.heads,2); 3698 break; 3699 case 0x02: // 1.44M floppy 3700 write_word(ebda_seg,&EbdaData->cdemu.vdevice.spt,18); 3701 write_word(ebda_seg,&EbdaData->cdemu.vdevice.cylinders,80); 3702 write_word(ebda_seg,&EbdaData->cdemu.vdevice.heads,2); 3703 break; 3704 case 0x03: // 2.88M floppy 3705 write_word(ebda_seg,&EbdaData->cdemu.vdevice.spt,36); 3706 write_word(ebda_seg,&EbdaData->cdemu.vdevice.cylinders,80); 3707 write_word(ebda_seg,&EbdaData->cdemu.vdevice.heads,2); 3708 break; 3709 case 0x04: // Harddrive 3710 write_word(ebda_seg,&EbdaData->cdemu.vdevice.spt,read_byte(boot_segment,446+6)&0x3f); 3711 write_word(ebda_seg,&EbdaData->cdemu.vdevice.cylinders, 3712 (read_byte(boot_segment,446+6)<<2) + read_byte(boot_segment,446+7) + 1); 3713 write_word(ebda_seg,&EbdaData->cdemu.vdevice.heads,read_byte(boot_segment,446+5) + 1); 3714 break; 3715 } 3716 3717 if(read_byte(ebda_seg,&EbdaData->cdemu.media)!=0) { 3