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

Cache object: 708b39314e0f0bc57fbfb4c39b003871


[ 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.