//
//   BSD LICENSE
//
//   Copyright(c) 2016 Mellanox Technologies, Ltd. All rights reserved.
//   All rights reserved.
//
//   Redistribution and use in source and binary forms, with or without
//   modification, are permitted provided that the following conditions
//   are met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in
//       the documentation and/or other materials provided with the
//       distribution.
//     * Neither the name of Mellanox Technologies nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
//   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
//   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
//   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
//   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
//   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
//   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
//   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
//   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
//   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
//   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
//   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//

#ifndef __PKA_MMIO_H__
#define __PKA_MMIO_H__


/// Macros for standard MMIO functions.

#ifdef __KERNEL__

#include <linux/types.h>
#include <linux/compiler.h>
#include <linux/io.h>

#define pka_mmio_read64(addr)       readq_relaxed(addr)
#define pka_mmio_write64(addr, val) writeq_relaxed((val), (addr))
#define pka_mmio_read(addr)         pka_mmio_read64(addr)
#define pka_mmio_write(addr, val)   pka_mmio_write64((addr), (val))

#else

#include <stdbool.h>
#include <features.h>
#include <stdint.h>

#ifndef __BIG_ENDIAN__

static inline __attribute__((always_inline)) uint64_t
__pka_mmio_read64(void* addr)
{
  return *((volatile uint64_t*)addr);
}

static inline __attribute__((always_inline)) void
__pka_mmio_write64(void* addr, uint64_t val)
{
  *((volatile uint64_t*)addr) = val;
}

#else

static inline __attribute__((always_inline)) uint64_t
__pka_mmio_read64(void* addr)
{
  return __builtin_bswap64(*((volatile uint64_t*)addr));
}

static inline __attribute__((always_inline)) void
__pka_mmio_write64(void* addr, uint64_t val)
{
  *((volatile uint64_t*)addr) = __builtin_bswap64(val);
}

#endif //__BIG_ENDIAN__

/* Default size is 64-bit. */
#define pka_mmio_read(addr)       __pka_mmio_read64(addr)
#define pka_mmio_write(addr, val) __pka_mmio_write64(addr, val)

#endif // __KERNEL__

#endif // __PKA_MMIO_H__
