From owner-svn-soc-all@freebsd.org Mon Aug 17 09:13:45 2015 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 05F899BB4E0 for ; Mon, 17 Aug 2015 09:13:45 +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 E0BF41DC8 for ; Mon, 17 Aug 2015 09:13:44 +0000 (UTC) (envelope-from iateaca@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id t7H9Dijm098177 for ; Mon, 17 Aug 2015 09:13:44 GMT (envelope-from iateaca@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id t7H9DiaI098136 for svn-soc-all@FreeBSD.org; Mon, 17 Aug 2015 09:13:44 GMT (envelope-from iateaca@FreeBSD.org) Date: Mon, 17 Aug 2015 09:13:44 GMT Message-Id: <201508170913.t7H9DiaI098136@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: r289821 - 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: Mon, 17 Aug 2015 09:13:45 -0000 Author: iateaca Date: Mon Aug 17 09:13:43 2015 New Revision: 289821 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=289821 Log: redesign the emulation of the CR 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 Mon Aug 17 07:36:12 2015 (r289820) +++ soc2015/iateaca/bhyve-ne2000-head/usr.sbin/bhyve/pci_ne2000.c Mon Aug 17 09:13:43 2015 (r289821) @@ -124,6 +124,8 @@ ne2000_write_asic(struct pci_ne2000_softc *sc, uint8_t offset, uint16_t value); static int +ne2000_emul_reg_cr(struct pci_ne2000_softc *sc, uint8_t value); +static int ne2000_emul_reg_page0(struct pci_ne2000_softc *sc, uint8_t offset, uint8_t value); static int @@ -653,24 +655,9 @@ { int err; - /* check is not selected a new page */ - if (offset == ED_P0_CR) { - switch (value & (ED_CR_PS0 | ED_CR_PS1)) { - case ED_CR_PAGE_0: - sc->page = NE2000_P0; - break; - case ED_CR_PAGE_1: - sc->page = NE2000_P1; - break; - case ED_CR_PAGE_2: - DPRINTF("The ED driver seleted PAGE2"); - assert(0); - break; - case ED_CR_PAGE_3: - sc->page = NE2000_P3; - break; - } - } + /* the CR register is located always at offset = 0 */ + if (offset == ED_P0_CR || offset == ED_P1_CR || offset == ED_P2_CR) + return ne2000_emul_reg_cr(sc, value); if (!(sc->page == NE2000_P0 && offset == ED_P0_ISR)) ne2000_set_reg_by_offset(sc, sc->page, offset, value); @@ -768,8 +755,7 @@ } static int -ne2000_emul_reg_page0(struct pci_ne2000_softc *sc, uint8_t offset, - uint8_t value) +ne2000_emul_reg_cr(struct pci_ne2000_softc *sc, uint8_t value) { int err; uint8_t rbcr0 = 0; @@ -786,56 +772,85 @@ uint16_t tbcr = 0; uint8_t tpsr = 0; + /* check is not selected a new page */ + switch (value & (ED_CR_PS0 | ED_CR_PS1)) { + case ED_CR_PAGE_0: + sc->page = NE2000_P0; + break; + case ED_CR_PAGE_1: + sc->page = NE2000_P1; + break; + case ED_CR_PAGE_2: + DPRINTF("The ED driver seleted PAGE2"); + assert(0); + break; + case ED_CR_PAGE_3: + sc->page = NE2000_P3; + break; + } + + /* emulate any command specified in the CR register */ + if (value & ED_CR_STP) { + 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("Remote DMA %s: from %d address of %d bytes", + sc->remote_read ? "read" : "write", rsar, rbcr); + } + if (value & ED_CR_TXP) { + assert(!(sc->remote_read || sc->remote_write)); + assert(value & ED_CR_STA); + + tpsr = ne2000_get_reg_by_offset(sc, NE2000_P0, + ED_P0_TPSR); + tbcr0 = ne2000_get_reg_by_offset(sc, NE2000_P0, + ED_P0_TBCR0); + tbcr1 = ne2000_get_reg_by_offset(sc, NE2000_P0, + ED_P0_TBCR1); + tbcr = tbcr0 | (tbcr1 << 8); + + err = ne2000_tap_tx(sc, tpsr, tbcr); + assert(err == 0); + } + + /* store the value in the CR register located in the Page0 */ + ne2000_set_reg_by_offset(sc, NE2000_P0, ED_P0_CR, value); + + return 0; +} + +static int +ne2000_emul_reg_page0(struct pci_ne2000_softc *sc, uint8_t offset, + uint8_t value) +{ uint8_t pstart = 0; uint8_t pstop = 0; - switch (offset) { - case ED_P0_CR: - if (value & ED_CR_STP) { - 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); + assert(offset != ED_P0_CR); - DPRINTF("Remote DMA %s: from %d address of %d bytes", - sc->remote_read ? "read" : "write", rsar, rbcr); - } - if (value & ED_CR_TXP) { - assert(!(sc->remote_read || sc->remote_write)); - assert(value & ED_CR_STA); - - tpsr = ne2000_get_reg_by_offset(sc, NE2000_P0, - ED_P0_TPSR); - tbcr0 = ne2000_get_reg_by_offset(sc, NE2000_P0, - ED_P0_TBCR0); - tbcr1 = ne2000_get_reg_by_offset(sc, NE2000_P0, - ED_P0_TBCR1); - tbcr = tbcr0 | (tbcr1 << 8); - - err = ne2000_tap_tx(sc, tpsr, tbcr); - assert(err == 0); - } - break; + switch (offset) { case ED_P0_PSTART: DPRINTF("Page Start Register: %d", value); assert(value > 0 && value * ED_PAGE_SIZE < NE2000_MEM_SIZE); @@ -867,15 +882,12 @@ ne2000_emul_reg_page1(struct pci_ne2000_softc *sc, uint8_t offset, uint8_t value) { - int err; uint8_t pstart = 0; uint8_t pstop = 0; + assert(offset != ED_P1_CR); + switch (offset) { - case ED_P1_CR: - err = ne2000_emul_reg_page0(sc, offset, value); - assert(err == 0); - break; case ED_P1_PAR0 ... ED_P1_PAR5: DPRINTF("PAR[%d]: 0x%x", offset - ED_P1_PAR0, value); break;