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
30typedef uint8 __u8;
31typedef uint32 __u32;
32typedef uint64 __u64;
33
34
35static inline __u32
36nvme_mmio_read_4(const volatile __u32 *addr)
37{
38	return *addr;
39}
40
41
42static inline void
43nvme_mmio_write_4(volatile __u32 *addr, __u32 val)
44{
45	*addr = val;
46}
47
48
49static inline __u64
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
72static inline void
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