VirtualBox

Changeset 39560 in vbox


Ignore:
Timestamp:
Dec 8, 2011 4:41:37 PM (13 years ago)
Author:
vboxsync
Message:

BIOS: Initial AHCI CD-ROM support.

Location:
trunk/src/VBox/Devices/PC/BIOS-new
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/PC/BIOS-new/ahci.c

    r39375 r39560  
    6464     *  Must be aligned on 128 byte boundary.
    6565     */
    66     uint8_t         abCmd[0x80];
     66    uint8_t         abCmd[0x40];
     67    /** The ATAPI command region.
     68     *  Located 40h bytes after the beginning of the CFIS (Command FIS).
     69     */
     70    uint8_t         abAcmd[0x20];
     71    /** Align the PRDT structure on a 128 byte boundary. */
     72    uint8_t         abAlignment2[0x20];
    6773    /** Physical Region Descriptor Table (PRDT) array. In other
    6874     *  words, a scatter/gather descriptor list.
     
    155161
    156162#define ATA_CMD_IDENTIFY_DEVICE     0xEC
     163#define ATA_CMD_IDENTIFY_PACKET     0xA1
     164#define ATA_CMD_PACKET              0xA0
    157165#define AHCI_CMD_READ_DMA_EXT       0x25
    158166#define AHCI_CMD_WRITE_DMA_EXT      0x35
     
    239247        /* Prepare the command header. */
    240248        ahci->aCmdHdr[0] = RT_BIT_32(16) | RT_BIT_32(7) | val;
    241         ahci->aCmdHdr[1] = cbData;
     249        ahci->aCmdHdr[1] = 0; //cbData;  //@todo: Is this really an input parameter?
    242250        ahci->aCmdHdr[2] = ahci_addr_to_phys(&ahci->abCmd[0]);
    243251
     
    277285    ahci_t __far    *ahci  = bios_dsk->ahci_seg :> 0;
    278286    uint16_t        n_sect = bios_dsk->drqp.nsect;
     287    uint16_t        sectsz = bios_dsk->drqp.sect_sz;
    279288
    280289    _fmemset(&ahci->abCmd[0], 0, sizeof(ahci->abCmd));
     
    301310    /* Lock memory needed for DMA. */
    302311    ahci->edds.num_avail = NUM_EDDS_SG;
    303     vds_build_sg_list(&ahci->edds, bios_dsk->drqp.buffer, n_sect * 512);
     312    vds_build_sg_list(&ahci->edds, bios_dsk->drqp.buffer, (uint32_t)n_sect * sectsz);
    304313
    305314    /* Set up the PRDT. */
     
    307316    ahci->aPrdt[0].len       = ahci->edds.u.sg[0].size - 1;
    308317
    309     /* Build variable part first of command dword. */
     318    /* Build variable part first of command dword (reuses 'cmd'). */
    310319    if (cmd == AHCI_CMD_WRITE_DMA_EXT)
    311         cmd = RT_BIT_32(6);
    312     else
     320        cmd = RT_BIT_32(6);     /* Indicate write to device. */
     321    else if (cmd == ATA_CMD_PACKET) {
     322        cmd |= RT_BIT_32(5);    /* Indicate ATAPI command. */
     323        ahci->abCmd[3] |= 1;    /* DMA transfers. */
     324    } else
    313325        cmd = 0;
    314326
    315 //    if (fAtapi)
    316 //        cmd |= RT_BIT_32(5);
    317 
    318     cmd |= 5;   /* Five dwords. */
    319 
    320     ahci_port_cmd_sync(ahci, cmd, n_sect * 512);
     327    cmd |= 5;   /* Five DWORDs. */
     328
     329    ahci_port_cmd_sync(ahci, cmd, n_sect * sectsz);
    321330
    322331    /* Unlock the buffer again. */
     
    427436    device_id = bios_dsk->drqp.dev_id - BX_MAX_ATA_DEVICES - BX_MAX_SCSI_DEVICES;
    428437    if (device_id > BX_MAX_AHCI_DEVICES)
    429         BX_PANIC("ahci_read_sectors: device_id out of range %d\n", device_id);
     438        BX_PANIC("%s: device_id out of range %d\n", __func__, device_id);
     439
     440    VBOXAHCI_DEBUG("%s: %u sectors @ LBA %lu, device %d, port %d\n", __func__,
     441                   bios_dsk->drqp.nsect, bios_dsk->drqp.lba, device_id,
     442                   bios_dsk->ahcidev[device_id].port);
    430443
    431444    ahci_port_init(bios_dsk->ahci_seg :> 0, bios_dsk->ahcidev[device_id].port);
     
    450463    device_id = bios_dsk->drqp.dev_id - BX_MAX_ATA_DEVICES - BX_MAX_SCSI_DEVICES;
    451464    if (device_id > BX_MAX_AHCI_DEVICES)
    452         BX_PANIC("ahci_write_sectors: device_id out of range %d\n", device_id);
     465        BX_PANIC("%s: device_id out of range %d\n", __func__, device_id);
     466
     467    VBOXAHCI_DEBUG("%s: %u sectors @ LBA %lu, device %d, port %d\n", __func__,
     468                   bios_dsk->drqp.nsect, bios_dsk->drqp.lba, device_id,
     469                   bios_dsk->ahcidev[device_id].port);
    453470
    454471    ahci_port_init(bios_dsk->ahci_seg :> 0, bios_dsk->ahcidev[device_id].port);
    455472    ahci_cmd_data(bios_dsk, AHCI_CMD_WRITE_DMA_EXT);
    456473    return 0;   //@todo!!
     474}
     475
     476//@todo: move
     477#define ATA_DATA_NO      0x00
     478#define ATA_DATA_IN      0x01
     479#define ATA_DATA_OUT     0x02
     480
     481uint16_t ahci_cmd_packet(uint16_t device_id, uint8_t cmdlen, char __far *cmdbuf,
     482                         uint16_t header, uint32_t length, uint8_t inout, char __far *buffer)
     483{
     484    bio_dsk_t __far *bios_dsk = read_word(0x0040, 0x000E) :> &EbdaData->bdisk;
     485    ahci_t __far    *ahci     = bios_dsk->ahci_seg :> 0;
     486
     487    /* Data out is currently not supported. */
     488    if (inout == ATA_DATA_OUT) {
     489        BX_INFO("%s: DATA_OUT not supported yet\n", __func__);
     490        return 1;
     491    }
     492
     493    /* The header length must be even. */
     494    if (header & 1) {
     495        VBOXAHCI_DEBUG("%s: header must be even (%04x)\n", __func__, header);
     496        return 1;
     497    }
     498
     499    /* Convert to AHCI specific device number. */
     500    device_id = device_id - BX_MAX_ATA_DEVICES - BX_MAX_SCSI_DEVICES;
     501
     502    VBOXAHCI_DEBUG("%s: reading %lu bytes, header %u, device %d, port %d\n", __func__,
     503                   length, header, device_id, bios_dsk->ahcidev[device_id].port);
     504
     505    bios_dsk->drqp.lba     = (uint32_t)length << 8;     //@todo: xfer length limit
     506    bios_dsk->drqp.buffer  = buffer;
     507    bios_dsk->drqp.nsect   = length / 2048;
     508    bios_dsk->drqp.sect_sz = 2048;
     509
     510    ahci_port_init(bios_dsk->ahci_seg :> 0, bios_dsk->ahcidev[device_id].port);
     511
     512    /* Copy the ATAPI command where the HBA can fetch it. */
     513    _fmemcpy(ahci->abAcmd, cmdbuf, cmdlen);
     514
     515    /* Reset transferred counts. */
     516    // @todo: clear in calling code?
     517    bios_dsk->drqp.trsfsectors = 0;
     518    bios_dsk->drqp.trsfbytes   = 0;
     519
     520    ahci_cmd_data(bios_dsk, ATA_CMD_PACKET);
     521    VBOXAHCI_DEBUG("%s: transferred %lu bytes\n", __func__, ahci->aCmdHdr[1]);
     522#ifdef DMA_WORKAROUND
     523    rep_movsw(bios_dsk->drqp.buffer, bios_dsk->drqp.buffer, bios_dsk->drqp.nsect * 2048 / 2);
     524#endif
     525    bios_dsk->drqp.trsfbytes = ahci->aCmdHdr[1];
     526    return ahci->aCmdHdr[1] == 0 ? 4 : 0;
     527//    return 0;   //@todo!!
    457528}
    458529
     
    478549    if (ahci_ctrl_extract_bits(val, 0xfL, 0) == 0x3)
    479550    {
    480         uint8_t     hdcount, hdcount_ahci, hd_index;
    481 
    482         hdcount_ahci = bios_dsk->ahci_hdcount;
     551        uint8_t     abBuffer[0x0200];
     552        uint8_t     hdcount, devcount_ahci, hd_index;
     553        uint8_t     cdcount;
     554        uint8_t     removable;
     555
     556        devcount_ahci = bios_dsk->ahci_devcnt;
    483557
    484558        VBOXAHCI_DEBUG("AHCI: Device detected on port %d\n", u8Port);
    485559
    486         if (hdcount_ahci < BX_MAX_AHCI_DEVICES)
     560        //@todo: Merge common HD/CDROM detection code
     561        if (devcount_ahci < BX_MAX_AHCI_DEVICES)
    487562        {
    488563            /* Device detected, enable FIS receive. */
     
    495570            {
    496571                uint32_t    cSectors;
    497                 uint8_t     abBuffer[0x0200];
    498                 uint8_t     fRemovable;
    499572                uint16_t    cCylinders, cHeads, cSectorsPerTrack;
    500573                uint8_t     idxCmosChsBase;
     
    503576
    504577                /* Identify device. */
    505                 bios_dsk->drqp.lba    = 0;
    506                 bios_dsk->drqp.buffer = &abBuffer;
    507                 bios_dsk->drqp.nsect  = 1;
     578                bios_dsk->drqp.lba     = 0;
     579                bios_dsk->drqp.buffer  = &abBuffer;
     580                bios_dsk->drqp.nsect   = 1;
     581                bios_dsk->drqp.sect_sz = 512;
    508582                ahci_cmd_data(bios_dsk, ATA_CMD_IDENTIFY_DEVICE);
    509583
    510                 /* Calculate index into the generic disk table. */
    511                 hd_index = hdcount_ahci + BX_MAX_ATA_DEVICES + BX_MAX_SCSI_DEVICES;
    512 
    513                 fRemovable       = *(abBuffer+0) & 0x80 ? 1 : 0;
     584                /* Calculate index into the generic device table. */
     585                hd_index = devcount_ahci + BX_MAX_ATA_DEVICES + BX_MAX_SCSI_DEVICES;
     586
     587                removable        = *(abBuffer+0) & 0x80 ? 1 : 0;
    514588                cCylinders       = *(uint16_t *)(abBuffer+(1*2));   // word 1
    515589                cHeads           = *(uint16_t *)(abBuffer+(3*2));   // word 3
     
    523597                VBOXAHCI_DEBUG("AHCI: %ld sectors\n", cSectors);
    524598
    525                 bios_dsk->ahcidev[hdcount_ahci].port = u8Port;
     599                bios_dsk->ahcidev[devcount_ahci].port = u8Port;
    526600                bios_dsk->devices[hd_index].type        = ATA_TYPE_AHCI;
    527601                bios_dsk->devices[hd_index].device      = ATA_DEVICE_HD;
    528                 bios_dsk->devices[hd_index].removable   = fRemovable;
     602                bios_dsk->devices[hd_index].removable   = removable;
    529603                bios_dsk->devices[hd_index].lock        = 0;
    530604                bios_dsk->devices[hd_index].blksize     = 512;
     
    537611
    538612                /* Get logical CHS geometry. */
    539                 switch (hdcount_ahci)
     613                switch (devcount_ahci)
    540614                {
    541615                    case 0:
     
    567641                }
    568642                VBOXAHCI_DEBUG("AHCI: Dev %d LCHS=%d/%d/%d\n",
    569                                hdcount_ahci, cCylinders, cHeads, cSectorsPerTrack);
     643                               devcount_ahci, cCylinders, cHeads, cSectorsPerTrack);
    570644
    571645                bios_dsk->devices[hd_index].lchs.heads     = cHeads;
     
    573647                bios_dsk->devices[hd_index].lchs.spt       = cSectorsPerTrack;
    574648
    575                 /* Store the id of the disk in the ata hdidmap. */
     649                /* Store the ID of the disk in the BIOS hdidmap. */
    576650                hdcount = bios_dsk->hdcount;
    577                 bios_dsk->hdidmap[hdcount] = hdcount_ahci + BX_MAX_ATA_DEVICES + BX_MAX_SCSI_DEVICES;
     651                bios_dsk->hdidmap[hdcount] = devcount_ahci + BX_MAX_ATA_DEVICES + BX_MAX_SCSI_DEVICES;
    578652                hdcount++;
    579653                bios_dsk->hdcount = hdcount;
     
    582656                hdcount = read_byte(0x40, 0x75);
    583657                hdcount++;
    584                 write_byte(0x40, 0x75, hdcount);
    585                
     658                write_byte(0x40, 0x75, hdcount);               
    586659            }
    587660            else if (val == 0xeb140101)
    588661            {
    589662                VBOXAHCI_DEBUG("AHCI: Detected ATAPI device\n");
     663
     664                /* Identify packet device. */
     665                bios_dsk->drqp.lba     = 0;
     666                bios_dsk->drqp.buffer  = &abBuffer;
     667                bios_dsk->drqp.nsect   = 1;
     668                bios_dsk->drqp.sect_sz = 512;
     669                ahci_cmd_data(bios_dsk, ATA_CMD_IDENTIFY_PACKET);
     670
     671                /* Calculate index into the generic device table. */
     672                hd_index = devcount_ahci + BX_MAX_ATA_DEVICES + BX_MAX_SCSI_DEVICES;
     673
     674                removable = *(abBuffer+0) & 0x80 ? 1 : 0;
     675
     676                bios_dsk->ahcidev[devcount_ahci].port = u8Port;
     677                bios_dsk->devices[hd_index].type      = ATA_TYPE_AHCI;
     678                bios_dsk->devices[hd_index].device    = ATA_DEVICE_CDROM;
     679                bios_dsk->devices[hd_index].removable = removable;
     680                bios_dsk->devices[hd_index].blksize   = 2048;
     681
     682                /* Store the ID of the device in the BIOS cdidmap. */
     683                cdcount = bios_dsk->cdcount;
     684                bios_dsk->cdidmap[cdcount] = devcount_ahci + BX_MAX_ATA_DEVICES + BX_MAX_SCSI_DEVICES;
     685                cdcount++;
     686                bios_dsk->cdcount = cdcount;
    590687            }
    591688            else
    592689                VBOXAHCI_DEBUG("AHCI: Ignoring unknown device\n");
    593690
    594             hdcount_ahci++;
    595             bios_dsk->ahci_hdcount = hdcount_ahci;
     691            devcount_ahci++;
     692            bios_dsk->ahci_devcnt = devcount_ahci;
    596693        }
    597694        else
     
    651748
    652749    write_word(ebda_seg, (uint16_t)&EbdaData->bdisk.ahci_seg, ahci_seg);
    653     write_byte(ebda_seg, (uint16_t)&EbdaData->bdisk.ahci_hdcount, 0);
     750    write_byte(ebda_seg, (uint16_t)&EbdaData->bdisk.ahci_devcnt, 0);
    654751    write_byte(ahci_seg, (uint16_t)&AhciData->cur_port, 0xff);
    655752    write_word(ahci_seg, (uint16_t)&AhciData->iobase, io_base);
  • trunk/src/VBox/Devices/PC/BIOS-new/ata.c

    r39366 r39560  
    586586            bios_dsk->drqp.dev_id = device;
    587587
    588             if (ata_cmd_data_in(bios_dsk, ATA_CMD_IDENTIFY_DEVICE_PACKET, 1) != 0)
     588            if (ata_cmd_data_in(bios_dsk, ATA_CMD_IDENTIFY_PACKET, 1) != 0)
    589589                BX_PANIC("ata-detect: Failed to detect ATAPI device\n");
    590590
     
    11281128// End of ATA/ATAPI Driver
    11291129// ---------------------------------------------------------------------------
    1130 
    1131 uint16_t atapi_is_cdrom(uint8_t device)
    1132 {
    1133     bio_dsk_t __far *bios_dsk;
    1134    
    1135     bios_dsk = read_word(0x0040, 0x000E) :> &EbdaData->bdisk;
    1136    
    1137     if (device >= BX_MAX_ATA_DEVICES)
    1138         return 0;
    1139    
    1140     if (bios_dsk->devices[device].type != ATA_TYPE_ATAPI)
    1141         return 0;
    1142    
    1143     if (bios_dsk->devices[device].device != ATA_DEVICE_CDROM)
    1144         return 0;
    1145    
    1146     return 1;
    1147 }
    1148 
    1149 // ---------------------------------------------------------------------------
    1150 // End of ATA/ATAPI generic functions
    1151 // ---------------------------------------------------------------------------
  • trunk/src/VBox/Devices/PC/BIOS-new/ata.h

    r39372 r39560  
    128128#define ATA_CMD_FORMAT_TRACK                 0x50
    129129#define ATA_CMD_IDENTIFY_DEVICE              0xEC
    130 #define ATA_CMD_IDENTIFY_DEVICE_PACKET       0xA1
    131 #define ATA_CMD_IDENTIFY_PACKET_DEVICE       0xA1
     130#define ATA_CMD_IDENTIFY_PACKET              0xA1
    132131#define ATA_CMD_IDLE1                        0xE3
    133132#define ATA_CMD_IDLE2                        0x97
     
    204203#define Int13DPT ((dpt_t *) 0)
    205204
    206 
    207205extern void     ata_reset(uint16_t device);
    208 extern uint16_t atapi_is_cdrom(uint8_t device);
    209 extern uint16_t ata_cmd_packet(uint16_t device, uint8_t cmdlen,
    210                                char __far *cmdbuf, uint16_t header,
    211                                uint32_t length, uint8_t inout,
    212                                char __far *buffer);
  • trunk/src/VBox/Devices/PC/BIOS-new/disk.c

    r39375 r39560  
    161161        bios_dsk->drqp.buffer   = MK_FP(ES, BX);
    162162        bios_dsk->drqp.nsect    = count;
     163        bios_dsk->drqp.sect_sz  = 512;  //@todo: device specific?
    163164        bios_dsk->drqp.cylinder = cylinder;
    164165        bios_dsk->drqp.head     = head;
     
    373374
    374375        /* Pass request information to low level disk code. */
    375         bios_dsk->drqp.lba    = lba;
    376         bios_dsk->drqp.buffer = MK_FP(segment, offset);
    377         bios_dsk->drqp.nsect  = count;
    378         bios_dsk->drqp.sector = 0;      /* Indicate LBA. */
     376        bios_dsk->drqp.lba     = lba;
     377        bios_dsk->drqp.buffer  = MK_FP(segment, offset);
     378        bios_dsk->drqp.nsect   = count;
     379        bios_dsk->drqp.sect_sz = 512;   //@todo: device specific?
     380        bios_dsk->drqp.sector  = 0;     /* Indicate LBA. */
    379381       
    380382        // Execute the command
  • trunk/src/VBox/Devices/PC/BIOS-new/ebda.h

    r39372 r39560  
    195195    uint8_t     dev_id;             /* Device ID; index into devices array. */
    196196    uint16_t    nsect;              /* Number of sectors to be transferred. */
     197    uint16_t    sect_sz;            /* Size of a sector in bytes. */
    197198    uint16_t    cylinder;           /* Starting cylinder (CHS only). */
    198199    uint16_t    head;               /* Starting head (CHS only). */
     
    216217
    217218    uint8_t     cdcount;            /* Number of CD-ROMs. */
    218     /* Map between (BIOS CD-ROM ID - 0xE0) and ATA channels. */
     219    /* Map between (BIOS CD-ROM ID - 0xE0) and ATA/SCSI/AHCI devices. */
    219220    uint8_t     cdidmap[BX_MAX_STORAGE_DEVICES];
    220221
     
    231232    /* SATA (AHCI) bus-specific device information. */
    232233    ahci_dev_t  ahcidev[BX_MAX_AHCI_DEVICES];
    233     uint8_t     ahci_hdcount;       /* Number of SATA disks. */
     234    uint8_t     ahci_devcnt;        /* Number of SATA devices. */
    234235    uint16_t    ahci_seg;           /* Segment of AHCI data block. */
    235236#endif
     
    296297int __fastcall ahci_write_sectors(bio_dsk_t __far *bios_dsk);
    297298
     299
     300uint16_t ahci_cmd_packet(uint16_t device_id, uint8_t cmdlen, char __far *cmdbuf,
     301                         uint16_t header, uint32_t length, uint8_t inout, char __far *buffer);
     302
     303uint16_t ata_cmd_packet(uint16_t device, uint8_t cmdlen, char __far *cmdbuf,
     304                        uint16_t header, uint32_t length, uint8_t inout, char __far *buffer);
     305
    298306// @todo: put this elsewhere (and change/eliminate?)
    299307#define SET_DISK_RET_STATUS(status) write_byte(0x0040, 0x0074, status)
  • trunk/src/VBox/Devices/PC/BIOS-new/eltorito.c

    r39355 r39560  
    189189// ---------------------------------------------------------------------------
    190190
     191/* Utility routine to check if a device is a CD-ROM. */
     192//@todo: this function is kinda useless as the ATAPI type check is obsolete.
     193static uint16_t device_is_cdrom(uint8_t device)
     194{
     195    bio_dsk_t __far *bios_dsk;
     196   
     197    bios_dsk = read_word(0x0040, 0x000E) :> &EbdaData->bdisk;
     198   
     199    if (device >= BX_MAX_STORAGE_DEVICES)
     200        return 0;
     201   
     202//    if (bios_dsk->devices[device].type != ATA_TYPE_ATAPI)
     203//        return 0;
     204   
     205    if (bios_dsk->devices[device].device != ATA_DEVICE_CDROM)
     206        return 0;
     207   
     208    return 1;
     209}
     210
     211// ---------------------------------------------------------------------------
     212// End of ATA/ATAPI generic functions
     213// ---------------------------------------------------------------------------
    191214static const char isotag[]="CD001";
    192215static const char eltorito[]="EL TORITO SPECIFICATION";
     
    207230    cdemu = ebda_seg :> &EbdaData->cdemu;
    208231
    209     // Find out the first cdrom
    210     for (device=0; device<BX_MAX_ATA_DEVICES;device++) {
    211         if (atapi_is_cdrom(device))
     232    /* Find the first CD-ROM. */
     233    for (device = 0; device < BX_MAX_STORAGE_DEVICES; ++device) {
     234        if (device_is_cdrom(device))
    212235            break;
    213236    }
    214237
    215     // if not found
    216     if(device >= BX_MAX_ATA_DEVICES) return 2;
    217    
    218     // Read the Boot Record Volume Descriptor
    219     _fmemset(&atacmd,0,12);
    220     atacmd[0]=0x28;                      // READ command
    221     atacmd[7]=(0x01 & 0xff00) >> 8;      // Sectors
    222     atacmd[8]=(0x01 & 0x00ff);           // Sectors
    223     atacmd[2]=(0x11 & 0xff000000) >> 24; // LBA
    224     atacmd[3]=(0x11 & 0x00ff0000) >> 16;
    225     atacmd[4]=(0x11 & 0x0000ff00) >> 8;
    226     atacmd[5]=(0x11 & 0x000000ff);
    227 
    228     for (read_try = 0; read_try <= 4; read_try++)
     238    /* Fail if not found. */
     239    if (device >= BX_MAX_STORAGE_DEVICES)
     240        return 2;
     241   
     242    /* Read the Boot Record Volume Descriptor (BRVD). */
     243    _fmemset(&atacmd, 0, 12);
     244    //@todo: use some sane byte swapping routines here
     245    atacmd[0] = 0x28;                       // READ command
     246    atacmd[7] = (0x01 & 0xff00) >> 8;       // Sectors
     247    atacmd[8] = (0x01 & 0x00ff);            // Sectors
     248    atacmd[2] = (0x11 & 0xff000000) >> 24;  // LBA
     249    atacmd[3] = (0x11 & 0x00ff0000) >> 16;
     250    atacmd[4] = (0x11 & 0x0000ff00) >> 8;
     251    atacmd[5] = (0x11 & 0x000000ff);
     252
     253    for (read_try = 0; read_try <= 4; ++read_try)
    229254    {
    230         error = ata_cmd_packet(device, 12, &atacmd, 0, 2048L, ATA_DATA_IN, &buffer);
     255        //@todo: Use indirect calls instead?
     256        if (device > BX_MAX_ATA_DEVICES)
     257            error = ahci_cmd_packet(device, 12, &atacmd, 0, 2048L, ATA_DATA_IN, &buffer);
     258        else
     259            error = ata_cmd_packet(device, 12, &atacmd, 0, 2048L, ATA_DATA_IN, &buffer);
    231260        if (!error)
    232261            break;
     
    235264        return 3;
    236265
    237     // Validity checks
    238     if(buffer[0]!=0)
     266    /* Check for a valid BRVD. */
     267    if (buffer[0] != 0)
    239268        return 4;
    240     for(i=0;i<5;i++){
    241         if(buffer[1+i] != isotag[i])
     269    //@todo: what's wrong with memcmp()?
     270    for (i = 0; i < 5; ++i) {
     271        if (buffer[1+i] != isotag[i])
    242272            return 5;
    243273    }
    244     for(i=0;i<23;i++)
    245         if(buffer[7+i] != eltorito[i])
     274    for (i = 0; i < 23; ++i)
     275        if (buffer[7+i] != eltorito[i])
    246276            return 6;
    247277
    248278    //@todo: this swaps the LBA back and forth for no good reason??!
    249279    // ok, now we calculate the Boot catalog address
    250     lba=buffer[0x4A]*0x1000000UL+buffer[0x49]*0x10000UL+buffer[0x48]*0x100UL+buffer[0x47];
     280    lba = buffer[0x4A]*0x1000000UL + buffer[0x49]*0x10000UL + buffer[0x48]*0x100UL + buffer[0x47];
    251281    BX_DEBUG_ELTORITO("BRVD at LBA %lx\n", lba);
    252282
    253     // And we read the Boot Catalog
     283    /* Now we read the Boot Catalog. */
    254284    _fmemset(&atacmd,0,12);
    255     atacmd[0]=0x28;                      // READ command
    256     atacmd[7]=(0x01 & 0xff00) >> 8;      // Sectors
    257     atacmd[8]=(0x01 & 0x00ff);           // Sectors
    258     atacmd[2]=(lba & 0xff000000) >> 24;  // LBA
    259     atacmd[3]=(lba & 0x00ff0000) >> 16;
    260     atacmd[4]=(lba & 0x0000ff00) >> 8;
    261     atacmd[5]=(lba & 0x000000ff);
    262     if((error = ata_cmd_packet(device, 12, &atacmd, 0, 2048L, ATA_DATA_IN, &buffer)) != 0)
     285    //@todo: use some sane byte swapping routines here
     286    atacmd[0] = 0x28;                       // READ command
     287    atacmd[7] = (0x01 & 0xff00) >> 8;       // Sectors
     288    atacmd[8] = (0x01 & 0x00ff);            // Sectors
     289    atacmd[2] = (lba & 0xff000000) >> 24;   // LBA
     290    atacmd[3] = (lba & 0x00ff0000) >> 16;
     291    atacmd[4] = (lba & 0x0000ff00) >> 8;
     292    atacmd[5] = (lba & 0x000000ff);
     293
     294    if (device > BX_MAX_ATA_DEVICES)
     295        error = ahci_cmd_packet(device, 12, &atacmd, 0, 2048L, ATA_DATA_IN, &buffer);
     296    else
     297        error = ata_cmd_packet(device, 12, &atacmd, 0, 2048L, ATA_DATA_IN, &buffer);
     298
     299    if (error != 0)
    263300        return 7;
    264301   
    265     // Validation entry
    266     if(buffer[0x00]!=0x01)
     302    /* Check if the Boot Catalog looks valid. */
     303    if (buffer[0x00] != 0x01)
    267304        return 8;   // Header
    268     if(buffer[0x01]!=0x00)
     305    if (buffer[0x01] != 0x00)
    269306        return 9;   // Platform
    270     if(buffer[0x1E]!=0x55)
     307    if (buffer[0x1E] != 0x55)
    271308        return 10;  // key 1
    272     if(buffer[0x1F]!=0xAA)
     309    if (buffer[0x1F] != 0xAA)
    273310        return 10;  // key 2
    274311   
    275312    // Initial/Default Entry
    276     if(buffer[0x20]!=0x88)
     313    if (buffer[0x20] != 0x88)
    277314        return 11; // Bootable
    278315
    279316    BX_DEBUG_ELTORITO("Emulate drive %x\n", buffer[0x21]);
    280317    cdemu->media = buffer[0x21];
    281     if(buffer[0x21]==0){
     318    if (buffer[0x21] == 0) {
    282319        // FIXME ElTorito Hardcoded. cdrom is hardcoded as device 0xE0.
    283320        // Win2000 cd boot needs to know it booted from cd
    284321        cdemu->emulated_drive = 0xE0;
    285322    }
    286     else if(buffer[0x21]<4)
     323    else if (buffer[0x21] < 4)
    287324        cdemu->emulated_drive = 0x00;
    288325    else
     
    305342    cdemu->ilba = lba;
    306343   
    307     // And we read the image in memory
    308     _fmemset(&atacmd,0,12);
    309     atacmd[0]=0x28;                      // READ command
    310     atacmd[7]=((1+(nbsectors-1)/4) & 0xff00) >> 8;      // Sectors
    311     atacmd[8]=((1+(nbsectors-1)/4) & 0x00ff);           // Sectors
    312     atacmd[2]=(lba & 0xff000000) >> 24;  // LBA
    313     atacmd[3]=(lba & 0x00ff0000) >> 16;
    314     atacmd[4]=(lba & 0x0000ff00) >> 8;
    315     atacmd[5]=(lba & 0x000000ff);
    316     if((error = ata_cmd_packet(device, 12, &atacmd, 0, nbsectors*512L, ATA_DATA_IN, MK_FP(boot_segment,0))) != 0)
     344    /* Read the image into memory. */
     345    _fmemset(&atacmd, 0, 12);
     346    atacmd[0] = 0x28;                               // READ command
     347    atacmd[7] = ((1+(nbsectors-1)/4) & 0xff00) >> 8;// Sectors
     348    atacmd[8] = ((1+(nbsectors-1)/4) & 0x00ff);     // Sectors
     349    atacmd[2] = (lba & 0xff000000) >> 24;           // LBA
     350    atacmd[3] = (lba & 0x00ff0000) >> 16;
     351    atacmd[4] = (lba & 0x0000ff00) >> 8;
     352    atacmd[5] = (lba & 0x000000ff);
     353
     354    if (device > BX_MAX_ATA_DEVICES)
     355        error = ahci_cmd_packet(device, 12, &atacmd, 0, nbsectors*512L, ATA_DATA_IN, MK_FP(boot_segment,0));
     356    else
     357        error = ata_cmd_packet(device, 12, &atacmd, 0, nbsectors*512L, ATA_DATA_IN, MK_FP(boot_segment,0));
     358    if (error != 0)
    317359        return 12;
    318360   
    319361    // Remember the media type
    320     switch(cdemu->media) {
     362    switch (cdemu->media) {
    321363    case 0x01:  // 1.2M floppy
    322364        cdemu->vdevice.spt       = 15;
     
    341383    }
    342384   
    343     if(cdemu->media != 0) {
    344         // Increase bios installed hardware number of devices
    345         if(cdemu->emulated_drive == 0x00)
     385    if (cdemu->media != 0) {
     386        /* Increase BIOS installed number of drives (floppy or fixed). */
     387        if (cdemu->emulated_drive == 0x00)
    346388            write_byte(0x40,0x10,read_byte(0x40,0x10)|0x41);
    347389        else
     
    351393   
    352394    // everything is ok, so from now on, the emulation is active
    353     if(cdemu->media !=0 )
     395    if (cdemu->media !=0 )
    354396        cdemu->active = 0x01;
    355397   
     
    391433   
    392434    /* basic checks : emulation should be active, dl should equal the emulated drive */
    393     if( (cdemu->active ==0 )
    394       || (cdemu->emulated_drive != GET_DL())) {
     435    if (!cdemu->active || (cdemu->emulated_drive != GET_DL())) {
    395436        BX_INFO("%s: function %02x, emulation not active for DL= %02x\n", __func__, GET_AH(), GET_DL());
    396437        goto int13_fail;
     
    475516        elba = (uint32_t)(vlba+nbsectors-1)/4;
    476517       
    477         _fmemset(&atacmd,0,12);
    478         atacmd[0]=0x28;                      // READ command
    479         atacmd[7]=((uint16_t)(elba-slba+1) & 0xff00) >> 8; // Sectors
    480         atacmd[8]=((uint16_t)(elba-slba+1) & 0x00ff);      // Sectors
    481         atacmd[2]=(ilba+slba & 0xff000000) >> 24;  // LBA
    482         atacmd[3]=(ilba+slba & 0x00ff0000) >> 16;
    483         atacmd[4]=(ilba+slba & 0x0000ff00) >> 8;
    484         atacmd[5]=(ilba+slba & 0x000000ff);
    485         if((status = ata_cmd_packet(device, 12, &atacmd, before*512, nbsectors*512L, ATA_DATA_IN, MK_FP(segment,offset))) != 0) {
     518        _fmemset(&atacmd, 0, 12);
     519        //@todo: use some sane byte swapping routines here
     520        atacmd[0] = 0x28;                                   // READ command
     521        atacmd[7] = ((uint16_t)(elba-slba+1) & 0xff00) >> 8;// Sectors
     522        atacmd[8] = ((uint16_t)(elba-slba+1) & 0x00ff);     // Sectors
     523        atacmd[2] = (ilba+slba & 0xff000000) >> 24;         // LBA
     524        atacmd[3] = (ilba+slba & 0x00ff0000) >> 16;
     525        atacmd[4] = (ilba+slba & 0x0000ff00) >> 8;
     526        atacmd[5] = (ilba+slba & 0x000000ff);
     527
     528        if (device > BX_MAX_ATA_DEVICES)
     529            status = ahci_cmd_packet(device, 12, &atacmd, before*512, nbsectors*512L, ATA_DATA_IN, MK_FP(segment,offset));
     530        else
     531            status = ata_cmd_packet(device, 12, &atacmd, before*512, nbsectors*512L, ATA_DATA_IN, MK_FP(segment,offset));
     532
     533        if (status != 0) {
    486534            BX_INFO("%s: function %02x, error %02x !\n", __func__, GET_AH(), status);
    487535            SET_AH(0x02);
     
    506554                          // FIXME ElTorito Harddisk. should send the HD count
    507555
    508         switch(cdemu->media) {
     556        switch (cdemu->media) {
    509557        case 0x01: SET_BL( 0x02 ); break;
    510558        case 0x02: SET_BL( 0x04 ); break;
     
    572620    uint32_t        lba;
    573621    uint16_t        count, segment, offset, size;
    574     bio_dsk_t __far *ata;
    575 
    576     ata = ebda_seg :> &EbdaData->bdisk;
     622    bio_dsk_t __far *bios_dsk;
     623
     624    bios_dsk = ebda_seg :> &EbdaData->bdisk;
    577625
    578626   
     
    582630   
    583631    /* basic check : device should be 0xE0+ */
    584     if( (GET_ELDL() < 0xE0) || (GET_ELDL() >= 0xE0+BX_MAX_ATA_DEVICES) ) {
     632    if( (GET_ELDL() < 0xE0) || (GET_ELDL() >= 0xE0 + BX_MAX_STORAGE_DEVICES) ) {
    585633        BX_DEBUG("%s: function %02x, ELDL out of range %02x\n", __func__, GET_AH(), GET_ELDL());
    586634        goto int13_fail;
     
    588636   
    589637    // Get the ata channel
    590     device = ata->cdidmap[GET_ELDL()-0xE0];
     638    device = bios_dsk->cdidmap[GET_ELDL()-0xE0];
    591639   
    592640    /* basic check : device has to be valid  */
    593     if (device >= BX_MAX_ATA_DEVICES) {
     641    if (device >= BX_MAX_STORAGE_DEVICES) {
    594642        BX_DEBUG("%s: function %02x, unmapped device for ELDL=%02x\n", __func__, GET_AH(), GET_ELDL());
    595643        goto int13_fail;
    596644    }
    597645
    598   switch (GET_AH()) {
     646    switch (GET_AH()) {
    599647
    600648    // all those functions return SUCCESS
     
    607655    case 0x14: /* controller internal diagnostic */
    608656    case 0x16: /* detect disk change */
    609       goto int13_success;
    610       break;
     657        goto int13_success;
     658        break;
    611659
    612660    // all those functions return disk write-protected
     
    614662    case 0x05: /* format disk track */
    615663    case 0x43: // IBM/MS extended write
    616       SET_AH(0x03);
    617       goto int13_fail_noah;
    618       break;
     664        SET_AH(0x03);
     665        goto int13_fail_noah;
     666        break;
    619667
    620668    case 0x01: /* read disk status */
    621       status = read_byte(0x0040, 0x0074);
    622       SET_AH(status);
    623       SET_DISK_RET_STATUS(0);
    624 
    625       /* set CF if error status read */
    626       if (status) goto int13_fail_nostatus;
    627       else        goto int13_success_noah;
    628       break;
     669        status = read_byte(0x0040, 0x0074);
     670        SET_AH(status);
     671        SET_DISK_RET_STATUS(0);
     672
     673        /* set CF if error status read */
     674        if (status)
     675            goto int13_fail_nostatus;
     676        else
     677            goto int13_success_noah;
     678        break;
    629679
    630680    case 0x15: /* read disk drive size */
    631       SET_AH(0x02);
    632       goto int13_fail_noah;
    633       break;
     681        SET_AH(0x02);
     682        goto int13_fail_noah;
     683        break;
    634684
    635685    case 0x41: // IBM/MS installation check
    636       BX=0xaa55;     // install check
    637       SET_AH(0x30);  // EDD 2.1
    638       CX=0x0007;     // ext disk access, removable and edd
    639       goto int13_success_noah;
    640       break;
     686        BX = 0xaa55;    // install check
     687        SET_AH(0x30);   // EDD 2.1
     688        CX = 0x0007;    // ext disk access, removable and edd
     689        goto int13_success_noah;
     690        break;
    641691
    642692    case 0x42: // IBM/MS extended read
     
    644694    case 0x47: // IBM/MS extended seek
    645695
    646       count=read_word(DS, SI+(uint16_t)&Int13Ext->count);
    647       segment=read_word(DS, SI+(uint16_t)&Int13Ext->segment);
    648       offset=read_word(DS, SI+(uint16_t)&Int13Ext->offset);
    649 
    650       // Can't use 64 bits lba
    651       lba=read_dword(DS, SI+(uint16_t)&Int13Ext->lba2);
    652       if (lba != 0L) {
    653         BX_PANIC("%s: function %02x. Can't use 64bits lba\n", __func__,GET_AH());
    654         goto int13_fail;
    655         }
    656 
    657       // Get 32 bits lba
    658       lba=read_dword(DS, SI+(uint16_t)&Int13Ext->lba1);
    659 
    660       // If verify or seek
    661       if (( GET_AH() == 0x44 ) || ( GET_AH() == 0x47 ))
     696        count   = read_word(DS, SI+(uint16_t)&Int13Ext->count);
     697        segment = read_word(DS, SI+(uint16_t)&Int13Ext->segment);
     698        offset  = read_word(DS, SI+(uint16_t)&Int13Ext->offset);
     699
     700        // Can't use 64 bits lba
     701        lba = read_dword(DS, SI+(uint16_t)&Int13Ext->lba2);
     702        if (lba != 0L) {
     703            BX_PANIC("%s: function %02x. Can't use 64bits lba\n", __func__, GET_AH());
     704            goto int13_fail;
     705        }
     706
     707        // Get 32 bits lba
     708        lba = read_dword(DS, SI+(uint16_t)&Int13Ext->lba1);
     709
     710        // If verify or seek
     711        if (( GET_AH() == 0x44 ) || ( GET_AH() == 0x47 ))
     712            goto int13_success;
     713
     714        BX_INFO("%s: read %u sectors @ LBA %lu to %04X:%04X\n",
     715                __func__, count, lba, segment, offset);
     716
     717        _fmemset(&atacmd, 0, 12);
     718        //@todo: use some sane byte swapping routines here
     719        atacmd[0] = 0x28;                     // READ command
     720        atacmd[7] = (count & 0xff00) >> 8;    // Sectors
     721        atacmd[8] = (count & 0x00ff);         // Sectors
     722        atacmd[2] = (lba & 0xff000000) >> 24; // LBA
     723        atacmd[3] = (lba & 0x00ff0000) >> 16;
     724        atacmd[4] = (lba & 0x0000ff00) >> 8;
     725        atacmd[5] = (lba & 0x000000ff);
     726
     727        if (device > BX_MAX_ATA_DEVICES)
     728            status = ahci_cmd_packet(device, 12, &atacmd, 0, count*2048L, ATA_DATA_IN, MK_FP(segment,offset));
     729        else
     730            status = ata_cmd_packet(device, 12, &atacmd, 0, count*2048L, ATA_DATA_IN, MK_FP(segment,offset));
     731
     732        count = (uint16_t)(bios_dsk->drqp.trsfbytes >> 11);
     733        write_word(DS, SI+(uint16_t)&Int13Ext->count, count);
     734
     735        if (status != 0) {
     736            BX_INFO("%s: function %02x, status %02x !\n", __func__, GET_AH(), status);
     737            SET_AH(0x0c);
     738            goto int13_fail_noah;
     739        }
     740
    662741        goto int13_success;
    663 
    664       _fmemset(&atacmd,0,12);
    665       atacmd[0]=0x28;                      // READ command
    666       atacmd[7]=(count & 0xff00) >> 8;     // Sectors
    667       atacmd[8]=(count & 0x00ff);          // Sectors
    668       atacmd[2]=(lba & 0xff000000) >> 24;  // LBA
    669       atacmd[3]=(lba & 0x00ff0000) >> 16;
    670       atacmd[4]=(lba & 0x0000ff00) >> 8;
    671       atacmd[5]=(lba & 0x000000ff);
    672       status = ata_cmd_packet(device, 12, &atacmd, 0, count*2048L, ATA_DATA_IN, MK_FP(segment,offset));
    673 
    674       count = (uint16_t)(ata->drqp.trsfbytes >> 11);
    675       write_word(DS, SI+(uint16_t)&Int13Ext->count, count);
    676 
    677       if (status != 0) {
    678         BX_INFO("%s: function %02x, status %02x !\n", __func__, GET_AH(), status);
    679         SET_AH(0x0c);
    680         goto int13_fail_noah;
    681         }
    682 
    683       goto int13_success;
    684       break;
     742        break;
    685743
    686744    case 0x45: // IBM/MS lock/unlock drive
    687       if (GET_AL() > 2) goto int13_fail;
    688 
    689       locks = ata->devices[device].lock;
    690 
    691       switch (GET_AL()) {
     745        if (GET_AL() > 2)
     746            goto int13_fail;
     747
     748        locks = bios_dsk->devices[device].lock;
     749
     750        switch (GET_AL()) {
    692751        case 0 :  // lock
    693           if (locks == 0xff) {
    694             SET_AH(0xb4);
     752            if (locks == 0xff) {
     753                SET_AH(0xb4);
     754                SET_AL(1);
     755                goto int13_fail_noah;
     756            }
     757            bios_dsk->devices[device].lock = ++locks;
    695758            SET_AL(1);
     759            break;
     760        case 1 :  // unlock
     761            if (locks == 0x00) {
     762                SET_AH(0xb0);
     763                SET_AL(0);
     764                goto int13_fail_noah;
     765            }
     766            bios_dsk->devices[device].lock = --locks;
     767            SET_AL(locks==0?0:1);
     768            break;
     769        case 2 :  // status
     770            SET_AL(locks==0?0:1);
     771            break;
     772        }
     773        goto int13_success;
     774        break;
     775
     776    case 0x46: // IBM/MS eject media
     777        locks = bios_dsk->devices[device].lock;
     778
     779        if (locks != 0) {
     780            SET_AH(0xb1); // media locked
    696781            goto int13_fail_noah;
    697             }
    698           ata->devices[device].lock = ++locks;
    699           SET_AL(1);
    700           break;
    701         case 1 :  // unlock
    702           if (locks == 0x00) {
    703             SET_AH(0xb0);
    704             SET_AL(0);
    705             goto int13_fail_noah;
    706             }
    707           ata->devices[device].lock = --locks;
    708           SET_AL(locks==0?0:1);
    709           break;
    710         case 2 :  // status
    711           SET_AL(locks==0?0:1);
    712           break;
    713         }
    714       goto int13_success;
    715       break;
    716 
    717     case 0x46: // IBM/MS eject media
    718       locks = ata->devices[device].lock;
    719 
    720       if (locks != 0) {
    721         SET_AH(0xb1); // media locked
    722         goto int13_fail_noah;
    723         }
    724       // FIXME should handle 0x31 no media in device
    725       // FIXME should handle 0xb5 valid request failed
     782        }
     783        // FIXME should handle 0x31 no media in device
     784        // FIXME should handle 0xb5 valid request failed
    726785
    727786#if 0 //@todo: implement!
    728       // Call removable media eject
    729       ASM_START
     787        // Call removable media eject
     788        ASM_START
    730789        push bp
    731790        mov  bp, sp
     
    738797int13_cdrom_rme_end:
    739798        pop bp
    740       ASM_END
     799        ASM_END
    741800#endif
    742801
    743       if (status != 0) {
    744         SET_AH(0xb1); // media locked
    745         goto int13_fail_noah;
    746       }
    747 
    748       goto int13_success;
    749       break;
     802        if (status != 0) {
     803            SET_AH(0xb1); // media locked
     804            goto int13_fail_noah;
     805        }
     806
     807        goto int13_success;
     808        break;
    750809
    751810    case 0x48: // IBM/MS get drive parameters
    752       size = read_word(DS,SI+(uint16_t)&Int13Ext->size);
    753 
    754       // Buffer is too small
    755       if(size < 0x1a)
    756         goto int13_fail;
    757 
    758       // EDD 1.x
    759       if(size >= 0x1a) {
    760         uint16_t   blksize;
    761 
    762         blksize   = ata->devices[device].blksize;
    763 
    764         write_word(DS, SI+(uint16_t)&Int13DPT->size, 0x1a);
    765         write_word(DS, SI+(uint16_t)&Int13DPT->infos, 0x74); // removable, media change, lockable, max values
    766         write_dword(DS, SI+(uint16_t)&Int13DPT->cylinders, 0xffffffff);
    767         write_dword(DS, SI+(uint16_t)&Int13DPT->heads, 0xffffffff);
    768         write_dword(DS, SI+(uint16_t)&Int13DPT->spt, 0xffffffff);
    769         write_dword(DS, SI+(uint16_t)&Int13DPT->sector_count1, 0xffffffff);  // FIXME should be Bit64
    770         write_dword(DS, SI+(uint16_t)&Int13DPT->sector_count2, 0xffffffff);
    771         write_word(DS, SI+(uint16_t)&Int13DPT->blksize, blksize);
    772         }
    773 
    774       // EDD 2.x
    775       if(size >= 0x1e) {
    776         uint8_t  channel, irq, mode, checksum, i;
    777         uint16_t iobase1, iobase2, options;
    778 
    779         write_word(DS, SI+(uint16_t)&Int13DPT->size, 0x1e);
    780 
    781         write_word(DS, SI+(uint16_t)&Int13DPT->dpte_segment, ebda_seg);
    782         write_word(DS, SI+(uint16_t)&Int13DPT->dpte_offset, (uint16_t)&EbdaData->bdisk.dpte);
    783 
    784         // Fill in dpte
    785         channel = device / 2;
    786         iobase1 = ata->channels[channel].iobase1;
    787         iobase2 = ata->channels[channel].iobase2;
    788         irq     = ata->channels[channel].irq;
    789         mode    = ata->devices[device].mode;
    790 
    791         // FIXME atapi device
    792         options  = (1<<4); // lba translation
    793         options |= (1<<5); // removable device
    794         options |= (1<<6); // atapi device
    795         options |= (mode==ATA_MODE_PIO32?1:0<<7);
    796 
    797         ata->dpte.iobase1   = iobase1;
    798         ata->dpte.iobase2   = iobase2;
    799         ata->dpte.prefix    = (0xe | (device % 2))<<4;
    800         ata->dpte.unused    = 0xcb;
    801         ata->dpte.irq       = irq;
    802         ata->dpte.blkcount  = 1 ;
    803         ata->dpte.dma       = 0;
    804         ata->dpte.pio       = 0;
    805         ata->dpte.options   = options;
    806         ata->dpte.reserved  = 0;
    807         ata->dpte.revision  = 0x11;
    808 
    809         checksum=0;
    810         for (i=0; i<15; i++)
    811             checksum += read_byte(ebda_seg, (uint16_t)&EbdaData->bdisk.dpte + i);
    812         checksum = -checksum;
    813         ata->dpte.checksum = checksum;
    814         }
    815 
    816       // EDD 3.x
    817       if(size >= 0x42) {
    818         uint8_t  channel, iface, checksum, i;
    819         uint16_t iobase1;
    820 
    821         channel = device / 2;
    822         iface   = ata->channels[channel].iface;
    823         iobase1 = ata->channels[channel].iobase1;
    824 
    825         write_word(DS, SI+(uint16_t)&Int13DPT->size, 0x42);
    826         write_word(DS, SI+(uint16_t)&Int13DPT->key, 0xbedd);
    827         write_byte(DS, SI+(uint16_t)&Int13DPT->dpi_length, 0x24);
    828         write_byte(DS, SI+(uint16_t)&Int13DPT->reserved1, 0);
    829         write_word(DS, SI+(uint16_t)&Int13DPT->reserved2, 0);
    830 
    831         if (iface==ATA_IFACE_ISA) {
    832           write_byte(DS, SI+(uint16_t)&Int13DPT->host_bus[0], 'I');
    833           write_byte(DS, SI+(uint16_t)&Int13DPT->host_bus[1], 'S');
    834           write_byte(DS, SI+(uint16_t)&Int13DPT->host_bus[2], 'A');
    835           write_byte(DS, SI+(uint16_t)&Int13DPT->host_bus[3], 0);
    836           }
    837         else {
    838           // FIXME PCI
    839           }
    840         write_byte(DS, SI+(uint16_t)&Int13DPT->iface_type[0], 'A');
    841         write_byte(DS, SI+(uint16_t)&Int13DPT->iface_type[1], 'T');
    842         write_byte(DS, SI+(uint16_t)&Int13DPT->iface_type[2], 'A');
    843         write_byte(DS, SI+(uint16_t)&Int13DPT->iface_type[3], 0);
    844 
    845         if (iface==ATA_IFACE_ISA) {
    846           write_word(DS, SI+(uint16_t)&Int13DPT->iface_path[0], iobase1);
    847           write_word(DS, SI+(uint16_t)&Int13DPT->iface_path[2], 0);
    848           write_dword(DS, SI+(uint16_t)&Int13DPT->iface_path[4], 0L);
    849           }
    850         else {
    851           // FIXME PCI
    852           }
    853         write_byte(DS, SI+(uint16_t)&Int13DPT->device_path[0], device%2);
    854         write_byte(DS, SI+(uint16_t)&Int13DPT->device_path[1], 0);
    855         write_word(DS, SI+(uint16_t)&Int13DPT->device_path[2], 0);
    856         write_dword(DS, SI+(uint16_t)&Int13DPT->device_path[4], 0L);
    857 
    858         checksum=0;
    859         for (i=30; i<64; i++) checksum+=read_byte(DS, SI + i);
    860         checksum = -checksum;
    861         write_byte(DS, SI+(uint16_t)&Int13DPT->checksum, checksum);
    862         }
    863 
    864       goto int13_success;
    865       break;
     811        size = read_word(DS,SI+(uint16_t)&Int13Ext->size);
     812
     813        // Buffer is too small
     814        if(size < 0x1a)
     815            goto int13_fail;
     816
     817        // EDD 1.x
     818        if(size >= 0x1a) {
     819            uint16_t   blksize;
     820
     821            blksize   = bios_dsk->devices[device].blksize;
     822
     823            write_word(DS, SI+(uint16_t)&Int13DPT->size, 0x1a);
     824            write_word(DS, SI+(uint16_t)&Int13DPT->infos, 0x74); // removable, media change, lockable, max values
     825            write_dword(DS, SI+(uint16_t)&Int13DPT->cylinders, 0xffffffff);
     826            write_dword(DS, SI+(uint16_t)&Int13DPT->heads, 0xffffffff);
     827            write_dword(DS, SI+(uint16_t)&Int13DPT->spt, 0xffffffff);
     828            write_dword(DS, SI+(uint16_t)&Int13DPT->sector_count1, 0xffffffff);  // FIXME should be Bit64
     829            write_dword(DS, SI+(uint16_t)&Int13DPT->sector_count2, 0xffffffff);
     830            write_word(DS, SI+(uint16_t)&Int13DPT->blksize, blksize);
     831        }
     832
     833        // EDD 2.x
     834        if(size >= 0x1e) {
     835            uint8_t  channel, irq, mode, checksum, i;
     836            uint16_t iobase1, iobase2, options;
     837
     838            write_word(DS, SI+(uint16_t)&Int13DPT->size, 0x1e);
     839
     840            write_word(DS, SI+(uint16_t)&Int13DPT->dpte_segment, ebda_seg);
     841            write_word(DS, SI+(uint16_t)&Int13DPT->dpte_offset, (uint16_t)&EbdaData->bdisk.dpte);
     842
     843            // Fill in dpte
     844            channel = device / 2;
     845            iobase1 = bios_dsk->channels[channel].iobase1;
     846            iobase2 = bios_dsk->channels[channel].iobase2;
     847            irq     = bios_dsk->channels[channel].irq;
     848            mode    = bios_dsk->devices[device].mode;
     849
     850            // FIXME atapi device
     851            options  = (1<<4); // lba translation
     852            options |= (1<<5); // removable device
     853            options |= (1<<6); // atapi device
     854            options |= (mode==ATA_MODE_PIO32?1:0<<7);
     855
     856            bios_dsk->dpte.iobase1   = iobase1;
     857            bios_dsk->dpte.iobase2   = iobase2;
     858            bios_dsk->dpte.prefix    = (0xe | (device % 2))<<4;
     859            bios_dsk->dpte.unused    = 0xcb;
     860            bios_dsk->dpte.irq       = irq;
     861            bios_dsk->dpte.blkcount  = 1 ;
     862            bios_dsk->dpte.dma       = 0;
     863            bios_dsk->dpte.pio       = 0;
     864            bios_dsk->dpte.options   = options;
     865            bios_dsk->dpte.reserved  = 0;
     866            bios_dsk->dpte.revision  = 0x11;
     867
     868            checksum = 0;
     869            for (i=0; i<15; i++)
     870                checksum += read_byte(ebda_seg, (uint16_t)&EbdaData->bdisk.dpte + i);
     871            checksum = -checksum;
     872            bios_dsk->dpte.checksum = checksum;
     873        }
     874
     875        // EDD 3.x
     876        if(size >= 0x42) {
     877            uint8_t  channel, iface, checksum, i;
     878            uint16_t iobase1;
     879
     880            channel = device / 2;
     881            iface   = bios_dsk->channels[channel].iface;
     882            iobase1 = bios_dsk->channels[channel].iobase1;
     883
     884            write_word(DS, SI+(uint16_t)&Int13DPT->size, 0x42);
     885            write_word(DS, SI+(uint16_t)&Int13DPT->key, 0xbedd);
     886            write_byte(DS, SI+(uint16_t)&Int13DPT->dpi_length, 0x24);
     887            write_byte(DS, SI+(uint16_t)&Int13DPT->reserved1, 0);
     888            write_word(DS, SI+(uint16_t)&Int13DPT->reserved2, 0);
     889
     890            if (iface == ATA_IFACE_ISA) {
     891                write_byte(DS, SI+(uint16_t)&Int13DPT->host_bus[0], 'I');
     892                write_byte(DS, SI+(uint16_t)&Int13DPT->host_bus[1], 'S');
     893                write_byte(DS, SI+(uint16_t)&Int13DPT->host_bus[2], 'A');
     894                write_byte(DS, SI+(uint16_t)&Int13DPT->host_bus[3], 0);
     895            }
     896            else {
     897                // FIXME PCI
     898            }
     899            write_byte(DS, SI+(uint16_t)&Int13DPT->iface_type[0], 'A');
     900            write_byte(DS, SI+(uint16_t)&Int13DPT->iface_type[1], 'T');
     901            write_byte(DS, SI+(uint16_t)&Int13DPT->iface_type[2], 'A');
     902            write_byte(DS, SI+(uint16_t)&Int13DPT->iface_type[3], 0);
     903
     904            if (iface==ATA_IFACE_ISA) {
     905                write_word(DS, SI+(uint16_t)&Int13DPT->iface_path[0], iobase1);
     906                write_word(DS, SI+(uint16_t)&Int13DPT->iface_path[2], 0);
     907                write_dword(DS, SI+(uint16_t)&Int13DPT->iface_path[4], 0L);
     908            }
     909            else {
     910                // FIXME PCI
     911            }
     912            write_byte(DS, SI+(uint16_t)&Int13DPT->device_path[0], device%2);
     913            write_byte(DS, SI+(uint16_t)&Int13DPT->device_path[1], 0);
     914            write_word(DS, SI+(uint16_t)&Int13DPT->device_path[2], 0);
     915            write_dword(DS, SI+(uint16_t)&Int13DPT->device_path[4], 0L);
     916
     917            checksum = 0;
     918            for (i=30; i<64; i++)
     919                checksum+=read_byte(DS, SI + i);
     920            checksum = -checksum;
     921            write_byte(DS, SI+(uint16_t)&Int13DPT->checksum, checksum);
     922        }
     923
     924        goto int13_success;
     925        break;
    866926
    867927    case 0x49: // IBM/MS extended media change
    868       // always send changed ??
    869       SET_AH(06);
    870       goto int13_fail_nostatus;
    871       break;
     928        // always send changed ??
     929        SET_AH(06);
     930        goto int13_fail_nostatus;
     931        break;
    872932
    873933    case 0x4e: // // IBM/MS set hardware configuration
    874       // DMA, prefetch, PIO maximum not supported
    875       switch (GET_AL()) {
     934        // DMA, prefetch, PIO maximum not supported
     935        switch (GET_AL()) {
    876936        case 0x01:
    877937        case 0x03:
    878938        case 0x04:
    879939        case 0x06:
    880           goto int13_success;
    881           break;
     940            goto int13_success;
     941            break;
    882942        default :
    883           goto int13_fail;
    884         }
    885       break;
     943            goto int13_fail;
     944        }
     945        break;
    886946
    887947    // all those functions return unimplemented
     
    894954    case 0x50: // ? - send packet command
    895955    default:
    896       BX_INFO("%s: unsupported AH=%02x\n", __func__, GET_AH());
    897       goto int13_fail;
    898       break;
     956        BX_INFO("%s: unsupported AH=%02x\n", __func__, GET_AH());
     957        goto int13_fail;
     958        break;
    899959    }
    900960
Note: See TracChangeset for help on using the changeset viewer.

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