[ewg] [PATCH 5/6] nes: Cosmetic changes; support virtual WQs and PPC

Glenn Grundstrom NetEffect glenn at lists.openfabrics.org
Wed Nov 14 14:38:48 PST 2007


Updated code for the NetEffect NE020 adapter.

Updates include:
- Support for userspace/virtual WQs.
- PowerPC
- Support for multiple debugging levels
- Many, many cosmetic changes inline with kernel.org standards

Diffs for nes_user.h and nes_utils.c

Signed-off-by: Glenn Grundstrom <ggrundstrom at neteffect.com>

---
diff --git a/drivers/infiniband/hw/nes/nes_user.h b/drivers/infiniband/hw/nes/nes_user.h
index a170399..6ab2357 100644
--- a/drivers/infiniband/hw/nes/nes_user.h
+++ b/drivers/infiniband/hw/nes/nes_user.h
@@ -39,6 +39,9 @@
 
 #include <linux/types.h>
 
+#define NES_ABI_USERSPACE_VER 1
+#define NES_ABI_KERNEL_VER    1
+
 /*
  * Make sure that all structs defined in this file remain laid out so
  * that they pack the same way on 32-bit and 64-bit architectures (to
@@ -47,11 +50,19 @@
  * instead.
  */
 
+struct nes_alloc_ucontext_req {
+	__u32 reserved32;
+	__u8  userspace_ver;
+	__u8  reserved8[3];
+};
+
 struct nes_alloc_ucontext_resp {
 	__u32 max_pds; /* maximum pds allowed for this user process */
 	__u32 max_qps; /* maximum qps allowed for this user process */
 	__u32 wq_size; /* size of the WQs (sq+rq) allocated to the mmaped area */
-	__u32 reserved;
+	__u8  virtwq;  /* flag to indicate if virtual WQ are to be used or not */
+	__u8  kernel_ver;
+	__u8  reserved[2];
 };
 
 struct nes_alloc_pd_resp {
@@ -63,6 +74,10 @@ struct nes_create_cq_req {
 	__u64 user_cq_buffer;
 };
 
+struct nes_create_qp_req {
+	__u64 user_wqe_buffers;
+};
+
 enum iwnes_memreg_type {
 	IWNES_MEMREG_TYPE_MEM = 0x0000,
 	IWNES_MEMREG_TYPE_QP = 0x0001,
diff --git a/drivers/infiniband/hw/nes/nes_utils.c b/drivers/infiniband/hw/nes/nes_utils.c
index 1d478e0..b6aa6d3 100644
--- a/drivers/infiniband/hw/nes/nes_utils.c
+++ b/drivers/infiniband/hw/nes/nes_utils.c
@@ -50,19 +50,8 @@
 
 #include "nes.h"
 
-#define BITMASK(X)     (1L << (X))
-#define NES_CRC_WID     32
-
 static u16 nes_read16_eeprom(void __iomem *addr, u16 offset);
 
-static u32 nesCRCTable[256];
-static u32 nesCRCInitialized = 0;
-
-static u32 nesCRCWidMask(u32);
-static u32 nes_crc_table_gen(u32 *, u32, u32, u32);
-static u32 reflect(u32, u32);
-static u32 byte_swap(u32, u32);
-
 u32 mh_detected;
 u32 mh_pauses_sent;
 
@@ -76,7 +65,9 @@ int nes_read_eeprom_values(struct nes_device *nesdev, struct nes_adapter *nesada
 	u16 eeprom_data;
 	u16 eeprom_offset;
 	u16 next_section_address;
-	u32 index;
+	u16 sw_section_ver;
+	u8  major_ver = 0;
+	u8  minor_ver = 0;
 
 	/* TODO: deal with EEPROM endian issues */
 	if (nesadapter->firmware_eeprom_offset == 0) {
@@ -104,6 +95,9 @@ int nes_read_eeprom_values(struct nes_device *nesdev, struct nes_adapter *nesada
 			printk("Not a valid Software Image = 0x%04X\n", eeprom_data);
 			return -1;
 		}
+		sw_section_ver = nes_read16_eeprom(nesdev->regs, nesadapter->software_eeprom_offset  + 6);
+		nes_debug(NES_DBG_HW, "Software section version number = 0x%04X\n",
+				sw_section_ver);
 
 		eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset + 2);
 		nes_debug(NES_DBG_HW, "EEPROM Offset %u (next section)  = 0x%04X\n",
@@ -179,7 +173,14 @@ int nes_read_eeprom_values(struct nes_device *nesdev, struct nes_adapter *nesada
 		}
 		eeprom_data = nes_read16_eeprom(nesdev->regs, next_section_address + 8);
 		printk(PFX "Firmware version %u.%u\n", (u8)(eeprom_data>>8), (u8)eeprom_data);
+		major_ver = (u8)(eeprom_data >> 8);
+		minor_ver = (u8)(eeprom_data);
 
+		if (nes_drv_opt & NES_DRV_OPT_DISABLE_VIRT_WQ) {
+			nes_debug(NES_DBG_HW, "Virtual WQs have been disabled\n");
+		} else if (((major_ver == 2) && (minor_ver > 21)) || (major_ver > 2)) {
+			nesadapter->virtwq = 1;
+		}
 		nesadapter->firmware_version = (((u32)(u8)(eeprom_data>>8))  <<  16) +
 				(u32)((u8)eeprom_data);
 
@@ -205,22 +206,60 @@ no_fw_rev:
 		/* Read the Phy Type array */
 		eeprom_offset += 10;
 		eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset);
-		nes_debug(NES_DBG_HW, "PhyType: 0x%04x\n", eeprom_data);
+		nesadapter->phy_type[0] = (u8)(eeprom_data >> 8);
+		nesadapter->phy_type[1] = (u8)eeprom_data;
 
 		/* Read the port array */
 		eeprom_offset += 2;
 		eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset);
+		nesadapter->phy_type[2] = (u8)(eeprom_data >> 8);
+		nesadapter->phy_type[3] = (u8)eeprom_data;
 		/* port_count is set by soft reset reg */
-		for (index = 0; index < 4; index++) {
-			nesadapter->ports[index] = eeprom_data & 0x000f;
-			eeprom_data >>= 4;
-		}
-		nes_debug(NES_DBG_HW, "port_count = %u, port 0 -> %u, port 1 -> %u, port 2 -> %u, port 3 -> %u\n",
+		nes_debug(NES_DBG_HW, "port_count = %u, port 0 -> %u, port 1 -> %u,"
+				" port 2 -> %u, port 3 -> %u\n",
 				nesadapter->port_count,
-				nesadapter->ports[0], nesadapter->ports[1],
-				nesadapter->ports[2], nesadapter->ports[3]);
+				nesadapter->phy_type[0], nesadapter->phy_type[1],
+				nesadapter->phy_type[2], nesadapter->phy_type[3]);
+
+		/* Read PD config array */
+		eeprom_offset += 10;
+		eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset);
+		nesadapter->pd_config_size[0] = eeprom_data;
+		eeprom_offset += 2;
+		eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset);
+		nesadapter->pd_config_base[0] = eeprom_data;
+		nes_debug(NES_DBG_HW, "PD0 config, size=0x%04x, base=0x%04x\n",
+				nesadapter->pd_config_size[0], nesadapter->pd_config_base[0]);
 
-		eeprom_offset += 46;
+		eeprom_offset += 2;
+		eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset);
+		nesadapter->pd_config_size[1] = eeprom_data;
+		eeprom_offset += 2;
+		eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset);
+		nesadapter->pd_config_base[1] = eeprom_data;
+		nes_debug(NES_DBG_HW, "PD1 config, size=0x%04x, base=0x%04x\n",
+				nesadapter->pd_config_size[1], nesadapter->pd_config_base[1]);
+
+		eeprom_offset += 2;
+		eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset);
+		nesadapter->pd_config_size[2] = eeprom_data;
+		eeprom_offset += 2;
+		eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset);
+		nesadapter->pd_config_base[2] = eeprom_data;
+		nes_debug(NES_DBG_HW, "PD2 config, size=0x%04x, base=0x%04x\n",
+				nesadapter->pd_config_size[2], nesadapter->pd_config_base[2]);
+
+		eeprom_offset += 2;
+		eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset);
+		nesadapter->pd_config_size[3] = eeprom_data;
+		eeprom_offset += 2;
+		eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset);
+		nesadapter->pd_config_base[3] = eeprom_data;
+		nes_debug(NES_DBG_HW, "PD3 config, size=0x%04x, base=0x%04x\n",
+				nesadapter->pd_config_size[3], nesadapter->pd_config_base[3]);
+
+		/* Read Rx Pool Size */
+		eeprom_offset += 22;   /* 46 */
 		eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset);
 		eeprom_offset += 2;
 		nesadapter->rx_pool_size = (((u32)eeprom_data) << 16) +
@@ -290,15 +329,26 @@ no_fw_rev:
 		nesadapter->core_clock = (((u32)eeprom_data) << 16) +
 				nes_read16_eeprom(nesdev->regs, eeprom_offset);
 		nes_debug(NES_DBG_HW, "core_clock = 0x%08X\n", nesadapter->core_clock);
-	}
-
-	nesadapter->phy_index[0] = 4;
-	nesadapter->phy_index[1] = 5;
-	nesadapter->phy_index[2] = 6;
-	nesadapter->phy_index[3] = 7;
 
-	/* TODO: get this from EEPROM */
-	nesdev->base_doorbell_index = 1;
+		if ((sw_section_ver) && (nesadapter->hw_rev != NE020_REV)) {
+			eeprom_offset += 2;
+			eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset);
+			nesadapter->phy_index[0] = (eeprom_data & 0xff00)>>8;
+			nesadapter->phy_index[1] = eeprom_data & 0x00ff;
+			eeprom_offset += 2;
+			eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset);
+			nesadapter->phy_index[2] = (eeprom_data & 0xff00)>>8;
+			nesadapter->phy_index[3] = eeprom_data & 0x00ff;
+		} else {
+			nesadapter->phy_index[0] = 4;
+			nesadapter->phy_index[1] = 5;
+			nesadapter->phy_index[2] = 6;
+			nesadapter->phy_index[3] = 7;
+		}
+		nes_debug(NES_DBG_HW, "Phy address map = 0 > %u,  1 > %u, 2 > %u, 3 > %u\n",
+			   nesadapter->phy_index[0],nesadapter->phy_index[1],
+			   nesadapter->phy_index[2],nesadapter->phy_index[3]);
+	}
 
 	return 0;
 }
@@ -316,7 +366,7 @@ static u16 nes_read16_eeprom(void __iomem *addr, u16 offset)
 	} while (readl((void __iomem *)addr + NES_EEPROM_COMMAND) &
 			NES_EEPROM_READ_REQUEST);
 
-	return(readw((void __iomem *)addr + NES_EEPROM_DATA));
+	return readw((void __iomem *)addr + NES_EEPROM_DATA);
 }
 
 
@@ -363,8 +413,8 @@ void nes_read_1G_phy_reg(struct nes_device *nesdev, u8 phy_reg, u8 phy_addr, u16
 	u32 counter;
 	unsigned long flags;
 
-	/* nes_debug(NES_DBG_PHY, "%s: phy addr = %d, mac_index = %d\n",
-			__FUNCTION__, phy_addr, nesdev->mac_index); */
+	/* nes_debug(NES_DBG_PHY, "phy addr = %d, mac_index = %d\n",
+			phy_addr, nesdev->mac_index); */
 	spin_lock_irqsave(&nesadapter->phy_lock, flags);
 
 	nes_write_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL,
@@ -400,12 +450,12 @@ void nes_write_10G_phy_reg(struct nes_device *nesdev, u16 phy_reg,
 	u32 u32temp;
 	u32 counter;
 
-	dev_addr = 5;
-	port_addr = 0;
+	dev_addr = 1;
+	port_addr = phy_addr;
 
 	/* set address */
 	nes_write_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL,
-			0x00020000 | phy_reg | (dev_addr << 18) | (port_addr << 23));
+			0x00020000 | (u32)phy_reg | (((u32)dev_addr) << 18) | (((u32)port_addr) << 23));
 	for (counter = 0; counter < 100 ; counter++) {
 		udelay(30);
 		u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS);
@@ -420,7 +470,7 @@ void nes_write_10G_phy_reg(struct nes_device *nesdev, u16 phy_reg,
 
 	/* set data */
 	nes_write_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL,
-			0x10020000 | data | (dev_addr << 18) | (port_addr << 23));
+			0x10020000 | (u32)data | (((u32)dev_addr) << 18) | (((u32)port_addr) << 23));
 	for (counter = 0; counter < 100 ; counter++) {
 		udelay(30);
 		u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS);
@@ -447,12 +497,12 @@ void nes_read_10G_phy_reg(struct nes_device *nesdev, u16 phy_reg, u8 phy_addr)
 	u32 u32temp;
 	u32 counter;
 
-	dev_addr = 5;
-	port_addr = 0;
+	dev_addr = 1;
+	port_addr = phy_addr;
 
 	/* set address */
 	nes_write_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL,
-			0x00020000 | phy_reg | (dev_addr << 18) | (port_addr << 23));
+			0x00020000 | (u32)phy_reg | (((u32)dev_addr) << 18) | (((u32)port_addr) << 23));
 	for (counter = 0; counter < 100 ; counter++) {
 		udelay(30);
 		u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS);
@@ -467,7 +517,7 @@ void nes_read_10G_phy_reg(struct nes_device *nesdev, u16 phy_reg, u8 phy_addr)
 
 	/* issue read */
 	nes_write_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL,
-			0x30020000 | (dev_addr << 18) | (port_addr << 23));
+			0x30020000 | (((u32)dev_addr) << 18) | (((u32)port_addr) << 23));
 	for (counter = 0; counter < 100 ; counter++) {
 		udelay(30);
 		u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS);
@@ -483,6 +533,96 @@ void nes_read_10G_phy_reg(struct nes_device *nesdev, u16 phy_reg, u8 phy_addr)
 
 
 /**
+ * nes_get_cqp_request
+ */
+struct nes_cqp_request *nes_get_cqp_request(struct nes_device *nesdev)
+{
+	unsigned long flags;
+	struct nes_cqp_request *cqp_request = NULL;
+
+	if (!list_empty(&nesdev->cqp_avail_reqs)) {
+		spin_lock_irqsave(&nesdev->cqp.lock, flags);
+		cqp_request = list_entry(nesdev->cqp_avail_reqs.next,
+				struct nes_cqp_request, list);
+		list_del_init(&cqp_request->list);
+		spin_unlock_irqrestore(&nesdev->cqp.lock, flags);
+	} else {
+		cqp_request = kzalloc(sizeof(struct nes_cqp_request), GFP_KERNEL);
+		if (cqp_request) {
+			cqp_request->dynamic = 1;
+			INIT_LIST_HEAD(&cqp_request->list);
+		}
+	}
+
+	if (cqp_request) {
+		init_waitqueue_head(&cqp_request->waitq);
+		cqp_request->waiting = 0;
+		cqp_request->request_done = 0;
+		init_waitqueue_head(&cqp_request->waitq);
+		nes_debug(NES_DBG_CQP, "Got cqp request %p from the available list \n",
+				cqp_request);
+	} else
+		printk(KERN_ERR PFX "%s: Could not allocated a CQP request.\n",
+			   __FUNCTION__);
+
+	return cqp_request;
+}
+
+
+/**
+ * nes_post_cqp_request
+ */
+void nes_post_cqp_request(struct nes_device *nesdev,
+		struct nes_cqp_request *cqp_request, int ring_doorbell)
+{
+	struct nes_hw_cqp_wqe *cqp_wqe;
+	unsigned long flags;
+	u32 cqp_head;
+
+	spin_lock_irqsave(&nesdev->cqp.lock, flags);
+
+	if (((((nesdev->cqp.sq_tail+(nesdev->cqp.sq_size*2))-nesdev->cqp.sq_head) &
+			(nesdev->cqp.sq_size - 1)) != 1)
+			&& (list_empty(&nesdev->cqp_pending_reqs))) {
+		cqp_head = nesdev->cqp.sq_head++;
+		nesdev->cqp.sq_head &= nesdev->cqp.sq_size-1;
+		cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head];
+		memcpy(cqp_wqe, &cqp_request->cqp_wqe, sizeof(*cqp_wqe));
+		barrier();
+		cqp_wqe->wqe_words[NES_CQP_WQE_COMP_SCRATCH_LOW_IDX] = cpu_to_le32((u32)((u64)(cqp_request)));
+		cqp_wqe->wqe_words[NES_CQP_WQE_COMP_SCRATCH_HIGH_IDX] = cpu_to_le32((u32)(((u64)(cqp_request))>>32));
+		nes_debug(NES_DBG_CQP, "CQP request (opcode 0x%02X), line 1 = 0x%08X put on CQPs SQ,"
+				" request = %p, cqp_head = %u, cqp_tail = %u, cqp_size = %u,"
+				" waiting = %d, refcount = %d.\n",
+				le32_to_cpu(cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX])&0x3f,
+				le32_to_cpu(cqp_wqe->wqe_words[NES_CQP_WQE_ID_IDX]), cqp_request,
+				nesdev->cqp.sq_head, nesdev->cqp.sq_tail, nesdev->cqp.sq_size,
+				cqp_request->waiting, atomic_read(&cqp_request->refcount));
+		barrier();
+		if (ring_doorbell) {
+			/* Ring doorbell (1 WQEs) */
+			nes_write32(nesdev->regs+NES_WQE_ALLOC, 0x01800000 | nesdev->cqp.qp_id);
+		}
+
+		barrier();
+	} else {
+		nes_debug(NES_DBG_CQP, "CQP request %p (opcode 0x%02X), line 1 = 0x%08X"
+				" put on the pending queue.\n",
+				cqp_request,
+				cqp_request->cqp_wqe.wqe_words[NES_CQP_WQE_OPCODE_IDX]&0x3f,
+				cqp_request->cqp_wqe.wqe_words[NES_CQP_WQE_ID_IDX]);
+		list_add_tail(&cqp_request->list, &nesdev->cqp_pending_reqs);
+	}
+
+	spin_unlock_irqrestore(&nesdev->cqp.lock, flags);
+
+	return;
+}
+
+
+
+
+/**
  * nes_arp_table
  */
 int nes_arp_table(struct nes_device *nesdev, u32 ip_addr, u8 *mac_addr, u32 action)
@@ -503,7 +643,7 @@ int nes_arp_table(struct nes_device *nesdev, u32 ip_addr, u8 *mac_addr, u32 acti
 
 		arp_index = 0;
 		err = nes_alloc_resource(nesadapter, nesadapter->allocated_arps,
-				nesadapter->arp_table_size, &arp_index, &nesadapter->next_arp_index);
+				nesadapter->arp_table_size, (u32 *)&arp_index, &nesadapter->next_arp_index);
 		if (err) {
 			nes_debug(NES_DBG_NETDEV, "nes_alloc_resource returned error = %u\n", err);
 			return err;
@@ -680,194 +820,75 @@ no_mh_work:
 }
 
 
-/*
-"Everything you wanted to know about CRC algorithms, but were afraid to ask
- for fear that errors in your understanding might be detected." Version  : 3.
-Date  : 19 August 1993.
-Author  : Ross N. Williams.
-Net  : ross at guest.adelaide.edu.au.
-FTP  : ftp.adelaide.edu.au/pub/rocksoft/crc_v3.txt
-Company  : Rocksoft™ Pty Ltd.
-Snail  : 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
-Fax  : +61 8 373-4911 (c/- Internode Systems Pty Ltd).
-Phone  : +61 8 379-9217 (10am to 10pm Adelaide Australia time).
-Note  : "Rocksoft" is a trademark of Rocksoft Pty Ltd, Australia.
-Status  : Copyright (C) Ross Williams, 1993. However, permission is granted to
- make and distribute verbatim copies of this document provided that this information
- block and copyright notice is included. Also, the C code modules included in this
- document are fully public domain.
-
-Thanks  : Thanks to Jean-loup Gailly (jloup at chorus.fr) and Mark Adler
- (me at quest.jpl.nasa.gov) who both proof read this document and picked
- out lots of nits as well as some big fat bugs.
-
-The current web page for this seems to be http://www.ross.net/crc/crcpaper.html.
-
-*/
-
-/****************************************************************************/
-/*                            Generate width mask                           */
-/****************************************************************************/
-/*                                                                          */
-/* Returns a longword whose value is (2^p_cm->cm_width)-1.                  */
-/* The trick is to do this portably (e.g. without doing <<32).              */
-/*                                                                          */
-/* Author:  Tristan Gross                                                   */
-/* Source:  "A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS"            */
-/*          Ross N. Williams                                                */
-/*          http://www.rocksoft.com                                         */
-/*                                                                          */
-/****************************************************************************/
-
-static u32 nesCRCWidMask (u32 width)
-{
-	return(((1L<<(((u32)width)-1))-1L)<<1)|1L;
-}
-
-
-/****************************************************************************/
-/*                             Generate CRC table                           */
-/****************************************************************************/
-/*                                                                          */
-/* Source:  "A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS"            */
-/*          Ross N. Williams                                                */
-/*          http://www.rocksoft.com                                         */
-/*                                                                          */
-/****************************************************************************/
-static u32 nes_crc_table_gen ( u32 *pCRCTable,
-		u32  poly,
-		u32  order,
-		u32  reflectIn)
-{
-	u32 i;
-	u32 reg;
-	u32 byte;
-	u32 topbit = BITMASK(NES_CRC_WID-1);
-	u32 tmp;
-
-	for (byte=0;byte<256;byte++) {
-
-		// If we need to creat a reflected table we must reflect the index (byte) and
-		// reflect the final reg
-		tmp = (reflectIn) ? reflect(byte,8): byte;
-
-		reg = tmp << (NES_CRC_WID-8);
-
-		for (i=0; i<8; i++) {
-			if (reg & topbit) {
-				reg = (reg << 1) ^ poly;
-			} else {
-				reg <<= 1;
-			}
-		}
-
-		reg = (reflectIn) ?  reflect(reg,order): reg;
-		pCRCTable[byte] = reg & nesCRCWidMask(NES_CRC_WID);
-	}
-
-	return 0;
-}
-
-
-/****************************************************************************/
-/*                    Perform 32 bit based CRC calculation                  */
-/****************************************************************************/
-/*                                                                          */
-/* Source:  "A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS"            */
-/*          Ross N. Williams                                                */
-/*          http://www.rocksoft.com                                         */
-/*                                                                          */
-/* This performs a standard 32 bit crc on an array of arbitrary length      */
-/* with an arbitrary initial value and passed generator polynomial          */
-/* in the form of a crc table.                                              */
-/*                                                                          */
-/****************************************************************************/
-static u32 reflect (u32 data, u32 num)
-{
-	/* Reflects the lower num bits in 'data' around their center point. */
-	u32 i;
-	u32 j      = 1;
-	u32 result = 0;
-
-	for (i=(u32)1<<(num-1); i; i>>=1) {
-		if (data & i) result|=j;
-		j <<= 1;
-	}
-	return result;
-}
-
-
 /**
- * byte_swap
+ * nes_dump_mem
  */
-static u32 byte_swap (u32 data, u32 num)
+void nes_dump_mem(unsigned int dump_debug_level, void *addr, int length)
 {
-	u32 i;
-	u32 result = 0;
-
-	if (num%16) {
-		dprintk("\nbyte_swap: ERROR: num is not an even number of bytes\n");
-		/* ASSERT(0); */
+	char  xlate[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+		'a', 'b', 'c', 'd', 'e', 'f'};
+	char  *ptr;
+	char  hex_buf[80];
+	char  ascii_buf[20];
+	int   num_char;
+	int   num_ascii;
+	int   num_hex;
+
+	if (!(nes_debug_level & dump_debug_level)) {
+		return;
 	}
 
-	for (i = 0; i < num; i += 8) {
-		result |= (0xFF & (data >> i)) << (num-8-i);
-	}
-
-	return result;
-}
-
-
-/**
- * nes_crc32 -
- * This is a reflected table algorithm. ReflectIn basically
- * means to reflect each incomming byte of the data. But to make
- * things more complicated,  we can instead reflect the initial
- * value, the final crc, and shift data to the right using a
- * reflected pCRCTable. CRC is FUN!!
- */
-u32 nes_crc32 (   u32  reverse,
-		u32  initialValue,
-		u32  finalXOR,
-		u32  messageLength,
-		u8  *pMessage,
-		u32  order,
-		u32  reflectIn,
-		u32  reflectOut)
-
-{
-	u8     *pBlockAddr = pMessage;
-	u32     mlen       = messageLength;
-	u32     crc;
-
-	if (0 == nesCRCInitialized) {
-		nes_crc_table_gen( &nesCRCTable[0], CRC32C_POLY, ORDER, REFIN);
-		nesCRCInitialized = 1;
+	ptr = addr;
+	if (length > 0x100) {
+		nes_debug(dump_debug_level, "Length truncated from %x to %x\n", length, 0x100);
+		length = 0x100;
 	}
+	nes_debug(dump_debug_level, "Address=0x%p, length=0x%x (%d)\n", ptr, length, length);
+
+	memset(ascii_buf, 0, 20);
+	memset(hex_buf, 0, 80);
+
+	num_ascii = 0;
+	num_hex = 0;
+	for (num_char = 0; num_char < length; num_char++) {
+		if (num_ascii == 8) {
+			ascii_buf[num_ascii++] = ' ';
+			hex_buf[num_hex++] = '-';
+			hex_buf[num_hex++] = ' ';
+		}
 
-	crc = (reflectIn) ? reflect(initialValue,order): initialValue;
-
-	while (mlen--) {
-		/* printf("byte = %x, index = %u, crctable[index] = %x\n",
-				*pBlockAddr, (crc & 0xffL) ^ *pBlockAddr,
-				nesCRCTable[(crc & 0xffL) ^ *pBlockAddr]);
-		*/
-		if (reflectIn) {
-			crc = nesCRCTable[(crc & 0xffL ) ^ *pBlockAddr++] ^ (crc >> 8);
-		} else {
-			crc = nesCRCTable[((crc>>24) ^ *pBlockAddr++) & 0xFFL] ^ (crc << 8);
+		if (*ptr < 0x20 || *ptr > 0x7e)
+			ascii_buf[num_ascii++] = '.';
+		else
+			ascii_buf[num_ascii++] = *ptr;
+		hex_buf[num_hex++] = xlate[((*ptr & 0xf0) >> 4)];
+		hex_buf[num_hex++] = xlate[*ptr & 0x0f];
+		hex_buf[num_hex++] = ' ';
+		ptr++;
+
+		if (num_ascii >= 17) {
+			/* output line and reset */
+			nes_debug(dump_debug_level, "   %s |  %s\n", hex_buf, ascii_buf);
+			memset(ascii_buf, 0, 20);
+			memset(hex_buf, 0, 80);
+			num_ascii = 0;
+			num_hex = 0;
 		}
 	}
 
-	/* if reflectOut and reflectIn are both set, we don't */
-	/* do anything since reflecting twice effectively does nothing. */
-	crc = ((reflectIn)^(reflectOut)) ? reflect(crc,order): crc;
-
-	crc = crc^finalXOR;
-
-	/* We don't really use this, but it is here for completeness */
-	crc = (reverse) ? byte_swap(crc,32): crc;
+	/* output the rest */
+	if (num_ascii) {
+		while (num_ascii < 17) {
+			if (num_ascii == 8) {
+				hex_buf[num_hex++] = ' ';
+				hex_buf[num_hex++] = ' ';
+			}
+			hex_buf[num_hex++] = ' ';
+			hex_buf[num_hex++] = ' ';
+			hex_buf[num_hex++] = ' ';
+			num_ascii++;
+		}
 
-	return crc;
+		nes_debug(dump_debug_level, "   %s |  %s\n", hex_buf, ascii_buf);
+	}
 }
-



More information about the ewg mailing list