2 *******************************************************************************
3 Copyright (C) 2015 Annapurna Labs Ltd.
5 This file may be licensed under the terms of the Annapurna Labs Commercial
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
12 Alternatively, redistribution and use in source and binary forms, with or
13 without modification, are permitted provided that the following conditions are
16 * Redistributions of source code must retain the above copyright notice,
17 this list of conditions and the following disclaimer.
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
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.
35 *******************************************************************************/
38 * @defgroup group_services Platform Services API
40 * The Platform Services API provides miscellaneous system services to HAL
42 * - Registers read/write
45 * - Endianness conversions
48 * @file plat_api/sample/al_hal_plat_services.h
50 * @brief API for Platform services provided for to HAL drivers
55 #ifndef __PLAT_SERVICES_H__
56 #define __PLAT_SERVICES_H__
58 #include <machine/atomic.h>
59 #include <sys/cdefs.h>
60 __FBSDID("$FreeBSD$");
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>
68 #include <sys/mutex.h>
69 #include <machine/bus.h>
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,
75 uint16_t generic_bs_r_2(bus_space_tag_t t, bus_space_handle_t bsh,
78 uint32_t generic_bs_r_4(bus_space_tag_t t, bus_space_handle_t bsh,
81 void generic_bs_w_1(bus_space_tag_t t, bus_space_handle_t bsh,
82 bus_size_t offset, uint8_t value);
84 void generic_bs_w_2(bus_space_tag_t t, bus_space_handle_t bsh,
85 bus_size_t offset, uint16_t value);
87 void generic_bs_w_4(bus_space_tag_t t, bus_space_handle_t bsh,
88 bus_size_t offset, uint32_t value);
90 void generic_bs_w_8(bus_space_tag_t t, bus_space_handle_t bsh,
91 bus_size_t offset, uint64_t value);
93 #define __UNUSED __attribute__((unused))
102 * Make sure data will be visible by other masters (other CPUS and DMA).
103 * usually this is achieved by the ARM DMB instruction.
105 static void al_data_memory_barrier(void);
106 static void al_smp_data_memory_barrier(void);
109 * Make sure data will be visible by DMA masters, no restriction for other cpus
112 al_data_memory_barrier(void)
122 * Make sure data will be visible in order by other cpus masters.
125 al_smp_data_memory_barrier(void)
135 * Make sure write data will be visible in order by other cpus masters.
138 al_local_data_memory_barrier(void)
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.
156 * Read MMIO 8 bits register
157 * @param offset register offset
159 * @return register value
161 static uint8_t al_reg_read8(uint8_t * offset);
164 * Read MMIO 16 bits register
165 * @param offset register offset
167 * @return register value
169 static uint16_t al_reg_read16(uint16_t * offset);
172 * Read MMIO 32 bits register
173 * @param offset register offset
175 * @return register value
177 static uint32_t al_reg_read32(uint32_t * offset);
180 * Read MMIO 64 bits register
181 * @param offset register offset
183 * @return register value
185 uint64_t al_reg_read64(uint64_t * offset);
188 * Relaxed read MMIO 32 bits register
190 * Relaxed register read/write functions don't involve cpu instructions that
191 * force syncronization, nor ordering between the register access and memory
193 * These instructions are used in performance critical code to avoid the
194 * overhead of the synchronization instructions.
196 * @param offset register offset
198 * @return register value
200 #define al_bus_dma_to_va(bus_tag, bus_handle) ((void*)bus_handle)
203 * Relaxed read MMIO 32 bits register
205 * Relaxed register read/write functions don't involve cpu instructions that
206 * force syncronization, nor ordering between the register access and memory
208 * These instructions are used in performance critical code to avoid the
209 * overhead of the synchronization instructions.
211 * @param offset register offset
213 * @return register value
215 #define al_reg_read32_relaxed(l) generic_bs_r_4(NULL, (bus_space_handle_t)l, 0)
218 * Relaxed write to MMIO 32 bits register
220 * Relaxed register read/write functions don't involve cpu instructions that
221 * force syncronization, nor ordering between the register access and memory
223 * These instructions are used in performance critical code to avoid the
224 * overhead of the synchronization instructions.
226 * @param offset register offset
227 * @param val value to write to the register
229 #define al_reg_write32_relaxed(l,v) generic_bs_w_4(NULL, (bus_space_handle_t)l, 0, v)
232 * Write to MMIO 8 bits register
233 * @param offset register offset
234 * @param val value to write to the register
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(); \
243 * Write to MMIO 16 bits register
244 * @param offset register offset
245 * @param val value to write to the register
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(); \
254 * Write to MMIO 32 bits register
255 * @param offset register offset
256 * @param val value to write to the register
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(); \
265 * Write to MMIO 64 bits register
266 * @param offset register offset
267 * @param val value to write to the register
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(); \
275 static inline uint8_t
276 al_reg_read8(uint8_t *l)
279 al_data_memory_barrier();
280 return (generic_bs_r_1(NULL, (bus_space_handle_t)l, 0));
283 static inline uint16_t
284 al_reg_read16(uint16_t *l)
287 al_data_memory_barrier();
288 return (generic_bs_r_2(NULL, (bus_space_handle_t)l, 0));
291 static inline uint32_t
292 al_reg_read32(uint32_t *l)
295 al_data_memory_barrier();
296 return (generic_bs_r_4(NULL, (bus_space_handle_t)l, 0));
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
305 #define AL_DBG_LEVEL AL_DBG_LEVEL_ERR
307 #define AL_DBG_LOCK()
308 #define AL_DBG_UNLOCK()
313 * @param format The format string
314 * @param ... Additional arguments
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)
319 * print error message
323 #define al_err(...) do { if (AL_DBG_LEVEL >= AL_DBG_LEVEL_ERR) { AL_DBG_LOCK(); printf(__VA_ARGS__); AL_DBG_UNLOCK(); } } while(0)
326 * print warning message
330 #define al_warn(...) do { if (AL_DBG_LEVEL >= AL_DBG_LEVEL_WARN) { AL_DBG_LOCK(); printf(__VA_ARGS__); AL_DBG_UNLOCK(); } } while(0)
337 #define al_info(...) do { if (AL_DBG_LEVEL >= AL_DBG_LEVEL_INFO) { AL_DBG_LOCK(); printf(__VA_ARGS__); AL_DBG_UNLOCK(); } } while(0)
340 * print debug message
344 #define al_dbg(...) do { if (AL_DBG_LEVEL >= AL_DBG_LEVEL_DBG) { AL_DBG_LOCK(); printf(__VA_ARGS__); AL_DBG_UNLOCK(); } } while(0)
351 #define al_assert(COND) \
355 "%s:%d:%s: Assertion failed! (%s)\n", \
356 __FILE__, __LINE__, __func__, #COND); \
360 * al_udelay - micro sec delay
362 #define al_udelay(u) DELAY(u)
365 * al_msleep - mili sec delay
367 #define al_msleep(m) DELAY((m) * 1000)
370 * swap half word to little endian
372 * @param x 16 bit value
374 * @return the value in little endian
376 #define swap16_to_le(x) htole16(x)
378 * swap word to little endian
380 * @param x 32 bit value
382 * @return the value in little endian
384 #define swap32_to_le(x) htole32(x)
387 * swap 8 bytes to little endian
389 * @param x 64 bit value
391 * @return the value in little endian
393 #define swap64_to_le(x) htole64(x)
396 * swap half word from little endian
398 * @param x 16 bit value
400 * @return the value in the cpu endianess
402 #define swap16_from_le(x) le16toh(x)
405 * swap word from little endian
407 * @param x 32 bit value
409 * @return the value in the cpu endianess
411 #define swap32_from_le(x) le32toh(x)
414 * swap 8 bytes from little endian
416 * @param x 64 bit value
418 * @return the value in the cpu endianess
420 #define swap64_from_le(x) le64toh(x)
425 * @param p memory pointer
426 * @param val value for setting
427 * @param cnt number of bytes to set
429 #define al_memset(p, val, cnt) memset(p, val, cnt)
434 * @param p1 memory pointer
435 * @param p2 memory pointer
436 * @param cnt number of bytes to copy
438 #define al_memcpy(p1, p2, cnt) memcpy(p1, p2, cnt)
443 * @param p1 memory pointer
444 * @param p2 memory pointer
445 * @param cnt number of bytes to compare
447 #define al_memcmp(p1, p2, cnt) memcmp(p1, p2, cnt)
452 * @param s1 string pointer
453 * @param s2 string pointer
455 #define al_strcmp(s1, s2) strcmp(s1, s2)
457 #define al_get_cpu_id() 0
464 /** @} end of Platform Services API group */
465 #endif /* __PLAT_SERVICES_H__ */