Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 19 Nov 2012 01:58:20 +0000 (UTC)
From:      Juli Mallett <jmallett@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r243255 - head/sys/mips/cavium
Message-ID:  <201211190158.qAJ1wKr2058487@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jmallett
Date: Mon Nov 19 01:58:20 2012
New Revision: 243255
URL: http://svnweb.freebsd.org/changeset/base/243255

Log:
  Add basic support for the Radisys-specific PCI console mechanism found on the
  Radisys ATCA-7220.

Modified:
  head/sys/mips/cavium/octeon_pci_console.c

Modified: head/sys/mips/cavium/octeon_pci_console.c
==============================================================================
--- head/sys/mips/cavium/octeon_pci_console.c	Mon Nov 19 01:15:32 2012	(r243254)
+++ head/sys/mips/cavium/octeon_pci_console.c	Mon Nov 19 01:58:20 2012	(r243255)
@@ -39,8 +39,22 @@ __FBSDID("$FreeBSD$");
 
 #include <contrib/octeon-sdk/cvmx.h>
 #include <contrib/octeon-sdk/cvmx-bootmem.h>
+#include <contrib/octeon-sdk/cvmx-interrupt.h>
 #include <contrib/octeon-sdk/octeon-pci-console.h>
 
+#ifdef OCTEON_VENDOR_RADISYS
+#define	OPCIC_FLAG_RSYS		(0x00000001)
+
+#define	OPCIC_RSYS_FIFO_SIZE	(0x2000)
+#endif
+
+struct opcic_softc {
+	unsigned sc_flags;
+	uint64_t sc_base_addr;
+};
+
+static struct opcic_softc opcic_instance;
+
 static cn_probe_t opcic_cnprobe;
 static cn_init_t opcic_cninit;
 static cn_term_t opcic_cnterm;
@@ -49,20 +63,46 @@ static cn_putc_t opcic_cnputc;
 static cn_grab_t opcic_cngrab;
 static cn_ungrab_t opcic_cnungrab;
 
+#ifdef OCTEON_VENDOR_RADISYS
+static int opcic_rsys_cngetc(struct opcic_softc *);
+static void opcic_rsys_cnputc(struct opcic_softc *, int);
+#endif
+
 CONSOLE_DRIVER(opcic);
 
 static void
 opcic_cnprobe(struct consdev *cp)
 {
 	const struct cvmx_bootmem_named_block_desc *pci_console_block;
+	struct opcic_softc *sc;
+
+	sc = &opcic_instance;
+	sc->sc_flags = 0;
+	sc->sc_base_addr = 0;
 
 	cp->cn_pri = CN_DEAD;
 
-	pci_console_block = cvmx_bootmem_find_named_block(OCTEON_PCI_CONSOLE_BLOCK_NAME);
-	if (pci_console_block == NULL)
-		return;
+	switch (cvmx_sysinfo_get()->board_type) {
+#ifdef OCTEON_VENDOR_RADISYS
+	case CVMX_BOARD_TYPE_CUST_RADISYS_RSYS4GBE:
+		pci_console_block =
+		    cvmx_bootmem_find_named_block("rsys_gbl_memory");
+		if (pci_console_block != NULL) {
+			sc->sc_flags |= OPCIC_FLAG_RSYS;
+			sc->sc_base_addr = pci_console_block->base_addr;
+			break;
+		}
+#endif
+	default:
+		pci_console_block =
+		    cvmx_bootmem_find_named_block(OCTEON_PCI_CONSOLE_BLOCK_NAME);
+		if (pci_console_block == NULL)
+			return;
+		sc->sc_base_addr = pci_console_block->base_addr;
+		break;
+	}
 
-	cp->cn_arg = (void *)(uintptr_t)pci_console_block->base_addr;
+	cp->cn_arg = sc;
 	snprintf(cp->cn_name, sizeof cp->cn_name, "opcic@%p", cp->cn_arg);
 	cp->cn_pri = (boothowto & RB_SERIAL) ? CN_REMOTE : CN_NORMAL;
 }
@@ -82,13 +122,19 @@ opcic_cnterm(struct consdev *cp)
 static int
 opcic_cngetc(struct consdev *cp)
 {
-	uint64_t console_desc_addr;
+	struct opcic_softc *sc;
 	char ch;
 	int rv;
 
-	console_desc_addr = (uintptr_t)cp->cn_arg;
+	sc = cp->cn_arg;
 
-	rv = octeon_pci_console_read(console_desc_addr, 0, &ch, 1, OCT_PCI_CON_FLAG_NONBLOCK);
+#ifdef OCTEON_VENDOR_RADISYS
+	if ((sc->sc_flags & OPCIC_FLAG_RSYS) != 0)
+		return (opcic_rsys_cngetc(sc));
+#endif
+
+	rv = octeon_pci_console_read(sc->sc_base_addr, 0, &ch, 1,
+	    OCT_PCI_CON_FLAG_NONBLOCK);
 	if (rv != 1)
 		return (-1);
 	return (ch);
@@ -97,14 +143,21 @@ opcic_cngetc(struct consdev *cp)
 static void
 opcic_cnputc(struct consdev *cp, int c)
 {
-	uint64_t console_desc_addr;
+	struct opcic_softc *sc;
 	char ch;
 	int rv;
 
-	console_desc_addr = (uintptr_t)cp->cn_arg;
+	sc = cp->cn_arg;
 	ch = c;
 
-	rv = octeon_pci_console_write(console_desc_addr, 0, &ch, 1, 0);
+#ifdef OCTEON_VENDOR_RADISYS
+	if ((sc->sc_flags & OPCIC_FLAG_RSYS) != 0) {
+		opcic_rsys_cnputc(sc, c);
+		return;
+	}
+#endif
+
+	rv = octeon_pci_console_write(sc->sc_base_addr, 0, &ch, 1, 0);
 	if (rv == -1)
 		panic("%s: octeon_pci_console_write failed.", __func__);
 }
@@ -120,3 +173,64 @@ opcic_cnungrab(struct consdev *cp)
 {
 	(void)cp;
 }
+
+#ifdef OCTEON_VENDOR_RADISYS
+static int
+opcic_rsys_cngetc(struct opcic_softc *sc)
+{
+	uint64_t gbl_base;
+	uint64_t console_base;
+	uint64_t console_rbuf;
+	uint64_t console_rcnt[2];
+	uint16_t rcnt[2];
+	uint16_t roff;
+	int c;
+
+	gbl_base = CVMX_ADD_IO_SEG(sc->sc_base_addr);
+	console_base = gbl_base + 0x10;
+
+	console_rbuf = console_base + 0x2018;
+	console_rcnt[0] = console_base + 0x08;
+	console_rcnt[1] = console_base + 0x0a;
+
+	/* Check if there is anything new in the FIFO.  */
+	rcnt[0] = cvmx_read64_uint16(console_rcnt[0]);
+	rcnt[1] = cvmx_read64_uint16(console_rcnt[1]);
+	if (rcnt[0] == rcnt[1])
+		return (-1);
+
+	/* Get first new character in the FIFO.  */
+	if (rcnt[0] != 0)
+		roff = rcnt[0] - 1;
+	else
+		roff = OPCIC_RSYS_FIFO_SIZE - 1;
+	c = cvmx_read64_uint8(console_rbuf + roff);
+
+	/* Advance FIFO.  */
+	rcnt[1] = (rcnt[1] + 1) % OPCIC_RSYS_FIFO_SIZE;
+	cvmx_write64_uint16(console_rcnt[1], rcnt[1]);
+
+	return (c);
+}
+
+static void
+opcic_rsys_cnputc(struct opcic_softc *sc, int c)
+{
+	uint64_t gbl_base;
+	uint64_t console_base;
+	uint64_t console_wbuf;
+	uint64_t console_wcnt;
+	uint16_t wcnt;
+
+	gbl_base = CVMX_ADD_IO_SEG(sc->sc_base_addr);
+	console_base = gbl_base + 0x10;
+
+	console_wbuf = console_base + 0x0018;
+	console_wcnt = console_base + 0x0c;
+
+	/* Append character to FIFO.  */
+	wcnt = cvmx_read64_uint16(console_wcnt) % OPCIC_RSYS_FIFO_SIZE;
+	cvmx_write64_uint8(console_wbuf + wcnt, (uint8_t)c);
+	cvmx_write64_uint16(console_wcnt, wcnt + 1);
+}
+#endif



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201211190158.qAJ1wKr2058487>