1 #ifndef __INC_ENDIANFREE_H
2 #define __INC_ENDIANFREE_H
3 
4 /*
5  *	Call endian free function when
6  *		1. Read/write packet content.
7  *		2. Before write integer to IO.
8  *		3. After read integer from IO.
9  */
10 
11 #define __MACHINE_LITTLE_ENDIAN 1234    /* LSB first: i386, vax */
12 #define __MACHINE_BIG_ENDIAN    4321    /* MSB first: 68000, ibm, net, ppc */
13 
14 #define BYTE_ORDER __MACHINE_LITTLE_ENDIAN
15 
16 #if BYTE_ORDER == __MACHINE_LITTLE_ENDIAN
17 // Convert data
18 #define EF1Byte(_val)				((u8)(_val))
19 #define EF2Byte(_val)				((u16)(_val))
20 #define EF4Byte(_val)				((u32)(_val))
21 
22 #else
23 // Convert data
24 #define EF1Byte(_val)				((u8)(_val))
25 #define EF2Byte(_val)				(((((u16)(_val))&0x00ff)<<8)|((((u16)(_val))&0xff00)>>8))
26 #define EF4Byte(_val)				(((((u32)(_val))&0x000000ff)<<24)|\
27 						((((u32)(_val))&0x0000ff00)<<8)|\
28 						((((u32)(_val))&0x00ff0000)>>8)|\
29 						((((u32)(_val))&0xff000000)>>24))
30 #endif
31 
32 // Read data from memory
33 #define ReadEF1Byte(_ptr)		EF1Byte(*((u8 *)(_ptr)))
34 #define ReadEF2Byte(_ptr)		EF2Byte(*((u16 *)(_ptr)))
35 #define ReadEF4Byte(_ptr)		EF4Byte(*((u32 *)(_ptr)))
36 
37 // Write data to memory
38 #define WriteEF1Byte(_ptr, _val)	(*((u8 *)(_ptr)))=EF1Byte(_val)
39 #define WriteEF2Byte(_ptr, _val)	(*((u16 *)(_ptr)))=EF2Byte(_val)
40 #define WriteEF4Byte(_ptr, _val)	(*((u32 *)(_ptr)))=EF4Byte(_val)
41 // Convert Host system specific byte ording (litten or big endia) to Network byte ording (big endian).
42 // 2006.05.07, by rcnjko.
43 #if BYTE_ORDER == __MACHINE_LITTLE_ENDIAN
44 #define H2N1BYTE(_val)	((u8)(_val))
45 #define H2N2BYTE(_val)	(((((u16)(_val))&0x00ff)<<8)|\
46 			((((u16)(_val))&0xff00)>>8))
47 #define H2N4BYTE(_val)	(((((u32)(_val))&0x000000ff)<<24)|\
48 			((((u32)(_val))&0x0000ff00)<<8)	|\
49 			((((u32)(_val))&0x00ff0000)>>8)	|\
50 			((((u32)(_val))&0xff000000)>>24))
51 #else
52 #define H2N1BYTE(_val)			((u8)(_val))
53 #define H2N2BYTE(_val)			((u16)(_val))
54 #define H2N4BYTE(_val)			((u32)(_val))
55 #endif
56 
57 // Convert from Network byte ording (big endian) to Host system specific byte ording (litten or big endia).
58 // 2006.05.07, by rcnjko.
59 #if BYTE_ORDER == __MACHINE_LITTLE_ENDIAN
60 #define N2H1BYTE(_val)	((u8)(_val))
61 #define N2H2BYTE(_val)	(((((u16)(_val))&0x00ff)<<8)|\
62 			((((u16)(_val))&0xff00)>>8))
63 #define N2H4BYTE(_val)	(((((u32)(_val))&0x000000ff)<<24)|\
64 			((((u32)(_val))&0x0000ff00)<<8)	|\
65 			((((u32)(_val))&0x00ff0000)>>8)	|\
66 			((((u32)(_val))&0xff000000)>>24))
67 #else
68 #define N2H1BYTE(_val)			((u8)(_val))
69 #define N2H2BYTE(_val)			((u16)(_val))
70 #define N2H4BYTE(_val)			((u32)(_val))
71 #endif
72 
73 //
74 //	Example:
75 //		BIT_LEN_MASK_32(0) => 0x00000000
76 //		BIT_LEN_MASK_32(1) => 0x00000001
77 //		BIT_LEN_MASK_32(2) => 0x00000003
78 //		BIT_LEN_MASK_32(32) => 0xFFFFFFFF
79 //
80 #define BIT_LEN_MASK_32(__BitLen) (0xFFFFFFFF >> (32 - (__BitLen)))
81 //
82 //	Example:
83 //		BIT_OFFSET_LEN_MASK_32(0, 2) => 0x00000003
84 //		BIT_OFFSET_LEN_MASK_32(16, 2) => 0x00030000
85 //
86 #define BIT_OFFSET_LEN_MASK_32(__BitOffset, __BitLen) (BIT_LEN_MASK_32(__BitLen) << (__BitOffset))
87 
88 //
89 //	Description:
90 //		Return 4-byte value in host byte ordering from
91 //		4-byte pointer in litten-endian system.
92 //
93 #define LE_P4BYTE_TO_HOST_4BYTE(__pStart) (EF4Byte(*((u32 *)(__pStart))))
94 
95 //
96 //	Description:
97 //		Translate subfield (continuous bits in little-endian) of 4-byte value in litten byte to
98 //		4-byte value in host byte ordering.
99 //
100 #define LE_BITS_TO_4BYTE(__pStart, __BitOffset, __BitLen) \
101 	( \
102 	  ( LE_P4BYTE_TO_HOST_4BYTE(__pStart) >> (__BitOffset) ) \
103 	  & \
104 	  BIT_LEN_MASK_32(__BitLen) \
105 	)
106 
107 //
108 //	Description:
109 //		Mask subfield (continuous bits in little-endian) of 4-byte value in litten byte oredering
110 //		and return the result in 4-byte value in host byte ordering.
111 //
112 #define LE_BITS_CLEARED_TO_4BYTE(__pStart, __BitOffset, __BitLen) \
113 	( \
114 	  LE_P4BYTE_TO_HOST_4BYTE(__pStart) \
115 	  & \
116 	  ( ~BIT_OFFSET_LEN_MASK_32(__BitOffset, __BitLen) ) \
117 	)
118 
119 //
120 //	Description:
121 //		Set subfield of little-endian 4-byte value to specified value.
122 //
123 #define SET_BITS_TO_LE_4BYTE(__pStart, __BitOffset, __BitLen, __Value) \
124 	*((u32 *)(__pStart)) = \
125 	EF4Byte( \
126 	LE_BITS_CLEARED_TO_4BYTE(__pStart, __BitOffset, __BitLen) \
127 	| \
128 	( (((u32)__Value) & BIT_LEN_MASK_32(__BitLen)) << (__BitOffset) ) \
129        );
130 
131 
132 #define BIT_LEN_MASK_16(__BitLen) \
133 	(0xFFFF >> (16 - (__BitLen)))
134 
135 #define BIT_OFFSET_LEN_MASK_16(__BitOffset, __BitLen) \
136 	(BIT_LEN_MASK_16(__BitLen) << (__BitOffset))
137 
138 #define LE_P2BYTE_TO_HOST_2BYTE(__pStart) \
139 	(EF2Byte(*((u16 *)(__pStart))))
140 
141 #define LE_BITS_TO_2BYTE(__pStart, __BitOffset, __BitLen) \
142 	( \
143 	  ( LE_P2BYTE_TO_HOST_2BYTE(__pStart) >> (__BitOffset) ) \
144 	  & \
145 	  BIT_LEN_MASK_16(__BitLen) \
146 	)
147 
148 #define LE_BITS_CLEARED_TO_2BYTE(__pStart, __BitOffset, __BitLen) \
149 	( \
150 	  LE_P2BYTE_TO_HOST_2BYTE(__pStart) \
151 	  & \
152 	  ( ~BIT_OFFSET_LEN_MASK_16(__BitOffset, __BitLen) ) \
153 	)
154 
155 #define SET_BITS_TO_LE_2BYTE(__pStart, __BitOffset, __BitLen, __Value) \
156 	*((u16 *)(__pStart)) = \
157 	EF2Byte( \
158 		LE_BITS_CLEARED_TO_2BYTE(__pStart, __BitOffset, __BitLen) \
159 		| \
160 		( (((u16)__Value) & BIT_LEN_MASK_16(__BitLen)) << (__BitOffset) ) \
161        );
162 
163 #define BIT_LEN_MASK_8(__BitLen) \
164 	(0xFF >> (8 - (__BitLen)))
165 
166 #define BIT_OFFSET_LEN_MASK_8(__BitOffset, __BitLen) \
167 	(BIT_LEN_MASK_8(__BitLen) << (__BitOffset))
168 
169 #define LE_P1BYTE_TO_HOST_1BYTE(__pStart) \
170 	(EF1Byte(*((u8 *)(__pStart))))
171 
172 #define LE_BITS_TO_1BYTE(__pStart, __BitOffset, __BitLen) \
173 	( \
174 	  ( LE_P1BYTE_TO_HOST_1BYTE(__pStart) >> (__BitOffset) ) \
175 	  & \
176 	  BIT_LEN_MASK_8(__BitLen) \
177 	)
178 
179 #define LE_BITS_CLEARED_TO_1BYTE(__pStart, __BitOffset, __BitLen) \
180 	( \
181 	  LE_P1BYTE_TO_HOST_1BYTE(__pStart) \
182 	  & \
183 	  ( ~BIT_OFFSET_LEN_MASK_8(__BitOffset, __BitLen) ) \
184 	)
185 
186 #define SET_BITS_TO_LE_1BYTE(__pStart, __BitOffset, __BitLen, __Value) \
187 	*((u8 *)(__pStart)) = \
188 	EF1Byte( \
189 		LE_BITS_CLEARED_TO_1BYTE(__pStart, __BitOffset, __BitLen) \
190 		| \
191 		( (((u8)__Value) & BIT_LEN_MASK_8(__BitLen)) << (__BitOffset) ) \
192        );
193 
194 #endif // #ifndef __INC_ENDIANFREE_H
195