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**/
35UINT8 *
36EFIAPI
37MmioReadBuffer8 (
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**/
80UINT16 *
81EFIAPI
82MmioReadBuffer16 (
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**/
131UINT32 *
132EFIAPI
133MmioReadBuffer32 (
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**/
183UINT64 *
184EFIAPI
185MmioReadBuffer64 (
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**/
232UINT8 *
233EFIAPI
234MmioWriteBuffer8 (
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**/
279UINT16 *
280EFIAPI
281MmioWriteBuffer16 (
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**/
334UINT32 *
335EFIAPI
336MmioWriteBuffer32 (
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**/
388UINT64 *
389EFIAPI
390MmioWriteBuffer64 (
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