Date: Sat, 6 Jun 2015 18:08:33 GMT From: iateaca@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r286746 - soc2015/iateaca/bhyve-ne2000-head/usr.sbin/bhyve Message-ID: <201506061808.t56I8XEn044757@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201506061808.t56I8XEn044757>