Currently bhyve only supports virtio disk for the guest's block device. This project will add AHCI device emulation to bhyve so that we can emulate normal cdroms and disks. This project will benefit bhyve a lot. First of all, since AHCI is widely supported in various Operating Systems, bhyve can support other nonproprietary and proprietary guest OSs without the virtio disk driver in those OSs. Secondly, this project will make it possible to install a GENERIC system from a emulated cdrom device.
Approach to solving the problem
As specified in AHCI spec, the AHCI sends command to the device through the so called Command List which consists of 1 to 32 command headers. Each command header points to one Command Table which includes a CFIS(Command FIS), an ATAPI command buffer and a bunch of PRDTs(Physical Region Descriptor Table). The data payload address and size can be gotten from the PRDT. So the key task of this project is to emulate the Command List, Command Table and PRDT entry. Another key task is to emulate the necessary ATA/ATAPI command with the backing file in the host filesystem.
Deliverables and Milestones
* June 17 - July 6: a bare bone pci_ahci.c following exisiting bhyve pci device emulation framework. The following features should be ready: The option parsing and backing file open etc. The pci config space such as device, vendor, class, subclass and progif. It means freebsd should recognize the device as an AHCI device. Global Host Control registers emulation: CAP, GHC, IS, PI and VS.
* July 6 - August 2: Port Registers emulation, command list and command table emulation and PRDT(Physical Region Descriptor table) entry emulation.
It should emulate the following Port Registers: PxCLB, PxCLBU, PxFB, PxFBU, PxIS, PxIE, PxCMD, PxTFD, PxSIG, PxSSTS, PxSCTL, PxSERR, PxSACT and PxCI. We can calculate the port number by (pe_read/write offset - 0x100)/0x80.
Command list and Command table emulation: We can calculate the command slot by searching which bit is set in the PxCI. Then we can get the command header from PxCLB and PxCLBU with the slot. And finally we get the command table from the command header. So we will parse the CFIS(Command FIS) in the command table to know the FIS type, command type and so on. Here we can emulate various ATA command with the backing file, such as ATA_READ_FPDMA_QUEUED, ATA_WRITE_FPDMA_QUEUED and so on.
PRDT entry emulation: We can get the PRDT table from the command header(CTBA+0x80). Then we setup the correct iovec struct of preadv()/pwritev()
* August 2 - August 24: ATA Command support. We don't need to support all ATA commands. In fact, to run FreeBSD I may just need to support the following ATA commands defined in : ATA_READ_DMA48, ATA_WRITE_DMA48, ATA_READ_FPDMA_QUEUED, ATA_WRITE_FPDMA_QUEUED, ATA_PACKET_CMD, ATA_ATAPI_IDENTIFY, ATA_STANDBY_IMMEDIATE, ATA_SLEEP, ATA_FLUSHCACHE, ATA_FLUSHCACHE48, ATA_ATA_IDENTIFY and ATA_SETFEATURES.
* August 25 - September 16: ATAPI Command support.
We can know it's for ATAPI either by
testing the "A" bit in Command header is set or not or
detecting the command in CFIS is ATA_PACKET_CMD or not.
Then we will parse and execute the ACMD(ATAPI Command) in the command table. I plan to support the following ATAPI command defined in : TEST_UNIT_READY, REQUEST_SENSE, INQUIRY, START_STOP_UNIT, PREVENT_ALLOW, READ_CAPACITY, READ_10, POSITION_TO_ELEMENT, MODE_SENSE_10 and READ_12.
NOTE: More ATA and ATAPI commands may be added in the supported command list if necessary.
Emulate one ahci disk device with the virtio disk backing file, boot from it, then rebuild "world" and boot from it