xref: /freebsd-src/sys/compat/linuxkpi/common/include/linux/iosys-map.h (revision f8ab2f5bae1d4e4e13f95f4738c9bb49fcda6261)
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