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>
70 /* Prototypes for all the bus_space structure functions */
72 bs_protos(generic_armv4);
74 #define __UNUSED __attribute__((unused))
83 * WMA: This is a hack which allows not modifying the __iomem accessing HAL code.
84 * On ARMv7, bus_handle holds the information about VA of accessed memory. It
85 * is possible to use direct load/store instruction instead of bus_dma machinery.
86 * WARNING: This is not guaranteed to stay that way forever, nor that
87 * on other architectures these variables behave similarly. Keep that
88 * in mind during porting to other systems.
91 * Read MMIO 8 bits register
92 * @param offset register offset
94 * @return register value
96 static uint8_t al_reg_read8(uint8_t * offset);
99 * Read MMIO 16 bits register
100 * @param offset register offset
102 * @return register value
104 static uint16_t al_reg_read16(uint16_t * offset);
107 * Read MMIO 32 bits register
108 * @param offset register offset
110 * @return register value
112 static uint32_t al_reg_read32(uint32_t * offset);
115 * Read MMIO 64 bits register
116 * @param offset register offset
118 * @return register value
120 uint64_t al_reg_read64(uint64_t * offset);
123 * Relaxed read MMIO 32 bits register
125 * Relaxed register read/write functions don't involve cpu instructions that
126 * force syncronization, nor ordering between the register access and memory
128 * These instructions are used in performance critical code to avoid the
129 * overhead of the synchronization instructions.
131 * @param offset register offset
133 * @return register value
135 #define al_bus_dma_to_va(bus_tag, bus_handle) ((void*)bus_handle)
138 * Relaxed read MMIO 32 bits register
140 * Relaxed register read/write functions don't involve cpu instructions that
141 * force syncronization, nor ordering between the register access and memory
143 * These instructions are used in performance critical code to avoid the
144 * overhead of the synchronization instructions.
146 * @param offset register offset
148 * @return register value
150 #define al_reg_read32_relaxed(l) generic_bs_r_4(NULL, (bus_space_handle_t)l, 0)
153 * Relaxed write to MMIO 32 bits register
155 * Relaxed register read/write functions don't involve cpu instructions that
156 * force syncronization, nor ordering between the register access and memory
158 * These instructions are used in performance critical code to avoid the
159 * overhead of the synchronization instructions.
161 * @param offset register offset
162 * @param val value to write to the register
164 #define al_reg_write32_relaxed(l,v) generic_bs_w_4(NULL, (bus_space_handle_t)l, 0, v)
167 * Write to MMIO 8 bits register
168 * @param offset register offset
169 * @param val value to write to the register
171 #define al_reg_write8(l,v) do { dsb(); generic_bs_w_1(NULL, (bus_space_handle_t)l, 0, v); dmb(); } while (0)
174 * Write to MMIO 16 bits register
175 * @param offset register offset
176 * @param val value to write to the register
178 #define al_reg_write16(l,v) do { dsb(); generic_bs_w_2(NULL, (bus_space_handle_t)l, 0, v); dmb(); } while (0)
181 * Write to MMIO 32 bits register
182 * @param offset register offset
183 * @param val value to write to the register
185 #define al_reg_write32(l,v) do { dsb(); generic_bs_w_4(NULL, (bus_space_handle_t)l, 0, v); dmb(); } while (0)
188 * Write to MMIO 64 bits register
189 * @param offset register offset
190 * @param val value to write to the register
192 #define al_reg_write64(l,v) do { dsb(); generic_bs_w_8(NULL, (bus_space_handle_t)l, 0, v); dmb(); } while (0)
194 static inline uint8_t
195 al_reg_read8(uint8_t *l)
199 return (generic_bs_r_1(NULL, (bus_space_handle_t)l, 0));
202 static inline uint16_t
203 al_reg_read16(uint16_t *l)
207 return (generic_bs_r_2(NULL, (bus_space_handle_t)l, 0));
210 static inline uint32_t
211 al_reg_read32(uint32_t *l)
215 return (generic_bs_r_4(NULL, (bus_space_handle_t)l, 0));
218 #define AL_DBG_LEVEL_NONE 0
219 #define AL_DBG_LEVEL_ERR 1
220 #define AL_DBG_LEVEL_WARN 2
221 #define AL_DBG_LEVEL_INFO 3
222 #define AL_DBG_LEVEL_DBG 4
224 #define AL_DBG_LEVEL AL_DBG_LEVEL_ERR
226 extern struct mtx al_dbg_lock;
228 #define AL_DBG_LOCK() mtx_lock_spin(&al_dbg_lock)
229 #define AL_DBG_UNLOCK() mtx_unlock_spin(&al_dbg_lock)
234 * @param format The format string
235 * @param ... Additional arguments
237 #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)
240 * print error message
244 #define al_err(...) do { if (AL_DBG_LEVEL >= AL_DBG_LEVEL_ERR) { AL_DBG_LOCK(); printf(__VA_ARGS__); AL_DBG_UNLOCK(); } } while(0)
247 * print warning message
251 #define al_warn(...) do { if (AL_DBG_LEVEL >= AL_DBG_LEVEL_WARN) { AL_DBG_LOCK(); printf(__VA_ARGS__); AL_DBG_UNLOCK(); } } while(0)
258 #define al_info(...) do { if (AL_DBG_LEVEL >= AL_DBG_LEVEL_INFO) { AL_DBG_LOCK(); printf(__VA_ARGS__); AL_DBG_UNLOCK(); } } while(0)
261 * print debug message
265 #define al_dbg(...) do { if (AL_DBG_LEVEL >= AL_DBG_LEVEL_DBG) { AL_DBG_LOCK(); printf(__VA_ARGS__); AL_DBG_UNLOCK(); } } while(0)
272 #define al_assert(COND) \
276 "%s:%d:%s: Assertion failed! (%s)\n", \
277 __FILE__, __LINE__, __func__, #COND); \
281 * Make sure data will be visible by other masters (other CPUS and DMA).
282 * usually this is achieved by the ARM DMB instruction.
284 static void al_data_memory_barrier(void);
287 * Make sure data will be visible by DMA masters, no restriction for other cpus
290 al_data_memory_barrier(void)
296 * Make sure data will be visible in order by other cpus masters.
299 al_smp_data_memory_barrier(void)
305 * Make sure write data will be visible in order by other cpus masters.
308 al_local_data_memory_barrier(void)
314 * al_udelay - micro sec delay
316 #define al_udelay(u) DELAY(u)
319 * al_msleep - mili sec delay
321 #define al_msleep(m) DELAY((m) * 1000)
324 * swap half word to little endian
326 * @param x 16 bit value
328 * @return the value in little endian
330 #define swap16_to_le(x) htole16(x)
332 * swap word to little endian
334 * @param x 32 bit value
336 * @return the value in little endian
338 #define swap32_to_le(x) htole32(x)
341 * swap 8 bytes to little endian
343 * @param x 64 bit value
345 * @return the value in little endian
347 #define swap64_to_le(x) htole64(x)
350 * swap half word from little endian
352 * @param x 16 bit value
354 * @return the value in the cpu endianess
356 #define swap16_from_le(x) le16toh(x)
359 * swap word from little endian
361 * @param x 32 bit value
363 * @return the value in the cpu endianess
365 #define swap32_from_le(x) le32toh(x)
368 * swap 8 bytes from little endian
370 * @param x 64 bit value
372 * @return the value in the cpu endianess
374 #define swap64_from_le(x) le64toh(x)
379 * @param p memory pointer
380 * @param val value for setting
381 * @param cnt number of bytes to set
383 #define al_memset(p, val, cnt) memset(p, val, cnt)
388 * @param p1 memory pointer
389 * @param p2 memory pointer
390 * @param cnt number of bytes to copy
392 #define al_memcpy(p1, p2, cnt) memcpy(p1, p2, cnt)
397 * @param p1 memory pointer
398 * @param p2 memory pointer
399 * @param cnt number of bytes to compare
401 #define al_memcmp(p1, p2, cnt) memcmp(p1, p2, cnt)
406 * @param s1 string pointer
407 * @param s2 string pointer
409 #define al_strcmp(s1, s2) strcmp(s1, s2)
411 #define al_get_cpu_id() 0
418 /** @} end of Platform Services API group */
419 #endif /* __PLAT_SERVICES_H__ */