Changeset 39597 in vbox for trunk/src/VBox/Devices/PC/BIOS-new
- Timestamp:
- Dec 13, 2011 5:03:01 PM (13 years ago)
- 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 83 83 /** Current port which uses the memory to communicate with the controller. */ 84 84 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; 85 89 /** VDS EDDS DMA buffer descriptor structure. */ 86 90 vds_edds edds; … … 235 239 * Issues a command to the SATA controller and waits for completion. 236 240 */ 237 static void ahci_port_cmd_sync(ahci_t __far *ahci, uint8_t val , uint16_t cbData)241 static void ahci_port_cmd_sync(ahci_t __far *ahci, uint8_t val) 238 242 { 239 243 uint16_t io_base; … … 246 250 { 247 251 /* 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; 250 254 ahci->aCmdHdr[2] = ahci_addr_to_phys(&ahci->abCmd[0]); 251 255 … … 286 290 uint16_t n_sect = bios_dsk->drqp.nsect; 287 291 uint16_t sectsz = bios_dsk->drqp.sect_sz; 292 uint16_t prdt_idx; 288 293 289 294 _fmemset(&ahci->abCmd[0], 0, sizeof(ahci->abCmd)); … … 310 315 /* Lock memory needed for DMA. */ 311 316 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); 312 319 vds_build_sg_list(&ahci->edds, bios_dsk->drqp.buffer, (uint32_t)n_sect * sectsz); 313 320 321 prdt_idx = ahci->cur_prd; 322 314 323 /* 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'). */ 319 337 if (cmd == AHCI_CMD_WRITE_DMA_EXT) 320 338 cmd = RT_BIT_32(6); /* Indicate a write to device. */ … … 327 345 cmd |= 5; /* Five DWORDs. */ 328 346 329 ahci_port_cmd_sync(ahci, cmd , n_sect * sectsz);347 ahci_port_cmd_sync(ahci, cmd); 330 348 331 349 /* Unlock the buffer again. */ … … 422 440 423 441 ahci->cur_port = u8Port; 442 ahci->cur_prd = 0; 424 443 } 425 444 … … 481 500 482 501 uint16_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) 484 503 { 485 504 bio_dsk_t __far *bios_dsk = read_word(0x0040, 0x000E) :> &EbdaData->bdisk; … … 492 511 } 493 512 494 /* The headerlength 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); 497 516 return 1; 498 517 } … … 501 520 device_id = device_id - BX_MAX_ATA_DEVICES - BX_MAX_SCSI_DEVICES; 502 521 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); 505 525 DBG_AHCI("%s: reading %u %u-byte sectors\n", __func__, 506 526 bios_dsk->drqp.nsect, bios_dsk->drqp.sect_sz); … … 520 540 bios_dsk->drqp.trsfsectors = 0; 521 541 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 } 522 549 523 550 ahci_cmd_data(bios_dsk, ATA_CMD_PACKET); … … 761 788 ahci->iobase = io_base; 762 789 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 763 795 /* Reset the controller. */ 764 796 ahci_ctrl_set_bits(io_base, AHCI_REG_GHC, AHCI_GHC_HR); -
trunk/src/VBox/Devices/PC/BIOS-new/ebda.h
r39560 r39597 201 201 uint16_t trsfsectors; /* Actual sectors transferred. */ 202 202 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. */ 203 205 } disk_req_t; 204 206 -
trunk/src/VBox/Devices/PC/BIOS-new/eltorito.c
r39583 r39597 366 366 bios_dsk->drqp.sect_sz = 512; 367 367 368 bios_dsk->drqp.skip_a = 2048 - nbsectors * 512L % 2048; 369 368 370 if (device > BX_MAX_ATA_DEVICES) 369 371 error = ahci_cmd_packet(device, 12, (char __far *)&atapicmd, 0, nbsectors*512L, ATA_DATA_IN, MK_FP(boot_segment,0)); 370 372 else 371 373 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 372 377 if (error != 0) 373 378 return 12; … … 529 534 530 535 // 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; 533 538 534 539 // end lba on cd 535 elba = (uint32_t)(vlba +nbsectors-1)/4;540 elba = (uint32_t)(vlba + nbsectors - 1) / 4; 536 541 537 542 _fmemset(&atapicmd, 0, sizeof(atapicmd)); … … 543 548 bios_dsk->drqp.sect_sz = 512; 544 549 550 bios_dsk->drqp.skip_b = before * 512; 551 bios_dsk->drqp.skip_a = 2048 - nbsectors * 512L % 2048 - bios_dsk->drqp.skip_b; 552 545 553 if (device > BX_MAX_ATA_DEVICES) 546 554 status = ahci_cmd_packet(device, 12, (char __far *)&atapicmd, before*512, nbsectors*512L, ATA_DATA_IN, MK_FP(segment,offset)); 547 555 else 548 556 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; 549 560 550 561 if (status != 0) {
Note:
See TracChangeset
for help on using the changeset viewer.