1#pragma once
2
3#include <uacpi/internal/types.h>
4#include <uacpi/internal/helpers.h>
5#include <uacpi/platform/libc.h>
6#include <uacpi/kernel_api.h>
7
8#ifndef uacpi_memcpy
9void *uacpi_memcpy(void *dest, const void *src, uacpi_size count);
10#endif
11
12#ifndef uacpi_memmove
13void *uacpi_memmove(void *dest, const void *src, uacpi_size count);
14#endif
15
16#ifndef uacpi_memset
17void *uacpi_memset(void *dest, uacpi_i32 ch, uacpi_size count);
18#endif
19
20#ifndef uacpi_memcmp
21uacpi_i32 uacpi_memcmp(const void *lhs, const void *rhs, uacpi_size count);
22#endif
23
24#ifndef uacpi_strlen
25uacpi_size uacpi_strlen(const uacpi_char *str);
26#endif
27
28#ifndef uacpi_strlen
29uacpi_size uacpi_strnlen(const uacpi_char *str, uacpi_size max);
30#endif
31
32#ifndef uacpi_strcmp
33uacpi_i32 uacpi_strcmp(const uacpi_char *lhs, const uacpi_char *rhs);
34#endif
35
36#ifndef uacpi_snprintf
37UACPI_PRINTF_DECL(3, 4)
38uacpi_i32 uacpi_snprintf(
39 uacpi_char *buffer, uacpi_size capacity, const uacpi_char *fmt, ...
40);
41#endif
42
43#ifndef uacpi_vsnprintf
44uacpi_i32 uacpi_vsnprintf(
45 uacpi_char *buffer, uacpi_size capacity, const uacpi_char *fmt,
46 uacpi_va_list vlist
47);
48#endif
49
50#ifdef UACPI_SIZED_FREES
51#define uacpi_free(mem, size) uacpi_kernel_free(mem, size)
52#else
53#define uacpi_free(mem, _) uacpi_kernel_free(mem)
54#endif
55
56#define uacpi_memzero(ptr, size) uacpi_memset(ptr, 0, size)
57
58#define UACPI_COMPARE(x, y, op) ((x) op (y) ? (x) : (y))
59#define UACPI_MIN(x, y) UACPI_COMPARE(x, y, <)
60#define UACPI_MAX(x, y) UACPI_COMPARE(x, y, >)
61
62#define UACPI_ALIGN_UP_MASK(x, mask) (((x) + (mask)) & ~(mask))
63#define UACPI_ALIGN_UP(x, val, type) UACPI_ALIGN_UP_MASK(x, (type)(val) - 1)
64
65#define UACPI_ALIGN_DOWN_MASK(x, mask) ((x) & ~(mask))
66#define UACPI_ALIGN_DOWN(x, val, type) UACPI_ALIGN_DOWN_MASK(x, (type)(val) - 1)
67
68#define UACPI_IS_ALIGNED_MASK(x, mask) (((x) & (mask)) == 0)
69#define UACPI_IS_ALIGNED(x, val, type) UACPI_IS_ALIGNED_MASK(x, (type)(val) - 1)
70
71#define UACPI_IS_POWER_OF_TWO(x, type) UACPI_IS_ALIGNED(x, x, type)
72
73void uacpi_memcpy_zerout(void *dst, const void *src,
74 uacpi_size dst_size, uacpi_size src_size);
75
76// Returns the one-based bit location of LSb or 0
77uacpi_u8 uacpi_bit_scan_forward(uacpi_u64);
78
79// Returns the one-based bit location of MSb or 0
80uacpi_u8 uacpi_bit_scan_backward(uacpi_u64);
81
82uacpi_u8 uacpi_popcount(uacpi_u64);
83
84#ifdef UACPI_TRACE_MUTEXES
85#define UACPI_TRACE_MUTEX_ACQUISITION(mtx) \
86 uacpi_trace("mutex %p acquired at %s:%d\n", mtx, __FILE__, __LINE__)
87
88#define UACPI_TRACE_MUTEX_ACQUISITION_TIMEOUT(mtx, timeout) \
89 uacpi_trace("mutex %p acquisition timed out after %dms at %s:%d\n", \
90 mtx, (uacpi_u16)timeout, __FILE__, __LINE__)
91
92#define UACPI_TRACE_MUTEX_RELEASE(mtx) \
93 uacpi_trace("mutex %p released at %s:%d\n", mtx, __FILE__, __LINE__)
94#else
95#define UACPI_TRACE_MUTEX_ACQUISITION(mtx)
96#define UACPI_TRACE_MUTEX_ACQUISITION_TIMEOUT(mtx, timeout)
97#define UACPI_TRACE_MUTEX_RELEASE(mtx)
98#endif
99
100#define UACPI_MUTEX_ACQUIRE(mtx) \
101 do { \
102 if (uacpi_unlikely(!uacpi_kernel_acquire_mutex(mtx, 0xFFFF))) { \
103 uacpi_error( \
104 "%s: unable to acquire mutex %p with an infinite timeout\n", \
105 __FUNCTION__, mtx \
106 ); \
107 return UACPI_STATUS_INTERNAL_ERROR; \
108 } \
109 UACPI_TRACE_MUTEX_ACQUISITION(mtx); \
110 } while (0)
111
112#define UACPI_MUTEX_ACQUIRE_WITH_TIMEOUT(mtx, timeout, ret) \
113 do { \
114 ret = uacpi_kernel_acquire_mutex(mtx, timeout); \
115 if (ret) { \
116 UACPI_TRACE_MUTEX_ACQUISITION(mtx); \
117 } else { \
118 UACPI_TRACE_MUTEX_ACQUISITION_TIMEOUT(mtx, timeout); \
119 } \
120 } while (0)
121
122#define UACPI_MUTEX_RELEASE(mtx) do { \
123 uacpi_kernel_release_mutex(mtx); \
124 UACPI_TRACE_MUTEX_RELEASE(mtx); \
125 } while (0)
126