1 /** @file
2   I/O Library MMIO Buffer Functions.
3 
4   Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
5   This program and the accompanying materials
6   are licensed and made available under the terms and conditions of the BSD License
7   which accompanies this distribution.  The full text of the license may be found at
8   http://opensource.org/licenses/bsd-license.php.
9 
10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 
13 **/
14 
15 #include "SmmCpuIoLibInternal.h"
16 
17 /**
18   Copy data from MMIO region to system memory by using 8-bit access.
19 
20   Copy data from MMIO region specified by starting address StartAddress
21   to system memory specified by Buffer by using 8-bit access. The total
22   number of byte to be copied is specified by Length. Buffer is returned.
23 
24   If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().
25   If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
26 
27 
28   @param  StartAddress    The starting address for the MMIO region to be copied from.
29   @param  Length          The size in bytes of the copy.
30   @param  Buffer          The pointer to a system memory buffer receiving the data read.
31 
32   @return Buffer
33 
34 **/
35 UINT8 *
36 EFIAPI
MmioReadBuffer8(IN UINTN StartAddress,IN UINTN Length,OUT UINT8 * Buffer)37 MmioReadBuffer8 (
38   IN  UINTN       StartAddress,
39   IN  UINTN       Length,
40   OUT UINT8       *Buffer
41   )
42 {
43   UINT8   *ReturnBuffer;
44 
45   ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));
46   ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));
47 
48   ReturnBuffer = Buffer;
49 
50   while (Length-- > 0) {
51     *(Buffer++) = MmioRead8 (StartAddress++);
52   }
53 
54   return ReturnBuffer;
55 }
56 
57 /**
58   Copy data from MMIO region to system memory by using 16-bit access.
59 
60   Copy data from MMIO region specified by starting address StartAddress
61   to system memory specified by Buffer by using 16-bit access. The total
62   number of byte to be copied is specified by Length. Buffer is returned.
63 
64   If StartAddress is not aligned on a 16-bit boundary, then ASSERT().
65 
66   If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().
67   If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
68 
69   If Length is not aligned on a 16-bit boundary, then ASSERT().
70 
71   If Buffer is not aligned on a 16-bit boundary, then ASSERT().
72 
73   @param  StartAddress    The starting address for the MMIO region to be copied from.
74   @param  Length          The size in bytes of the copy.
75   @param  Buffer          The pointer to a system memory buffer receiving the data read.
76 
77   @return Buffer
78 
79 **/
80 UINT16 *
81 EFIAPI
MmioReadBuffer16(IN UINTN StartAddress,IN UINTN Length,OUT UINT16 * Buffer)82 MmioReadBuffer16 (
83   IN  UINTN       StartAddress,
84   IN  UINTN       Length,
85   OUT UINT16      *Buffer
86   )
87 {
88   UINT16    *ReturnBuffer;
89 
90   ASSERT ((StartAddress & (sizeof (UINT16) - 1)) == 0);
91 
92   ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));
93   ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));
94 
95   ASSERT ((Length & (sizeof (UINT16) - 1)) == 0);
96   ASSERT (((UINTN) Buffer & (sizeof (UINT16) - 1)) == 0);
97 
98   ReturnBuffer = Buffer;
99 
100   while (Length > 0) {
101     *(Buffer++) = MmioRead16 (StartAddress);
102     StartAddress += sizeof (UINT16);
103     Length -= sizeof (UINT16);
104   }
105 
106   return ReturnBuffer;
107 }
108 
109 /**
110   Copy data from MMIO region to system memory by using 32-bit access.
111 
112   Copy data from MMIO region specified by starting address StartAddress
113   to system memory specified by Buffer by using 32-bit access. The total
114   number of byte to be copied is specified by Length. Buffer is returned.
115 
116   If StartAddress is not aligned on a 32-bit boundary, then ASSERT().
117 
118   If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().
119   If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
120 
121   If Length is not aligned on a 32-bit boundary, then ASSERT().
122   If Buffer is not aligned on a 32-bit boundary, then ASSERT().
123 
124   @param  StartAddress    The starting address for the MMIO region to be copied from.
125   @param  Length          The size in bytes of the copy.
126   @param  Buffer          The pointer to a system memory buffer receiving the data read.
127 
128   @return Buffer
129 
130 **/
131 UINT32 *
132 EFIAPI
MmioReadBuffer32(IN UINTN StartAddress,IN UINTN Length,OUT UINT32 * Buffer)133 MmioReadBuffer32 (
134   IN  UINTN       StartAddress,
135   IN  UINTN       Length,
136   OUT UINT32      *Buffer
137   )
138 {
139   UINT32    *ReturnBuffer;
140 
141   ASSERT ((StartAddress & (sizeof (UINT32) - 1)) == 0);
142 
143   ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));
144   ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));
145 
146   ASSERT ((Length & (sizeof (UINT32) - 1)) == 0);
147   ASSERT (((UINTN) Buffer & (sizeof (UINT32) - 1)) == 0);
148 
149   ReturnBuffer = Buffer;
150 
151   while (Length > 0) {
152     *(Buffer++) = MmioRead32 (StartAddress);
153     StartAddress += sizeof (UINT32);
154     Length -= sizeof (UINT32);
155   }
156 
157   return ReturnBuffer;
158 }
159 
160 /**
161   Copy data from MMIO region to system memory by using 64-bit access.
162 
163   Copy data from MMIO region specified by starting address StartAddress
164   to system memory specified by Buffer by using 64-bit access. The total
165   number of byte to be copied is specified by Length. Buffer is returned.
166 
167   If StartAddress is not aligned on a 64-bit boundary, then ASSERT().
168 
169   If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().
170   If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
171 
172   If Length is not aligned on a 64-bit boundary, then ASSERT().
173 
174   If Buffer is not aligned on a 64-bit boundary, then ASSERT().
175 
176   @param  StartAddress    The starting address for the MMIO region to be copied from.
177   @param  Length          The size in bytes of the copy.
178   @param  Buffer          The pointer to a system memory buffer receiving the data read.
179 
180   @return Buffer
181 
182 **/
183 UINT64 *
184 EFIAPI
MmioReadBuffer64(IN UINTN StartAddress,IN UINTN Length,OUT UINT64 * Buffer)185 MmioReadBuffer64 (
186   IN  UINTN       StartAddress,
187   IN  UINTN       Length,
188   OUT UINT64      *Buffer
189   )
190 {
191   UINT64    *ReturnBuffer;
192 
193   ASSERT ((StartAddress & (sizeof (UINT64) - 1)) == 0);
194 
195   ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));
196   ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));
197 
198   ASSERT ((Length & (sizeof (UINT64) - 1)) == 0);
199   ASSERT (((UINTN) Buffer & (sizeof (UINT64) - 1)) == 0);
200 
201   ReturnBuffer = Buffer;
202 
203   while (Length > 0) {
204     *(Buffer++) = MmioRead64 (StartAddress);
205     StartAddress += sizeof (UINT64);
206     Length -= sizeof (UINT64);
207   }
208 
209   return ReturnBuffer;
210 }
211 
212 
213 /**
214   Copy data from system memory to MMIO region by using 8-bit access.
215 
216   Copy data from system memory specified by Buffer to MMIO region specified
217   by starting address StartAddress by using 8-bit access. The total number
218   of byte to be copied is specified by Length. Buffer is returned.
219 
220   If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().
221   If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().
222 
223 
224   @param  StartAddress    The starting address for the MMIO region to be copied to.
225   @param  Length          The size in bytes of the copy.
226   @param  Buffer          The pointer to a system memory buffer containing the
227                           data to write.
228 
229   @return Buffer
230 
231 **/
232 UINT8 *
233 EFIAPI
MmioWriteBuffer8(IN UINTN StartAddress,IN UINTN Length,IN CONST UINT8 * Buffer)234 MmioWriteBuffer8 (
235   IN  UINTN         StartAddress,
236   IN  UINTN         Length,
237   IN  CONST UINT8   *Buffer
238   )
239 {
240   VOID* ReturnBuffer;
241 
242   ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));
243   ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));
244 
245   ReturnBuffer = (UINT8 *) Buffer;
246 
247   while (Length-- > 0) {
248      MmioWrite8 (StartAddress++, *(Buffer++));
249   }
250 
251   return ReturnBuffer;
252 
253 }
254 
255 /**
256   Copy data from system memory to MMIO region by using 16-bit access.
257 
258   Copy data from system memory specified by Buffer to MMIO region specified
259   by starting address StartAddress by using 16-bit access. The total number
260   of byte to be copied is specified by Length. Buffer is returned.
261 
262   If StartAddress is not aligned on a 16-bit boundary, then ASSERT().
263 
264   If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().
265   If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().
266 
267   If Length is not aligned on a 16-bit boundary, then ASSERT().
268 
269   If Buffer is not aligned on a 16-bit boundary, then ASSERT().
270 
271   @param  StartAddress    The starting address for the MMIO region to be copied to.
272   @param  Length          The size in bytes of the copy.
273   @param  Buffer          The pointer to a system memory buffer containing the
274                           data to write.
275 
276   @return Buffer
277 
278 **/
279 UINT16 *
280 EFIAPI
MmioWriteBuffer16(IN UINTN StartAddress,IN UINTN Length,IN CONST UINT16 * Buffer)281 MmioWriteBuffer16 (
282   IN  UINTN        StartAddress,
283   IN  UINTN        Length,
284   IN  CONST UINT16 *Buffer
285   )
286 {
287   UINT16    *ReturnBuffer;
288 
289   ASSERT ((StartAddress & (sizeof (UINT16) - 1)) == 0);
290 
291   ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));
292   ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));
293 
294   ASSERT ((Length & (sizeof (UINT16) - 1)) == 0);
295   ASSERT (((UINTN) Buffer & (sizeof (UINT16) - 1)) == 0);
296 
297   ReturnBuffer = (UINT16 *) Buffer;
298 
299   while (Length > 0) {
300     MmioWrite16 (StartAddress, *(Buffer++));
301 
302     StartAddress += sizeof (UINT16);
303     Length -= sizeof (UINT16);
304   }
305 
306   return ReturnBuffer;
307 }
308 
309 
310 /**
311   Copy data from system memory to MMIO region by using 32-bit access.
312 
313   Copy data from system memory specified by Buffer to MMIO region specified
314   by starting address StartAddress by using 32-bit access. The total number
315   of byte to be copied is specified by Length. Buffer is returned.
316 
317   If StartAddress is not aligned on a 32-bit boundary, then ASSERT().
318 
319   If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().
320   If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().
321 
322   If Length is not aligned on a 32-bit boundary, then ASSERT().
323 
324   If Buffer is not aligned on a 32-bit boundary, then ASSERT().
325 
326   @param  StartAddress    The starting address for the MMIO region to be copied to.
327   @param  Length          The size in bytes of the copy.
328   @param  Buffer          The pointer to a system memory buffer containing the
329                           data to write.
330 
331   @return Buffer
332 
333 **/
334 UINT32 *
335 EFIAPI
MmioWriteBuffer32(IN UINTN StartAddress,IN UINTN Length,IN CONST UINT32 * Buffer)336 MmioWriteBuffer32 (
337   IN  UINTN        StartAddress,
338   IN  UINTN        Length,
339   IN  CONST UINT32 *Buffer
340   )
341 {
342   UINT32    *ReturnBuffer;
343 
344   ASSERT ((StartAddress & (sizeof (UINT32) - 1)) == 0);
345 
346   ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));
347   ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));
348 
349   ASSERT ((Length & (sizeof (UINT32) - 1)) == 0);
350   ASSERT (((UINTN) Buffer & (sizeof (UINT32) - 1)) == 0);
351 
352   ReturnBuffer = (UINT32 *) Buffer;
353 
354   while (Length > 0) {
355     MmioWrite32 (StartAddress, *(Buffer++));
356 
357     StartAddress += sizeof (UINT32);
358     Length -= sizeof (UINT32);
359   }
360 
361   return ReturnBuffer;
362 }
363 
364 /**
365   Copy data from system memory to MMIO region by using 64-bit access.
366 
367   Copy data from system memory specified by Buffer to MMIO region specified
368   by starting address StartAddress by using 64-bit access. The total number
369   of byte to be copied is specified by Length. Buffer is returned.
370 
371   If StartAddress is not aligned on a 64-bit boundary, then ASSERT().
372 
373   If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().
374   If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().
375 
376   If Length is not aligned on a 64-bit boundary, then ASSERT().
377 
378   If Buffer is not aligned on a 64-bit boundary, then ASSERT().
379 
380   @param  StartAddress    The starting address for the MMIO region to be copied to.
381   @param  Length          The size in bytes of the copy.
382   @param  Buffer          The pointer to a system memory buffer containing the
383                           data to write.
384 
385   @return Buffer
386 
387 **/
388 UINT64 *
389 EFIAPI
MmioWriteBuffer64(IN UINTN StartAddress,IN UINTN Length,IN CONST UINT64 * Buffer)390 MmioWriteBuffer64 (
391   IN  UINTN        StartAddress,
392   IN  UINTN        Length,
393   IN  CONST UINT64 *Buffer
394   )
395 {
396   UINT64    *ReturnBuffer;
397 
398   ASSERT ((StartAddress & (sizeof (UINT64) - 1)) == 0);
399 
400   ASSERT ((Length - 1) <=  (MAX_ADDRESS - StartAddress));
401   ASSERT ((Length - 1) <=  (MAX_ADDRESS - (UINTN) Buffer));
402 
403   ASSERT ((Length & (sizeof (UINT64) - 1)) == 0);
404   ASSERT (((UINTN) Buffer & (sizeof (UINT64) - 1)) == 0);
405 
406   ReturnBuffer = (UINT64 *) Buffer;
407 
408   while (Length > 0) {
409     MmioWrite64 (StartAddress, *(Buffer++));
410 
411     StartAddress += sizeof (UINT64);
412     Length -= sizeof (UINT64);
413   }
414 
415   return ReturnBuffer;
416 }
417 
418