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/contrib/alpine-hal/al_hal_plat_services.h

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 *******************************************************************************
    3 Copyright (C) 2015 Annapurna Labs Ltd.
    4 
    5 This file may be licensed under the terms of the Annapurna Labs Commercial
    6 License Agreement.
    7 
    8 Alternatively, this file can be distributed under the terms of the GNU General
    9 Public License V2 as published by the Free Software Foundation and can be
   10 found at http://www.gnu.org/licenses/gpl-2.0.html
   11 
   12 Alternatively, redistribution and use in source and binary forms, with or
   13 without modification, are permitted provided that the following conditions are
   14 met:
   15 
   16     *     Redistributions of source code must retain the above copyright notice,
   17 this list of conditions and the following disclaimer.
   18 
   19     *     Redistributions in binary form must reproduce the above copyright
   20 notice, this list of conditions and the following disclaimer in
   21 the documentation and/or other materials provided with the
   22 distribution.
   23 
   24 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
   25 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   26 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   27 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
   28 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   29 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   30 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
   31 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   32 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   34 
   35 *******************************************************************************/
   36 
   37 /**
   38  * @defgroup group_services Platform Services API
   39  *  @{
   40  * The Platform Services API provides miscellaneous system services to HAL
   41  * drivers, such as:
   42  * - Registers read/write
   43  * - Assertions
   44  * - Memory barriers
   45  * - Endianness conversions
   46  *
   47  * And more.
   48  * @file   plat_api/sample/al_hal_plat_services.h
   49  *
   50  * @brief  API for Platform services provided for to HAL drivers
   51  *
   52  *
   53  */
   54 
   55 #ifndef __PLAT_SERVICES_H__
   56 #define __PLAT_SERVICES_H__
   57 
   58 #include <machine/atomic.h>
   59 #include <sys/cdefs.h>
   60 __FBSDID("$FreeBSD$");
   61 
   62 #include <sys/param.h>
   63 #include <sys/systm.h>
   64 #include <sys/kernel.h>
   65 #include <sys/endian.h>
   66 #include <sys/errno.h>
   67 #include <sys/lock.h>
   68 #include <sys/mutex.h>
   69 #include <machine/bus.h>
   70 
   71 /* Prototypes for all the bus_space structure functions */
   72 uint8_t generic_bs_r_1(bus_space_tag_t t, bus_space_handle_t bsh,
   73     bus_size_t offset);
   74 
   75 uint16_t generic_bs_r_2(bus_space_tag_t t, bus_space_handle_t bsh,
   76     bus_size_t offset);
   77 
   78 uint32_t generic_bs_r_4(bus_space_tag_t t, bus_space_handle_t bsh,
   79     bus_size_t offset);
   80 
   81 void generic_bs_w_1(bus_space_tag_t t, bus_space_handle_t bsh,
   82     bus_size_t offset, uint8_t value);
   83 
   84 void generic_bs_w_2(bus_space_tag_t t, bus_space_handle_t bsh,
   85     bus_size_t offset, uint16_t value);
   86 
   87 void generic_bs_w_4(bus_space_tag_t t, bus_space_handle_t bsh,
   88     bus_size_t offset, uint32_t value);
   89 
   90 void generic_bs_w_8(bus_space_tag_t t, bus_space_handle_t bsh,
   91     bus_size_t offset, uint64_t value);
   92 
   93 #define __UNUSED __attribute__((unused))
   94 
   95 /* *INDENT-OFF* */
   96 #ifdef __cplusplus
   97 extern "C" {
   98 #endif
   99 /* *INDENT-ON* */
  100 
  101 /**
  102   * Make sure data will be visible by other masters (other CPUS and DMA).
  103   * usually this is achieved by the ARM DMB instruction.
  104   */
  105 static void al_data_memory_barrier(void);
  106 static void al_smp_data_memory_barrier(void);
  107 
  108 /**
  109   * Make sure data will be visible by DMA masters, no restriction for other cpus
  110   */
  111 static inline void
  112 al_data_memory_barrier(void)
  113 {
  114 #ifndef __aarch64__
  115         dsb();
  116 #else
  117         dsb(sy);
  118 #endif
  119 }
  120 
  121 /**
  122   * Make sure data will be visible in order by other cpus masters.
  123   */
  124 static inline void
  125 al_smp_data_memory_barrier(void)
  126 {
  127 #ifndef __aarch64__
  128         dmb();
  129 #else
  130         dmb(ish);
  131 #endif
  132 }
  133 
  134 /**
  135   * Make sure write data will be visible in order by other cpus masters.
  136   */
  137 static inline void
  138 al_local_data_memory_barrier(void)
  139 {
  140 #ifndef __aarch64__
  141         dsb();
  142 #else
  143         dsb(sy);
  144 #endif
  145 }
  146 
  147 /*
  148  * WMA: This is a hack which allows not modifying the __iomem accessing HAL code.
  149  * On ARMv7, bus_handle holds the information about VA of accessed memory. It
  150  * is possible to use direct load/store instruction instead of bus_dma machinery.
  151  * WARNING: This is not guaranteed to stay that way forever, nor that
  152  * on other architectures these variables behave similarly. Keep that
  153  * in mind during porting to other systems.
  154  */
  155 /**
  156  * Read MMIO 8 bits register
  157  * @param  offset       register offset
  158  *
  159  * @return register value
  160  */
  161 static uint8_t al_reg_read8(uint8_t * offset);
  162 
  163 /**
  164  * Read MMIO 16 bits register
  165  * @param  offset       register offset
  166  *
  167  * @return register value
  168  */
  169 static uint16_t al_reg_read16(uint16_t * offset);
  170 
  171 /**
  172  * Read MMIO 32 bits register
  173  * @param  offset       register offset
  174  *
  175  * @return register value
  176  */
  177 static uint32_t al_reg_read32(uint32_t * offset);
  178 
  179 /**
  180  * Read MMIO 64 bits register
  181  * @param  offset       register offset
  182  *
  183  * @return register value
  184  */
  185 uint64_t al_reg_read64(uint64_t * offset);
  186 
  187 /**
  188  * Relaxed read MMIO 32 bits register
  189  *
  190  * Relaxed register read/write functions don't involve cpu instructions that
  191  * force syncronization, nor ordering between the register access and memory
  192  * data access.
  193  * These instructions are used in performance critical code to avoid the
  194  * overhead of the synchronization instructions.
  195  *
  196  * @param  offset       register offset
  197  *
  198  * @return register value
  199  */
  200 #define al_bus_dma_to_va(bus_tag, bus_handle)   ((void*)bus_handle)
  201 
  202 /**
  203  * Relaxed read MMIO 32 bits register
  204  *
  205  * Relaxed register read/write functions don't involve cpu instructions that
  206  * force syncronization, nor ordering between the register access and memory
  207  * data access.
  208  * These instructions are used in performance critical code to avoid the
  209  * overhead of the synchronization instructions.
  210  *
  211  * @param  offset       register offset
  212  *
  213  * @return register value
  214  */
  215 #define al_reg_read32_relaxed(l)        generic_bs_r_4(NULL, (bus_space_handle_t)l, 0)
  216 
  217 /**
  218  * Relaxed write to MMIO 32 bits register
  219  *
  220  * Relaxed register read/write functions don't involve cpu instructions that
  221  * force syncronization, nor ordering between the register access and memory
  222  * data access.
  223  * These instructions are used in performance critical code to avoid the
  224  * overhead of the synchronization instructions.
  225  *
  226  * @param  offset       register offset
  227  * @param  val          value to write to the register
  228  */
  229 #define al_reg_write32_relaxed(l,v)     generic_bs_w_4(NULL, (bus_space_handle_t)l, 0, v)
  230 
  231 /**
  232  * Write to MMIO 8 bits register
  233  * @param  offset       register offset
  234  * @param  val          value to write to the register
  235  */
  236 #define al_reg_write8(l, v) do {                                \
  237         al_data_memory_barrier();                               \
  238         generic_bs_w_1(NULL, (bus_space_handle_t)l, 0, v);      \
  239         al_smp_data_memory_barrier();                           \
  240 } while (0)
  241 
  242 /**
  243  * Write to MMIO 16 bits register
  244  * @param  offset       register offset
  245  * @param  val          value to write to the register
  246  */
  247 #define al_reg_write16(l, v) do {                               \
  248         al_data_memory_barrier();                               \
  249         generic_bs_w_2(NULL, (bus_space_handle_t)l, 0, v);      \
  250         al_smp_data_memory_barrier();                           \
  251 } while (0)
  252 
  253 /**
  254  * Write to MMIO 32 bits register
  255  * @param  offset       register offset
  256  * @param  val          value to write to the register
  257  */
  258 #define al_reg_write32(l, v) do {                               \
  259         al_data_memory_barrier();                               \
  260         generic_bs_w_4(NULL, (bus_space_handle_t)l, 0, v);      \
  261         al_smp_data_memory_barrier();                           \
  262 } while (0)
  263 
  264 /**
  265  * Write to MMIO 64 bits register
  266  * @param  offset       register offset
  267  * @param  val          value to write to the register
  268  */
  269 #define al_reg_write64(l, v) do {                               \
  270         al_data_memory_barrier();                               \
  271         generic_bs_w_8(NULL, (bus_space_handle_t)l, 0, v);      \
  272         al_smp_data_memory_barrier();                           \
  273 } while (0)
  274 
  275 static inline uint8_t
  276 al_reg_read8(uint8_t *l)
  277 {
  278 
  279         al_data_memory_barrier();
  280         return (generic_bs_r_1(NULL, (bus_space_handle_t)l, 0));
  281 }
  282 
  283 static inline uint16_t
  284 al_reg_read16(uint16_t *l)
  285 {
  286 
  287         al_data_memory_barrier();
  288         return (generic_bs_r_2(NULL, (bus_space_handle_t)l, 0));
  289 }
  290 
  291 static inline uint32_t
  292 al_reg_read32(uint32_t *l)
  293 {
  294 
  295         al_data_memory_barrier();
  296         return (generic_bs_r_4(NULL, (bus_space_handle_t)l, 0));
  297 }
  298 
  299 #define AL_DBG_LEVEL_NONE 0
  300 #define AL_DBG_LEVEL_ERR 1
  301 #define AL_DBG_LEVEL_WARN 2
  302 #define AL_DBG_LEVEL_INFO 3
  303 #define AL_DBG_LEVEL_DBG 4
  304 
  305 #define AL_DBG_LEVEL AL_DBG_LEVEL_ERR
  306 
  307 #define AL_DBG_LOCK()
  308 #define AL_DBG_UNLOCK()
  309 
  310 /**
  311  * print message
  312  *
  313  * @param format The format string
  314  * @param ... Additional arguments
  315  */
  316 #define al_print(type, fmt, ...)                do { if (AL_DBG_LEVEL >= AL_DBG_LEVEL_NONE) { AL_DBG_LOCK(); printf(fmt, ##__VA_ARGS__); AL_DBG_UNLOCK(); } } while(0)
  317 
  318 /**
  319  * print error message
  320  *
  321  * @param format
  322  */
  323 #define al_err(...)                     do { if (AL_DBG_LEVEL >= AL_DBG_LEVEL_ERR) { AL_DBG_LOCK(); printf(__VA_ARGS__); AL_DBG_UNLOCK(); } } while(0)
  324 
  325 /**
  326  * print warning message
  327  *
  328  * @param format
  329  */
  330 #define al_warn(...)                    do { if (AL_DBG_LEVEL >= AL_DBG_LEVEL_WARN) { AL_DBG_LOCK(); printf(__VA_ARGS__); AL_DBG_UNLOCK(); } } while(0)
  331 
  332 /**
  333  * print info message
  334  *
  335  * @param format
  336  */
  337 #define al_info(...)                    do { if (AL_DBG_LEVEL >= AL_DBG_LEVEL_INFO) { AL_DBG_LOCK(); printf(__VA_ARGS__); AL_DBG_UNLOCK(); } } while(0)
  338 
  339 /**
  340  * print debug message
  341  *
  342  * @param format
  343  */
  344 #define al_dbg(...)                     do { if (AL_DBG_LEVEL >= AL_DBG_LEVEL_DBG) { AL_DBG_LOCK(); printf(__VA_ARGS__); AL_DBG_UNLOCK(); } } while(0)
  345 
  346 /**
  347  * Assertion
  348  *
  349  * @param condition
  350  */
  351 #define al_assert(COND)         \
  352         do {                    \
  353                 if (!(COND))    \
  354                         al_err( \
  355                         "%s:%d:%s: Assertion failed! (%s)\n",   \
  356                         __FILE__, __LINE__, __func__, #COND);   \
  357         } while(AL_FALSE)
  358 
  359 /**
  360  * al_udelay - micro sec delay
  361  */
  362 #define al_udelay(u)            DELAY(u)
  363 
  364 /**
  365  * al_msleep - mili sec delay
  366  */
  367 #define al_msleep(m)            DELAY((m) * 1000)
  368 
  369 /**
  370  * swap half word to little endian
  371  *
  372  * @param x 16 bit value
  373  *
  374  * @return the value in little endian
  375  */
  376 #define swap16_to_le(x)         htole16(x)
  377 /**
  378  * swap word to little endian
  379  *
  380  * @param x 32 bit value
  381  *
  382  * @return the value in little endian
  383  */
  384 #define swap32_to_le(x)         htole32(x)
  385 
  386 /**
  387  * swap 8 bytes to little endian
  388  *
  389  * @param x 64 bit value
  390  *
  391  * @return the value in little endian
  392  */
  393 #define swap64_to_le(x)         htole64(x)
  394 
  395 /**
  396  * swap half word from little endian
  397  *
  398  * @param x 16 bit value
  399  *
  400  * @return the value in the cpu endianess
  401  */
  402 #define swap16_from_le(x)       le16toh(x)
  403 
  404 /**
  405  * swap word from little endian
  406  *
  407  * @param x 32 bit value
  408  *
  409  * @return the value in the cpu endianess
  410  */
  411 #define swap32_from_le(x)       le32toh(x)
  412 
  413 /**
  414  * swap 8 bytes from little endian
  415  *
  416  * @param x 64 bit value
  417  *
  418  * @return the value in the cpu endianess
  419  */
  420 #define swap64_from_le(x)       le64toh(x)
  421 
  422 /**
  423  * Memory set
  424  *
  425  * @param p memory pointer
  426  * @param val value for setting
  427  * @param cnt number of bytes to set
  428  */
  429 #define al_memset(p, val, cnt)  memset(p, val, cnt)
  430 
  431 /**
  432  * Memory copy
  433  *
  434  * @param p1 memory pointer
  435  * @param p2 memory pointer
  436  * @param cnt number of bytes to copy
  437  */
  438 #define al_memcpy(p1, p2, cnt)  memcpy(p1, p2, cnt)
  439 
  440 /**
  441  * Memory compare
  442  *
  443  * @param p1 memory pointer
  444  * @param p2 memory pointer
  445  * @param cnt number of bytes to compare
  446  */
  447 #define al_memcmp(p1, p2, cnt)  memcmp(p1, p2, cnt)
  448 
  449 /**
  450  * String compare
  451  *
  452  * @param s1 string pointer
  453  * @param s2 string pointer
  454  */
  455 #define al_strcmp(s1, s2)       strcmp(s1, s2)
  456 
  457 #define al_get_cpu_id()         0
  458 
  459 /* *INDENT-OFF* */
  460 #ifdef __cplusplus
  461 }
  462 #endif
  463 /* *INDENT-ON* */
  464 /** @} end of Platform Services API group */
  465 #endif                          /* __PLAT_SERVICES_H__ */

Cache object: 7b57327504fd3e310751f935b0d0ffcc


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