1*f8ab2f5bSVladimir Kondratyev /* Public domain. */
2*f8ab2f5bSVladimir Kondratyev
3*f8ab2f5bSVladimir Kondratyev #ifndef _LINUXKPI_LINUX_IOSYS_MAP_H
4*f8ab2f5bSVladimir Kondratyev #define _LINUXKPI_LINUX_IOSYS_MAP_H
5*f8ab2f5bSVladimir Kondratyev
6*f8ab2f5bSVladimir Kondratyev #include <linux/io.h>
7*f8ab2f5bSVladimir Kondratyev #include <linux/string.h>
8*f8ab2f5bSVladimir Kondratyev
9*f8ab2f5bSVladimir Kondratyev struct iosys_map {
10*f8ab2f5bSVladimir Kondratyev union {
11*f8ab2f5bSVladimir Kondratyev void *vaddr_iomem;
12*f8ab2f5bSVladimir Kondratyev void *vaddr;
13*f8ab2f5bSVladimir Kondratyev };
14*f8ab2f5bSVladimir Kondratyev bool is_iomem;
15*f8ab2f5bSVladimir Kondratyev #ifdef __OpenBSD__
16*f8ab2f5bSVladimir Kondratyev bus_space_handle_t bsh;
17*f8ab2f5bSVladimir Kondratyev bus_size_t size;
18*f8ab2f5bSVladimir Kondratyev #endif
19*f8ab2f5bSVladimir Kondratyev };
20*f8ab2f5bSVladimir Kondratyev
21*f8ab2f5bSVladimir Kondratyev #define IOSYS_MAP_INIT_OFFSET(_ism_src_p, _off) ({ \
22*f8ab2f5bSVladimir Kondratyev struct iosys_map ism_dst = *(_ism_src_p); \
23*f8ab2f5bSVladimir Kondratyev iosys_map_incr(&ism_dst, _off); \
24*f8ab2f5bSVladimir Kondratyev ism_dst; \
25*f8ab2f5bSVladimir Kondratyev })
26*f8ab2f5bSVladimir Kondratyev
27*f8ab2f5bSVladimir Kondratyev static inline void
iosys_map_incr(struct iosys_map * ism,size_t n)28*f8ab2f5bSVladimir Kondratyev iosys_map_incr(struct iosys_map *ism, size_t n)
29*f8ab2f5bSVladimir Kondratyev {
30*f8ab2f5bSVladimir Kondratyev if (ism->is_iomem)
31*f8ab2f5bSVladimir Kondratyev ism->vaddr_iomem += n;
32*f8ab2f5bSVladimir Kondratyev else
33*f8ab2f5bSVladimir Kondratyev ism->vaddr += n;
34*f8ab2f5bSVladimir Kondratyev }
35*f8ab2f5bSVladimir Kondratyev
36*f8ab2f5bSVladimir Kondratyev static inline void
iosys_map_memcpy_to(struct iosys_map * ism,size_t off,const void * src,size_t len)37*f8ab2f5bSVladimir Kondratyev iosys_map_memcpy_to(struct iosys_map *ism, size_t off, const void *src,
38*f8ab2f5bSVladimir Kondratyev size_t len)
39*f8ab2f5bSVladimir Kondratyev {
40*f8ab2f5bSVladimir Kondratyev if (ism->is_iomem)
41*f8ab2f5bSVladimir Kondratyev memcpy_toio(ism->vaddr_iomem + off, src, len);
42*f8ab2f5bSVladimir Kondratyev else
43*f8ab2f5bSVladimir Kondratyev memcpy(ism->vaddr + off, src, len);
44*f8ab2f5bSVladimir Kondratyev }
45*f8ab2f5bSVladimir Kondratyev
46*f8ab2f5bSVladimir Kondratyev static inline bool
iosys_map_is_null(const struct iosys_map * ism)47*f8ab2f5bSVladimir Kondratyev iosys_map_is_null(const struct iosys_map *ism)
48*f8ab2f5bSVladimir Kondratyev {
49*f8ab2f5bSVladimir Kondratyev if (ism->is_iomem)
50*f8ab2f5bSVladimir Kondratyev return (ism->vaddr_iomem == NULL);
51*f8ab2f5bSVladimir Kondratyev else
52*f8ab2f5bSVladimir Kondratyev return (ism->vaddr == NULL);
53*f8ab2f5bSVladimir Kondratyev }
54*f8ab2f5bSVladimir Kondratyev
55*f8ab2f5bSVladimir Kondratyev static inline bool
iosys_map_is_set(const struct iosys_map * ism)56*f8ab2f5bSVladimir Kondratyev iosys_map_is_set(const struct iosys_map *ism)
57*f8ab2f5bSVladimir Kondratyev {
58*f8ab2f5bSVladimir Kondratyev if (ism->is_iomem)
59*f8ab2f5bSVladimir Kondratyev return (ism->vaddr_iomem != NULL);
60*f8ab2f5bSVladimir Kondratyev else
61*f8ab2f5bSVladimir Kondratyev return (ism->vaddr != NULL);
62*f8ab2f5bSVladimir Kondratyev }
63*f8ab2f5bSVladimir Kondratyev
64*f8ab2f5bSVladimir Kondratyev static inline bool
iosys_map_is_equal(const struct iosys_map * ism_a,const struct iosys_map * ism_b)65*f8ab2f5bSVladimir Kondratyev iosys_map_is_equal(const struct iosys_map *ism_a,
66*f8ab2f5bSVladimir Kondratyev const struct iosys_map *ism_b)
67*f8ab2f5bSVladimir Kondratyev {
68*f8ab2f5bSVladimir Kondratyev if (ism_a->is_iomem != ism_b->is_iomem)
69*f8ab2f5bSVladimir Kondratyev return (false);
70*f8ab2f5bSVladimir Kondratyev
71*f8ab2f5bSVladimir Kondratyev if (ism_a->is_iomem)
72*f8ab2f5bSVladimir Kondratyev return (ism_a->vaddr_iomem == ism_b->vaddr_iomem);
73*f8ab2f5bSVladimir Kondratyev else
74*f8ab2f5bSVladimir Kondratyev return (ism_a->vaddr == ism_b->vaddr);
75*f8ab2f5bSVladimir Kondratyev }
76*f8ab2f5bSVladimir Kondratyev
77*f8ab2f5bSVladimir Kondratyev static inline void
iosys_map_clear(struct iosys_map * ism)78*f8ab2f5bSVladimir Kondratyev iosys_map_clear(struct iosys_map *ism)
79*f8ab2f5bSVladimir Kondratyev {
80*f8ab2f5bSVladimir Kondratyev if (ism->is_iomem) {
81*f8ab2f5bSVladimir Kondratyev ism->vaddr_iomem = NULL;
82*f8ab2f5bSVladimir Kondratyev ism->is_iomem = false;
83*f8ab2f5bSVladimir Kondratyev } else {
84*f8ab2f5bSVladimir Kondratyev ism->vaddr = NULL;
85*f8ab2f5bSVladimir Kondratyev }
86*f8ab2f5bSVladimir Kondratyev }
87*f8ab2f5bSVladimir Kondratyev
88*f8ab2f5bSVladimir Kondratyev static inline void
iosys_map_set_vaddr_iomem(struct iosys_map * ism,void * addr)89*f8ab2f5bSVladimir Kondratyev iosys_map_set_vaddr_iomem(struct iosys_map *ism, void *addr)
90*f8ab2f5bSVladimir Kondratyev {
91*f8ab2f5bSVladimir Kondratyev ism->vaddr_iomem = addr;
92*f8ab2f5bSVladimir Kondratyev ism->is_iomem = true;
93*f8ab2f5bSVladimir Kondratyev }
94*f8ab2f5bSVladimir Kondratyev
95*f8ab2f5bSVladimir Kondratyev static inline void
iosys_map_set_vaddr(struct iosys_map * ism,void * addr)96*f8ab2f5bSVladimir Kondratyev iosys_map_set_vaddr(struct iosys_map *ism, void *addr)
97*f8ab2f5bSVladimir Kondratyev {
98*f8ab2f5bSVladimir Kondratyev ism->vaddr = addr;
99*f8ab2f5bSVladimir Kondratyev ism->is_iomem = false;
100*f8ab2f5bSVladimir Kondratyev }
101*f8ab2f5bSVladimir Kondratyev
102*f8ab2f5bSVladimir Kondratyev static inline void
iosys_map_memset(struct iosys_map * ism,size_t off,int value,size_t len)103*f8ab2f5bSVladimir Kondratyev iosys_map_memset(struct iosys_map *ism, size_t off, int value, size_t len)
104*f8ab2f5bSVladimir Kondratyev {
105*f8ab2f5bSVladimir Kondratyev if (ism->is_iomem)
106*f8ab2f5bSVladimir Kondratyev memset_io(ism->vaddr_iomem + off, value, len);
107*f8ab2f5bSVladimir Kondratyev else
108*f8ab2f5bSVladimir Kondratyev memset(ism->vaddr + off, value, len);
109*f8ab2f5bSVladimir Kondratyev }
110*f8ab2f5bSVladimir Kondratyev
111*f8ab2f5bSVladimir Kondratyev #ifdef __LP64__
112*f8ab2f5bSVladimir Kondratyev #define _iosys_map_readq(_addr) readq(_addr)
113*f8ab2f5bSVladimir Kondratyev #define _iosys_map_writeq(_val, _addr) writeq(_val, _addr)
114*f8ab2f5bSVladimir Kondratyev #else
115*f8ab2f5bSVladimir Kondratyev #define _iosys_map_readq(_addr) ({ \
116*f8ab2f5bSVladimir Kondratyev uint64_t val; \
117*f8ab2f5bSVladimir Kondratyev memcpy_fromio(&val, _addr, sizeof(uint64_t)); \
118*f8ab2f5bSVladimir Kondratyev val; \
119*f8ab2f5bSVladimir Kondratyev })
120*f8ab2f5bSVladimir Kondratyev #define _iosys_map_writeq(_val, _addr) \
121*f8ab2f5bSVladimir Kondratyev memcpy_toio(_addr, &(_val), sizeof(uint64_t))
122*f8ab2f5bSVladimir Kondratyev #endif
123*f8ab2f5bSVladimir Kondratyev
124*f8ab2f5bSVladimir Kondratyev #define iosys_map_rd(_ism, _off, _type) ({ \
125*f8ab2f5bSVladimir Kondratyev _type val; \
126*f8ab2f5bSVladimir Kondratyev if ((_ism)->is_iomem) { \
127*f8ab2f5bSVladimir Kondratyev void *addr = (_ism)->vaddr_iomem + (_off); \
128*f8ab2f5bSVladimir Kondratyev val = _Generic(val, \
129*f8ab2f5bSVladimir Kondratyev uint8_t : readb(addr), \
130*f8ab2f5bSVladimir Kondratyev uint16_t: readw(addr), \
131*f8ab2f5bSVladimir Kondratyev uint32_t: readl(addr), \
132*f8ab2f5bSVladimir Kondratyev uint64_t: _iosys_map_readq(addr)); \
133*f8ab2f5bSVladimir Kondratyev } else \
134*f8ab2f5bSVladimir Kondratyev val = READ_ONCE(*(_type *)((_ism)->vaddr + (_off))); \
135*f8ab2f5bSVladimir Kondratyev val; \
136*f8ab2f5bSVladimir Kondratyev })
137*f8ab2f5bSVladimir Kondratyev #define iosys_map_wr(_ism, _off, _type, _val) ({ \
138*f8ab2f5bSVladimir Kondratyev _type val = (_val); \
139*f8ab2f5bSVladimir Kondratyev if ((_ism)->is_iomem) { \
140*f8ab2f5bSVladimir Kondratyev void *addr = (_ism)->vaddr_iomem + (_off); \
141*f8ab2f5bSVladimir Kondratyev _Generic(val, \
142*f8ab2f5bSVladimir Kondratyev uint8_t : writeb(val, addr), \
143*f8ab2f5bSVladimir Kondratyev uint16_t: writew(val, addr), \
144*f8ab2f5bSVladimir Kondratyev uint32_t: writel(val, addr), \
145*f8ab2f5bSVladimir Kondratyev uint64_t: _iosys_map_writeq(val, addr)); \
146*f8ab2f5bSVladimir Kondratyev } else \
147*f8ab2f5bSVladimir Kondratyev WRITE_ONCE(*(_type *)((_ism)->vaddr + (_off)), val); \
148*f8ab2f5bSVladimir Kondratyev })
149*f8ab2f5bSVladimir Kondratyev
150*f8ab2f5bSVladimir Kondratyev #define iosys_map_rd_field(_ism, _off, _type, _field) ({ \
151*f8ab2f5bSVladimir Kondratyev _type *s; \
152*f8ab2f5bSVladimir Kondratyev iosys_map_rd(_ism, (_off) + offsetof(_type, _field), \
153*f8ab2f5bSVladimir Kondratyev __typeof(s->_field)); \
154*f8ab2f5bSVladimir Kondratyev })
155*f8ab2f5bSVladimir Kondratyev #define iosys_map_wr_field(_ism, _off, _type, _field, _val) ({ \
156*f8ab2f5bSVladimir Kondratyev _type *s; \
157*f8ab2f5bSVladimir Kondratyev iosys_map_wr(_ism, (_off) + offsetof(_type, _field), \
158*f8ab2f5bSVladimir Kondratyev __typeof(s->_field), _val); \
159*f8ab2f5bSVladimir Kondratyev })
160*f8ab2f5bSVladimir Kondratyev
161*f8ab2f5bSVladimir Kondratyev #endif
162