1 /*
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2019 Western Digital Corporation or its affiliates.
5  *
6  * Authors:
7  *   Anup Patel <anup.patel@wdc.com>
8  */
9 
10 #ifndef __RISCV_IO_H__
11 #define __RISCV_IO_H__
12 
__raw_hartid(void)13 static inline uint32_t __raw_hartid(void)
14 {
15     extern int boot_hartid;
16     return boot_hartid;
17 }
18 
__raw_writeb(rt_uint8_t val,volatile void * addr)19 static inline void __raw_writeb(rt_uint8_t val, volatile void *addr)
20 {
21     asm volatile("sb %0, 0(%1)" : : "r"(val), "r"(addr));
22 }
23 
__raw_writew(rt_uint16_t val,volatile void * addr)24 static inline void __raw_writew(rt_uint16_t val, volatile void *addr)
25 {
26     asm volatile("sh %0, 0(%1)" : : "r"(val), "r"(addr));
27 }
28 
__raw_writel(rt_uint32_t val,volatile void * addr)29 static inline void __raw_writel(rt_uint32_t val, volatile void *addr)
30 {
31     asm volatile("sw %0, 0(%1)" : : "r"(val), "r"(addr));
32 }
33 
34 #if __riscv_xlen != 32
__raw_writeq(rt_uint64_t val,volatile void * addr)35 static inline void __raw_writeq(rt_uint64_t val, volatile void *addr)
36 {
37     asm volatile("sd %0, 0(%1)" : : "r"(val), "r"(addr));
38 }
39 #endif
40 
__raw_readb(const volatile void * addr)41 static inline rt_uint8_t __raw_readb(const volatile void *addr)
42 {
43     rt_uint8_t val;
44 
45     asm volatile("lb %0, 0(%1)" : "=r"(val) : "r"(addr));
46     return val;
47 }
48 
__raw_readw(const volatile void * addr)49 static inline rt_uint16_t __raw_readw(const volatile void *addr)
50 {
51     rt_uint16_t val;
52 
53     asm volatile("lh %0, 0(%1)" : "=r"(val) : "r"(addr));
54     return val;
55 }
56 
__raw_readl(const volatile void * addr)57 static inline rt_uint32_t __raw_readl(const volatile void *addr)
58 {
59     rt_uint32_t val;
60 
61     asm volatile("lw %0, 0(%1)" : "=r"(val) : "r"(addr));
62     return val;
63 }
64 
65 #if __riscv_xlen != 32
__raw_readq(const volatile void * addr)66 static inline rt_uint64_t __raw_readq(const volatile void *addr)
67 {
68     rt_uint64_t val;
69 
70     asm volatile("ld %0, 0(%1)" : "=r"(val) : "r"(addr));
71     return val;
72 }
73 #endif
74 
75 /* FIXME: These are now the same as asm-generic */
76 
77 /* clang-format off */
78 
79 #define __io_rbr()      do {} while (0)
80 #define __io_rar()      do {} while (0)
81 #define __io_rbw()      do {} while (0)
82 #define __io_raw()      do {} while (0)
83 
84 #define readb_relaxed(c)    ({ rt_uint8_t  __v; __io_rbr(); __v = __raw_readb(c); __io_rar(); __v; })
85 #define readw_relaxed(c)    ({ rt_uint16_t __v; __io_rbr(); __v = __raw_readw(c); __io_rar(); __v; })
86 #define readl_relaxed(c)    ({ rt_uint32_t __v; __io_rbr(); __v = __raw_readl(c); __io_rar(); __v; })
87 
88 #define writeb_relaxed(v,c) ({ __io_rbw(); __raw_writeb((v),(c)); __io_raw(); })
89 #define writew_relaxed(v,c) ({ __io_rbw(); __raw_writew((v),(c)); __io_raw(); })
90 #define writel_relaxed(v,c) ({ __io_rbw(); __raw_writel((v),(c)); __io_raw(); })
91 
92 #if __riscv_xlen != 32
93 #define readq_relaxed(c)    ({ rt_uint64_t __v; __io_rbr(); __v = __raw_readq(c); __io_rar(); __v; })
94 #define writeq_relaxed(v,c) ({ __io_rbw(); __raw_writeq((v),(c)); __io_raw(); })
95 #endif
96 
97 #define __io_br()   do {} while (0)
98 #define __io_ar()   __asm__ __volatile__ ("fence i,r" : : : "memory");
99 #define __io_bw()   __asm__ __volatile__ ("fence w,o" : : : "memory");
100 #define __io_aw()   do {} while (0)
101 
102 #define readb(c)    ({ rt_uint8_t  __v; __io_br(); __v = __raw_readb(c); __io_ar(); __v; })
103 #define readw(c)    ({ rt_uint16_t __v; __io_br(); __v = __raw_readw(c); __io_ar(); __v; })
104 #define readl(c)    ({ rt_uint32_t __v; __io_br(); __v = __raw_readl(c); __io_ar(); __v; })
105 
106 #define writeb(v,c) ({ __io_bw(); __raw_writeb((v),(c)); __io_aw(); })
107 #define writew(v,c) ({ __io_bw(); __raw_writew((v),(c)); __io_aw(); })
108 #define writel(v,c) ({ __io_bw(); __raw_writel((v),(c)); __io_aw(); })
109 
110 #if __riscv_xlen != 32
111 #define readq(c)    ({ rt_uint64_t __v; __io_br(); __v = __raw_readq(c); __io_ar(); __v; })
112 #define writeq(v,c) ({ __io_bw(); __raw_writeq((v),(c)); __io_aw(); })
113 #endif
114 
115 #endif
116