VirtualBox

Ignore:
Timestamp:
Dec 13, 2011 5:03:01 PM (13 years ago)
Author:
vboxsync
Message:

Throw away unneeded data from CD.

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

Legend:

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

    r39596 r39597  
    8383    /** Current port which uses the memory to communicate with the controller. */
    8484    uint8_t         cur_port;
     85    /** Current PRD index (for pre/post skip). */
     86    uint8_t         cur_prd;
     87    /** Physical address of the sink buffer (for pre/post skip). */
     88    uint32_t        sink_buf_phys;
    8589    /** VDS EDDS DMA buffer descriptor structure. */
    8690    vds_edds        edds;
     
    235239 * Issues a command to the SATA controller and waits for completion.
    236240 */
    237 static void ahci_port_cmd_sync(ahci_t __far *ahci, uint8_t val, uint16_t cbData)
     241static void ahci_port_cmd_sync(ahci_t __far *ahci, uint8_t val)
    238242{
    239243    uint16_t        io_base;
     
    246250    {
    247251        /* Prepare the command header. */
    248         ahci->aCmdHdr[0] = RT_BIT_32(16) | RT_BIT_32(7) | val;
    249         ahci->aCmdHdr[1] = 0; //cbData;  //@todo: Is this really an input parameter?
     252        ahci->aCmdHdr[0] = ((uint32_t)ahci->cur_prd << 16) | RT_BIT_32(7) | val;
     253        ahci->aCmdHdr[1] = 0;
    250254        ahci->aCmdHdr[2] = ahci_addr_to_phys(&ahci->abCmd[0]);
    251255
     
    286290    uint16_t        n_sect = bios_dsk->drqp.nsect;
    287291    uint16_t        sectsz = bios_dsk->drqp.sect_sz;
     292    uint16_t        prdt_idx;
    288293
    289294    _fmemset(&ahci->abCmd[0], 0, sizeof(ahci->abCmd));
     
    310315    /* Lock memory needed for DMA. */
    311316    ahci->edds.num_avail = NUM_EDDS_SG;
     317    DBG_AHCI("AHCI: S/G list for %lu bytes (skip %u)\n",
     318             (uint32_t)n_sect * sectsz, bios_dsk->drqp.skip_a);
    312319    vds_build_sg_list(&ahci->edds, bios_dsk->drqp.buffer, (uint32_t)n_sect * sectsz);
    313320
     321    prdt_idx = ahci->cur_prd;
     322
    314323    /* Set up the PRDT. */
    315     ahci->aPrdt[0].phys_addr = ahci->edds.u.sg[0].phys_addr;
    316     ahci->aPrdt[0].len       = ahci->edds.u.sg[0].size - 1;
    317 
    318     /* Build variable part first of command dword (reuses 'cmd'). */
     324    ahci->aPrdt[prdt_idx].len       = ahci->edds.u.sg[prdt_idx].size - 1;
     325    ahci->aPrdt[prdt_idx].phys_addr = ahci->edds.u.sg[prdt_idx].phys_addr;
     326    ++prdt_idx;
     327
     328    if (bios_dsk->drqp.skip_a) {
     329        ahci->aPrdt[prdt_idx].len       = bios_dsk->drqp.skip_a - 1;
     330        ahci->aPrdt[prdt_idx].phys_addr = ahci->sink_buf_phys;
     331        ++prdt_idx;
     332    }
     333
     334    ahci->cur_prd = prdt_idx;
     335
     336    /* Build variable part of first command DWORD (reuses 'cmd'). */
    319337    if (cmd == AHCI_CMD_WRITE_DMA_EXT)
    320338        cmd = RT_BIT_32(6);     /* Indicate a write to device. */
     
    327345    cmd |= 5;   /* Five DWORDs. */
    328346
    329     ahci_port_cmd_sync(ahci, cmd, n_sect * sectsz);
     347    ahci_port_cmd_sync(ahci, cmd);
    330348
    331349    /* Unlock the buffer again. */
     
    422440
    423441    ahci->cur_port = u8Port;
     442    ahci->cur_prd  = 0;
    424443}
    425444
     
    481500
    482501uint16_t ahci_cmd_packet(uint16_t device_id, uint8_t cmdlen, char __far *cmdbuf,
    483                          uint16_t header, uint32_t length, uint8_t inout, char __far *buffer)
     502                         uint16_t skip_b, uint32_t length, uint8_t inout, char __far *buffer)
    484503{
    485504    bio_dsk_t __far *bios_dsk = read_word(0x0040, 0x000E) :> &EbdaData->bdisk;
     
    492511    }
    493512
    494     /* The header length must be even. */
    495     if (header & 1) {
    496         DBG_AHCI("%s: header must be even (%04x)\n", __func__, header);
     513    /* The skip length must be even. */
     514    if (skip_b & 1) {
     515        DBG_AHCI("%s: skip must be even (%04x)\n", __func__, skip_b);
    497516        return 1;
    498517    }
     
    501520    device_id = device_id - BX_MAX_ATA_DEVICES - BX_MAX_SCSI_DEVICES;
    502521
    503     DBG_AHCI("%s: reading %lu bytes, header %u, device %d, port %d\n", __func__,
    504              length, header, device_id, bios_dsk->ahcidev[device_id].port);
     522    DBG_AHCI("%s: reading %lu bytes, skip %u/%u, device %d, port %d\n", __func__,
     523             length, bios_dsk->drqp.skip_b, bios_dsk->drqp.skip_a,
     524             device_id, bios_dsk->ahcidev[device_id].port);
    505525    DBG_AHCI("%s: reading %u %u-byte sectors\n", __func__,
    506526             bios_dsk->drqp.nsect, bios_dsk->drqp.sect_sz);
     
    520540    bios_dsk->drqp.trsfsectors = 0;
    521541    bios_dsk->drqp.trsfbytes   = 0;
     542
     543    /* Set up a PRD entry to throw away the beginning of the transfer. */
     544    if (bios_dsk->drqp.skip_b) {
     545        ahci->aPrdt[0].len       = bios_dsk->drqp.skip_b - 1;
     546        ahci->aPrdt[0].phys_addr = ahci->sink_buf_phys;
     547        ahci->cur_prd++;
     548    }
    522549
    523550    ahci_cmd_data(bios_dsk, ATA_CMD_PACKET);
     
    761788    ahci->iobase   = io_base;
    762789
     790    /* Physical address of memory used for throwing away ATAPI data when reading 512-byte
     791     * blocks from 2048-byte CD sectors.
     792     */
     793    ahci->sink_buf_phys = 0xCC000;  //@todo: find some better place!
     794
    763795    /* Reset the controller. */
    764796    ahci_ctrl_set_bits(io_base, AHCI_REG_GHC, AHCI_GHC_HR);
  • trunk/src/VBox/Devices/PC/BIOS-new/ebda.h

    r39560 r39597  
    201201    uint16_t    trsfsectors;        /* Actual sectors transferred. */
    202202    uint32_t    trsfbytes;          /* Actual bytes transferred. */
     203    uint16_t    skip_b;             /* Bytes to skip before transfer. */
     204    uint16_t    skip_a;             /* Bytes to skip after transfer. */
    203205} disk_req_t;
    204206
  • trunk/src/VBox/Devices/PC/BIOS-new/eltorito.c

    r39583 r39597  
    366366    bios_dsk->drqp.sect_sz = 512;
    367367
     368    bios_dsk->drqp.skip_a = 2048 - nbsectors * 512L % 2048;
     369
    368370    if (device > BX_MAX_ATA_DEVICES)
    369371        error = ahci_cmd_packet(device, 12, (char __far *)&atapicmd, 0, nbsectors*512L, ATA_DATA_IN, MK_FP(boot_segment,0));
    370372    else
    371373        error = ata_cmd_packet(device, 12, (char __far *)&atapicmd, 0, nbsectors*512L, ATA_DATA_IN, MK_FP(boot_segment,0));
     374
     375    bios_dsk->drqp.skip_a = 0;
     376
    372377    if (error != 0)
    373378        return 12;
     
    529534       
    530535        // start lba on cd
    531         slba  = (uint32_t)vlba/4;
    532         before= (uint32_t)vlba%4;
     536        slba   = (uint32_t)vlba / 4;
     537        before = (uint32_t)vlba % 4;
    533538       
    534539        // end lba on cd
    535         elba = (uint32_t)(vlba+nbsectors-1)/4;
     540        elba = (uint32_t)(vlba + nbsectors - 1) / 4;
    536541
    537542        _fmemset(&atapicmd, 0, sizeof(atapicmd));
     
    543548        bios_dsk->drqp.sect_sz = 512;
    544549
     550        bios_dsk->drqp.skip_b = before * 512;
     551        bios_dsk->drqp.skip_a = 2048 - nbsectors * 512L % 2048 - bios_dsk->drqp.skip_b;
     552
    545553        if (device > BX_MAX_ATA_DEVICES)
    546554            status = ahci_cmd_packet(device, 12, (char __far *)&atapicmd, before*512, nbsectors*512L, ATA_DATA_IN, MK_FP(segment,offset));
    547555        else
    548556            status = ata_cmd_packet(device, 12, (char __far *)&atapicmd, before*512, nbsectors*512L, ATA_DATA_IN, MK_FP(segment,offset));
     557
     558        bios_dsk->drqp.skip_b = 0;
     559        bios_dsk->drqp.skip_a = 0;
    549560
    550561        if (status != 0) {
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