From owner-svn-soc-all@freebsd.org Fri Aug 21 16:41:16 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 7B95D9BFDB3 for ; Fri, 21 Aug 2015 16:41:16 +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 5B8DACFE for ; Fri, 21 Aug 2015 16:41:16 +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 t7LGfGqx081558 for ; Fri, 21 Aug 2015 16:41:16 GMT (envelope-from iateaca@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id t7LGfFeJ081516 for svn-soc-all@FreeBSD.org; Fri, 21 Aug 2015 16:41:15 GMT (envelope-from iateaca@FreeBSD.org) Date: Fri, 21 Aug 2015 16:41:15 GMT Message-Id: <201508211641.t7LGfFeJ081516@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: r290035 - 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: Fri, 21 Aug 2015 16:41:16 -0000 Author: iateaca Date: Fri Aug 21 16:41:14 2015 New Revision: 290035 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=290035 Log: implement the LPC attachment for the ne2k0 and ne2k1 devices Modified: soc2015/iateaca/bhyve-ne2000-head/usr.sbin/bhyve/pci_lpc.c soc2015/iateaca/bhyve-ne2000-head/usr.sbin/bhyve/pci_ne2000.c Modified: soc2015/iateaca/bhyve-ne2000-head/usr.sbin/bhyve/pci_lpc.c ============================================================================== --- soc2015/iateaca/bhyve-ne2000-head/usr.sbin/bhyve/pci_lpc.c Fri Aug 21 16:30:37 2015 (r290034) +++ soc2015/iateaca/bhyve-ne2000-head/usr.sbin/bhyve/pci_lpc.c Fri Aug 21 16:41:14 2015 (r290035) @@ -73,6 +73,18 @@ static const char *lpc_uart_names[LPC_UART_NUM] = { "COM1", "COM2" }; +#define LPC_NE2000_NUM 2 + +static struct lpc_ne2000_config { + const char *opts; + uint8_t enabled; +} lpc_ne2000[LPC_NE2000_NUM] = {{NULL, 0}, {NULL, 0}}; + +static const char *lpc_ne2000_names[LPC_NE2000_NUM] = {"ne2k0", "ne2k1"}; + +extern int +lpc_ne2000_init(struct vmctx *lpc_ctx, uint8_t unit, const char *opts); + /* * LPC device configuration is in the following form: * [,] @@ -95,6 +107,15 @@ goto done; } } + + for (unit = 0; unit < LPC_NE2000_NUM; unit++) { + if (strcasecmp(lpcdev, lpc_ne2000_names[unit]) == 0) { + lpc_ne2000[unit].enabled = 1; + lpc_ne2000[unit].opts = str; + error = 0; + goto done; + } + } } done: @@ -197,6 +218,18 @@ sc->enabled = 1; } + /* ne2k0 and ne2k1 */ + for (unit = 0; unit < LPC_NE2000_NUM; unit++) { + if (lpc_ne2000[unit].enabled) { + error = lpc_ne2000_init(lpc_bridge->pi_vmctx, unit, + lpc_ne2000[unit].opts); + if (error) { + fprintf(stderr, "Unable to initialize the " + "LPC ne2k%d device\n", unit); + } + } + } + return (0); } @@ -379,6 +412,8 @@ return (-1); } + lpc_bridge = pi; + if (lpc_init() != 0) return (-1); @@ -388,8 +423,6 @@ pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_BRIDGE); pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_BRIDGE_ISA); - lpc_bridge = pi; - return (0); } Modified: soc2015/iateaca/bhyve-ne2000-head/usr.sbin/bhyve/pci_ne2000.c ============================================================================== --- soc2015/iateaca/bhyve-ne2000-head/usr.sbin/bhyve/pci_ne2000.c Fri Aug 21 16:30:37 2015 (r290034) +++ soc2015/iateaca/bhyve-ne2000-head/usr.sbin/bhyve/pci_ne2000.c Fri Aug 21 16:41:14 2015 (r290035) @@ -1,5 +1,7 @@ +#include +#include #include #include @@ -9,9 +11,11 @@ #include #include +#include #include #include "pci_emul.h" +#include "inout.h" #include "mevent.h" #include "if_edreg.h" @@ -44,6 +48,8 @@ #define NE2000_BAR_NIC 0 #define NE2000_BAR_ASIC 1 +#define LPC_NE2000_NUM 2 + #define ED_RTL80X9_CONFIG2 0x05 #define ED_RTL80X9_CF2_10_T 0x40 #define ED_RTL80X9_CONFIG3 0x06 @@ -77,7 +83,7 @@ uint8_t remote_read; uint8_t remote_write; - /* NIC memory is 16k */ + /* NIC memory is 32k */ uint8_t ram[NE2000_MEM_SIZE]; uint8_t rcv_buf[ETHER_MAX_FRAME_LEN]; @@ -95,6 +101,17 @@ void *intr_arg; }; +static struct lpc_ne2000_softc { + struct ne2000_softc *ne2000_sc; + struct vmctx *lpc_ctx; + int base_addr; + int irq; + const char *name; +} lpc_ne2000_sc[LPC_NE2000_NUM] = { + {NULL, NULL, 0x310, 10, "ne2k0"}, + {NULL, NULL, 0x330, 11, "ne2k1"} +}; + /* * NE2000 module function declarations */ @@ -110,7 +127,7 @@ static struct ne2000_softc * ne2000_init(ne2000_intr_func_t intr_assert, ne2000_intr_func_t intr_deassert, - void *intr_arg, char *opts); + void *intr_arg, const char *opts); static void ne2000_update_intr(struct ne2000_softc *sc); @@ -163,7 +180,7 @@ ne2000_ether_crc32_be(const uint8_t *buf, size_t len); static int -ne2000_parse_input(char *opts, char *tap_name, uint8_t *mac); +ne2000_parse_input(const char *opts, char *tap_name, uint8_t *mac); /* * PCI NE2000 function declarations @@ -183,6 +200,20 @@ pci_ne2000_intr_deassert(void *arg); /* + * LPC NE2000 function declarations + */ +int +lpc_ne2000_init(struct vmctx *lpc_ctx, uint8_t unit, const char *opts); +static int +lpc_ne2000_io_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, + uint32_t *eax, void *arg); + +static void +lpc_ne2000_intr_assert(void *arg); +static void +lpc_ne2000_intr_deassert(void *arg); + +/* * NE2000 module function definitions */ static void @@ -526,9 +557,10 @@ } static int -ne2000_parse_input(char *opts, char *tap_name, uint8_t *mac) +ne2000_parse_input(const char *opts, char *tap_name, uint8_t *mac) { uint8_t len = 0; + char cp_opts[MAX_INPUT_LEN]; char *delim = NULL; char *p_mac = NULL; struct ether_addr *addr = NULL; @@ -542,8 +574,10 @@ return 1; } + strncpy(cp_opts, opts, MAX_INPUT_LEN); + /* search for mac address in the input string */ - delim = strchr(opts, ','); + delim = strchr(cp_opts, ','); if (delim != NULL) { /* mark the end of the tap name */ @@ -563,7 +597,7 @@ } /* copy the tap name */ - strcpy(tap_name, opts); + strcpy(tap_name, cp_opts); return 0; } @@ -854,7 +888,7 @@ static struct ne2000_softc * ne2000_init(ne2000_intr_func_t intr_assert, ne2000_intr_func_t intr_deassert, - void *intr_arg, char *opts) + void *intr_arg, const char *opts) { struct ne2000_softc *sc = NULL; @@ -1143,6 +1177,8 @@ pi->pi_arg = sc; + DPRINTF("PCI NE2000 initialized: ne2k,%s", opts); + return 0; } @@ -1195,6 +1231,104 @@ return; } +/* + * LPC NE2000 function definitions + */ +int +lpc_ne2000_init(struct vmctx *lpc_ctx, uint8_t unit, const char *opts) +{ + struct ne2000_softc *sc = NULL; + struct inout_port iop; + int err; + + assert(lpc_ctx != NULL); + assert(unit < LPC_NE2000_NUM); + + if (lpc_ne2000_sc[unit].ne2000_sc != NULL) { + fprintf(stderr, "The LPC ne2k%d device is initialized\n", unit); + return 0; + } + + /* + * Allocate one io port for both NIC and ASIC I/O bus address offsets. + * The NE2000 devices on the LPC bus generate edge triggered interrupts + * so nothing more to do here + */ + bzero(&iop, sizeof(struct inout_port)); + iop.name = lpc_ne2000_sc[unit].name; + iop.port = lpc_ne2000_sc[unit].base_addr; + iop.size = ED_NOVELL_IO_PORTS; + iop.flags = IOPORT_F_INOUT; + iop.handler = lpc_ne2000_io_handler; + iop.arg = &lpc_ne2000_sc[unit]; + + err = register_inout(&iop); + assert(err == 0); + + /* initialize the ne2000 data structure */ + sc = ne2000_init(lpc_ne2000_intr_assert, lpc_ne2000_intr_deassert, + &lpc_ne2000_sc[unit], opts); + if (sc == NULL) + return -1; + + lpc_ne2000_sc[unit].ne2000_sc = sc; + lpc_ne2000_sc[unit].lpc_ctx = lpc_ctx; + + DPRINTF("LPC NE2000 initialized: %s,%s", lpc_ne2000_sc[unit].name, opts); + + return 0; +} + +static int +lpc_ne2000_io_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, + uint32_t *eax, void *arg) +{ + struct lpc_ne2000_softc *sc_lpc_ne2000 = (struct lpc_ne2000_softc *)arg; + struct ne2000_softc *sc = NULL; + + uint8_t offset = 0; + int err; + + assert(sc_lpc_ne2000 != NULL); + + sc = sc_lpc_ne2000->ne2000_sc; + assert(sc != NULL); + + offset = port - sc_lpc_ne2000->base_addr; + + if (in) { + *eax = ne2000_read(sc, offset, bytes); + } + else { + err = ne2000_write(sc, offset, *eax, bytes); + assert(err == 0); + } + + return 0; +} + +static void +lpc_ne2000_intr_assert(void *arg) +{ + struct lpc_ne2000_softc *sc_lpc_ne2000 = (struct lpc_ne2000_softc *)arg; + struct vmctx *lpc_ctx = sc_lpc_ne2000->lpc_ctx; + + vm_isa_pulse_irq(lpc_ctx, sc_lpc_ne2000->irq, sc_lpc_ne2000->irq); + + return; +} + +static void +lpc_ne2000_intr_deassert(void *arg) +{ + /* + * The NE2000 devices on the LPC bus generate edge triggered interrupts + * so nothing more to do here + */ + + return; +} + struct pci_devemu pci_de_ne2000_net = { .pe_emu = "ne2000-net", .pe_init = pci_ne2000_init,