5562N/A/*
5562N/A * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
5562N/A */
5562N/A
5562N/A/*
7118N/A * Redistribution and use in source and binary forms, with or without
7118N/A * modification, are permitted provided that the following conditions are met:
5562N/A *
5562N/A * 1. Redistributions of source code must retain the above copyright notice,
5562N/A * this list of conditions and the following disclaimer.
5562N/A *
5562N/A * 2. Redistributions in binary form must reproduce the above copyright notice,
5562N/A * this list of conditions and the following disclaimer in the documentation
5562N/A * and/or other materials provided with the distribution.
5562N/A *
5562N/A * 3. Neither the name of the copyright holder nor the names of its contributors
7118N/A * may be used to endorse or promote products derived from this software
7118N/A * without specific prior written permission.
5562N/A *
5562N/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
7118N/A * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
7118N/A * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
7118N/A * ARE DISCLAIMED.
7118N/A * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
7118N/A * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
7118N/A * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
7118N/A * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
7118N/A * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
7118N/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
7118N/A * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5562N/A */
5562N/A
5562N/A#ifndef _PSIF_ENDIAN_H
5562N/A#define _PSIF_ENDIAN_H
5562N/A
5562N/A#if defined(__arm__)
5562N/A#undef HOST_BIG_ENDIAN
5562N/A#define HOST_LITTLE_ENDIAN
5562N/A#else /* __arm__ */
5562N/A#if defined(__KERNEL__)
5562N/A# if defined(__BIG_ENDIAN) || defined(_BIG_ENDIAN)
5562N/A# define HOST_BIG_ENDIAN
5562N/A# elif defined(__LITTLE_ENDIAN) || defined(_LITTLE_ENDIAN)
5562N/A# define HOST_LITTLE_ENDIAN
5562N/A# else
5562N/A# error "could not determine byte order"
5562N/A# endif
5562N/A#else /* defined(__KERNEL__) */
5562N/A# include "os_header.h"
5562N/A# if defined(__BYTE_ORDER)
5562N/A# if __BYTE_ORDER == __BIG_ENDIAN
5562N/A# define HOST_BIG_ENDIAN
5562N/A# elif __BYTE_ORDER == __LITTLE_ENDIAN
5562N/A# define HOST_LITTLE_ENDIAN
5562N/A# else
5562N/A# error "could not determine byte order"
5562N/A# endif
5562N/A# else /* defined(__BYTE_ORDER) */
5562N/A# error "could not determine byte order"
5562N/A# endif
5562N/A#endif /* defined(__KERNEL__) */
5562N/A#endif
5562N/A
7118N/A#if !defined(__KERNEL__)
5562N/A
5562N/A#if !defined(__arm__)
5562N/A#include <stdlib.h>
5562N/A#endif /* !__arm__ */
5562N/A
5562N/A#if defined(HOST_BIG_ENDIAN)
5562N/A
7118N/A#define copy_convert(dest, src, n) { memcpy((void *)dest, (void const *)(src), n); wmb(); }
7118N/A#define copy_convert_to_hw(dest, src, n) copy_convert(dest, src, n)
7118N/A#define copy_convert_to_sw(dest, src, n) copy_convert(dest, src, n)
5562N/A
5562N/A#else /* HOST_LITTLE_ENDIAN */
5562N/A
5562N/A#if defined(__arm__)
5562N/A#include <stdint.h>
5562N/A#include "epsfw_misc.h"
5562N/A#define htobe64(x) eps_htobe64(x)
7118N/A#define htobe32(x) eps_htobe32(x)
7118N/A#define htobe16(x) eps_htobe16(x)
7118N/A#define be64toh(x) eps_be64toh(x)
7118N/A#define be32toh(x) eps_be32toh(x)
7118N/A#define be16toh(x) eps_be16toh(x)
7118N/A
7118N/A#define cpu_to_be64(x) htobe64(x)
7118N/A#define cpu_to_be32(x) htobe32(x)
7118N/A#define cpu_to_be16(x) htobe16(x)
7118N/A#define be64_to_cpu(x) be64toh(x)
7118N/A#define be32_to_cpu(x) be32toh(x)
7118N/A#define be16_to_cpu(x) be16toh(x)
7118N/A
5562N/A#define u64 uint64_t
5562N/A
7118N/Astatic inline void __DSB(void)
7118N/A{
7118N/A/* __dsb() doesn't serve as sequence point in armcc so adding
7118N/A * __schedule_barrier() around it to force the compiler to see it as a
7118N/A * sequence point
7118N/A */
7118N/A__schedule_barrier();
7118N/A__dsb(0xf);
7118N/A__schedule_barrier();
5562N/A}
7118N/A#define wmb() __DSB()
5562N/A
5562N/A/*
5562N/A * Alternatively, use this one as barrier?
7118N/A * #define wmb() __memory_changed()
5562N/A */
5562N/A#endif /* __arm__ */
5562N/A
7118N/A/*
7118N/A * assertions:
7118N/A * - dest and src are 8 bytes aligned
7118N/A * - n is an integer multiple of 8
7118N/A */
5562N/Astatic inline void _copy_convert(void *dest, void const *src, size_t n)
5562N/A{
7118N/A int i, words = n / 8;
5562N/A volatile u64 *dp = (volatile u64 *) dest;
5562N/A const volatile u64 *sp = (const volatile u64 *) src;
7118N/A
5562N/A for (i = 0; i < words; i++) {
5562N/A *dp++ = htobe64(*sp);
5562N/A sp++;
5562N/A }
5562N/A wmb();
5562N/A}
5562N/A
7118N/A/*
7118N/A * assertions:
7118N/A * - dest and src are 8 bytes aligned
7118N/A * - n is an integer multiple of 8
7118N/A */
5562N/Astatic inline void _copy_convert_to_hw(volatile void *dest, void const *src, size_t n)
5562N/A{
7118N/A int i, words = n / 8;
5562N/A volatile u64 *dp = (volatile u64 *) dest;
5562N/A const u64 *sp = (const u64 *) src;
7118N/A
5562N/A for (i = 0; i < words; i++) {
5562N/A *dp++ = htobe64(*sp);
5562N/A sp++;
5562N/A }
5562N/A wmb();
5562N/A}
5562N/A
7118N/A/*
7118N/A * assertions:
7118N/A * - dest and src are 8 bytes aligned
7118N/A * - n is an integer multiple of 8
7118N/A */
5562N/Astatic inline void _copy_convert_to_sw(void *dest, volatile void const *src, size_t n)
5562N/A{
7118N/A int i, words = n / 8;
5562N/A u64 *dp = (u64 *) dest;
5562N/A const volatile u64 *sp = (const volatile u64 *) src;
7118N/A
5562N/A for (i = 0; i < words; i++) {
5562N/A *dp++ = htobe64(*sp);
5562N/A sp++;
5562N/A }
5562N/A wmb();
5562N/A}
5562N/A
7118N/A#define copy_convert(dest, src, n) _copy_convert(dest, src, n)
7118N/A#define copy_convert_to_hw(dest, src, n) _copy_convert_to_hw(dest, src, n)
7118N/A#define copy_convert_to_sw(dest, src, n) _copy_convert_to_sw(dest, src, n)
5562N/A
5562N/A#endif /* HOST_ENDIAN */
5562N/A#endif /* !__KERNEL__ */
5562N/A#endif /* _PSIF_ENDIAN_H */