Example PCI Device¶
The example device is used for hardware calculation of the Adler-32 checksum.
We provide it as a modified version of qemu.
Driver for the example device: adlerdev.tar.gz
QEMU¶
To use the example device, a modified version of qemu is required, available in source version. To compile the modified version of qemu, you should:
Clone the repository https://github.com/mwkmwkmwk/qemu
git checkout adlerdevMake sure the dependencies are installed:
ncurses,libsdl,curl, and in some distributions alsoncurses-dev,libsdl-dev,curl-dev(package names may vary slightly depending on the distribution)Run
./configurewith options as desired (see./configure --help). The official binary was compiled with:--target-list=x86_64-softmmu
Execute
makeInstall by executing
make install, or run directly (the binary isx86_64-softmmu/qemu-system-x86_64).
Device¶
The device is connected to the computer via the PCI bus --
the vendor identifier is 0x0666, and the device identifier is
0x0a32. The device has 5 registers:
BAR0 + 0x0000: INTRInterrupt status register. When read, it has a value of 1 if the device is signaling an interrupt, or 0 if it is not. To respond to an interrupt (and cause the device to stop signaling an interrupt), you should write 1 to this register. You should also write 1 to this register when starting the device (the device may signal an interrupt at startup).
BAR0 + 0x0004: INTR_ENABLEInterrupt enable register, read and write. If it has a value of 1, the device is allowed to signal an interrupt. If it has a value of 0, the device will not signal a PCI interrupt (the interrupt will still be visible in the
INTRregister).BAR0 + 0x0008: DATA_PTRPointer to the data to be processed, read and write. During data processing, the device will automatically increment this pointer.
BAR0 + 0x000c: DATA_SIZESize of the data to be processed, read and write. Writing a non-zero value to this register will immediately start data processing. During processing, the device will automatically decrement this register. When all data has been processed (and this register drops to zero), an interrupt will be signaled (
INTRwill have a value of 1).BAR0 + 0x0010: SUMCurrent sum. Before processing data, the initial value of the sum should be written here. As data is processed, the device updates the sum.
To process data, you should:
make sure that
INTRis zeroed andINTR_ENABLEis enabledwrite the initial value of the sum to
SUMwrite the data pointer to
DATA_PTRwrite the data size to
DATA_SIZEwait for an interrupt
clear the interrupt (write 1 to
INTR)