2022-06-03 19:15:11 +00:00
|
|
|
/* SPDX-License-Identifier: BSD-3-Clause
|
2022-11-01 20:26:26 +00:00
|
|
|
* Copyright (C) 2015 Intel Corporation.
|
2015-12-10 23:56:12 +00:00
|
|
|
* All rights reserved.
|
|
|
|
*/
|
|
|
|
|
2016-04-29 18:04:33 +00:00
|
|
|
/** \file
|
|
|
|
* Memory-mapped I/O utility functions
|
|
|
|
*/
|
|
|
|
|
2015-12-10 23:56:12 +00:00
|
|
|
#ifndef SPDK_MMIO_H
|
|
|
|
#define SPDK_MMIO_H
|
|
|
|
|
2017-05-01 20:22:48 +00:00
|
|
|
#include "spdk/stdinc.h"
|
|
|
|
|
2016-02-12 14:52:35 +00:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
2017-02-07 00:37:18 +00:00
|
|
|
#include "spdk/barrier.h"
|
|
|
|
|
2015-12-10 23:56:12 +00:00
|
|
|
#ifdef __x86_64__
|
|
|
|
#define SPDK_MMIO_64BIT 1 /* Can do atomic 64-bit memory read/write (over PCIe) */
|
|
|
|
#else
|
|
|
|
#define SPDK_MMIO_64BIT 0
|
|
|
|
#endif
|
|
|
|
|
2017-10-10 23:41:18 +00:00
|
|
|
static inline uint8_t
|
|
|
|
spdk_mmio_read_1(const volatile uint8_t *addr)
|
|
|
|
{
|
|
|
|
spdk_compiler_barrier();
|
|
|
|
return *addr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
spdk_mmio_write_1(volatile uint8_t *addr, uint8_t val)
|
|
|
|
{
|
|
|
|
spdk_compiler_barrier();
|
|
|
|
*addr = val;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline uint16_t
|
|
|
|
spdk_mmio_read_2(const volatile uint16_t *addr)
|
|
|
|
{
|
|
|
|
spdk_compiler_barrier();
|
|
|
|
return *addr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
spdk_mmio_write_2(volatile uint16_t *addr, uint16_t val)
|
|
|
|
{
|
|
|
|
spdk_compiler_barrier();
|
|
|
|
*addr = val;
|
|
|
|
}
|
|
|
|
|
2015-12-10 23:56:12 +00:00
|
|
|
static inline uint32_t
|
|
|
|
spdk_mmio_read_4(const volatile uint32_t *addr)
|
|
|
|
{
|
2017-02-07 00:37:18 +00:00
|
|
|
spdk_compiler_barrier();
|
2015-12-10 23:56:12 +00:00
|
|
|
return *addr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
spdk_mmio_write_4(volatile uint32_t *addr, uint32_t val)
|
|
|
|
{
|
2017-02-07 00:37:18 +00:00
|
|
|
spdk_compiler_barrier();
|
2015-12-10 23:56:12 +00:00
|
|
|
*addr = val;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline uint64_t
|
|
|
|
spdk_mmio_read_8(volatile uint64_t *addr)
|
|
|
|
{
|
|
|
|
uint64_t val;
|
|
|
|
volatile uint32_t *addr32 = (volatile uint32_t *)addr;
|
|
|
|
|
2017-02-07 00:37:18 +00:00
|
|
|
spdk_compiler_barrier();
|
|
|
|
|
2015-12-10 23:56:12 +00:00
|
|
|
if (SPDK_MMIO_64BIT) {
|
|
|
|
val = *addr;
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* Read lower 4 bytes before upper 4 bytes.
|
|
|
|
* This particular order is required by I/OAT.
|
|
|
|
* If the other order is required, use a pair of spdk_mmio_read_4() calls.
|
|
|
|
*/
|
|
|
|
val = addr32[0];
|
|
|
|
val |= (uint64_t)addr32[1] << 32;
|
|
|
|
}
|
|
|
|
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
spdk_mmio_write_8(volatile uint64_t *addr, uint64_t val)
|
|
|
|
{
|
|
|
|
volatile uint32_t *addr32 = (volatile uint32_t *)addr;
|
|
|
|
|
2017-02-07 00:37:18 +00:00
|
|
|
spdk_compiler_barrier();
|
|
|
|
|
2015-12-10 23:56:12 +00:00
|
|
|
if (SPDK_MMIO_64BIT) {
|
|
|
|
*addr = val;
|
|
|
|
} else {
|
|
|
|
addr32[0] = (uint32_t)val;
|
|
|
|
addr32[1] = (uint32_t)(val >> 32);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-12 14:52:35 +00:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-12-10 23:56:12 +00:00
|
|
|
#endif
|