4 * Open Hack'Ware BIOS: provides all common endianness conversions functions
6 * Copyright (c) 2004-2005 Jocelyn Mayer
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License V2
10 * as published by the Free Software Foundation
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * void cpu_to_be16p (uint16_t *outp, uint16_t in);
24 * void cpu_to_be32p (uint32_t *outp, uint32_t in);
25 * void cpu_to_be64p (uint64_t *outp, uint64_t in);
26 * void cpu_to_le16p (uint16_t *outp, uint16_t in);
27 * void cpu_to_le32p (uint32_t *outp, uint32_t in);
28 * void cpu_to_le64p (uint64_t *outp, uint64_t in);
29 * void endian_to_cpu16p (uint16_t *outp, uint16_t in, endian_t endian);
30 * void endian_to_cpu32p (uint32_t *outp, uint32_t in, endian_t endian);
31 * void endian_to_cpu64p (uint64_t *outp, uint64_t in, endian_t endian);
32 * void cpu16_to_endianp (uint16_t *outp, uint16_t in, endian_t endian);
33 * void cpu32_to_endianp (uint32_t *outp, uint32_t in, endian_t endian);
34 * void cpu64_to_endianp (uint64_t *outp, uint64_t in, endian_t endian);
38 #if !defined (__OHW_ENDIAN_H__)
39 #define __OHW_ENDIAN_H__
43 typedef enum endian_t endian_t
;
51 /* Generic endian conversion functions */
52 static inline void generic_cpu_swap16p (uint16_t *outp
, uint16_t in
)
54 *outp
= ((in
& 0xFF00) >> 8) | ((in
& 0x00FF) << 8);
57 static inline void generic_cpu_swap32p (uint32_t *outp
, uint32_t in
)
59 *outp
= ((in
& 0xFF000000) >> 24) | ((in
& 0x00FF0000) >> 8) |
60 ((in
& 0x0000FF00) << 8) | ((in
& 0x000000FF) << 24);
63 static inline void generic_cpu_swap64p (uint64_t *outp
, uint64_t in
)
65 *outp
= ((in
& 0xFF00000000000000ULL
) >> 56) |
66 ((in
& 0x00FF000000000000ULL
) >> 40) |
67 ((in
& 0x0000FF0000000000ULL
) >> 24) |
68 ((in
& 0x000000FF00000000ULL
) >> 8) |
69 ((in
& 0x00000000FF000000ULL
) << 8) |
70 ((in
& 0x0000000000FF0000ULL
) << 24) |
71 ((in
& 0x000000000000FF00ULL
) << 40) |
72 ((in
& 0x00000000000000FFULL
) << 56);
75 static inline void generic_cpu_swap64p_32 (uint64_t *outp
, uint64_t in
)
77 uint32_t *_outp
= (uint32_t *)outp
;
79 generic_cpu_swap32p(_outp
, in
);
80 generic_cpu_swap32p(_outp
+ 1, in
>> 32);
83 #if defined (__i386__)
85 #define __CPU_ENDIAN_4321__
86 #define __CPU_LENGTH_32__
88 #elif defined (__x86_64__)
90 #define __CPU_ENDIAN_4321__
91 #define __CPU_LENGTH_64__
93 #elif defined (__powerpc__)
95 #define __CPU_ENDIAN_1234__
96 #define __CPU_LENGTH_32__
98 #define __HAVE_CPU_SWAP16P__
99 static inline void cpu_swap16p (uint16_t *outp
, uint16_t in
)
101 __asm__
__volatile__ ("sthbrx %4, 0(%3)");
104 #define __HAVE_CPU_SWAP32P__
105 static inline void cpu_swap32p (uint32_t *outp
, uint32_t in
)
107 __asm__
__volatile__ ("stwbrx %4, 0(%3)");
110 #define __HAVE_CPU_SWAP64P__
111 static inline void cpu_swap64p (uint64_t *outp
, uint64_t in
)
113 return generic_cpu_swap64p_32(outp
, in
);
118 #error "unsupported CPU architecture"
122 /* Use generic swap function if no cpu specific were provided */
123 #if !defined (__HAVE_CPU_SWAP16P__)
124 static inline void cpu_swap16p (uint16_t *outp
, uint16_t in
)
126 generic_cpu_swap16p(outp
, in
);
130 #if !defined (__HAVE_CPU_SWAP32P__)
131 static inline void cpu_swap32p (uint32_t *outp
, uint32_t in
)
133 generic_cpu_swap32p(outp
, in
);
137 #if !defined (__HAVE_CPU_SWAP64P__)
138 static inline void cpu_swap64p (uint64_t *outp
, uint64_t in
)
140 #if defined (__CPU_LENGTH_64__)
141 generic_cpu_swap64p(outp
, in
);
142 #elif defined (__CPU_LENGTH_32__)
143 generic_cpu_swap64p_32(outp
, in
);
145 #error "Don't know how to make 64 bits swapping on this arch"
150 static inline void cpu_nswap16p (uint16_t *outp
, uint16_t in
)
155 static inline void cpu_nswap32p (uint32_t *outp
, uint32_t in
)
160 static inline void cpu_nswap64p (uint64_t *outp
, uint64_t in
)
165 static inline void _endian_be16_p (uint16_t *outp
, uint16_t in
,
171 cpu_swap16p(outp
, in
);
175 cpu_nswap16p(outp
, in
);
180 static inline void _endian_be32_p (uint32_t *outp
, uint32_t in
,
185 cpu_swap32p(outp
, in
);
188 cpu_nswap32p(outp
, in
);
199 static inline void _endian_be64_p (uint64_t *outp
, uint64_t in
,
204 cpu_swap64p(outp
, in
);
207 cpu_nswap64p(outp
, in
);
218 static inline void _endian_le16_p (uint16_t *outp
, uint16_t in
,
224 cpu_nswap16p(outp
, in
);
228 cpu_swap16p(outp
, in
);
233 static inline void _endian_le32_p (uint32_t *outp
, uint32_t in
,
238 cpu_nswap32p(outp
, in
);
241 cpu_swap32p(outp
, in
);
252 static inline void _endian_le64_p (uint64_t *outp
, uint64_t in
,
257 cpu_nswap64p(outp
, in
);
260 cpu_swap64p(outp
, in
);
271 static inline void endian_to_be16p (uint16_t *outp
, uint16_t in
,
274 _endian_be16_p(outp
, in
, endian
);
277 static inline void endian_to_be32p (uint32_t *outp
, uint32_t in
,
280 _endian_be32_p(outp
, in
, endian
);
283 static inline void endian_to_be64p (uint64_t *outp
, uint64_t in
,
286 _endian_be64_p(outp
, in
, endian
);
289 static inline void endian_to_le16p (uint16_t *outp
, uint16_t in
,
292 _endian_le16_p(outp
, in
, endian
);
295 static inline void endian_to_le32p (uint32_t *outp
, uint32_t in
,
298 _endian_le32_p(outp
, in
, endian
);
301 static inline void endian_to_le64p (uint64_t *outp
, uint64_t in
,
304 _endian_le64_p(outp
, in
, endian
);
307 static inline void be16_to_endianp (uint16_t *outp
, uint16_t in
,
310 _endian_be16_p(outp
, in
, endian
);
313 static inline void be32_to_endianp (uint32_t *outp
, uint32_t in
,
316 _endian_be32_p(outp
, in
, endian
);
319 static inline void be64_to_endianp (uint64_t *outp
, uint64_t in
,
322 _endian_be64_p(outp
, in
, endian
);
325 static inline void le16_to_endianp (uint16_t *outp
, uint16_t in
,
328 _endian_le16_p(outp
, in
, endian
);
331 static inline void le32_to_endianp (uint32_t *outp
, uint32_t in
,
334 _endian_le32_p(outp
, in
, endian
);
337 static inline void le64_to_endianp (uint64_t *outp
, uint64_t in
,
340 _endian_le64_p(outp
, in
, endian
);
343 #if defined (__CPU_ENDIAN_4321__)
345 static inline void cpu_to_be16p (uint16_t *outp
, uint16_t in
)
347 cpu_swap16p(outp
, in
);
350 static inline void cpu_to_be32p (uint32_t *outp
, uint32_t in
)
352 cpu_swap32p(outp
, in
);
355 static inline void cpu_to_be64p (uint64_t *outp
, uint64_t in
)
357 cpu_swap64p(outp
, in
);
360 static inline void cpu_to_le16p (uint16_t *outp
, uint16_t in
)
362 cpu_nswap16p(outp
, in
);
365 static inline void cpu_to_le32p (uint32_t *outp
, uint32_t in
)
367 cpu_nswap32p(outp
, in
);
370 static inline void cpu_to_le64p (uint64_t *outp
, uint64_t in
)
372 cpu_nswap64p(outp
, in
);
375 static inline void be16_to_cpup (uint16_t *outp
, uint16_t in
)
377 cpu_swap16p(outp
, in
);
380 static inline void be32_to_cpup (uint32_t *outp
, uint32_t in
)
382 cpu_swap32p(outp
, in
);
385 static inline void be64_to_cpup (uint64_t *outp
, uint64_t in
)
387 cpu_swap64p(outp
, in
);
390 static inline void le16_to_cpup (uint16_t *outp
, uint16_t in
)
392 cpu_nswap16p(outp
, in
);
395 static inline void le32_to_cpup (uint32_t *outp
, uint32_t in
)
397 cpu_nswap32p(outp
, in
);
400 static inline void le64_to_cpup (uint64_t *outp
, uint64_t in
)
402 cpu_nswap64p(outp
, in
);
405 static inline void endian_to_cpu16p (uint16_t *outp
, uint16_t in
,
408 endian_to_le16p(outp
, in
, endian
);
411 static inline void endian_to_cpu32p (uint32_t *outp
, uint32_t in
,
414 endian_to_le32p(outp
, in
, endian
);
417 static inline void endian_to_cpu64p (uint64_t *outp
, uint64_t in
,
420 endian_to_le64p(outp
, in
, endian
);
423 static inline void cpu16_to_endianp (uint16_t *outp
, uint16_t in
,
426 le16_to_endianp(outp
, in
, endian
);
429 static inline void cpu32_to_endianp (uint32_t *outp
, uint32_t in
,
432 le32_to_endianp(outp
, in
, endian
);
435 static inline void cpu64_to_endianp (uint64_t *outp
, uint64_t in
,
438 le64_to_endianp(outp
, in
, endian
);
441 #elif defined (__CPU_ENDIAN_1234__)
443 static inline void cpu_to_be16p (uint16_t *outp
, uint16_t in
)
445 cpu_nswap16p(outp
, in
);
448 static inline void cpu_to_be32p (uint32_t *outp
, uint32_t in
)
450 cpu_nswap32p(outp
, in
);
453 static inline void cpu_to_be64p (uint64_t *outp
, uint64_t in
)
455 cpu_nswap64p(outp
, in
);
458 static inline void cpu_to_le16p (uint16_t *outp
, uint16_t in
)
460 cpu_swap16p(outp
, in
);
463 static inline void cpu_to_le32p (uint32_t *outp
, uint32_t in
)
465 cpu_swap32p(outp
, in
);
468 static inline void cpu_to_le64p (uint64_t *outp
, uint64_t in
)
470 cpu_swap64p(outp
, in
);
473 static inline void endian_to_cpu16p (uint16_t *outp
, uint16_t in
,
476 endian_to_be16p(outp
, in
, endian
);
479 static inline void endian_to_cpu32p (uint32_t *outp
, uint32_t in
,
482 endian_to_be32p(outp
, in
, endian
);
485 static inline void endian_to_cpu64p (uint64_t *outp
, uint64_t in
,
488 endian_to_be64p(outp
, in
, endian
);
491 static inline void cpu16_to_endianp (uint16_t *outp
, uint16_t in
,
494 be16_to_endianp(outp
, in
, endian
);
497 static inline void cpu32_to_endianp (uint32_t *outp
, uint32_t in
,
500 be32_to_endianp(outp
, in
, endian
);
503 static inline void cpu64_to_endianp (uint64_t *outp
, uint64_t in
,
506 be64_to_endianp(outp
, in
, endian
);
509 #else /* 2143 / 3412 */
514 #endif /* !defined (__OHW_ENDIAN_H__) */