diff options
author | Ilias Apalodimas <ilias.apalodimas@linaro.org> | 2017-10-02 22:07:03 +0300 |
---|---|---|
committer | Ilias Apalodimas <ilias.apalodimas@linaro.org> | 2017-10-02 22:07:03 +0300 |
commit | 8fe0c3bf5802dd0538d3ae5aaafa37c7277086aa (patch) | |
tree | 8d8fe97eb80c7d16d80a64852a9a5857e4950411 | |
parent | 476d2f1d4c03be3a8fb6eecbb5d92ffac59fe783 (diff) |
Added API for reading/writing regs
-rwxr-xr-x | build.sh | 2 | ||||
-rw-r--r-- | reg_api.h | 92 | ||||
-rw-r--r-- | test.c | 59 | ||||
-rw-r--r-- | vfio-netem.c | 3 |
4 files changed, 145 insertions, 11 deletions
@@ -5,5 +5,5 @@ if [ -n "$1" -a "$1" = 'clean' ]; then rm check_dma else make -C /lib/modules/`uname -r`/build M=`pwd` modules - gcc test.c -o test_dma -Werror -Wall -Wunused + gcc test.c -o test_dma -Werror -Wall -Wunused -O2 fi diff --git a/reg_api.h b/reg_api.h new file mode 100644 index 0000000..cb9932a --- /dev/null +++ b/reg_api.h @@ -0,0 +1,92 @@ +#ifndef _REG_API_H +#define _REG_API_H + +static inline uint8_t io_read8_relaxed(const volatile void *addr) +{ + return *(const volatile uint8_t *)addr; +} + +static inline uint16_t io_read16_relaxed(const volatile void *addr) +{ + return *(const volatile uint16_t *)addr; +} + +static inline uint32_t io_read32_relaxed(const volatile void *addr) +{ + return *(const volatile uint32_t *)addr; +} + +static inline uint64_t io_read64_relaxed(const volatile void *addr) +{ + return *(const volatile uint64_t *)addr; +} + +static inline void io_write8_relaxed(uint8_t value, volatile void *addr) +{ + *(volatile uint8_t *)addr = value; +} + +static inline void io_write16_relaxed(uint16_t value, volatile void *addr) +{ + *(volatile uint16_t *)addr = value; +} + +static inline void io_write32_relaxed(uint32_t value, volatile void *addr) +{ + *(volatile uint32_t *)addr = value; +} + +static inline void io_write64_relaxed(uint64_t value, volatile void *addr) +{ + *(volatile uint64_t *)addr = value; +} + +static inline uint8_t io_read8(const volatile void *addr) +{ + uint8_t val; + val = io_read8_relaxed(addr); + return val; +} + +static inline uint16_t io_read16(const volatile void *addr) +{ + uint16_t val; + val = io_read16_relaxed(addr); + return val; +} + +static inline uint32_t io_read32(const volatile void *addr) +{ + uint32_t val; + val = io_read32_relaxed(addr); + return val; +} + +static inline uint64_t io_read64(const volatile void *addr) +{ + uint64_t val; + val = io_read64_relaxed(addr); + return val; +} + +static inline void io_write8(uint8_t value, volatile void *addr) +{ + io_write8_relaxed(value, addr); +} + +static inline void io_write16(uint16_t value, volatile void *addr) +{ + io_write16_relaxed(value, addr); +} + +static inline void io_write32(uint32_t value, volatile void *addr) +{ + io_write32_relaxed(value, addr); +} + +static inline void io_write64(uint64_t value, volatile void *addr) +{ + io_write64_relaxed(value, addr); +} + +#endif @@ -10,9 +10,14 @@ #include <unistd.h> #include <stdlib.h> #include <stdint.h> +#include "reg_api.h" const char glob_uuid[] = "d0b24768-9c51-11e7-8de5-c7b0c2769e69"; #define TEST_SIZE 1024 * 1024 +#define EOR (1<<30) +#define OWN (1<<31) +#define NUM_TX_DESC 64 + /* * @fd: container fd @@ -68,21 +73,55 @@ int dma_unmap_type1(int fd, unsigned long sz, void *vaddr) return ret; } -int rtl_8169_remap(void) +struct rtl_8169_descriptor { + unsigned int command; /* command/status uint32_t */ + unsigned int vlan; /* currently unused */ + unsigned int low_buf; /* low 32-bits of physical buffer address */ + unsigned int high_buf; /* high 32-bits of physical buffer address */ +}; + +int rtl_8169_remap(int container, void *map) { + ((uint8_t *)map)[80] = 0xc0; + ((uint8_t *)map)[55] = 0x04; + uint32_t vaddr; + + dma_map_type1(container, TEST_SIZE, &vaddr); + + printf("AAA 0x%02x\n", io_read8(map + 0x50)); + printf("AAA 0x%02x\n", io_read8(map + 0x37)); + printf("AAA 0x%02x\n", io_read8(map + 0xEC)); + //writeb(map, 0x50, 0xC0); + //writeb(map, 0x37, 0x04); + //writeb(map, 0xEC, 0x3B); /* max tx packet size */ + //writeb(map, 0xEC, 0x27); /* max tx packet size */ + //Done + //writeb(map, 0x50, 0x00); #if 0 - if (i == 2) { - ((uint8_t *)map)[80] = 0xc0; - dma_map_type1(container, TEST_SIZE, &vaddr); - - ((uint64_t *)map)[32] = (unsigned long)&vaddr; - //dma_unmap_type1(container, TEST_SIZE, &vaddr); - } + outb(ioaddr + 0x50, 0xC0); /* Unlock config registers */ + outl(ioaddr + 0x44, 0x0000E70F); /* RxConfig = RXFTH: unlimited, MXDMA: unlimited, AAP: set (promisc. mode set) */ + outb(ioaddr + 0x37, 0x04); /* Enable Tx in the Command register, required before setting TxConfig */ + outl(ioaddr + 0x40, 0x03000700); /* TxConfig = IFG: normal, MXDMA: unlimited */ + outw(ioaddr + 0xDA, 0x1FFF); /* Max rx packet size */ + outb(ioaddr + 0xEC, 0x3B); /* max tx packet size */ + + /* offset 0x20 == Transmit Descriptor Start Address Register + offset 0xE4 == Receive Descriptor Start Address Register + + Again, these are *physical* addresses. This code assumes physical==linear, this is + typically not the case in real world kernels + */ + outl(ioaddr + 0x20, (unsigned long)&Tx_Descriptors[0]; /* Tell the NIC where the first Tx descriptor is */ + outl(ioaddr + 0xE4, (unsigned long)&Rx_Descriptors[0]; /* Tell the NIC where the first Rx descriptor is */ + + outb(ioaddr + 0x37, 0x0C); /* Enable Rx/Tx in the Command register */ + outb(ioaddr + 0x50, 0x00); /* Lock config registers */ #endif + dma_unmap_type1(container, TEST_SIZE, &vaddr); + return 0; } -#define DBG int main(int argc, char* argv[]) { int container, group, device, i; @@ -154,6 +193,8 @@ int main(int argc, char* argv[]) printf("mmap failed\n"); continue; } + rtl_8169_remap(container, map); + #ifdef DBG int j; diff --git a/vfio-netem.c b/vfio-netem.c index 324c80c..e02b865 100644 --- a/vfio-netem.c +++ b/vfio-netem.c @@ -242,7 +242,8 @@ static long vfio_net_ioctl(struct mdev_device *mdev, unsigned int cmd, info.flags = VFIO_REGION_INFO_FLAG_READ | VFIO_REGION_INFO_FLAG_WRITE; /* FIXME not all BARS are not mappable */ - info.flags |= VFIO_REGION_INFO_FLAG_MMAP; + if (info.index == VFIO_PCI_BAR2_REGION_INDEX) + info.flags |= VFIO_REGION_INFO_FLAG_MMAP; #if 0 if (vdev->bar_mmap_supported[info.index]) { info.flags |= VFIO_REGION_INFO_FLAG_MMAP; |