Changeset 106027 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Sep 12, 2024 11:24:04 AM (3 months ago)
- Location:
- trunk/src/VBox/Devices/PC/BIOS
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/BIOS/ahci.c
r104068 r106027 348 348 static uint16_t ahci_cmd_data(bio_dsk_t __far *bios_dsk, uint8_t cmd) 349 349 { 350 ahci_t __far *ahci = bios_dsk->ahci_seg:> 0;350 ahci_t __far *ahci = (read_word(0x0040, 0x000E) + bios_dsk->ahci_ofs) :> 0; 351 351 uint16_t n_sect = bios_dsk->drqp.nsect; 352 352 uint16_t sectsz = bios_dsk->drqp.sect_sz; … … 524 524 uint16_t device_id; 525 525 uint16_t rc; 526 uint16_t ahci_seg = read_word(0x0040, 0x000E) + bios_dsk->ahci_ofs; 526 527 527 528 device_id = VBOX_GET_AHCI_DEVICE(bios_dsk->drqp.dev_id); … … 533 534 device_id, bios_dsk->ahcidev[device_id].port); 534 535 535 high_bits_save( bios_dsk->ahci_seg :> 0);536 ahci_port_init( bios_dsk->ahci_seg :> 0, bios_dsk->ahcidev[device_id].port);536 high_bits_save(ahci_seg :> 0); 537 ahci_port_init(ahci_seg :> 0, bios_dsk->ahcidev[device_id].port); 537 538 rc = ahci_cmd_data(bios_dsk, AHCI_CMD_READ_DMA_EXT); 538 539 DBG_AHCI("%s: transferred %lu bytes\n", __func__, ((ahci_t __far *)(bios_dsk->ahci_seg :> 0))->aCmdHdr[1]); … … 541 542 rep_movsw(bios_dsk->drqp.buffer, bios_dsk->drqp.buffer, bios_dsk->drqp.nsect * 512 / 2); 542 543 #endif 543 high_bits_restore( bios_dsk->ahci_seg :> 0);544 high_bits_restore(ahci_seg :> 0); 544 545 return rc; 545 546 } … … 556 557 uint16_t device_id; 557 558 uint16_t rc; 559 uint16_t ahci_seg = read_word(0x0040, 0x000E) + bios_dsk->ahci_ofs; 558 560 559 561 device_id = VBOX_GET_AHCI_DEVICE(bios_dsk->drqp.dev_id); … … 565 567 bios_dsk->ahcidev[device_id].port); 566 568 567 high_bits_save( bios_dsk->ahci_seg :> 0);568 ahci_port_init( bios_dsk->ahci_seg :> 0, bios_dsk->ahcidev[device_id].port);569 high_bits_save(ahci_seg :> 0); 570 ahci_port_init(ahci_seg :> 0, bios_dsk->ahcidev[device_id].port); 569 571 rc = ahci_cmd_data(bios_dsk, AHCI_CMD_WRITE_DMA_EXT); 570 572 DBG_AHCI("%s: transferred %lu bytes\n", __func__, ((ahci_t __far *)(bios_dsk->ahci_seg :> 0))->aCmdHdr[1]); 571 573 bios_dsk->drqp.trsfsectors = bios_dsk->drqp.nsect; 572 high_bits_restore( bios_dsk->ahci_seg :> 0);574 high_bits_restore(ahci_seg :> 0); 573 575 return rc; 574 576 } … … 582 584 uint32_t length, uint8_t inout, char __far *buffer) 583 585 { 584 bio_dsk_t __far *bios_dsk = read_word(0x0040, 0x000E) :> &EbdaData->bdisk; 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; 585 589 ahci_t __far *ahci; 586 590 … … 604 608 // bios_dsk->drqp.sect_sz = 2048; 605 609 606 ahci = bios_dsk->ahci_seg :> 0;610 ahci = ahci_seg :> 0; 607 611 high_bits_save(ahci); 608 612 609 ahci_port_init( bios_dsk->ahci_seg :> 0, bios_dsk->ahcidev[device_id].port);613 ahci_port_init(ahci_seg :> 0, bios_dsk->ahcidev[device_id].port); 610 614 611 615 /* Copy the ATAPI command where the HBA can fetch it. */ … … 825 829 826 830 /** 827 * Allocates 1K of conventional memory.828 */829 static uint16_t ahci_mem_alloc(void)830 {831 uint16_t base_mem_kb;832 uint16_t ahci_seg;833 834 base_mem_kb = read_word(0x00, 0x0413);835 836 DBG_AHCI("AHCI: %dK of base mem\n", base_mem_kb);837 838 if (base_mem_kb == 0)839 return 0;840 841 base_mem_kb--; /* Allocate one block. */842 ahci_seg = (((uint32_t)base_mem_kb * 1024) >> 4); /* Calculate start segment. */843 844 write_word(0x00, 0x0413, base_mem_kb);845 846 return ahci_seg;847 }848 849 /**850 831 * Initializes the AHCI HBA and detects attached devices. 851 832 */ … … 855 836 uint32_t val; 856 837 uint16_t ebda_seg; 838 uint16_t ahci_ofs; 857 839 uint16_t ahci_seg; 858 840 bio_dsk_t __far *bios_dsk; 859 841 ahci_t __far *ahci; 860 842 843 /* Allocate 1K of base memory (this will move the EBDA). */ 844 ahci_ofs = ebda_mem_alloc(1/*KB*/); 845 if (ahci_ofs == 0) 846 { 847 DBG_AHCI("AHCI: Could not allocate 1K of memory\n"); 848 return 0; 849 } 861 850 862 851 ebda_seg = read_word(0x0040, 0x000E); 852 ahci_seg = ebda_seg + ahci_ofs; 863 853 bios_dsk = ebda_seg :> &EbdaData->bdisk; 864 854 … … 868 858 ahci_ctrl_extract_bits(val, 0x0000ffff, 0)); 869 859 870 /* Allocate 1K of base memory. */ 871 ahci_seg = ahci_mem_alloc(); 872 if (ahci_seg == 0) 873 { 874 DBG_AHCI("AHCI: Could not allocate 1K of memory, can't boot from controller\n"); 875 return 0; 876 } 877 DBG_AHCI("AHCI: ahci_seg=%04x, size=%04x, pointer at EBDA:%04x (EBDA size=%04x)\n", 878 ahci_seg, sizeof(ahci_t), (uint16_t)&EbdaData->bdisk.ahci_seg, sizeof(ebda_data_t)); 879 880 bios_dsk->ahci_seg = ahci_seg; 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; 881 864 bios_dsk->ahci_devcnt = 0; 882 865 -
trunk/src/VBox/Devices/PC/BIOS/biosint.h
r98103 r106027 283 283 extern void delay_boot(uint16_t secs); 284 284 extern bx_bool set_enable_a20(bx_bool val); 285 extern uint16_t ebda_mem_alloc(int n_kb); 285 286 286 287 #define printf(...) bios_printf(BIOS_PRINTF_SCREEN, __VA_ARGS__) -
trunk/src/VBox/Devices/PC/BIOS/ebda.h
r104194 r106027 198 198 /* SCSI specific device information. */ 199 199 typedef struct { 200 uint16_t hba_ seg; /* Segment of HBA driver data block. */200 uint16_t hba_ofs; /* Offset (in paragraphs) of HBA driver data block within EBDA. */ 201 201 uint8_t idx_hba; /* The HBA driver to use. */ 202 202 uint8_t target_id; /* Target ID. */ … … 285 285 ahci_dev_t ahcidev[BX_MAX_AHCI_DEVICES]; 286 286 uint8_t ahci_devcnt; /* Number of SATA devices. */ 287 uint16_t ahci_ seg; /* Segment of AHCI data block. */287 uint16_t ahci_ofs; /* Offset (in paragraphs) of AHCI data block within EBDA. */ 288 288 #endif 289 289 -
trunk/src/VBox/Devices/PC/BIOS/post.c
r98103 r106027 217 217 218 218 #endif 219 220 /** 221 * Allocate n KB of conventional memory at the end of the EBDA. 222 * Returns offset (in paragraphs) to the allocated block within 223 * the EBDA. 224 * 225 * NB: By default, the EBDA is 1KB in size, located at 639KB 226 * into the start of memory (just below the video RAM). Optional 227 * BIOS components may need additional real-mode addressable RAM 228 * which is added to the EBDA. 229 * 230 * The EBDA should be relocatable as a whole. All pointers to 231 * the EBDA must be relative, actual address is calculated from 232 * the value at 40:0E. 233 * 234 * Items like PS/2 mouse support must be at a fixed offset from 235 * the start of the EBDA. Therefore, any additional memory gets 236 * allocated at the end and the original EBDA contents are 237 * shifted down. 238 * 239 * WARNING: When successful, this function moves the EBDA! 240 */ 241 uint16_t ebda_mem_alloc(int n_kb) 242 { 243 uint16_t base_mem_kb; 244 uint16_t ebda_kb; 245 uint16_t user_ofs; /* Offset and size in paragraphs */ 246 uint16_t user_size; 247 uint16_t old_ebda_seg; 248 uint16_t new_ebda_seg; 249 250 base_mem_kb = read_word(0x00, 0x0413); 251 252 DPRINT("BIOS: %dK of base mem, removing %dK\n", base_mem_kb, n_kb); 253 254 if (base_mem_kb == 0) 255 return 0; 256 257 /* Reduce conventional memory size and update the BDA. */ 258 base_mem_kb -= n_kb; 259 write_word(0x0040, 0x0013, base_mem_kb); 260 261 /* Figure out what's where. */ 262 old_ebda_seg = read_word(0x0040, 0x000E); 263 ebda_kb = read_byte(old_ebda_seg, 0); 264 user_ofs = ebda_kb * (1024 / 16); /* Old EBDA size == new mem offset. */ 265 user_size = n_kb * (1024 / 16); 266 267 /* Shift the existing EBDA down. */ 268 new_ebda_seg = old_ebda_seg - user_size; 269 /* This is where we should be using memmove(), but we know how our own memcpy() works. */ 270 _fmemcpy(MK_FP(new_ebda_seg, 0), MK_FP(old_ebda_seg, 0), user_ofs * 16); 271 _fmemset(MK_FP(new_ebda_seg + user_ofs, 0), 0, user_size * 16); 272 273 /* Update the EBDA location and size. */ 274 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 -
trunk/src/VBox/Devices/PC/BIOS/scsi.c
r100984 r106027 104 104 105 105 /** 106 * Allocates 1K of conventional memory.107 */108 static uint16_t scsi_hba_mem_alloc(void)109 {110 uint16_t base_mem_kb;111 uint16_t hba_seg;112 113 base_mem_kb = read_word(0x00, 0x0413);114 115 DBG_SCSI("SCSI: %dK of base mem\n", base_mem_kb);116 117 if (base_mem_kb == 0)118 return 0;119 120 base_mem_kb--; /* Allocate one block. */121 hba_seg = (((uint32_t)base_mem_kb * 1024) >> 4); /* Calculate start segment. */122 123 write_word(0x00, 0x0413, base_mem_kb);124 125 return hba_seg;126 }127 128 /**129 106 * Read sectors from an attached SCSI device. 130 107 * … … 160 137 161 138 162 hba_seg = bios_dsk->scsidev[device_id].hba_seg;139 hba_seg = read_word(0x0040, 0x000E) + bios_dsk->scsidev[device_id].hba_ofs; 163 140 idx_hba = bios_dsk->scsidev[device_id].idx_hba; 164 141 target_id = bios_dsk->scsidev[device_id].target_id; … … 213 190 cdb.pad2 = 0; 214 191 215 hba_seg = bios_dsk->scsidev[device_id].hba_seg;192 hba_seg = read_word(0x0040, 0x000E) + bios_dsk->scsidev[device_id].hba_ofs; 216 193 idx_hba = bios_dsk->scsidev[device_id].idx_hba; 217 194 target_id = bios_dsk->scsidev[device_id].target_id; … … 275 252 276 253 high_bits_save(&eax_hi); 277 hba_seg = bios_dsk->scsidev[device_id].hba_seg;254 hba_seg = read_word(0x0040, 0x000E) + bios_dsk->scsidev[device_id].hba_ofs; 278 255 idx_hba = bios_dsk->scsidev[device_id].idx_hba; 279 256 target_id = bios_dsk->scsidev[device_id].target_id; … … 301 278 * 302 279 * @param hba_seg Segement of the HBA controller block. 280 * @param hba_ofs Offset of the HBA controller block within the EBDA. 303 281 * @param idx_hba The HBA driver index used for accessing the enumerated devices. 304 282 */ 305 static void scsi_enumerate_attached_devices(uint16_t hba_seg, uint 8_t idx_hba)283 static void scsi_enumerate_attached_devices(uint16_t hba_seg, uint16_t hba_ofs, uint8_t idx_hba) 306 284 { 307 285 int i; … … 433 411 hd_index = devcount_scsi + BX_MAX_ATA_DEVICES; 434 412 435 bios_dsk->scsidev[devcount_scsi].hba_ seg = hba_seg;413 bios_dsk->scsidev[devcount_scsi].hba_ofs = hba_ofs; 436 414 bios_dsk->scsidev[devcount_scsi].idx_hba = idx_hba; 437 415 bios_dsk->scsidev[devcount_scsi].target_id = i; … … 494 472 removable = buffer[1] & 0x80 ? 1 : 0; 495 473 496 bios_dsk->scsidev[devcount_scsi].hba_ seg = hba_seg;474 bios_dsk->scsidev[devcount_scsi].hba_ofs = hba_ofs; 497 475 bios_dsk->scsidev[devcount_scsi].idx_hba = idx_hba; 498 476 bios_dsk->scsidev[devcount_scsi].target_id = i; … … 544 522 int rc; 545 523 uint8_t u8Bus, u8DevFn; 546 uint16_t hba_seg = scsi_hba_mem_alloc(); 547 if (hba_seg == 0) /* No point in trying the rest if we are out of memory. */ 524 uint16_t hba_seg; 525 uint16_t hba_ofs = ebda_mem_alloc(1/*KB*/); 526 if (hba_ofs == 0) /* No point in trying the rest if we are out of memory. */ 548 527 break; 528 529 hba_seg = read_word(0x0040, 0x000E) + hba_ofs; 549 530 550 531 u8Bus = (busdevfn & 0xff00) >> 8; … … 554 535 rc = hbaacc[i].init(hba_seg :> 0, u8Bus, u8DevFn); 555 536 if (!rc) 556 scsi_enumerate_attached_devices(hba_seg, i);537 scsi_enumerate_attached_devices(hba_seg, hba_ofs, i); 557 538 /** @todo Free memory on error. */ 558 539 }
Note:
See TracChangeset
for help on using the changeset viewer.