at v4.12 3.9 kB view raw
1/* 2 * Copyright(c) 2015 Intel Corporation. All rights reserved. 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of version 2 of the GNU General Public License as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 * General Public License for more details. 12 */ 13#ifndef __PMEM_H__ 14#define __PMEM_H__ 15 16#include <linux/io.h> 17#include <linux/uio.h> 18 19#ifdef CONFIG_ARCH_HAS_PMEM_API 20#define ARCH_MEMREMAP_PMEM MEMREMAP_WB 21#include <asm/pmem.h> 22#else 23#define ARCH_MEMREMAP_PMEM MEMREMAP_WT 24/* 25 * These are simply here to enable compilation, all call sites gate 26 * calling these symbols with arch_has_pmem_api() and redirect to the 27 * implementation in asm/pmem.h. 28 */ 29static inline void arch_memcpy_to_pmem(void *dst, const void *src, size_t n) 30{ 31 BUG(); 32} 33 34static inline size_t arch_copy_from_iter_pmem(void *addr, size_t bytes, 35 struct iov_iter *i) 36{ 37 BUG(); 38 return 0; 39} 40 41static inline void arch_clear_pmem(void *addr, size_t size) 42{ 43 BUG(); 44} 45 46static inline void arch_wb_cache_pmem(void *addr, size_t size) 47{ 48 BUG(); 49} 50 51static inline void arch_invalidate_pmem(void *addr, size_t size) 52{ 53 BUG(); 54} 55#endif 56 57static inline bool arch_has_pmem_api(void) 58{ 59 return IS_ENABLED(CONFIG_ARCH_HAS_PMEM_API); 60} 61 62/** 63 * memcpy_to_pmem - copy data to persistent memory 64 * @dst: destination buffer for the copy 65 * @src: source buffer for the copy 66 * @n: length of the copy in bytes 67 * 68 * Perform a memory copy that results in the destination of the copy 69 * being effectively evicted from, or never written to, the processor 70 * cache hierarchy after the copy completes. After memcpy_to_pmem() 71 * data may still reside in cpu or platform buffers, so this operation 72 * must be followed by a blkdev_issue_flush() on the pmem block device. 73 */ 74static inline void memcpy_to_pmem(void *dst, const void *src, size_t n) 75{ 76 if (arch_has_pmem_api()) 77 arch_memcpy_to_pmem(dst, src, n); 78 else 79 memcpy(dst, src, n); 80} 81 82/** 83 * copy_from_iter_pmem - copy data from an iterator to PMEM 84 * @addr: PMEM destination address 85 * @bytes: number of bytes to copy 86 * @i: iterator with source data 87 * 88 * Copy data from the iterator 'i' to the PMEM buffer starting at 'addr'. 89 * See blkdev_issue_flush() note for memcpy_to_pmem(). 90 */ 91static inline size_t copy_from_iter_pmem(void *addr, size_t bytes, 92 struct iov_iter *i) 93{ 94 if (arch_has_pmem_api()) 95 return arch_copy_from_iter_pmem(addr, bytes, i); 96 return copy_from_iter_nocache(addr, bytes, i); 97} 98 99/** 100 * clear_pmem - zero a PMEM memory range 101 * @addr: virtual start address 102 * @size: number of bytes to zero 103 * 104 * Write zeros into the memory range starting at 'addr' for 'size' bytes. 105 * See blkdev_issue_flush() note for memcpy_to_pmem(). 106 */ 107static inline void clear_pmem(void *addr, size_t size) 108{ 109 if (arch_has_pmem_api()) 110 arch_clear_pmem(addr, size); 111 else 112 memset(addr, 0, size); 113} 114 115/** 116 * invalidate_pmem - flush a pmem range from the cache hierarchy 117 * @addr: virtual start address 118 * @size: bytes to invalidate (internally aligned to cache line size) 119 * 120 * For platforms that support clearing poison this flushes any poisoned 121 * ranges out of the cache 122 */ 123static inline void invalidate_pmem(void *addr, size_t size) 124{ 125 if (arch_has_pmem_api()) 126 arch_invalidate_pmem(addr, size); 127} 128 129/** 130 * wb_cache_pmem - write back processor cache for PMEM memory range 131 * @addr: virtual start address 132 * @size: number of bytes to write back 133 * 134 * Write back the processor cache range starting at 'addr' for 'size' bytes. 135 * See blkdev_issue_flush() note for memcpy_to_pmem(). 136 */ 137static inline void wb_cache_pmem(void *addr, size_t size) 138{ 139 if (arch_has_pmem_api()) 140 arch_wb_cache_pmem(addr, size); 141} 142#endif /* __PMEM_H__ */