cvmx-utils.h revision 210284
1/***********************license start***************
2 *  Copyright (c) 2003-2009 Cavium Networks (support@cavium.com). All rights
3 *  reserved.
4 *
5 *
6 *  Redistribution and use in source and binary forms, with or without
7 *  modification, are permitted provided that the following conditions are
8 *  met:
9 *
10 *      * Redistributions of source code must retain the above copyright
11 *        notice, this list of conditions and the following disclaimer.
12 *
13 *      * Redistributions in binary form must reproduce the above
14 *        copyright notice, this list of conditions and the following
15 *        disclaimer in the documentation and/or other materials provided
16 *        with the distribution.
17 *
18 *      * Neither the name of Cavium Networks nor the names of
19 *        its contributors may be used to endorse or promote products
20 *        derived from this software without specific prior written
21 *        permission.
22 *
23 *  TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
24 *  AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS
25 *  OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH
26 *  RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY
27 *  REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT
28 *  DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES
29 *  OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR
30 *  PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET
31 *  POSSESSION OR CORRESPONDENCE TO DESCRIPTION.  THE ENTIRE RISK ARISING OUT
32 *  OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
33 *
34 *
35 *  For any questions regarding licensing please contact marketing@caviumnetworks.com
36 *
37 ***********************license end**************************************/
38
39/**
40 * @file
41 * Small utility functions and macros to ease programming of Octeon.
42 *
43 * <hr>$Revision: 38306 $<hr>
44*/
45#ifndef __CVMX_UTILS_H__
46#define __CVMX_UTILS_H__
47
48#ifdef	__cplusplus
49extern "C" {
50#endif
51
52#ifndef TRUE
53#define FALSE   0
54#define TRUE    (!(FALSE))
55#endif
56
57/*
58 * The macros cvmx_likely and cvmx_unlikely use the
59 * __builtin_expect GCC operation to control branch
60 * probabilities for a conditional. For example, an "if"
61 * statement in the code that will almost always be
62 * executed should be written as "if (cvmx_likely(...))".
63 * If the "else" section of an if statement is more
64 * probable, use "if (cvmx_unlikey(...))".
65 */
66#define cvmx_likely(x)      __builtin_expect(!!(x), 1)
67#define cvmx_unlikely(x)    __builtin_expect(!!(x), 0)
68
69#if CVMX_ENABLE_DEBUG_PRINTS
70    #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
71        #define cvmx_dprintf        printk
72    #else
73        #define cvmx_dprintf        printf
74    #endif
75#else
76    static inline void cvmx_dprintf(const char *format, ...) __attribute__ ((format(printf, 1, 2)));
77    static inline void cvmx_dprintf(const char *format, ...)
78    {
79        /* Prints are disbled, do nothing */
80    }
81#endif
82
83#define CAST64(v) ((long long)(long)(v))
84#define CASTPTR(type, v) ((type *)(long)(v))
85#define CVMX_MAX_CORES          (16)
86#define CVMX_CACHE_LINE_SIZE    (128)   // In bytes
87#define CVMX_CACHE_LINE_MASK    (CVMX_CACHE_LINE_SIZE - 1)   // In bytes
88#define CVMX_CACHE_LINE_ALIGNED __attribute__ ((aligned (CVMX_CACHE_LINE_SIZE)))
89
90/**
91 * This macro spins on a field waiting for it to reach a value. It
92 * is common in code to need to wait for a specific field in a CSR
93 * to match a specific value. Conceptually this macro expands to:
94 *
95 * 1) read csr at "address" with a csr typedef of "type"
96 * 2) Check if ("type".s."field" "op" "value")
97 * 3) If #2 isn't true loop to #1 unless too much time has passed.
98 */
99#define CVMX_WAIT_FOR_FIELD64(address, type, field, op, value, timeout_usec)\
100    ({int result;                                                       \
101    do {                                                                \
102        uint64_t done = cvmx_get_cycle() + (uint64_t)timeout_usec *     \
103                           cvmx_sysinfo_get()->cpu_clock_hz / 1000000;  \
104        type c;                                                         \
105        while (1)                                                       \
106        {                                                               \
107            c.u64 = cvmx_read_csr(address);                             \
108            if ((c.s.field) op (value)) {                               \
109                result = 0;                                             \
110                break;                                                  \
111            } else if (cvmx_get_cycle() > done) {                       \
112                result = -1;                                            \
113                break;                                                  \
114            } else                                                      \
115                cvmx_wait(100);                                         \
116        }                                                               \
117    } while (0);                                                        \
118    result;})
119
120/**
121 * Builds a bit mask given the required size in bits.
122 *
123 * @param bits   Number of bits in the mask
124 * @return The mask
125 */
126static inline uint64_t cvmx_build_mask(uint64_t bits)
127{
128    return ~((~0x0ull) << bits);
129}
130
131
132/**
133 * Builds a memory address for I/O based on the Major and Sub DID.
134 *
135 * @param major_did 5 bit major did
136 * @param sub_did   3 bit sub did
137 * @return I/O base address
138 */
139static inline uint64_t cvmx_build_io_address(uint64_t major_did, uint64_t sub_did)
140{
141    return ((0x1ull << 48) | (major_did << 43) | (sub_did << 40));
142}
143
144
145/**
146 * Perform mask and shift to place the supplied value into
147 * the supplied bit rage.
148 *
149 * Example: cvmx_build_bits(39,24,value)
150 * <pre>
151 * 6       5       4       3       3       2       1
152 * 3       5       7       9       1       3       5       7      0
153 * +-------+-------+-------+-------+-------+-------+-------+------+
154 * 000000000000000000000000___________value000000000000000000000000
155 * </pre>
156 *
157 * @param high_bit Highest bit value can occupy (inclusive) 0-63
158 * @param low_bit  Lowest bit value can occupy inclusive 0-high_bit
159 * @param value    Value to use
160 * @return Value masked and shifted
161 */
162static inline uint64_t cvmx_build_bits(uint64_t high_bit, uint64_t low_bit, uint64_t value)
163{
164    return ((value & cvmx_build_mask(high_bit - low_bit + 1)) << low_bit);
165}
166
167
168/**
169 * Return the number of cores available in the chip
170 *
171 * @return
172 */
173static inline uint32_t cvmx_octeon_num_cores(void)
174{
175    uint32_t ciu_fuse = (uint32_t)cvmx_read_csr(CVMX_CIU_FUSE) & 0xffff;
176    return cvmx_pop(ciu_fuse);
177}
178
179
180/**
181 * Return true if Octeon is CN38XX pass 1
182 *
183 * @return
184 */
185static inline int cvmx_octeon_is_pass1(void)
186{
187    return OCTEON_IS_MODEL(OCTEON_CN38XX_PASS1);
188}
189
190
191/**
192 * Return true if Octeon is CN36XX
193 *
194 * @return
195 */
196static inline int cvmx_octeon_model_CN36XX(void)
197{
198    return(OCTEON_IS_MODEL(OCTEON_CN38XX)
199           && !OCTEON_IS_MODEL(OCTEON_CN38XX_PASS1)
200           &&cvmx_fuse_read(264));
201}
202
203
204/**
205 * @deprecated
206 * Determine if Octeon supports the DFA state machines. This function is
207 * deprecated, use octeon_has_feature(OCTEON_FEATURE_DFA) instead.
208 *
209 * @return Non zero if DFA is supported
210 */
211static inline int cvmx_octeon_dfa_present(void) __attribute__((deprecated));
212static inline int cvmx_octeon_dfa_present(void)
213{
214    return octeon_has_feature(OCTEON_FEATURE_DFA);
215}
216
217
218/**
219 * @deprecated
220 * Determine if Octeon supports ZIP. This function is deprecated, use
221 * octeon_has_feature(OCTEON_FEATURE_ZIP) instead.
222 *
223 * @return Non zero if DFA is supported
224 */
225static inline int cvmx_octeon_zip_present(void) __attribute__((deprecated));
226static inline int cvmx_octeon_zip_present(void)
227{
228    return octeon_has_feature(OCTEON_FEATURE_ZIP);
229}
230
231
232/**
233 * @deprecated
234 * Determine if Octeon supports Crypto acceleration. This function is
235 * deprecated, use octeon_has_feature(OCTEON_FEATURE_CRYPTO) instead.
236 *
237 * @return Non zero if DFA is supported
238 */
239static inline int cvmx_octeon_crypto_present(void) __attribute__((deprecated));
240static inline int cvmx_octeon_crypto_present(void)
241{
242    return octeon_has_feature(OCTEON_FEATURE_CRYPTO);
243}
244
245
246/**
247 * @deprecated
248 * This function is a trival wrapper around cvmx_read64_uint64(). Use
249 * cvmx_read64_uint64() instead as this function is deprecated.
250 *
251 * @param address
252 *
253 * @return
254 */
255static inline uint64_t cvmx_read64(uint64_t address) __attribute__((deprecated));
256static inline uint64_t cvmx_read64(uint64_t address)
257{
258    return cvmx_read64_uint64(address);
259}
260
261
262/**
263 * @deprecated
264 * This function is a trival wrapper around cvmx_write64_uint64(). Use
265 * cvmx_write64_uint64() instead as this function is deprecated.
266 *
267 * @param address Location to write ro
268 * @param value Value to write
269 *
270 * @return
271 */
272static inline void cvmx_write64(uint64_t address, uint64_t value) __attribute__((deprecated));
273static inline void cvmx_write64(uint64_t address, uint64_t value)
274{
275    cvmx_write64_uint64(address, value);
276}
277
278#ifdef	__cplusplus
279}
280#endif
281
282#endif /* __CVMX_UTILS_H__ */
283
284