1 /*++
2 
3 Copyright (c) 2004 - 2006, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution.  The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8 
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11 
12 
13 Module Name:
14 
15   IoLibMsc.c
16 
17 Abstract:
18 
19   I/O Library. This file has compiler specifics for Microsft C as there is no
20   ANSI C standard for doing IO.
21 
22   MSC - uses intrinsic functions and the optimize will remove the function call
23   overhead.
24 
25   We don't advocate putting compiler specifics in libraries or drivers but there
26   is no other way to make this work.
27 
28 --*/
29 
30 #include "EdkIIGlueBase.h"
31 
32 #if _MSC_EXTENSIONS
33 
34 //
35 // Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics
36 //
37 int            _inp (unsigned short port);
38 unsigned short _inpw (unsigned short port);
39 unsigned long  _inpd (unsigned short port);
40 int            _outp (unsigned short port, int databyte );
41 unsigned short _outpw (unsigned short port, unsigned short dataword );
42 unsigned long  _outpd (unsigned short port, unsigned long dataword );
43 void          _ReadWriteBarrier (void);
44 
45 #pragma intrinsic(_inp)
46 #pragma intrinsic(_inpw)
47 #pragma intrinsic(_inpd)
48 #pragma intrinsic(_outp)
49 #pragma intrinsic(_outpw)
50 #pragma intrinsic(_outpd)
51 #pragma intrinsic(_ReadWriteBarrier)
52 
53 //
54 // _ReadWriteBarrier() forces memory reads and writes to complete at the point
55 // in the call. This is only a hint to the compiler and does emit code.
56 // In past versions of the compiler, _ReadWriteBarrier was enforced only
57 // locally and did not affect functions up the call tree. In Visual C++
58 // 2005, _ReadWriteBarrier is enforced all the way up the call tree.
59 //
60 
61 /**
62   Reads an 8-bit I/O port.
63 
64   Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.
65   This function must guarantee that all I/O read and write operations are
66   serialized.
67 
68   If 8-bit I/O port operations are not supported, then ASSERT().
69 
70   @param  Port  The I/O port to read.
71 
72   @return The value read.
73 
74 **/
75 UINT8
76 EFIAPI
GlueIoRead8(IN UINTN Port)77 GlueIoRead8 (
78   IN      UINTN                     Port
79   )
80 {
81   UINT8                             Value;
82 
83   _ReadWriteBarrier ();
84   Value = (UINT8)_inp ((UINT16)Port);
85   _ReadWriteBarrier ();
86   return Value;
87 }
88 
89 /**
90   Writes an 8-bit I/O port.
91 
92   Writes the 8-bit I/O port specified by Port with the value specified by Value
93   and returns Value. This function must guarantee that all I/O read and write
94   operations are serialized.
95 
96   If 8-bit I/O port operations are not supported, then ASSERT().
97 
98   @param  Port  The I/O port to write.
99   @param  Value The value to write to the I/O port.
100 
101   @return The value written the I/O port.
102 
103 **/
104 UINT8
105 EFIAPI
GlueIoWrite8(IN UINTN Port,IN UINT8 Value)106 GlueIoWrite8 (
107   IN      UINTN                     Port,
108   IN      UINT8                     Value
109   )
110 {
111   _ReadWriteBarrier ();
112   (UINT8)_outp ((UINT16)Port, Value);
113   _ReadWriteBarrier ();
114   return Value;
115 }
116 
117 /**
118   Reads a 16-bit I/O port.
119 
120   Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned.
121   This function must guarantee that all I/O read and write operations are
122   serialized.
123 
124   If 16-bit I/O port operations are not supported, then ASSERT().
125 
126   @param  Port  The I/O port to read.
127 
128   @return The value read.
129 
130 **/
131 UINT16
132 EFIAPI
GlueIoRead16(IN UINTN Port)133 GlueIoRead16 (
134   IN      UINTN                     Port
135   )
136 {
137   UINT16                            Value;
138 
139   ASSERT ((Port & 1) == 0);
140   _ReadWriteBarrier ();
141   Value = _inpw ((UINT16)Port);
142   _ReadWriteBarrier ();
143   return Value;
144 }
145 
146 /**
147   Writes a 16-bit I/O port.
148 
149   Writes the 16-bit I/O port specified by Port with the value specified by Value
150   and returns Value. This function must guarantee that all I/O read and write
151   operations are serialized.
152 
153   If 16-bit I/O port operations are not supported, then ASSERT().
154 
155   @param  Port  The I/O port to write.
156   @param  Value The value to write to the I/O port.
157 
158   @return The value written the I/O port.
159 
160 **/
161 UINT16
162 EFIAPI
GlueIoWrite16(IN UINTN Port,IN UINT16 Value)163 GlueIoWrite16 (
164   IN      UINTN                     Port,
165   IN      UINT16                    Value
166   )
167 {
168   ASSERT ((Port & 1) == 0);
169   _ReadWriteBarrier ();
170   _outpw ((UINT16)Port, Value);
171   _ReadWriteBarrier ();
172   return Value;
173 }
174 
175 /**
176   Reads a 32-bit I/O port.
177 
178   Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned.
179   This function must guarantee that all I/O read and write operations are
180   serialized.
181 
182   If 32-bit I/O port operations are not supported, then ASSERT().
183 
184   @param  Port  The I/O port to read.
185 
186   @return The value read.
187 
188 **/
189 UINT32
190 EFIAPI
GlueIoRead32(IN UINTN Port)191 GlueIoRead32 (
192   IN      UINTN                     Port
193   )
194 {
195   UINT32                            Value;
196 
197   ASSERT ((Port & 3) == 0);
198   _ReadWriteBarrier ();
199   Value = _inpd ((UINT16)Port);
200   _ReadWriteBarrier ();
201   return Value;
202 }
203 
204 /**
205   Writes a 32-bit I/O port.
206 
207   Writes the 32-bit I/O port specified by Port with the value specified by Value
208   and returns Value. This function must guarantee that all I/O read and write
209   operations are serialized.
210 
211   If 32-bit I/O port operations are not supported, then ASSERT().
212 
213   @param  Port  The I/O port to write.
214   @param  Value The value to write to the I/O port.
215 
216   @return The value written the I/O port.
217 
218 **/
219 UINT32
220 EFIAPI
GlueIoWrite32(IN UINTN Port,IN UINT32 Value)221 GlueIoWrite32 (
222   IN      UINTN                     Port,
223   IN      UINT32                    Value
224   )
225 {
226   ASSERT ((Port & 3) == 0);
227   _ReadWriteBarrier ();
228   _outpd ((UINT16)Port, Value);
229   _ReadWriteBarrier ();
230   return Value;
231 }
232 
233 
234 /**
235   Reads an 8-bit MMIO register.
236 
237   Reads the 8-bit MMIO register specified by Address. The 8-bit read value is
238   returned. This function must guarantee that all MMIO read and write
239   operations are serialized.
240 
241   If 8-bit MMIO register operations are not supported, then ASSERT().
242 
243   @param  Address The MMIO register to read.
244 
245   @return The value read.
246 
247 **/
248 UINT8
249 EFIAPI
MmioRead8(IN UINTN Address)250 MmioRead8 (
251   IN      UINTN                     Address
252   )
253 {
254   UINT8                             Value;
255 
256   Value = *(volatile UINT8*)Address;
257   return Value;
258 }
259 
260 /**
261   Writes an 8-bit MMIO register.
262 
263   Writes the 8-bit MMIO register specified by Address with the value specified
264   by Value and returns Value. This function must guarantee that all MMIO read
265   and write operations are serialized.
266 
267   If 8-bit MMIO register operations are not supported, then ASSERT().
268 
269   @param  Address The MMIO register to write.
270   @param  Value   The value to write to the MMIO register.
271 
272 **/
273 UINT8
274 EFIAPI
MmioWrite8(IN UINTN Address,IN UINT8 Value)275 MmioWrite8 (
276   IN      UINTN                     Address,
277   IN      UINT8                     Value
278   )
279 {
280   return *(volatile UINT8*)Address = Value;
281 }
282 
283 /**
284   Reads a 16-bit MMIO register.
285 
286   Reads the 16-bit MMIO register specified by Address. The 16-bit read value is
287   returned. This function must guarantee that all MMIO read and write
288   operations are serialized.
289 
290   If 16-bit MMIO register operations are not supported, then ASSERT().
291 
292   @param  Address The MMIO register to read.
293 
294   @return The value read.
295 
296 **/
297 UINT16
298 EFIAPI
MmioRead16(IN UINTN Address)299 MmioRead16 (
300   IN      UINTN                     Address
301   )
302 {
303   UINT16                            Value;
304 
305   ASSERT ((Address & 1) == 0);
306   Value = *(volatile UINT16*)Address;
307   return Value;
308 }
309 
310 /**
311   Writes a 16-bit MMIO register.
312 
313   Writes the 16-bit MMIO register specified by Address with the value specified
314   by Value and returns Value. This function must guarantee that all MMIO read
315   and write operations are serialized.
316 
317   If 16-bit MMIO register operations are not supported, then ASSERT().
318 
319   @param  Address The MMIO register to write.
320   @param  Value   The value to write to the MMIO register.
321 
322 **/
323 UINT16
324 EFIAPI
MmioWrite16(IN UINTN Address,IN UINT16 Value)325 MmioWrite16 (
326   IN      UINTN                     Address,
327   IN      UINT16                    Value
328   )
329 {
330   ASSERT ((Address & 1) == 0);
331   return *(volatile UINT16*)Address = Value;
332 }
333 
334 /**
335   Reads a 32-bit MMIO register.
336 
337   Reads the 32-bit MMIO register specified by Address. The 32-bit read value is
338   returned. This function must guarantee that all MMIO read and write
339   operations are serialized.
340 
341   If 32-bit MMIO register operations are not supported, then ASSERT().
342 
343   @param  Address The MMIO register to read.
344 
345   @return The value read.
346 
347 **/
348 UINT32
349 EFIAPI
MmioRead32(IN UINTN Address)350 MmioRead32 (
351   IN      UINTN                     Address
352   )
353 {
354   UINT32                            Value;
355 
356   ASSERT ((Address & 3) == 0);
357   Value = *(volatile UINT32*)Address;
358   return Value;
359 }
360 
361 /**
362   Writes a 32-bit MMIO register.
363 
364   Writes the 32-bit MMIO register specified by Address with the value specified
365   by Value and returns Value. This function must guarantee that all MMIO read
366   and write operations are serialized.
367 
368   If 32-bit MMIO register operations are not supported, then ASSERT().
369 
370   @param  Address The MMIO register to write.
371   @param  Value   The value to write to the MMIO register.
372 
373 **/
374 UINT32
375 EFIAPI
MmioWrite32(IN UINTN Address,IN UINT32 Value)376 MmioWrite32 (
377   IN      UINTN                     Address,
378   IN      UINT32                    Value
379   )
380 {
381   ASSERT ((Address & 3) == 0);
382   return *(volatile UINT32*)Address = Value;
383 }
384 
385 /**
386   Reads a 64-bit MMIO register.
387 
388   Reads the 64-bit MMIO register specified by Address. The 64-bit read value is
389   returned. This function must guarantee that all MMIO read and write
390   operations are serialized.
391 
392   If 64-bit MMIO register operations are not supported, then ASSERT().
393 
394   @param  Address The MMIO register to read.
395 
396   @return The value read.
397 
398 **/
399 UINT64
400 EFIAPI
MmioRead64(IN UINTN Address)401 MmioRead64 (
402   IN      UINTN                     Address
403   )
404 {
405   UINT64                            Value;
406 
407   ASSERT ((Address & 7) == 0);
408   Value = *(volatile UINT64*)Address;
409   return Value;
410 }
411 
412 /**
413   Writes a 64-bit MMIO register.
414 
415   Writes the 64-bit MMIO register specified by Address with the value specified
416   by Value and returns Value. This function must guarantee that all MMIO read
417   and write operations are serialized.
418 
419   If 64-bit MMIO register operations are not supported, then ASSERT().
420 
421   @param  Address The MMIO register to write.
422   @param  Value   The value to write to the MMIO register.
423 
424 **/
425 UINT64
426 EFIAPI
MmioWrite64(IN UINTN Address,IN UINT64 Value)427 MmioWrite64 (
428   IN      UINTN                     Address,
429   IN      UINT64                    Value
430   )
431 {
432   ASSERT ((Address & 7) == 0);
433   return *(volatile UINT64*)Address = Value;
434 }
435 
436 #endif
437