VirtualBox

Changeset 106051 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Sep 13, 2024 4:03:16 PM (6 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
164810
Message:

BIOS: Don't allocate AHCI data in EBDA, it can't be sagely relocated as it requires 1K alignment (see bugref:6549).

Location:
trunk/src/VBox/Devices/PC/BIOS
Files:
5 edited

Legend:

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

    r106027 r106051  
    348348static uint16_t ahci_cmd_data(bio_dsk_t __far *bios_dsk, uint8_t cmd)
    349349{
    350     ahci_t __far    *ahci  = (read_word(0x0040, 0x000E) + bios_dsk->ahci_ofs) :> 0;
     350    ahci_t __far    *ahci  = bios_dsk->ahci_seg :> 0;
    351351    uint16_t        n_sect = bios_dsk->drqp.nsect;
    352352    uint16_t        sectsz = bios_dsk->drqp.sect_sz;
     
    524524    uint16_t        device_id;
    525525    uint16_t        rc;
    526     uint16_t        ahci_seg = read_word(0x0040, 0x000E) + bios_dsk->ahci_ofs;
    527526
    528527    device_id = VBOX_GET_AHCI_DEVICE(bios_dsk->drqp.dev_id);
     
    534533             device_id, bios_dsk->ahcidev[device_id].port);
    535534
    536     high_bits_save(ahci_seg :> 0);
    537     ahci_port_init(ahci_seg :> 0, bios_dsk->ahcidev[device_id].port);
     535    high_bits_save(bios_dsk->ahci_seg :> 0);
     536    ahci_port_init(bios_dsk->ahci_seg :> 0, bios_dsk->ahcidev[device_id].port);
    538537    rc = ahci_cmd_data(bios_dsk, AHCI_CMD_READ_DMA_EXT);
    539538    DBG_AHCI("%s: transferred %lu bytes\n", __func__, ((ahci_t __far *)(bios_dsk->ahci_seg :> 0))->aCmdHdr[1]);
     
    542541    rep_movsw(bios_dsk->drqp.buffer, bios_dsk->drqp.buffer, bios_dsk->drqp.nsect * 512 / 2);
    543542#endif
    544     high_bits_restore(ahci_seg :> 0);
     543    high_bits_restore(bios_dsk->ahci_seg :> 0);
    545544    return rc;
    546545}
     
    557556    uint16_t        device_id;
    558557    uint16_t        rc;
    559     uint16_t        ahci_seg = read_word(0x0040, 0x000E) + bios_dsk->ahci_ofs;
    560558
    561559    device_id = VBOX_GET_AHCI_DEVICE(bios_dsk->drqp.dev_id);
     
    567565             bios_dsk->ahcidev[device_id].port);
    568566
    569     high_bits_save(ahci_seg :> 0);
    570     ahci_port_init(ahci_seg :> 0, bios_dsk->ahcidev[device_id].port);
     567    high_bits_save(bios_dsk->ahci_seg :> 0);
     568    ahci_port_init(bios_dsk->ahci_seg :> 0, bios_dsk->ahcidev[device_id].port);
    571569    rc = ahci_cmd_data(bios_dsk, AHCI_CMD_WRITE_DMA_EXT);
    572570    DBG_AHCI("%s: transferred %lu bytes\n", __func__, ((ahci_t __far *)(bios_dsk->ahci_seg :> 0))->aCmdHdr[1]);
    573571    bios_dsk->drqp.trsfsectors = bios_dsk->drqp.nsect;
    574     high_bits_restore(ahci_seg :> 0);
     572    high_bits_restore(bios_dsk->ahci_seg :> 0);
    575573    return rc;
    576574}
     
    584582                         uint32_t length, uint8_t inout, char __far *buffer)
    585583{
    586     uint16_t        ebda_seg = read_word(0x0040, 0x000E);
    587     bio_dsk_t __far *bios_dsk = ebda_seg :> &EbdaData->bdisk;
    588     uint16_t        ahci_seg = ebda_seg + bios_dsk->ahci_ofs;
     584    bio_dsk_t __far *bios_dsk = read_word(0x0040, 0x000E) :> &EbdaData->bdisk;
    589585    ahci_t __far    *ahci;
    590586
     
    608604//    bios_dsk->drqp.sect_sz = 2048;
    609605
    610     ahci = ahci_seg :> 0;
     606    ahci = bios_dsk->ahci_seg :> 0;
    611607    high_bits_save(ahci);
    612608
    613     ahci_port_init(ahci_seg :> 0, bios_dsk->ahcidev[device_id].port);
     609    ahci_port_init(bios_dsk->ahci_seg :> 0, bios_dsk->ahcidev[device_id].port);
    614610
    615611    /* Copy the ATAPI command where the HBA can fetch it. */
     
    836832    uint32_t            val;
    837833    uint16_t            ebda_seg;
    838     uint16_t            ahci_ofs;
    839834    uint16_t            ahci_seg;
    840835    bio_dsk_t __far     *bios_dsk;
    841836    ahci_t __far        *ahci;
    842837
    843     /* Allocate 1K of base memory (this will move the EBDA). */
    844     ahci_ofs = ebda_mem_alloc(1/*KB*/);
    845     if (ahci_ofs == 0)
     838    /* Allocate 1K of base memory (this will move the EBDA).
     839     * NB: The AHCI memory block must be 1K aligned. If the EBDA
     840     * gets relocated, it will land on a paragraph aligned boundary;
     841     * therefore the memory is allocated outside of the EBDA.
     842     */
     843    ahci_seg = conv_mem_alloc(1/*KB*/, 0/*in_ebda*/);
     844    if (ahci_seg == 0)
    846845    {
    847846        DBG_AHCI("AHCI: Could not allocate 1K of memory\n");
     
    850849
    851850    ebda_seg = read_word(0x0040, 0x000E);
    852     ahci_seg = ebda_seg + ahci_ofs;
    853851    bios_dsk = ebda_seg :> &EbdaData->bdisk;
    854852
     
    858856             ahci_ctrl_extract_bits(val, 0x0000ffff,  0));
    859857
    860     DBG_AHCI("AHCI: ahci_ofs=%04x, size=%04x, pointer at EBDA:%04x (EBDA size=%04x)\n",
    861              ahci_ofs, sizeof(ahci_t), (uint16_t)&EbdaData->bdisk.ahci_ofs, sizeof(ebda_data_t));
    862 
    863     bios_dsk->ahci_ofs    = ahci_ofs;
     858    DBG_AHCI("AHCI: ahci_seg=%04x, size=%04x, pointer at EBDA:%04x (EBDA size=%04x)\n",
     859             ahci_seg, sizeof(ahci_t), (uint16_t)&EbdaData->bdisk.ahci_seg, sizeof(ebda_data_t));
     860
     861    bios_dsk->ahci_seg    = ahci_seg;
    864862    bios_dsk->ahci_devcnt = 0;
    865863
  • trunk/src/VBox/Devices/PC/BIOS/biosint.h

    r106027 r106051  
    283283extern  void        delay_boot(uint16_t secs);
    284284extern  bx_bool     set_enable_a20(bx_bool val);
    285 extern  uint16_t    ebda_mem_alloc(int n_kb);
     285extern uint16_t     conv_mem_alloc(int n_kb, int in_ebda);
    286286
    287287#define printf(...)  bios_printf(BIOS_PRINTF_SCREEN, __VA_ARGS__)
  • trunk/src/VBox/Devices/PC/BIOS/ebda.h

    r106027 r106051  
    285285    ahci_dev_t  ahcidev[BX_MAX_AHCI_DEVICES];
    286286    uint8_t     ahci_devcnt;        /* Number of SATA devices. */
    287     uint16_t    ahci_ofs;           /* Offset (in paragraphs) of AHCI data block within EBDA. */
     287    uint16_t    ahci_seg;           /* Segment of AHCI data block. */
    288288#endif
    289289
  • trunk/src/VBox/Devices/PC/BIOS/post.c

    r106027 r106051  
    219219
    220220/**
    221  * Allocate n KB of conventional memory at the end of the EBDA.
     221 * Allocate n KB of conventional memory, and either add it to
     222 * the EBDA or just take it away from memory below 640K.
     223 *
    222224 * Returns offset (in paragraphs) to the allocated block within
    223  * the EBDA.
     225 * the EBDA when adding to the EBDA, or segment address when
     226 * allocating outside of the EBDA.
    224227 *
    225228 * NB: By default, the EBDA is 1KB in size, located at 639KB
     
    237240 * shifted down.
    238241 *
     242 * To make relocating the EBDA practical, the EBDA must
     243 * immediately follow the end of conventional memory. Therefore,
     244 * new
     245 *
    239246 * WARNING: When successful, this function moves the EBDA!
    240247 */
    241 uint16_t ebda_mem_alloc(int n_kb)
     248uint16_t conv_mem_alloc(int n_kb, int in_ebda)
    242249{
    243250    uint16_t        base_mem_kb;
     
    247254    uint16_t        old_ebda_seg;
    248255    uint16_t        new_ebda_seg;
     256    uint16_t        ret_val;
    249257
    250258    base_mem_kb = read_word(0x00, 0x0413);
     
    271279    _fmemset(MK_FP(new_ebda_seg + user_ofs, 0), 0, user_size * 16);
    272280
    273     /* Update the EBDA location and size. */
     281    /* Update the EBDA location and possibly size. */
    274282    write_word(0x0040, 0x000E, new_ebda_seg);
    275     write_byte(new_ebda_seg, 0, ebda_kb + n_kb);
    276 
    277     DPRINT("BIOS: added %04X paras at EBDA offset %04X\n", user_size, user_ofs);
    278 
    279     return user_ofs;
    280 }
    281 
     283    if (in_ebda) {
     284        write_byte(new_ebda_seg, 0, ebda_kb + n_kb);
     285        ret_val = user_ofs;
     286    } else {
     287        ret_val = new_ebda_seg + user_ofs;
     288    }
     289
     290    DPRINT("BIOS: added %04X paras ofs or seg %04X\n", user_size, ret_val);
     291    return ret_val;
     292}
     293
  • trunk/src/VBox/Devices/PC/BIOS/scsi.c

    r106027 r106051  
    523523            uint8_t  u8Bus, u8DevFn;
    524524            uint16_t hba_seg;
    525             uint16_t hba_ofs = ebda_mem_alloc(1/*KB*/);
     525            uint16_t hba_ofs = conv_mem_alloc(1/*KB*/, 1/*in_ebda*/);
    526526            if (hba_ofs == 0) /* No point in trying the rest if we are out of memory. */
    527527                break;
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