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/dev/liquidio/base/lio_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  *   BSD LICENSE
    3  *
    4  *   Copyright(c) 2017 Cavium, Inc.. All rights reserved.
    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  *
   11  *     * Redistributions of source code must retain the above copyright
   12  *       notice, this list of conditions and the following disclaimer.
   13  *     * Redistributions in binary form must reproduce the above copyright
   14  *       notice, this list of conditions and the following disclaimer in
   15  *       the documentation and/or other materials provided with the
   16  *       distribution.
   17  *     * Neither the name of Cavium, Inc. nor the names of its
   18  *       contributors may be used to endorse or promote products derived
   19  *       from this software without specific prior written permission.
   20  *
   21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   25  *   OWNER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   32  */
   33 /*$FreeBSD$*/
   34 
   35 /*
   36  * @file lio_console.c
   37  */
   38 
   39 #include "lio_bsd.h"
   40 #include "lio_common.h"
   41 #include "lio_droq.h"
   42 #include "lio_iq.h"
   43 #include "lio_response_manager.h"
   44 #include "lio_device.h"
   45 #include "lio_image.h"
   46 #include "lio_mem_ops.h"
   47 #include "lio_main.h"
   48 
   49 static void     lio_get_uboot_version(struct octeon_device *oct);
   50 static void     lio_remote_lock(void);
   51 static void     lio_remote_unlock(void);
   52 static uint64_t cvmx_bootmem_phy_named_block_find(struct octeon_device *oct,
   53                                                   const char *name,
   54                                                   uint32_t flags);
   55 static int      lio_console_read(struct octeon_device *oct,
   56                                  uint32_t console_num, char *buffer,
   57                                  uint32_t buf_size);
   58 
   59 #define CAST_ULL(v)     ((unsigned long long)(v))
   60 
   61 #define LIO_BOOTLOADER_PCI_READ_BUFFER_DATA_ADDR        0x0006c008
   62 #define LIO_BOOTLOADER_PCI_READ_BUFFER_LEN_ADDR         0x0006c004
   63 #define LIO_BOOTLOADER_PCI_READ_BUFFER_OWNER_ADDR       0x0006c000
   64 #define LIO_BOOTLOADER_PCI_READ_DESC_ADDR               0x0006c100
   65 #define LIO_BOOTLOADER_PCI_WRITE_BUFFER_STR_LEN         248
   66 
   67 #define LIO_PCI_IO_BUF_OWNER_OCTEON     0x00000001
   68 #define LIO_PCI_IO_BUF_OWNER_HOST       0x00000002
   69 
   70 #define LIO_PCI_CONSOLE_BLOCK_NAME      "__pci_console"
   71 #define LIO_CONSOLE_POLL_INTERVAL_MS    100     /* 10 times per second */
   72 
   73 /*
   74  * First three members of cvmx_bootmem_desc are left in original positions
   75  * for backwards compatibility. Assumes big endian target
   76  */
   77 struct cvmx_bootmem_desc {
   78         /* lock to control access to list */
   79         uint32_t        lock;
   80 
   81         /* flags for indicating various conditions */
   82         uint32_t        flags;
   83 
   84         uint64_t        head_addr;
   85 
   86         /* incremented changed when incompatible changes made */
   87         uint32_t        major_version;
   88 
   89         /*
   90          * incremented changed when compatible changes made, reset to zero
   91          * when major incremented
   92          */
   93         uint32_t        minor_version;
   94 
   95         uint64_t        app_data_addr;
   96         uint64_t        app_data_size;
   97 
   98         /* number of elements in named blocks array */
   99         uint32_t        nb_num_blocks;
  100 
  101         /* length of name array in bootmem blocks */
  102         uint32_t        named_block_name_len;
  103 
  104         /* address of named memory block descriptors */
  105         uint64_t        named_block_array_addr;
  106 };
  107 
  108 /*
  109  * Structure that defines a single console.
  110  *
  111  * Note: when read_index == write_index, the buffer is empty. The actual usable
  112  * size of each console is console_buf_size -1;
  113  */
  114 struct lio_pci_console {
  115         uint64_t        input_base_addr;
  116         uint32_t        input_read_index;
  117         uint32_t        input_write_index;
  118         uint64_t        output_base_addr;
  119         uint32_t        output_read_index;
  120         uint32_t        output_write_index;
  121         uint32_t        lock;
  122         uint32_t        buf_size;
  123 };
  124 
  125 /*
  126  * This is the main container structure that contains all the information
  127  * about all PCI consoles.  The address of this structure is passed to
  128  * various routines that operation on PCI consoles.
  129  */
  130 struct lio_pci_console_desc {
  131         uint32_t        major_version;
  132         uint32_t        minor_version;
  133         uint32_t        lock;
  134         uint32_t        flags;
  135         uint32_t        num_consoles;
  136         uint32_t        pad;
  137         /* must be 64 bit aligned here... */
  138         /* Array of addresses of octeon_pci_console structures */
  139         uint64_t        console_addr_array[1];
  140         /* Implicit storage for console_addr_array */
  141 };
  142 
  143 /*
  144  * This macro returns the size of a member of a structure. Logically it is
  145  * the same as "sizeof(s::field)" in C++, but C lacks the "::" operator.
  146  */
  147 #define SIZEOF_FIELD(s, field) sizeof(((s *)NULL)->field)
  148 /*
  149  * This function is the implementation of the get macros defined
  150  * for individual structure members. The argument are generated
  151  * by the macros inorder to read only the needed memory.
  152  *
  153  * @param oct    Pointer to current octeon device
  154  * @param base   64bit physical address of the complete structure
  155  * @param offset Offset from the beginning of the structure to the member being
  156  *               accessed.
  157  * @param size   Size of the structure member.
  158  *
  159  * @return Value of the structure member promoted into a uint64_t.
  160  */
  161 static inline uint64_t
  162 __cvmx_bootmem_desc_get(struct octeon_device *oct, uint64_t base,
  163                         uint32_t offset, uint32_t size)
  164 {
  165 
  166         base = (1ull << 63) | (base + offset);
  167         switch (size) {
  168         case 4:
  169                 return (lio_read_device_mem32(oct, base));
  170         case 8:
  171                 return (lio_read_device_mem64(oct, base));
  172         default:
  173                 return (0);
  174         }
  175 }
  176 
  177 /*
  178  * This function retrieves the string name of a named block. It is
  179  * more complicated than a simple memcpy() since the named block
  180  * descriptor may not be directly accessible.
  181  *
  182  * @param oct    Pointer to current octeon device
  183  * @param addr   Physical address of the named block descriptor
  184  * @param str    String to receive the named block string name
  185  * @param len    Length of the string buffer, which must match the length
  186  *               stored in the bootmem descriptor.
  187  */
  188 static void
  189 lio_bootmem_named_get_name(struct octeon_device *oct, uint64_t addr, char *str,
  190                            uint32_t len)
  191 {
  192 
  193         addr += offsetof(struct cvmx_bootmem_named_block_desc, name);
  194         lio_pci_read_core_mem(oct, addr, (uint8_t *) str, len);
  195         str[len] = 0;
  196 }
  197 
  198 /* See header file for descriptions of functions */
  199 
  200 /*
  201  * Check the version information on the bootmem descriptor
  202  *
  203  * @param oct    Pointer to current octeon device
  204  * @param exact_match
  205  *              Exact major version to check against. A zero means
  206  *              check that the version supports named blocks.
  207  *
  208  * @return Zero if the version is correct. Negative if the version is
  209  *         incorrect. Failures also cause a message to be displayed.
  210  */
  211 static int
  212 __cvmx_bootmem_check_version(struct octeon_device *oct, uint32_t exact_match)
  213 {
  214         uint32_t        major_version;
  215         uint32_t        minor_version;
  216 
  217         if (!oct->bootmem_desc_addr)
  218                 oct->bootmem_desc_addr =
  219                         lio_read_device_mem64(oct,
  220                                         LIO_BOOTLOADER_PCI_READ_DESC_ADDR);
  221 
  222         major_version = (uint32_t) __cvmx_bootmem_desc_get(oct,
  223                         oct->bootmem_desc_addr,
  224                         offsetof(struct cvmx_bootmem_desc, major_version),
  225                         SIZEOF_FIELD(struct cvmx_bootmem_desc, major_version));
  226         minor_version = (uint32_t) __cvmx_bootmem_desc_get(oct,
  227                         oct->bootmem_desc_addr,
  228                         offsetof(struct cvmx_bootmem_desc, minor_version),
  229                         SIZEOF_FIELD(struct cvmx_bootmem_desc, minor_version));
  230 
  231         lio_dev_dbg(oct, "%s: major_version=%d\n", __func__, major_version);
  232         if ((major_version > 3) ||
  233             (exact_match && major_version != exact_match)) {
  234                 lio_dev_err(oct, "bootmem ver mismatch %d.%d addr:0x%llx\n",
  235                             major_version, minor_version,
  236                             CAST_ULL(oct->bootmem_desc_addr));
  237                 return (-1);
  238         } else {
  239                 return (0);
  240         }
  241 }
  242 
  243 static const struct cvmx_bootmem_named_block_desc *
  244 __cvmx_bootmem_find_named_block_flags(struct octeon_device *oct,
  245                                       const char *name, uint32_t flags)
  246 {
  247         struct cvmx_bootmem_named_block_desc    *desc =
  248                 &oct->bootmem_named_block_desc;
  249         uint64_t        named_addr;
  250 
  251         named_addr = cvmx_bootmem_phy_named_block_find(oct, name,
  252                                                        flags);
  253         if (named_addr) {
  254                 desc->base_addr = __cvmx_bootmem_desc_get(oct, named_addr,
  255                         offsetof(struct cvmx_bootmem_named_block_desc,
  256                                  base_addr),
  257                         SIZEOF_FIELD(struct cvmx_bootmem_named_block_desc,
  258                                      base_addr));
  259 
  260                 desc->size = __cvmx_bootmem_desc_get(oct, named_addr,
  261                          offsetof(struct cvmx_bootmem_named_block_desc, size),
  262                          SIZEOF_FIELD(struct cvmx_bootmem_named_block_desc,
  263                                       size));
  264 
  265                 strncpy(desc->name, name, sizeof(desc->name));
  266                 desc->name[sizeof(desc->name) - 1] = 0;
  267 
  268                 return (&oct->bootmem_named_block_desc);
  269         } else {
  270                 return (NULL);
  271         }
  272 }
  273 
  274 static uint64_t
  275 cvmx_bootmem_phy_named_block_find(struct octeon_device *oct, const char *name,
  276                                   uint32_t flags)
  277 {
  278         uint64_t        result = 0;
  279 
  280         if (!__cvmx_bootmem_check_version(oct, 3)) {
  281                 uint32_t i;
  282 
  283                 uint64_t named_block_array_addr =
  284                         __cvmx_bootmem_desc_get(oct, oct->bootmem_desc_addr,
  285                                         offsetof(struct cvmx_bootmem_desc,
  286                                                  named_block_array_addr),
  287                                         SIZEOF_FIELD(struct cvmx_bootmem_desc,
  288                                                      named_block_array_addr));
  289                 uint32_t num_blocks =
  290                         (uint32_t) __cvmx_bootmem_desc_get(oct,
  291                                         oct->bootmem_desc_addr,
  292                                         offsetof(struct cvmx_bootmem_desc,
  293                                                  nb_num_blocks),
  294                                         SIZEOF_FIELD(struct cvmx_bootmem_desc,
  295                                                      nb_num_blocks));
  296 
  297                 uint32_t name_length =
  298                         (uint32_t) __cvmx_bootmem_desc_get(oct,
  299                                         oct->bootmem_desc_addr,
  300                                         offsetof(struct cvmx_bootmem_desc,
  301                                                  named_block_name_len),
  302                                         SIZEOF_FIELD(struct cvmx_bootmem_desc,
  303                                                      named_block_name_len));
  304 
  305                 uint64_t named_addr = named_block_array_addr;
  306 
  307                 for (i = 0; i < num_blocks; i++) {
  308                         uint64_t named_size =
  309                           __cvmx_bootmem_desc_get(oct, named_addr,
  310                             offsetof(struct cvmx_bootmem_named_block_desc,
  311                                      size),
  312                             SIZEOF_FIELD(struct cvmx_bootmem_named_block_desc,
  313                                          size));
  314 
  315                         if (name && named_size) {
  316                                 char    *name_tmp = malloc(name_length + 1,
  317                                                            M_DEVBUF, M_NOWAIT |
  318                                                            M_ZERO);
  319                                 if (!name_tmp)
  320                                         break;
  321 
  322                                 lio_bootmem_named_get_name(oct, named_addr,
  323                                                            name_tmp,
  324                                                            name_length);
  325 
  326                                 if (!strncmp(name, name_tmp, name_length)) {
  327                                         result = named_addr;
  328                                         free(name_tmp, M_DEVBUF);
  329                                         break;
  330                                 }
  331 
  332                                 free(name_tmp, M_DEVBUF);
  333 
  334                         } else if (!name && !named_size) {
  335                                 result = named_addr;
  336                                 break;
  337                         }
  338 
  339                         named_addr +=
  340                                 sizeof(struct cvmx_bootmem_named_block_desc);
  341                 }
  342         }
  343         return (result);
  344 }
  345 
  346 /*
  347  * Find a named block on the remote Octeon
  348  *
  349  * @param oct       Pointer to current octeon device
  350  * @param name      Name of block to find
  351  * @param base_addr Address the block is at (OUTPUT)
  352  * @param size      The size of the block (OUTPUT)
  353  *
  354  * @return Zero on success, One on failure.
  355  */
  356 static int
  357 lio_named_block_find(struct octeon_device *oct, const char *name,
  358                      uint64_t * base_addr, uint64_t * size)
  359 {
  360         const struct cvmx_bootmem_named_block_desc      *named_block;
  361 
  362         lio_remote_lock();
  363         named_block = __cvmx_bootmem_find_named_block_flags(oct, name, 0);
  364         lio_remote_unlock();
  365         if (named_block != NULL) {
  366                 *base_addr = named_block->base_addr;
  367                 *size = named_block->size;
  368                 return (0);
  369         }
  370 
  371         return (1);
  372 }
  373 
  374 
  375 static void
  376 lio_remote_lock(void)
  377 {
  378 
  379         /* fill this in if any sharing is needed */
  380 }
  381 
  382 static void
  383 lio_remote_unlock(void)
  384 {
  385 
  386         /* fill this in if any sharing is needed */
  387 }
  388 
  389 int
  390 lio_console_send_cmd(struct octeon_device *oct, char *cmd_str,
  391                      uint32_t wait_hundredths)
  392 {
  393         uint32_t        len = (uint32_t) strlen(cmd_str);
  394 
  395         lio_dev_dbg(oct, "sending \"%s\" to bootloader\n", cmd_str);
  396 
  397         if (len > LIO_BOOTLOADER_PCI_WRITE_BUFFER_STR_LEN - 1) {
  398                 lio_dev_err(oct, "Command string too long, max length is: %d\n",
  399                             LIO_BOOTLOADER_PCI_WRITE_BUFFER_STR_LEN - 1);
  400                 return (-1);
  401         }
  402 
  403         if (lio_wait_for_bootloader(oct, wait_hundredths)) {
  404                 lio_dev_err(oct, "Bootloader not ready for command.\n");
  405                 return (-1);
  406         }
  407 
  408         /* Write command to bootloader */
  409         lio_remote_lock();
  410         lio_pci_write_core_mem(oct, LIO_BOOTLOADER_PCI_READ_BUFFER_DATA_ADDR,
  411                                (uint8_t *) cmd_str, len);
  412         lio_write_device_mem32(oct, LIO_BOOTLOADER_PCI_READ_BUFFER_LEN_ADDR,
  413                                len);
  414         lio_write_device_mem32(oct, LIO_BOOTLOADER_PCI_READ_BUFFER_OWNER_ADDR,
  415                                LIO_PCI_IO_BUF_OWNER_OCTEON);
  416 
  417         /*
  418          * Bootloader should accept command very quickly if it really was
  419          * ready
  420          */
  421         if (lio_wait_for_bootloader(oct, 200)) {
  422                 lio_remote_unlock();
  423                 lio_dev_err(oct, "Bootloader did not accept command.\n");
  424                 return (-1);
  425         }
  426 
  427         lio_remote_unlock();
  428         return (0);
  429 }
  430 
  431 int
  432 lio_wait_for_bootloader(struct octeon_device *oct,
  433                         uint32_t wait_time_hundredths)
  434 {
  435         lio_dev_dbg(oct, "waiting %d0 ms for bootloader\n",
  436                     wait_time_hundredths);
  437 
  438         if (lio_mem_access_ok(oct))
  439                 return (-1);
  440 
  441         while (wait_time_hundredths > 0 &&
  442                lio_read_device_mem32(oct,
  443                                 LIO_BOOTLOADER_PCI_READ_BUFFER_OWNER_ADDR) !=
  444                LIO_PCI_IO_BUF_OWNER_HOST) {
  445                 if (--wait_time_hundredths <= 0)
  446                         return (-1);
  447 
  448                 lio_sleep_timeout(10);
  449         }
  450 
  451         return (0);
  452 }
  453 
  454 static void
  455 lio_console_handle_result(struct octeon_device *oct, size_t console_num)
  456 {
  457         struct lio_console      *console;
  458 
  459         console = &oct->console[console_num];
  460 
  461         console->waiting = 0;
  462 }
  463 
  464 static char     console_buffer[LIO_MAX_CONSOLE_READ_BYTES];
  465 
  466 static void
  467 lio_output_console_line(struct octeon_device *oct, struct lio_console *console,
  468                         size_t console_num, char *console_buffer,
  469                         int32_t bytes_read)
  470 {
  471         size_t          len;
  472         int32_t         i;
  473         char           *line;
  474 
  475         line = console_buffer;
  476         for (i = 0; i < bytes_read; i++) {
  477                 /* Output a line at a time, prefixed */
  478                 if (console_buffer[i] == '\n') {
  479                         console_buffer[i] = '\0';
  480                         /* We need to output 'line', prefaced by 'leftover'.
  481                          * However, it is possible we're being called to
  482                          * output 'leftover' by itself (in the case of nothing
  483                          * having been read from the console).
  484                          *
  485                          * To avoid duplication, check for this condition.
  486                          */
  487                         if (console->leftover[0] &&
  488                             (line != console->leftover)) {
  489                                 if (console->print)
  490                                         (*console->print)(oct,
  491                                                           (uint32_t)console_num,
  492                                                         console->leftover,line);
  493                                 console->leftover[0] = '\0';
  494                         } else {
  495                                 if (console->print)
  496                                         (*console->print)(oct,
  497                                                           (uint32_t)console_num,
  498                                                           line, NULL);
  499                         }
  500 
  501                         line = &console_buffer[i + 1];
  502                 }
  503         }
  504 
  505         /* Save off any leftovers */
  506         if (line != &console_buffer[bytes_read]) {
  507                 console_buffer[bytes_read] = '\0';
  508                 len = strlen(console->leftover);
  509                 strncpy(&console->leftover[len], line,
  510                         sizeof(console->leftover) - len);
  511         }
  512 }
  513 
  514 static void
  515 lio_check_console(void *arg)
  516 {
  517         struct lio_console *console;
  518         struct lio_callout *console_callout = arg;
  519         struct octeon_device *oct =
  520                 (struct octeon_device *)console_callout->ctxptr;
  521         size_t          len;
  522         uint32_t        console_num = (uint32_t) console_callout->ctxul;
  523         int32_t         bytes_read, total_read, tries;
  524 
  525         console = &oct->console[console_num];
  526         tries = 0;
  527         total_read = 0;
  528 
  529         if (callout_pending(&console_callout->timer) ||
  530             (callout_active(&console_callout->timer) == 0))
  531                 return;
  532 
  533         do {
  534                 /*
  535                  * Take console output regardless of whether it will be
  536                  * logged
  537                  */
  538                 bytes_read = lio_console_read(oct, console_num, console_buffer,
  539                                               sizeof(console_buffer) - 1);
  540                 if (bytes_read > 0) {
  541                         total_read += bytes_read;
  542                         if (console->waiting)
  543                                 lio_console_handle_result(oct, console_num);
  544 
  545                         if (console->print) {
  546                                 lio_output_console_line(oct, console,
  547                                                         console_num,
  548                                                         console_buffer,
  549                                                         bytes_read);
  550                         }
  551 
  552                 } else if (bytes_read < 0) {
  553                         lio_dev_err(oct, "Error reading console %u, ret=%d\n",
  554                                     console_num, bytes_read);
  555                 }
  556 
  557                 tries++;
  558         } while ((bytes_read > 0) && (tries < 16));
  559 
  560         /*
  561          * If nothing is read after polling the console, output any leftovers
  562          * if any
  563          */
  564         if (console->print && (total_read == 0) && (console->leftover[0])) {
  565                 /* append '\n' as terminator for 'output_console_line' */
  566                 len = strlen(console->leftover);
  567                 console->leftover[len] = '\n';
  568                 lio_output_console_line(oct, console, console_num,
  569                                         console->leftover, (int32_t)(len + 1));
  570                 console->leftover[0] = '\0';
  571         }
  572         callout_schedule(&oct->console_timer[console_num].timer,
  573                          lio_ms_to_ticks(LIO_CONSOLE_POLL_INTERVAL_MS));
  574 }
  575 
  576 
  577 int
  578 lio_init_consoles(struct octeon_device *oct)
  579 {
  580         uint64_t        addr, size;
  581         int             ret = 0;
  582 
  583         ret = lio_mem_access_ok(oct);
  584         if (ret) {
  585                 lio_dev_err(oct, "Memory access not okay'\n");
  586                 return (ret);
  587         }
  588         ret = lio_named_block_find(oct, LIO_PCI_CONSOLE_BLOCK_NAME, &addr,
  589                                    &size);
  590         if (ret) {
  591                 lio_dev_err(oct, "Could not find console '%s'\n",
  592                             LIO_PCI_CONSOLE_BLOCK_NAME);
  593                 return (ret);
  594         }
  595 
  596         /*
  597          * Use BAR1_INDEX15 to create a static mapping to a region of
  598          * Octeon's DRAM that contains the PCI console named block.
  599          */
  600         oct->console_nb_info.bar1_index = 15;
  601         oct->fn_list.bar1_idx_setup(oct, addr, oct->console_nb_info.bar1_index,
  602                                     1);
  603         oct->console_nb_info.dram_region_base = addr & 0xFFFFFFFFFFC00000ULL;
  604 
  605         /*
  606          * num_consoles > 0, is an indication that the consoles are
  607          * accessible
  608          */
  609         oct->num_consoles = lio_read_device_mem32(oct,
  610                                 addr + offsetof(struct lio_pci_console_desc,
  611                                                 num_consoles));
  612         oct->console_desc_addr = addr;
  613 
  614         lio_dev_dbg(oct, "Initialized consoles. %d available\n",
  615                     oct->num_consoles);
  616 
  617         return (ret);
  618 }
  619 
  620 int
  621 lio_add_console(struct octeon_device *oct, uint32_t console_num, char *dbg_enb)
  622 {
  623         struct callout *timer;
  624         struct lio_console *console;
  625         uint64_t        coreaddr;
  626         int             ret = 0;
  627 
  628         if (console_num >= oct->num_consoles) {
  629                 lio_dev_err(oct, "trying to read from console number %d when only 0 to %d exist\n",
  630                             console_num, oct->num_consoles);
  631         } else {
  632                 console = &oct->console[console_num];
  633 
  634                 console->waiting = 0;
  635 
  636                 coreaddr = oct->console_desc_addr + console_num * 8 +
  637                         offsetof(struct lio_pci_console_desc,
  638                                  console_addr_array);
  639                 console->addr = lio_read_device_mem64(oct, coreaddr);
  640                 coreaddr = console->addr + offsetof(struct lio_pci_console,
  641                                                     buf_size);
  642                 console->buffer_size = lio_read_device_mem32(oct, coreaddr);
  643                 coreaddr = console->addr + offsetof(struct lio_pci_console,
  644                                                     input_base_addr);
  645                 console->input_base_addr = lio_read_device_mem64(oct, coreaddr);
  646                 coreaddr = console->addr + offsetof(struct lio_pci_console,
  647                                                     output_base_addr);
  648                 console->output_base_addr =
  649                         lio_read_device_mem64(oct, coreaddr);
  650                 console->leftover[0] = '\0';
  651 
  652                 timer = &oct->console_timer[console_num].timer;
  653 
  654                 if (oct->uboot_len == 0)
  655                         lio_get_uboot_version(oct);
  656 
  657                 callout_init(timer, 0);
  658                 oct->console_timer[console_num].ctxptr = (void *)oct;
  659                 oct->console_timer[console_num].ctxul = console_num;
  660                 callout_reset(timer,
  661                               lio_ms_to_ticks(LIO_CONSOLE_POLL_INTERVAL_MS),
  662                               lio_check_console, timer);
  663                 /* an empty string means use default debug console enablement */
  664                 if (dbg_enb && !dbg_enb[0])
  665                         dbg_enb = "setenv pci_console_active 1";
  666 
  667                 if (dbg_enb)
  668                         ret = lio_console_send_cmd(oct, dbg_enb, 2000);
  669 
  670                 console->active = 1;
  671         }
  672 
  673         return (ret);
  674 }
  675 
  676 /*
  677  * Removes all consoles
  678  *
  679  * @param oct         octeon device
  680  */
  681 void
  682 lio_remove_consoles(struct octeon_device *oct)
  683 {
  684         struct lio_console      *console;
  685         uint32_t                i;
  686 
  687         for (i = 0; i < oct->num_consoles; i++) {
  688                 console = &oct->console[i];
  689 
  690                 if (!console->active)
  691                         continue;
  692 
  693                 callout_stop(&oct->console_timer[i].timer);
  694                 console->addr = 0;
  695                 console->buffer_size = 0;
  696                 console->input_base_addr = 0;
  697                 console->output_base_addr = 0;
  698         }
  699 
  700         oct->num_consoles = 0;
  701 }
  702 
  703 static inline int
  704 lio_console_free_bytes(uint32_t buffer_size, uint32_t wr_idx, uint32_t rd_idx)
  705 {
  706 
  707         if (rd_idx >= buffer_size || wr_idx >= buffer_size)
  708                 return (-1);
  709 
  710         return (((buffer_size - 1) - (wr_idx - rd_idx)) % buffer_size);
  711 }
  712 
  713 static inline int
  714 lio_console_avail_bytes(uint32_t buffer_size, uint32_t wr_idx, uint32_t rd_idx)
  715 {
  716 
  717         if (rd_idx >= buffer_size || wr_idx >= buffer_size)
  718                 return (-1);
  719 
  720         return (buffer_size - 1 -
  721                 lio_console_free_bytes(buffer_size, wr_idx, rd_idx));
  722 }
  723 
  724 static int
  725 lio_console_read(struct octeon_device *oct, uint32_t console_num, char *buffer,
  726                  uint32_t buf_size)
  727 {
  728         struct lio_console      *console;
  729         int                     bytes_to_read;
  730         uint32_t                rd_idx, wr_idx;
  731 
  732         if (console_num >= oct->num_consoles) {
  733                 lio_dev_err(oct, "Attempted to read from disabled console %d\n",
  734                             console_num);
  735                 return (0);
  736         }
  737 
  738         console = &oct->console[console_num];
  739 
  740         /*
  741          * Check to see if any data is available. Maybe optimize this with
  742          * 64-bit read.
  743          */
  744         rd_idx = lio_read_device_mem32(oct, console->addr +
  745                        offsetof(struct lio_pci_console, output_read_index));
  746         wr_idx = lio_read_device_mem32(oct, console->addr +
  747                       offsetof(struct lio_pci_console, output_write_index));
  748 
  749         bytes_to_read = lio_console_avail_bytes(console->buffer_size,
  750                                                 wr_idx, rd_idx);
  751         if (bytes_to_read <= 0)
  752                 return (bytes_to_read);
  753 
  754         bytes_to_read = min(bytes_to_read, buf_size);
  755 
  756         /*
  757          * Check to see if what we want to read is not contiguous, and limit
  758          * ourselves to the contiguous block
  759          */
  760         if (rd_idx + bytes_to_read >= console->buffer_size)
  761                 bytes_to_read = console->buffer_size - rd_idx;
  762 
  763         lio_pci_read_core_mem(oct, console->output_base_addr + rd_idx,
  764                               (uint8_t *) buffer, bytes_to_read);
  765         lio_write_device_mem32(oct, console->addr +
  766                                offsetof(struct lio_pci_console,
  767                                         output_read_index),
  768                                (rd_idx + bytes_to_read) % console->buffer_size);
  769 
  770         return (bytes_to_read);
  771 }
  772 
  773 static void
  774 lio_get_uboot_version(struct octeon_device *oct)
  775 {
  776         struct lio_console *console;
  777         int32_t         bytes_read, total_read, tries;
  778         uint32_t        console_num = 0;
  779         int             i, ret __unused = 0;
  780 
  781         ret = lio_console_send_cmd(oct, "setenv stdout pci", 50);
  782 
  783         console = &oct->console[console_num];
  784         tries = 0;
  785         total_read = 0;
  786 
  787         ret = lio_console_send_cmd(oct, "version", 1);
  788 
  789         do {
  790                 /*
  791                  * Take console output regardless of whether it will be
  792                  * logged
  793                  */
  794                 bytes_read = lio_console_read(oct,
  795                                               console_num, oct->uboot_version +
  796                                               total_read,
  797                                               OCTEON_UBOOT_BUFFER_SIZE - 1 -
  798                                               total_read);
  799                 if (bytes_read > 0) {
  800                         oct->uboot_version[bytes_read] = 0x0;
  801 
  802                         total_read += bytes_read;
  803                         if (console->waiting)
  804                                 lio_console_handle_result(oct, console_num);
  805 
  806                 } else if (bytes_read < 0) {
  807                         lio_dev_err(oct, "Error reading console %u, ret=%d\n",
  808                                     console_num, bytes_read);
  809                 }
  810 
  811                 tries++;
  812         } while ((bytes_read > 0) && (tries < 16));
  813 
  814         /*
  815          * If nothing is read after polling the console, output any leftovers
  816          * if any
  817          */
  818         if ((total_read == 0) && (console->leftover[0])) {
  819                 lio_dev_dbg(oct, "%u: %s\n", console_num, console->leftover);
  820                 console->leftover[0] = '\0';
  821         }
  822 
  823         ret = lio_console_send_cmd(oct, "setenv stdout serial", 50);
  824 
  825         /* U-Boot */
  826         for (i = 0; i < (OCTEON_UBOOT_BUFFER_SIZE - 9); i++) {
  827                 if (oct->uboot_version[i] == 'U' &&
  828                     oct->uboot_version[i + 2] == 'B' &&
  829                     oct->uboot_version[i + 3] == 'o' &&
  830                     oct->uboot_version[i + 4] == 'o' &&
  831                     oct->uboot_version[i + 5] == 't') {
  832                         oct->uboot_sidx = i;
  833                         i++;
  834                         for (; oct->uboot_version[i] != 0x0; i++) {
  835                                 if (oct->uboot_version[i] == 'm' &&
  836                                     oct->uboot_version[i + 1] == 'i' &&
  837                                     oct->uboot_version[i + 2] == 'p' &&
  838                                     oct->uboot_version[i + 3] == 's') {
  839                                         oct->uboot_eidx = i - 1;
  840                                         oct->uboot_version[i - 1] = 0x0;
  841                                         oct->uboot_len = oct->uboot_eidx -
  842                                                 oct->uboot_sidx + 1;
  843                                         lio_dev_info(oct, "%s\n",
  844                                                      &oct->uboot_version
  845                                                      [oct->uboot_sidx]);
  846                                         return;
  847                                 }
  848                         }
  849                 }
  850         }
  851 }
  852 
  853 
  854 #define FBUF_SIZE       (4 * 1024 * 1024)
  855 
  856 int
  857 lio_download_firmware(struct octeon_device *oct, const uint8_t * data,
  858                       size_t size)
  859 {
  860         struct lio_firmware_file_header *h;
  861         uint64_t        load_addr;
  862         uint32_t        crc32_result, i, image_len, rem;
  863 
  864         if (size < sizeof(struct lio_firmware_file_header)) {
  865                 lio_dev_err(oct, "Firmware file too small (%d < %d).\n",
  866                             (uint32_t) size,
  867                             (uint32_t) sizeof(struct lio_firmware_file_header));
  868                 return (-EINVAL);
  869         }
  870 
  871         h = __DECONST(struct lio_firmware_file_header *, data);
  872 
  873         if (be32toh(h->magic) != LIO_NIC_MAGIC) {
  874                 lio_dev_err(oct, "Unrecognized firmware file.\n");
  875                 return (-EINVAL);
  876         }
  877 
  878         crc32_result = crc32(data, sizeof(struct lio_firmware_file_header) -
  879                              sizeof(uint32_t));
  880         if (crc32_result != be32toh(h->crc32)) {
  881                 lio_dev_err(oct, "Firmware CRC mismatch (0x%08x != 0x%08x).\n",
  882                             crc32_result, be32toh(h->crc32));
  883                 return (-EINVAL);
  884         }
  885 
  886         if (memcmp(LIO_BASE_VERSION, h->version,
  887                    strlen(LIO_BASE_VERSION))) {
  888                 lio_dev_err(oct, "Unmatched firmware version. Expected %s.x, got %s.\n",
  889                             LIO_BASE_VERSION, h->version);
  890                 return (-EINVAL);
  891         }
  892 
  893         if (be32toh(h->num_images) > LIO_MAX_IMAGES) {
  894                 lio_dev_err(oct, "Too many images in firmware file (%d).\n",
  895                             be32toh(h->num_images));
  896                 return (-EINVAL);
  897         }
  898 
  899         lio_dev_info(oct, "Firmware version: %s\n", h->version);
  900         snprintf(oct->fw_info.lio_firmware_version, 32, "LIQUIDIO: %s",
  901                  h->version);
  902 
  903         data += sizeof(struct lio_firmware_file_header);
  904 
  905         lio_dev_info(oct, "Loading %d image(s)\n", be32toh(h->num_images));
  906 
  907         /* load all images */
  908         for (i = 0; i < be32toh(h->num_images); i++) {
  909                 load_addr = be64toh(h->desc[i].addr);
  910                 image_len = be32toh(h->desc[i].len);
  911 
  912                 lio_dev_info(oct, "Loading firmware %d at %llx\n", image_len,
  913                              (unsigned long long)load_addr);
  914 
  915                 /* Write in 4MB chunks */
  916                 rem = image_len;
  917 
  918                 while (rem) {
  919                         if (rem < FBUF_SIZE)
  920                                 size = rem;
  921                         else
  922                                 size = FBUF_SIZE;
  923 
  924                         /* download the image */
  925                         lio_pci_write_core_mem(oct, load_addr,
  926                                                __DECONST(uint8_t *, data),
  927                                                (uint32_t) size);
  928 
  929                         data += size;
  930                         rem -= (uint32_t) size;
  931                         load_addr += size;
  932                 }
  933         }
  934 
  935         lio_dev_info(oct, "Writing boot command: %s\n", h->bootcmd);
  936 
  937         /* Invoke the bootcmd */
  938         lio_console_send_cmd(oct, h->bootcmd, 50);
  939         return (0);
  940 }

Cache object: 45c1978792308e3c1d96b7d73471b6d4


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