1630a1854SFrançois Tigeot /*-
2630a1854SFrançois Tigeot * Copyright (c) 2010 Isilon Systems, Inc.
3630a1854SFrançois Tigeot * Copyright (c) 2010 iX Systems, Inc.
4630a1854SFrançois Tigeot * Copyright (c) 2010 Panasas, Inc.
5c08e5966SFrançois Tigeot * Copyright (c) 2013-2016 Mellanox Technologies, Ltd.
69547fcc6SFrançois Tigeot * Copyright (c) 2015-2020 François Tigeot <ftigeot@wolfpond.org>
7630a1854SFrançois Tigeot * All rights reserved.
8630a1854SFrançois Tigeot *
9630a1854SFrançois Tigeot * Redistribution and use in source and binary forms, with or without
10630a1854SFrançois Tigeot * modification, are permitted provided that the following conditions
11630a1854SFrançois Tigeot * are met:
12630a1854SFrançois Tigeot * 1. Redistributions of source code must retain the above copyright
13630a1854SFrançois Tigeot * notice unmodified, this list of conditions, and the following
14630a1854SFrançois Tigeot * disclaimer.
15630a1854SFrançois Tigeot * 2. Redistributions in binary form must reproduce the above copyright
16630a1854SFrançois Tigeot * notice, this list of conditions and the following disclaimer in the
17630a1854SFrançois Tigeot * documentation and/or other materials provided with the distribution.
18630a1854SFrançois Tigeot *
19630a1854SFrançois Tigeot * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20630a1854SFrançois Tigeot * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21630a1854SFrançois Tigeot * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22630a1854SFrançois Tigeot * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23630a1854SFrançois Tigeot * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24630a1854SFrançois Tigeot * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25630a1854SFrançois Tigeot * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26630a1854SFrançois Tigeot * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27630a1854SFrançois Tigeot * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28630a1854SFrançois Tigeot * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29630a1854SFrançois Tigeot */
30630a1854SFrançois Tigeot
31630a1854SFrançois Tigeot #ifndef _LINUX_COMPILER_H_
32630a1854SFrançois Tigeot #define _LINUX_COMPILER_H_
33630a1854SFrançois Tigeot
34630a1854SFrançois Tigeot #include <sys/cdefs.h>
35630a1854SFrançois Tigeot
36630a1854SFrançois Tigeot #define __user
37630a1854SFrançois Tigeot #define __kernel
38630a1854SFrançois Tigeot #define __safe
39630a1854SFrançois Tigeot #define __force
40630a1854SFrançois Tigeot #define __nocast
41630a1854SFrançois Tigeot #define __iomem
42630a1854SFrançois Tigeot #define __chk_user_ptr(x) 0
43630a1854SFrançois Tigeot #define __chk_io_ptr(x) 0
44630a1854SFrançois Tigeot #define __builtin_warning(x, y...) (1)
45630a1854SFrançois Tigeot #define __acquires(x)
46630a1854SFrançois Tigeot #define __releases(x)
47630a1854SFrançois Tigeot #define __acquire(x) 0
48630a1854SFrançois Tigeot #define __release(x) 0
49630a1854SFrançois Tigeot #define __cond_lock(x,c) (c)
50630a1854SFrançois Tigeot #define __bitwise
51630a1854SFrançois Tigeot #define __devinitdata
52630a1854SFrançois Tigeot #define __init
53630a1854SFrançois Tigeot #define __devinit
54630a1854SFrançois Tigeot #define __devexit
55630a1854SFrançois Tigeot #define __exit
56630a1854SFrançois Tigeot #define __stringify(x) #x
57630a1854SFrançois Tigeot #define __attribute_const__ __attribute__((__const__))
58630a1854SFrançois Tigeot #undef __always_inline
59630a1854SFrançois Tigeot #define __always_inline inline
609547fcc6SFrançois Tigeot #define noinline __attribute__((noinline))
61630a1854SFrançois Tigeot
62630a1854SFrançois Tigeot #define likely(x) __builtin_expect(!!(x), 1)
63630a1854SFrançois Tigeot #define unlikely(x) __builtin_expect(!!(x), 0)
64630a1854SFrançois Tigeot #define typeof(x) __typeof(x)
65630a1854SFrançois Tigeot
661487f786SFrançois Tigeot #define __maybe_unused __unused
678e26cdf6SFrançois Tigeot #define __always_unused __unused
681dedbd3bSFrançois Tigeot #define __malloc
69a3faafcbSSascha Wildner #define __must_check __heedresult
70ce3d36d7SFrançois Tigeot
7147ad44e8SFrançois Tigeot #define __printf(a,b) __printflike(a,b)
7247ad44e8SFrançois Tigeot
733f8dbd6bSFrançois Tigeot
743f8dbd6bSFrançois Tigeot #define barrier() cpu_ccfence()
753f8dbd6bSFrançois Tigeot
767ddbbbe5SFrançois Tigeot #ifdef _KERNEL /* This file is included by kdump(1) */
777ddbbbe5SFrançois Tigeot
787ddbbbe5SFrançois Tigeot #include <sys/param.h>
797ddbbbe5SFrançois Tigeot
807ddbbbe5SFrançois Tigeot /*
817ddbbbe5SFrançois Tigeot * The READ_ONCE() and WRITE_ONCE() macros force volatile accesses to
827ddbbbe5SFrançois Tigeot * various data types.
837ddbbbe5SFrançois Tigeot * Their complexity is caused by the necessity to work-around
847ddbbbe5SFrançois Tigeot * compiler cleverness and bugs.
857ddbbbe5SFrançois Tigeot * Some GCC versions drop the volatile modifier if the variable used
867ddbbbe5SFrançois Tigeot * is not of a scalar type.
877ddbbbe5SFrançois Tigeot */
887ddbbbe5SFrançois Tigeot static inline void
__volatile_read(const volatile void * x,int size,void * result)897ddbbbe5SFrançois Tigeot __volatile_read(const volatile void *x, int size, void *result)
907ddbbbe5SFrançois Tigeot {
917ddbbbe5SFrançois Tigeot switch(size) {
927ddbbbe5SFrançois Tigeot case 8:
937ddbbbe5SFrançois Tigeot *(uint64_t *)result = *(const volatile uint64_t *)x;
947ddbbbe5SFrançois Tigeot break;
957ddbbbe5SFrançois Tigeot case 4:
967ddbbbe5SFrançois Tigeot *(uint32_t *)result = *(const volatile uint32_t *)x;
977ddbbbe5SFrançois Tigeot break;
987ddbbbe5SFrançois Tigeot case 2:
997ddbbbe5SFrançois Tigeot *(uint16_t *)result = *(const volatile uint16_t *)x;
1007ddbbbe5SFrançois Tigeot break;
1017ddbbbe5SFrançois Tigeot case 1:
1027ddbbbe5SFrançois Tigeot *(uint8_t *)result = *(const volatile uint8_t *)x;
1037ddbbbe5SFrançois Tigeot break;
1047ddbbbe5SFrançois Tigeot default:
1057ddbbbe5SFrançois Tigeot panic("__volatile_read called with size %d\n", size);
1067ddbbbe5SFrançois Tigeot }
1077ddbbbe5SFrançois Tigeot }
1087ddbbbe5SFrançois Tigeot
1097ddbbbe5SFrançois Tigeot static inline void
__volatile_write(volatile void * var,int size,void * value)1107ddbbbe5SFrançois Tigeot __volatile_write(volatile void *var, int size, void *value)
1117ddbbbe5SFrançois Tigeot {
1127ddbbbe5SFrançois Tigeot switch(size) {
1137ddbbbe5SFrançois Tigeot case 8:
1147ddbbbe5SFrançois Tigeot *(volatile uint64_t *)var = *(uint64_t *)value;
1157ddbbbe5SFrançois Tigeot break;
1167ddbbbe5SFrançois Tigeot case 4:
1177ddbbbe5SFrançois Tigeot *(volatile uint32_t *)var = *(uint32_t *)value;
1187ddbbbe5SFrançois Tigeot break;
1197ddbbbe5SFrançois Tigeot case 2:
1207ddbbbe5SFrançois Tigeot *(volatile uint16_t *)var = *(uint16_t *)value;
1217ddbbbe5SFrançois Tigeot break;
1227ddbbbe5SFrançois Tigeot case 1:
1237ddbbbe5SFrançois Tigeot *(volatile uint8_t *)var = *(uint8_t *)value;
1247ddbbbe5SFrançois Tigeot break;
1257ddbbbe5SFrançois Tigeot default:
1267ddbbbe5SFrançois Tigeot panic("__volatile_write called with size %d\n", size);
1277ddbbbe5SFrançois Tigeot }
1287ddbbbe5SFrançois Tigeot
1297ddbbbe5SFrançois Tigeot }
130c08e5966SFrançois Tigeot
131c08e5966SFrançois Tigeot #define READ_ONCE(x) ({ \
1327ddbbbe5SFrançois Tigeot union { \
1337ddbbbe5SFrançois Tigeot __typeof(x) initial_type; \
1347ddbbbe5SFrançois Tigeot uint8_t nc_type; \
1357ddbbbe5SFrançois Tigeot } result; \
1367ddbbbe5SFrançois Tigeot \
1377ddbbbe5SFrançois Tigeot result.nc_type = 0; \
1387ddbbbe5SFrançois Tigeot __volatile_read(&(x), sizeof(x), &result.nc_type); \
1397ddbbbe5SFrançois Tigeot result.initial_type; \
140c08e5966SFrançois Tigeot })
141c08e5966SFrançois Tigeot
1427ddbbbe5SFrançois Tigeot #define WRITE_ONCE(var, value) ({ \
1437ddbbbe5SFrançois Tigeot union { \
1447ddbbbe5SFrançois Tigeot __typeof(var) initial_type; \
1457ddbbbe5SFrançois Tigeot uint8_t nc_type; \
1467ddbbbe5SFrançois Tigeot } result; \
1477ddbbbe5SFrançois Tigeot \
1487ddbbbe5SFrançois Tigeot result.initial_type = value; \
1497ddbbbe5SFrançois Tigeot __volatile_write(&(var), sizeof(var), &result.nc_type); \
1507ddbbbe5SFrançois Tigeot result.initial_type; \
1517ddbbbe5SFrançois Tigeot })
1527ddbbbe5SFrançois Tigeot
15341e2def0SFrançois Tigeot #define __rcu
15441e2def0SFrançois Tigeot
155*3dbf45c4SSascha Wildner /* Workaround to protect from the 'DEBUG' kernel config option */
156*3dbf45c4SSascha Wildner #undef DEBUG
157*3dbf45c4SSascha Wildner
1587ddbbbe5SFrançois Tigeot #endif /* __KERNEL__ */
1597ddbbbe5SFrançois Tigeot
160a85cb24fSFrançois Tigeot #define GCC_VERSION \
161a85cb24fSFrançois Tigeot (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
162a85cb24fSFrançois Tigeot
1633f2dd94aSFrançois Tigeot #ifndef unreachable
1643f2dd94aSFrançois Tigeot #define unreachable() \
1653f2dd94aSFrançois Tigeot do { \
1663f2dd94aSFrançois Tigeot __asm __volatile(""); \
1673f2dd94aSFrançois Tigeot __builtin_unreachable(); \
1683f2dd94aSFrançois Tigeot } while (0)
1693f2dd94aSFrançois Tigeot #endif
1703f2dd94aSFrançois Tigeot
171630a1854SFrançois Tigeot #endif /* _LINUX_COMPILER_H_ */
172