Browse Source

Adjust IPEDMA register model to address new revision

Suren A. Chilingaryan 8 years ago
parent
commit
641ddcdeec
5 changed files with 111 additions and 40 deletions
  1. 48 20
      dma/ipe.c
  2. 36 10
      dma/ipe.h
  3. 25 8
      dma/ipe_private.h
  4. 1 1
      dma/nwl.c
  5. 1 1
      tests/ipedma/test.sh

+ 48 - 20
dma/ipe.c

@@ -26,31 +26,59 @@
 
 
 pcilib_dma_context_t *dma_ipe_init(pcilib_t *pcilib, const char *model, const void *arg) {
+    int err = 0;
     pcilib_register_value_t value;
 
-    const pcilib_model_description_t *model_info = pcilib_get_model_description(pcilib);
+//    const pcilib_model_description_t *model_info = pcilib_get_model_description(pcilib);
 
     ipe_dma_t *ctx = malloc(sizeof(ipe_dma_t));
 
     if (ctx) {
 	memset(ctx, 0, sizeof(ipe_dma_t));
 	ctx->dmactx.pcilib = pcilib;
+	pcilib_register_bank_t dma_bankc = pcilib_find_register_bank_by_addr(pcilib, PCILIB_REGISTER_BANK_DMACONF);
+	pcilib_register_bank_t dma_bank0 = pcilib_find_register_bank_by_addr(pcilib, PCILIB_REGISTER_BANK_DMA0);
+	pcilib_register_bank_t dma_bank1 = pcilib_find_register_bank_by_addr(pcilib, PCILIB_REGISTER_BANK_DMA1);
 
-	pcilib_register_bank_t dma_bank = pcilib_find_register_bank_by_addr(pcilib, PCILIB_REGISTER_BANK_DMA);
-
-	if (dma_bank == PCILIB_REGISTER_BANK_INVALID) {
+	if ((dma_bankc == PCILIB_REGISTER_BANK_INVALID)||(dma_bank0 == PCILIB_REGISTER_BANK_INVALID)||(dma_bank1 == PCILIB_REGISTER_BANK_INVALID)) {
 	    free(ctx);
 	    pcilib_error("DMA Register Bank could not be found");
 	    return NULL;
 	}
 
-	ctx->dma_bank = model_info->banks + dma_bank;
-	ctx->base_addr = pcilib_resolve_register_address(pcilib, ctx->dma_bank->bar, ctx->dma_bank->read_addr);
+	ctx->base_addr[0] = (void*)pcilib_resolve_bank_address_by_id(pcilib, 0, dma_bank0);
+	ctx->base_addr[1] = (void*)pcilib_resolve_bank_address_by_id(pcilib, 0, dma_bank1);
+	ctx->base_addr[2] = (void*)pcilib_resolve_bank_address_by_id(pcilib, 0, dma_bankc);
+
+
+	if ((model)&&(!strcasecmp(model, "ipecamera"))) {
+	    ctx->version = 2;
+	} else {
+	    RD(IPEDMA_REG_VERSION, value);
 
+	    if (value >= 0xa7) {
+		ctx->version = 3;
+	    } else {
+		ctx->version = 2;
+	    }
 
-	RD(IPEDMA_REG_VERSION, value);
-	ctx->version = value;
+	    err = pcilib_add_registers(pcilib, PCILIB_MODEL_MODIFICATON_FLAGS_DEFAULT, 0, ipe_dma_app_registers, NULL);
+	}
 	
+	if (ctx->version >= 3) {
+	    if (!err) 
+		err = pcilib_add_registers(pcilib, PCILIB_MODEL_MODIFICATON_FLAGS_DEFAULT, 0, ipe_dma_v3_registers, NULL);
+	} else {
+	    if (!err)
+	        err = pcilib_add_registers(pcilib, PCILIB_MODEL_MODIFICATON_FLAGS_DEFAULT, 0, ipe_dma_v2_registers, NULL);
+	}
+	
+	if (err) {
+	    free(ctx);
+	    pcilib_error("Error (%i) registering firmware-dependent IPEDMA registers", err);
+	    return NULL;
+	}
+
 	RD(IPEDMA_REG_PCIE_GEN, value);
 
 #ifdef IPEDMA_ENFORCE_64BIT_MODE
@@ -149,7 +177,7 @@ int dma_ipe_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dm
 		if (ctx->streaming)
 		    preserve = 1;
 		else {
-		    RD(IPEDMA_REG_PAGE_COUNT, value);
+		    RD(IPEDMA_REG2_PAGE_COUNT, value);
 
 		    if (value != IPEDMA_DMA_PAGES) 
 			pcilib_warning("Inconsistent DMA buffers are found (Number of allocated buffers (%lu) does not match current request (%lu)), reinitializing...", value + 1, IPEDMA_DMA_PAGES);
@@ -169,7 +197,7 @@ int dma_ipe_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dm
 	ctx->preserve = 1;
 	
 	    // Detect the current state of DMA engine
-	RD(IPEDMA_REG_LAST_READ, value);
+	RD(IPEDMA_REG2_LAST_READ, value);
 	    // Numbered from 1 in FPGA
 # ifdef IPEDMA_BUG_LAST_READ
 	if (value == IPEDMA_DMA_PAGES)
@@ -218,15 +246,15 @@ int dma_ipe_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dm
 	WR(IPEDMA_REG_UPDATE_THRESHOLD, IPEDMA_DMA_PROGRESS_THRESHOLD);
         
 	    // Reseting configured DMA pages
-        WR(IPEDMA_REG_PAGE_COUNT, 0);
+        WR(IPEDMA_REG2_PAGE_COUNT, 0);
         
 	    // Setting current read position and configuring progress register
 #ifdef IPEDMA_BUG_LAST_READ
-	WR(IPEDMA_REG_LAST_READ, IPEDMA_DMA_PAGES - 1);
+	WR(IPEDMA_REG2_LAST_READ, IPEDMA_DMA_PAGES - 1);
 #else /* IPEDMA_BUG_LAST_READ */
-	WR(IPEDMA_REG_LAST_READ, IPEDMA_DMA_PAGES);
+	WR(IPEDMA_REG2_LAST_READ, IPEDMA_DMA_PAGES);
 #endif /* IPEDMA_BUG_LAST_READ */
-	WR(IPEDMA_REG_UPDATE_ADDR, pcilib_kmem_get_block_ba(ctx->dmactx.pcilib, desc, 0));
+	WR(IPEDMA_REG2_UPDATE_ADDR, pcilib_kmem_get_block_ba(ctx->dmactx.pcilib, desc, 0));
 
 	    // Instructing DMA engine that writting should start from the first DMA page
 	*last_written_addr_ptr = 0;
@@ -239,10 +267,10 @@ int dma_ipe_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dm
 	
 	for (i = 0; i < num_pages; i++) {
 	    uintptr_t bus_addr_check, bus_addr = pcilib_kmem_get_block_ba(ctx->dmactx.pcilib, pages, i);
-	    WR(IPEDMA_REG_PAGE_ADDR, bus_addr);
+	    WR(IPEDMA_REG2_PAGE_ADDR, bus_addr);
 	    if (bus_addr%4096) printf("Bad address %lu: %lx\n", i, bus_addr);
 
-	    RD(IPEDMA_REG_PAGE_ADDR, bus_addr_check);
+	    RD(IPEDMA_REG2_PAGE_ADDR, bus_addr_check);
 	    if (bus_addr_check != bus_addr) {
 		pcilib_error("Written (%x) and read (%x) bus addresses does not match\n", bus_addr, bus_addr_check);
 	    }
@@ -298,7 +326,7 @@ int dma_ipe_stop(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dma
 	usleep(IPEDMA_RESET_DELAY);
 
 	    // Reseting configured DMA pages
-        WR(IPEDMA_REG_PAGE_COUNT, 0);
+        WR(IPEDMA_REG2_PAGE_COUNT, 0);
 	usleep(IPEDMA_RESET_DELAY);
     }
 
@@ -544,7 +572,7 @@ int dma_ipe_stream_read(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, uin
 	    else last_free = IPEDMA_DMA_PAGES - 1;
 
 	    uintptr_t buf_ba = pcilib_kmem_get_block_ba(ctx->dmactx.pcilib, ctx->pages, last_free);
-	    WR(IPEDMA_REG_PAGE_ADDR, buf_ba);
+	    WR(IPEDMA_REG2_PAGE_ADDR, buf_ba);
 # ifdef IPEDMA_STREAMING_CHECKS
 	    pcilib_register_value_t streaming_status;
 	    RD(IPEDMA_REG_STREAMING_STATUS, streaming_status);
@@ -555,9 +583,9 @@ int dma_ipe_stream_read(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, uin
 
 	    // Numbered from 1
 #ifdef IPEDMA_BUG_LAST_READ
-	WR(IPEDMA_REG_LAST_READ, cur_read?cur_read:IPEDMA_DMA_PAGES);
+	WR(IPEDMA_REG2_LAST_READ, cur_read?cur_read:IPEDMA_DMA_PAGES);
 #else /* IPEDMA_BUG_LAST_READ */
-	WR(IPEDMA_REG_LAST_READ, cur_read + 1);
+	WR(IPEDMA_REG2_LAST_READ, cur_read + 1);
 #endif /* IPEDMA_BUG_LAST_READ */
 
 	pcilib_debug(DMA, "Buffer returned     %4u - last read: %4u, last_read_addr: %4u (0x%x), last_written: %4u (0x%x)", cur_read, ctx->last_read, 

+ 36 - 10
dma/ipe.h

@@ -44,6 +44,7 @@ static const pcilib_dma_engine_description_t ipe_dma_engines[] = {
 
 static const pcilib_register_bank_description_t ipe_dma_banks[] = {
     { PCILIB_REGISTER_BANK_DMA, PCILIB_REGISTER_PROTOCOL_DEFAULT, PCILIB_BAR0, 0, 0, 32, 0x0200, PCILIB_LITTLE_ENDIAN, PCILIB_LITTLE_ENDIAN, "0x%lx", "dma", "DMA Registers"},
+    { PCILIB_REGISTER_BANK_DMA1, PCILIB_REGISTER_PROTOCOL_DEFAULT, PCILIB_BAR0, 0x9000, 0x9000, 32, 0x0100, PCILIB_LITTLE_ENDIAN, PCILIB_LITTLE_ENDIAN, "0x%lx", "dma9000", "Additional DMA Registers"},
     { PCILIB_REGISTER_BANK_DMACONF, PCILIB_REGISTER_PROTOCOL_SOFTWARE, PCILIB_BAR_NOBAR, 0, 0, 32, 0x1000, PCILIB_HOST_ENDIAN, PCILIB_HOST_ENDIAN, "0x%lx", "dmaconf", "DMA Configuration"},
     { 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
 };
@@ -73,20 +74,12 @@ static const pcilib_register_description_t ipe_dma_registers[] = {
     {0x0018, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_mode_flags",		"DMA operation mode"},
     {0x0018, 	0, 	4, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "pcie_gen",  			"PCIe version 2/3 depending on the used XILINX core"},
     {0x0018, 	4, 	1, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "streaming_dma", 			"Streaming mode (enabled/disabled)"},
-    {0x0020,	0,	32,	0,	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "dma_firmware",		"Version of DMA firmware"},
     {0x0028, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "mwr_perf",			"MWR Performance"},
     {0x003C, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "cfg_lnk_width",		"Negotiated and max width of PCIe Link"},
     {0x003C, 	0, 	6, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "cfg_cap_max_lnk_width", 		"Max link width"},
     {0x003C, 	8, 	6, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "cfg_prg_max_lnk_width", 		"Negotiated link width"},
-    {0x0040, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "cfg_payload_size",  		""},
-    {0x0040, 	0, 	4, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "cfg_cap_max_payload_size",	"Max payload size"},
-    {0x0040, 	8, 	3, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "cfg_prg_max_payload_size",	"Prog max payload size"},
-    {0x0040, 	16, 	3, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "cfg_max_rd_req_size",		"Max read request size"},
-    {0x0050, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "desc_mem_din",  		"Descriptor memory"},
-    {0x0054, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "update_addr",  		"Address of progress register"},
-    {0x0058, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "last_descriptor_read",	"Last descriptor read by the host"},
-    {0x005C, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "desc_mem_addr", 		"Number of descriptors configured"},
     {0x0060, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "update_thresh",  		"Update threshold of progress register"},
+	// software registers
     {0x0000, 	0, 	32, 	PCILIB_VERSION, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMACONF, "dma_version",	"Version of DMA engine"},
     {0x0004, 	0, 	32, 	IPEDMA_DMA_TIMEOUT, 	0x00000000,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMACONF, "dma_timeout",	"Default DMA timeout"},
     {0x0008, 	0, 	32, 	IPEDMA_DMA_PAGES,	0x00000000,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMACONF, "dma_pages",	"Number of buffers in DMA page ring"},
@@ -96,10 +89,43 @@ static const pcilib_register_description_t ipe_dma_registers[] = {
     {0x0010, 	1, 	1, 	0,			0xFFFFFFFF,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_BITS,	PCILIB_REGISTER_BANK_DMACONF, "ipedma_nosleep",	"Do not sleep while there is no data"},
     {0,		0,	0,	0,	0x00000000,	0,                                           0,                        0, NULL, 			NULL}
 };
+#endif /* _PCILIB_EXPORT_C */
 
+#ifdef _PCILIB_DMA_IPE_C
+static const pcilib_register_description_t ipe_dma_app_registers[] = {
+    {0x0000,	0,	32,	0,	0xFFFFFFFF,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA1, "cntgen",			"Dummy counter"},
+    {0x0000,	0,	1,	0,	0xFFFFFFFF,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA1, "enable_cntgen",			"Enable counting/fixed pattern dummy generator"},
+    {0x0000,	4,	1,	0,	0xFFFFFFFF,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA1, "reset_cntgen",			"Reset dummy counter of dummy generator"},
+    {0x0000,	8,	1,	0,	0xFFFFFFFF,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA1, "fix_cntgen",			"Enable fixed pattern mode of dummy generator"},
+    {0x0004,	0,	32,	0,	0x00000000,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA1, "cntgen_pattern",		"Pattern for fixed pattern dummy generator"},
+    {0x0008,	0,	32,	0,	0x00000000,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA1, "update_word0",		"Content of first 32-bit word in the progress register"},
+    {0x0020,	0,	32,	0,	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA1, "dma_firmware",		"Version of DMA firmware"},
+    {0,		0,	0,	0,	0x00000000,	0,                                           0,                        0, NULL, 			NULL}
+};
 
+static const pcilib_register_description_t ipe_dma_v2_registers[] = {
+    {0x0040, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "cfg_payload_size",  		""},
+    {0x0040, 	0, 	4, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "cfg_cap_max_payload_size",	"Max payload size"},
+    {0x0040, 	8, 	3, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "cfg_prg_max_payload_size",	"Prog max payload size"},
+    {0x0040, 	16, 	3, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_BITS, PCILIB_REGISTER_BANK_DMA, "cfg_max_rd_req_size",		"Max read request size"},
+    {0x0050, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "desc_mem_din",  		"Descriptor memory"},
+    {0x0054, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "update_addr",  		"Address of progress register"},
+    {0x0058, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "last_descriptor_read",	"Last descriptor read by the host"},
+    {0x005C, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "desc_mem_addr", 		"Number of descriptors configured"},
+    {0,		0,	0,	0,	0x00000000,	0,                                           0,                        0, NULL, 			NULL}
+};
 
-#endif /* _PCILIB_EXPORT_C */
+static const pcilib_register_description_t ipe_dma_v3_registers[] = {
+    {0x0040, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "desc_mem_addr", 		"Number of descriptors configured"},
+    {0x0050, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "desc_mem_din_hi",  		"Descriptor memory (high bits)"},
+    {0x0054, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "desc_mem_din_lo",  		"Descriptor memory (low bits)"},
+    {0x0058, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "update_addr_hi",  		"Address of progress register (high bits)"},
+    {0x005C, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_R   , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMA, "update_addr_lo",  		"Address of progress register (low bits)"},
+	// software registgers
+    {0x0080, 	0, 	32, 	0, 	0x00000000,	PCILIB_REGISTER_RW  , PCILIB_REGISTER_STANDARD, PCILIB_REGISTER_BANK_DMACONF, "last_descriptor_read",	"Last descriptor read by the host"},
+    {0,		0,	0,	0,	0x00000000,	0,                                           0,                        0, NULL, 			NULL}
+};
+#endif /* _PCILIB_DMA_IPE_C */
 
 
 #endif /* _PCILIB_DMA_IPE_H */

+ 25 - 8
dma/ipe_private.h

@@ -19,20 +19,37 @@
 //#define IPEDMA_DETECT_PACKETS				/**< Using empty_deceted flag */
 #define  IPEDMA_SUPPORT_EMPTY_DETECTED			/**< Avoid waiting for data when empty_detected flag is set in hardware */
 
+#define IPEDMA_REG_ADDR_MASK 0xFFF
+#define IPEDMA_REG_BANK_MASK 0xF000
+#define IPEDMA_REG_BANK_SHIFT 24
+
+#define REG2VIRT(reg) (ctx->base_addr[(reg&IPEDMA_REG_BANK_MASK)>>IPEDMA_REG_BANK_SHIFT] + (reg&IPEDMA_REG_ADDR_MASK))
+#define REG(bank, addr) ((bank<<IPEDMA_REG_BANK_SHIFT)|addr)
+#define CONFREG(addr) REG(2, addr)
+
+#define IPEDMA_REG_VERSION		REG(1, 0x20)
 
 #define IPEDMA_REG_RESET		0x00
 #define IPEDMA_REG_CONTROL		0x04
 #define IPEDMA_REG_TLP_SIZE		0x0C
 #define IPEDMA_REG_TLP_COUNT		0x10
 #define IPEDMA_REG_PCIE_GEN		0x18
-#define IPEDMA_REG_VERSION		0x20
-#define IPEDMA_REG_PAGE_ADDR		0x50
-#define IPEDMA_REG_UPDATE_ADDR		0x54
-#define IPEDMA_REG_LAST_READ		0x58		/**< In streaming mode, we can use it freely to track current status */
-#define IPEDMA_REG_PAGE_COUNT		0x5C
 #define IPEDMA_REG_UPDATE_THRESHOLD	0x60
 #define IPEDMA_REG_STREAMING_STATUS	0x68
 
+    // PCIe gen2
+#define IPEDMA_REG2_PAGE_ADDR		0x50
+#define IPEDMA_REG2_UPDATE_ADDR		0x54
+#define IPEDMA_REG2_LAST_READ		0x58		/**< In streaming mode, we can use it freely to track current status */
+#define IPEDMA_REG2_PAGE_COUNT		0x5C
+
+    // PCIe gen3
+#define IPEDMA_REG3_PAGE_COUNT		0x40		/**< Read-only now */
+#define IPEDMA_REG3_PAGE_ADDR		0x50
+#define IPEDMA_REG3_UPDATE_ADDR		0x58
+#define IPEDMA_REG3_LAST_READ		CONFREG(0x80)
+
+
 #define IPEDMA_FLAG_NOSYNC		0x01		/**< Do not call kernel space for page synchronization */
 #define IPEDMA_FLAG_NOSLEEP		0x02		/**< Do not sleep in the loop while waiting for the data */
 
@@ -44,8 +61,8 @@
 #define IPEDMA_NODATA_SLEEP		100		/**< To keep CPU free, in nanoseconds */
 
 
-#define WR(addr, value) { *(uint32_t*)(ctx->base_addr + addr) = value; }
-#define RD(addr, value) { value = *(uint32_t*)(ctx->base_addr + addr); }
+#define WR(addr, value) { *(uint32_t*)(REG2VIRT(addr)) = value; }
+#define RD(addr, value) { value = *(uint32_t*)(REG2VIRT(addr)); }
 
 
 typedef struct ipe_dma_s ipe_dma_t;
@@ -55,7 +72,7 @@ struct ipe_dma_s {
     //pcilib_dma_engine_description_t engine[2];
 
     const pcilib_register_bank_description_t *dma_bank;
-    char *base_addr;
+    char *base_addr[3];
 
     pcilib_irq_type_t irq_enabled;	/**< indicates that IRQs are enabled */
     pcilib_irq_type_t irq_preserve;	/**< indicates that IRQs should not be disabled during clean-up */

+ 1 - 1
dma/nwl.c

@@ -98,7 +98,7 @@ pcilib_dma_context_t *dma_nwl_init(pcilib_t *pcilib, const char *model, const vo
     }
 
     ctx->dma_bank = model_info->banks + dma_bank;
-    ctx->base_addr = pcilib_resolve_register_address(pcilib, ctx->dma_bank->bar, ctx->dma_bank->read_addr);
+    ctx->base_addr = pcilib_resolve_bar_address(pcilib, ctx->dma_bank->bar, ctx->dma_bank->read_addr);
 
     if ((model)&&(strcasestr(model, "ipecamera"))) {
 	ctx->type = NWL_MODIFICATION_IPECAMERA;

+ 1 - 1
tests/ipedma/test.sh

@@ -26,7 +26,7 @@ pci -w 0x9000 0x1
 #done
 
 echo "Reading the data from DMA..."
-for i in `seq 1 1000`; do
+for i in `seq 1 100`; do
     pci -r dma0 --multipacket -s $size -o bench.out --timeout 1000000
 #    pci -r dma0 --multipacket -s $size -o /dev/null --timeout 10000000
     if [ $? -ne 0 ]; then