📄 rombios.c
字号:
e.type = 3; e.flags = 0; e.vector = 0; e.description = 0; e.reserved = 0; memcpyb(IPL_SEG, IPL_TABLE_OFFSET + count * sizeof (e), ss, &e, sizeof (e)); count++;#endif /* Remember how many devices we have */ write_word(IPL_SEG, IPL_COUNT_OFFSET, count); /* Not tried booting anything yet */ write_word(IPL_SEG, IPL_SEQUENCE_OFFSET, 0xffff);}static Bit8uget_boot_vector(i, e)Bit16u i; struct ipl_entry *e; { Bit16u count; Bit16u ss = get_SS(); /* Get the count of boot devices, and refuse to overrun the array */ count = read_word(IPL_SEG, IPL_COUNT_OFFSET); if (i >= count) return 0; /* OK to read this device */ memcpyb(ss, e, IPL_SEG, IPL_TABLE_OFFSET + i * sizeof (*e), sizeof (*e)); return 1;}//--------------------------------------------------------------------------// print_boot_device// displays the boot device//--------------------------------------------------------------------------static char drivetypes[][10]={"", "Floppy","Hard Disk","CD-Rom", "Network"};voidprint_boot_device(type) Bit16u type;{ /* NIC appears as type 0x80 */ if (type == 0x80 ) type = 0x4; if (type == 0 || type > 0x4) BX_PANIC("Bad drive type\n"); printf("Booting from %s...\n", drivetypes[type]);}//--------------------------------------------------------------------------// print_boot_failure// displays the reason why boot failed//-------------------------------------------------------------------------- voidprint_boot_failure(type, reason) Bit16u type; Bit8u reason;{ if (type == 0 || type > 0x3) BX_PANIC("Bad drive type\n"); printf("Boot from %s failed", drivetypes[type]); if (type < 4) { /* Report the reason too */ if (reason==0) printf(": not a bootable disk"); else printf(": could not read the boot disk"); } printf("\n");}//--------------------------------------------------------------------------// print_cdromboot_failure// displays the reason why boot failed//-------------------------------------------------------------------------- voidprint_cdromboot_failure( code ) Bit16u code;{ bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, "CDROM boot failure code : %04x\n",code); return;}voidnmi_handler_msg(){ BX_PANIC("NMI Handler called\n");}voidint18_panic_msg(){ BX_PANIC("INT18: BOOT FAILURE\n");}voidlog_bios_start(){#if BX_DEBUG_SERIAL outb(BX_DEBUG_PORT+UART_LCR, 0x03); /* setup for serial logging: 8N1 */#endif BX_INFO("%s\n", bios_version_string);} bx_boolset_enable_a20(val) bx_bool val;{ Bit8u oldval; // Use PS2 System Control port A to set A20 enable // get current setting first oldval = inb(0x92); // change A20 status if (val) outb(0x92, oldval | 0x02); else outb(0x92, oldval & 0xfd); return((oldval & 0x02) != 0);} voiddebugger_on(){ outb(0xfedc, 0x01);} voiddebugger_off(){ outb(0xfedc, 0x00);}#if BX_USE_ATADRV// ---------------------------------------------------------------------------// Start of ATA/ATAPI Driver// ---------------------------------------------------------------------------// Global defines -- ATA register and register bits.// command block & control block regs#define ATA_CB_DATA 0 // data reg in/out pio_base_addr1+0#define ATA_CB_ERR 1 // error in pio_base_addr1+1#define ATA_CB_FR 1 // feature reg out pio_base_addr1+1#define ATA_CB_SC 2 // sector count in/out pio_base_addr1+2#define ATA_CB_SN 3 // sector number in/out pio_base_addr1+3#define ATA_CB_CL 4 // cylinder low in/out pio_base_addr1+4#define ATA_CB_CH 5 // cylinder high in/out pio_base_addr1+5#define ATA_CB_DH 6 // device head in/out pio_base_addr1+6#define ATA_CB_STAT 7 // primary status in pio_base_addr1+7#define ATA_CB_CMD 7 // command out pio_base_addr1+7#define ATA_CB_ASTAT 6 // alternate status in pio_base_addr2+6#define ATA_CB_DC 6 // device control out pio_base_addr2+6#define ATA_CB_DA 7 // device address in pio_base_addr2+7#define ATA_CB_ER_ICRC 0x80 // ATA Ultra DMA bad CRC#define ATA_CB_ER_BBK 0x80 // ATA bad block#define ATA_CB_ER_UNC 0x40 // ATA uncorrected error#define ATA_CB_ER_MC 0x20 // ATA media change#define ATA_CB_ER_IDNF 0x10 // ATA id not found#define ATA_CB_ER_MCR 0x08 // ATA media change request#define ATA_CB_ER_ABRT 0x04 // ATA command aborted#define ATA_CB_ER_NTK0 0x02 // ATA track 0 not found#define ATA_CB_ER_NDAM 0x01 // ATA address mark not found#define ATA_CB_ER_P_SNSKEY 0xf0 // ATAPI sense key (mask)#define ATA_CB_ER_P_MCR 0x08 // ATAPI Media Change Request#define ATA_CB_ER_P_ABRT 0x04 // ATAPI command abort#define ATA_CB_ER_P_EOM 0x02 // ATAPI End of Media#define ATA_CB_ER_P_ILI 0x01 // ATAPI Illegal Length Indication// ATAPI Interrupt Reason bits in the Sector Count reg (CB_SC)#define ATA_CB_SC_P_TAG 0xf8 // ATAPI tag (mask)#define ATA_CB_SC_P_REL 0x04 // ATAPI release#define ATA_CB_SC_P_IO 0x02 // ATAPI I/O#define ATA_CB_SC_P_CD 0x01 // ATAPI C/D// bits 7-4 of the device/head (CB_DH) reg#define ATA_CB_DH_DEV0 0xa0 // select device 0#define ATA_CB_DH_DEV1 0xb0 // select device 1// status reg (CB_STAT and CB_ASTAT) bits#define ATA_CB_STAT_BSY 0x80 // busy#define ATA_CB_STAT_RDY 0x40 // ready#define ATA_CB_STAT_DF 0x20 // device fault#define ATA_CB_STAT_WFT 0x20 // write fault (old name)#define ATA_CB_STAT_SKC 0x10 // seek complete#define ATA_CB_STAT_SERV 0x10 // service#define ATA_CB_STAT_DRQ 0x08 // data request#define ATA_CB_STAT_CORR 0x04 // corrected#define ATA_CB_STAT_IDX 0x02 // index#define ATA_CB_STAT_ERR 0x01 // error (ATA)#define ATA_CB_STAT_CHK 0x01 // check (ATAPI)// device control reg (CB_DC) bits#define ATA_CB_DC_HD15 0x08 // bit should always be set to one#define ATA_CB_DC_SRST 0x04 // soft reset#define ATA_CB_DC_NIEN 0x02 // disable interrupts// Most mandtory and optional ATA commands (from ATA-3),#define ATA_CMD_CFA_ERASE_SECTORS 0xC0#define ATA_CMD_CFA_REQUEST_EXT_ERR_CODE 0x03#define ATA_CMD_CFA_TRANSLATE_SECTOR 0x87#define ATA_CMD_CFA_WRITE_MULTIPLE_WO_ERASE 0xCD#define ATA_CMD_CFA_WRITE_SECTORS_WO_ERASE 0x38#define ATA_CMD_CHECK_POWER_MODE1 0xE5#define ATA_CMD_CHECK_POWER_MODE2 0x98#define ATA_CMD_DEVICE_RESET 0x08#define ATA_CMD_EXECUTE_DEVICE_DIAGNOSTIC 0x90#define ATA_CMD_FLUSH_CACHE 0xE7#define ATA_CMD_FORMAT_TRACK 0x50#define ATA_CMD_IDENTIFY_DEVICE 0xEC#define ATA_CMD_IDENTIFY_DEVICE_PACKET 0xA1#define ATA_CMD_IDENTIFY_PACKET_DEVICE 0xA1#define ATA_CMD_IDLE1 0xE3#define ATA_CMD_IDLE2 0x97#define ATA_CMD_IDLE_IMMEDIATE1 0xE1#define ATA_CMD_IDLE_IMMEDIATE2 0x95#define ATA_CMD_INITIALIZE_DRIVE_PARAMETERS 0x91#define ATA_CMD_INITIALIZE_DEVICE_PARAMETERS 0x91#define ATA_CMD_NOP 0x00#define ATA_CMD_PACKET 0xA0#define ATA_CMD_READ_BUFFER 0xE4#define ATA_CMD_READ_DMA 0xC8#define ATA_CMD_READ_DMA_QUEUED 0xC7#define ATA_CMD_READ_MULTIPLE 0xC4#define ATA_CMD_READ_SECTORS 0x20#define ATA_CMD_READ_VERIFY_SECTORS 0x40#define ATA_CMD_RECALIBRATE 0x10#define ATA_CMD_SEEK 0x70#define ATA_CMD_SET_FEATURES 0xEF#define ATA_CMD_SET_MULTIPLE_MODE 0xC6#define ATA_CMD_SLEEP1 0xE6#define ATA_CMD_SLEEP2 0x99#define ATA_CMD_STANDBY1 0xE2#define ATA_CMD_STANDBY2 0x96#define ATA_CMD_STANDBY_IMMEDIATE1 0xE0#define ATA_CMD_STANDBY_IMMEDIATE2 0x94#define ATA_CMD_WRITE_BUFFER 0xE8#define ATA_CMD_WRITE_DMA 0xCA#define ATA_CMD_WRITE_DMA_QUEUED 0xCC#define ATA_CMD_WRITE_MULTIPLE 0xC5#define ATA_CMD_WRITE_SECTORS 0x30#define ATA_CMD_WRITE_VERIFY 0x3C#define ATA_IFACE_NONE 0x00#define ATA_IFACE_ISA 0x00#define ATA_IFACE_PCI 0x01#define ATA_TYPE_NONE 0x00#define ATA_TYPE_UNKNOWN 0x01#define ATA_TYPE_ATA 0x02#define ATA_TYPE_ATAPI 0x03#define ATA_DEVICE_NONE 0x00#define ATA_DEVICE_HD 0xFF#define ATA_DEVICE_CDROM 0x05#define ATA_MODE_NONE 0x00#define ATA_MODE_PIO16 0x00#define ATA_MODE_PIO32 0x01#define ATA_MODE_ISADMA 0x02#define ATA_MODE_PCIDMA 0x03#define ATA_MODE_USEIRQ 0x10#define ATA_TRANSLATION_NONE 0#define ATA_TRANSLATION_LBA 1#define ATA_TRANSLATION_LARGE 2#define ATA_TRANSLATION_RECHS 3#define ATA_DATA_NO 0x00#define ATA_DATA_IN 0x01#define ATA_DATA_OUT 0x02 // ---------------------------------------------------------------------------// ATA/ATAPI driver : initialization// ---------------------------------------------------------------------------void ata_init( ){ Bit16u ebda_seg=read_word(0x0040,0x000E); Bit8u channel, device; // Channels info init. for (channel=0; channel<BX_MAX_ATA_INTERFACES; channel++) { write_byte(ebda_seg,&EbdaData->ata.channels[channel].iface,ATA_IFACE_NONE); write_word(ebda_seg,&EbdaData->ata.channels[channel].iobase1,0x0); write_word(ebda_seg,&EbdaData->ata.channels[channel].iobase2,0x0); write_byte(ebda_seg,&EbdaData->ata.channels[channel].irq,0); } // Devices info init. for (device=0; device<BX_MAX_ATA_DEVICES; device++) { write_byte(ebda_seg,&EbdaData->ata.devices[device].type,ATA_TYPE_NONE); write_byte(ebda_seg,&EbdaData->ata.devices[device].device,ATA_DEVICE_NONE); write_byte(ebda_seg,&EbdaData->ata.devices[device].removable,0); write_byte(ebda_seg,&EbdaData->ata.devices[device].lock,0); write_byte(ebda_seg,&EbdaData->ata.devices[device].mode,ATA_MODE_NONE); write_word(ebda_seg,&EbdaData->ata.devices[device].blksize,0); write_byte(ebda_seg,&EbdaData->ata.devices[device].translation,ATA_TRANSLATION_NONE); write_word(ebda_seg,&EbdaData->ata.devices[device].lchs.heads,0); write_word(ebda_seg,&EbdaData->ata.devices[device].lchs.cylinders,0); write_word(ebda_seg,&EbdaData->ata.devices[device].lchs.spt,0); write_word(ebda_seg,&EbdaData->ata.devices[device].pchs.heads,0); write_word(ebda_seg,&EbdaData->ata.devices[device].pchs.cylinders,0); write_word(ebda_seg,&EbdaData->ata.devices[device].pchs.spt,0); write_dword(ebda_seg,&EbdaData->ata.devices[device].sectors,0L); } // hdidmap and cdidmap init. for (device=0; device<BX_MAX_ATA_DEVICES; device++) { write_byte(ebda_seg,&EbdaData->ata.hdidmap[device],BX_MAX_ATA_DEVICES); write_byte(ebda_seg,&EbdaData->ata.cdidmap[device],BX_MAX_ATA_DEVICES); } write_byte(ebda_seg,&EbdaData->ata.hdcount,0); write_byte(ebda_seg,&EbdaData->ata.cdcount,0);}// ---------------------------------------------------------------------------// ATA/ATAPI driver : device detection// ---------------------------------------------------------------------------void ata_detect( ){ Bit16u ebda_seg=read_word(0x0040,0x000E); Bit8u hdcount, cdcount, device, type; Bit8u buffer[0x0200];#if BX_MAX_ATA_INTERFACES > 0 write_byte(ebda_seg,&EbdaData->ata.channels[0].iface,ATA_IFACE_ISA); write_word(ebda_seg,&EbdaData->ata.channels[0].iobase1,0x1f0); write_word(ebda_seg,&EbdaData->ata.channels[0].iobase2,0x3f0); write_byte(ebda_seg,&EbdaData->ata.channels[0].irq,14);#endif#if BX_MAX_ATA_INTERFACES > 1 write_byte(ebda_seg,&EbdaData->ata.channels[1].iface,ATA_IFACE_ISA); write_word(ebda_seg,&EbdaData->ata.channels[1].iobase1,0x170); write_word(ebda_seg,&EbdaData->ata.channels[1].iobase2,0x370); write_byte(ebda_seg,&EbdaData->ata.channels[1].irq,15);#endif#if BX_MAX_ATA_INTERFACES > 2 write_byte(ebda_seg,&EbdaData->ata.channels[2].iface,ATA_IFACE_ISA); write_word(ebda_seg,&EbdaData->ata.channels[2].iobase1,0x1e8); write_word(ebda_seg,&EbdaData->ata.channels[2].iobase2,0x3e0); write_byte(ebda_seg,&EbdaData->ata.channels[2].irq,12);#endif#if BX_MAX_ATA_INTERFACES > 3 write_byte(ebda_seg,&EbdaData->ata.channels[3].iface,ATA_IFACE_ISA); write_word(ebda_seg,&EbdaData->ata.channels[3].iobase1,0x168); write_word(ebda_seg,&EbdaData->ata.channels[3].iobase2,0x360); write_byte(ebda_seg,&EbdaData->ata.channels[3].irq,11);#endif#if BX_MAX_ATA_INTERFACES > 4#error Please fill the ATA interface informations#endif // Device detection hdcount=cdcount=0; for(device=0; device<BX_MAX_ATA_DEVICES; device++) { Bit16u iobase1, iobase2; Bit8u channel, slave, shift; Bit8u sc, sn, cl, ch, st; channel = device / 2; slave = device % 2; iobase1 =read_word(ebda_seg,&EbdaData->ata.channels[channel].iobase1); iobase2 =read_word(ebda_seg,&EbdaData->ata.channels[channel].iobase2); // Disable interrupts outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN); // Look for device outb(iobase1+ATA_CB_DH, slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0); outb(iobase1+ATA_CB_SC, 0x55); outb(iobase1+ATA_CB_SN, 0xaa); outb(iobase1+ATA_CB_SC, 0xaa); outb(iobase1+ATA_CB_SN, 0x55); outb(iobase1+ATA_CB_SC, 0x55); outb(iobase1+ATA_CB_SN, 0xaa); // If we found something sc = inb(iobase1+ATA_CB_SC); sn = inb(iobase1+ATA_CB_SN); if ( (sc == 0x55) && (sn == 0xaa) ) { write_byte(ebda_seg,&EbdaData->ata.devices[device].type,ATA_TYPE_UNKNOWN); // reset the channel ata_reset (device); // check for ATA or ATAPI outb(iobase1+ATA_CB_DH, slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0); sc = inb(iobase1+ATA_CB_SC); sn = inb(iobase1+ATA_CB_SN); if ( (sc==0x01) && (sn==0x01) ) { cl = inb(iobase1+ATA_CB_CL); ch = inb(iobase1+ATA_CB_CH); st = inb(iobase1+ATA_CB_STAT); if ( (cl==0x14) && (ch==0xeb) ) { write_byte(ebda_seg,&EbdaData->ata.devices[device].type,ATA_TYPE_ATAPI); } else if ( (cl==0x00) && (ch==0x00) && (st!=0x00) ) { write_byte(ebda_seg,&EbdaData->ata.devices[device].type,ATA_TYPE_ATA); } } } type=read_byte(ebda_seg,&EbdaData->ata.devices[device].type); // Now we send a IDENTIFY command to ATA device if(type == ATA_TYPE_ATA) { Bit32u sectors; Bit16u cylinders, heads, spt, blksize; Bit8u translation, removable, mode; // default mode to PIO16 mode = ATA_MODE_PIO16; //Temporary values to do the transfer write_byte(ebda_seg,&EbdaData->ata.devices[device].device,ATA_DEVICE_HD); write_byte(ebda_seg,&EbdaData->ata.devices[device].mode, ATA_MODE_PIO16); if (ata_cmd_data_in(device,ATA_CMD_IDENTIFY_DEVICE, 1, 0, 0, 0, 0L, get_SS(),buffer) !=0 ) BX_PANIC("ata-detect: Failed to detect ATA device\n"); removable = (read_byte(get_SS(),buffer+0) & 0x80) ? 1 : 0;#ifndef NO_PIO32 mode = read_byte(get_SS(),buffer+96) ? ATA_MODE_PIO32 : ATA_MODE_PIO16;#endif blksize = read_word(get_SS(),buffer+10); cylinders = read_word(get_SS(),buffer+(1*2)); // word 1 heads = read_word(get_SS(),buffer+(3*2)); // word 3 spt = read_word(get_SS(),buffer+(6*2)); // word 6 sectors = read_dword(get_SS(),buffer+(60*2)); // word 60 and word 61 write_byte(ebda_seg,&EbdaData->ata.devices[device].device,ATA_DEVICE_HD); write_byte(ebda_seg,&EbdaData->ata.devices[device].removable, removable); write_byte(ebda_seg,&EbdaData->ata.devices[device].mode, mode); write_word(ebda_seg,&EbdaData->ata.devices[device].blksize, blksize); write_word(ebda_seg,&EbdaData->ata.devices[device].pchs.heads, heads); write_word(ebda_seg,&EbdaData->ata.devices[device].pchs.cylinders, cylinders); write_word(ebda_seg,&EbdaData->ata.devices[device].pchs.spt, spt); write_dword(ebda_seg,&EbdaData->ata.devices[device].sectors, sectors); BX_INFO("ata%d-%d: PCHS=%u/%d/%d translation=", channel, slave,cylinders, heads, spt); translation = inb_cmos(0x39 + channel/2); for (shift=device%4; shift>0; shift--) translation >>= 2; translation &= 0x03; write_byte(ebda_seg,&EbdaData->ata.devices[device].translation, translation); switch (translation) { case ATA_TRANSLATION_NONE: BX_INFO("none"); break; case ATA_TRANSLATION_LBA: BX_INFO("lba"); break; case ATA_TRANSLATION_LARGE: BX_INFO("large"); break; case ATA_TRANSLATION_RECHS: BX_INFO("r-echs"); break; } switch (translation) { case ATA_TRANSLATION_NONE: break; case ATA_TRANSLATION_LBA: spt = 63; sectors /= 63; heads = sectors / 1024; if (heads>128) heads = 255; else if (heads>64) heads = 128; else if (heads>32) heads = 64; else if (heads>16) heads = 32; else heads=16; cylinders = sectors / heads; break; case ATA_TRANSLATION_RECHS: // Take care not to overflow if (head
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -