1 /*
2  * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef __MMIO_H__
8 #define __MMIO_H__
9 #include <stdint.h>
10 #include "types.h"
11 
12 #ifndef ARCH_ARM
13 #define __raw_readb(a)        (*(volatile unsigned char *)(a))
14 #define __raw_readw(a)        (*(volatile unsigned short *)(a))
15 #define __raw_readl(a)        (*(volatile unsigned int *)(a))
16 #define __raw_readq(a)        (*(volatile unsigned long long *)(a))
17 
18 #define __raw_writeb(v,a)      (*(volatile unsigned char *)(a) = (v))
19 #define __raw_writew(v,a)      (*(volatile unsigned short *)(a) = (v))
20 #define __raw_writel(v,a)      (*(volatile unsigned int *)(a) = (v))
21 #define __raw_writeq(v,a)      (*(volatile unsigned long long *)(a) = (v))
22 
23 /*
24  * I/O memory access primitives. Reads are ordered relative to any
25  * following Normal memory access. Writes are ordered relative to any prior
26  * Normal memory access.  The memory barriers here are necessary as RISC-V
27  * doesn't define any ordering between the memory space and the I/O space.
28  */
29 #define __io_br()   do {} while (0)
30 #define __io_ar(v)  __asm__ __volatile__ ("fence i,r" : : : "memory")
31 #define __io_bw()   __asm__ __volatile__ ("fence w,o" : : : "memory")
32 //#define __io_aw()   mmiowb_set_pending()
33 #define __io_aw()   do {} while (0)
34 
35 #define readb(c)    ({ u8  __v; __io_br(); __v = __raw_readb(c); __io_ar(__v); __v; })
36 #define readw(c)    ({ u16 __v; __io_br(); __v = __raw_readw(c); __io_ar(__v); __v; })
37 #define readl(c)    ({ u32 __v; __io_br(); __v = __raw_readl(c); __io_ar(__v); __v; })
38 
39 #define writeb(v, c)    ({ __io_bw(); __raw_writeb((v), (c)); __io_aw(); })
40 #define writew(v, c)    ({ __io_bw(); __raw_writew((v), (c)); __io_aw(); })
41 #define writel(v, c)    ({ __io_bw(); __raw_writel((v), (c)); __io_aw(); })
42 
43 #ifdef CONFIG_64BIT
44 #define readq(c)    ({ u64 __v; __io_br(); __v = __raw_readq(c); __io_ar(__v); __v; })
45 #define writeq(v, c)    ({ __io_bw(); __raw_writeq((v), (c)); __io_aw(); })
46 #endif // CONFIG_64BIT
47 
48 #else
49 #define __raw_readb(a)        (*(volatile unsigned char *)(a))
50 #define __raw_readw(a)        (*(volatile unsigned short *)(a))
51 #define __raw_readl(a)        (*(volatile unsigned int *)(a))
52 #define __raw_readq(a)        (*(volatile unsigned long long *)(a))
53 
54 #define __raw_writeb(v,a)      (*(volatile unsigned char *)(a) = (v))
55 #define __raw_writew(v,a)      (*(volatile unsigned short *)(a) = (v))
56 #define __raw_writel(v,a)      (*(volatile unsigned int *)(a) = (v))
57 #define __raw_writeq(v,a)      (*(volatile unsigned long long *)(a) = (v))
58 
59 #define readb(a)        __raw_readb(a)
60 #define readw(a)        __raw_readw(a)
61 #define readl(a)        __raw_readl(a)
62 #define readq(a)        __raw_readq(a)
63 
64 #define writeb(v, a)        __raw_writeb(v,a)
65 #define writew(v, a)        __raw_writew(v,a)
66 #define writel(v, a)        __raw_writel(v,a)
67 #define writeq(v, a)        __raw_writeq(v,a)
68 
69 #define cpu_write8(a, v)    writeb(a, v)
70 #define cpu_write16(a, v)   writew(a, v)
71 #define cpu_write32(a, v)   writel(a, v)
72 #endif /* ARCH_ARM */
73 
74 #define mmio_wr32 mmio_write_32
75 #define mmio_rd32 mmio_read_32
76 
mmio_write_8(uintptr_t addr,uint8_t value)77 static inline void mmio_write_8(uintptr_t addr, uint8_t value)
78 {
79     writeb(value, (void *) addr);
80 }
81 
mmio_read_8(uintptr_t addr)82 static inline uint8_t mmio_read_8(uintptr_t addr)
83 {
84     return readb((void *) addr);
85 }
86 
mmio_write_16(uintptr_t addr,uint16_t value)87 static inline void mmio_write_16(uintptr_t addr, uint16_t value)
88 {
89     writew(value, (void *) addr);
90 }
91 
mmio_read_16(uintptr_t addr)92 static inline uint16_t mmio_read_16(uintptr_t addr)
93 {
94     return readw((void *) addr);
95 }
96 
mmio_write_32(uintptr_t addr,uint32_t value)97 static inline void mmio_write_32(uintptr_t addr, uint32_t value)
98 {
99     writel(value, (void *) addr);
100 }
101 
mmio_read_32(uintptr_t addr)102 static inline uint32_t mmio_read_32(uintptr_t addr)
103 {
104     return readl((void *) addr);
105 }
106 
mmio_write_64(uintptr_t addr,uint64_t value)107 static inline void mmio_write_64(uintptr_t addr, uint64_t value)
108 {
109     writeq(value, (void *) addr);
110 }
111 
mmio_read_64(uintptr_t addr)112 static inline uint64_t mmio_read_64(uintptr_t addr)
113 {
114     return readq((void *) addr);
115 }
116 
mmio_clrbits_32(uintptr_t addr,uint32_t clear)117 static inline void mmio_clrbits_32(uintptr_t addr, uint32_t clear)
118 {
119     writel(readl((void *) addr) & ~clear , (void *) addr);
120 }
121 
mmio_setbits_32(uintptr_t addr,uint32_t set)122 static inline void mmio_setbits_32(uintptr_t addr, uint32_t set)
123 {
124     writel(readl((void *) addr) | set , (void *) addr);
125 }
126 
mmio_clrsetbits_32(uintptr_t addr,uint32_t clear,uint32_t set)127 static inline void mmio_clrsetbits_32(uintptr_t addr, uint32_t clear,
128                       uint32_t set)
129 {
130     writel((readl((void *) addr) & ~clear) | set , (void *) addr);
131 }
132 
133 /* from Linux usage */
134 #define ioremap(a, l)       (a)
135 
136 #define _reg_read(addr)     mmio_read_32((addr))
137 #define _reg_write(addr, data)  mmio_write_32((addr), (data))
138 #define _reg_write_mask(addr, mask, data) mmio_clrsetbits_32(addr, mask, data)
139 
140 #define ioread8 readb
141 #define ioread16 readw
142 #define ioread32 readl
143 #define ioread64 readq
144 
145 #define iowrite8 writeb
146 #define iowrite16 writew
147 #define iowrite32 writel
148 #define iowrite64 writeq
149 
150 #endif /* __MMIO_H__ */
151