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/powerpc/powernv/opal_async.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) 2019 Justin Hibbits
    3  *
    4  * Redistribution and use in source and binary forms, with or without
    5  * modification, are permitted provided that the following conditions
    6  * are met:
    7  * 1. Redistributions of source code must retain the above copyright
    8  *    notice, this list of conditions and the following disclaimer.
    9  * 2. Redistributions in binary form must reproduce the above copyright
   10  *    notice, this list of conditions and the following disclaimer in the
   11  *    documentation and/or other materials provided with the distribution.
   12  *
   13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   14  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   15  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   16  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   17  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   18  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   19  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   20  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   21  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   22  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   23  *
   24  * $FreeBSD$
   25  */
   26 
   27 #include <sys/cdefs.h>
   28 #include <sys/param.h>
   29 #include <sys/eventhandler.h>
   30 #include <sys/malloc.h>
   31 #include <sys/proc.h>
   32 #include <sys/vmem.h>
   33 
   34 #include <vm/vm.h>
   35 #include <vm/pmap.h>
   36 #include "opal.h"
   37 
   38 #include <machine/cpufunc.h>
   39 
   40 /*
   41  * Manage asynchronous tokens for the OPAL abstraction layer.
   42  *
   43  * Only a finite number of in-flight tokens are supported by OPAL, so we must be
   44  * careful managing this.  The basic design uses the vmem subsystem as a general
   45  * purpose allocator, with wrappers to manage expected behaviors and
   46  * requirements.
   47  */
   48 static vmem_t *async_token_pool;
   49 
   50 static void opal_handle_async_completion(void *, struct opal_msg *);
   51 
   52 struct async_completion {
   53         volatile uint64_t       completed;
   54         struct opal_msg         msg;
   55 };
   56 
   57 struct async_completion *completions;
   58 
   59 /* Setup the token pool. */
   60 int
   61 opal_init_async_tokens(int count)
   62 {
   63         /* Only allow one initialization */
   64         if (async_token_pool != NULL)
   65                 return (EINVAL);
   66 
   67         async_token_pool = vmem_create("OPAL Async", 0, count, 1, 1,
   68             M_WAITOK | M_FIRSTFIT);
   69         completions = malloc(count * sizeof(struct async_completion),
   70             M_DEVBUF, M_WAITOK | M_ZERO);
   71 
   72         EVENTHANDLER_REGISTER(OPAL_ASYNC_COMP, opal_handle_async_completion,
   73             NULL, EVENTHANDLER_PRI_ANY);
   74 
   75         return (0);
   76 }
   77 
   78 int
   79 opal_alloc_async_token(void)
   80 {
   81         vmem_addr_t token;
   82 
   83         vmem_alloc(async_token_pool, 1, M_FIRSTFIT | M_WAITOK, &token);
   84         completions[token].completed = false;
   85 
   86         return (token);
   87 }
   88 
   89 void
   90 opal_free_async_token(int token)
   91 {
   92 
   93         vmem_free(async_token_pool, token, 1);
   94 }
   95 
   96 /*
   97  * Wait for the operation watched by the token to complete.  Return the result
   98  * of the operation, error if it returns early.
   99  */
  100 int
  101 opal_wait_completion(void *buf, uint64_t size, int token)
  102 {
  103         int err;
  104 
  105         do {
  106                 err = opal_call(OPAL_CHECK_ASYNC_COMPLETION,
  107                     vtophys(buf), size, token);
  108                 if (err == OPAL_BUSY) {
  109                         if (completions[token].completed) {
  110                                 atomic_thread_fence_acq();
  111                                 memcpy(buf, &completions[token].msg, size);
  112                                 return (OPAL_SUCCESS);
  113                         }
  114                 }
  115                 DELAY(100);
  116         } while (err == OPAL_BUSY);
  117 
  118         return (err);
  119 }
  120 
  121 static void opal_handle_async_completion(void *arg, struct opal_msg *msg)
  122 {
  123         int token;
  124 
  125         token = msg->params[0];
  126         memcpy(&completions[token].msg, msg, sizeof(*msg));
  127         atomic_thread_fence_rel();
  128         completions[token].completed = true;
  129 }

Cache object: 7abb63bd7773099533669699a5572f57


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