Changeset 89363 in vbox
- Timestamp:
- May 28, 2021 3:20:23 PM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 144712
- Location:
- trunk/src/VBox/Devices/PC/BIOS
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/BIOS/ebda.h
r89168 r89363 304 304 uint16_t sector_count; 305 305 chs_t vdevice; /* Virtual device geometry. */ 306 uint8_t __far *ptr_unaligned; /* Bounce buffer for sector unaligned reads. */ 306 307 } cdemu_t; 307 308 #endif -
trunk/src/VBox/Devices/PC/BIOS/eltorito.c
r89168 r89363 79 79 #endif 80 80 81 #define MIN(a, b) ((a) < (b) ? (a) : (b)) 81 82 82 83 /// @todo put in a header … … 153 154 extern int diskette_param_table; 154 155 156 /** 157 * Allocates 2K of conventional memory. 158 */ 159 static uint16_t cdemu_bounce_buf_alloc(void) 160 { 161 uint16_t base_mem_kb; 162 uint16_t bounce_seg; 163 164 base_mem_kb = read_word(0x00, 0x0413); 165 if (base_mem_kb == 0) 166 return 0; 167 168 base_mem_kb -= 2; 169 bounce_seg = (((uint32_t)base_mem_kb * 1024) >> 4); /* Calculate start segment. */ 170 171 write_word(0x00, 0x0413, base_mem_kb); 172 173 return bounce_seg; 174 } 175 155 176 void BIOSCALL cdemu_init(void) 156 177 { 157 178 /// @todo a macro or a function for getting the EBDA segment 158 179 uint16_t ebda_seg = read_word(0x0040,0x000E); 180 cdemu_t __far *cdemu = ebda_seg :> &EbdaData->cdemu; 159 181 160 182 // the only important data is this one for now 161 write_byte(ebda_seg,(uint16_t)&EbdaData->cdemu.active, 0x00); 183 cdemu->active = 0x00; 184 cdemu->ptr_unaligned = cdemu_bounce_buf_alloc() :> 0; 162 185 } 163 186 … … 272 295 } 273 296 297 static uint16_t atapi_read(uint8_t device, uint32_t lba, uint16_t nbsectors, void __far *buf) 298 { 299 uint16_t ebda_seg=read_word(0x0040,0x000E); 300 cdb_atapi atapicmd; 301 bio_dsk_t __far *bios_dsk = ebda_seg :> &EbdaData->bdisk; 302 303 atapicmd.command = 0x28; // READ 10 command 304 atapicmd.lba = swap_32(lba); 305 atapicmd.nsect = swap_16(nbsectors); 306 307 bios_dsk->drqp.nsect = nbsectors; 308 bios_dsk->drqp.sect_sz = 2048L; 309 bios_dsk->drqp.skip_b = 0; 310 bios_dsk->drqp.skip_a = 0; 311 312 return pktacc[bios_dsk->devices[device].type](device, 12, (char __far *)&atapicmd, 0, nbsectors*2048L, ATA_DATA_IN, buf); 313 } 314 315 static uint16_t cdemu_read(uint8_t device, uint32_t lba, uint16_t nbsectors, void __far *buf) 316 { 317 uint16_t ebda_seg=read_word(0x0040,0x000E); 318 uint16_t error; 319 cdemu_t __far *cdemu = ebda_seg :> &EbdaData->cdemu; 320 uint32_t ilba = cdemu->ilba; 321 uint32_t slba; 322 uint16_t before; 323 uint8_t __far *dst = (uint8_t __far *)buf; 324 325 BX_DEBUG_ELTORITO("cdemu_read: lba=%lu nbsectors=%u\n", lba, nbsectors); 326 327 // start lba on cd 328 slba = (uint32_t)lba / 4; 329 before = (uint32_t)lba % 4; 330 331 // Unaligned start will go to a bounce buffer first. 332 if (before) 333 { 334 uint16_t xfer_sect = MIN(nbsectors, 4 - before); 335 336 error = atapi_read(device, ilba + slba, 1, cdemu->ptr_unaligned); 337 if (error != 0) 338 return error; 339 340 _fmemcpy(dst, cdemu->ptr_unaligned + before * 512L, xfer_sect * 512L); 341 dst += xfer_sect * 512L; 342 nbsectors -= xfer_sect; 343 slba++; 344 } 345 346 // Now for the aligned part. 347 if (nbsectors / 4) 348 { 349 uint16_t xfer_sect = nbsectors / 4; 350 351 error = atapi_read(device, ilba + slba, xfer_sect, dst); 352 if (error != 0) 353 return error; 354 dst += xfer_sect * 2048L; 355 nbsectors -= xfer_sect; 356 slba += xfer_sect; 357 } 358 359 // Now for the unaligned end. 360 if (nbsectors) 361 { 362 error = atapi_read(device, ilba + slba, 1, cdemu->ptr_unaligned); 363 if (error != 0) 364 return error; 365 366 _fmemcpy(dst, cdemu->ptr_unaligned, nbsectors * 512); 367 } 368 369 return error; 370 } 371 274 372 // --------------------------------------------------------------------------- 275 373 // End of ATA/ATAPI generic functions … … 285 383 uint16_t ebda_seg=read_word(0x0040,0x000E); 286 384 uint8_t buffer[2048]; 287 cdb_atapi atapicmd;288 385 uint32_t lba; 289 386 uint16_t boot_segment, nbsectors, i, error; … … 307 404 308 405 /* Read the Boot Record Volume Descriptor (BRVD). */ 309 _fmemset(&atapicmd, 0, sizeof(atapicmd));310 atapicmd.command = 0x28; // READ 10 command311 atapicmd.lba = swap_32(0x11);312 atapicmd.nsect = swap_16(1);313 314 bios_dsk->drqp.nsect = 1;315 bios_dsk->drqp.sect_sz = 2048;316 317 406 for (read_try = 0; read_try <= 4; ++read_try) 318 407 { 319 error = pktacc[bios_dsk->devices[device].type](device, 12, (char __far *)&atapicmd, 0, 2048L, ATA_DATA_IN, &buffer);408 error = atapi_read(device, 0x11, 1, &buffer); 320 409 if (!error) 321 410 break; … … 341 430 342 431 /* Now we read the Boot Catalog. */ 343 atapicmd.command = 0x28; // READ 10 command 344 atapicmd.lba = swap_32(lba); 345 atapicmd.nsect = swap_16(1); 346 347 #if 0 // Not necessary as long as previous values are reused 348 bios_dsk->drqp.nsect = 1; 349 bios_dsk->drqp.sect_sz = 512; 350 #endif 351 352 error = pktacc[bios_dsk->devices[device].type](device, 12, (char __far *)&atapicmd, 0, 2048L, ATA_DATA_IN, &buffer); 432 error = atapi_read(device, lba, 1, buffer); 353 433 if (error != 0) 354 434 return 7; … … 407 487 408 488 /* Read the disk image's boot sector into memory. */ 409 atapicmd.command = 0x28; // READ 10 command 410 atapicmd.lba = swap_32(lba); 411 atapicmd.nsect = swap_16(1 + (nbsectors - 1) / 4); 412 413 bios_dsk->drqp.nsect = 1 + (nbsectors - 1) / 4; 414 bios_dsk->drqp.sect_sz = 512; 415 416 bios_dsk->drqp.skip_a = (2048 - nbsectors * 512) % 2048; 417 418 error = pktacc[bios_dsk->devices[device].type](device, 12, (char __far *)&atapicmd, 0, nbsectors*512L, ATA_DATA_IN, MK_FP(boot_segment,0)); 419 420 bios_dsk->drqp.skip_a = 0; 421 489 error = cdemu_read(device, 0, nbsectors, MK_FP(boot_segment,0)); 422 490 if (error != 0) 423 491 return 13; … … 482 550 uint16_t vheads, vspt, vcylinders; 483 551 uint16_t head, sector, cylinder, nbsectors; 484 uint32_t vlba, ilba, slba, elba; 485 uint16_t before, segment, offset; 486 cdb_atapi atapicmd; 552 uint32_t vlba; 553 uint16_t segment, offset; 487 554 cdemu_t __far *cdemu; 488 555 bio_dsk_t __far *bios_dsk; … … 554 621 vcylinders = cdemu->vdevice.cylinders; 555 622 vheads = cdemu->vdevice.heads; 556 ilba = cdemu->ilba;557 623 558 624 sector = GET_CL() & 0x003f; … … 590 656 SET_AL(nbsectors); 591 657 592 // start lba on cd 593 slba = (uint32_t)vlba / 4; 594 before = (uint32_t)vlba % 4; 595 596 // end lba on cd 597 elba = (uint32_t)(vlba + nbsectors - 1) / 4; 598 599 _fmemset(&atapicmd, 0, sizeof(atapicmd)); 600 atapicmd.command = 0x28; // READ 10 command 601 atapicmd.lba = swap_32(ilba + slba); 602 atapicmd.nsect = swap_16(elba - slba + 1); 603 604 bios_dsk->drqp.nsect = nbsectors; 605 bios_dsk->drqp.sect_sz = 512; 606 607 bios_dsk->drqp.skip_b = before * 512; 608 bios_dsk->drqp.skip_a = ((4 - nbsectors % 4 - before) * 512) % 2048; 609 610 status = pktacc[bios_dsk->devices[device].type](device, 12, (char __far *)&atapicmd, before*512, nbsectors*512L, ATA_DATA_IN, MK_FP(segment,offset)); 611 612 bios_dsk->drqp.skip_b = 0; 613 bios_dsk->drqp.skip_a = 0; 614 658 status = cdemu_read(device, vlba, nbsectors, MK_FP(segment,offset)); 615 659 if (status != 0) { 616 660 BX_INFO("%s: function %02x, error %02x !\n", __func__, GET_AH(), status); … … 691 735 __func__, count, lba, segment, offset); 692 736 693 nbsectors = count; 694 vlba = lba; 695 ilba = cdemu->ilba; 696 697 // start lba on cd 698 slba = (uint32_t)vlba / 4; 699 before = (uint32_t)vlba % 4; 700 701 // end lba on cd 702 elba = (uint32_t)(vlba + nbsectors - 1) / 4; 703 704 _fmemset(&atapicmd, 0, sizeof(atapicmd)); 705 atapicmd.command = 0x28; // READ 10 command 706 atapicmd.lba = swap_32(ilba + slba); 707 atapicmd.nsect = swap_16(elba - slba + 1); 708 709 bios_dsk->drqp.skip_b = before * 512; 710 bios_dsk->drqp.skip_a = ((4 - nbsectors % 4 - before) * 512) % 2048; 711 712 status = pktacc[bios_dsk->devices[device].type](device, 12, (char __far *)&atapicmd, before*512, nbsectors*512L, ATA_DATA_IN, MK_FP(segment,offset)); 713 714 bios_dsk->drqp.skip_b = 0; 715 bios_dsk->drqp.skip_a = 0; 716 737 status = cdemu_read(device, lba, count, MK_FP(segment,offset)); 717 738 count = (uint16_t)(bios_dsk->drqp.trsfbytes >> 9); 718 739 i13x->count = count; … … 774 795 uint16_t ebda_seg = read_word(0x0040,0x000E); 775 796 uint8_t device, status, locks; 776 cdb_atapi atapicmd;777 797 uint32_t lba; 778 798 uint16_t count, segment, offset; … … 875 895 __func__, count, lba, segment, offset); 876 896 877 _fmemset(&atapicmd, 0, sizeof(atapicmd)); 878 atapicmd.command = 0x28; // READ 10 command 879 atapicmd.lba = swap_32(lba); 880 atapicmd.nsect = swap_16(count); 881 882 bios_dsk->drqp.nsect = count; 883 bios_dsk->drqp.sect_sz = 2048; 884 885 status = pktacc[bios_dsk->devices[device].type](device, 12, (char __far *)&atapicmd, 0, count*2048L, ATA_DATA_IN, MK_FP(segment,offset)); 886 897 status = atapi_read(device, lba, count, MK_FP(segment,offset)); 887 898 count = (uint16_t)(bios_dsk->drqp.trsfbytes >> 11); 888 899 i13x->count = count;
Note:
See TracChangeset
for help on using the changeset viewer.