From owner-svn-soc-all@FreeBSD.ORG Sat Jun 6 18:08:33 2015 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id CF7EC5D8 for ; Sat, 6 Jun 2015 18:08:33 +0000 (UTC) (envelope-from iateaca@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id B0CBC1C34 for ; Sat, 6 Jun 2015 18:08:33 +0000 (UTC) (envelope-from iateaca@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.14.9/8.14.9) with ESMTP id t56I8XM3045382 for ; Sat, 6 Jun 2015 18:08:33 GMT (envelope-from iateaca@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.14.9/8.14.9/Submit) id t56I8XEn044757 for svn-soc-all@FreeBSD.org; Sat, 6 Jun 2015 18:08:33 GMT (envelope-from iateaca@FreeBSD.org) Date: Sat, 6 Jun 2015 18:08:33 GMT Message-Id: <201506061808.t56I8XEn044757@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to iateaca@FreeBSD.org using -f From: iateaca@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r286746 - soc2015/iateaca/bhyve-ne2000-head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 06 Jun 2015 18:08:34 -0000 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);