summaryrefslogtreecommitdiffstats
path: root/sys/contrib/octeon-sdk/cvmx-utils.h
blob: 32d87a180f54b7b05954089bbcc888539092c3aa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
/***********************license start***************
 *  Copyright (c) 2003-2009 Cavium Networks (support@cavium.com). All rights
 *  reserved.
 *
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are
 *  met:
 *
 *      * Redistributions of source code must retain the above copyright
 *        notice, this list of conditions and the following disclaimer.
 *
 *      * Redistributions in binary form must reproduce the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer in the documentation and/or other materials provided
 *        with the distribution.
 *
 *      * Neither the name of Cavium Networks nor the names of
 *        its contributors may be used to endorse or promote products
 *        derived from this software without specific prior written
 *        permission.
 *
 *  TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
 *  AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS
 *  OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH
 *  RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY
 *  REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT
 *  DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES
 *  OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR
 *  PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET
 *  POSSESSION OR CORRESPONDENCE TO DESCRIPTION.  THE ENTIRE RISK ARISING OUT
 *  OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
 *
 *
 *  For any questions regarding licensing please contact marketing@caviumnetworks.com
 *
 ***********************license end**************************************/

/**
 * @file
 * Small utility functions and macros to ease programming of Octeon.
 *
 * <hr>$Revision: 38306 $<hr>
*/
#ifndef __CVMX_UTILS_H__
#define __CVMX_UTILS_H__

#ifdef	__cplusplus
extern "C" {
#endif

#ifndef TRUE
#define FALSE   0
#define TRUE    (!(FALSE))
#endif

/*
 * The macros cvmx_likely and cvmx_unlikely use the
 * __builtin_expect GCC operation to control branch
 * probabilities for a conditional. For example, an "if"
 * statement in the code that will almost always be
 * executed should be written as "if (cvmx_likely(...))".
 * If the "else" section of an if statement is more
 * probable, use "if (cvmx_unlikey(...))".
 */
#define cvmx_likely(x)      __builtin_expect(!!(x), 1)
#define cvmx_unlikely(x)    __builtin_expect(!!(x), 0)

#if CVMX_ENABLE_DEBUG_PRINTS
    #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
        #define cvmx_dprintf        printk
    #else
        #define cvmx_dprintf        printf
    #endif
#else
    static inline void cvmx_dprintf(const char *format, ...) __attribute__ ((format(printf, 1, 2)));
    static inline void cvmx_dprintf(const char *format, ...)
    {
        /* Prints are disbled, do nothing */
    }
#endif

#define CAST64(v) ((long long)(long)(v))
#define CASTPTR(type, v) ((type *)(long)(v))
#define CVMX_MAX_CORES          (16)
#define CVMX_CACHE_LINE_SIZE    (128)   // In bytes
#define CVMX_CACHE_LINE_MASK    (CVMX_CACHE_LINE_SIZE - 1)   // In bytes
#define CVMX_CACHE_LINE_ALIGNED __attribute__ ((aligned (CVMX_CACHE_LINE_SIZE)))

/**
 * This macro spins on a field waiting for it to reach a value. It
 * is common in code to need to wait for a specific field in a CSR
 * to match a specific value. Conceptually this macro expands to:
 *
 * 1) read csr at "address" with a csr typedef of "type"
 * 2) Check if ("type".s."field" "op" "value")
 * 3) If #2 isn't true loop to #1 unless too much time has passed.
 */
#define CVMX_WAIT_FOR_FIELD64(address, type, field, op, value, timeout_usec)\
    ({int result;                                                       \
    do {                                                                \
        uint64_t done = cvmx_get_cycle() + (uint64_t)timeout_usec *     \
                           cvmx_sysinfo_get()->cpu_clock_hz / 1000000;  \
        type c;                                                         \
        while (1)                                                       \
        {                                                               \
            c.u64 = cvmx_read_csr(address);                             \
            if ((c.s.field) op (value)) {                               \
                result = 0;                                             \
                break;                                                  \
            } else if (cvmx_get_cycle() > done) {                       \
                result = -1;                                            \
                break;                                                  \
            } else                                                      \
                cvmx_wait(100);                                         \
        }                                                               \
    } while (0);                                                        \
    result;})

/**
 * Builds a bit mask given the required size in bits.
 *
 * @param bits   Number of bits in the mask
 * @return The mask
 */
static inline uint64_t cvmx_build_mask(uint64_t bits)
{
    return ~((~0x0ull) << bits);
}


/**
 * Builds a memory address for I/O based on the Major and Sub DID.
 *
 * @param major_did 5 bit major did
 * @param sub_did   3 bit sub did
 * @return I/O base address
 */
static inline uint64_t cvmx_build_io_address(uint64_t major_did, uint64_t sub_did)
{
    return ((0x1ull << 48) | (major_did << 43) | (sub_did << 40));
}


/**
 * Perform mask and shift to place the supplied value into
 * the supplied bit rage.
 *
 * Example: cvmx_build_bits(39,24,value)
 * <pre>
 * 6       5       4       3       3       2       1
 * 3       5       7       9       1       3       5       7      0
 * +-------+-------+-------+-------+-------+-------+-------+------+
 * 000000000000000000000000___________value000000000000000000000000
 * </pre>
 *
 * @param high_bit Highest bit value can occupy (inclusive) 0-63
 * @param low_bit  Lowest bit value can occupy inclusive 0-high_bit
 * @param value    Value to use
 * @return Value masked and shifted
 */
static inline uint64_t cvmx_build_bits(uint64_t high_bit, uint64_t low_bit, uint64_t value)
{
    return ((value & cvmx_build_mask(high_bit - low_bit + 1)) << low_bit);
}


/**
 * Return the number of cores available in the chip
 *
 * @return
 */
static inline uint32_t cvmx_octeon_num_cores(void)
{
    uint32_t ciu_fuse = (uint32_t)cvmx_read_csr(CVMX_CIU_FUSE) & 0xffff;
    return cvmx_pop(ciu_fuse);
}


/**
 * Return true if Octeon is CN38XX pass 1
 *
 * @return
 */
static inline int cvmx_octeon_is_pass1(void)
{
    return OCTEON_IS_MODEL(OCTEON_CN38XX_PASS1);
}


/**
 * Return true if Octeon is CN36XX
 *
 * @return
 */
static inline int cvmx_octeon_model_CN36XX(void)
{
    return(OCTEON_IS_MODEL(OCTEON_CN38XX)
           && !OCTEON_IS_MODEL(OCTEON_CN38XX_PASS1)
           &&cvmx_fuse_read(264));
}


/**
 * @deprecated
 * Determine if Octeon supports the DFA state machines. This function is
 * deprecated, use octeon_has_feature(OCTEON_FEATURE_DFA) instead.
 *
 * @return Non zero if DFA is supported
 */
static inline int cvmx_octeon_dfa_present(void) __attribute__((deprecated));
static inline int cvmx_octeon_dfa_present(void)
{
    return octeon_has_feature(OCTEON_FEATURE_DFA);
}


/**
 * @deprecated
 * Determine if Octeon supports ZIP. This function is deprecated, use
 * octeon_has_feature(OCTEON_FEATURE_ZIP) instead.
 *
 * @return Non zero if DFA is supported
 */
static inline int cvmx_octeon_zip_present(void) __attribute__((deprecated));
static inline int cvmx_octeon_zip_present(void)
{
    return octeon_has_feature(OCTEON_FEATURE_ZIP);
}


/**
 * @deprecated
 * Determine if Octeon supports Crypto acceleration. This function is
 * deprecated, use octeon_has_feature(OCTEON_FEATURE_CRYPTO) instead.
 *
 * @return Non zero if DFA is supported
 */
static inline int cvmx_octeon_crypto_present(void) __attribute__((deprecated));
static inline int cvmx_octeon_crypto_present(void)
{
    return octeon_has_feature(OCTEON_FEATURE_CRYPTO);
}


/**
 * @deprecated
 * This function is a trival wrapper around cvmx_read64_uint64(). Use
 * cvmx_read64_uint64() instead as this function is deprecated.
 *
 * @param address
 *
 * @return
 */
static inline uint64_t cvmx_read64(uint64_t address) __attribute__((deprecated));
static inline uint64_t cvmx_read64(uint64_t address)
{
    return cvmx_read64_uint64(address);
}


/**
 * @deprecated
 * This function is a trival wrapper around cvmx_write64_uint64(). Use
 * cvmx_write64_uint64() instead as this function is deprecated.
 *
 * @param address Location to write ro
 * @param value Value to write
 *
 * @return
 */
static inline void cvmx_write64(uint64_t address, uint64_t value) __attribute__((deprecated));
static inline void cvmx_write64(uint64_t address, uint64_t value)
{
    cvmx_write64_uint64(address, value);
}

#ifdef	__cplusplus
}
#endif

#endif /* __CVMX_UTILS_H__ */

OpenPOWER on IntegriCloud