| 2 |
theseven |
1 |
//
|
|
|
2 |
//
|
|
|
3 |
// Copyright 2010 TheSeven
|
|
|
4 |
//
|
|
|
5 |
//
|
|
|
6 |
// This file is part of emBIOS.
|
|
|
7 |
//
|
|
|
8 |
// emBIOS is free software: you can redistribute it and/or
|
|
|
9 |
// modify it under the terms of the GNU General Public License as
|
|
|
10 |
// published by the Free Software Foundation, either version 2 of the
|
|
|
11 |
// License, or (at your option) any later version.
|
|
|
12 |
//
|
|
|
13 |
// emBIOS is distributed in the hope that it will be useful,
|
|
|
14 |
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
15 |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
16 |
// See the GNU General Public License for more details.
|
|
|
17 |
//
|
|
|
18 |
// You should have received a copy of the GNU General Public License along
|
|
|
19 |
// with emBIOS. If not, see <http://www.gnu.org/licenses/>.
|
|
|
20 |
//
|
|
|
21 |
//
|
|
|
22 |
|
|
|
23 |
|
|
|
24 |
#ifndef __UTIL_H__
|
|
|
25 |
#define __UTIL_H__
|
|
|
26 |
|
|
|
27 |
|
|
|
28 |
#include "global.h"
|
|
|
29 |
|
|
|
30 |
|
| 58 |
theseven |
31 |
#ifndef NULL
|
|
|
32 |
#define NULL ((void*)0)
|
| 2 |
theseven |
33 |
#endif
|
| 58 |
theseven |
34 |
|
|
|
35 |
#ifndef MIN
|
|
|
36 |
#define MIN(a, b) (((a)<(b))?(a):(b))
|
|
|
37 |
#endif
|
|
|
38 |
|
|
|
39 |
#ifndef MAX
|
|
|
40 |
#define MAX(a, b) (((a)>(b))?(a):(b))
|
|
|
41 |
#endif
|
|
|
42 |
|
|
|
43 |
/* return number of elements in array a */
|
|
|
44 |
#define ARRAYLEN(a) (sizeof(a)/sizeof((a)[0]))
|
|
|
45 |
|
|
|
46 |
/* return p incremented by specified number of bytes */
|
|
|
47 |
#define SKIPBYTES(p, count) ((typeof (p))((char *)(p) + (count)))
|
|
|
48 |
|
|
|
49 |
#define P2_M1(p2) ((1 << (p2))-1)
|
|
|
50 |
|
|
|
51 |
/* align up or down to nearest 2^p2 */
|
|
|
52 |
#define ALIGN_DOWN_P2(n, p2) ((n) & ~P2_M1(p2))
|
|
|
53 |
#define ALIGN_UP_P2(n, p2) ALIGN_DOWN_P2((n) + P2_M1(p2),p2)
|
|
|
54 |
|
|
|
55 |
/* align up or down to nearest integer multiple of a */
|
|
|
56 |
#define ALIGN_DOWN(n, a) ((n)/(a)*(a))
|
|
|
57 |
#define ALIGN_UP(n, a) ALIGN_DOWN((n)+((a)-1),a)
|
|
|
58 |
|
|
|
59 |
/* align start and end of buffer to nearest integer multiple of a */
|
|
|
60 |
#define ALIGN_BUFFER(ptr,len,align) \
|
|
|
61 |
{\
|
|
|
62 |
uintptr_t tmp_ptr1 = (uintptr_t)ptr; \
|
|
|
63 |
uintptr_t tmp_ptr2 = tmp_ptr1 + len;\
|
|
|
64 |
tmp_ptr1 = ALIGN_UP(tmp_ptr1,align); \
|
|
|
65 |
tmp_ptr2 = ALIGN_DOWN(tmp_ptr2,align); \
|
|
|
66 |
len = tmp_ptr2 - tmp_ptr1; \
|
|
|
67 |
ptr = (typeof(ptr))tmp_ptr1; \
|
|
|
68 |
}
|
|
|
69 |
|
|
|
70 |
|
|
|
71 |
/* live endianness conversion */
|
|
|
72 |
#ifdef LITTLE_ENDIAN
|
|
|
73 |
#define letoh16(x) (x)
|
|
|
74 |
#define letoh32(x) (x)
|
|
|
75 |
#define htole16(x) (x)
|
|
|
76 |
#define htole32(x) (x)
|
|
|
77 |
#define betoh16(x) swap16(x)
|
|
|
78 |
#define betoh32(x) swap32(x)
|
|
|
79 |
#define htobe16(x) swap16(x)
|
|
|
80 |
#define htobe32(x) swap32(x)
|
|
|
81 |
#define swap_odd_even_be32(x) (x)
|
|
|
82 |
#define swap_odd_even_le32(x) swap_odd_even32(x)
|
|
|
83 |
#else
|
|
|
84 |
#define letoh16(x) swap16(x)
|
|
|
85 |
#define letoh32(x) swap32(x)
|
|
|
86 |
#define htole16(x) swap16(x)
|
|
|
87 |
#define htole32(x) swap32(x)
|
|
|
88 |
#define betoh16(x) (x)
|
|
|
89 |
#define betoh32(x) (x)
|
|
|
90 |
#define htobe16(x) (x)
|
|
|
91 |
#define htobe32(x) (x)
|
|
|
92 |
#define swap_odd_even_be32(x) swap_odd_even32(x)
|
|
|
93 |
#define swap_odd_even_le32(x) (x)
|
|
|
94 |
#endif
|
|
|
95 |
|
|
|
96 |
|
|
|
97 |
/* static endianness conversion */
|
|
|
98 |
#define SWAP_16(x) ((typeof(x))(unsigned short)(((unsigned short)(x) >> 8) | \
|
|
|
99 |
((unsigned short)(x) << 8)))
|
|
|
100 |
|
|
|
101 |
#define SWAP_32(x) ((typeof(x))(unsigned long)( ((unsigned long)(x) >> 24) | \
|
|
|
102 |
(((unsigned long)(x) & 0xff0000ul) >> 8) | \
|
|
|
103 |
(((unsigned long)(x) & 0xff00ul) << 8) | \
|
|
|
104 |
((unsigned long)(x) << 24)))
|
|
|
105 |
|
|
|
106 |
#ifdef RLITTLE_ENDIAN
|
|
|
107 |
#define LE_TO_H16(x) (x)
|
|
|
108 |
#define LE_TO_H32(x) (x)
|
|
|
109 |
#define H_TO_LE16(x) (x)
|
|
|
110 |
#define H_TO_LE32(x) (x)
|
|
|
111 |
#define BE_TO_H16(x) SWAP_16(x)
|
|
|
112 |
#define BE_TO_H32(x) SWAP_32(x)
|
|
|
113 |
#define H_TO_BE16(x) SWAP_16(x)
|
|
|
114 |
#define H_TO_BE32(x) SWAP_32(x)
|
|
|
115 |
#else
|
|
|
116 |
#define LE_TO_H16(x) SWAP_16(x)
|
|
|
117 |
#define LE_TO_H32(x) SWAP_32(x)
|
|
|
118 |
#define H_TO_LE16(x) SWAP_16(x)
|
|
|
119 |
#define H_TO_LE32(x) SWAP_32(x)
|
|
|
120 |
#define BE_TO_H16(x) (x)
|
|
|
121 |
#define BE_TO_H32(x) (x)
|
|
|
122 |
#define H_TO_BE16(x) (x)
|
|
|
123 |
#define H_TO_BE32(x) (x)
|
|
|
124 |
#endif
|
|
|
125 |
|
|
|
126 |
/* Get the byte offset of a type's member */
|
|
|
127 |
#define OFFSETOF(type, membername) ((off_t)&((type *)0)->membername)
|
|
|
128 |
|
|
|
129 |
/* Get the type pointer from one of its members */
|
|
|
130 |
#define TYPE_FROM_MEMBER(type, memberptr, membername) \
|
|
|
131 |
((type *)((intptr_t)(memberptr) - OFFSETOF(type, membername)))
|
|
|
132 |
|
|
|
133 |
static inline uint16_t swap16(uint16_t value)
|
|
|
134 |
/*
|
|
|
135 |
result[15..8] = value[ 7..0];
|
|
|
136 |
result[ 7..0] = value[15..8];
|
|
|
137 |
*/
|
|
|
138 |
{
|
|
|
139 |
return (value >> 8) | (value << 8);
|
|
|
140 |
}
|
|
|
141 |
|
|
|
142 |
static inline uint32_t swap32(uint32_t value)
|
|
|
143 |
/*
|
|
|
144 |
result[31..24] = value[ 7.. 0];
|
|
|
145 |
result[23..16] = value[15.. 8];
|
|
|
146 |
result[15.. 8] = value[23..16];
|
|
|
147 |
result[ 7.. 0] = value[31..24];
|
|
|
148 |
*/
|
|
|
149 |
{
|
|
|
150 |
uint32_t hi = swap16(value >> 16);
|
|
|
151 |
uint32_t lo = swap16(value & 0xffff);
|
|
|
152 |
return (lo << 16) | hi;
|
|
|
153 |
}
|
|
|
154 |
|
|
|
155 |
static inline uint32_t swap_odd_even32(uint32_t value)
|
|
|
156 |
{
|
|
|
157 |
/*
|
|
|
158 |
result[31..24],[15.. 8] = value[23..16],[ 7.. 0]
|
|
|
159 |
result[23..16],[ 7.. 0] = value[31..24],[15.. 8]
|
|
|
160 |
*/
|
|
|
161 |
uint32_t t = value & 0xff00ff00;
|
|
|
162 |
return (t >> 8) | ((t ^ value) << 8);
|
|
|
163 |
}
|
|
|
164 |
|
|
|
165 |
#ifndef BIT_N
|
|
|
166 |
#define BIT_N(n) (1U << (n))
|
|
|
167 |
#endif
|
|
|
168 |
|
|
|
169 |
#ifndef CACHEALIGN_SIZE /* could be elsewhere for a particular reason */
|
|
|
170 |
#ifdef CACHEALIGN_BITS
|
|
|
171 |
/* 2^CACHEALIGN_BITS = the byte size */
|
|
|
172 |
#define CACHEALIGN_SIZE (1u << CACHEALIGN_BITS)
|
|
|
173 |
#else
|
|
|
174 |
#define CACHEALIGN_SIZE 16 /* FIXME */
|
|
|
175 |
#endif
|
|
|
176 |
#endif /* CACHEALIGN_SIZE */
|
|
|
177 |
|
|
|
178 |
#define CACHEALIGN_ATTR __attribute__((aligned(CACHEALIGN_SIZE)))
|
|
|
179 |
/* Aligns x up to a CACHEALIGN_SIZE boundary */
|
|
|
180 |
#define CACHEALIGN_UP(x) \
|
|
|
181 |
((typeof (x))ALIGN_UP_P2((uintptr_t)(x), CACHEALIGN_BITS))
|
|
|
182 |
/* Aligns x down to a CACHEALIGN_SIZE boundary */
|
|
|
183 |
#define CACHEALIGN_DOWN(x) \
|
|
|
184 |
((typeof (x))ALIGN_DOWN_P2((uintptr_t)(x), CACHEALIGN_BITS))
|
|
|
185 |
/* Aligns at least to the greater of size x or CACHEALIGN_SIZE */
|
|
|
186 |
#define CACHEALIGN_AT_LEAST_ATTR(x) \
|
|
|
187 |
__attribute__((aligned(CACHEALIGN_UP(x))))
|
|
|
188 |
/* Aligns a buffer pointer and size to proper boundaries */
|
|
|
189 |
#define CACHEALIGN_BUFFER(start, size) \
|
|
|
190 |
ALIGN_BUFFER((start), (size), CACHEALIGN_SIZE)
|
|
|
191 |
|
|
|
192 |
/* Double-cast to avoid 'dereferencing type-punned pointer will
|
|
|
193 |
* break strict aliasing rules' B.S. */
|
|
|
194 |
#define PUN_PTR(type, p) ((type)(intptr_t)(p))
|
|
|
195 |
|
|
|
196 |
|
|
|
197 |
#endif
|