The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/mips/cavium/octeon_pci_console.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2012 Juli Mallett <jmallett@FreeBSD.org>
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   26  * SUCH DAMAGE.
   27  *
   28  * $FreeBSD$
   29  */
   30 
   31 #include <sys/cdefs.h>
   32 __FBSDID("$FreeBSD$");
   33 
   34 #include <sys/param.h>
   35 #include <sys/systm.h>
   36 #include <sys/bus.h>
   37 #include <sys/conf.h>
   38 #include <sys/cons.h>
   39 #include <sys/kernel.h>
   40 #include <sys/reboot.h>
   41 
   42 #include <contrib/octeon-sdk/cvmx.h>
   43 #include <contrib/octeon-sdk/cvmx-bootmem.h>
   44 #include <contrib/octeon-sdk/cvmx-interrupt.h>
   45 #include <contrib/octeon-sdk/octeon-pci-console.h>
   46 
   47 #ifdef OCTEON_VENDOR_RADISYS
   48 #define OPCIC_FLAG_RSYS         (0x00000001)
   49 
   50 #define OPCIC_RSYS_FIFO_SIZE    (0x2000)
   51 #endif
   52 
   53 struct opcic_softc {
   54         unsigned sc_flags;
   55         uint64_t sc_base_addr;
   56 };
   57 
   58 static struct opcic_softc opcic_instance;
   59 
   60 static cn_probe_t opcic_cnprobe;
   61 static cn_init_t opcic_cninit;
   62 static cn_term_t opcic_cnterm;
   63 static cn_getc_t opcic_cngetc;
   64 static cn_putc_t opcic_cnputc;
   65 static cn_grab_t opcic_cngrab;
   66 static cn_ungrab_t opcic_cnungrab;
   67 
   68 #ifdef OCTEON_VENDOR_RADISYS
   69 static int opcic_rsys_cngetc(struct opcic_softc *);
   70 static void opcic_rsys_cnputc(struct opcic_softc *, int);
   71 #endif
   72 
   73 CONSOLE_DRIVER(opcic);
   74 
   75 static void
   76 opcic_cnprobe(struct consdev *cp)
   77 {
   78         const struct cvmx_bootmem_named_block_desc *pci_console_block;
   79         struct opcic_softc *sc;
   80 
   81         sc = &opcic_instance;
   82         sc->sc_flags = 0;
   83         sc->sc_base_addr = 0;
   84 
   85         cp->cn_pri = CN_DEAD;
   86 
   87         switch (cvmx_sysinfo_get()->board_type) {
   88 #ifdef OCTEON_VENDOR_RADISYS
   89         case CVMX_BOARD_TYPE_CUST_RADISYS_RSYS4GBE:
   90                 pci_console_block =
   91                     cvmx_bootmem_find_named_block("rsys_gbl_memory");
   92                 if (pci_console_block != NULL) {
   93                         sc->sc_flags |= OPCIC_FLAG_RSYS;
   94                         sc->sc_base_addr = pci_console_block->base_addr;
   95                         break;
   96                 }
   97 #endif
   98         default:
   99                 pci_console_block =
  100                     cvmx_bootmem_find_named_block(OCTEON_PCI_CONSOLE_BLOCK_NAME);
  101                 if (pci_console_block == NULL)
  102                         return;
  103                 sc->sc_base_addr = pci_console_block->base_addr;
  104                 break;
  105         }
  106 
  107         cp->cn_arg = sc;
  108         snprintf(cp->cn_name, sizeof cp->cn_name, "opcic@%p", cp->cn_arg);
  109         cp->cn_pri = (boothowto & RB_SERIAL) ? CN_REMOTE : CN_NORMAL;
  110 }
  111 
  112 static void
  113 opcic_cninit(struct consdev *cp)
  114 {
  115         (void)cp;
  116 }
  117 
  118 static void
  119 opcic_cnterm(struct consdev *cp)
  120 {
  121         (void)cp;
  122 }
  123 
  124 static int
  125 opcic_cngetc(struct consdev *cp)
  126 {
  127         struct opcic_softc *sc;
  128         char ch;
  129         int rv;
  130 
  131         sc = cp->cn_arg;
  132 
  133 #ifdef OCTEON_VENDOR_RADISYS
  134         if ((sc->sc_flags & OPCIC_FLAG_RSYS) != 0)
  135                 return (opcic_rsys_cngetc(sc));
  136 #endif
  137 
  138         rv = octeon_pci_console_read(sc->sc_base_addr, 0, &ch, 1,
  139             OCT_PCI_CON_FLAG_NONBLOCK);
  140         if (rv != 1)
  141                 return (-1);
  142         return (ch);
  143 }
  144 
  145 static void
  146 opcic_cnputc(struct consdev *cp, int c)
  147 {
  148         struct opcic_softc *sc;
  149         char ch;
  150         int rv;
  151 
  152         sc = cp->cn_arg;
  153         ch = c;
  154 
  155 #ifdef OCTEON_VENDOR_RADISYS
  156         if ((sc->sc_flags & OPCIC_FLAG_RSYS) != 0) {
  157                 opcic_rsys_cnputc(sc, c);
  158                 return;
  159         }
  160 #endif
  161 
  162         rv = octeon_pci_console_write(sc->sc_base_addr, 0, &ch, 1, 0);
  163         if (rv == -1)
  164                 panic("%s: octeon_pci_console_write failed.", __func__);
  165 }
  166 
  167 static void
  168 opcic_cngrab(struct consdev *cp)
  169 {
  170         (void)cp;
  171 }
  172 
  173 static void
  174 opcic_cnungrab(struct consdev *cp)
  175 {
  176         (void)cp;
  177 }
  178 
  179 #ifdef OCTEON_VENDOR_RADISYS
  180 static int
  181 opcic_rsys_cngetc(struct opcic_softc *sc)
  182 {
  183         uint64_t gbl_base;
  184         uint64_t console_base;
  185         uint64_t console_rbuf;
  186         uint64_t console_rcnt[2];
  187         uint16_t rcnt[2];
  188         uint16_t roff;
  189         int c;
  190 
  191         gbl_base = CVMX_ADD_IO_SEG(sc->sc_base_addr);
  192         console_base = gbl_base + 0x10;
  193 
  194         console_rbuf = console_base + 0x2018;
  195         console_rcnt[0] = console_base + 0x08;
  196         console_rcnt[1] = console_base + 0x0a;
  197 
  198         /* Check if there is anything new in the FIFO.  */
  199         rcnt[0] = cvmx_read64_uint16(console_rcnt[0]);
  200         rcnt[1] = cvmx_read64_uint16(console_rcnt[1]);
  201         if (rcnt[0] == rcnt[1])
  202                 return (-1);
  203 
  204         /* Get first new character in the FIFO.  */
  205         if (rcnt[0] != 0)
  206                 roff = rcnt[0] - 1;
  207         else
  208                 roff = OPCIC_RSYS_FIFO_SIZE - 1;
  209         c = cvmx_read64_uint8(console_rbuf + roff);
  210 
  211         /* Advance FIFO.  */
  212         rcnt[1] = (rcnt[1] + 1) % OPCIC_RSYS_FIFO_SIZE;
  213         cvmx_write64_uint16(console_rcnt[1], rcnt[1]);
  214 
  215         return (c);
  216 }
  217 
  218 static void
  219 opcic_rsys_cnputc(struct opcic_softc *sc, int c)
  220 {
  221         uint64_t gbl_base;
  222         uint64_t console_base;
  223         uint64_t console_wbuf;
  224         uint64_t console_wcnt;
  225         uint16_t wcnt;
  226 
  227         gbl_base = CVMX_ADD_IO_SEG(sc->sc_base_addr);
  228         console_base = gbl_base + 0x10;
  229 
  230         console_wbuf = console_base + 0x0018;
  231         console_wcnt = console_base + 0x0c;
  232 
  233         /* Append character to FIFO.  */
  234         wcnt = cvmx_read64_uint16(console_wcnt) % OPCIC_RSYS_FIFO_SIZE;
  235         cvmx_write64_uint8(console_wbuf + wcnt, (uint8_t)c);
  236         cvmx_write64_uint16(console_wcnt, wcnt + 1);
  237 }
  238 #endif

Cache object: d282dfcacf766c3e8bd3cbc6dd2b7404


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.