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