diff options
| author | mcayland-ntx <mark.caveayland@nutanix.com> | 2025-10-22 00:17:36 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-10-22 00:17:36 +0100 |
| commit | ca9943be5c18ed230f9d4674cc223d1e194f6d23 (patch) | |
| tree | d62b9562d5d83054dc541c5df628e55fead1d483 | |
| parent | d7cb436ffb0606fec6ec65e6087fae33e777913a (diff) | |
| download | libvfio-user-master.zip libvfio-user-master.tar.gz libvfio-user-master.tar.bz2 | |
Newer kernels implement read register caching for the gpio-pci-idio-16 which
means that the pin counter is never incremented, making it impossible to change
the input register for testing.
Improve the gpio-pci-idio-16 emulation so that the input and output registers
match those of the real hardware, and update the logic so that toggling an
output line 3 times will toggle the corresponding input line to allow testing
individual inputs and outputs.
Signed-off-by: Mark Cave-Ayland <mark.caveayland@nutanix.com>
| -rw-r--r-- | samples/gpio-pci-idio-16.c | 53 |
1 files changed, 49 insertions, 4 deletions
diff --git a/samples/gpio-pci-idio-16.c b/samples/gpio-pci-idio-16.c index 6c4e99b..739e242 100644 --- a/samples/gpio-pci-idio-16.c +++ b/samples/gpio-pci-idio-16.c @@ -51,17 +51,62 @@ _log(vfu_ctx_t *vfu_ctx UNUSED, UNUSED int level, char const *msg) fprintf(stderr, "gpio: %s\n", msg); } -static int pin; +static int pin[16]; bool dirty = true; static ssize_t bar2_access(vfu_ctx_t *vfu_ctx UNUSED, char * const buf, size_t count, loff_t offset, const bool is_write) { - if (offset == 0 && !is_write) - buf[0] = pin++ / 3; + int i; + + if (is_write) { + /* Output registers are 0x0 and 0x4 */ + switch (offset) { + case 0x0: + /* Output pins 0-7 */ + for (i = 0; i < 8; i++) { + if (buf[0] & (1 << i)) { + pin[i]++; + } + } + break; + + case 0x4: + /* Output pins 8-15 */ + for (i = 0; i < 8; i++) { + if (buf[0] & (1 << i)) { + pin[i + 8]++; + } + } + break; + } - dirty = true; + dirty = true; + } else { + /* Input registers are 0x1 and 0x5 */ + switch (offset) { + case 0x1: + /* Input pins 0-7 */ + buf[0] = 0; + for (i = 0; i < 8; i++) { + if ((pin[i] % 3) == 0) { + buf[0] |= (1 << i); + } + } + break; + + case 0x5: + /* Input pins 8-15 */ + buf[0] = 0; + for (i = 0; i < 8; i++) { + if ((pin[i + 8] % 3) == 0) { + buf[0] |= (1 << i); + } + } + break; + } + } return count; } |
