xref: /spdk/include/spdk/mmio.h (revision a6dbe3721eb3b5990707fc3e378c95e505dd8ab5)
1488570ebSJim Harris /*   SPDX-License-Identifier: BSD-3-Clause
2*a6dbe372Spaul luse  *   Copyright (C) 2015 Intel Corporation.
3460327eaSDaniel Verkamp  *   All rights reserved.
4460327eaSDaniel Verkamp  */
5460327eaSDaniel Verkamp 
68eafb654SDaniel Verkamp /** \file
78eafb654SDaniel Verkamp  * Memory-mapped I/O utility functions
88eafb654SDaniel Verkamp  */
98eafb654SDaniel Verkamp 
10460327eaSDaniel Verkamp #ifndef SPDK_MMIO_H
11460327eaSDaniel Verkamp #define SPDK_MMIO_H
12460327eaSDaniel Verkamp 
1345cab335SDaniel Verkamp #include "spdk/stdinc.h"
1445cab335SDaniel Verkamp 
1504adec22SDaniel Verkamp #ifdef __cplusplus
1604adec22SDaniel Verkamp extern "C" {
1704adec22SDaniel Verkamp #endif
1804adec22SDaniel Verkamp 
194a1d47ebSDaniel Verkamp #include "spdk/barrier.h"
204a1d47ebSDaniel Verkamp 
21460327eaSDaniel Verkamp #ifdef __x86_64__
22460327eaSDaniel Verkamp #define SPDK_MMIO_64BIT	1 /* Can do atomic 64-bit memory read/write (over PCIe) */
23460327eaSDaniel Verkamp #else
24460327eaSDaniel Verkamp #define SPDK_MMIO_64BIT	0
25460327eaSDaniel Verkamp #endif
26460327eaSDaniel Verkamp 
2715e97834SDaniel Verkamp static inline uint8_t
spdk_mmio_read_1(const volatile uint8_t * addr)2815e97834SDaniel Verkamp spdk_mmio_read_1(const volatile uint8_t *addr)
2915e97834SDaniel Verkamp {
3015e97834SDaniel Verkamp 	spdk_compiler_barrier();
3115e97834SDaniel Verkamp 	return *addr;
3215e97834SDaniel Verkamp }
3315e97834SDaniel Verkamp 
3415e97834SDaniel Verkamp static inline void
spdk_mmio_write_1(volatile uint8_t * addr,uint8_t val)3515e97834SDaniel Verkamp spdk_mmio_write_1(volatile uint8_t *addr, uint8_t val)
3615e97834SDaniel Verkamp {
3715e97834SDaniel Verkamp 	spdk_compiler_barrier();
3815e97834SDaniel Verkamp 	*addr = val;
3915e97834SDaniel Verkamp }
4015e97834SDaniel Verkamp 
4115e97834SDaniel Verkamp static inline uint16_t
spdk_mmio_read_2(const volatile uint16_t * addr)4215e97834SDaniel Verkamp spdk_mmio_read_2(const volatile uint16_t *addr)
4315e97834SDaniel Verkamp {
4415e97834SDaniel Verkamp 	spdk_compiler_barrier();
4515e97834SDaniel Verkamp 	return *addr;
4615e97834SDaniel Verkamp }
4715e97834SDaniel Verkamp 
4815e97834SDaniel Verkamp static inline void
spdk_mmio_write_2(volatile uint16_t * addr,uint16_t val)4915e97834SDaniel Verkamp spdk_mmio_write_2(volatile uint16_t *addr, uint16_t val)
5015e97834SDaniel Verkamp {
5115e97834SDaniel Verkamp 	spdk_compiler_barrier();
5215e97834SDaniel Verkamp 	*addr = val;
5315e97834SDaniel Verkamp }
5415e97834SDaniel Verkamp 
55460327eaSDaniel Verkamp static inline uint32_t
spdk_mmio_read_4(const volatile uint32_t * addr)56460327eaSDaniel Verkamp spdk_mmio_read_4(const volatile uint32_t *addr)
57460327eaSDaniel Verkamp {
584a1d47ebSDaniel Verkamp 	spdk_compiler_barrier();
59460327eaSDaniel Verkamp 	return *addr;
60460327eaSDaniel Verkamp }
61460327eaSDaniel Verkamp 
62460327eaSDaniel Verkamp static inline void
spdk_mmio_write_4(volatile uint32_t * addr,uint32_t val)63460327eaSDaniel Verkamp spdk_mmio_write_4(volatile uint32_t *addr, uint32_t val)
64460327eaSDaniel Verkamp {
654a1d47ebSDaniel Verkamp 	spdk_compiler_barrier();
66460327eaSDaniel Verkamp 	*addr = val;
67460327eaSDaniel Verkamp }
68460327eaSDaniel Verkamp 
69460327eaSDaniel Verkamp static inline uint64_t
spdk_mmio_read_8(volatile uint64_t * addr)70460327eaSDaniel Verkamp spdk_mmio_read_8(volatile uint64_t *addr)
71460327eaSDaniel Verkamp {
72460327eaSDaniel Verkamp 	uint64_t val;
73460327eaSDaniel Verkamp 	volatile uint32_t *addr32 = (volatile uint32_t *)addr;
74460327eaSDaniel Verkamp 
754a1d47ebSDaniel Verkamp 	spdk_compiler_barrier();
764a1d47ebSDaniel Verkamp 
77460327eaSDaniel Verkamp 	if (SPDK_MMIO_64BIT) {
78460327eaSDaniel Verkamp 		val = *addr;
79460327eaSDaniel Verkamp 	} else {
80460327eaSDaniel Verkamp 		/*
81460327eaSDaniel Verkamp 		 * Read lower 4 bytes before upper 4 bytes.
82460327eaSDaniel Verkamp 		 * This particular order is required by I/OAT.
83460327eaSDaniel Verkamp 		 * If the other order is required, use a pair of spdk_mmio_read_4() calls.
84460327eaSDaniel Verkamp 		 */
85460327eaSDaniel Verkamp 		val = addr32[0];
86460327eaSDaniel Verkamp 		val |= (uint64_t)addr32[1] << 32;
87460327eaSDaniel Verkamp 	}
88460327eaSDaniel Verkamp 
89460327eaSDaniel Verkamp 	return val;
90460327eaSDaniel Verkamp }
91460327eaSDaniel Verkamp 
92460327eaSDaniel Verkamp static inline void
spdk_mmio_write_8(volatile uint64_t * addr,uint64_t val)93460327eaSDaniel Verkamp spdk_mmio_write_8(volatile uint64_t *addr, uint64_t val)
94460327eaSDaniel Verkamp {
95460327eaSDaniel Verkamp 	volatile uint32_t *addr32 = (volatile uint32_t *)addr;
96460327eaSDaniel Verkamp 
974a1d47ebSDaniel Verkamp 	spdk_compiler_barrier();
984a1d47ebSDaniel Verkamp 
99460327eaSDaniel Verkamp 	if (SPDK_MMIO_64BIT) {
100460327eaSDaniel Verkamp 		*addr = val;
101460327eaSDaniel Verkamp 	} else {
102460327eaSDaniel Verkamp 		addr32[0] = (uint32_t)val;
103460327eaSDaniel Verkamp 		addr32[1] = (uint32_t)(val >> 32);
104460327eaSDaniel Verkamp 	}
105460327eaSDaniel Verkamp }
106460327eaSDaniel Verkamp 
10704adec22SDaniel Verkamp #ifdef __cplusplus
10804adec22SDaniel Verkamp }
10904adec22SDaniel Verkamp #endif
11004adec22SDaniel Verkamp 
111460327eaSDaniel Verkamp #endif
112