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 adlerdev
Make 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
./configure
with options as desired (see./configure --help
). The official binary was compiled with:--target-list=x86_64-softmmu
Execute
make
Install 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: INTR
Interrupt 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_ENABLE
Interrupt 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
INTR
register).BAR0 + 0x0008: DATA_PTR
Pointer to the data to be processed, read and write. During data processing, the device will automatically increment this pointer.
BAR0 + 0x000c: DATA_SIZE
Size 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 (
INTR
will have a value of 1).BAR0 + 0x0010: SUM
Current 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
INTR
is zeroed andINTR_ENABLE
is enabledwrite the initial value of the sum to
SUM
write the data pointer to
DATA_PTR
write the data size to
DATA_SIZE
wait for an interrupt
clear the interrupt (write 1 to
INTR
)