VirtualBox

Ignore:
Timestamp:
Nov 18, 2011 4:50:34 PM (13 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
74968
Message:

Refactored AHCI code to get rid of custom INT 13h handler.

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

Legend:

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

    r39366 r39372  
    1515 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
    1616 */
    17 /**
    18  * Parts are based on the int13_harddisk code in rombios.c
    19  */
    2017
    2118//@todo!!!! save/restore high bits of EAX/ECX and whatever else may be needed.
     
    3027
    3128#define VBOX_AHCI_DEBUG         1
    32 #define VBOX_AHCI_INT13_DEBUG   0
    3329
    3430#if VBOX_AHCI_DEBUG
     
    3834#endif
    3935
    40 #if VBOX_AHCI_INT13_DEBUG
    41 # define VBOXAHCI_INT13_DEBUG(...)  BX_INFO(__VA_ARGS__)
    42 #else
    43 # define VBOXAHCI_INT13_DEBUG(...)
    44 #endif
    45 
    46 #define AHCI_MAX_STORAGE_DEVICES 4
    47 
    4836/* Number of S/G table entries in EDDS. */
    4937#define NUM_EDDS_SG         16
    5038
    51 
    52 /**
    53  * AHCI device data.
    54  */
    55 typedef struct
    56 {
    57     uint8_t     type;         // Detected type of ata (ata/atapi/none/unknown/scsi)
    58     uint8_t     device;       // Detected type of attached devices (hd/cd/none)
    59     uint8_t     removable;    // Removable device flag
    60     uint8_t     lock;         // Locks for removable devices
    61     uint16_t    blksize;      // block size
    62     chs_t       lchs;         // Logical CHS
    63     chs_t       pchs;         // Physical CHS
    64     uint32_t    cSectors;     // Total sectors count
    65     uint8_t     port;         // Port this device is on.
    66 } ahci_device_t;
    6739
    6840/**
     
    10678    uint16_t        iobase;
    10779    /** Current port which uses the memory to communicate with the controller. */
    108     uint8_t         port;
    109     /** AHCI device information. */
    110     ahci_device_t   aDevices[AHCI_MAX_STORAGE_DEVICES];
    111     /** Index of the next unoccupied device slot. */
    112     uint8_t         cDevices;
    113     /** Map between (bios hd id - 0x80) and ahci devices. */
    114     uint8_t         cHardDisks;
    115     uint8_t         aHdIdMap[AHCI_MAX_STORAGE_DEVICES];
    116     /** Map between (bios cd id - 0xE0) and ahci_devices. */
    117     uint8_t         cCdDrives;
    118     uint8_t         aCdIdMap[AHCI_MAX_STORAGE_DEVICES];
    119     /** Number of harddisks detected before the AHCI driver started detection. */
    120     uint8_t         cHardDisksOld;
    121     /** int13 handler to call if given device is not from AHCI. */
    122     uint16_t        pfnInt13Old;
     80    uint8_t         cur_port;
    12381    /** VDS EDDS DMA buffer descriptor structure. */
    12482    vds_edds        edds;
     
    275233    ahci_t __far    *ahci = ahci_seg :> 0;
    276234
    277     u8Port = ahci->port;
     235    u8Port = ahci->cur_port;
    278236
    279237    if (u8Port != 0xff)
     
    376334    ahci_t __far    *ahci = ahci_seg :> 0;
    377335
    378     u8Port = ahci->port;
     336    u8Port = ahci->cur_port;
    379337
    380338    if (u8Port != 0xff)
     
    408366        VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_IE, 0);
    409367
    410         ahci->port = 0xff;
     368        ahci->cur_port = 0xff;
    411369    }
    412370}
     
    459417    VBOXAHCI_PORT_WRITE_REG(u16IoBase, u8Port, AHCI_REG_PORT_SERR, 0xffffffff);
    460418
    461     ahci->port = u8Port;
    462 }
    463 
    464 /**
    465  * Write data to the device.
    466  */
    467 static void ahci_cmd_data_out(uint16_t ahci_seg, uint16_t u16IoBase, uint8_t u8Port, uint8_t u8Cmd, uint32_t u32Lba, uint16_t u16Sectors, uint16_t SegData, uint16_t OffData)
    468 {
    469     uint8_t u8CylLow, u8CylHigh, u8Device, u8Sect, u8CylHighExp, u8CylLowExp, u8SectExp, u8SectCount, u8SectCountExp;
    470 
    471     u8SectCount = (uint8_t)(u16Sectors & 0xff);
    472     u8SectCountExp = (uint8_t)((u16Sectors >> 8) & 0xff);;
    473     u8Sect = (uint8_t)(u32Lba & 0xff);
    474     u8SectExp = (uint8_t)((u32Lba >> 24) & 0xff);
    475     u8CylLow = (uint8_t)((u32Lba >> 8) & 0xff);
     419    ahci->cur_port = u8Port;
     420}
     421
     422/**
     423 * Read sectors from an attached AHCI device.
     424 *
     425 * @returns status code.
     426 * @param   bios_dsk    Pointer to disk request packet (in the
     427 *                      EBDA).
     428 */
     429int ahci_read_sectors(bio_dsk_t __far *bios_dsk)
     430{
     431    uint32_t        lba;
     432    void __far      *buffer;
     433    uint16_t        n_sect;
     434    uint16_t        ahci_seg;
     435    uint16_t        io_base;
     436    uint16_t        device_id;
     437    uint8_t         port;
     438    uint8_t         u8CylLow, u8CylHigh, u8Device, u8Sect, u8CylHighExp, u8CylLowExp, u8SectExp, u8SectCount, u8SectCountExp;
     439
     440    device_id = bios_dsk->drqp.dev_id - BX_MAX_ATA_DEVICES - BX_MAX_SCSI_DEVICES;
     441    if (device_id > BX_MAX_AHCI_DEVICES)
     442        BX_PANIC("ahci_read_sectors: device_id out of range %d\n", device_id);
     443
     444    ahci_seg = bios_dsk->ahci_seg;
     445    io_base  = read_word(ahci_seg, (uint16_t)&AhciData->iobase);
     446    port     = bios_dsk->ahcidev[device_id].port;
     447
     448    lba    = bios_dsk->drqp.lba;
     449    buffer = bios_dsk->drqp.buffer;
     450    n_sect = bios_dsk->drqp.nsect;
     451
     452    u8SectCount = (uint8_t)(n_sect & 0xff);
     453    u8SectCountExp = (uint8_t)((n_sect >> 8) & 0xff);
     454    u8Sect = (uint8_t)(lba & 0xff);
     455    u8SectExp = (uint8_t)((lba >> 24) & 0xff);
     456    u8CylLow = (uint8_t)((lba >> 8) & 0xff);
    476457    u8CylLowExp = 0;
    477     u8CylHigh = (uint8_t)((u32Lba >> 16) & 0xff);
     458    u8CylHigh = (uint8_t)((lba >> 16) & 0xff);
    478459    u8CylHighExp = 0;
     460
    479461    u8Device = (1 << 6); /* LBA access */
    480462
     463    ahci_port_init(ahci_seg, io_base, port);
     464    ahci_cmd_data(ahci_seg, io_base, AHCI_CMD_READ_DMA_EXT, 0, u8Device, u8CylHigh, u8CylLow,
     465                  u8Sect, 0, u8CylHighExp, u8CylLowExp, u8SectExp, u8SectCount,
     466                  u8SectCountExp, buffer, n_sect * 512, 0);
     467#ifdef DMA_WORKAROUND
     468    rep_movsw(buffer, buffer, n_sect * 512 / 2);
     469#endif
     470    return 0;   //@todo!!
     471}
     472
     473/**
     474 * Write sectors to an attached AHCI device.
     475 *
     476 * @returns status code.
     477 * @param   bios_dsk    Pointer to disk request packet (in the
     478 *                      EBDA).
     479 */
     480int ahci_write_sectors(bio_dsk_t __far *bios_dsk)
     481{
     482    uint32_t        lba;
     483    void __far      *buffer;
     484    uint16_t        n_sect;
     485    uint16_t        ahci_seg;
     486    uint16_t        io_base;
     487    uint16_t        device_id;
     488    uint8_t         port;
     489    uint8_t         u8CylLow, u8CylHigh, u8Device, u8Sect, u8CylHighExp, u8CylLowExp, u8SectExp, u8SectCount, u8SectCountExp;
     490
     491    device_id = bios_dsk->drqp.dev_id - BX_MAX_ATA_DEVICES - BX_MAX_SCSI_DEVICES;
     492    if (device_id > BX_MAX_AHCI_DEVICES)
     493        BX_PANIC("ahci_write_sectors: device_id out of range %d\n", device_id);
     494
     495    ahci_seg = bios_dsk->ahci_seg;
     496    io_base  = read_word(ahci_seg, (uint16_t)&AhciData->iobase);
     497    port     = bios_dsk->ahcidev[device_id].port;
     498
     499    lba    = bios_dsk->drqp.lba;
     500    buffer = bios_dsk->drqp.buffer;
     501    n_sect = bios_dsk->drqp.nsect;
     502
     503    u8SectCount = (uint8_t)(n_sect & 0xff);
     504    u8SectCountExp = (uint8_t)((n_sect >> 8) & 0xff);
     505    u8Sect = (uint8_t)(lba & 0xff);
     506    u8SectExp = (uint8_t)((lba >> 24) & 0xff);
     507    u8CylLow = (uint8_t)((lba >> 8) & 0xff);
     508    u8CylLowExp = 0;
     509    u8CylHigh = (uint8_t)((lba >> 16) & 0xff);
     510    u8CylHighExp = 0;
     511
     512    u8Device = (1 << 6); /* LBA access */
     513
     514    ahci_port_init(ahci_seg, io_base, port);
     515    ahci_cmd_data(ahci_seg, io_base, AHCI_CMD_WRITE_DMA_EXT, 0, u8Device, u8CylHigh, u8CylLow,
     516                  u8Sect, 0, u8CylHighExp, u8CylLowExp, u8SectExp, u8SectCount,
     517                  u8SectCountExp, buffer, n_sect * 512, 0);
     518    return 0;   //@todo!!
     519}
     520
     521static void ahci_port_detect_device(uint16_t ahci_seg, uint16_t u16IoBase, uint8_t u8Port)
     522{
     523    uint32_t            val;
     524    bio_dsk_t __far     *bios_dsk;
     525
    481526    ahci_port_init(ahci_seg, u16IoBase, u8Port);
    482     ahci_cmd_data(ahci_seg, u16IoBase, u8Cmd, 0, u8Device, u8CylHigh, u8CylLow,
    483                   u8Sect,0, u8CylHighExp, u8CylLowExp, u8SectExp, u8SectCount,
    484                   u8SectCountExp, SegData :> OffData, u16Sectors * 512, 1);
    485 }
    486 
    487 
    488 /**
    489  * Read data from the device.
    490  */
    491 static void ahci_cmd_data_in(uint16_t ahci_seg, uint16_t u16IoBase, uint8_t u8Port, uint8_t u8Cmd,
    492                              uint32_t u32Lba, uint16_t u16Sectors, uint16_t SegData, uint16_t OffData)
    493 {
    494     uint8_t     u8CylLow, u8CylHigh, u8Device, u8Sect, u8CylHighExp, u8CylLowExp, u8SectExp, u8SectCount, u8SectCountExp;
    495 
    496     u8SectCount = (uint8_t)(u16Sectors & 0xff);
    497     u8SectCountExp = (uint8_t)((u16Sectors >> 8) & 0xff);;
    498     u8Sect = (uint8_t)(u32Lba & 0xff);
    499     u8SectExp = (uint8_t)((u32Lba >> 24) & 0xff);
    500     u8CylLow = (uint8_t)((u32Lba >> 8) & 0xff);
    501     u8CylLowExp = 0;
    502     u8CylHigh = (uint8_t)((u32Lba >> 16) & 0xff);
    503     u8CylHighExp = 0;
    504 
    505     u8Device = (1 << 6); /* LBA access */
    506 
    507     ahci_port_init(ahci_seg, u16IoBase, u8Port);
    508     ahci_cmd_data(ahci_seg, u16IoBase, u8Cmd, 0, u8Device, u8CylHigh, u8CylLow,
    509                   u8Sect, 0, u8CylHighExp, u8CylLowExp, u8SectExp, u8SectCount,
    510                   u8SectCountExp, SegData :> OffData, u16Sectors * 512, 0);
    511 #ifdef DMA_WORKAROUND
    512     rep_movsw(SegData :> OffData, SegData :> OffData, u16Sectors * 512 / 2);
    513 #endif
    514 }
    515 
    516 static void ahci_port_detect_device(uint16_t ahci_seg, uint16_t u16IoBase, uint8_t u8Port)
    517 {
    518     uint32_t    val;
    519 
    520     ahci_port_init(ahci_seg, u16IoBase, u8Port);
     527
     528    bios_dsk = read_word(0x0040, 0x000E) :> &EbdaData->bdisk;
    521529
    522530    /* Reset connection. */
     
    532540    if (ahci_ctrl_extract_bits(val, 0xfL, 0) == 0x3L)
    533541    {
    534         uint8_t     idxDevice;
    535 
    536         idxDevice = read_byte(ahci_seg, (uint16_t)&AhciData->cDevices);
     542        uint8_t     hdcount, hdcount_ahci, hd_index;
     543
     544        hdcount_ahci = bios_dsk->ahci_hdcount;
     545
    537546        VBOXAHCI_DEBUG("AHCI: Device detected on port %d\n", u8Port);
    538547
    539         if (idxDevice < AHCI_MAX_STORAGE_DEVICES)
     548        if (hdcount_ahci < BX_MAX_AHCI_DEVICES)
    540549        {
    541550            /* Device detected, enable FIS receive. */
     
    547556            if (val == 0x101L)
    548557            {
    549                 uint8_t     idxHdCurr;
    550558                uint32_t    cSectors;
    551559                uint8_t     abBuffer[0x0200];
    552560                uint8_t     fRemovable;
    553561                uint16_t    cCylinders, cHeads, cSectorsPerTrack;
    554                 uint8_t     cHardDisksOld;
    555562                uint8_t     idxCmosChsBase;
    556563
    557                 idxHdCurr = read_byte(ahci_seg, (uint16_t)&AhciData->cHardDisks);
    558564                VBOXAHCI_DEBUG("AHCI: Detected hard disk\n");
    559565
     
    561567                ahci_cmd_data(ahci_seg, u16IoBase, ATA_CMD_IDENTIFY_DEVICE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &abBuffer, sizeof(abBuffer), 0);
    562568
    563                 write_byte(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].port, u8Port);
     569                /* Calculate index into the generic disk table. */
     570                hd_index = hdcount_ahci + BX_MAX_ATA_DEVICES + BX_MAX_SCSI_DEVICES;
    564571
    565572                fRemovable       = *(abBuffer+0) & 0x80 ? 1 : 0;
     
    575582                VBOXAHCI_DEBUG("AHCI: %ld sectors\n", cSectors);
    576583
    577                 write_byte(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].device,ATA_DEVICE_HD);
    578                 write_byte(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].removable, fRemovable);
    579                 write_word(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].blksize, 512);
    580                 write_word(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].pchs.heads, cHeads);
    581                 write_word(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].pchs.cylinders, cCylinders);
    582                 write_word(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].pchs.spt, cSectorsPerTrack);
    583                 write_dword(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].cSectors, cSectors);
     584                bios_dsk->ahcidev[hdcount_ahci].port = u8Port;
     585                bios_dsk->devices[hd_index].type        = ATA_TYPE_AHCI;
     586                bios_dsk->devices[hd_index].device      = ATA_DEVICE_HD;
     587                bios_dsk->devices[hd_index].removable   = fRemovable;
     588                bios_dsk->devices[hd_index].lock        = 0;
     589                bios_dsk->devices[hd_index].blksize     = 512;
     590                bios_dsk->devices[hd_index].translation = ATA_TRANSLATION_LBA;
     591                bios_dsk->devices[hd_index].sectors     = cSectors;
     592
     593                bios_dsk->devices[hd_index].pchs.heads     = cHeads;
     594                bios_dsk->devices[hd_index].pchs.cylinders = cCylinders;
     595                bios_dsk->devices[hd_index].pchs.spt       = cSectorsPerTrack;
    584596
    585597                /* Get logical CHS geometry. */
    586                 switch (idxDevice)
     598                switch (hdcount_ahci)
    587599                {
    588600                    case 0:
     
    614626                }
    615627                VBOXAHCI_DEBUG("AHCI: Dev %d LCHS=%d/%d/%d\n",
    616                                idxDevice, cCylinders, cHeads, cSectorsPerTrack);
    617                 write_word(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].lchs.heads, cHeads);
    618                 write_word(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].lchs.cylinders, cCylinders);
    619                 write_word(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].lchs.spt, cSectorsPerTrack);
    620 
    621                 write_byte(ahci_seg, (uint16_t)&AhciData->aHdIdMap[idxHdCurr], idxDevice);
    622                 idxHdCurr++;
    623                 write_byte(ahci_seg, (uint16_t)&AhciData->cHardDisks, idxHdCurr);
     628                               hdcount_ahci, cCylinders, cHeads, cSectorsPerTrack);
     629
     630                bios_dsk->devices[hd_index].lchs.heads     = cHeads;
     631                bios_dsk->devices[hd_index].lchs.cylinders = cCylinders;
     632                bios_dsk->devices[hd_index].lchs.spt       = cSectorsPerTrack;
     633
     634                /* Store the id of the disk in the ata hdidmap. */
     635                hdcount = bios_dsk->hdcount;
     636                bios_dsk->hdidmap[hdcount] = hdcount_ahci + BX_MAX_ATA_DEVICES + BX_MAX_SCSI_DEVICES;
     637                hdcount++;
     638                bios_dsk->hdcount = hdcount;
    624639
    625640                /* Update hdcount in the BDA. */
    626                 cHardDisksOld = read_byte(0x40, 0x75);
    627                 cHardDisksOld++;
    628                 write_byte(0x40, 0x75, cHardDisksOld);
     641                hdcount = read_byte(0x40, 0x75);
     642                hdcount++;
     643                write_byte(0x40, 0x75, hdcount);
     644               
    629645            }
    630646            else if (val == 0xeb140101)
     
    635651                VBOXAHCI_DEBUG("AHCI: Ignoring unknown device\n");
    636652
    637             idxDevice++;
    638             write_byte(ahci_seg, (uint16_t)&AhciData->cDevices, idxDevice);
     653            hdcount_ahci++;
     654            bios_dsk->ahci_hdcount = hdcount_ahci;
    639655        }
    640656        else
     
    643659}
    644660
    645 #define SET_DISK_RET_STATUS(status) write_byte(0x0040, 0x0074, status)
    646 
    647 /**
    648  * Int 13 handler.
    649  */
    650 void BIOSCALL ahci_int13(volatile uint16_t RET, volatile uint16_t ES, volatile uint16_t DS, volatile uint16_t DI,
    651                          volatile uint16_t SI, volatile uint16_t BP, volatile uint16_t SP, volatile uint16_t BX,
    652                          volatile uint16_t DX, volatile uint16_t CX, volatile uint16_t AX, volatile uint16_t IPIRET,
    653                          volatile uint16_t CSIRET, volatile uint16_t FLAGSIRET, volatile uint16_t IP,
    654                          volatile uint16_t CS, volatile uint16_t FLAGS)
    655 {
    656     uint16_t    ebda_seg;
    657     uint16_t    ahci_seg, u16IoBase;
    658     uint8_t     idxDevice;
    659     uint8_t     old_disks;
    660     uint8_t     u8Port;
    661 
    662     uint32_t    lba;
    663     uint16_t    cylinder, head, sector;
    664     uint16_t    segment, offset;
    665     uint16_t    npc, nph, npspt, nlc, nlh, nlspt;
    666     uint16_t    count;
    667 //    uint16_t    size;
    668     uint8_t     status;
    669 
    670     VBOXAHCI_INT13_DEBUG("ahci_int13 AX=%x CX=%x DX=%x BX=%x ES=%x SP=%x BP=%x SI=%x DI=%x IP=%x CS=%x FLAGS=%x\n",
    671                          AX, CX, DX, BX, ES, SP, BP, SI, DI, IP, CS, FLAGS);
    672 
    673     ebda_seg  = read_word(0x0040, 0x000E);
    674     ahci_seg  = read_word(ebda_seg, (uint16_t)&EbdaData->ahci_seg);
    675     u16IoBase = read_word(ahci_seg, (uint16_t)&AhciData->iobase);
    676     old_disks = read_byte(ahci_seg, (uint16_t)&AhciData->cHardDisksOld);
    677     VBOXAHCI_INT13_DEBUG("ahci_int13: ahci_seg=%x u16IoBase=%x old_disks=%d\n", ahci_seg, u16IoBase, old_disks);
    678 
    679     /* Check if the device is controlled by us first. */
    680     if (   (GET_DL() < 0x80)
    681         || (GET_DL() < 0x80 + old_disks)
    682         || ((GET_DL() & 0xe0) != 0x80) /* No CD-ROM drives supported for now */)
    683     {
    684         VBOXAHCI_INT13_DEBUG("ahci_int13: device not controlled by us, forwarding to old handler (%d)\n", old_disks);
    685         /* Fill the iret frame to jump to the old handler. */
    686         IPIRET    = read_word(ahci_seg, (uint16_t)&AhciData->pfnInt13Old);
    687         CSIRET    = 0xf000;
    688         FLAGSIRET = FLAGS;
    689         RET       = 1;
    690         return;
    691     }
    692 
    693     //@todo: pre-init aHdIdMap!
    694     idxDevice = read_byte(ahci_seg, (uint16_t)&AhciData->aHdIdMap[GET_DL() - 0x80 - old_disks]);
    695 
    696     if (idxDevice >= AHCI_MAX_STORAGE_DEVICES)
    697     {
    698         VBOXAHCI_INT13_DEBUG("ahci_int13: function %02x, unmapped device for ELDL=%02x\n", GET_AH(), GET_DL());
    699         goto ahci_int13_fail;
    700     }
    701 
    702     u8Port = read_byte(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].port);
    703 
    704     switch (GET_AH())
    705     {
    706         case 0x00: /* disk controller reset */
    707         {
    708             /** @todo: not really important I think. */
    709             goto ahci_int13_success;
    710             break;
    711         }
    712         case 0x01: /* read disk status */
    713         {
    714             status = read_byte(0x0040, 0x0074);
    715             SET_AH(status);
    716             SET_DISK_RET_STATUS(0);
    717             /* set CF if error status read */
    718             if (status)
    719                 goto ahci_int13_fail_nostatus;
    720             else
    721                 goto ahci_int13_success_noah;
    722             break;
    723         }
    724         case 0x02: // read disk sectors
    725         case 0x03: // write disk sectors
    726         case 0x04: // verify disk sectors
    727         {
    728             count       = GET_AL();
    729             cylinder    = GET_CH();
    730             cylinder   |= ( ((uint16_t) GET_CL()) << 2) & 0x300;
    731             sector      = (GET_CL() & 0x3f);
    732             head        = GET_DH();
    733 
    734             segment = ES;
    735             offset  = BX;
    736 
    737             if ((count > 128) || (count == 0))
    738             {
    739                 BX_INFO("ahci_int13: function %02x, count out of range!\n",GET_AH());
    740                 goto ahci_int13_fail;
    741             }
    742 
    743             nlc   = read_word(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].lchs.cylinders);
    744             nlh   = read_word(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].lchs.heads);
    745             nlspt = read_word(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].lchs.spt);
    746 
    747             // sanity check on cyl heads, sec
    748             if( (cylinder >= nlc) || (head >= nlh) || (sector > nlspt ))
    749             {
    750               BX_INFO("ahci_int13: function %02x, disk %02x, idx %02x, parameters out of range %04x/%04x/%04x!\n",
    751                       GET_AH(), GET_DL(), idxDevice, cylinder, head, sector);
    752               goto ahci_int13_fail;
    753             }
    754 
    755             // FIXME verify
    756             if ( GET_AH() == 0x04 )
    757                 goto ahci_int13_success;
    758 
    759             lba = ((((uint32_t)cylinder * (uint32_t)nlh) + (uint32_t)head) * (uint32_t)nlspt) + (uint32_t)sector - 1;
    760 
    761             status = 0;
    762             if ( GET_AH() == 0x02 )
    763                 ahci_cmd_data_in(ahci_seg, u16IoBase, u8Port, AHCI_CMD_READ_DMA_EXT, lba, count, segment, offset);
    764             else
    765                 ahci_cmd_data_out(ahci_seg, u16IoBase, u8Port, AHCI_CMD_WRITE_DMA_EXT, lba, count, segment, offset);
    766 
    767             // Set nb of sector transferred
    768             SET_AL(read_word(ebda_seg, (uint16_t)&EbdaData->bdisk.drqp.trsfsectors));
    769 
    770             if (status != 0)
    771             {
    772                 BX_INFO("ahci_int13: function %02x, error %02x !\n",GET_AH(),status);
    773                 SET_AH(0x0c);
    774                 goto ahci_int13_fail_noah;
    775             }
    776 
    777             goto ahci_int13_success;
    778             break;
    779         }
    780         case 0x05: /* format disk track */
    781             BX_INFO("format disk track called\n");
    782             goto ahci_int13_success;
    783             break;
    784         case 0x08: /* read disk drive parameters */
    785         {
    786             // Get logical geometry from table
    787             nlc   = read_word(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].lchs.cylinders);
    788             nlh   = read_word(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].lchs.heads);
    789             nlspt = read_word(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].lchs.spt);
    790 
    791             count = read_byte(ahci_seg, (uint16_t)&AhciData->cHardDisks); /** @todo correct? */
    792             /* Maximum cylinder number is just one less than the number of cylinders. */
    793             nlc = nlc - 1; /* 0 based , last sector not used */
    794             SET_AL(0);
    795             SET_CH(nlc & 0xff);
    796             SET_CL(((nlc >> 2) & 0xc0) | (nlspt & 0x3f));
    797             SET_DH(nlh - 1);
    798             SET_DL(count); /* FIXME returns 0, 1, or n hard drives */
    799             // FIXME should set ES & DI
    800             goto ahci_int13_success;
    801             break;
    802         }
    803         case 0x10: /* check drive ready */
    804         {
    805             /** @todo */
    806             goto ahci_int13_success;
    807             break;
    808         }
    809         case 0x15: /* read disk drive size */
    810         {
    811             // Get physical geometry from table
    812             npc   = read_word(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].pchs.cylinders);
    813             nph   = read_word(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].pchs.heads);
    814             npspt = read_word(ahci_seg, (uint16_t)&AhciData->aDevices[idxDevice].pchs.spt);
    815 
    816             // Compute sector count seen by int13
    817             lba = (uint32_t)npc * (uint32_t)nph * (uint32_t)npspt;
    818             CX = lba >> 16;
    819             DX = lba & 0xffff;
    820 
    821             SET_AH(3);  // hard disk accessible
    822             goto ahci_int13_success_noah;
    823             break;
    824         }
    825 #if 0
    826         case 0x41: // IBM/MS installation check
    827         {
    828             BX=0xaa55;     // install check
    829             SET_AH(0x30);  // EDD 3.0
    830             CX=0x0007;     // ext disk access and edd, removable supported
    831             goto ahci_int13_success_noah;
    832             break;
    833         }
    834         case 0x42: // IBM/MS extended read
    835         case 0x43: // IBM/MS extended write
    836         case 0x44: // IBM/MS verify
    837         case 0x47: // IBM/MS extended seek
    838         {
    839             count=read_word(DS, SI+(uint16_t)&Int13Ext->count);
    840             segment=read_word(DS, SI+(uint16_t)&Int13Ext->segment);
    841             offset=read_word(DS, SI+(uint16_t)&Int13Ext->offset);
    842 
    843             // Can't use 64 bits lba
    844             lba=read_dword(DS, SI+(uint16_t)&Int13Ext->lba2);
    845             if (lba != 0L)
    846             {
    847                 BX_PANIC("ahci_int13: function %02x. Can't use 64bits lba\n",GET_AH());
    848                 goto ahci_int13_fail;
    849             }
    850 
    851             // Get 32 bits lba and check
    852             lba=read_dword(DS, SI+(uint16_t)&Int13Ext->lba1);
    853 
    854             if (lba >= read_word(ahci_seg, &AhciData->aDevices[idxDevice].cSectors) )
    855             {
    856                 BX_INFO("ahci_int13: function %02x. LBA out of range\n",GET_AH());
    857                 goto ahci_int13_fail;
    858             }
    859 
    860             // If verify or seek
    861             if (( GET_AH() == 0x44 ) || ( GET_AH() == 0x47 ))
    862                 goto ahci_int13_success;
    863 
    864             // Execute the command
    865             if ( GET_AH() == 0x42 )
    866             {
    867                 ...
    868             }
    869             else
    870             {
    871                 ...
    872             }
    873 
    874             count=read_word(ebda_seg, &EbdaData->bdisk.drqp.trsfsectors);
    875             write_word(DS, SI+(uint16_t)&Int13Ext->count, count);
    876 
    877             if (status != 0)
    878             {
    879                 BX_INFO("ahci_int13: function %02x, error %02x !\n",GET_AH(),status);
    880                 SET_AH(0x0c);
    881                 goto ahci_int13_fail_noah;
    882             }
    883             goto ahci_int13_success;
    884             break;
    885         }
    886         case 0x45: // IBM/MS lock/unlock drive
    887         case 0x49: // IBM/MS extended media change
    888             goto ahci_int13_success;    // Always success for HD
    889             break;
    890         case 0x46: // IBM/MS eject media
    891             SET_AH(0xb2);          // Volume Not Removable
    892             goto ahci_int13_fail_noah;  // Always fail for HD
    893             break;
    894 
    895         case 0x48: // IBM/MS get drive parameters
    896             size=read_word(DS,SI+(uint16_t)&Int13DPT->size);
    897 
    898             // Buffer is too small
    899             if(size < 0x1a)
    900                 goto ahci_int13_fail;
    901 
    902             // EDD 1.x
    903             if(size >= 0x1a)
    904             {
    905                 uint16_t   blksize;
    906 
    907                 npc     = read_word(ahci_seg, &AhciData->aDevices[idxDevice].pchs.cylinders);
    908                 nph     = read_word(ahci_seg, &AhciData->aDevices[idxDevice].pchs.heads);
    909                 npspt   = read_word(ahci_seg, &AhciData->aDevices[idxDevice].pchs.spt);
    910                 lba     = read_dword(ahci_seg, &AhciData->aDevices[idxDevice].cSectors);
    911                 blksize = read_word(ahci_seg, &AhciData->aDevices[idxDevice].blksize);
    912 
    913                 write_word(DS, SI+(uint16_t)&Int13DPT->size, 0x1a);
    914                 write_word(DS, SI+(uint16_t)&Int13DPT->infos, 0x02); // geometry is valid
    915                 write_dword(DS, SI+(uint16_t)&Int13DPT->cylinders, (uint32_t)npc);
    916                 write_dword(DS, SI+(uint16_t)&Int13DPT->heads, (uint32_t)nph);
    917                 write_dword(DS, SI+(uint16_t)&Int13DPT->spt, (uint32_t)npspt);
    918                 write_dword(DS, SI+(uint16_t)&Int13DPT->sector_count1, lba);  // FIXME should be Bit64
    919                 write_dword(DS, SI+(uint16_t)&Int13DPT->sector_count2, 0L);
    920                 write_word(DS, SI+(uint16_t)&Int13DPT->blksize, blksize);
    921             }
    922 
    923 #if 0 /* Disable EDD 2.X and 3.x for now, don't know if it is required by any OS loader yet */
    924             // EDD 2.x
    925             if(size >= 0x1e)
    926             {
    927                 uint8_t     channel, dev, irq, mode, checksum, i, translation;
    928                 uint16_t    iobase1, iobase2, options;
    929 
    930                 translation = ATA_TRANSLATION_LBA;
    931 
    932                 write_word(DS, SI+(uint16_t)&Int13DPT->size, 0x1e);
    933 
    934                 write_word(DS, SI+(uint16_t)&Int13DPT->dpte_segment, ebda_seg);
    935                 write_word(DS, SI+(uint16_t)&Int13DPT->dpte_offset, &EbdaData->bdisk.dpte);
    936 
    937                 // Fill in dpte
    938                 channel = device / 2;
    939                 iobase1 = read_word(ebda_seg, &EbdaData->bdisk.channels[channel].iobase1);
    940                 iobase2 = read_word(ebda_seg, &EbdaData->bdisk.channels[channel].iobase2);
    941                 irq = read_byte(ebda_seg, &EbdaData->bdisk.channels[channel].irq);
    942                 mode = read_byte(ebda_seg, &EbdaData->bdisk.devices[device].mode);
    943                 translation = read_byte(ebda_seg, &EbdaData->bdisk.devices[device].translation);
    944 
    945                 options  = (translation==ATA_TRANSLATION_NONE?0:1<<3); // chs translation
    946                 options |= (1<<4); // lba translation
    947                 options |= (mode==ATA_MODE_PIO32?1:0<<7);
    948                 options |= (translation==ATA_TRANSLATION_LBA?1:0<<9);
    949                 options |= (translation==ATA_TRANSLATION_RECHS?3:0<<9);
    950 
    951                 write_word(ebda_seg, &EbdaData->bdisk.dpte.iobase1, iobase1);
    952                 write_word(ebda_seg, &EbdaData->bdisk.dpte.iobase2, iobase2);
    953                 //write_byte(ebda_seg, &EbdaData->bdisk.dpte.prefix, (0xe | /*(device % 2))<<4*/ );
    954                 write_byte(ebda_seg, &EbdaData->bdisk.dpte.unused, 0xcb );
    955                 write_byte(ebda_seg, &EbdaData->bdisk.dpte.irq, irq );
    956                 write_byte(ebda_seg, &EbdaData->bdisk.dpte.blkcount, 1 );
    957                 write_byte(ebda_seg, &EbdaData->bdisk.dpte.dma, 0 );
    958                 write_byte(ebda_seg, &EbdaData->bdisk.dpte.pio, 0 );
    959                 write_word(ebda_seg, &EbdaData->bdisk.dpte.options, options);
    960                 write_word(ebda_seg, &EbdaData->bdisk.dpte.reserved, 0);
    961                 write_byte(ebda_seg, &EbdaData->bdisk.dpte.revision, 0x11);
    962 
    963                 checksum=0;
    964                 for (i=0; i<15; i++)
    965                     checksum+=read_byte(ebda_seg, (&EbdaData->bdisk.dpte) + i);
    966 
    967                 checksum = -checksum;
    968                 write_byte(ebda_seg, &EbdaData->bdisk.dpte.checksum, checksum);
    969             }
    970 
    971             // EDD 3.x
    972             if(size >= 0x42)
    973             {
    974                 uint8_t     channel, iface, checksum, i;
    975                 uint16_t    iobase1;
    976 
    977                 channel = device / 2;
    978                 iface = read_byte(ebda_seg, &EbdaData->bdisk.channels[channel].iface);
    979                 iobase1 = read_word(ebda_seg, &EbdaData->bdisk.channels[channel].iobase1);
    980 
    981                 write_word(DS, SI+(uint16_t)&Int13DPT->size, 0x42);
    982                 write_word(DS, SI+(uint16_t)&Int13DPT->key, 0xbedd);
    983                 write_byte(DS, SI+(uint16_t)&Int13DPT->dpi_length, 0x24);
    984                 write_byte(DS, SI+(uint16_t)&Int13DPT->reserved1, 0);
    985                 write_word(DS, SI+(uint16_t)&Int13DPT->reserved2, 0);
    986 
    987                 if (iface==ATA_IFACE_ISA) {
    988                   write_byte(DS, SI+(uint16_t)&Int13DPT->host_bus[0], 'I');
    989                   write_byte(DS, SI+(uint16_t)&Int13DPT->host_bus[1], 'S');
    990                   write_byte(DS, SI+(uint16_t)&Int13DPT->host_bus[2], 'A');
    991                   write_byte(DS, SI+(uint16_t)&Int13DPT->host_bus[3], 0);
    992                   }
    993                 else {
    994                   // FIXME PCI
    995                   }
    996                 write_byte(DS, SI+(uint16_t)&Int13DPT->iface_type[0], 'A');
    997                 write_byte(DS, SI+(uint16_t)&Int13DPT->iface_type[1], 'T');
    998                 write_byte(DS, SI+(uint16_t)&Int13DPT->iface_type[2], 'A');
    999                 write_byte(DS, SI+(uint16_t)&Int13DPT->iface_type[3], 0);
    1000 
    1001                 if (iface==ATA_IFACE_ISA) {
    1002                   write_word(DS, SI+(uint16_t)&Int13DPT->iface_path[0], iobase1);
    1003                   write_word(DS, SI+(uint16_t)&Int13DPT->iface_path[2], 0);
    1004                   write_dword(DS, SI+(uint16_t)&Int13DPT->iface_path[4], 0L);
    1005                   }
    1006                 else {
    1007                   // FIXME PCI
    1008                   }
    1009                 //write_byte(DS, SI+(uint16_t)&Int13DPT->device_path[0], device%2);
    1010                 write_byte(DS, SI+(uint16_t)&Int13DPT->device_path[1], 0);
    1011                 write_word(DS, SI+(uint16_t)&Int13DPT->device_path[2], 0);
    1012                 write_dword(DS, SI+(uint16_t)&Int13DPT->device_path[4], 0L);
    1013 
    1014                 checksum=0;
    1015                 for (i=30; i<64; i++) checksum+=read_byte(DS, SI + i);
    1016                 checksum = -checksum;
    1017                 write_byte(DS, SI+(uint16_t)&Int13DPT->checksum, checksum);
    1018             }
    1019 #endif
    1020             goto ahci_int13_success;
    1021             break;
    1022         case 0x4e: // // IBM/MS set hardware configuration
    1023             // DMA, prefetch, PIO maximum not supported
    1024             switch (GET_AL())
    1025             {
    1026                 case 0x01:
    1027                 case 0x03:
    1028                 case 0x04:
    1029                 case 0x06:
    1030                     goto ahci_int13_success;
    1031                     break;
    1032                 default :
    1033                     goto ahci_int13_fail;
    1034             }
    1035             break;
    1036 #endif
    1037         case 0x09: /* initialize drive parameters */
    1038         case 0x0c: /* seek to specified cylinder */
    1039         case 0x0d: /* alternate disk reset */
    1040         case 0x11: /* recalibrate */
    1041         case 0x14: /* controller internal diagnostic */
    1042             BX_INFO("ahci_int13: function %02xh unimplemented, returns success\n", GET_AH());
    1043             goto ahci_int13_success;
    1044             break;
    1045 
    1046         case 0x0a: /* read disk sectors with ECC */
    1047         case 0x0b: /* write disk sectors with ECC */
    1048         case 0x18: // set media type for format
    1049         case 0x50: // IBM/MS send packet command
    1050         default:
    1051             BX_INFO("ahci_int13: function %02xh unsupported, returns fail\n", GET_AH());
    1052             goto ahci_int13_fail;
    1053             break;
    1054     }
    1055 
    1056     //@todo: this is really badly written, reuse the code more!
    1057 ahci_int13_fail:
    1058     SET_AH(0x01); // defaults to invalid function in AH or invalid parameter
    1059 ahci_int13_fail_noah:
    1060     SET_DISK_RET_STATUS(GET_AH());
    1061 ahci_int13_fail_nostatus:
    1062     VBOXAHCI_INT13_DEBUG("ahci_int13: done, AH=%02x\n", GET_AH());
    1063     SET_CF();     // error occurred
    1064     return;
    1065 
    1066 ahci_int13_success:
    1067     SET_AH(0x00); // no error
    1068 ahci_int13_success_noah:
    1069     SET_DISK_RET_STATUS(0x00);
    1070     VBOXAHCI_INT13_DEBUG("ahci_int13: done, AH=%02x\n", GET_AH());
    1071     CLEAR_CF();   // no error
    1072     return;
    1073 }
    1074 
    1075 #undef SET_DISK_RET_STATUS
    1076 
    1077 /* Defined in assembler code. */
    1078 extern void ahci_int13_handler(void);
    1079 #pragma aux ahci_int13_handler "*";
    1080 
    1081 /**
    1082  * Install the in13 interrupt handler
    1083  * preserving the previous one.
    1084  */
    1085 static void ahci_install_int_handler(uint16_t ahci_seg)
    1086 {
    1087 
    1088     uint16_t    pfnInt13Old;
    1089 
    1090     VBOXAHCI_DEBUG("AHCI: Hooking int 13h vector\n");
    1091 
    1092     /* Read the old interrupt handler. */
    1093     pfnInt13Old = read_word(0x0000, 0x0013*4);
    1094     write_word(ahci_seg, (uint16_t)&AhciData->pfnInt13Old, pfnInt13Old);
    1095 
    1096     /* Set our own */
    1097     write_word(0x0000, 0x0013*4, (uint16_t)ahci_int13_handler);
    1098 }
    1099 
    1100 /**
    1101  * Allocates 1K from the base memory.
     661/**
     662 * Allocates 1K of conventional memory.
    1102663 */
    1103664static uint16_t ahci_mem_alloc(void)
     
    1146707    }
    1147708    VBOXAHCI_DEBUG("AHCI: ahci_seg=%04x, size=%04x, pointer at EBDA:%04x (EBDA size=%04x)\n",
    1148                    ahci_seg, sizeof(ahci_t), (uint16_t)&EbdaData->ahci_seg, sizeof(ebda_data_t));
    1149 
    1150     write_word(ebda_seg, (uint16_t)&EbdaData->ahci_seg, ahci_seg);
    1151     write_byte(ahci_seg, (uint16_t)&AhciData->port, 0xff);
     709                   ahci_seg, sizeof(ahci_t), (uint16_t)&EbdaData->bdisk.ahci_seg, sizeof(ebda_data_t));
     710
     711    write_word(ebda_seg, (uint16_t)&EbdaData->bdisk.ahci_seg, ahci_seg);
     712    write_byte(ebda_seg, (uint16_t)&EbdaData->bdisk.ahci_hdcount, 0);
     713    write_byte(ahci_seg, (uint16_t)&AhciData->cur_port, 0xff);
    1152714    write_word(ahci_seg, (uint16_t)&AhciData->iobase, u16IoBase);
    1153     write_byte(ahci_seg, (uint16_t)&AhciData->cHardDisksOld, read_byte(0x40, 0x75));
    1154715
    1155716    /* Reset the controller. */
     
    1178739        }
    1179740        i++;
    1180     }
    1181 
    1182     if (read_byte(ahci_seg, (uint16_t)&AhciData->cDevices) > 0)
    1183     {
    1184         /*
    1185          * Init completed and there is at least one device present.
    1186          * Install our int13 handler.
    1187          */
    1188         ahci_install_int_handler(ahci_seg);
    1189741    }
    1190742
  • trunk/src/VBox/Devices/PC/BIOS-new/ata.h

    r39366 r39372  
    4343#define ATA_DATA_IN      0x01
    4444#define ATA_DATA_OUT     0x02
    45 
    46 #define ATA_TRANSLATION_NONE  0
    47 #define ATA_TRANSLATION_LBA   1
    48 #define ATA_TRANSLATION_LARGE 2
    49 #define ATA_TRANSLATION_RECHS 3
    5045
    5146#define ATA_IFACE_NONE    0x00
  • trunk/src/VBox/Devices/PC/BIOS-new/disk.c

    r39366 r39372  
    168168        if ( GET_AH() == 0x02 )
    169169        {
     170#ifdef VBOX_WITH_AHCI
     171            if (VBOX_IS_AHCI_DEVICE(device))
     172                status = ahci_read_sectors(bios_dsk);
     173            else
     174#endif
    170175#ifdef VBOX_WITH_SCSI
    171176            if (VBOX_IS_SCSI_DEVICE(device))
     
    175180                status = ata_read_sectors(bios_dsk);
    176181        } else {
     182#ifdef VBOX_WITH_AHCI
     183            if (VBOX_IS_AHCI_DEVICE(device))
     184                status = ahci_write_sectors(bios_dsk);
     185            else
     186#endif
    177187#ifdef VBOX_WITH_SCSI
    178188            if (VBOX_IS_SCSI_DEVICE(device))
     
    370380        // Execute the command
    371381        if ( GET_AH() == 0x42 ) {
     382#ifdef VBOX_WITH_AHCI
     383            if (VBOX_IS_AHCI_DEVICE(device))
     384                status = ahci_read_sectors(bios_dsk);
     385            else
     386#endif
    372387#ifdef VBOX_WITH_SCSI
    373388            if (VBOX_IS_SCSI_DEVICE(device))
     
    377392                status = ata_read_sectors(bios_dsk);
    378393        } else {
     394#ifdef VBOX_WITH_AHCI
     395            if (VBOX_IS_AHCI_DEVICE(device))
     396                status = ahci_write_sectors(bios_dsk);
     397            else
     398#endif
    379399#ifdef VBOX_WITH_SCSI
    380400            if (VBOX_IS_SCSI_DEVICE(device))
  • trunk/src/VBox/Devices/PC/BIOS-new/ebda.h

    r39366 r39372  
    5050
    5151#ifdef VBOX_WITH_SCSI
    52 /* Enough for now */
    53 #    define BX_MAX_SCSI_DEVICES 4
    54 #    define BX_MAX_STORAGE_DEVICES (BX_MAX_ATA_DEVICES + BX_MAX_SCSI_DEVICES)
    55 
    56 /* A SCSI device starts always at BX_MAX_ATA_DEVICES. */
    57 #    define VBOX_IS_SCSI_DEVICE(device_id) (device_id >= BX_MAX_ATA_DEVICES)
    58 #    define VBOX_GET_SCSI_DEVICE(device_id) (device_id - BX_MAX_ATA_DEVICES)
     52    /* Enough for now */
     53    #define BX_MAX_SCSI_DEVICES 4
     54    /* A SCSI device starts always at BX_MAX_ATA_DEVICES. */
     55    #define VBOX_IS_SCSI_DEVICE(device_id) (device_id >= BX_MAX_ATA_DEVICES)
     56    #define VBOX_GET_SCSI_DEVICE(device_id) (device_id - BX_MAX_ATA_DEVICES)
    5957#else
    60 #    define BX_MAX_STORAGE_DEVICES  BX_MAX_ATA_DEVICES
    61 #endif
     58    #define BX_MAX_SCSI_DEVICES 0
     59#endif
     60
     61#ifdef VBOX_WITH_AHCI
     62    /* Four should be enough for now */
     63    #define BX_MAX_AHCI_DEVICES 4
     64
     65    /* An AHCI device starts always at BX_MAX_ATA_DEVICES + BX_MAX_SCSI_DEVICES. */
     66    #define VBOX_IS_AHCI_DEVICE(device_id) (device_id >= (BX_MAX_ATA_DEVICES + BX_MAX_SCSI_DEVICES))
     67    #define VBOX_GET_AHCI_DEVICE(device_id) (device_id - (BX_MAX_ATA_DEVICES + BX_MAX_SCSI_DEVICES))
     68#else
     69    #define BX_MAX_AHCI_DEVICES 0
     70#endif
     71
     72#define BX_MAX_STORAGE_DEVICES (BX_MAX_ATA_DEVICES + BX_MAX_SCSI_DEVICES + BX_MAX_AHCI_DEVICES)
    6273
    6374/* Generic storage device types. Bit of a misnomer! */
     
    6778#define ATA_TYPE_ATAPI      0x03
    6879#define ATA_TYPE_SCSI       0x04 // SCSI disk
     80#define ATA_TYPE_AHCI       0x05 // SATA disk
    6981
    7082#define ATA_DEVICE_NONE     0x00
     
    7284#define ATA_DEVICE_CDROM    0x05
    7385
     86#define ATA_TRANSLATION_NONE  0
     87#define ATA_TRANSLATION_LBA   1
     88#define ATA_TRANSLATION_LARGE 2
     89#define ATA_TRANSLATION_RECHS 3
    7490
    7591#if 1 //BX_USE_ATADRV
     
    146162#endif
    147163
     164#ifdef VBOX_WITH_AHCI
     165
     166/* AHCI specific device information. */
     167typedef struct {
     168    uint8_t     port;           /* SATA port. */
     169} ahci_dev_t;
     170
     171#endif
     172
    148173/* Generic disk information. */
    149174typedef struct {
     
    152177    uint8_t     removable;    /* Removable device flag. */
    153178    uint8_t     lock;         /* Lock count for removable devices. */
     179    //@todo: ATA specific - move?
    154180    uint8_t     mode;         /* Transfer mode: PIO 16/32 bits - IRQ - ISADMA - PCIDMA. */
    155181    uint8_t     translation;  /* Type of geometry translation. */
     
    182208    disk_req_t  drqp;               /* Disk request packet. */
    183209
    184     /* ATA bus-specific device information. */
    185     ata_chan_t  channels[BX_MAX_ATA_INTERFACES];
    186 
    187210    /* Bus-independent disk device information. */
    188     disk_dev_t  devices[BX_MAX_ATA_DEVICES + BX_MAX_SCSI_DEVICES];
    189 
    190     uint8_t     hdcount;            /* Number of ATA disks. */
    191     /* Map between (BIOS disk ID - 0x80) and ATA/SCSI disks. */
     211    disk_dev_t  devices[BX_MAX_STORAGE_DEVICES];
     212
     213    uint8_t     hdcount;            /* Total number of BIOS disks. */
     214    /* Map between (BIOS disk ID - 0x80) and ATA/SCSI/AHCI disks. */
    192215    uint8_t     hdidmap[BX_MAX_STORAGE_DEVICES];
    193216
     
    195218    /* Map between (BIOS CD-ROM ID - 0xE0) and ATA channels. */
    196219    uint8_t     cdidmap[BX_MAX_STORAGE_DEVICES];
     220
     221    /* ATA bus-specific device information. */
     222    ata_chan_t  channels[BX_MAX_ATA_INTERFACES];
    197223
    198224#ifdef VBOX_WITH_SCSI
     
    201227    uint8_t     scsi_hdcount;       /* Number of SCSI disks. */
    202228#endif
     229
     230#ifdef VBOX_WITH_AHCI
     231    /* SATA (AHCI) bus-specific device information. */
     232    ahci_dev_t  ahcidev[BX_MAX_AHCI_DEVICES];
     233    uint8_t     ahci_hdcount;       /* Number of SATA disks. */
     234    uint16_t    ahci_seg;           /* Segment of AHCI data block. */
     235#endif
     236
    203237    dpte_t      dpte;               /* Buffer for building a DPTE. */
    204238} bio_dsk_t;
     
    233267    fdpt_t      fdpt1;
    234268
    235 #if 0
    236269    uint8_t     filler2[0xC4];
    237 #else
    238     uint8_t     filler2[0xC2];
    239     uint16_t    ahci_seg;
    240 #endif
    241270
    242271    bio_dsk_t   bdisk;      /* Disk driver data (ATA/SCSI/AHCI). */
     
    244273#if BX_ELTORITO_BOOT
    245274    cdemu_t     cdemu;      /* El Torito floppy/HD emulation data. */
    246 #endif
    247 
    248 #ifdef VBOX_WITH_BIOS_AHCI
    249 //    ahci_t      ahci;
    250 //    uint16_t    ahci_seg;    //@todo: Someone is trashing the data here!?!
    251275#endif
    252276
     
    262286#define EbdaData ((ebda_data_t *) 0)
    263287
     288/* Note: Using fastcall reduces stack usage a little. */
     289int __fastcall ata_read_sectors(bio_dsk_t __far *bios_dsk);
     290int __fastcall ata_write_sectors(bio_dsk_t __far *bios_dsk);
     291
    264292int __fastcall scsi_read_sectors(bio_dsk_t __far *bios_dsk);
    265293int __fastcall scsi_write_sectors(bio_dsk_t __far *bios_dsk);
    266294
    267 int __fastcall ata_read_sectors(bio_dsk_t __far *bios_dsk);
    268 int __fastcall ata_write_sectors(bio_dsk_t __far *bios_dsk);
     295int __fastcall ahci_read_sectors(bio_dsk_t __far *bios_dsk);
     296int __fastcall ahci_write_sectors(bio_dsk_t __far *bios_dsk);
    269297
    270298// @todo: put this elsewhere (and change/eliminate?)
  • trunk/src/VBox/Devices/PC/BIOS-new/makefile

    r39346 r39372  
    1616CFLAGS = -q -0 -wx -zu -s -oas -d1+ -ms
    1717DEFS   = -DVBOX -DVBOX_LANBOOT_SEG=0xE200 -DVBOX_VERSION_STRING=$(QUOTE)0.9$(QUOTE) &
    18  -DVBOX_WITH_SCSI -DVBOX_WITH_BIOS_AHCI
     18 -DVBOX_WITH_SCSI -DVBOX_WITH_AHCI
    1919
    2020AFLAGS = -q -0 -wx
  • trunk/src/VBox/Devices/PC/BIOS-new/orgs.asm

    r39109 r39372  
    100100extrn           _cdemu_isactive:near
    101101extrn           _cdemu_emulated_drive:near
    102 extrn           _ahci_int13:near
    103102extrn           _int13_harddisk:near
    104103extrn           _int13_harddisk_ext:near
     
    155154public          hard_drive_post
    156155public          int13_legacy
    157 public          ahci_int13_handler
    158156public          int70_handler
    159157public          int75_handler
     
    453451endif
    454452
    455                 ;; floppy setup
    456                 call    floppy_post
    457 
    458                 ;; hard drive setup
    459                 call    hard_drive_post
    460 
    461                 C_SETUP                 ; in case assembly code changed things
    462 ifdef VBOX_WITH_BIOS_AHCI
     453ifdef VBOX_WITH_AHCI
    463454                ; AHCI driver setup
    464455                call    _ahci_init
    465456endif
    466457
     458                ;; floppy setup
     459                call    floppy_post
     460
     461                ;; hard drive setup
     462                call    hard_drive_post
     463
     464                C_SETUP                 ; in case assembly code changed things
    467465                call    _print_bios_banner
    468466
     
    14901488include pirq.inc
    14911489
    1492 ifdef VBOX_WITH_BIOS_AHCI
    1493 
    1494 ahci_int13_handler:
    1495                 ;; allocate space for IRET frame used to call old INT 13h
    1496                 push    ax
    1497                 push    ax
    1498                 push    ax
    1499 
    1500                 pusha
    1501                 push    ds
    1502                 push    es
    1503                 push    0               ; Room for return value (default 0)
    1504                 C_SETUP
    1505                 call    _ahci_int13
    1506                 pop     ax
    1507                 pop     es
    1508                 pop     ds
    1509                 cmp     ax, 0           ; Check if interrupt was handled
    1510                 je      ahci_int13_out
    1511 
    1512                 popa                    ; Restore caller's registers
    1513                 iret                    ; Call old handler
    1514 
    1515 ahci_int13_out:
    1516                 popa
    1517                 add     sp, 6           ; Remove the IRET frame
    1518                 iret
    1519                
    1520 endif
    15211490
    15221491;; --------------------------------------------------------
  • trunk/src/VBox/Devices/PC/BIOS-new/scsi.c

    r39366 r39372  
    2121#include "inlines.h"
    2222#include "ebda.h"
    23 #include "ata.h"
    2423
    2524
     
    339338                bios_dsk->devices[hd_index].removable   = 0;
    340339                bios_dsk->devices[hd_index].lock        = 0;
    341                 bios_dsk->devices[hd_index].mode        = ATA_MODE_PIO16;
    342340                bios_dsk->devices[hd_index].blksize     = sector_size;
    343341                bios_dsk->devices[hd_index].translation = ATA_TRANSLATION_LBA;
Note: See TracChangeset for help on using the changeset viewer.

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