socsvn commit: r286746 - soc2015/iateaca/bhyve-ne2000-head/usr.sbin/bhyve

iateaca at FreeBSD.org iateaca at FreeBSD.org
Sat Jun 6 18:08:34 UTC 2015


Author: iateaca
Date: Sat Jun  6 18:08:32 2015
New Revision: 286746
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=286746

Log:
  - improve the Remote DMA protocol with a better error checking and assert ED_ISR_RDC flag in ISR register when Write is complete
  - emulate ISR register

Modified:
  soc2015/iateaca/bhyve-ne2000-head/usr.sbin/bhyve/pci_ne2000.c

Modified: soc2015/iateaca/bhyve-ne2000-head/usr.sbin/bhyve/pci_ne2000.c
==============================================================================
--- soc2015/iateaca/bhyve-ne2000-head/usr.sbin/bhyve/pci_ne2000.c	Sat Jun  6 17:25:45 2015	(r286745)
+++ soc2015/iateaca/bhyve-ne2000-head/usr.sbin/bhyve/pci_ne2000.c	Sat Jun  6 18:08:32 2015	(r286746)
@@ -57,12 +57,26 @@
 
 	/* State Variables */
 	uint8_t page;
+	uint8_t remote_read;
+	uint8_t remote_write;
 
 	/* NIC memory is 16k */
 	uint8_t ram[NE2000_MEM_SIZE];
 };
 
 /*
+ * NE2000 debug functions
+ */
+void vm_inject_fault(void *vm, int vcpuid, int vector, int errcode_valid,
+		int errcode);
+
+static void
+pci_ne2000_inject_ud(struct pci_ne2000_softc *sc)
+{
+	vm_inject_fault(sc->asc_pi->pi_vmctx, 0, 6, 0, 0);
+}
+
+/*
  * NE2000 module function declarations
  */
 static void
@@ -88,6 +102,9 @@
 static int
 ne2000_emul_reg_page0(struct pci_ne2000_softc *sc, uint8_t offset,
 		uint8_t value);
+static int
+ne2000_emul_reg_page1(struct pci_ne2000_softc *sc, uint8_t offset,
+		uint8_t value);
 
 static int ne2000_reset_board(void);
 static int ne2000_software_reset(struct pci_ne2000_softc *sc);
@@ -233,8 +250,10 @@
 	if (sc->page == NE2000_P0) {
 		err = ne2000_emul_reg_page0(sc, offset, value);
 		assert(err == 0);
-	}
-	else if (sc->page == NE2000_P3)
+	} else if (sc->page == NE2000_P1) {
+		err = ne2000_emul_reg_page1(sc, offset, value);
+		assert(err == 0);
+	} else if (sc->page == NE2000_P3)
 		DPRINTF("The ED driver wrote a register from PAGE3");
 	else
 		assert(0);
@@ -246,7 +265,6 @@
 ne2000_write_asic(struct pci_ne2000_softc *sc, uint8_t offset, uint16_t value)
 {
 	uint8_t dcr = 0;
-	uint8_t cr = 0;
 	uint8_t rbcr0 = 0;
 	uint8_t rbcr1 = 0;
 	uint8_t rsar0 = 0;
@@ -266,12 +284,11 @@
 		dcr = ne2000_get_reg_by_offset(sc, NE2000_P0, ED_P0_DCR);
 		if ((dcr & ED_DCR_WTS) != ED_DCR_WTS) {
 			DPRINTF("The NE2000 card is working only in Word mode");
+			sc->remote_write = 0;
 			break;
 		}
 
-		cr = ne2000_get_reg_by_offset(sc, NE2000_P0, ED_P0_CR);
-		assert((cr & (ED_CR_RD1 | ED_CR_STA)) ==
-				(ED_CR_RD1 | ED_CR_STA));
+		assert(sc->remote_write);
 
 		rbcr0 = ne2000_get_reg_by_offset(sc, NE2000_P0, ED_P0_RBCR0);
 		rbcr1 = ne2000_get_reg_by_offset(sc, NE2000_P0, ED_P0_RBCR1);
@@ -290,6 +307,12 @@
 		rsar += 2;
 		rbcr -= 2;
 
+		if (rbcr == 0) {
+			sc->remote_write = 0;
+			ne2000_set_field_by_offset(sc, NE2000_P0, ED_P0_ISR,
+					ED_ISR_RDC, ED_ISR_RDC);
+		}
+
 		ne2000_set_reg_by_offset(sc, NE2000_P0, ED_P0_RSAR0, rsar);
 		ne2000_set_reg_by_offset(sc, NE2000_P0, ED_P0_RSAR1, rsar >> 8);
 
@@ -309,6 +332,13 @@
 		uint8_t value)
 {
 	int err;
+	uint8_t rbcr0 = 0;
+	uint8_t rbcr1 = 0;
+	uint8_t rsar0 = 0;
+	uint8_t rsar1 = 0;
+
+	uint16_t rbcr = 0;
+	uint16_t rsar = 0;
 
 	switch (offset) {
 	case ED_P0_CR:
@@ -316,6 +346,36 @@
 			err = ne2000_software_reset(sc);
 			assert(err == 0);
 		}
+		if (value & ED_CR_RD2)
+			assert(!(sc->remote_read || sc->remote_write));
+		if (value & (ED_CR_RD0 | ED_CR_RD1)) {
+			assert(value & ED_CR_STA);
+
+			if (value & ED_CR_RD0)
+				sc->remote_read = 1;
+			else
+				sc->remote_write = 1;
+
+			rbcr0 = ne2000_get_reg_by_offset(sc, NE2000_P0,
+					ED_P0_RBCR0);
+			rbcr1 = ne2000_get_reg_by_offset(sc, NE2000_P0,
+					ED_P0_RBCR1);
+			rbcr = rbcr0 | (rbcr1 << 8);
+
+			rsar0 = ne2000_get_reg_by_offset(sc, NE2000_P0,
+					ED_P0_RSAR0);
+			rsar1 = ne2000_get_reg_by_offset(sc, NE2000_P0,
+					ED_P0_RSAR1);
+			rsar = rsar0 | (rsar1 << 8);
+
+			DPRINTF("ED driver started a Remote DMA %s op from %d address of %d bytes",
+				sc->remote_read ? "read" : "write", rsar, rbcr);
+		}
+		if (value & ED_CR_TXP) {
+		}
+		break;
+	case ED_P0_ISR:
+		ne2000_set_field_by_offset(sc, NE2000_P0, ED_P0_ISR, value, 0);
 		break;
 	}
 
@@ -323,14 +383,20 @@
 }
 
 static int
-ne2000_software_reset(struct pci_ne2000_softc *sc)
+ne2000_emul_reg_page1(struct pci_ne2000_softc *sc, uint8_t offset,
+		uint8_t value)
 {
-	uint8_t mask = 0;
-	uint8_t value = 0;
+	if (offset == ED_P1_CR)
+		return ne2000_emul_reg_page0(sc, offset, value);
+
+	return 0;
+}
 
-	mask |= ED_ISR_RST;
-	value |= ED_ISR_RST;
-	ne2000_set_field_by_offset(sc, NE2000_P0, ED_P0_ISR, mask, value);
+static int
+ne2000_software_reset(struct pci_ne2000_softc *sc)
+{
+	ne2000_set_field_by_offset(sc, NE2000_P0, ED_P0_ISR,
+			ED_ISR_RST, ED_ISR_RST);
 
 	return 0;
 }
@@ -385,7 +451,6 @@
 {
 	int err;
 	uint8_t dcr = 0;
-	uint8_t cr = 0;
 	uint8_t rbcr0 = 0;
 	uint8_t rbcr1 = 0;
 	uint8_t rsar0 = 0;
@@ -408,12 +473,11 @@
 		dcr = ne2000_get_reg_by_offset(sc, NE2000_P0, ED_P0_DCR);
 		if ((dcr & ED_DCR_WTS) != ED_DCR_WTS) {
 			DPRINTF("The NE2000 card is working only in Word mode");
+			sc->remote_read = 0;
 			break;
 		}
 
-		cr = ne2000_get_reg_by_offset(sc, NE2000_P0, ED_P0_CR);
-		assert((cr & (ED_CR_RD0 | ED_CR_STA)) ==
-				(ED_CR_RD0 | ED_CR_STA));
+		assert(sc->remote_read);
 
 		rbcr0 = ne2000_get_reg_by_offset(sc, NE2000_P0, ED_P0_RBCR0);
 		rbcr1 = ne2000_get_reg_by_offset(sc, NE2000_P0, ED_P0_RBCR1);
@@ -431,6 +495,9 @@
 		rsar += 2;
 		rbcr -= 2;
 
+		if (rbcr == 0)
+			sc->remote_read = 0;
+
 		ne2000_set_reg_by_offset(sc, NE2000_P0, ED_P0_RSAR0, rsar);
 		ne2000_set_reg_by_offset(sc, NE2000_P0, ED_P0_RSAR1, rsar >> 8);
 


More information about the svn-soc-all mailing list