1 /* 2 * Copyright 2019, Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Augustin Cavalier <waddlesplash> 7 */ 8 #ifndef __NVME_ARCH_H__ 9 #define __NVME_ARCH_H__ 10 11 12 #include <OS.h> 13 #include <arch_vm.h> 14 #include <arch_atomic.h> 15 16 17 #define NVME_ARCH_64 __HAIKU_ARCH_64_BIT 18 #define NVME_MMIO_64BIT NVME_ARCH_64 19 #define PAGE_SIZE B_PAGE_SIZE 20 21 22 #ifndef asm 23 #define asm __asm__ 24 #endif 25 26 27 #define nvme_wmb() memory_write_barrier() 28 29 30 typedef uint8 __u8; 31 typedef uint32 __u32; 32 typedef uint64 __u64; 33 34 35 static inline __u32 nvme_mmio_read_4(const volatile __u32 * addr)36nvme_mmio_read_4(const volatile __u32 *addr) 37 { 38 return *addr; 39 } 40 41 42 static inline void nvme_mmio_write_4(volatile __u32 * addr,__u32 val)43nvme_mmio_write_4(volatile __u32 *addr, __u32 val) 44 { 45 *addr = val; 46 } 47 48 49 static inline __u64 nvme_mmio_read_8(volatile __u64 * addr)50nvme_mmio_read_8(volatile __u64 *addr) 51 { 52 #ifdef NVME_MMIO_64BIT 53 return *addr; 54 #else 55 volatile __u32 *addr32 = (volatile __u32 *)addr; 56 __u64 val; 57 58 /* 59 * Read lower 4 bytes before upper 4 bytes. 60 * This particular order is required by I/OAT. 61 * If the other order is required, use a pair of 62 * _nvme_mmio_read_4() calls. 63 */ 64 val = addr32[0]; 65 val |= (__u64)addr32[1] << 32; 66 67 return val; 68 #endif 69 } 70 71 72 static inline void nvme_mmio_write_8(volatile __u64 * addr,__u64 val)73nvme_mmio_write_8(volatile __u64 *addr, __u64 val) 74 { 75 76 #ifdef NVME_MMIO_64BIT 77 *addr = val; 78 #else 79 volatile __u32 *addr32 = (volatile __u32 *)addr; 80 81 addr32[0] = (__u32)val; 82 addr32[1] = (__u32)(val >> 32); 83 #endif 84 } 85 86 #endif /* __NVME_ARCH_H__ */ 87