cvmx-utils.h revision 210284
1210284Sjmallett/***********************license start***************
2210284Sjmallett *  Copyright (c) 2003-2009 Cavium Networks (support@cavium.com). All rights
3210284Sjmallett *  reserved.
4210284Sjmallett *
5210284Sjmallett *
6210284Sjmallett *  Redistribution and use in source and binary forms, with or without
7210284Sjmallett *  modification, are permitted provided that the following conditions are
8210284Sjmallett *  met:
9210284Sjmallett *
10210284Sjmallett *      * Redistributions of source code must retain the above copyright
11210284Sjmallett *        notice, this list of conditions and the following disclaimer.
12210284Sjmallett *
13210284Sjmallett *      * Redistributions in binary form must reproduce the above
14210284Sjmallett *        copyright notice, this list of conditions and the following
15210284Sjmallett *        disclaimer in the documentation and/or other materials provided
16210284Sjmallett *        with the distribution.
17210284Sjmallett *
18210284Sjmallett *      * Neither the name of Cavium Networks nor the names of
19210284Sjmallett *        its contributors may be used to endorse or promote products
20210284Sjmallett *        derived from this software without specific prior written
21210284Sjmallett *        permission.
22210284Sjmallett *
23210284Sjmallett *  TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
24210284Sjmallett *  AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS
25210284Sjmallett *  OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH
26210284Sjmallett *  RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY
27210284Sjmallett *  REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT
28210284Sjmallett *  DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES
29210284Sjmallett *  OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR
30210284Sjmallett *  PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET
31210284Sjmallett *  POSSESSION OR CORRESPONDENCE TO DESCRIPTION.  THE ENTIRE RISK ARISING OUT
32210284Sjmallett *  OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
33210284Sjmallett *
34210284Sjmallett *
35210284Sjmallett *  For any questions regarding licensing please contact marketing@caviumnetworks.com
36210284Sjmallett *
37210284Sjmallett ***********************license end**************************************/
38210284Sjmallett
39210284Sjmallett/**
40210284Sjmallett * @file
41210284Sjmallett * Small utility functions and macros to ease programming of Octeon.
42210284Sjmallett *
43210284Sjmallett * <hr>$Revision: 38306 $<hr>
44210284Sjmallett*/
45210284Sjmallett#ifndef __CVMX_UTILS_H__
46210284Sjmallett#define __CVMX_UTILS_H__
47210284Sjmallett
48210284Sjmallett#ifdef	__cplusplus
49210284Sjmallettextern "C" {
50210284Sjmallett#endif
51210284Sjmallett
52210284Sjmallett#ifndef TRUE
53210284Sjmallett#define FALSE   0
54210284Sjmallett#define TRUE    (!(FALSE))
55210284Sjmallett#endif
56210284Sjmallett
57210284Sjmallett/*
58210284Sjmallett * The macros cvmx_likely and cvmx_unlikely use the
59210284Sjmallett * __builtin_expect GCC operation to control branch
60210284Sjmallett * probabilities for a conditional. For example, an "if"
61210284Sjmallett * statement in the code that will almost always be
62210284Sjmallett * executed should be written as "if (cvmx_likely(...))".
63210284Sjmallett * If the "else" section of an if statement is more
64210284Sjmallett * probable, use "if (cvmx_unlikey(...))".
65210284Sjmallett */
66210284Sjmallett#define cvmx_likely(x)      __builtin_expect(!!(x), 1)
67210284Sjmallett#define cvmx_unlikely(x)    __builtin_expect(!!(x), 0)
68210284Sjmallett
69210284Sjmallett#if CVMX_ENABLE_DEBUG_PRINTS
70210284Sjmallett    #ifdef CVMX_BUILD_FOR_LINUX_KERNEL
71210284Sjmallett        #define cvmx_dprintf        printk
72210284Sjmallett    #else
73210284Sjmallett        #define cvmx_dprintf        printf
74210284Sjmallett    #endif
75210284Sjmallett#else
76210284Sjmallett    static inline void cvmx_dprintf(const char *format, ...) __attribute__ ((format(printf, 1, 2)));
77210284Sjmallett    static inline void cvmx_dprintf(const char *format, ...)
78210284Sjmallett    {
79210284Sjmallett        /* Prints are disbled, do nothing */
80210284Sjmallett    }
81210284Sjmallett#endif
82210284Sjmallett
83210284Sjmallett#define CAST64(v) ((long long)(long)(v))
84210284Sjmallett#define CASTPTR(type, v) ((type *)(long)(v))
85210284Sjmallett#define CVMX_MAX_CORES          (16)
86210284Sjmallett#define CVMX_CACHE_LINE_SIZE    (128)   // In bytes
87210284Sjmallett#define CVMX_CACHE_LINE_MASK    (CVMX_CACHE_LINE_SIZE - 1)   // In bytes
88210284Sjmallett#define CVMX_CACHE_LINE_ALIGNED __attribute__ ((aligned (CVMX_CACHE_LINE_SIZE)))
89210284Sjmallett
90210284Sjmallett/**
91210284Sjmallett * This macro spins on a field waiting for it to reach a value. It
92210284Sjmallett * is common in code to need to wait for a specific field in a CSR
93210284Sjmallett * to match a specific value. Conceptually this macro expands to:
94210284Sjmallett *
95210284Sjmallett * 1) read csr at "address" with a csr typedef of "type"
96210284Sjmallett * 2) Check if ("type".s."field" "op" "value")
97210284Sjmallett * 3) If #2 isn't true loop to #1 unless too much time has passed.
98210284Sjmallett */
99210284Sjmallett#define CVMX_WAIT_FOR_FIELD64(address, type, field, op, value, timeout_usec)\
100210284Sjmallett    ({int result;                                                       \
101210284Sjmallett    do {                                                                \
102210284Sjmallett        uint64_t done = cvmx_get_cycle() + (uint64_t)timeout_usec *     \
103210284Sjmallett                           cvmx_sysinfo_get()->cpu_clock_hz / 1000000;  \
104210284Sjmallett        type c;                                                         \
105210284Sjmallett        while (1)                                                       \
106210284Sjmallett        {                                                               \
107210284Sjmallett            c.u64 = cvmx_read_csr(address);                             \
108210284Sjmallett            if ((c.s.field) op (value)) {                               \
109210284Sjmallett                result = 0;                                             \
110210284Sjmallett                break;                                                  \
111210284Sjmallett            } else if (cvmx_get_cycle() > done) {                       \
112210284Sjmallett                result = -1;                                            \
113210284Sjmallett                break;                                                  \
114210284Sjmallett            } else                                                      \
115210284Sjmallett                cvmx_wait(100);                                         \
116210284Sjmallett        }                                                               \
117210284Sjmallett    } while (0);                                                        \
118210284Sjmallett    result;})
119210284Sjmallett
120210284Sjmallett/**
121210284Sjmallett * Builds a bit mask given the required size in bits.
122210284Sjmallett *
123210284Sjmallett * @param bits   Number of bits in the mask
124210284Sjmallett * @return The mask
125210284Sjmallett */
126210284Sjmallettstatic inline uint64_t cvmx_build_mask(uint64_t bits)
127210284Sjmallett{
128210284Sjmallett    return ~((~0x0ull) << bits);
129210284Sjmallett}
130210284Sjmallett
131210284Sjmallett
132210284Sjmallett/**
133210284Sjmallett * Builds a memory address for I/O based on the Major and Sub DID.
134210284Sjmallett *
135210284Sjmallett * @param major_did 5 bit major did
136210284Sjmallett * @param sub_did   3 bit sub did
137210284Sjmallett * @return I/O base address
138210284Sjmallett */
139210284Sjmallettstatic inline uint64_t cvmx_build_io_address(uint64_t major_did, uint64_t sub_did)
140210284Sjmallett{
141210284Sjmallett    return ((0x1ull << 48) | (major_did << 43) | (sub_did << 40));
142210284Sjmallett}
143210284Sjmallett
144210284Sjmallett
145210284Sjmallett/**
146210284Sjmallett * Perform mask and shift to place the supplied value into
147210284Sjmallett * the supplied bit rage.
148210284Sjmallett *
149210284Sjmallett * Example: cvmx_build_bits(39,24,value)
150210284Sjmallett * <pre>
151210284Sjmallett * 6       5       4       3       3       2       1
152210284Sjmallett * 3       5       7       9       1       3       5       7      0
153210284Sjmallett * +-------+-------+-------+-------+-------+-------+-------+------+
154210284Sjmallett * 000000000000000000000000___________value000000000000000000000000
155210284Sjmallett * </pre>
156210284Sjmallett *
157210284Sjmallett * @param high_bit Highest bit value can occupy (inclusive) 0-63
158210284Sjmallett * @param low_bit  Lowest bit value can occupy inclusive 0-high_bit
159210284Sjmallett * @param value    Value to use
160210284Sjmallett * @return Value masked and shifted
161210284Sjmallett */
162210284Sjmallettstatic inline uint64_t cvmx_build_bits(uint64_t high_bit, uint64_t low_bit, uint64_t value)
163210284Sjmallett{
164210284Sjmallett    return ((value & cvmx_build_mask(high_bit - low_bit + 1)) << low_bit);
165210284Sjmallett}
166210284Sjmallett
167210284Sjmallett
168210284Sjmallett/**
169210284Sjmallett * Return the number of cores available in the chip
170210284Sjmallett *
171210284Sjmallett * @return
172210284Sjmallett */
173210284Sjmallettstatic inline uint32_t cvmx_octeon_num_cores(void)
174210284Sjmallett{
175210284Sjmallett    uint32_t ciu_fuse = (uint32_t)cvmx_read_csr(CVMX_CIU_FUSE) & 0xffff;
176210284Sjmallett    return cvmx_pop(ciu_fuse);
177210284Sjmallett}
178210284Sjmallett
179210284Sjmallett
180210284Sjmallett/**
181210284Sjmallett * Return true if Octeon is CN38XX pass 1
182210284Sjmallett *
183210284Sjmallett * @return
184210284Sjmallett */
185210284Sjmallettstatic inline int cvmx_octeon_is_pass1(void)
186210284Sjmallett{
187210284Sjmallett    return OCTEON_IS_MODEL(OCTEON_CN38XX_PASS1);
188210284Sjmallett}
189210284Sjmallett
190210284Sjmallett
191210284Sjmallett/**
192210284Sjmallett * Return true if Octeon is CN36XX
193210284Sjmallett *
194210284Sjmallett * @return
195210284Sjmallett */
196210284Sjmallettstatic inline int cvmx_octeon_model_CN36XX(void)
197210284Sjmallett{
198210284Sjmallett    return(OCTEON_IS_MODEL(OCTEON_CN38XX)
199210284Sjmallett           && !OCTEON_IS_MODEL(OCTEON_CN38XX_PASS1)
200210284Sjmallett           &&cvmx_fuse_read(264));
201210284Sjmallett}
202210284Sjmallett
203210284Sjmallett
204210284Sjmallett/**
205210284Sjmallett * @deprecated
206210284Sjmallett * Determine if Octeon supports the DFA state machines. This function is
207210284Sjmallett * deprecated, use octeon_has_feature(OCTEON_FEATURE_DFA) instead.
208210284Sjmallett *
209210284Sjmallett * @return Non zero if DFA is supported
210210284Sjmallett */
211210284Sjmallettstatic inline int cvmx_octeon_dfa_present(void) __attribute__((deprecated));
212210284Sjmallettstatic inline int cvmx_octeon_dfa_present(void)
213210284Sjmallett{
214210284Sjmallett    return octeon_has_feature(OCTEON_FEATURE_DFA);
215210284Sjmallett}
216210284Sjmallett
217210284Sjmallett
218210284Sjmallett/**
219210284Sjmallett * @deprecated
220210284Sjmallett * Determine if Octeon supports ZIP. This function is deprecated, use
221210284Sjmallett * octeon_has_feature(OCTEON_FEATURE_ZIP) instead.
222210284Sjmallett *
223210284Sjmallett * @return Non zero if DFA is supported
224210284Sjmallett */
225210284Sjmallettstatic inline int cvmx_octeon_zip_present(void) __attribute__((deprecated));
226210284Sjmallettstatic inline int cvmx_octeon_zip_present(void)
227210284Sjmallett{
228210284Sjmallett    return octeon_has_feature(OCTEON_FEATURE_ZIP);
229210284Sjmallett}
230210284Sjmallett
231210284Sjmallett
232210284Sjmallett/**
233210284Sjmallett * @deprecated
234210284Sjmallett * Determine if Octeon supports Crypto acceleration. This function is
235210284Sjmallett * deprecated, use octeon_has_feature(OCTEON_FEATURE_CRYPTO) instead.
236210284Sjmallett *
237210284Sjmallett * @return Non zero if DFA is supported
238210284Sjmallett */
239210284Sjmallettstatic inline int cvmx_octeon_crypto_present(void) __attribute__((deprecated));
240210284Sjmallettstatic inline int cvmx_octeon_crypto_present(void)
241210284Sjmallett{
242210284Sjmallett    return octeon_has_feature(OCTEON_FEATURE_CRYPTO);
243210284Sjmallett}
244210284Sjmallett
245210284Sjmallett
246210284Sjmallett/**
247210284Sjmallett * @deprecated
248210284Sjmallett * This function is a trival wrapper around cvmx_read64_uint64(). Use
249210284Sjmallett * cvmx_read64_uint64() instead as this function is deprecated.
250210284Sjmallett *
251210284Sjmallett * @param address
252210284Sjmallett *
253210284Sjmallett * @return
254210284Sjmallett */
255210284Sjmallettstatic inline uint64_t cvmx_read64(uint64_t address) __attribute__((deprecated));
256210284Sjmallettstatic inline uint64_t cvmx_read64(uint64_t address)
257210284Sjmallett{
258210284Sjmallett    return cvmx_read64_uint64(address);
259210284Sjmallett}
260210284Sjmallett
261210284Sjmallett
262210284Sjmallett/**
263210284Sjmallett * @deprecated
264210284Sjmallett * This function is a trival wrapper around cvmx_write64_uint64(). Use
265210284Sjmallett * cvmx_write64_uint64() instead as this function is deprecated.
266210284Sjmallett *
267210284Sjmallett * @param address Location to write ro
268210284Sjmallett * @param value Value to write
269210284Sjmallett *
270210284Sjmallett * @return
271210284Sjmallett */
272210284Sjmallettstatic inline void cvmx_write64(uint64_t address, uint64_t value) __attribute__((deprecated));
273210284Sjmallettstatic inline void cvmx_write64(uint64_t address, uint64_t value)
274210284Sjmallett{
275210284Sjmallett    cvmx_write64_uint64(address, value);
276210284Sjmallett}
277210284Sjmallett
278210284Sjmallett#ifdef	__cplusplus
279210284Sjmallett}
280210284Sjmallett#endif
281210284Sjmallett
282210284Sjmallett#endif /* __CVMX_UTILS_H__ */
283210284Sjmallett
284